From 2aa4a82499d4becd2284cdb482213d541b8804dd Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 28 Apr 2024 16:29:10 +0200 Subject: Adding upstream version 86.0.1. Signed-off-by: Daniel Baumann --- security/manager/ssl/CSTrustDomain.cpp | 194 + security/manager/ssl/CSTrustDomain.h | 80 + security/manager/ssl/CommonSocketControl.cpp | 350 + security/manager/ssl/CommonSocketControl.h | 35 + security/manager/ssl/ContentSignatureVerifier.cpp | 441 + security/manager/ssl/ContentSignatureVerifier.h | 32 + security/manager/ssl/CredentialManagerSecret.cpp | 114 + security/manager/ssl/CredentialManagerSecret.h | 28 + security/manager/ssl/CryptoTask.cpp | 43 + security/manager/ssl/CryptoTask.h | 52 + security/manager/ssl/DER.jsm | 320 + security/manager/ssl/DataStorage.cpp | 1086 + security/manager/ssl/DataStorage.h | 257 + security/manager/ssl/DataStorageIPCUtils.h | 21 + security/manager/ssl/DataStorageList.h | 19 + security/manager/ssl/EnterpriseRoots.cpp | 375 + security/manager/ssl/EnterpriseRoots.h | 35 + security/manager/ssl/KeychainSecret.cpp | 186 + security/manager/ssl/KeychainSecret.h | 45 + security/manager/ssl/LibSecret.cpp | 383 + security/manager/ssl/LibSecret.h | 31 + security/manager/ssl/LocalCertService.cpp | 444 + security/manager/ssl/LocalCertService.h | 26 + security/manager/ssl/NSSErrorsService.cpp | 212 + security/manager/ssl/NSSErrorsService.h | 56 + security/manager/ssl/NSSKeyStore.cpp | 225 + security/manager/ssl/NSSKeyStore.h | 36 + security/manager/ssl/OSKeyStore.cpp | 726 + security/manager/ssl/OSKeyStore.h | 105 + security/manager/ssl/OSReauthenticator.cpp | 567 + security/manager/ssl/OSReauthenticator.h | 36 + security/manager/ssl/OSReauthenticatorDarwin.mm | 60 + security/manager/ssl/PKCS11ModuleDB.cpp | 185 + security/manager/ssl/PKCS11ModuleDB.h | 35 + security/manager/ssl/PSMIPCCommon.cpp | 161 + security/manager/ssl/PSMIPCCommon.h | 34 + security/manager/ssl/PSMIPCTypes.ipdlh | 36 + security/manager/ssl/PSMRunnable.cpp | 42 + security/manager/ssl/PSMRunnable.h | 48 + security/manager/ssl/PVerifySSLServerCert.ipdl | 31 + security/manager/ssl/PublicKeyPinningService.cpp | 346 + security/manager/ssl/PublicKeyPinningService.h | 65 + security/manager/ssl/PublicSSL.h | 24 + security/manager/ssl/RemoteSecuritySettings.jsm | 850 + .../manager/ssl/RootCertificateTelemetryUtils.cpp | 138 + .../manager/ssl/RootCertificateTelemetryUtils.h | 37 + security/manager/ssl/RootHashes.inc | 1315 + security/manager/ssl/SSLServerCertVerification.cpp | 1422 + security/manager/ssl/SSLServerCertVerification.h | 163 + security/manager/ssl/ScopedNSSTypes.h | 368 + security/manager/ssl/SecretDecoderRing.cpp | 343 + security/manager/ssl/SecretDecoderRing.h | 37 + security/manager/ssl/SharedCertVerifier.h | 42 + security/manager/ssl/SharedSSLState.cpp | 189 + security/manager/ssl/SharedSSLState.h | 84 + security/manager/ssl/StaticHPKPins.errors | 33 + security/manager/ssl/StaticHPKPins.h | 1149 + security/manager/ssl/TransportSecurityInfo.cpp | 1240 + security/manager/ssl/TransportSecurityInfo.h | 255 + security/manager/ssl/VerifySSLServerCertChild.cpp | 129 + security/manager/ssl/VerifySSLServerCertChild.h | 62 + security/manager/ssl/VerifySSLServerCertParent.cpp | 180 + security/manager/ssl/VerifySSLServerCertParent.h | 62 + security/manager/ssl/X509.jsm | 637 + security/manager/ssl/X509CertValidity.cpp | 146 + security/manager/ssl/X509CertValidity.h | 35 + security/manager/ssl/cert_storage/Cargo.toml | 24 + .../manager/ssl/cert_storage/src/cert_storage.h | 25 + security/manager/ssl/cert_storage/src/lib.rs | 1742 + security/manager/ssl/components.conf | 160 + security/manager/ssl/crashtests/398665-1.html | 1 + security/manager/ssl/crashtests/crashtests.list | 1 + security/manager/ssl/md4.c | 179 + security/manager/ssl/md4.h | 38 + security/manager/ssl/moz.build | 246 + security/manager/ssl/nsCertOverrideService.cpp | 806 + security/manager/ssl/nsCertOverrideService.h | 160 + security/manager/ssl/nsCertTree.cpp | 824 + security/manager/ssl/nsCertTree.h | 131 + security/manager/ssl/nsClientAuthRemember.cpp | 276 + security/manager/ssl/nsClientAuthRemember.h | 91 + security/manager/ssl/nsCryptoHash.cpp | 334 + security/manager/ssl/nsCryptoHash.h | 58 + security/manager/ssl/nsICertOverrideService.idl | 175 + security/manager/ssl/nsICertStorage.idl | 272 + security/manager/ssl/nsICertTree.idl | 39 + security/manager/ssl/nsICertificateDialogs.idl | 68 + security/manager/ssl/nsIClientAuthDialogs.idl | 41 + .../manager/ssl/nsIClientAuthRememberService.idl | 62 + .../manager/ssl/nsIContentSignatureVerifier.idl | 39 + security/manager/ssl/nsICryptoHMAC.idl | 106 + security/manager/ssl/nsICryptoHash.idl | 103 + security/manager/ssl/nsIKeyModule.idl | 41 + security/manager/ssl/nsILocalCertService.idl | 72 + security/manager/ssl/nsINSSComponent.idl | 114 + security/manager/ssl/nsINSSErrorsService.idl | 72 + security/manager/ssl/nsINSSVersion.idl | 37 + security/manager/ssl/nsIOSKeyStore.idl | 144 + security/manager/ssl/nsIOSReauthenticator.idl | 45 + security/manager/ssl/nsIPK11Token.idl | 81 + security/manager/ssl/nsIPK11TokenDB.idl | 31 + security/manager/ssl/nsIPKCS11Module.idl | 21 + security/manager/ssl/nsIPKCS11ModuleDB.idl | 40 + security/manager/ssl/nsIPKCS11Slot.idl | 52 + security/manager/ssl/nsIProtectedAuthThread.idl | 48 + security/manager/ssl/nsISecretDecoderRing.idl | 77 + security/manager/ssl/nsISecurityUITelemetry.idl | 138 + security/manager/ssl/nsISiteSecurityService.idl | 257 + security/manager/ssl/nsITokenDialogs.idl | 24 + security/manager/ssl/nsITokenPasswordDialogs.idl | 30 + security/manager/ssl/nsIX509Cert.idl | 223 + security/manager/ssl/nsIX509CertDB.idl | 351 + security/manager/ssl/nsIX509CertValidity.idl | 72 + security/manager/ssl/nsKeyModule.cpp | 102 + security/manager/ssl/nsKeyModule.h | 59 + security/manager/ssl/nsNSSCallbacks.cpp | 1382 + security/manager/ssl/nsNSSCallbacks.h | 45 + security/manager/ssl/nsNSSCertHelper.cpp | 100 + security/manager/ssl/nsNSSCertHelper.h | 31 + security/manager/ssl/nsNSSCertTrust.cpp | 121 + security/manager/ssl/nsNSSCertTrust.h | 55 + security/manager/ssl/nsNSSCertificate.cpp | 856 + security/manager/ssl/nsNSSCertificate.h | 91 + security/manager/ssl/nsNSSCertificateDB.cpp | 1375 + security/manager/ssl/nsNSSCertificateDB.h | 71 + security/manager/ssl/nsNSSComponent.cpp | 2755 + security/manager/ssl/nsNSSComponent.h | 176 + security/manager/ssl/nsNSSHelper.h | 32 + security/manager/ssl/nsNSSIOLayer.cpp | 2916 + security/manager/ssl/nsNSSIOLayer.h | 359 + security/manager/ssl/nsNSSModule.cpp | 134 + security/manager/ssl/nsNSSModule.h | 23 + security/manager/ssl/nsNSSVersion.cpp | 78 + security/manager/ssl/nsNSSVersion.h | 30 + security/manager/ssl/nsNTLMAuthModule.cpp | 1077 + security/manager/ssl/nsNTLMAuthModule.h | 33 + security/manager/ssl/nsPK11TokenDB.cpp | 286 + security/manager/ssl/nsPK11TokenDB.h | 67 + security/manager/ssl/nsPKCS11Slot.cpp | 276 + security/manager/ssl/nsPKCS11Slot.h | 58 + security/manager/ssl/nsPKCS12Blob.cpp | 343 + security/manager/ssl/nsPKCS12Blob.h | 54 + security/manager/ssl/nsProtectedAuthThread.cpp | 135 + security/manager/ssl/nsProtectedAuthThread.h | 54 + security/manager/ssl/nsRandomGenerator.cpp | 36 + security/manager/ssl/nsRandomGenerator.h | 29 + security/manager/ssl/nsSSLSocketProvider.cpp | 46 + security/manager/ssl/nsSSLSocketProvider.h | 32 + security/manager/ssl/nsSTSPreloadList.inc | 109307 ++++++++++++++++++ security/manager/ssl/nsSecureBrowserUI.cpp | 162 + security/manager/ssl/nsSecureBrowserUI.h | 53 + security/manager/ssl/nsSecurityHeaderParser.cpp | 206 + security/manager/ssl/nsSecurityHeaderParser.h | 78 + security/manager/ssl/nsSiteSecurityService.cpp | 1195 + security/manager/ssl/nsSiteSecurityService.h | 165 + security/manager/ssl/nsTLSSocketProvider.cpp | 47 + security/manager/ssl/nsTLSSocketProvider.h | 31 + security/manager/ssl/nsVerificationJob.h | 48 + security/manager/ssl/osclientcerts/Cargo.toml | 32 + .../ssl/osclientcerts/dynamic-library/moz.build | 30 + .../dynamic-library/osclientcerts.symbols | 1 + .../ssl/osclientcerts/dynamic-library/stub.cpp | 8 + security/manager/ssl/osclientcerts/moz.build | 9 + .../manager/ssl/osclientcerts/src/backend_macos.rs | 967 + .../ssl/osclientcerts/src/backend_windows.rs | 933 + .../ssl/osclientcerts/src/bindings_macos.rs | 58 + security/manager/ssl/osclientcerts/src/lib.rs | 1208 + security/manager/ssl/osclientcerts/src/manager.rs | 614 + security/manager/ssl/osclientcerts/src/util.rs | 463 + .../manager/ssl/osclientcerts/test/certificate.bin | Bin 0 -> 909 bytes .../manager/ssl/osclientcerts/test/modulus.bin | 2 + security/manager/ssl/osclientcerts/test/rsa.bin | Bin 0 -> 270 bytes security/manager/ssl/tests/.eslintrc.js | 8 + security/manager/ssl/tests/gtest/CertDBTest.cpp | 52 + security/manager/ssl/tests/gtest/CertListTest.cpp | 332 + security/manager/ssl/tests/gtest/CoseTest.cpp | 756 + .../manager/ssl/tests/gtest/DataStorageTest.cpp | 201 + .../ssl/tests/gtest/DeserializeCertTest.cpp | 247 + security/manager/ssl/tests/gtest/MD4Test.cpp | 62 + security/manager/ssl/tests/gtest/OCSPCacheTest.cpp | 321 + security/manager/ssl/tests/gtest/README.txt | 2 + .../manager/ssl/tests/gtest/TLSIntoleranceTest.cpp | 383 + security/manager/ssl/tests/gtest/moz.build | 29 + .../ssl/tests/mochitest/browser/browser.ini | 25 + .../browser/browser_bug627234_perwindowpb.js | 101 + .../tests/mochitest/browser/browser_certViewer.js | 107 + .../browser/browser_certificateManager.js | 179 + .../browser/browser_clientAuthRememberService.js | 257 + .../browser/browser_clientAuth_connection.js | 342 + .../mochitest/browser/browser_clientAuth_ui.js | 199 + .../mochitest/browser/browser_deleteCert_ui.js | 257 + .../mochitest/browser/browser_downloadCert_ui.js | 133 + .../mochitest/browser/browser_editCACertTrust.js | 140 + .../browser/browser_exportP12_passwordUI.js | 163 + .../browser/browser_loadPKCS11Module_ui.js | 312 + .../manager/ssl/tests/mochitest/browser/ca.pem | 17 + .../ssl/tests/mochitest/browser/ca.pem.certspec | 4 + .../browser/client-cert-via-intermediate.pem | 19 + .../client-cert-via-intermediate.pem.certspec | 3 + .../browser/client-cert-with-ocsp-signing.pem | 20 + .../client-cert-with-ocsp-signing.pem.certspec | 3 + .../ssl/tests/mochitest/browser/code-ee.pem | 17 + .../tests/mochitest/browser/code-ee.pem.certspec | 3 + .../tests/mochitest/browser/ee-from-expired-ca.pem | 17 + .../browser/ee-from-expired-ca.pem.certspec | 2 + .../mochitest/browser/ee-from-untrusted-ca.pem | 17 + .../browser/ee-from-untrusted-ca.pem.certspec | 2 + .../ssl/tests/mochitest/browser/email-ee.pem | 17 + .../tests/mochitest/browser/email-ee.pem.certspec | 3 + .../ssl/tests/mochitest/browser/expired-ca.pem | 18 + .../mochitest/browser/expired-ca.pem.certspec | 5 + .../manager/ssl/tests/mochitest/browser/has-cn.pem | 18 + .../tests/mochitest/browser/has-cn.pem.certspec | 2 + .../tests/mochitest/browser/has-empty-subject.pem | 16 + .../browser/has-empty-subject.pem.certspec | 3 + .../mochitest/browser/has-non-empty-subject.pem | 17 + .../browser/has-non-empty-subject.pem.certspec | 2 + .../manager/ssl/tests/mochitest/browser/has-o.pem | 17 + .../ssl/tests/mochitest/browser/has-o.pem.certspec | 2 + .../manager/ssl/tests/mochitest/browser/has-ou.pem | 17 + .../tests/mochitest/browser/has-ou.pem.certspec | 2 + .../manager/ssl/tests/mochitest/browser/head.js | 83 + .../ssl/tests/mochitest/browser/intermediate.pem | 20 + .../mochitest/browser/intermediate.pem.certspec | 4 + .../ssl/tests/mochitest/browser/invalid.pem | 17 + .../tests/mochitest/browser/invalid.pem.certspec | 3 + .../ssl/tests/mochitest/browser/longOID.pem | 25 + .../tests/mochitest/browser/longOID.pem.certspec | 4 + .../manager/ssl/tests/mochitest/browser/md5-ee.pem | 17 + .../tests/mochitest/browser/md5-ee.pem.certspec | 3 + .../manager/ssl/tests/mochitest/browser/moz.build | 41 + .../tests/mochitest/browser/pgo-ca-all-usages.pem | 21 + .../browser/pgo-ca-all-usages.pem.certspec | 4 + .../mochitest/browser/pgo-ca-regular-usages.pem | 21 + .../browser/pgo-ca-regular-usages.pem.certspec | 4 + .../ssl/tests/mochitest/browser/revoked.pem | 17 + .../tests/mochitest/browser/revoked.pem.certspec | 2 + .../manager/ssl/tests/mochitest/browser/ssl-ee.pem | 18 + .../tests/mochitest/browser/ssl-ee.pem.certspec | 3 + .../ssl/tests/mochitest/browser/unknown-issuer.pem | 17 + .../mochitest/browser/unknown-issuer.pem.certspec | 2 + .../ssl/tests/mochitest/browser/untrusted-ca.pem | 18 + .../mochitest/browser/untrusted-ca.pem.certspec | 4 + .../tests/mochitest/mixedcontent/alloworigin.sjs | 6 + .../ssl/tests/mochitest/mixedcontent/backward.html | 18 + .../ssl/tests/mochitest/mixedcontent/bug329869.js | 11 + .../mochitest/mixedcontent/bug383369step2.html | 28 + .../mochitest/mixedcontent/bug383369step3.html | 29 + .../ssl/tests/mochitest/mixedcontent/download.auto | 1 + .../mochitest/mixedcontent/download.auto^headers^ | 2 + .../tests/mochitest/mixedcontent/emptyimage.sjs | 5 + .../ssl/tests/mochitest/mixedcontent/hugebmp.sjs | 13 + .../ssl/tests/mochitest/mixedcontent/iframe.html | 14 + .../ssl/tests/mochitest/mixedcontent/iframe2.html | 15 + .../mochitest/mixedcontent/iframeMetaRedirect.html | 8 + .../mochitest/mixedcontent/iframesecredirect.sjs | 5 + .../mochitest/mixedcontent/iframeunsecredirect.sjs | 5 + .../mochitest/mixedcontent/imgsecredirect.sjs | 5 + .../mochitest/mixedcontent/imgunsecredirect.sjs | 5 + .../mochitest/mixedcontent/mixedContentTest.js | 211 + .../ssl/tests/mochitest/mixedcontent/mochitest.ini | 65 + .../tests/mochitest/mixedcontent/moonsurface.jpg | Bin 0 -> 52159 bytes .../ssl/tests/mochitest/mixedcontent/moz.build | 7 + .../ssl/tests/mochitest/mixedcontent/nocontent.sjs | 4 + .../mixedcontent/redirecttoemptyimage.sjs | 5 + .../ssl/tests/mochitest/mixedcontent/somestyle.css | 4 + .../mochitest/mixedcontent/test_bug329869.html | 36 + .../mochitest/mixedcontent/test_bug383369.html | 92 + .../mochitest/mixedcontent/test_bug455367.html | 37 + .../mochitest/mixedcontent/test_bug472986.html | 46 + .../mochitest/mixedcontent/test_bug477118.html | 34 + .../mochitest/mixedcontent/test_bug521461.html | 39 + .../mochitest/mixedcontent/test_cssBefore1.html | 42 + .../mochitest/mixedcontent/test_cssContent1.html | 41 + .../mochitest/mixedcontent/test_cssContent2.html | 46 + .../mixedcontent/test_documentWrite1.html | 38 + .../mixedcontent/test_documentWrite2.html | 40 + .../test_dynDelayedUnsecurePicture.html | 47 + .../mixedcontent/test_dynDelayedUnsecureXHR.html | 48 + .../mixedcontent/test_dynUnsecureBackground.html | 44 + .../test_dynUnsecureIframeRedirect.html | 44 + .../mixedcontent/test_dynUnsecurePicture.html | 46 + .../test_dynUnsecurePicturePreload.html | 36 + .../mixedcontent/test_dynUnsecureRedirect.html | 39 + .../test_innerHtmlDelayedUnsecurePicture.html | 42 + .../test_innerHtmlUnsecurePicture.html | 40 + .../mixedcontent/test_javascriptPicture.html | 34 + .../mochitest/mixedcontent/test_secureAll.html | 42 + .../mochitest/mixedcontent/test_securePicture.html | 36 + .../mixedcontent/test_unsecureBackground.html | 35 + .../mochitest/mixedcontent/test_unsecureCSS.html | 38 + .../mixedcontent/test_unsecureIframe.html | 36 + .../mixedcontent/test_unsecureIframe2.html | 36 + .../test_unsecureIframeMetaRedirect.html | 36 + .../mixedcontent/test_unsecureIframeRedirect.html | 36 + .../mixedcontent/test_unsecurePicture.html | 34 + .../mixedcontent/test_unsecurePictureDup.html | 20 + .../mixedcontent/test_unsecurePictureInIframe.html | 36 + .../mixedcontent/test_unsecureRedirect.html | 36 + .../mochitest/mixedcontent/unsecureIframe.html | 9 + .../mochitest/mixedcontent/unsecurePictureDup.html | 34 + security/manager/ssl/tests/mochitest/moz.build | 11 + .../mochitest/stricttransportsecurity/chrome.ini | 6 + .../stricttransportsecurity/mochitest.ini | 12 + .../mochitest/stricttransportsecurity/moz.build | 9 + .../stricttransportsecurity/nosts_bootstrap.html | 28 + .../nosts_bootstrap.html^headers^ | 1 + .../stricttransportsecurity/page_blank.html | 5 + .../stricttransportsecurity/plain_bootstrap.html | 28 + .../plain_bootstrap.html^headers^ | 2 + .../stricttransportsecurity/subdom_bootstrap.html | 28 + .../subdom_bootstrap.html^headers^ | 2 + .../test_stricttransportsecurity.html | 126 + .../test_sts_privatebrowsing_perwindowpb.html | 268 + .../mochitest/stricttransportsecurity/verify.sjs | 47 + security/manager/ssl/tests/moz.build | 17 + .../tests/unit/bad_certs/badSubjectAltNames.pem | 18 + .../unit/bad_certs/badSubjectAltNames.pem.certspec | 3 + .../ssl/tests/unit/bad_certs/beforeEpoch.pem | 19 + .../tests/unit/bad_certs/beforeEpoch.pem.certspec | 5 + .../ssl/tests/unit/bad_certs/beforeEpochINT.pem | 18 + .../unit/bad_certs/beforeEpochINT.pem.certspec | 5 + .../ssl/tests/unit/bad_certs/beforeEpochIssuer.pem | 20 + .../unit/bad_certs/beforeEpochIssuer.pem.certspec | 4 + .../tests/unit/bad_certs/ca-used-as-end-entity.pem | 20 + .../bad_certs/ca-used-as-end-entity.pem.certspec | 5 + .../ssl/tests/unit/bad_certs/default-ee.key | 28 + .../tests/unit/bad_certs/default-ee.key.keyspec | 1 + .../ssl/tests/unit/bad_certs/default-ee.pem | 21 + .../tests/unit/bad_certs/default-ee.pem.certspec | 4 + .../bad_certs/ee-from-missing-intermediate.pem | 19 + .../ee-from-missing-intermediate.pem.certspec | 3 + .../unit/bad_certs/ee-imminently-distrusted.pem | 20 + .../ee-imminently-distrusted.pem.certspec | 4 + .../ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem | 19 + .../unit/bad_certs/eeIssuedByNonCA.pem.certspec | 4 + .../ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem | 18 + .../unit/bad_certs/eeIssuedByV1Cert.pem.certspec | 3 + .../ssl/tests/unit/bad_certs/emptyIssuerName.pem | 18 + .../unit/bad_certs/emptyIssuerName.pem.certspec | 3 + .../ssl/tests/unit/bad_certs/emptyNameCA.pem | 17 + .../tests/unit/bad_certs/emptyNameCA.pem.certspec | 4 + .../tests/unit/bad_certs/ev-test-intermediate.pem | 20 + .../bad_certs/ev-test-intermediate.pem.certspec | 7 + .../manager/ssl/tests/unit/bad_certs/ev-test.pem | 20 + .../ssl/tests/unit/bad_certs/ev-test.pem.certspec | 5 + .../manager/ssl/tests/unit/bad_certs/evroot.key | 28 + .../ssl/tests/unit/bad_certs/evroot.key.keyspec | 1 + .../manager/ssl/tests/unit/bad_certs/evroot.pem | 18 + .../ssl/tests/unit/bad_certs/evroot.pem.certspec | 7 + .../ssl/tests/unit/bad_certs/expired-ee.pem | 19 + .../tests/unit/bad_certs/expired-ee.pem.certspec | 5 + .../ssl/tests/unit/bad_certs/expiredINT.pem | 18 + .../tests/unit/bad_certs/expiredINT.pem.certspec | 5 + .../ssl/tests/unit/bad_certs/expiredissuer.pem | 20 + .../unit/bad_certs/expiredissuer.pem.certspec | 4 + .../ssl/tests/unit/bad_certs/idn-certificate.pem | 19 + .../unit/bad_certs/idn-certificate.pem.certspec | 3 + .../tests/unit/bad_certs/inadequateKeySizeEE.key | 16 + .../unit/bad_certs/inadequateKeySizeEE.key.keyspec | 1 + .../tests/unit/bad_certs/inadequateKeySizeEE.pem | 17 + .../bad_certs/inadequateKeySizeEE.pem.certspec | 5 + .../tests/unit/bad_certs/inadequatekeyusage-ee.pem | 20 + .../bad_certs/inadequatekeyusage-ee.pem.certspec | 5 + .../unit/bad_certs/ipAddressAsDNSNameInSAN.pem | 18 + .../bad_certs/ipAddressAsDNSNameInSAN.pem.certspec | 3 + .../tests/unit/bad_certs/md5signature-expired.pem | 20 + .../bad_certs/md5signature-expired.pem.certspec | 6 + .../ssl/tests/unit/bad_certs/md5signature.pem | 19 + .../tests/unit/bad_certs/md5signature.pem.certspec | 5 + .../ssl/tests/unit/bad_certs/mismatch-expired.pem | 19 + .../unit/bad_certs/mismatch-expired.pem.certspec | 5 + .../tests/unit/bad_certs/mismatch-notYetValid.pem | 20 + .../bad_certs/mismatch-notYetValid.pem.certspec | 5 + .../unit/bad_certs/mismatch-untrusted-expired.pem | 20 + .../mismatch-untrusted-expired.pem.certspec | 5 + .../tests/unit/bad_certs/mismatch-untrusted.pem | 20 + .../unit/bad_certs/mismatch-untrusted.pem.certspec | 4 + .../manager/ssl/tests/unit/bad_certs/mismatch.pem | 20 + .../ssl/tests/unit/bad_certs/mismatch.pem.certspec | 4 + .../ssl/tests/unit/bad_certs/mismatchCN.pem | 17 + .../tests/unit/bad_certs/mismatchCN.pem.certspec | 2 + security/manager/ssl/tests/unit/bad_certs/mitm.pem | 18 + .../ssl/tests/unit/bad_certs/mitm.pem.certspec | 3 + .../manager/ssl/tests/unit/bad_certs/moz.build | 71 + .../ssl/tests/unit/bad_certs/noValidNames.pem | 19 + .../tests/unit/bad_certs/noValidNames.pem.certspec | 3 + .../ssl/tests/unit/bad_certs/notYetValid.pem | 19 + .../tests/unit/bad_certs/notYetValid.pem.certspec | 5 + .../ssl/tests/unit/bad_certs/notYetValidINT.pem | 18 + .../unit/bad_certs/notYetValidINT.pem.certspec | 5 + .../ssl/tests/unit/bad_certs/notYetValidIssuer.pem | 20 + .../unit/bad_certs/notYetValidIssuer.pem.certspec | 4 + .../tests/unit/bad_certs/nsCertTypeCritical.pem | 19 + .../unit/bad_certs/nsCertTypeCritical.pem.certspec | 4 + .../nsCertTypeCriticalWithExtKeyUsage.pem | 20 + .../nsCertTypeCriticalWithExtKeyUsage.pem.certspec | 6 + .../tests/unit/bad_certs/nsCertTypeNotCritical.pem | 19 + .../bad_certs/nsCertTypeNotCritical.pem.certspec | 4 + .../ssl/tests/unit/bad_certs/other-issuer-ee.pem | 21 + .../unit/bad_certs/other-issuer-ee.pem.certspec | 6 + .../ssl/tests/unit/bad_certs/other-test-ca.key | 28 + .../tests/unit/bad_certs/other-test-ca.key.keyspec | 1 + .../ssl/tests/unit/bad_certs/other-test-ca.pem | 18 + .../unit/bad_certs/other-test-ca.pem.certspec | 7 + .../unit/bad_certs/self-signed-EE-with-cA-true.pem | 21 + .../self-signed-EE-with-cA-true.pem.certspec | 5 + .../unit/bad_certs/selfsigned-inadequateEKU.pem | 21 + .../selfsigned-inadequateEKU.pem.certspec | 6 + .../ssl/tests/unit/bad_certs/selfsigned.pem | 20 + .../tests/unit/bad_certs/selfsigned.pem.certspec | 4 + .../manager/ssl/tests/unit/bad_certs/test-ca.pem | 18 + .../ssl/tests/unit/bad_certs/test-ca.pem.certspec | 4 + .../manager/ssl/tests/unit/bad_certs/test-int.pem | 18 + .../ssl/tests/unit/bad_certs/test-int.pem.certspec | 5 + .../ssl/tests/unit/bad_certs/unknownissuer.pem | 22 + .../unit/bad_certs/unknownissuer.pem.certspec | 4 + .../ssl/tests/unit/bad_certs/untrusted-expired.pem | 20 + .../unit/bad_certs/untrusted-expired.pem.certspec | 5 + .../ssl/tests/unit/bad_certs/untrustedissuer.pem | 20 + .../unit/bad_certs/untrustedissuer.pem.certspec | 4 + .../manager/ssl/tests/unit/bad_certs/v1Cert.pem | 17 + .../ssl/tests/unit/bad_certs/v1Cert.pem.certspec | 3 + security/manager/ssl/tests/unit/head_psm.js | 1231 + security/manager/ssl/tests/unit/moz.build | 42 + .../unit/ocsp_certs/ca-used-as-end-entity.pem | 20 + .../ocsp_certs/ca-used-as-end-entity.pem.certspec | 5 + .../ssl/tests/unit/ocsp_certs/default-ee.key | 28 + .../tests/unit/ocsp_certs/default-ee.key.keyspec | 1 + .../ssl/tests/unit/ocsp_certs/default-ee.pem | 21 + .../tests/unit/ocsp_certs/default-ee.pem.certspec | 4 + .../tests/unit/ocsp_certs/delegatedSHA1Signer.pem | 18 + .../ocsp_certs/delegatedSHA1Signer.pem.certspec | 5 + .../ssl/tests/unit/ocsp_certs/delegatedSigner.pem | 18 + .../unit/ocsp_certs/delegatedSigner.pem.certspec | 4 + .../invalidDelegatedSignerFromIntermediate.pem | 19 + ...lidDelegatedSignerFromIntermediate.pem.certspec | 4 + .../invalidDelegatedSignerKeyUsageCrlSigning.pem | 18 + ...dDelegatedSignerKeyUsageCrlSigning.pem.certspec | 4 + .../invalidDelegatedSignerNoExtKeyUsage.pem | 18 + ...nvalidDelegatedSignerNoExtKeyUsage.pem.certspec | 3 + .../invalidDelegatedSignerWrongExtKeyUsage.pem | 18 + ...lidDelegatedSignerWrongExtKeyUsage.pem.certspec | 4 + .../manager/ssl/tests/unit/ocsp_certs/moz.build | 42 + .../unit/ocsp_certs/multi-tls-feature-bad-ee.pem | 19 + .../multi-tls-feature-bad-ee.pem.certspec | 4 + .../unit/ocsp_certs/multi-tls-feature-good-ee.pem | 19 + .../multi-tls-feature-good-ee.pem.certspec | 4 + .../must-staple-ee-with-must-staple-int.pem | 19 + ...ust-staple-ee-with-must-staple-int.pem.certspec | 4 + .../ssl/tests/unit/ocsp_certs/must-staple-ee.pem | 19 + .../unit/ocsp_certs/must-staple-ee.pem.certspec | 5 + .../unit/ocsp_certs/must-staple-missing-ee.pem | 18 + .../ocsp_certs/must-staple-missing-ee.pem.certspec | 3 + .../unit/ocsp_certs/ocspEEWithIntermediate.pem | 20 + .../ocsp_certs/ocspEEWithIntermediate.pem.certspec | 4 + .../tests/unit/ocsp_certs/ocspOtherEndEntity.pem | 19 + .../ocsp_certs/ocspOtherEndEntity.pem.certspec | 4 + .../ssl/tests/unit/ocsp_certs/other-test-ca.key | 28 + .../unit/ocsp_certs/other-test-ca.key.keyspec | 1 + .../ssl/tests/unit/ocsp_certs/other-test-ca.pem | 18 + .../unit/ocsp_certs/other-test-ca.pem.certspec | 7 + .../ocsp_certs/rsa-1016-keysizeDelegatedSigner.key | 16 + .../rsa-1016-keysizeDelegatedSigner.key.keyspec | 1 + .../ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem | 15 + .../rsa-1016-keysizeDelegatedSigner.pem.certspec | 4 + .../manager/ssl/tests/unit/ocsp_certs/test-ca.pem | 18 + .../ssl/tests/unit/ocsp_certs/test-ca.pem.certspec | 4 + .../manager/ssl/tests/unit/ocsp_certs/test-int.pem | 18 + .../tests/unit/ocsp_certs/test-int.pem.certspec | 5 + .../unit/ocsp_certs/test-multi-tls-feature-int.pem | 19 + .../test-multi-tls-feature-int.pem.certspec | 5 + .../tests/unit/ocsp_certs/test-must-staple-int.pem | 19 + .../ocsp_certs/test-must-staple-int.pem.certspec | 5 + .../ssl/tests/unit/pkcs11testmodule/moz.build | 20 + .../unit/pkcs11testmodule/pkcs11testmodule.cpp | 577 + .../unit/pkcs11testmodule/pkcs11testmodule.symbols | 1 + security/manager/ssl/tests/unit/pycert.py | 815 + security/manager/ssl/tests/unit/pycms.py | 219 + security/manager/ssl/tests/unit/pyct.py | 103 + security/manager/ssl/tests/unit/pykey.py | 958 + security/manager/ssl/tests/unit/requirements.txt | 6 + security/manager/ssl/tests/unit/sign_app.py | 399 + .../ssl/tests/unit/sss_readstate_child_worker.js | 66 + .../ssl/tests/unit/test_add_preexisting_cert.js | 46 + .../ssl/tests/unit/test_allow_all_cert_errors.js | 25 + .../tests/unit/test_baseline_requirements/ca.pem | 17 + .../test_baseline_requirements/ca.pem.certspec | 5 + .../unit/test_baseline_requirements/moz.build | 19 + .../unit/test_baseline_requirements/no-san-old.pem | 17 + .../no-san-old.pem.certspec | 3 + .../test_baseline_requirements/no-san-older.pem | 17 + .../no-san-older.pem.certspec | 3 + .../test_baseline_requirements/no-san-recent.pem | 17 + .../no-san-recent.pem.certspec | 3 + .../san-contains-no-hostnames-old.pem | 18 + .../san-contains-no-hostnames-old.pem.certspec | 4 + .../san-contains-no-hostnames-older.pem | 18 + .../san-contains-no-hostnames-older.pem.certspec | 4 + .../san-contains-no-hostnames-recent.pem | 18 + .../san-contains-no-hostnames-recent.pem.certspec | 4 + ...st_baseline_requirements_subject_common_name.js | 295 + .../ssl/tests/unit/test_blocklist_onecrl.js | 75 + .../ssl/tests/unit/test_blocklist_pinning.js | 127 + .../manager/ssl/tests/unit/test_broken_fips.js | 64 + .../ssl/tests/unit/test_broken_fips/key4.db | Bin 0 -> 36864 bytes .../ssl/tests/unit/test_broken_fips/pkcs11.txt | 5 + .../ssl/tests/unit/test_certDB_export_pkcs12.js | 57 + ...st_certDB_export_pkcs12_with_master_password.js | 117 + .../manager/ssl/tests/unit/test_certDB_import.js | 217 + .../unit/test_certDB_import/cert_from_windows.pfx | Bin 0 -> 2041 bytes .../cert_from_windows_emptypass.pfx | Bin 0 -> 2068 bytes .../cert_from_windows_nopass.pfx | Bin 0 -> 2068 bytes .../ssl/tests/unit/test_certDB_import/emailEE.pem | 17 + .../unit/test_certDB_import/emailEE.pem.certspec | 2 + .../tests/unit/test_certDB_import/importedCA.pem | 17 + .../test_certDB_import/importedCA.pem.certspec | 3 + .../ssl/tests/unit/test_certDB_import/moz.build | 14 + .../ssl/tests/unit/test_certDB_import_pkcs12.js | 117 + .../test_certDB_import_with_master_password.js | 148 + .../manager/ssl/tests/unit/test_cert_chains.js | 814 + security/manager/ssl/tests/unit/test_cert_dbKey.js | 263 + security/manager/ssl/tests/unit/test_cert_eku.js | 189 + .../manager/ssl/tests/unit/test_cert_eku/ca.pem | 17 + .../ssl/tests/unit/test_cert_eku/ca.pem.certspec | 4 + .../manager/ssl/tests/unit/test_cert_eku/ee-CA.pem | 17 + .../tests/unit/test_cert_eku/ee-CA.pem.certspec | 3 + .../ssl/tests/unit/test_cert_eku/ee-SA-CA.pem | 18 + .../tests/unit/test_cert_eku/ee-SA-CA.pem.certspec | 3 + .../ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem | 18 + .../unit/test_cert_eku/ee-SA-OCSP.pem.certspec | 3 + .../ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem | 18 + .../unit/test_cert_eku/ee-SA-nsSGC.pem.certspec | 3 + .../manager/ssl/tests/unit/test_cert_eku/ee-SA.pem | 17 + .../tests/unit/test_cert_eku/ee-SA.pem.certspec | 3 + .../ssl/tests/unit/test_cert_eku/ee-int-CA.pem | 17 + .../unit/test_cert_eku/ee-int-CA.pem.certspec | 2 + .../ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem | 17 + .../unit/test_cert_eku/ee-int-SA-CA.pem.certspec | 2 + .../tests/unit/test_cert_eku/ee-int-SA-OCSP.pem | 17 + .../unit/test_cert_eku/ee-int-SA-OCSP.pem.certspec | 2 + .../tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem | 17 + .../test_cert_eku/ee-int-SA-nsSGC.pem.certspec | 2 + .../ssl/tests/unit/test_cert_eku/ee-int-SA.pem | 17 + .../unit/test_cert_eku/ee-int-SA.pem.certspec | 2 + .../tests/unit/test_cert_eku/ee-int-nsSGC-old.pem | 17 + .../test_cert_eku/ee-int-nsSGC-old.pem.certspec | 3 + .../unit/test_cert_eku/ee-int-nsSGC-older.pem | 17 + .../test_cert_eku/ee-int-nsSGC-older.pem.certspec | 3 + .../unit/test_cert_eku/ee-int-nsSGC-recent.pem | 17 + .../test_cert_eku/ee-int-nsSGC-recent.pem.certspec | 3 + .../ssl/tests/unit/test_cert_eku/ee-nsSGC.pem | 17 + .../tests/unit/test_cert_eku/ee-nsSGC.pem.certspec | 3 + .../ssl/tests/unit/test_cert_eku/int-CA.pem | 18 + .../tests/unit/test_cert_eku/int-CA.pem.certspec | 4 + .../ssl/tests/unit/test_cert_eku/int-SA-CA.pem | 18 + .../unit/test_cert_eku/int-SA-CA.pem.certspec | 4 + .../ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem | 18 + .../unit/test_cert_eku/int-SA-OCSP.pem.certspec | 4 + .../ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem | 18 + .../unit/test_cert_eku/int-SA-nsSGC.pem.certspec | 4 + .../ssl/tests/unit/test_cert_eku/int-SA.pem | 18 + .../tests/unit/test_cert_eku/int-SA.pem.certspec | 4 + .../ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem | 18 + .../unit/test_cert_eku/int-nsSGC-old.pem.certspec | 5 + .../tests/unit/test_cert_eku/int-nsSGC-older.pem | 18 + .../test_cert_eku/int-nsSGC-older.pem.certspec | 5 + .../tests/unit/test_cert_eku/int-nsSGC-recent.pem | 18 + .../test_cert_eku/int-nsSGC-recent.pem.certspec | 5 + .../manager/ssl/tests/unit/test_cert_eku/moz.build | 35 + .../ssl/tests/unit/test_cert_embedded_null.js | 54 + .../ssl/tests/unit/test_cert_embedded_null/ca.pem | 17 + .../unit/test_cert_embedded_null/ca.pem.certspec | 4 + .../unit/test_cert_embedded_null/embeddedNull.pem | 17 + .../embeddedNull.pem.certspec | 2 + .../embeddedNullCNAndSAN.pem | 18 + .../embeddedNullCNAndSAN.pem.certspec | 3 + .../test_cert_embedded_null/embeddedNullSAN.pem | 18 + .../embeddedNullSAN.pem.certspec | 3 + .../test_cert_embedded_null/embeddedNullSAN2.pem | 18 + .../embeddedNullSAN2.pem.certspec | 3 + .../tests/unit/test_cert_embedded_null/moz.build | 17 + .../ssl/tests/unit/test_cert_expiration_canary.js | 40 + .../ssl/tests/unit/test_cert_isBuiltInRoot.js | 73 + .../tests/unit/test_cert_isBuiltInRoot_reload.js | 124 + .../unit/test_cert_isBuiltInRoot_reload/cert9.db | Bin 0 -> 28672 bytes .../unit/test_cert_isBuiltInRoot_reload/key4.db | Bin 0 -> 36864 bytes .../manager/ssl/tests/unit/test_cert_keyUsage.js | 76 + .../unit/test_cert_keyUsage/ca-all-usages.pem | 18 + .../test_cert_keyUsage/ca-all-usages.pem.certspec | 4 + .../test_cert_keyUsage/ca-missing-keyCertSign.pem | 18 + .../ca-missing-keyCertSign.pem.certspec | 4 + .../ca-no-keyUsage-extension.pem | 18 + .../ca-no-keyUsage-extension.pem.certspec | 3 + ...yCertSign-and-keyEncipherment-ca-all-usages.pem | 18 + ...-and-keyEncipherment-ca-all-usages.pem.certspec | 3 + ...-and-keyEncipherment-ca-missing-keyCertSign.pem | 18 + ...ncipherment-ca-missing-keyCertSign.pem.certspec | 3 + ...nd-keyEncipherment-ca-no-keyUsage-extension.pem | 18 + ...ipherment-ca-no-keyUsage-extension.pem.certspec | 3 + .../ee-keyCertSign-only-ca-all-usages.pem | 18 + .../ee-keyCertSign-only-ca-all-usages.pem.certspec | 3 + .../ee-keyCertSign-only-ca-missing-keyCertSign.pem | 18 + ...rtSign-only-ca-missing-keyCertSign.pem.certspec | 3 + ...e-keyCertSign-only-ca-no-keyUsage-extension.pem | 18 + ...Sign-only-ca-no-keyUsage-extension.pem.certspec | 3 + .../ee-keyEncipherment-only-ca-all-usages.pem | 18 + ...keyEncipherment-only-ca-all-usages.pem.certspec | 3 + ...keyEncipherment-only-ca-missing-keyCertSign.pem | 18 + ...erment-only-ca-missing-keyCertSign.pem.certspec | 3 + ...yEncipherment-only-ca-no-keyUsage-extension.pem | 18 + ...ment-only-ca-no-keyUsage-extension.pem.certspec | 3 + .../ee-no-keyUsage-extension-ca-all-usages.pem | 17 + ...o-keyUsage-extension-ca-all-usages.pem.certspec | 2 + ...o-keyUsage-extension-ca-missing-keyCertSign.pem | 18 + ...e-extension-ca-missing-keyCertSign.pem.certspec | 2 + ...keyUsage-extension-ca-no-keyUsage-extension.pem | 18 + ...extension-ca-no-keyUsage-extension.pem.certspec | 2 + .../ssl/tests/unit/test_cert_keyUsage/moz.build | 27 + .../unit/test_cert_override_bits_mismatches.js | 116 + .../manager/ssl/tests/unit/test_cert_overrides.js | 718 + .../tests/unit/test_cert_overrides_read_only.js | 126 + .../unit/test_cert_overrides_read_only/cert9.db | Bin 0 -> 28672 bytes .../unit/test_cert_overrides_read_only/key4.db | Bin 0 -> 36864 bytes security/manager/ssl/tests/unit/test_cert_sha1.js | 187 + .../manager/ssl/tests/unit/test_cert_sha1/ca.pem | 17 + .../ssl/tests/unit/test_cert_sha1/ca.pem.certspec | 6 + .../tests/unit/test_cert_sha1/ee-post_int-post.pem | 17 + .../test_cert_sha1/ee-post_int-post.pem.certspec | 4 + .../tests/unit/test_cert_sha1/ee-post_int-pre.pem | 17 + .../test_cert_sha1/ee-post_int-pre.pem.certspec | 4 + .../tests/unit/test_cert_sha1/ee-pre_int-pre.pem | 17 + .../test_cert_sha1/ee-pre_int-pre.pem.certspec | 4 + .../ssl/tests/unit/test_cert_sha1/int-post.pem | 18 + .../unit/test_cert_sha1/int-post.pem.certspec | 6 + .../ssl/tests/unit/test_cert_sha1/int-pre.pem | 18 + .../tests/unit/test_cert_sha1/int-pre.pem.certspec | 6 + .../ssl/tests/unit/test_cert_sha1/moz.build | 18 + .../manager/ssl/tests/unit/test_cert_signatures.js | 140 + .../ssl/tests/unit/test_cert_signatures/ca-rsa.pem | 18 + .../unit/test_cert_signatures/ca-rsa.pem.certspec | 4 + .../unit/test_cert_signatures/ca-secp384r1.pem | 11 + .../test_cert_signatures/ca-secp384r1.pem.certspec | 7 + .../unit/test_cert_signatures/ee-rsa-direct.pem | 17 + .../ee-rsa-direct.pem.certspec | 2 + .../ssl/tests/unit/test_cert_signatures/ee-rsa.pem | 17 + .../unit/test_cert_signatures/ee-rsa.pem.certspec | 2 + .../test_cert_signatures/ee-secp384r1-direct.pem | 10 + .../ee-secp384r1-direct.pem.certspec | 5 + .../unit/test_cert_signatures/ee-secp384r1.pem | 10 + .../test_cert_signatures/ee-secp384r1.pem.certspec | 5 + .../tests/unit/test_cert_signatures/int-rsa.pem | 18 + .../unit/test_cert_signatures/int-rsa.pem.certspec | 4 + .../unit/test_cert_signatures/int-secp384r1.pem | 11 + .../int-secp384r1.pem.certspec | 7 + .../ssl/tests/unit/test_cert_signatures/moz.build | 20 + .../manager/ssl/tests/unit/test_cert_storage.js | 286 + .../ssl/tests/unit/test_cert_storage_broken_db.js | 95 + .../ssl/tests/unit/test_cert_storage_direct.js | 533 + .../revoked-cert-issuer.pem | 27 + .../unit/test_cert_storage_direct/revoked-cert.pem | 41 + .../test_cert_storage_direct/test-filter.crlite | Bin 0 -> 15244 bytes .../test_cert_storage_direct/test-filter.stash | Bin 0 -> 64267 bytes .../test_cert_storage_direct/valid-cert-issuer.pem | 27 + .../unit/test_cert_storage_direct/valid-cert.pem | 34 + .../tests/unit/test_cert_storage_preexisting.js | 59 + .../unit/test_cert_storage_preexisting/data.mdb | Bin 0 -> 45056 bytes .../test_cert_storage_preexisting/data.safe.bin | Bin 0 -> 122 bytes .../unit/test_cert_storage_preexisting/lock.mdb | Bin 0 -> 8192 bytes .../unit/test_cert_storage_preexisting_crlite.js | 71 + .../crlite.filter | Bin 0 -> 15244 bytes .../data.safe.bin | Bin 0 -> 1607775 bytes .../ssl/tests/unit/test_cert_storage_prefs.js | 34 + security/manager/ssl/tests/unit/test_cert_trust.js | 324 + .../manager/ssl/tests/unit/test_cert_trust/ca.pem | 17 + .../ssl/tests/unit/test_cert_trust/ca.pem.certspec | 4 + .../manager/ssl/tests/unit/test_cert_trust/ee.pem | 18 + .../ssl/tests/unit/test_cert_trust/ee.pem.certspec | 3 + .../manager/ssl/tests/unit/test_cert_trust/int.pem | 17 + .../tests/unit/test_cert_trust/int.pem.certspec | 4 + .../ssl/tests/unit/test_cert_trust/moz.build | 15 + security/manager/ssl/tests/unit/test_cert_utf8.js | 79 + .../unit/test_cert_utf8/certificateToAlter.pem | 24 + .../test_cert_utf8/certificateToAlter.pem.certspec | 3 + .../ssl/tests/unit/test_cert_utf8/moz.build | 13 + .../manager/ssl/tests/unit/test_cert_version.js | 304 + .../ssl/tests/unit/test_cert_version/ca.pem | 17 + .../tests/unit/test_cert_version/ca.pem.certspec | 4 + .../unit/test_cert_version/ee-v1-BC-cA_ca.pem | 17 + .../test_cert_version/ee-v1-BC-cA_ca.pem.certspec | 4 + .../unit/test_cert_version/ee-v1-BC-not-cA_ca.pem | 17 + .../ee-v1-BC-not-cA_ca.pem.certspec | 4 + .../tests/unit/test_cert_version/ee-v1-noBC_ca.pem | 17 + .../test_cert_version/ee-v1-noBC_ca.pem.certspec | 3 + .../unit/test_cert_version/ee-v2-BC-cA_ca.pem | 17 + .../test_cert_version/ee-v2-BC-cA_ca.pem.certspec | 4 + .../unit/test_cert_version/ee-v2-BC-not-cA_ca.pem | 17 + .../ee-v2-BC-not-cA_ca.pem.certspec | 4 + .../tests/unit/test_cert_version/ee-v2-noBC_ca.pem | 17 + .../test_cert_version/ee-v2-noBC_ca.pem.certspec | 3 + .../unit/test_cert_version/ee-v3-BC-cA_ca.pem | 17 + .../test_cert_version/ee-v3-BC-cA_ca.pem.certspec | 4 + .../unit/test_cert_version/ee-v3-BC-not-cA_ca.pem | 17 + .../ee-v3-BC-not-cA_ca.pem.certspec | 4 + .../tests/unit/test_cert_version/ee-v3-noBC_ca.pem | 17 + .../test_cert_version/ee-v3-noBC_ca.pem.certspec | 3 + .../unit/test_cert_version/ee-v4-BC-cA_ca.pem | 17 + .../test_cert_version/ee-v4-BC-cA_ca.pem.certspec | 4 + .../unit/test_cert_version/ee-v4-BC-not-cA_ca.pem | 17 + .../ee-v4-BC-not-cA_ca.pem.certspec | 4 + .../tests/unit/test_cert_version/ee-v4-noBC_ca.pem | 17 + .../test_cert_version/ee-v4-noBC_ca.pem.certspec | 3 + .../unit/test_cert_version/ee_int-v1-BC-cA.pem | 17 + .../test_cert_version/ee_int-v1-BC-cA.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v1-BC-not-cA.pem | 17 + .../ee_int-v1-BC-not-cA.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v1-noBC.pem | 17 + .../test_cert_version/ee_int-v1-noBC.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v2-BC-cA.pem | 17 + .../test_cert_version/ee_int-v2-BC-cA.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v2-BC-not-cA.pem | 17 + .../ee_int-v2-BC-not-cA.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v2-noBC.pem | 17 + .../test_cert_version/ee_int-v2-noBC.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v3-BC-cA.pem | 17 + .../test_cert_version/ee_int-v3-BC-cA.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v3-BC-not-cA.pem | 17 + .../ee_int-v3-BC-not-cA.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v3-noBC.pem | 17 + .../test_cert_version/ee_int-v3-noBC.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v4-BC-cA.pem | 17 + .../test_cert_version/ee_int-v4-BC-cA.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v4-BC-not-cA.pem | 17 + .../ee_int-v4-BC-not-cA.pem.certspec | 2 + .../unit/test_cert_version/ee_int-v4-noBC.pem | 17 + .../test_cert_version/ee_int-v4-noBC.pem.certspec | 2 + .../ssl/tests/unit/test_cert_version/generate.py | 93 + .../unit/test_cert_version/int-v1-BC-cA_ca.pem | 18 + .../test_cert_version/int-v1-BC-cA_ca.pem.certspec | 5 + .../unit/test_cert_version/int-v1-BC-not-cA_ca.pem | 18 + .../int-v1-BC-not-cA_ca.pem.certspec | 5 + .../unit/test_cert_version/int-v1-noBC_ca.pem | 17 + .../test_cert_version/int-v1-noBC_ca.pem.certspec | 4 + .../unit/test_cert_version/int-v2-BC-cA_ca.pem | 18 + .../test_cert_version/int-v2-BC-cA_ca.pem.certspec | 5 + .../unit/test_cert_version/int-v2-BC-not-cA_ca.pem | 18 + .../int-v2-BC-not-cA_ca.pem.certspec | 5 + .../unit/test_cert_version/int-v2-noBC_ca.pem | 17 + .../test_cert_version/int-v2-noBC_ca.pem.certspec | 4 + .../unit/test_cert_version/int-v3-BC-cA_ca.pem | 18 + .../test_cert_version/int-v3-BC-cA_ca.pem.certspec | 5 + .../unit/test_cert_version/int-v3-BC-not-cA_ca.pem | 18 + .../int-v3-BC-not-cA_ca.pem.certspec | 5 + .../unit/test_cert_version/int-v3-noBC_ca.pem | 17 + .../test_cert_version/int-v3-noBC_ca.pem.certspec | 4 + .../unit/test_cert_version/int-v4-BC-cA_ca.pem | 18 + .../test_cert_version/int-v4-BC-cA_ca.pem.certspec | 5 + .../unit/test_cert_version/int-v4-BC-not-cA_ca.pem | 18 + .../int-v4-BC-not-cA_ca.pem.certspec | 5 + .../unit/test_cert_version/int-v4-noBC_ca.pem | 17 + .../test_cert_version/int-v4-noBC_ca.pem.certspec | 4 + .../ssl/tests/unit/test_cert_version/moz.build | 61 + .../tests/unit/test_cert_version/ss-v1-BC-cA.pem | 17 + .../test_cert_version/ss-v1-BC-cA.pem.certspec | 4 + .../unit/test_cert_version/ss-v1-BC-not-cA.pem | 18 + .../test_cert_version/ss-v1-BC-not-cA.pem.certspec | 4 + .../tests/unit/test_cert_version/ss-v1-noBC.pem | 17 + .../unit/test_cert_version/ss-v1-noBC.pem.certspec | 3 + .../tests/unit/test_cert_version/ss-v2-BC-cA.pem | 18 + .../test_cert_version/ss-v2-BC-cA.pem.certspec | 4 + .../unit/test_cert_version/ss-v2-BC-not-cA.pem | 18 + .../test_cert_version/ss-v2-BC-not-cA.pem.certspec | 4 + .../tests/unit/test_cert_version/ss-v2-noBC.pem | 17 + .../unit/test_cert_version/ss-v2-noBC.pem.certspec | 3 + .../tests/unit/test_cert_version/ss-v3-BC-cA.pem | 18 + .../test_cert_version/ss-v3-BC-cA.pem.certspec | 4 + .../unit/test_cert_version/ss-v3-BC-not-cA.pem | 18 + .../test_cert_version/ss-v3-BC-not-cA.pem.certspec | 4 + .../tests/unit/test_cert_version/ss-v3-noBC.pem | 17 + .../unit/test_cert_version/ss-v3-noBC.pem.certspec | 3 + .../tests/unit/test_cert_version/ss-v4-BC-cA.pem | 18 + .../test_cert_version/ss-v4-BC-cA.pem.certspec | 4 + .../unit/test_cert_version/ss-v4-BC-not-cA.pem | 18 + .../test_cert_version/ss-v4-BC-not-cA.pem.certspec | 4 + .../tests/unit/test_cert_version/ss-v4-noBC.pem | 17 + .../unit/test_cert_version/ss-v4-noBC.pem.certspec | 3 + .../ssl/tests/unit/test_constructX509FromBase64.js | 90 + .../manager/ssl/tests/unit/test_content_signing.js | 435 + .../test_content_signing/content_signing_int.pem | 18 + .../content_signing_int.pem.certspec | 4 + .../content_signing_onecrl_RSA_ee.pem | 18 + .../content_signing_onecrl_RSA_ee.pem.certspec | 4 + .../content_signing_onecrl_ee.pem | 15 + .../content_signing_onecrl_ee.pem.certspec | 5 + .../content_signing_onecrl_ee_expired.pem | 15 + .../content_signing_onecrl_ee_expired.pem.certspec | 6 + .../content_signing_onecrl_ee_not_valid_yet.pem | 15 + ...nt_signing_onecrl_ee_not_valid_yet.pem.certspec | 6 + .../content_signing_onecrl_no_SAN_ee.pem | 14 + .../content_signing_onecrl_no_SAN_ee.pem.certspec | 4 + .../content_signing_onecrl_wrong_key_ee.pem | 14 + ...ontent_signing_onecrl_wrong_key_ee.pem.certspec | 5 + .../content_signing_remote_newtab_ee.pem | 15 + .../content_signing_remote_newtab_ee.pem.certspec | 5 + .../test_content_signing/content_signing_root.pem | 18 + .../content_signing_root.pem.certspec | 4 + .../ssl/tests/unit/test_content_signing/moz.build | 21 + .../ssl/tests/unit/test_content_signing/pysign.py | 35 + .../ssl/tests/unit/test_content_signing/test.txt | 1 + .../unit/test_content_signing/test.txt.signature | 1 + .../manager/ssl/tests/unit/test_crlite_filters.js | 697 + .../unit/test_crlite_filters/20201017-0-filter | Bin 0 -> 5770363 bytes .../test_crlite_filters/20201017-1-filter.stash | Bin 0 -> 36632 bytes .../test_crlite_filters/20201201-3-filter.stash | Bin 0 -> 57737 bytes .../ssl/tests/unit/test_crlite_filters/issuer.pem | 28 + .../unit/test_crlite_filters/no-sct-issuer.pem | 27 + .../ssl/tests/unit/test_crlite_filters/no-sct.pem | 33 + .../test_crlite_filters/revoked-in-stash-2.pem | 36 + .../unit/test_crlite_filters/revoked-in-stash.pem | 36 + .../ssl/tests/unit/test_crlite_filters/revoked.pem | 42 + .../ssl/tests/unit/test_crlite_filters/valid.pem | 39 + security/manager/ssl/tests/unit/test_ct.js | 75 + .../test_ct/ct-insufficient-scts.example.com.pem | 28 + .../ct-insufficient-scts.example.com.pem.certspec | 4 + .../tests/unit/test_ct/ct-valid.example.com.pem | 34 + .../unit/test_ct/ct-valid.example.com.pem.certspec | 4 + .../manager/ssl/tests/unit/test_ct/default-ee.key | 28 + .../ssl/tests/unit/test_ct/default-ee.key.keyspec | 1 + .../manager/ssl/tests/unit/test_ct/default-ee.pem | 21 + .../ssl/tests/unit/test_ct/default-ee.pem.certspec | 4 + security/manager/ssl/tests/unit/test_ct/moz.build | 23 + .../manager/ssl/tests/unit/test_ct/test-ca.pem | 18 + .../ssl/tests/unit/test_ct/test-ca.pem.certspec | 4 + .../ssl/tests/unit/test_db_format_pref_new.js | 22 + .../ssl/tests/unit/test_delegated_credentials.js | 91 + .../unit/test_delegated_credentials/default-ee.key | 5 + .../default-ee.key.keyspec | 1 + .../unit/test_delegated_credentials/default-ee.pem | 15 + .../default-ee.pem.certspec | 5 + .../test_delegated_credentials/delegated-ee.pem | 16 + .../delegated-ee.pem.certspec | 7 + .../unit/test_delegated_credentials/delegated.key | 6 + .../delegated.key.keyspec | 1 + .../unit/test_delegated_credentials/moz.build | 24 + .../unit/test_delegated_credentials/test-ca.pem | 18 + .../test-ca.pem.certspec | 4 + .../unit/test_delegated_credentials/test-int.pem | 19 + .../test-int.pem.certspec | 4 + security/manager/ssl/tests/unit/test_der.js | 380 + .../ssl/tests/unit/test_encrypted_client_hello.js | 93 + .../test_encrypted_client_hello/default-ee.key | 28 + .../default-ee.key.keyspec | 1 + .../test_encrypted_client_hello/default-ee.pem | 18 + .../default-ee.pem.certspec | 3 + .../unit/test_encrypted_client_hello/moz.build | 24 + .../test_encrypted_client_hello/private-ee.key | 28 + .../private-ee.key.keyspec | 1 + .../test_encrypted_client_hello/private-ee.pem | 18 + .../private-ee.pem.certspec | 3 + .../test_encrypted_client_hello/selfsigned.pem | 19 + .../selfsigned.pem.certspec | 3 + .../unit/test_encrypted_client_hello/test-ca.pem | 18 + .../test-ca.pem.certspec | 4 + .../test_encrypted_client_hello_client_only.js | 33 + .../ssl/tests/unit/test_enterprise_roots.js | 82 + security/manager/ssl/tests/unit/test_ev_certs.js | 437 + .../unit/test_ev_certs/anyPolicy-ee-path-ee.pem | 20 + .../anyPolicy-ee-path-ee.pem.certspec | 5 + .../unit/test_ev_certs/anyPolicy-ee-path-int.pem | 20 + .../anyPolicy-ee-path-int.pem.certspec | 7 + .../unit/test_ev_certs/anyPolicy-int-path-ee.pem | 21 + .../anyPolicy-int-path-ee.pem.certspec | 5 + .../unit/test_ev_certs/anyPolicy-int-path-int.pem | 20 + .../anyPolicy-int-path-int.pem.certspec | 7 + ...um-and-test-oid-ee-cabforum-oid-int-path-ee.pem | 23 + ...st-oid-ee-cabforum-oid-int-path-ee.pem.certspec | 5 + ...m-and-test-oid-ee-cabforum-oid-int-path-int.pem | 21 + ...t-oid-ee-cabforum-oid-int-path-int.pem.certspec | 7 + .../cabforum-and-test-oid-ee-path-ee.pem | 22 + .../cabforum-and-test-oid-ee-path-ee.pem.certspec | 5 + .../cabforum-and-test-oid-ee-path-int.pem | 21 + .../cabforum-and-test-oid-ee-path-int.pem.certspec | 7 + .../unit/test_ev_certs/cabforum-oid-path-ee.pem | 20 + .../cabforum-oid-path-ee.pem.certspec | 5 + .../unit/test_ev_certs/cabforum-oid-path-int.pem | 20 + .../cabforum-oid-path-int.pem.certspec | 7 + .../ssl/tests/unit/test_ev_certs/evroot.key | 28 + .../tests/unit/test_ev_certs/evroot.key.keyspec | 1 + .../ssl/tests/unit/test_ev_certs/evroot.pem | 18 + .../tests/unit/test_ev_certs/evroot.pem.certspec | 7 + .../manager/ssl/tests/unit/test_ev_certs/moz.build | 48 + .../unit/test_ev_certs/no-ocsp-ee-path-ee.pem | 19 + .../test_ev_certs/no-ocsp-ee-path-ee.pem.certspec | 4 + .../unit/test_ev_certs/no-ocsp-ee-path-int.pem | 20 + .../test_ev_certs/no-ocsp-ee-path-int.pem.certspec | 7 + .../unit/test_ev_certs/no-ocsp-int-path-ee.pem | 21 + .../test_ev_certs/no-ocsp-int-path-ee.pem.certspec | 5 + .../unit/test_ev_certs/no-ocsp-int-path-int.pem | 18 + .../no-ocsp-int-path-int.pem.certspec | 6 + .../unit/test_ev_certs/non-ev-root-path-ee.pem | 21 + .../test_ev_certs/non-ev-root-path-ee.pem.certspec | 5 + .../unit/test_ev_certs/non-ev-root-path-int.pem | 20 + .../non-ev-root-path-int.pem.certspec | 6 + .../ssl/tests/unit/test_ev_certs/non-evroot-ca.pem | 18 + .../unit/test_ev_certs/non-evroot-ca.pem.certspec | 4 + .../test_ev_certs/reverse-order-oids-path-ee.pem | 21 + .../reverse-order-oids-path-ee.pem.certspec | 5 + .../test_ev_certs/reverse-order-oids-path-int.pem | 21 + .../reverse-order-oids-path-int.pem.certspec | 7 + ...nd-cabforum-oid-ee-cabforum-oid-int-path-ee.pem | 23 + ...um-oid-ee-cabforum-oid-int-path-ee.pem.certspec | 5 + ...d-cabforum-oid-ee-cabforum-oid-int-path-int.pem | 21 + ...m-oid-ee-cabforum-oid-int-path-int.pem.certspec | 7 + .../test-and-cabforum-oid-ee-path-ee.pem | 22 + .../test-and-cabforum-oid-ee-path-ee.pem.certspec | 5 + .../test-and-cabforum-oid-ee-path-int.pem | 21 + .../test-and-cabforum-oid-ee-path-int.pem.certspec | 7 + .../test-oid-ee-cabforum-oid-int-path-ee.pem | 22 + ...st-oid-ee-cabforum-oid-int-path-ee.pem.certspec | 5 + .../test-oid-ee-cabforum-oid-int-path-int.pem | 21 + ...t-oid-ee-cabforum-oid-int-path-int.pem.certspec | 7 + .../tests/unit/test_ev_certs/test-oid-path-ee.pem | 20 + .../test_ev_certs/test-oid-path-ee.pem.certspec | 5 + .../tests/unit/test_ev_certs/test-oid-path-int.key | 28 + .../test_ev_certs/test-oid-path-int.key.keyspec | 1 + .../tests/unit/test_ev_certs/test-oid-path-int.pem | 20 + .../test_ev_certs/test-oid-path-int.pem.certspec | 7 + .../test_forget_about_site_security_headers.js | 205 + .../manager/ssl/tests/unit/test_hash_algorithms.js | 158 + .../ssl/tests/unit/test_hash_algorithms_wrap.js | 5 + security/manager/ssl/tests/unit/test_hmac.js | 157 + .../ssl/tests/unit/test_imminent_distrust.js | 39 + .../test_intermediate_basic_usage_constraints.js | 138 + .../ca.pem | 17 + .../ca.pem.certspec | 3 + .../ee-int-bad-ku-no-eku.pem | 18 + .../ee-int-bad-ku-no-eku.pem.certspec | 4 + .../ee-int-bad-ku-server-eku.pem | 18 + .../ee-int-bad-ku-server-eku.pem.certspec | 4 + .../ee-int-cA-FALSE-asserts-keyCertSign.pem | 19 + ...e-int-cA-FALSE-asserts-keyCertSign.pem.certspec | 4 + .../ee-int-limited-depth-invalid.pem | 18 + .../ee-int-limited-depth-invalid.pem.certspec | 4 + .../ee-int-limited-depth.pem | 18 + .../ee-int-limited-depth.pem.certspec | 4 + .../ee-int-no-extensions.pem | 18 + .../ee-int-no-extensions.pem.certspec | 4 + .../ee-int-no-ku-no-eku.pem | 18 + .../ee-int-no-ku-no-eku.pem.certspec | 4 + .../ee-int-no-ku-server-eku.pem | 18 + .../ee-int-no-ku-server-eku.pem.certspec | 4 + .../ee-int-not-a-ca.pem | 18 + .../ee-int-not-a-ca.pem.certspec | 4 + .../ee-int-valid-ku-no-eku.pem | 18 + .../ee-int-valid-ku-no-eku.pem.certspec | 4 + .../ee-int-valid-ku-server-eku.pem | 18 + .../ee-int-valid-ku-server-eku.pem.certspec | 4 + .../int-bad-ku-no-eku.pem | 18 + .../int-bad-ku-no-eku.pem.certspec | 4 + .../int-bad-ku-server-eku.pem | 18 + .../int-bad-ku-server-eku.pem.certspec | 5 + .../int-cA-FALSE-asserts-keyCertSign.pem | 18 + .../int-cA-FALSE-asserts-keyCertSign.pem.certspec | 4 + .../int-limited-depth-invalid.pem | 18 + .../int-limited-depth-invalid.pem.certspec | 3 + .../int-limited-depth.pem | 18 + .../int-limited-depth.pem.certspec | 3 + .../int-no-extensions.pem | 17 + .../int-no-extensions.pem.certspec | 2 + .../int-no-ku-no-eku.pem | 17 + .../int-no-ku-no-eku.pem.certspec | 3 + .../int-no-ku-server-eku.pem | 18 + .../int-no-ku-server-eku.pem.certspec | 4 + .../int-not-a-ca.pem | 17 + .../int-not-a-ca.pem.certspec | 3 + .../int-valid-ku-no-eku.pem | 18 + .../int-valid-ku-no-eku.pem.certspec | 4 + .../int-valid-ku-server-eku.pem | 19 + .../int-valid-ku-server-eku.pem.certspec | 5 + .../moz.build | 35 + .../ssl/tests/unit/test_intermediate_preloads.js | 645 + .../tests/unit/test_intermediate_preloads/ca.pem | 18 + .../test_intermediate_preloads/ca.pem.certspec | 5 + .../unit/test_intermediate_preloads/default-ee.key | 28 + .../default-ee.key.keyspec | 1 + .../unit/test_intermediate_preloads/default-ee.pem | 19 + .../default-ee.pem.certspec | 4 + .../tests/unit/test_intermediate_preloads/ee2.pem | 18 + .../test_intermediate_preloads/ee2.pem.certspec | 3 + .../tests/unit/test_intermediate_preloads/int.pem | 19 + .../test_intermediate_preloads/int.pem.certspec | 4 + .../tests/unit/test_intermediate_preloads/int2.pem | 19 + .../test_intermediate_preloads/int2.pem.certspec | 4 + .../unit/test_intermediate_preloads/moz.build | 24 + security/manager/ssl/tests/unit/test_keysize.js | 204 + .../ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem | 13 + ...sa_1016-int_rsa_1024-root_rsa_1024.pem.certspec | 4 + .../ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem | 13 + ...sa_1024-int_rsa_1016-root_rsa_1024.pem.certspec | 4 + .../ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem | 15 + ...sa_1024-int_rsa_1024-root_rsa_1016.pem.certspec | 4 + .../ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem | 13 + ...sa_1024-int_rsa_1024-root_rsa_1024.pem.certspec | 4 + ...cp224r1_224-int_secp256r1_256-root_rsa_2048.pem | 10 + ...24-int_secp256r1_256-root_rsa_2048.pem.certspec | 5 + ...r1_224-int_secp256r1_256-root_secp256r1_256.pem | 10 + ...t_secp256r1_256-root_secp256r1_256.pem.certspec | 5 + ...k1_256-int_secp256r1_256-root_secp256r1_256.pem | 10 + ...t_secp256r1_256-root_secp256r1_256.pem.certspec | 5 + ...cp256r1_256-int_rsa_1016-root_secp256r1_256.pem | 11 + ...56-int_rsa_1016-root_secp256r1_256.pem.certspec | 4 + ...r1_256-int_secp224r1_224-root_secp256r1_256.pem | 10 + ...t_secp224r1_224-root_secp256r1_256.pem.certspec | 5 + ...r1_256-int_secp256r1_256-root_secp224r1_224.pem | 10 + ...t_secp256r1_256-root_secp224r1_224.pem.certspec | 5 + ...r1_256-int_secp256r1_256-root_secp256k1_256.pem | 10 + ...t_secp256r1_256-root_secp256k1_256.pem.certspec | 5 + ...cp384r1_384-int_secp256r1_256-root_rsa_2048.pem | 11 + ...84-int_secp256r1_256-root_rsa_2048.pem.certspec | 5 + ...r1_521-int_secp384r1_384-root_secp256r1_256.pem | 12 + ...t_secp384r1_384-root_secp256r1_256.pem.certspec | 5 + .../test_keysize/int_rsa_1016-root_rsa_1024.pem | 13 + .../int_rsa_1016-root_rsa_1024.pem.certspec | 6 + .../int_rsa_1016-root_secp256r1_256.pem | 12 + .../int_rsa_1016-root_secp256r1_256.pem.certspec | 7 + .../test_keysize/int_rsa_1024-root_rsa_1016.pem | 13 + .../int_rsa_1024-root_rsa_1016.pem.certspec | 6 + .../test_keysize/int_rsa_1024-root_rsa_1024.pem | 13 + .../int_rsa_1024-root_rsa_1024.pem.certspec | 6 + .../int_secp224r1_224-root_secp256r1_256.pem | 10 + ...t_secp224r1_224-root_secp256r1_256.pem.certspec | 7 + .../int_secp256r1_256-root_rsa_2048.pem | 14 + .../int_secp256r1_256-root_rsa_2048.pem.certspec | 5 + .../int_secp256r1_256-root_secp224r1_224.pem | 10 + ...t_secp256r1_256-root_secp224r1_224.pem.certspec | 7 + .../int_secp256r1_256-root_secp256k1_256.pem | 10 + ...t_secp256r1_256-root_secp256k1_256.pem.certspec | 7 + .../int_secp256r1_256-root_secp256r1_256.pem | 10 + ...t_secp256r1_256-root_secp256r1_256.pem.certspec | 7 + .../int_secp384r1_384-root_secp256r1_256.pem | 11 + ...t_secp384r1_384-root_secp256r1_256.pem.certspec | 7 + .../manager/ssl/tests/unit/test_keysize/moz.build | 41 + .../ssl/tests/unit/test_keysize/root_rsa_1016.pem | 12 + .../unit/test_keysize/root_rsa_1016.pem.certspec | 6 + .../ssl/tests/unit/test_keysize/root_rsa_1024.pem | 12 + .../unit/test_keysize/root_rsa_1024.pem.certspec | 6 + .../ssl/tests/unit/test_keysize/root_rsa_2048.pem | 18 + .../unit/test_keysize/root_rsa_2048.pem.certspec | 4 + .../tests/unit/test_keysize/root_secp224r1_224.pem | 9 + .../test_keysize/root_secp224r1_224.pem.certspec | 7 + .../tests/unit/test_keysize/root_secp256k1_256.pem | 10 + .../test_keysize/root_secp256k1_256.pem.certspec | 7 + .../tests/unit/test_keysize/root_secp256r1_256.pem | 10 + .../test_keysize/root_secp256r1_256.pem.certspec | 7 + security/manager/ssl/tests/unit/test_keysize_ev.js | 171 + .../ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem | 21 + ...ee_rsa_2040-ev_int_rsa_2048-evroot.pem.certspec | 5 + .../ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem | 21 + ...ee_rsa_2048-ev_int_rsa_2040-evroot.pem.certspec | 5 + ...e_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem | 21 + ...8-ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec | 4 + .../ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem | 21 + ...ee_rsa_2048-ev_int_rsa_2048-evroot.pem.certspec | 4 + .../test_keysize_ev/ev_int_rsa_2040-evroot.pem | 20 + .../ev_int_rsa_2040-evroot.pem.certspec | 8 + .../tests/unit/test_keysize_ev/ev_int_rsa_2040.key | 28 + .../test_keysize_ev/ev_int_rsa_2040.key.keyspec | 1 + .../ev_int_rsa_2048-ev_root_rsa_2040.pem | 21 + .../ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec | 7 + .../test_keysize_ev/ev_int_rsa_2048-evroot.pem | 20 + .../ev_int_rsa_2048-evroot.pem.certspec | 7 + .../tests/unit/test_keysize_ev/ev_int_rsa_2048.key | 28 + .../test_keysize_ev/ev_int_rsa_2048.key.keyspec | 1 + .../unit/test_keysize_ev/ev_root_rsa_2040.key | 28 + .../test_keysize_ev/ev_root_rsa_2040.key.keyspec | 1 + .../unit/test_keysize_ev/ev_root_rsa_2040.pem | 18 + .../test_keysize_ev/ev_root_rsa_2040.pem.certspec | 7 + .../ssl/tests/unit/test_keysize_ev/evroot.key | 28 + .../tests/unit/test_keysize_ev/evroot.key.keyspec | 1 + .../ssl/tests/unit/test_keysize_ev/evroot.pem | 18 + .../tests/unit/test_keysize_ev/evroot.pem.certspec | 7 + .../ssl/tests/unit/test_keysize_ev/moz.build | 31 + security/manager/ssl/tests/unit/test_local_cert.js | 87 + .../ssl/tests/unit/test_logoutAndTeardown.js | 207 + .../ssl/tests/unit/test_missing_intermediate.js | 95 + .../missing-intermediate.pem | 18 + .../missing-intermediate.pem.certspec | 4 + .../tests/unit/test_missing_intermediate/moz.build | 19 + .../ssl/tests/unit/test_name_constraints.js | 71 + .../NameConstraints.dcissallowed.pem | 20 + .../NameConstraints.dcissallowed.pem.certspec | 2 + .../NameConstraints.dcissblocked.pem | 20 + .../NameConstraints.dcissblocked.pem.certspec | 2 + .../ca-example-com-permitted.pem | 19 + .../ca-example-com-permitted.pem.certspec | 5 + .../ssl/tests/unit/test_name_constraints/dciss.pem | 22 + .../unit/test_name_constraints/dciss.pem.certspec | 4 + .../ee-example-com-and-org.pem | 19 + .../ee-example-com-and-org.pem.certspec | 3 + .../unit/test_name_constraints/ee-example-com.pem | 18 + .../ee-example-com.pem.certspec | 3 + .../unit/test_name_constraints/ee-example-org.pem | 18 + .../ee-example-org.pem.certspec | 3 + .../unit/test_name_constraints/ee-example-test.pem | 18 + .../ee-example-test.pem.certspec | 3 + .../int-example-org-permitted.pem | 19 + .../int-example-org-permitted.pem.certspec | 5 + .../ssl/tests/unit/test_name_constraints/moz.build | 21 + .../manager/ssl/tests/unit/test_nonascii_path.js | 62 + security/manager/ssl/tests/unit/test_nsCertType.js | 32 + .../ssl/tests/unit/test_nsIX509CertValidity.js | 70 + .../ssl/tests/unit/test_nsIX509Cert_utf8.js | 96 + .../manager/ssl/tests/unit/test_nss_shutdown.js | 48 + .../manager/ssl/tests/unit/test_ocsp_caching.js | 406 + .../ssl/tests/unit/test_ocsp_enabled_pref.js | 150 + .../ssl/tests/unit/test_ocsp_must_staple.js | 160 + .../ssl/tests/unit/test_ocsp_no_hsts_upgrade.js | 68 + .../ssl/tests/unit/test_ocsp_private_caching.js | 138 + .../manager/ssl/tests/unit/test_ocsp_required.js | 74 + .../manager/ssl/tests/unit/test_ocsp_stapling.js | 393 + .../ssl/tests/unit/test_ocsp_stapling_expired.js | 319 + .../unit/test_ocsp_stapling_with_intermediate.js | 48 + .../manager/ssl/tests/unit/test_ocsp_timeout.js | 100 + security/manager/ssl/tests/unit/test_ocsp_url.js | 122 + .../ssl/tests/unit/test_ocsp_url/bad-scheme.pem | 18 + .../unit/test_ocsp_url/bad-scheme.pem.certspec | 3 + .../manager/ssl/tests/unit/test_ocsp_url/ca.pem | 17 + .../ssl/tests/unit/test_ocsp_url/ca.pem.certspec | 4 + .../tests/unit/test_ocsp_url/empty-scheme-url.pem | 18 + .../test_ocsp_url/empty-scheme-url.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/ftp-url.pem | 18 + .../tests/unit/test_ocsp_url/ftp-url.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/hTTp-url.pem | 18 + .../tests/unit/test_ocsp_url/hTTp-url.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/https-url.pem | 18 + .../unit/test_ocsp_url/https-url.pem.certspec | 3 + .../manager/ssl/tests/unit/test_ocsp_url/int.key | 28 + .../ssl/tests/unit/test_ocsp_url/int.key.keyspec | 1 + .../manager/ssl/tests/unit/test_ocsp_url/int.pem | 17 + .../ssl/tests/unit/test_ocsp_url/int.pem.certspec | 4 + .../manager/ssl/tests/unit/test_ocsp_url/moz.build | 33 + .../ssl/tests/unit/test_ocsp_url/negative-port.pem | 18 + .../unit/test_ocsp_url/negative-port.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/no-host-url.pem | 18 + .../unit/test_ocsp_url/no-host-url.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/no-path-url.pem | 18 + .../unit/test_ocsp_url/no-path-url.pem.certspec | 3 + .../unit/test_ocsp_url/no-scheme-host-port.pem | 18 + .../test_ocsp_url/no-scheme-host-port.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/no-scheme-url.pem | 18 + .../unit/test_ocsp_url/no-scheme-url.pem.certspec | 3 + .../tests/unit/test_ocsp_url/unknown-scheme.pem | 18 + .../unit/test_ocsp_url/unknown-scheme.pem.certspec | 3 + .../ssl/tests/unit/test_ocsp_url/user-pass.pem | 18 + .../unit/test_ocsp_url/user-pass.pem.certspec | 3 + ...ther-ee-revoked-by-revocations-txt-serial-2.pem | 17 + ...evoked-by-revocations-txt-serial-2.pem.certspec | 3 + .../another-ee-revoked-by-revocations-txt.pem | 17 + ...ther-ee-revoked-by-revocations-txt.pem.certspec | 3 + .../test_onecrl/ee-revoked-by-revocations-txt.pem | 17 + .../ee-revoked-by-revocations-txt.pem.certspec | 3 + .../ee-revoked-by-subject-and-pubkey.pem | 18 + .../ee-revoked-by-subject-and-pubkey.pem.certspec | 2 + .../manager/ssl/tests/unit/test_onecrl/moz.build | 18 + .../ssl/tests/unit/test_onecrl/same-issuer-ee.pem | 19 + .../unit/test_onecrl/same-issuer-ee.pem.certspec | 4 + .../tests/unit/test_onecrl/sample_revocations.txt | 41 + .../ssl/tests/unit/test_onecrl/test-int-ee.pem | 18 + .../unit/test_onecrl/test-int-ee.pem.certspec | 3 + .../ssl/tests/unit/test_osclientcerts_module.js | 63 + security/manager/ssl/tests/unit/test_oskeystore.js | 413 + .../ssl/tests/unit/test_osreauthenticator.js | 27 + .../manager/ssl/tests/unit/test_password_prompt.js | 87 + security/manager/ssl/tests/unit/test_pinning.js | 319 + .../manager/ssl/tests/unit/test_pkcs11_module.js | 58 + .../manager/ssl/tests/unit/test_pkcs11_moduleDB.js | 50 + .../ssl/tests/unit/test_pkcs11_safe_mode.js | 61 + .../manager/ssl/tests/unit/test_pkcs11_slot.js | 135 + .../manager/ssl/tests/unit/test_pkcs11_token.js | 149 + .../manager/ssl/tests/unit/test_pkcs11_tokenDB.js | 20 + .../apple-ist-ca-8-g1-intermediate.pem | 20 + .../ssl/tests/unit/test_sanctions/default-ee.key | 28 + .../unit/test_sanctions/default-ee.key.keyspec | 1 + .../ssl/tests/unit/test_sanctions/default-ee.pem | 21 + .../unit/test_sanctions/default-ee.pem.certspec | 4 + .../test_sanctions/gspe72-4-ssl-ls-apple-com.pem | 38 + .../ssl/tests/unit/test_sanctions/moz.build | 21 + .../symantec-ee-from-allowlist-after-cutoff.pem | 20 + ...tec-ee-from-allowlist-after-cutoff.pem.certspec | 4 + .../symantec-ee-from-allowlist-before-cutoff.pem | 20 + ...ec-ee-from-allowlist-before-cutoff.pem.certspec | 4 + .../symantec-ee-not-allowlisted-after-cutoff.pem | 20 + ...ec-ee-not-allowlisted-after-cutoff.pem.certspec | 4 + .../symantec-ee-not-allowlisted-before-cutoff.pem | 20 + ...c-ee-not-allowlisted-before-cutoff.pem.certspec | 4 + .../symantec-intermediate-allowlisted.pem | 22 + .../symantec-intermediate-allowlisted.pem.certspec | 5 + .../symantec-intermediate-other-crossigned.pem | 19 + ...ntec-intermediate-other-crossigned.pem.certspec | 5 + .../test_sanctions/symantec-intermediate-other.pem | 22 + .../symantec-intermediate-other.pem.certspec | 5 + .../tests/unit/test_sanctions/symantec-test-ca.pem | 23 + .../test_sanctions/symantec-test-ca.pem.certspec | 5 + .../unit/test_sanctions_symantec_apple_google.js | 107 + security/manager/ssl/tests/unit/test_sdr.js | 272 + .../manager/ssl/tests/unit/test_sdr_preexisting.js | 79 + .../ssl/tests/unit/test_sdr_preexisting/key4.db | Bin 0 -> 36864 bytes .../unit/test_sdr_preexisting_with_password.js | 138 + .../test_sdr_preexisting_with_password/key4.db | Bin 0 -> 36864 bytes .../ssl/tests/unit/test_self_signed_certs.js | 69 + .../ssl/tests/unit/test_self_signed_certs/cert9.db | Bin 0 -> 45056 bytes .../ssl/tests/unit/test_session_resumption.js | 298 + .../manager/ssl/tests/unit/test_signed_apps.js | 1013 + .../ssl/tests/unit/test_signed_apps/app/README | 1 + .../tests/unit/test_signed_apps/app/data/image.png | Bin 0 -> 534 bytes .../tests/unit/test_signed_apps/app/manifest.json | 5 + .../app_cose_tampered/META-INF/cose.manifest | 10 + .../app_cose_tampered/META-INF/cose.sig | Bin 0 -> 655 bytes .../unit/test_signed_apps/app_cose_tampered/README | 2 + .../app_cose_tampered/data/image.png | Bin 0 -> 534 bytes .../app_cose_tampered/manifest.json | 5 + .../app_mf-1-256_sf-1-256_p7-1-256.zip | Bin 0 -> 2678 bytes .../app_mf-1-256_sf-1-256_p7-1.zip | Bin 0 -> 2341 bytes .../app_mf-1-256_sf-1-256_p7-256.zip | Bin 0 -> 2362 bytes .../app_mf-1-256_sf-1_p7-1-256.zip | Bin 0 -> 2625 bytes .../test_signed_apps/app_mf-1-256_sf-1_p7-1.zip | Bin 0 -> 2289 bytes .../test_signed_apps/app_mf-1-256_sf-1_p7-256.zip | Bin 0 -> 2309 bytes .../app_mf-1-256_sf-256_p7-1-256.zip | Bin 0 -> 2643 bytes .../test_signed_apps/app_mf-1-256_sf-256_p7-1.zip | Bin 0 -> 2307 bytes .../app_mf-1-256_sf-256_p7-256.zip | Bin 0 -> 2327 bytes .../app_mf-1_sf-1-256_p7-1-256.zip | Bin 0 -> 2563 bytes .../test_signed_apps/app_mf-1_sf-1-256_p7-1.zip | Bin 0 -> 2226 bytes .../test_signed_apps/app_mf-1_sf-1-256_p7-256.zip | Bin 0 -> 2247 bytes .../test_signed_apps/app_mf-1_sf-1_p7-1-256.zip | Bin 0 -> 2513 bytes .../unit/test_signed_apps/app_mf-1_sf-1_p7-1.zip | Bin 0 -> 2174 bytes .../unit/test_signed_apps/app_mf-1_sf-1_p7-256.zip | Bin 0 -> 2196 bytes .../test_signed_apps/app_mf-1_sf-256_p7-1-256.zip | Bin 0 -> 2526 bytes .../unit/test_signed_apps/app_mf-1_sf-256_p7-1.zip | Bin 0 -> 2192 bytes .../test_signed_apps/app_mf-1_sf-256_p7-256.zip | Bin 0 -> 2210 bytes .../app_mf-256_sf-1-256_p7-1-256.zip | Bin 0 -> 2601 bytes .../test_signed_apps/app_mf-256_sf-1-256_p7-1.zip | Bin 0 -> 2264 bytes .../app_mf-256_sf-1-256_p7-256.zip | Bin 0 -> 2287 bytes .../test_signed_apps/app_mf-256_sf-1_p7-1-256.zip | Bin 0 -> 2549 bytes .../unit/test_signed_apps/app_mf-256_sf-1_p7-1.zip | Bin 0 -> 2213 bytes .../test_signed_apps/app_mf-256_sf-1_p7-256.zip | Bin 0 -> 2234 bytes .../app_mf-256_sf-256_p7-1-256.zip | Bin 0 -> 2568 bytes .../test_signed_apps/app_mf-256_sf-256_p7-1.zip | Bin 0 -> 2232 bytes .../test_signed_apps/app_mf-256_sf-256_p7-256.zip | Bin 0 -> 2251 bytes ...48-prod-tomato-clock-PKCS7-SHA1-ES256-ES384.zip | Bin 0 -> 459148 bytes ...48-prod-tomato-clock-PKCS7-SHA1-ES256-PS256.zip | Bin 0 -> 459984 bytes ...714ba248-prod-tomato-clock-PKCS7-SHA1-ES256.zip | Bin 0 -> 458382 bytes ...714ba248-prod-tomato-clock-PKCS7-SHA1-PS256.zip | Bin 0 -> 459272 bytes ...8-stage-tomato-clock-PKCS7-SHA1-ES256-ES384.zip | Bin 0 -> 459192 bytes ...8-stage-tomato-clock-PKCS7-SHA1-ES256-PS256.zip | Bin 0 -> 460028 bytes ...14ba248-stage-tomato-clock-PKCS7-SHA1-ES256.zip | Bin 0 -> 458426 bytes ...14ba248-stage-tomato-clock-PKCS7-SHA1-PS256.zip | Bin 0 -> 459315 bytes .../tests/unit/test_signed_apps/big_manifest.zip | Bin 0 -> 8107 bytes .../tests/unit/test_signed_apps/bug_1411458.zip | Bin 0 -> 2698 bytes .../cose_int_signed_with_pkcs7.zip | Bin 0 -> 4051 bytes .../cose_multiple_signed_with_pkcs7.zip | Bin 0 -> 3945 bytes .../test_signed_apps/cose_signed_with_pkcs7.zip | Bin 0 -> 3401 bytes .../test_signed_apps/cose_tampered_good_pkcs7.zip | Bin 0 -> 3379 bytes .../unit/test_signed_apps/empty_signerInfos.zip | Bin 0 -> 1892 bytes .../tests/unit/test_signed_apps/huge_manifest.zip | Bin 0 -> 31397 bytes .../ssl/tests/unit/test_signed_apps/moz.build | 72 + .../test_signed_apps/only_cose_multiple_signed.zip | Bin 0 -> 2109 bytes .../unit/test_signed_apps/only_cose_signed.zip | Bin 0 -> 1565 bytes .../unit/test_signed_apps/unknown_issuer_app.zip | Bin 0 -> 2255 bytes .../tests/unit/test_signed_apps/unsigned_app.zip | Bin 0 -> 510 bytes .../unit/test_signed_apps/xpcshellTestRoot.der | Bin 0 -> 794 bytes .../test_signed_apps/xpcshellTestRoot.pem.certspec | 6 + security/manager/ssl/tests/unit/test_ssl_status.js | 76 + .../manager/ssl/tests/unit/test_sss_enumerate.js | 101 + .../manager/ssl/tests/unit/test_sss_eviction.js | 100 + .../ssl/tests/unit/test_sss_originAttributes.js | 179 + .../manager/ssl/tests/unit/test_sss_readstate.js | 161 + .../ssl/tests/unit/test_sss_readstate_child.js | 40 + .../ssl/tests/unit/test_sss_readstate_empty.js | 56 + .../ssl/tests/unit/test_sss_readstate_garbage.js | 110 + .../ssl/tests/unit/test_sss_readstate_huge.js | 98 + .../manager/ssl/tests/unit/test_sss_resetState.js | 113 + .../ssl/tests/unit/test_sss_sanitizeOnShutdown.js | 72 + .../manager/ssl/tests/unit/test_sss_savestate.js | 122 + .../manager/ssl/tests/unit/test_startcom_wosign.js | 67 + .../test_startcom_wosign/StartCom-after-cutoff.pem | 19 + .../StartCom-after-cutoff.pem.certspec | 4 + .../StartCom-before-cutoff.pem | 19 + .../StartCom-before-cutoff.pem.certspec | 4 + .../tests/unit/test_startcom_wosign/StartComCA.pem | 19 + .../test_startcom_wosign/StartComCA.pem.certspec | 5 + .../test_startcom_wosign/WoSign-after-cutoff.pem | 19 + .../WoSign-after-cutoff.pem.certspec | 4 + .../test_startcom_wosign/WoSign-before-cutoff.pem | 19 + .../WoSign-before-cutoff.pem.certspec | 4 + .../tests/unit/test_startcom_wosign/WoSignCA.pem | 19 + .../test_startcom_wosign/WoSignCA.pem.certspec | 5 + .../ssl/tests/unit/test_startcom_wosign/ca.pem | 17 + .../unit/test_startcom_wosign/ca.pem.certspec | 5 + .../ssl/tests/unit/test_startcom_wosign/moz.build | 19 + security/manager/ssl/tests/unit/test_sts_fqdn.js | 50 + .../manager/ssl/tests/unit/test_sts_ipv4_ipv6.js | 59 + security/manager/ssl/tests/unit/test_sts_parser.js | 146 + .../ssl/tests/unit/test_sts_preload_dynamic.js | 86 + .../tests/unit/test_sts_preloadlist_perwindowpb.js | 455 + .../unit/test_sts_preloadlist_selfdestruct.js | 22 + security/manager/ssl/tests/unit/test_validity.js | 108 + .../ev_ee_27_months-ev_int_60_months-evroot.pem | 21 + ..._27_months-ev_int_60_months-evroot.pem.certspec | 5 + .../ev_ee_28_months-ev_int_60_months-evroot.pem | 21 + ..._28_months-ev_int_60_months-evroot.pem.certspec | 5 + .../unit/test_validity/ev_int_60_months-evroot.key | 28 + .../ev_int_60_months-evroot.key.keyspec | 1 + .../unit/test_validity/ev_int_60_months-evroot.pem | 20 + .../ev_int_60_months-evroot.pem.certspec | 8 + .../ssl/tests/unit/test_validity/evroot.key | 28 + .../tests/unit/test_validity/evroot.key.keyspec | 1 + .../ssl/tests/unit/test_validity/evroot.pem | 18 + .../tests/unit/test_validity/evroot.pem.certspec | 7 + .../manager/ssl/tests/unit/test_validity/moz.build | 24 + security/manager/ssl/tests/unit/test_x509.js | 142 + .../unit/tlsserver/cmd/BadCertAndPinningServer.cpp | 140 + .../tlsserver/cmd/DelegatedCredentialsServer.cpp | 142 + .../tlsserver/cmd/EncryptedClientHelloServer.cpp | 143 + .../unit/tlsserver/cmd/GenerateOCSPResponse.cpp | 168 + .../unit/tlsserver/cmd/OCSPStaplingServer.cpp | 153 + .../unit/tlsserver/cmd/SanctionsTestServer.cpp | 87 + .../manager/ssl/tests/unit/tlsserver/cmd/moz.build | 30 + .../ssl/tests/unit/tlsserver/default-ee.der | 3 + .../ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp | 204 + .../ssl/tests/unit/tlsserver/lib/OCSPCommon.h | 66 + .../ssl/tests/unit/tlsserver/lib/TLSServer.cpp | 669 + .../ssl/tests/unit/tlsserver/lib/TLSServer.h | 93 + .../manager/ssl/tests/unit/tlsserver/lib/moz.build | 16 + .../manager/ssl/tests/unit/tlsserver/moz.build | 8 + .../manager/ssl/tests/unit/xpcshell-smartcards.ini | 15 + security/manager/ssl/tests/unit/xpcshell.ini | 237 + 1336 files changed, 196215 insertions(+) create mode 100644 security/manager/ssl/CSTrustDomain.cpp create mode 100644 security/manager/ssl/CSTrustDomain.h create mode 100644 security/manager/ssl/CommonSocketControl.cpp create mode 100644 security/manager/ssl/CommonSocketControl.h create mode 100644 security/manager/ssl/ContentSignatureVerifier.cpp create mode 100644 security/manager/ssl/ContentSignatureVerifier.h create mode 100644 security/manager/ssl/CredentialManagerSecret.cpp create mode 100644 security/manager/ssl/CredentialManagerSecret.h create mode 100644 security/manager/ssl/CryptoTask.cpp create mode 100644 security/manager/ssl/CryptoTask.h create mode 100644 security/manager/ssl/DER.jsm create mode 100644 security/manager/ssl/DataStorage.cpp create mode 100644 security/manager/ssl/DataStorage.h create mode 100644 security/manager/ssl/DataStorageIPCUtils.h create mode 100644 security/manager/ssl/DataStorageList.h create mode 100644 security/manager/ssl/EnterpriseRoots.cpp create mode 100644 security/manager/ssl/EnterpriseRoots.h create mode 100644 security/manager/ssl/KeychainSecret.cpp create mode 100644 security/manager/ssl/KeychainSecret.h create mode 100644 security/manager/ssl/LibSecret.cpp create mode 100644 security/manager/ssl/LibSecret.h create mode 100644 security/manager/ssl/LocalCertService.cpp create mode 100644 security/manager/ssl/LocalCertService.h create mode 100644 security/manager/ssl/NSSErrorsService.cpp create mode 100644 security/manager/ssl/NSSErrorsService.h create mode 100644 security/manager/ssl/NSSKeyStore.cpp create mode 100644 security/manager/ssl/NSSKeyStore.h create mode 100644 security/manager/ssl/OSKeyStore.cpp create mode 100644 security/manager/ssl/OSKeyStore.h create mode 100644 security/manager/ssl/OSReauthenticator.cpp create mode 100644 security/manager/ssl/OSReauthenticator.h create mode 100644 security/manager/ssl/OSReauthenticatorDarwin.mm create mode 100644 security/manager/ssl/PKCS11ModuleDB.cpp create mode 100644 security/manager/ssl/PKCS11ModuleDB.h create mode 100644 security/manager/ssl/PSMIPCCommon.cpp create mode 100644 security/manager/ssl/PSMIPCCommon.h create mode 100644 security/manager/ssl/PSMIPCTypes.ipdlh create mode 100644 security/manager/ssl/PSMRunnable.cpp create mode 100644 security/manager/ssl/PSMRunnable.h create mode 100644 security/manager/ssl/PVerifySSLServerCert.ipdl create mode 100644 security/manager/ssl/PublicKeyPinningService.cpp create mode 100644 security/manager/ssl/PublicKeyPinningService.h create mode 100644 security/manager/ssl/PublicSSL.h create mode 100644 security/manager/ssl/RemoteSecuritySettings.jsm create mode 100644 security/manager/ssl/RootCertificateTelemetryUtils.cpp create mode 100644 security/manager/ssl/RootCertificateTelemetryUtils.h create mode 100644 security/manager/ssl/RootHashes.inc create mode 100644 security/manager/ssl/SSLServerCertVerification.cpp create mode 100644 security/manager/ssl/SSLServerCertVerification.h create mode 100644 security/manager/ssl/ScopedNSSTypes.h create mode 100644 security/manager/ssl/SecretDecoderRing.cpp create mode 100644 security/manager/ssl/SecretDecoderRing.h create mode 100644 security/manager/ssl/SharedCertVerifier.h create mode 100644 security/manager/ssl/SharedSSLState.cpp create mode 100644 security/manager/ssl/SharedSSLState.h create mode 100644 security/manager/ssl/StaticHPKPins.errors create mode 100644 security/manager/ssl/StaticHPKPins.h create mode 100644 security/manager/ssl/TransportSecurityInfo.cpp create mode 100644 security/manager/ssl/TransportSecurityInfo.h create mode 100644 security/manager/ssl/VerifySSLServerCertChild.cpp create mode 100644 security/manager/ssl/VerifySSLServerCertChild.h create mode 100644 security/manager/ssl/VerifySSLServerCertParent.cpp create mode 100644 security/manager/ssl/VerifySSLServerCertParent.h create mode 100644 security/manager/ssl/X509.jsm create mode 100644 security/manager/ssl/X509CertValidity.cpp create mode 100644 security/manager/ssl/X509CertValidity.h create mode 100644 security/manager/ssl/cert_storage/Cargo.toml create mode 100644 security/manager/ssl/cert_storage/src/cert_storage.h create mode 100644 security/manager/ssl/cert_storage/src/lib.rs create mode 100644 security/manager/ssl/components.conf create mode 100644 security/manager/ssl/crashtests/398665-1.html create mode 100644 security/manager/ssl/crashtests/crashtests.list create mode 100644 security/manager/ssl/md4.c create mode 100644 security/manager/ssl/md4.h create mode 100644 security/manager/ssl/moz.build create mode 100644 security/manager/ssl/nsCertOverrideService.cpp create mode 100644 security/manager/ssl/nsCertOverrideService.h create mode 100644 security/manager/ssl/nsCertTree.cpp create mode 100644 security/manager/ssl/nsCertTree.h create mode 100644 security/manager/ssl/nsClientAuthRemember.cpp create mode 100644 security/manager/ssl/nsClientAuthRemember.h create mode 100644 security/manager/ssl/nsCryptoHash.cpp create mode 100644 security/manager/ssl/nsCryptoHash.h create mode 100644 security/manager/ssl/nsICertOverrideService.idl create mode 100644 security/manager/ssl/nsICertStorage.idl create mode 100644 security/manager/ssl/nsICertTree.idl create mode 100644 security/manager/ssl/nsICertificateDialogs.idl create mode 100644 security/manager/ssl/nsIClientAuthDialogs.idl create mode 100644 security/manager/ssl/nsIClientAuthRememberService.idl create mode 100644 security/manager/ssl/nsIContentSignatureVerifier.idl create mode 100644 security/manager/ssl/nsICryptoHMAC.idl create mode 100644 security/manager/ssl/nsICryptoHash.idl create mode 100644 security/manager/ssl/nsIKeyModule.idl create mode 100644 security/manager/ssl/nsILocalCertService.idl create mode 100644 security/manager/ssl/nsINSSComponent.idl create mode 100644 security/manager/ssl/nsINSSErrorsService.idl create mode 100644 security/manager/ssl/nsINSSVersion.idl create mode 100644 security/manager/ssl/nsIOSKeyStore.idl create mode 100644 security/manager/ssl/nsIOSReauthenticator.idl create mode 100644 security/manager/ssl/nsIPK11Token.idl create mode 100644 security/manager/ssl/nsIPK11TokenDB.idl create mode 100644 security/manager/ssl/nsIPKCS11Module.idl create mode 100644 security/manager/ssl/nsIPKCS11ModuleDB.idl create mode 100644 security/manager/ssl/nsIPKCS11Slot.idl create mode 100644 security/manager/ssl/nsIProtectedAuthThread.idl create mode 100644 security/manager/ssl/nsISecretDecoderRing.idl create mode 100644 security/manager/ssl/nsISecurityUITelemetry.idl create mode 100644 security/manager/ssl/nsISiteSecurityService.idl create mode 100644 security/manager/ssl/nsITokenDialogs.idl create mode 100644 security/manager/ssl/nsITokenPasswordDialogs.idl create mode 100644 security/manager/ssl/nsIX509Cert.idl create mode 100644 security/manager/ssl/nsIX509CertDB.idl create mode 100644 security/manager/ssl/nsIX509CertValidity.idl create mode 100644 security/manager/ssl/nsKeyModule.cpp create mode 100644 security/manager/ssl/nsKeyModule.h create mode 100644 security/manager/ssl/nsNSSCallbacks.cpp create mode 100644 security/manager/ssl/nsNSSCallbacks.h create mode 100644 security/manager/ssl/nsNSSCertHelper.cpp create mode 100644 security/manager/ssl/nsNSSCertHelper.h create mode 100644 security/manager/ssl/nsNSSCertTrust.cpp create mode 100644 security/manager/ssl/nsNSSCertTrust.h create mode 100644 security/manager/ssl/nsNSSCertificate.cpp create mode 100644 security/manager/ssl/nsNSSCertificate.h create mode 100644 security/manager/ssl/nsNSSCertificateDB.cpp create mode 100644 security/manager/ssl/nsNSSCertificateDB.h create mode 100644 security/manager/ssl/nsNSSComponent.cpp create mode 100644 security/manager/ssl/nsNSSComponent.h create mode 100644 security/manager/ssl/nsNSSHelper.h create mode 100644 security/manager/ssl/nsNSSIOLayer.cpp create mode 100644 security/manager/ssl/nsNSSIOLayer.h create mode 100644 security/manager/ssl/nsNSSModule.cpp create mode 100644 security/manager/ssl/nsNSSModule.h create mode 100644 security/manager/ssl/nsNSSVersion.cpp create mode 100644 security/manager/ssl/nsNSSVersion.h create mode 100644 security/manager/ssl/nsNTLMAuthModule.cpp create mode 100644 security/manager/ssl/nsNTLMAuthModule.h create mode 100644 security/manager/ssl/nsPK11TokenDB.cpp create mode 100644 security/manager/ssl/nsPK11TokenDB.h create mode 100644 security/manager/ssl/nsPKCS11Slot.cpp create mode 100644 security/manager/ssl/nsPKCS11Slot.h create mode 100644 security/manager/ssl/nsPKCS12Blob.cpp create mode 100644 security/manager/ssl/nsPKCS12Blob.h create mode 100644 security/manager/ssl/nsProtectedAuthThread.cpp create mode 100644 security/manager/ssl/nsProtectedAuthThread.h create mode 100644 security/manager/ssl/nsRandomGenerator.cpp create mode 100644 security/manager/ssl/nsRandomGenerator.h create mode 100644 security/manager/ssl/nsSSLSocketProvider.cpp create mode 100644 security/manager/ssl/nsSSLSocketProvider.h create mode 100644 security/manager/ssl/nsSTSPreloadList.inc create mode 100644 security/manager/ssl/nsSecureBrowserUI.cpp create mode 100644 security/manager/ssl/nsSecureBrowserUI.h create mode 100644 security/manager/ssl/nsSecurityHeaderParser.cpp create mode 100644 security/manager/ssl/nsSecurityHeaderParser.h create mode 100644 security/manager/ssl/nsSiteSecurityService.cpp create mode 100644 security/manager/ssl/nsSiteSecurityService.h create mode 100644 security/manager/ssl/nsTLSSocketProvider.cpp create mode 100644 security/manager/ssl/nsTLSSocketProvider.h create mode 100644 security/manager/ssl/nsVerificationJob.h create mode 100644 security/manager/ssl/osclientcerts/Cargo.toml create mode 100644 security/manager/ssl/osclientcerts/dynamic-library/moz.build create mode 100644 security/manager/ssl/osclientcerts/dynamic-library/osclientcerts.symbols create mode 100644 security/manager/ssl/osclientcerts/dynamic-library/stub.cpp create mode 100644 security/manager/ssl/osclientcerts/moz.build create mode 100644 security/manager/ssl/osclientcerts/src/backend_macos.rs create mode 100644 security/manager/ssl/osclientcerts/src/backend_windows.rs create mode 100644 security/manager/ssl/osclientcerts/src/bindings_macos.rs create mode 100644 security/manager/ssl/osclientcerts/src/lib.rs create mode 100644 security/manager/ssl/osclientcerts/src/manager.rs create mode 100644 security/manager/ssl/osclientcerts/src/util.rs create mode 100644 security/manager/ssl/osclientcerts/test/certificate.bin create mode 100644 security/manager/ssl/osclientcerts/test/modulus.bin create mode 100644 security/manager/ssl/osclientcerts/test/rsa.bin create mode 100644 security/manager/ssl/tests/.eslintrc.js create mode 100644 security/manager/ssl/tests/gtest/CertDBTest.cpp create mode 100644 security/manager/ssl/tests/gtest/CertListTest.cpp create mode 100644 security/manager/ssl/tests/gtest/CoseTest.cpp create mode 100644 security/manager/ssl/tests/gtest/DataStorageTest.cpp create mode 100644 security/manager/ssl/tests/gtest/DeserializeCertTest.cpp create mode 100644 security/manager/ssl/tests/gtest/MD4Test.cpp create mode 100644 security/manager/ssl/tests/gtest/OCSPCacheTest.cpp create mode 100644 security/manager/ssl/tests/gtest/README.txt create mode 100644 security/manager/ssl/tests/gtest/TLSIntoleranceTest.cpp create mode 100644 security/manager/ssl/tests/gtest/moz.build create mode 100644 security/manager/ssl/tests/mochitest/browser/browser.ini create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_certViewer.js create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_certificateManager.js create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_clientAuthRememberService.js create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js create mode 100644 security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js create mode 100644 security/manager/ssl/tests/mochitest/browser/ca.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/ca.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/code-ee.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/code-ee.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/email-ee.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/email-ee.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/expired-ca.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/expired-ca.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/has-cn.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/has-cn.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/has-o.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/has-o.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/has-ou.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/has-ou.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/head.js create mode 100644 security/manager/ssl/tests/mochitest/browser/intermediate.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/intermediate.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/invalid.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/invalid.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/longOID.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/longOID.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/md5-ee.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/md5-ee.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/moz.build create mode 100644 security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/revoked.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/revoked.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/ssl-ee.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/ssl-ee.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem create mode 100644 security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem.certspec create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/backward.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/bug329869.js create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/bug383369step2.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/download.auto create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/download.auto^headers^ create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/iframe.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/mochitest.ini create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/moz.build create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_bug455367.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_bug472986.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_bug477118.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_bug521461.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_cssBefore1.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent1.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent2.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite1.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite2.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecurePicture.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecureXHR.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureBackground.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureIframeRedirect.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicture.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicturePreload.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureRedirect.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlDelayedUnsecurePicture.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlUnsecurePicture.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_javascriptPicture.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_secureAll.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_securePicture.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureBackground.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureCSS.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe2.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeMetaRedirect.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeRedirect.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePicture.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureDup.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureInIframe.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureRedirect.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html create mode 100644 security/manager/ssl/tests/mochitest/mixedcontent/unsecurePictureDup.html create mode 100644 security/manager/ssl/tests/mochitest/moz.build create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/mochitest.ini create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/moz.build create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html^headers^ create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html^headers^ create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html^headers^ create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/test_stricttransportsecurity.html create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html create mode 100644 security/manager/ssl/tests/mochitest/stricttransportsecurity/verify.sjs create mode 100644 security/manager/ssl/tests/moz.build create mode 100644 security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/default-ee.key create mode 100644 security/manager/ssl/tests/unit/bad_certs/default-ee.key.keyspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/default-ee.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/default-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/ev-test.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/ev-test.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/evroot.key create mode 100644 security/manager/ssl/tests/unit/bad_certs/evroot.key.keyspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/evroot.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/expired-ee.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/expired-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/expiredINT.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/expiredINT.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key create mode 100644 security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key.keyspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/md5signature.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/md5signature.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatch.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatch.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/mitm.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/mitm.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/moz.build create mode 100644 security/manager/ssl/tests/unit/bad_certs/noValidNames.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/noValidNames.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/notYetValid.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/notYetValid.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/other-test-ca.key create mode 100644 security/manager/ssl/tests/unit/bad_certs/other-test-ca.key.keyspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/selfsigned.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/selfsigned.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/test-ca.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/test-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/test-int.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/test-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem.certspec create mode 100644 security/manager/ssl/tests/unit/bad_certs/v1Cert.pem create mode 100644 security/manager/ssl/tests/unit/bad_certs/v1Cert.pem.certspec create mode 100644 security/manager/ssl/tests/unit/head_psm.js create mode 100644 security/manager/ssl/tests/unit/moz.build create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/default-ee.key create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/default-ee.key.keyspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/moz.build create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key.keyspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key.keyspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/test-int.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/test-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem create mode 100644 security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/pkcs11testmodule/moz.build create mode 100644 security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.cpp create mode 100644 security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.symbols create mode 100755 security/manager/ssl/tests/unit/pycert.py create mode 100755 security/manager/ssl/tests/unit/pycms.py create mode 100644 security/manager/ssl/tests/unit/pyct.py create mode 100755 security/manager/ssl/tests/unit/pykey.py create mode 100644 security/manager/ssl/tests/unit/requirements.txt create mode 100755 security/manager/ssl/tests/unit/sign_app.py create mode 100644 security/manager/ssl/tests/unit/sss_readstate_child_worker.js create mode 100644 security/manager/ssl/tests/unit/test_add_preexisting_cert.js create mode 100644 security/manager/ssl/tests/unit/test_allow_all_cert_errors.js create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/moz.build create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js create mode 100644 security/manager/ssl/tests/unit/test_blocklist_onecrl.js create mode 100644 security/manager/ssl/tests/unit/test_blocklist_pinning.js create mode 100644 security/manager/ssl/tests/unit/test_broken_fips.js create mode 100644 security/manager/ssl/tests/unit/test_broken_fips/key4.db create mode 100644 security/manager/ssl/tests/unit/test_broken_fips/pkcs11.txt create mode 100644 security/manager/ssl/tests/unit/test_certDB_export_pkcs12.js create mode 100644 security/manager/ssl/tests/unit/test_certDB_export_pkcs12_with_master_password.js create mode 100644 security/manager/ssl/tests/unit/test_certDB_import.js create mode 100644 security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows.pfx create mode 100644 security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_emptypass.pfx create mode 100644 security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_nopass.pfx create mode 100644 security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem create mode 100644 security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem create mode 100644 security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_certDB_import/moz.build create mode 100644 security/manager/ssl/tests/unit/test_certDB_import_pkcs12.js create mode 100644 security/manager/ssl/tests/unit/test_certDB_import_with_master_password.js create mode 100644 security/manager/ssl/tests/unit/test_cert_chains.js create mode 100644 security/manager/ssl/tests/unit/test_cert_dbKey.js create mode 100644 security/manager/ssl/tests/unit/test_cert_eku.js create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_eku/moz.build create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null.js create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_embedded_null/moz.build create mode 100644 security/manager/ssl/tests/unit/test_cert_expiration_canary.js create mode 100644 security/manager/ssl/tests/unit/test_cert_isBuiltInRoot.js create mode 100644 security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload.js create mode 100644 security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/cert9.db create mode 100644 security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/key4.db create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage.js create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_keyUsage/moz.build create mode 100644 security/manager/ssl/tests/unit/test_cert_override_bits_mismatches.js create mode 100644 security/manager/ssl/tests/unit/test_cert_overrides.js create mode 100644 security/manager/ssl/tests/unit/test_cert_overrides_read_only.js create mode 100644 security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db create mode 100644 security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1.js create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_sha1/moz.build create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures.js create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_signatures/moz.build create mode 100644 security/manager/ssl/tests/unit/test_cert_storage.js create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_broken_db.js create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_direct.js create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert-issuer.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.crlite create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.stash create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert-issuer.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_preexisting.js create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.mdb create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.safe.bin create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_preexisting/lock.mdb create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite.js create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/crlite.filter create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/data.safe.bin create mode 100644 security/manager/ssl/tests/unit/test_cert_storage_prefs.js create mode 100644 security/manager/ssl/tests/unit/test_cert_trust.js create mode 100644 security/manager/ssl/tests/unit/test_cert_trust/ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_trust/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_trust/ee.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_trust/ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_trust/int.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_trust/int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_trust/moz.build create mode 100644 security/manager/ssl/tests/unit/test_cert_utf8.js create mode 100644 security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_utf8/moz.build create mode 100644 security/manager/ssl/tests/unit/test_cert_version.js create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem.certspec create mode 100755 security/manager/ssl/tests/unit/test_cert_version/generate.py create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/moz.build create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem create mode 100644 security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_constructX509FromBase64.js create mode 100644 security/manager/ssl/tests/unit/test_content_signing.js create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem create mode 100644 security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_content_signing/moz.build create mode 100644 security/manager/ssl/tests/unit/test_content_signing/pysign.py create mode 100644 security/manager/ssl/tests/unit/test_content_signing/test.txt create mode 100644 security/manager/ssl/tests/unit/test_content_signing/test.txt.signature create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters.js create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters/20201017-0-filter create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters/20201017-1-filter.stash create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters/20201201-3-filter.stash create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters/issuer.pem create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters/no-sct-issuer.pem create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters/no-sct.pem create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash-2.pem create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash.pem create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters/revoked.pem create mode 100644 security/manager/ssl/tests/unit/test_crlite_filters/valid.pem create mode 100644 security/manager/ssl/tests/unit/test_ct.js create mode 100644 security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem create mode 100644 security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem create mode 100644 security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ct/default-ee.key create mode 100644 security/manager/ssl/tests/unit/test_ct/default-ee.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_ct/default-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ct/default-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ct/moz.build create mode 100644 security/manager/ssl/tests/unit/test_ct/test-ca.pem create mode 100644 security/manager/ssl/tests/unit/test_ct/test-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_db_format_pref_new.js create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials.js create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/moz.build create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem create mode 100644 security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_der.js create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello.js create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/moz.build create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_encrypted_client_hello_client_only.js create mode 100644 security/manager/ssl/tests/unit/test_enterprise_roots.js create mode 100644 security/manager/ssl/tests/unit/test_ev_certs.js create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/evroot.key create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/evroot.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/moz.build create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem create mode 100644 security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_forget_about_site_security_headers.js create mode 100644 security/manager/ssl/tests/unit/test_hash_algorithms.js create mode 100644 security/manager/ssl/tests/unit/test_hash_algorithms_wrap.js create mode 100644 security/manager/ssl/tests/unit/test_hmac.js create mode 100644 security/manager/ssl/tests/unit/test_imminent_distrust.js create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/moz.build create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads.js create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_intermediate_preloads/moz.build create mode 100644 security/manager/ssl/tests/unit/test_keysize.js create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/moz.build create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev.js create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/evroot.key create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/evroot.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_keysize_ev/moz.build create mode 100644 security/manager/ssl/tests/unit/test_local_cert.js create mode 100644 security/manager/ssl/tests/unit/test_logoutAndTeardown.js create mode 100644 security/manager/ssl/tests/unit/test_missing_intermediate.js create mode 100644 security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem create mode 100644 security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_missing_intermediate/moz.build create mode 100644 security/manager/ssl/tests/unit/test_name_constraints.js create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/dciss.pem create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/dciss.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_name_constraints/moz.build create mode 100644 security/manager/ssl/tests/unit/test_nonascii_path.js create mode 100644 security/manager/ssl/tests/unit/test_nsCertType.js create mode 100644 security/manager/ssl/tests/unit/test_nsIX509CertValidity.js create mode 100644 security/manager/ssl/tests/unit/test_nsIX509Cert_utf8.js create mode 100644 security/manager/ssl/tests/unit/test_nss_shutdown.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_caching.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_enabled_pref.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_must_staple.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_private_caching.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_required.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_stapling.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_timeout.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url.js create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ca.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.key create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/int.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/moz.build create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem create mode 100644 security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem create mode 100644 security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem create mode 100644 security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem create mode 100644 security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem create mode 100644 security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_onecrl/moz.build create mode 100644 security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_onecrl/sample_revocations.txt create mode 100644 security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_osclientcerts_module.js create mode 100644 security/manager/ssl/tests/unit/test_oskeystore.js create mode 100644 security/manager/ssl/tests/unit/test_osreauthenticator.js create mode 100644 security/manager/ssl/tests/unit/test_password_prompt.js create mode 100644 security/manager/ssl/tests/unit/test_pinning.js create mode 100644 security/manager/ssl/tests/unit/test_pkcs11_module.js create mode 100644 security/manager/ssl/tests/unit/test_pkcs11_moduleDB.js create mode 100644 security/manager/ssl/tests/unit/test_pkcs11_safe_mode.js create mode 100644 security/manager/ssl/tests/unit/test_pkcs11_slot.js create mode 100644 security/manager/ssl/tests/unit/test_pkcs11_token.js create mode 100644 security/manager/ssl/tests/unit/test_pkcs11_tokenDB.js create mode 100644 security/manager/ssl/tests/unit/test_sanctions/apple-ist-ca-8-g1-intermediate.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/default-ee.key create mode 100644 security/manager/ssl/tests/unit/test_sanctions/default-ee.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_sanctions/default-ee.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/default-ee.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_sanctions/gspe72-4-ssl-ls-apple-com.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/moz.build create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem create mode 100644 security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_sanctions_symantec_apple_google.js create mode 100644 security/manager/ssl/tests/unit/test_sdr.js create mode 100644 security/manager/ssl/tests/unit/test_sdr_preexisting.js create mode 100644 security/manager/ssl/tests/unit/test_sdr_preexisting/key4.db create mode 100644 security/manager/ssl/tests/unit/test_sdr_preexisting_with_password.js create mode 100644 security/manager/ssl/tests/unit/test_sdr_preexisting_with_password/key4.db create mode 100644 security/manager/ssl/tests/unit/test_self_signed_certs.js create mode 100644 security/manager/ssl/tests/unit/test_self_signed_certs/cert9.db create mode 100644 security/manager/ssl/tests/unit/test_session_resumption.js create mode 100644 security/manager/ssl/tests/unit/test_signed_apps.js create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app/README create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app/data/image.png create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app/manifest.json create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.manifest create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.sig create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/README create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/data/image.png create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/manifest.json create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-ES384.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-PS256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-PS256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-ES384.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-PS256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-PS256.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/big_manifest.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/bug_1411458.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/cose_int_signed_with_pkcs7.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/cose_multiple_signed_with_pkcs7.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/cose_signed_with_pkcs7.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/cose_tampered_good_pkcs7.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/empty_signerInfos.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/huge_manifest.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/moz.build create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/only_cose_multiple_signed.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/only_cose_signed.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/unknown_issuer_app.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/unsigned_app.zip create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.der create mode 100644 security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_ssl_status.js create mode 100644 security/manager/ssl/tests/unit/test_sss_enumerate.js create mode 100644 security/manager/ssl/tests/unit/test_sss_eviction.js create mode 100644 security/manager/ssl/tests/unit/test_sss_originAttributes.js create mode 100644 security/manager/ssl/tests/unit/test_sss_readstate.js create mode 100644 security/manager/ssl/tests/unit/test_sss_readstate_child.js create mode 100644 security/manager/ssl/tests/unit/test_sss_readstate_empty.js create mode 100644 security/manager/ssl/tests/unit/test_sss_readstate_garbage.js create mode 100644 security/manager/ssl/tests/unit/test_sss_readstate_huge.js create mode 100644 security/manager/ssl/tests/unit/test_sss_resetState.js create mode 100644 security/manager/ssl/tests/unit/test_sss_sanitizeOnShutdown.js create mode 100644 security/manager/ssl/tests/unit/test_sss_savestate.js create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign.js create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_startcom_wosign/moz.build create mode 100644 security/manager/ssl/tests/unit/test_sts_fqdn.js create mode 100644 security/manager/ssl/tests/unit/test_sts_ipv4_ipv6.js create mode 100644 security/manager/ssl/tests/unit/test_sts_parser.js create mode 100644 security/manager/ssl/tests/unit/test_sts_preload_dynamic.js create mode 100644 security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js create mode 100644 security/manager/ssl/tests/unit/test_sts_preloadlist_selfdestruct.js create mode 100644 security/manager/ssl/tests/unit/test_validity.js create mode 100644 security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key create mode 100644 security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_validity/evroot.key create mode 100644 security/manager/ssl/tests/unit/test_validity/evroot.key.keyspec create mode 100644 security/manager/ssl/tests/unit/test_validity/evroot.pem create mode 100644 security/manager/ssl/tests/unit/test_validity/evroot.pem.certspec create mode 100644 security/manager/ssl/tests/unit/test_validity/moz.build create mode 100644 security/manager/ssl/tests/unit/test_x509.js create mode 100644 security/manager/ssl/tests/unit/tlsserver/cmd/BadCertAndPinningServer.cpp create mode 100644 security/manager/ssl/tests/unit/tlsserver/cmd/DelegatedCredentialsServer.cpp create mode 100644 security/manager/ssl/tests/unit/tlsserver/cmd/EncryptedClientHelloServer.cpp create mode 100644 security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp create mode 100644 security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp create mode 100644 security/manager/ssl/tests/unit/tlsserver/cmd/SanctionsTestServer.cpp create mode 100644 security/manager/ssl/tests/unit/tlsserver/cmd/moz.build create mode 100644 security/manager/ssl/tests/unit/tlsserver/default-ee.der create mode 100644 security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp create mode 100644 security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h create mode 100644 security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp create mode 100644 security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h create mode 100644 security/manager/ssl/tests/unit/tlsserver/lib/moz.build create mode 100644 security/manager/ssl/tests/unit/tlsserver/moz.build create mode 100644 security/manager/ssl/tests/unit/xpcshell-smartcards.ini create mode 100644 security/manager/ssl/tests/unit/xpcshell.ini (limited to 'security/manager/ssl') diff --git a/security/manager/ssl/CSTrustDomain.cpp b/security/manager/ssl/CSTrustDomain.cpp new file mode 100644 index 0000000000..3f19d080ef --- /dev/null +++ b/security/manager/ssl/CSTrustDomain.cpp @@ -0,0 +1,194 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "CSTrustDomain.h" +#include "NSSCertDBTrustDomain.h" +#include "cert_storage/src/cert_storage.h" +#include "mozilla/Base64.h" +#include "mozilla/Logging.h" +#include "mozilla/Preferences.h" +#include "mozpkix/pkixnss.h" +#include "nsDirectoryServiceUtils.h" +#include "nsNSSComponent.h" +#include "nsServiceManagerUtils.h" + +using namespace mozilla::pkix; + +namespace mozilla { +namespace psm { + +static LazyLogModule gTrustDomainPRLog("CSTrustDomain"); +#define CSTrust_LOG(args) MOZ_LOG(gTrustDomainPRLog, LogLevel::Debug, args) + +CSTrustDomain::CSTrustDomain(nsTArray>& certList) + : mCertList(certList), mCertBlocklist(do_GetService(NS_CERT_STORAGE_CID)) {} + +Result CSTrustDomain::GetCertTrust(EndEntityOrCA endEntityOrCA, + const CertPolicyId& policy, + Input candidateCertDER, + /*out*/ TrustLevel& trustLevel) { + MOZ_ASSERT(policy.IsAnyPolicy()); + if (!policy.IsAnyPolicy()) { + return Result::FATAL_ERROR_INVALID_ARGS; + } + + nsTArray issuerBytes; + nsTArray serialBytes; + nsTArray subjectBytes; + nsTArray pubKeyBytes; + + Result result = + BuildRevocationCheckArrays(candidateCertDER, endEntityOrCA, issuerBytes, + serialBytes, subjectBytes, pubKeyBytes); + if (result != Success) { + return result; + } + + int16_t revocationState; + nsresult nsrv = mCertBlocklist->GetRevocationState( + issuerBytes, serialBytes, subjectBytes, pubKeyBytes, &revocationState); + if (NS_FAILED(nsrv)) { + return Result::FATAL_ERROR_LIBRARY_FAILURE; + } + + if (revocationState == nsICertStorage::STATE_ENFORCE) { + CSTrust_LOG(("CSTrustDomain: certificate is revoked\n")); + return Result::ERROR_REVOKED_CERTIFICATE; + } + + // Is this cert our built-in content signing root? + bool isRoot = false; + nsCOMPtr component(do_GetService(PSM_COMPONENT_CONTRACTID)); + if (!component) { + return Result::FATAL_ERROR_LIBRARY_FAILURE; + } + nsTArray candidateCert(candidateCertDER.UnsafeGetData(), + candidateCertDER.GetLength()); + nsrv = component->IsCertContentSigningRoot(candidateCert, &isRoot); + if (NS_FAILED(nsrv)) { + return Result::FATAL_ERROR_LIBRARY_FAILURE; + } + if (isRoot) { + CSTrust_LOG(("CSTrustDomain: certificate is a trust anchor\n")); + trustLevel = TrustLevel::TrustAnchor; + return Success; + } + CSTrust_LOG(("CSTrustDomain: certificate is *not* a trust anchor\n")); + + trustLevel = TrustLevel::InheritsTrust; + return Success; +} + +Result CSTrustDomain::FindIssuer(Input encodedIssuerName, + IssuerChecker& checker, Time time) { + // Loop over the chain, look for a matching subject + for (const auto& certBytes : mCertList) { + Input certInput; + Result rv = certInput.Init(certBytes.Elements(), certBytes.Length()); + if (rv != Success) { + continue; // probably too big + } + bool keepGoing; + rv = checker.Check(certInput, nullptr /*additionalNameConstraints*/, + keepGoing); + if (rv != Success) { + return rv; + } + if (!keepGoing) { + CSTrust_LOG(("CSTrustDomain: don't keep going\n")); + break; + } + } + + return Success; +} + +Result CSTrustDomain::CheckRevocation( + EndEntityOrCA endEntityOrCA, const CertID& certID, Time time, + Duration validityDuration, + /*optional*/ const Input* stapledOCSPresponse, + /*optional*/ const Input* aiaExtension, + /*optional*/ const Input* sctExtension) { + // We're relying solely on the CertBlocklist for revocation - and we're + // performing checks on this in GetCertTrust (as per nsNSSCertDBTrustDomain) + return Success; +} + +Result CSTrustDomain::IsChainValid(const DERArray& certChain, Time time, + const CertPolicyId& requiredPolicy) { + MOZ_ASSERT(requiredPolicy.IsAnyPolicy()); + // Check that our chain is not empty + if (certChain.GetLength() == 0) { + return Result::FATAL_ERROR_LIBRARY_FAILURE; + } + + return Success; +} + +Result CSTrustDomain::CheckSignatureDigestAlgorithm(DigestAlgorithm digestAlg, + EndEntityOrCA endEntityOrCA, + Time notBefore) { + if (digestAlg == DigestAlgorithm::sha1) { + return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED; + } + return Success; +} + +Result CSTrustDomain::CheckRSAPublicKeyModulusSizeInBits( + EndEntityOrCA endEntityOrCA, unsigned int modulusSizeInBits) { + if (modulusSizeInBits < 2048) { + return Result::ERROR_INADEQUATE_KEY_SIZE; + } + return Success; +} + +Result CSTrustDomain::VerifyRSAPKCS1SignedDigest( + const SignedDigest& signedDigest, Input subjectPublicKeyInfo) { + return VerifyRSAPKCS1SignedDigestNSS(signedDigest, subjectPublicKeyInfo, + nullptr); +} + +Result CSTrustDomain::CheckECDSACurveIsAcceptable(EndEntityOrCA endEntityOrCA, + NamedCurve curve) { + switch (curve) { + case NamedCurve::secp256r1: // fall through + case NamedCurve::secp384r1: // fall through + case NamedCurve::secp521r1: + return Success; + } + + return Result::ERROR_UNSUPPORTED_ELLIPTIC_CURVE; +} + +Result CSTrustDomain::VerifyECDSASignedDigest(const SignedDigest& signedDigest, + Input subjectPublicKeyInfo) { + return VerifyECDSASignedDigestNSS(signedDigest, subjectPublicKeyInfo, + nullptr); +} + +Result CSTrustDomain::CheckValidityIsAcceptable(Time notBefore, Time notAfter, + EndEntityOrCA endEntityOrCA, + KeyPurposeId keyPurpose) { + return Success; +} + +Result CSTrustDomain::NetscapeStepUpMatchesServerAuth(Time notBefore, + /*out*/ bool& matches) { + matches = false; + return Success; +} + +void CSTrustDomain::NoteAuxiliaryExtension(AuxiliaryExtension /*extension*/, + Input /*extensionData*/) {} + +Result CSTrustDomain::DigestBuf(Input item, DigestAlgorithm digestAlg, + /*out*/ uint8_t* digestBuf, + size_t digestBufLen) { + return DigestBufNSS(item, digestAlg, digestBuf, digestBufLen); +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/CSTrustDomain.h b/security/manager/ssl/CSTrustDomain.h new file mode 100644 index 0000000000..7bbdbb3792 --- /dev/null +++ b/security/manager/ssl/CSTrustDomain.h @@ -0,0 +1,80 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef CSTrustDomain_h +#define CSTrustDomain_h + +#include "mozpkix/pkixtypes.h" +#include "nsCOMPtr.h" +#include "nsICertStorage.h" +#include "nsTArray.h" + +namespace mozilla { +namespace psm { + +class CSTrustDomain final : public mozilla::pkix::TrustDomain { + public: + typedef mozilla::pkix::Result Result; + + explicit CSTrustDomain(nsTArray>& certList); + + virtual Result GetCertTrust( + mozilla::pkix::EndEntityOrCA endEntityOrCA, + const mozilla::pkix::CertPolicyId& policy, + mozilla::pkix::Input candidateCertDER, + /*out*/ mozilla::pkix::TrustLevel& trustLevel) override; + virtual Result FindIssuer(mozilla::pkix::Input encodedIssuerName, + IssuerChecker& checker, + mozilla::pkix::Time time) override; + virtual Result CheckRevocation( + mozilla::pkix::EndEntityOrCA endEntityOrCA, + const mozilla::pkix::CertID& certID, mozilla::pkix::Time time, + mozilla::pkix::Duration validityDuration, + /*optional*/ const mozilla::pkix::Input* stapledOCSPresponse, + /*optional*/ const mozilla::pkix::Input* aiaExtension, + /*optional*/ const mozilla::pkix::Input* sctExtension) override; + virtual Result IsChainValid( + const mozilla::pkix::DERArray& certChain, mozilla::pkix::Time time, + const mozilla::pkix::CertPolicyId& requiredPolicy) override; + virtual Result CheckSignatureDigestAlgorithm( + mozilla::pkix::DigestAlgorithm digestAlg, + mozilla::pkix::EndEntityOrCA endEntityOrCA, + mozilla::pkix::Time notBefore) override; + virtual Result CheckRSAPublicKeyModulusSizeInBits( + mozilla::pkix::EndEntityOrCA endEntityOrCA, + unsigned int modulusSizeInBits) override; + virtual Result VerifyRSAPKCS1SignedDigest( + const mozilla::pkix::SignedDigest& signedDigest, + mozilla::pkix::Input subjectPublicKeyInfo) override; + virtual Result CheckECDSACurveIsAcceptable( + mozilla::pkix::EndEntityOrCA endEntityOrCA, + mozilla::pkix::NamedCurve curve) override; + virtual Result VerifyECDSASignedDigest( + const mozilla::pkix::SignedDigest& signedDigest, + mozilla::pkix::Input subjectPublicKeyInfo) override; + virtual Result CheckValidityIsAcceptable( + mozilla::pkix::Time notBefore, mozilla::pkix::Time notAfter, + mozilla::pkix::EndEntityOrCA endEntityOrCA, + mozilla::pkix::KeyPurposeId keyPurpose) override; + virtual Result NetscapeStepUpMatchesServerAuth( + mozilla::pkix::Time notBefore, /*out*/ bool& matches) override; + virtual void NoteAuxiliaryExtension( + mozilla::pkix::AuxiliaryExtension extension, + mozilla::pkix::Input extensionData) override; + virtual Result DigestBuf(mozilla::pkix::Input item, + mozilla::pkix::DigestAlgorithm digestAlg, + /*out*/ uint8_t* digestBuf, + size_t digestBufLen) override; + + private: + nsTArray>& mCertList; // non-owning! + nsCOMPtr mCertBlocklist; +}; + +} // namespace psm +} // namespace mozilla + +#endif // CSTrustDomain_h diff --git a/security/manager/ssl/CommonSocketControl.cpp b/security/manager/ssl/CommonSocketControl.cpp new file mode 100644 index 0000000000..ed5dd4df29 --- /dev/null +++ b/security/manager/ssl/CommonSocketControl.cpp @@ -0,0 +1,350 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "CommonSocketControl.h" + +#include "BRNameMatchingPolicy.h" +#include "PublicKeyPinningService.h" +#include "SharedCertVerifier.h" +#include "nsNSSComponent.h" +#include "SharedSSLState.h" +#include "sslt.h" +#include "ssl.h" +#include "mozilla/net/SSLTokensCache.h" + +using namespace mozilla; + +extern LazyLogModule gPIPNSSLog; + +NS_IMPL_ISUPPORTS_INHERITED(CommonSocketControl, TransportSecurityInfo, + nsISSLSocketControl) + +CommonSocketControl::CommonSocketControl(uint32_t aProviderFlags) + : mHandshakeCompleted(false), + mJoined(false), + mSentClientCert(false), + mFailedVerification(false), + mSSLVersionUsed(nsISSLSocketControl::SSL_VERSION_UNKNOWN), + mProviderFlags(aProviderFlags) {} + +NS_IMETHODIMP +CommonSocketControl::GetNotificationCallbacks( + nsIInterfaceRequestor** aCallbacks) { + MutexAutoLock lock(mMutex); + *aCallbacks = mCallbacks; + NS_IF_ADDREF(*aCallbacks); + return NS_OK; +} + +NS_IMETHODIMP +CommonSocketControl::SetNotificationCallbacks( + nsIInterfaceRequestor* aCallbacks) { + MutexAutoLock lock(mMutex); + mCallbacks = aCallbacks; + return NS_OK; +} + +NS_IMETHODIMP +CommonSocketControl::ProxyStartSSL(void) { return NS_ERROR_NOT_IMPLEMENTED; } + +NS_IMETHODIMP +CommonSocketControl::StartTLS(void) { return NS_ERROR_NOT_IMPLEMENTED; } + +NS_IMETHODIMP +CommonSocketControl::SetNPNList(nsTArray& aNPNList) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::GetAlpnEarlySelection(nsACString& _retval) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::GetEarlyDataAccepted(bool* aEarlyDataAccepted) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::DriveHandshake(void) { return NS_ERROR_NOT_IMPLEMENTED; } + +NS_IMETHODIMP +CommonSocketControl::JoinConnection(const nsACString& npnProtocol, + const nsACString& hostname, int32_t port, + bool* _retval) { + nsresult rv = TestJoinConnection(npnProtocol, hostname, port, _retval); + if (NS_SUCCEEDED(rv) && *_retval) { + // All tests pass - this is joinable + mJoined = true; + } + return rv; +} + +NS_IMETHODIMP +CommonSocketControl::TestJoinConnection(const nsACString& npnProtocol, + const nsACString& hostname, + int32_t port, bool* _retval) { + *_retval = false; + + // Different ports may not be joined together + if (port != GetPort()) return NS_OK; + + { + MutexAutoLock lock(mMutex); + // Make sure NPN has been completed and matches requested npnProtocol + if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol)) return NS_OK; + } + + IsAcceptableForHost(hostname, _retval); // sets _retval + return NS_OK; +} + +NS_IMETHODIMP +CommonSocketControl::IsAcceptableForHost(const nsACString& hostname, + bool* _retval) { + NS_ENSURE_ARG(_retval); + + *_retval = false; + + // If this is the same hostname then the certicate status does not + // need to be considered. They are joinable. + if (hostname.Equals(GetHostName())) { + *_retval = true; + return NS_OK; + } + + // Before checking the server certificate we need to make sure the + // handshake has completed. + if (!mHandshakeCompleted || !HasServerCert()) { + return NS_OK; + } + + // If the cert has error bits (e.g. it is untrusted) then do not join. + // The value of mHaveCertErrorBits is only reliable because we know that + // the handshake completed. + if (mHaveCertErrorBits) { + return NS_OK; + } + + // If the connection is using client certificates then do not join + // because the user decides on whether to send client certs to hosts on a + // per-domain basis. + if (mSentClientCert) return NS_OK; + + // Ensure that the server certificate covers the hostname that would + // like to join this connection + + UniqueCERTCertificate nssCert; + + nsCOMPtr cert; + if (NS_FAILED(GetServerCert(getter_AddRefs(cert)))) { + return NS_OK; + } + if (cert) { + nssCert.reset(cert->GetCert()); + } + + if (!nssCert) { + return NS_OK; + } + + MutexAutoLock lock(mMutex); + + // An empty mSucceededCertChain means the server certificate verification + // failed before, so don't join in this case. + if (mSucceededCertChain.IsEmpty()) { + return NS_OK; + } + + // See where CheckCertHostname() is called in + // CertVerifier::VerifySSLServerCert. We are doing the same hostname-specific + // checks here. If any hostname-specific checks are added to + // CertVerifier::VerifySSLServerCert we need to add them here too. + Input serverCertInput; + mozilla::pkix::Result rv = + serverCertInput.Init(nssCert->derCert.data, nssCert->derCert.len); + if (rv != Success) { + return NS_OK; + } + + Input hostnameInput; + rv = hostnameInput.Init( + BitwiseCast(hostname.BeginReading()), + hostname.Length()); + if (rv != Success) { + return NS_OK; + } + + mozilla::psm::BRNameMatchingPolicy nameMatchingPolicy( + mIsBuiltCertChainRootBuiltInRoot + ? mozilla::psm::PublicSSLState()->NameMatchingMode() + : mozilla::psm::BRNameMatchingPolicy::Mode::DoNotEnforce); + rv = CheckCertHostname(serverCertInput, hostnameInput, nameMatchingPolicy); + if (rv != Success) { + return NS_OK; + } + + mozilla::psm::CertVerifier::PinningMode pinningMode = + mozilla::psm::PublicSSLState()->PinningMode(); + if (pinningMode != mozilla::psm::CertVerifier::pinningDisabled) { + bool chainHasValidPins; + bool enforceTestMode = + (pinningMode == mozilla::psm::CertVerifier::pinningEnforceTestMode); + + nsTArray> rawDerCertList; + nsTArray> derCertSpanList; + for (const auto& cert : mSucceededCertChain) { + rawDerCertList.EmplaceBack(); + nsresult nsrv = cert->GetRawDER(rawDerCertList.LastElement()); + if (NS_FAILED(nsrv)) { + return nsrv; + } + derCertSpanList.EmplaceBack(rawDerCertList.LastElement()); + } + + nsresult nsrv = mozilla::psm::PublicKeyPinningService::ChainHasValidPins( + derCertSpanList, PromiseFlatCString(hostname).BeginReading(), Now(), + enforceTestMode, GetOriginAttributes(lock), chainHasValidPins, nullptr); + if (NS_FAILED(nsrv)) { + return NS_OK; + } + + if (!chainHasValidPins) { + return NS_OK; + } + } + + // All tests pass + *_retval = true; + return NS_OK; +} + +void CommonSocketControl::RebuildCertificateInfoFromSSLTokenCache() { + nsAutoCString key; + GetPeerId(key); + mozilla::net::SessionCacheInfo info; + if (!mozilla::net::SSLTokensCache::GetSessionCacheInfo(key, info)) { + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("CommonSocketControl::RebuildCertificateInfoFromSSLTokenCache cannot " + "find cached info.")); + return; + } + + RefPtr nssc = nsNSSCertificate::ConstructFromDER( + BitwiseCast(info.mServerCertBytes.Elements()), + info.mServerCertBytes.Length()); + if (!nssc) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("RebuildCertificateInfoFromSSLTokenCache failed to construct " + "server cert")); + return; + } + + SetServerCert(nssc, info.mEVStatus); + SetCertificateTransparencyStatus(info.mCertificateTransparencyStatus); + if (info.mSucceededCertChainBytes) { + SetSucceededCertChain(std::move(*info.mSucceededCertChainBytes)); + } + + if (info.mIsBuiltCertChainRootBuiltInRoot) { + SetIsBuiltCertChainRootBuiltInRoot(*info.mIsBuiltCertChainRootBuiltInRoot); + } +} + +NS_IMETHODIMP +CommonSocketControl::GetKEAUsed(int16_t* aKEAUsed) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::GetKEAKeyBits(uint32_t* aKEAKeyBits) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::GetProviderFlags(uint32_t* aProviderFlags) { + *aProviderFlags = mProviderFlags; + return NS_OK; +} + +NS_IMETHODIMP +CommonSocketControl::GetProviderTlsFlags(uint32_t* aProviderTlsFlags) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::GetSSLVersionUsed(int16_t* aSSLVersionUsed) { + *aSSLVersionUsed = mSSLVersionUsed; + return NS_OK; +} + +NS_IMETHODIMP +CommonSocketControl::GetSSLVersionOffered(int16_t* aSSLVersionOffered) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::GetMACAlgorithmUsed(int16_t* aMACAlgorithmUsed) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +bool CommonSocketControl::GetDenyClientCert() { return true; } + +void CommonSocketControl::SetDenyClientCert(bool aDenyClientCert) {} + +NS_IMETHODIMP +CommonSocketControl::GetClientCert(nsIX509Cert** aClientCert) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::SetClientCert(nsIX509Cert* aClientCert) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::GetClientCertSent(bool* arg) { + *arg = mSentClientCert; + return NS_OK; +} + +NS_IMETHODIMP +CommonSocketControl::GetFailedVerification(bool* arg) { + *arg = mFailedVerification; + return NS_OK; +} + +NS_IMETHODIMP +CommonSocketControl::GetEsniTxt(nsACString& aEsniTxt) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::SetEsniTxt(const nsACString& aEsniTxt) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::GetEchConfig(nsACString& aEchConfig) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::SetEchConfig(const nsACString& aEchConfig) { + // TODO: Implement this in bug 1654507. + return NS_OK; +} + +NS_IMETHODIMP +CommonSocketControl::GetPeerId(nsACString& aResult) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +CommonSocketControl::GetRetryEchConfig(nsACString& aEchConfig) { + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/security/manager/ssl/CommonSocketControl.h b/security/manager/ssl/CommonSocketControl.h new file mode 100644 index 0000000000..4afd79d2d0 --- /dev/null +++ b/security/manager/ssl/CommonSocketControl.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef CommonSocketControl_h +#define CommonSocketControl_h + +#include "nsISSLSocketControl.h" +#include "TransportSecurityInfo.h" + +class CommonSocketControl : public mozilla::psm::TransportSecurityInfo, + public nsISSLSocketControl { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSISSLSOCKETCONTROL + + explicit CommonSocketControl(uint32_t providerFlags); + + uint32_t GetProviderFlags() const { return mProviderFlags; } + void SetSSLVersionUsed(int16_t version) { mSSLVersionUsed = version; } + void RebuildCertificateInfoFromSSLTokenCache(); + + protected: + ~CommonSocketControl() = default; + bool mHandshakeCompleted; + bool mJoined; + bool mSentClientCert; + bool mFailedVerification; + uint16_t mSSLVersionUsed; + uint32_t mProviderFlags; +}; + +#endif // CommonSocketControl_h diff --git a/security/manager/ssl/ContentSignatureVerifier.cpp b/security/manager/ssl/ContentSignatureVerifier.cpp new file mode 100644 index 0000000000..fa076bdff9 --- /dev/null +++ b/security/manager/ssl/ContentSignatureVerifier.cpp @@ -0,0 +1,441 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "ContentSignatureVerifier.h" + +#include "BRNameMatchingPolicy.h" +#include "CryptoTask.h" +#include "CSTrustDomain.h" +#include "ScopedNSSTypes.h" +#include "SharedCertVerifier.h" +#include "cryptohi.h" +#include "keyhi.h" +#include "mozilla/Base64.h" +#include "mozilla/dom/Promise.h" +#include "nsCOMPtr.h" +#include "nsPromiseFlatString.h" +#include "nsSecurityHeaderParser.h" +#include "nsWhitespaceTokenizer.h" +#include "mozpkix/pkix.h" +#include "mozpkix/pkixtypes.h" +#include "mozpkix/pkixutil.h" +#include "secerr.h" +#include "ssl.h" + +NS_IMPL_ISUPPORTS(ContentSignatureVerifier, nsIContentSignatureVerifier) + +using namespace mozilla; +using namespace mozilla::pkix; +using namespace mozilla::psm; +using dom::Promise; + +static LazyLogModule gCSVerifierPRLog("ContentSignatureVerifier"); +#define CSVerifier_LOG(args) MOZ_LOG(gCSVerifierPRLog, LogLevel::Debug, args) + +// Content-Signature prefix +const unsigned char kPREFIX[] = {'C', 'o', 'n', 't', 'e', 'n', 't', + '-', 'S', 'i', 'g', 'n', 'a', 't', + 'u', 'r', 'e', ':', 0}; + +class VerifyContentSignatureTask : public CryptoTask { + public: + VerifyContentSignatureTask(const nsACString& aData, + const nsACString& aCSHeader, + const nsACString& aCertChain, + const nsACString& aHostname, + RefPtr& aPromise) + : mData(aData), + mCSHeader(aCSHeader), + mCertChain(aCertChain), + mHostname(aHostname), + mSignatureVerified(false), + mPromise(new nsMainThreadPtrHolder( + "VerifyContentSignatureTask::mPromise", aPromise)) {} + + private: + virtual nsresult CalculateResult() override; + virtual void CallCallback(nsresult rv) override; + + nsCString mData; + nsCString mCSHeader; + nsCString mCertChain; + nsCString mHostname; + bool mSignatureVerified; + nsMainThreadPtrHandle mPromise; +}; + +NS_IMETHODIMP +ContentSignatureVerifier::AsyncVerifyContentSignature( + const nsACString& aData, const nsACString& aCSHeader, + const nsACString& aCertChain, const nsACString& aHostname, JSContext* aCx, + Promise** aPromise) { + NS_ENSURE_ARG_POINTER(aCx); + + nsIGlobalObject* globalObject = xpc::CurrentNativeGlobal(aCx); + if (NS_WARN_IF(!globalObject)) { + return NS_ERROR_UNEXPECTED; + } + + ErrorResult result; + RefPtr promise = Promise::Create(globalObject, result); + if (NS_WARN_IF(result.Failed())) { + return result.StealNSResult(); + } + + RefPtr task(new VerifyContentSignatureTask( + aData, aCSHeader, aCertChain, aHostname, promise)); + nsresult rv = task->Dispatch(); + if (NS_FAILED(rv)) { + return rv; + } + + promise.forget(aPromise); + return NS_OK; +} + +static nsresult VerifyContentSignatureInternal( + const nsACString& aData, const nsACString& aCSHeader, + const nsACString& aCertChain, const nsACString& aHostname, + /* out */ + mozilla::Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS& + aErrorLabel, + /* out */ nsACString& aCertFingerprint, /* out */ uint32_t& aErrorValue); +static nsresult ParseContentSignatureHeader( + const nsACString& aContentSignatureHeader, + /* out */ nsCString& aSignature); + +nsresult VerifyContentSignatureTask::CalculateResult() { + // 3 is the default, non-specific, "something failed" error. + Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS errorLabel = + Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err3; + nsAutoCString certFingerprint; + uint32_t errorValue = 3; + nsresult rv = + VerifyContentSignatureInternal(mData, mCSHeader, mCertChain, mHostname, + errorLabel, certFingerprint, errorValue); + if (NS_FAILED(rv)) { + CSVerifier_LOG(("CSVerifier: Signature verification failed")); + if (certFingerprint.Length() > 0) { + Telemetry::AccumulateCategoricalKeyed(certFingerprint, errorLabel); + } + Accumulate(Telemetry::CONTENT_SIGNATURE_VERIFICATION_STATUS, errorValue); + if (rv == NS_ERROR_INVALID_SIGNATURE) { + return NS_OK; + } + return rv; + } + + mSignatureVerified = true; + Accumulate(Telemetry::CONTENT_SIGNATURE_VERIFICATION_STATUS, 0); + + return NS_OK; +} + +void VerifyContentSignatureTask::CallCallback(nsresult rv) { + if (NS_FAILED(rv)) { + mPromise->MaybeReject(rv); + } else { + mPromise->MaybeResolve(mSignatureVerified); + } +} + +bool IsNewLine(char16_t c) { return c == '\n' || c == '\r'; } + +nsresult ReadChainIntoCertList(const nsACString& aCertChain, + nsTArray>& aCertList) { + bool inBlock = false; + bool certFound = false; + + const nsCString header = "-----BEGIN CERTIFICATE-----"_ns; + const nsCString footer = "-----END CERTIFICATE-----"_ns; + + nsCWhitespaceTokenizerTemplate tokenizer(aCertChain); + + nsAutoCString blockData; + while (tokenizer.hasMoreTokens()) { + nsDependentCSubstring token = tokenizer.nextToken(); + if (token.IsEmpty()) { + continue; + } + if (inBlock) { + if (token.Equals(footer)) { + inBlock = false; + certFound = true; + // base64 decode data, make certs, append to chain + nsAutoCString derString; + nsresult rv = Base64Decode(blockData, derString); + if (NS_FAILED(rv)) { + CSVerifier_LOG(("CSVerifier: decoding the signature failed")); + return rv; + } + nsTArray derBytes(derString.Data(), derString.Length()); + aCertList.AppendElement(std::move(derBytes)); + } else { + blockData.Append(token); + } + } else if (token.Equals(header)) { + inBlock = true; + blockData = ""; + } + } + if (inBlock || !certFound) { + // the PEM data did not end; bad data. + CSVerifier_LOG(("CSVerifier: supplied chain contains bad data")); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +// Given data to verify, a content signature header value, a string representing +// a list of PEM-encoded certificates, and a hostname to validate the +// certificates against, this function attempts to validate the certificate +// chain, extract the signature from the header, and verify the data using the +// key in the end-entity certificate from the chain. Returns NS_OK if everything +// is satisfactory and a failing nsresult otherwise. The output parameters are +// filled with telemetry data to report in the case of failures. +static nsresult VerifyContentSignatureInternal( + const nsACString& aData, const nsACString& aCSHeader, + const nsACString& aCertChain, const nsACString& aHostname, + /* out */ + Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS& aErrorLabel, + /* out */ nsACString& aCertFingerprint, + /* out */ uint32_t& aErrorValue) { + nsTArray> certList; + nsresult rv = ReadChainIntoCertList(aCertChain, certList); + if (NS_FAILED(rv)) { + return rv; + } + if (certList.Length() < 1) { + return NS_ERROR_FAILURE; + } + // The 0th element should be the end-entity that issued the content + // signature. + nsTArray& certBytes(certList.ElementAt(0)); + Input certInput; + mozilla::pkix::Result result = + certInput.Init(certBytes.Elements(), certBytes.Length()); + if (result != Success) { + return NS_ERROR_FAILURE; + } + + // Get EE certificate fingerprint for telemetry. + unsigned char fingerprint[SHA256_LENGTH] = {0}; + SECStatus srv = + PK11_HashBuf(SEC_OID_SHA256, fingerprint, certInput.UnsafeGetData(), + certInput.GetLength()); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + SECItem fingerprintItem = {siBuffer, fingerprint, SHA256_LENGTH}; + UniquePORTString tmpFingerprintString( + CERT_Hexify(&fingerprintItem, false /* don't use colon delimiters */)); + if (!tmpFingerprintString) { + return NS_ERROR_OUT_OF_MEMORY; + } + aCertFingerprint.Assign(tmpFingerprintString.get()); + + // Check the signerCert chain is good + CSTrustDomain trustDomain(certList); + result = BuildCertChain( + trustDomain, certInput, Now(), EndEntityOrCA::MustBeEndEntity, + KeyUsage::noParticularKeyUsageRequired, KeyPurposeId::id_kp_codeSigning, + CertPolicyId::anyPolicy, nullptr /*stapledOCSPResponse*/); + if (result != Success) { + // if there was a library error, return an appropriate error + if (IsFatalError(result)) { + return NS_ERROR_FAILURE; + } + // otherwise, assume the signature was invalid + if (result == mozilla::pkix::Result::ERROR_EXPIRED_CERTIFICATE) { + aErrorLabel = + Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err4; + aErrorValue = 4; + } else if (result == + mozilla::pkix::Result::ERROR_NOT_YET_VALID_CERTIFICATE) { + aErrorLabel = + Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err5; + aErrorValue = 5; + } else { + // Building cert chain failed for some other reason. + aErrorLabel = + Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err6; + aErrorValue = 6; + } + CSVerifier_LOG(("CSVerifier: The supplied chain is bad (%s)", + MapResultToName(result))); + return NS_ERROR_INVALID_SIGNATURE; + } + + // Check the SAN + Input hostnameInput; + + result = hostnameInput.Init( + BitwiseCast(aHostname.BeginReading()), + aHostname.Length()); + if (result != Success) { + return NS_ERROR_FAILURE; + } + + BRNameMatchingPolicy nameMatchingPolicy(BRNameMatchingPolicy::Mode::Enforce); + result = CheckCertHostname(certInput, hostnameInput, nameMatchingPolicy); + if (result != Success) { + // EE cert isnot valid for the given host name. + aErrorLabel = Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err7; + aErrorValue = 7; + return NS_ERROR_INVALID_SIGNATURE; + } + + pkix::BackCert backCert(certInput, EndEntityOrCA::MustBeEndEntity, nullptr); + result = backCert.Init(); + // This should never fail, because we've already built a verified certificate + // chain with this certificate. + if (result != Success) { + aErrorLabel = Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err8; + aErrorValue = 8; + CSVerifier_LOG(("CSVerifier: couldn't decode certificate to get spki")); + return NS_ERROR_INVALID_SIGNATURE; + } + Input spkiInput = backCert.GetSubjectPublicKeyInfo(); + SECItem spkiItem = {siBuffer, const_cast(spkiInput.UnsafeGetData()), + spkiInput.GetLength()}; + UniqueCERTSubjectPublicKeyInfo spki( + SECKEY_DecodeDERSubjectPublicKeyInfo(&spkiItem)); + if (!spki) { + aErrorLabel = Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err8; + aErrorValue = 8; + CSVerifier_LOG(("CSVerifier: couldn't decode spki")); + return NS_ERROR_INVALID_SIGNATURE; + } + mozilla::UniqueSECKEYPublicKey key(SECKEY_ExtractPublicKey(spki.get())); + if (!key) { + aErrorLabel = Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err8; + aErrorValue = 8; + CSVerifier_LOG(("CSVerifier: unable to extract a key")); + return NS_ERROR_INVALID_SIGNATURE; + } + + nsAutoCString signature; + rv = ParseContentSignatureHeader(aCSHeader, signature); + if (NS_FAILED(rv)) { + return rv; + } + + // Base 64 decode the signature + nsAutoCString rawSignature; + rv = Base64Decode(signature, rawSignature); + if (NS_FAILED(rv)) { + CSVerifier_LOG(("CSVerifier: decoding the signature failed")); + return rv; + } + + // get signature object + ScopedAutoSECItem signatureItem; + SECItem rawSignatureItem = { + siBuffer, + BitwiseCast(rawSignature.get()), + rawSignature.Length(), + }; + // We have a raw ecdsa signature r||s so we have to DER-encode it first + // Note that we have to check rawSignatureItem->len % 2 here as + // DSAU_EncodeDerSigWithLen asserts this + if (rawSignatureItem.len == 0 || rawSignatureItem.len % 2 != 0) { + CSVerifier_LOG(("CSVerifier: signature length is bad")); + return NS_ERROR_FAILURE; + } + if (DSAU_EncodeDerSigWithLen(&signatureItem, &rawSignatureItem, + rawSignatureItem.len) != SECSuccess) { + CSVerifier_LOG(("CSVerifier: encoding the signature failed")); + return NS_ERROR_FAILURE; + } + + // this is the only OID we support for now + SECOidTag oid = SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE; + mozilla::UniqueVFYContext cx( + VFY_CreateContext(key.get(), &signatureItem, oid, nullptr)); + if (!cx) { + // Creating context failed. + aErrorLabel = Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err9; + aErrorValue = 9; + return NS_ERROR_INVALID_SIGNATURE; + } + + if (VFY_Begin(cx.get()) != SECSuccess) { + // Creating context failed. + aErrorLabel = Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err9; + aErrorValue = 9; + return NS_ERROR_INVALID_SIGNATURE; + } + if (VFY_Update(cx.get(), kPREFIX, sizeof(kPREFIX)) != SECSuccess) { + aErrorLabel = Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err1; + aErrorValue = 1; + return NS_ERROR_INVALID_SIGNATURE; + } + if (VFY_Update(cx.get(), + reinterpret_cast(aData.BeginReading()), + aData.Length()) != SECSuccess) { + aErrorLabel = Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err1; + aErrorValue = 1; + return NS_ERROR_INVALID_SIGNATURE; + } + if (VFY_End(cx.get()) != SECSuccess) { + aErrorLabel = Telemetry::LABELS_CONTENT_SIGNATURE_VERIFICATION_ERRORS::err1; + aErrorValue = 1; + return NS_ERROR_INVALID_SIGNATURE; + } + + return NS_OK; +} + +static nsresult ParseContentSignatureHeader( + const nsACString& aContentSignatureHeader, + /* out */ nsCString& aSignature) { + // We only support p384 ecdsa. + constexpr auto signature_var = "p384ecdsa"_ns; + + aSignature.Truncate(); + + const nsCString& flatHeader = PromiseFlatCString(aContentSignatureHeader); + nsSecurityHeaderParser parser(flatHeader); + nsresult rv = parser.Parse(); + if (NS_FAILED(rv)) { + CSVerifier_LOG(("CSVerifier: could not parse ContentSignature header")); + return NS_ERROR_FAILURE; + } + LinkedList* directives = parser.GetDirectives(); + + for (nsSecurityHeaderDirective* directive = directives->getFirst(); + directive != nullptr; directive = directive->getNext()) { + CSVerifier_LOG( + ("CSVerifier: found directive '%s'", directive->mName.get())); + if (directive->mName.Length() == signature_var.Length() && + directive->mName.EqualsIgnoreCase(signature_var.get(), + signature_var.Length())) { + if (!aSignature.IsEmpty()) { + CSVerifier_LOG(("CSVerifier: found two ContentSignatures")); + return NS_ERROR_INVALID_SIGNATURE; + } + + CSVerifier_LOG(("CSVerifier: found a ContentSignature directive")); + aSignature.Assign(directive->mValue); + } + } + + // we have to ensure that we found a signature at this point + if (aSignature.IsEmpty()) { + CSVerifier_LOG( + ("CSVerifier: got a Content-Signature header but didn't find a " + "signature.")); + return NS_ERROR_FAILURE; + } + + // Bug 769521: We have to change b64 url to regular encoding as long as we + // don't have a b64 url decoder. This should change soon, but in the meantime + // we have to live with this. + aSignature.ReplaceChar('-', '+'); + aSignature.ReplaceChar('_', '/'); + + return NS_OK; +} diff --git a/security/manager/ssl/ContentSignatureVerifier.h b/security/manager/ssl/ContentSignatureVerifier.h new file mode 100644 index 0000000000..a10c9fe89c --- /dev/null +++ b/security/manager/ssl/ContentSignatureVerifier.h @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef ContentSignatureVerifier_h +#define ContentSignatureVerifier_h + +#include "nsIContentSignatureVerifier.h" +#include "nsString.h" + +// 45a5fe2f-c350-4b86-962d-02d5aaaa955a +#define NS_CONTENTSIGNATUREVERIFIER_CID \ + { \ + 0x45a5fe2f, 0xc350, 0x4b86, { \ + 0x96, 0x2d, 0x02, 0xd5, 0xaa, 0xaa, 0x95, 0x5a \ + } \ + } +#define NS_CONTENTSIGNATUREVERIFIER_CONTRACTID \ + "@mozilla.org/security/contentsignatureverifier;1" + +class ContentSignatureVerifier final : public nsIContentSignatureVerifier { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSICONTENTSIGNATUREVERIFIER + + private: + ~ContentSignatureVerifier() = default; +}; + +#endif // ContentSignatureVerifier_h diff --git a/security/manager/ssl/CredentialManagerSecret.cpp b/security/manager/ssl/CredentialManagerSecret.cpp new file mode 100644 index 0000000000..8c1e6d8461 --- /dev/null +++ b/security/manager/ssl/CredentialManagerSecret.cpp @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "CredentialManagerSecret.h" + +#include +#include + +#include "mozilla/Logging.h" +#include "mozilla/SyncRunnable.h" + +// This is the implementation of CredentialManagerSecretSecret, an instantiation +// of OSKeyStore for Windows. It uses the system credential manager, hence the +// name. + +using namespace mozilla; + +LazyLogModule gCredentialManagerSecretLog("credentialmanagersecret"); +struct ScopedDelete { + void operator()(CREDENTIALA* cred) { CredFree(cred); } +}; + +template +struct ScopedMaybeDelete { + void operator()(T* ptr) { + if (ptr) { + ScopedDelete del; + del(ptr); + } + } +}; +typedef std::unique_ptr> + ScopedCREDENTIALA; + +CredentialManagerSecret::CredentialManagerSecret() {} + +CredentialManagerSecret::~CredentialManagerSecret() {} + +nsresult CredentialManagerSecret::Lock() { + // The Windows credential manager can't be locked. + return NS_OK; +} + +nsresult CredentialManagerSecret::Unlock() { + // The Windows credential manager is always unlocked when the user is logged + // in. + return NS_OK; +} + +nsresult CredentialManagerSecret::StoreSecret(const nsACString& aSecret, + const nsACString& aLabel) { + if (aSecret.Length() > CRED_MAX_CREDENTIAL_BLOB_SIZE) { + // Windows doesn't allow blobs larger than CRED_MAX_CREDENTIAL_BLOB_SIZE + // bytes. + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("StoreSecret secret must not be larger than 512 bytes (got %d)", + aSecret.Length())); + return NS_ERROR_FAILURE; + } + CREDENTIALA cred = {0}; + cred.Type = CRED_TYPE_GENERIC; + const nsCString& label = PromiseFlatCString(aLabel); + cred.TargetName = const_cast(label.get()); + cred.CredentialBlobSize = aSecret.Length(); + const nsCString& secret = PromiseFlatCString(aSecret); + cred.CredentialBlob = (LPBYTE)secret.get(); + cred.Persist = CRED_PERSIST_LOCAL_MACHINE; + cred.UserName = const_cast(""); // -Wwritable-strings + + // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credwritea + BOOL ok = CredWriteA(&cred, 0); + if (!ok) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("CredWriteW failed %d", GetLastError())); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult CredentialManagerSecret::DeleteSecret(const nsACString& aLabel) { + // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-creddeletea + const nsCString& label = PromiseFlatCString(aLabel); + BOOL ok = CredDeleteA(label.get(), CRED_TYPE_GENERIC, 0); + int error = GetLastError(); + if (!ok && error != ERROR_NOT_FOUND) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("CredDeleteA failed %d", error)); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult CredentialManagerSecret::RetrieveSecret( + const nsACString& aLabel, + /* out */ nsACString& aSecret) { + aSecret.Truncate(); + PCREDENTIALA pcred_raw = nullptr; + const nsCString& label = PromiseFlatCString(aLabel); + // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-credreada + BOOL ok = CredReadA(label.get(), CRED_TYPE_GENERIC, 0, &pcred_raw); + ScopedCREDENTIALA pcred(pcred_raw); + if (!ok) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("CredReadA failed %d", GetLastError())); + return NS_ERROR_FAILURE; + } + MOZ_ASSERT(pcred); + aSecret.Assign(reinterpret_cast(pcred->CredentialBlob), + pcred->CredentialBlobSize); + return NS_OK; +} diff --git a/security/manager/ssl/CredentialManagerSecret.h b/security/manager/ssl/CredentialManagerSecret.h new file mode 100644 index 0000000000..52873151e7 --- /dev/null +++ b/security/manager/ssl/CredentialManagerSecret.h @@ -0,0 +1,28 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef CredentialManagerSecret_h +#define CredentialManagerSecret_h + +#include "OSKeyStore.h" +#include "nsString.h" + +class CredentialManagerSecret final : public AbstractOSKeyStore { + public: + CredentialManagerSecret(); + + virtual nsresult RetrieveSecret(const nsACString& label, + /* out */ nsACString& secret) override; + virtual nsresult StoreSecret(const nsACString& secret, + const nsACString& label) override; + virtual nsresult DeleteSecret(const nsACString& label) override; + virtual nsresult Lock() override; + virtual nsresult Unlock() override; + + virtual ~CredentialManagerSecret(); +}; + +#endif // CredentialManagerSecret_h diff --git a/security/manager/ssl/CryptoTask.cpp b/security/manager/ssl/CryptoTask.cpp new file mode 100644 index 0000000000..a466a374f6 --- /dev/null +++ b/security/manager/ssl/CryptoTask.cpp @@ -0,0 +1,43 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "CryptoTask.h" +#include "nsNSSComponent.h" +#include "nsNetCID.h" + +namespace mozilla { + +nsresult CryptoTask::Dispatch() { + // Ensure that NSS is initialized, since presumably CalculateResult + // will use NSS functions + if (!EnsureNSSInitializedChromeOrContent()) { + return NS_ERROR_FAILURE; + } + + // The stream transport service (note: not the socket transport service) can + // be used to perform background tasks or I/O that would otherwise block the + // main thread. + nsCOMPtr target( + do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID)); + if (!target) { + return NS_ERROR_FAILURE; + } + return target->Dispatch(this, NS_DISPATCH_NORMAL); +} + +NS_IMETHODIMP +CryptoTask::Run() { + if (!NS_IsMainThread()) { + mRv = CalculateResult(); + NS_DispatchToMainThread(this); + } else { + // back on the main thread + CallCallback(mRv); + } + return NS_OK; +} + +} // namespace mozilla diff --git a/security/manager/ssl/CryptoTask.h b/security/manager/ssl/CryptoTask.h new file mode 100644 index 0000000000..2cbd082d7a --- /dev/null +++ b/security/manager/ssl/CryptoTask.h @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla__CryptoTask_h +#define mozilla__CryptoTask_h + +#include "mozilla/Attributes.h" +#include "nsThreadUtils.h" + +namespace mozilla { + +/** + * Frequently we need to run a task on a background thread without blocking + * the main thread, and then call a callback on the main thread with the + * result. This class provides the framework for that. Subclasses must: + * + * (1) Override CalculateResult for the off-the-main-thread computation. + * (2) Override CallCallback() for the on-the-main-thread call of the + * callback. + */ +class CryptoTask : public Runnable { + public: + nsresult Dispatch(); + + protected: + CryptoTask() : Runnable("CryptoTask"), mRv(NS_ERROR_NOT_INITIALIZED) {} + + virtual ~CryptoTask() = default; + + /** + * Called on a background thread (never the main thread). Its result will be + * passed to CallCallback on the main thread. + */ + virtual nsresult CalculateResult() = 0; + + /** + * Called on the main thread with the result from CalculateResult(). + */ + virtual void CallCallback(nsresult rv) = 0; + + private: + NS_IMETHOD Run() final; + + nsresult mRv; +}; + +} // namespace mozilla + +#endif // mozilla__CryptoTask_h diff --git a/security/manager/ssl/DER.jsm b/security/manager/ssl/DER.jsm new file mode 100644 index 0000000000..15dc65a358 --- /dev/null +++ b/security/manager/ssl/DER.jsm @@ -0,0 +1,320 @@ +/* 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/. */ + +"use strict"; + +// A minimal ASN.1 DER decoder. Supports input lengths up to 65539 (one byte for +// the outer tag, one byte for the 0x82 length-length indicator, two bytes +// indicating a contents length of 65535, and then the 65535 bytes of contents). +// Intended to be used like so: +// +// let bytes = ; +// let der = new DER.DERDecoder(bytes); +// let contents = new DER.DERDecoder(der.readTagAndGetContents(DER.SEQUENCE)); +// while (!contents.atEnd()) { +// let integerBytes = contents.readTagAndGetContents(DER.INTEGER); +// <... do something with integerBytes ...> +// } +// der.assertAtEnd(); +// +// For CHOICE, use readTLVChoice and pass an array of acceptable tags. +// The convenience function readBIT_STRING is provided to handle the unused bits +// aspect of BIT STRING. It returns an object that has the properties contents +// (an array of bytes consisting of the bytes making up the BIT STRING) and +// unusedBits (indicating the number of unused bits at the end). +// All other functions generally return an array of bytes or a single byte as +// appropriate. +// peekTag can be used to see if the next tag is an expected given tag. +// readTLV reads and returns an entire (tag, length, value) tuple (again +// returned as an array of bytes). + +const UNIVERSAL = 0 << 6; +const CONSTRUCTED = 1 << 5; +const CONTEXT_SPECIFIC = 2 << 6; + +const INTEGER = UNIVERSAL | 0x02; // 0x02 +const BIT_STRING = UNIVERSAL | 0x03; // 0x03 +const NULL = UNIVERSAL | 0x05; // 0x05 +const OBJECT_IDENTIFIER = UNIVERSAL | 0x06; // 0x06 +const PrintableString = UNIVERSAL | 0x13; // 0x13 +const TeletexString = UNIVERSAL | 0x14; // 0x14 +const IA5String = UNIVERSAL | 0x16; // 0x16 +const UTCTime = UNIVERSAL | 0x17; // 0x17 +const GeneralizedTime = UNIVERSAL | 0x18; // 0x18 +const UTF8String = UNIVERSAL | 0x0c; // 0x0c +const SEQUENCE = UNIVERSAL | CONSTRUCTED | 0x10; // 0x30 +const SET = UNIVERSAL | CONSTRUCTED | 0x11; // 0x31 + +const ERROR_INVALID_INPUT = "invalid input"; +const ERROR_DATA_TRUNCATED = "data truncated"; +const ERROR_EXTRA_DATA = "extra data"; +const ERROR_INVALID_LENGTH = "invalid length"; +const ERROR_UNSUPPORTED_ASN1 = "unsupported asn.1"; +const ERROR_UNSUPPORTED_LENGTH = "unsupported length"; +const ERROR_INVALID_BIT_STRING = "invalid BIT STRING encoding"; + +/** Class representing a decoded BIT STRING. */ +class BitString { + /** + * @param {Number} unusedBits the number of unused bits + * @param {Number[]} contents an array of bytes comprising the BIT STRING + */ + constructor(unusedBits, contents) { + this._unusedBits = unusedBits; + this._contents = contents; + } + + /** + * Get the number of unused bits in the BIT STRING + * @return {Number} the number of unused bits + */ + get unusedBits() { + return this._unusedBits; + } + + /** + * Get the contents of the BIT STRING + * @return {Number[]} an array of bytes representing the contents + */ + get contents() { + return this._contents; + } +} + +/** Class representing DER-encoded data. Provides methods for decoding it. */ +class DERDecoder { + /** + * @param {Number[]} bytes an array of bytes representing the encoded data + */ + constructor(bytes) { + // Reject non-array inputs. + if (!Array.isArray(bytes)) { + throw new Error(ERROR_INVALID_INPUT); + } + if (bytes.length > 65539) { + throw new Error(ERROR_UNSUPPORTED_LENGTH); + } + // Reject inputs containing non-integer values or values too small or large. + if (bytes.some(b => !Number.isInteger(b) || b < 0 || b > 255)) { + throw new Error(ERROR_INVALID_INPUT); + } + this._bytes = bytes; + this._cursor = 0; + } + + /** + * Asserts that the decoder is at the end of the given data. Throws an error + * if this is not the case. + */ + assertAtEnd() { + if (!this.atEnd()) { + throw new Error(ERROR_EXTRA_DATA); + } + } + + /** + * Determines whether or not the decoder is at the end of the given data. + * @return {Boolean} true if the decoder is at the end and false otherwise + */ + atEnd() { + return this._cursor == this._bytes.length; + } + + /** + * Reads the next byte of data. Throws if no more data is available. + * @return {Number} the next byte of data + */ + readByte() { + if (this._cursor >= this._bytes.length) { + throw new Error(ERROR_DATA_TRUNCATED); + } + let val = this._bytes[this._cursor]; + this._cursor++; + return val; + } + + /** + * Given the next expected tag, reads and asserts that the next tag is in fact + * the given tag. + * @param {Number} expectedTag the expected next tag + */ + _readExpectedTag(expectedTag) { + let tag = this.readByte(); + if (tag != expectedTag) { + throw new Error(`unexpected tag: found ${tag} instead of ${expectedTag}`); + } + } + + /** + * Decodes and returns the length portion of an ASN.1 TLV tuple. Throws if the + * length is incorrectly encoded or if it describes a length greater than + * 65535 bytes. Indefinite-length encoding is not supported. + * @return {Number} the length of the value of the TLV tuple + */ + _readLength() { + let nextByte = this.readByte(); + if (nextByte < 0x80) { + return nextByte; + } + if (nextByte == 0x80) { + throw new Error(ERROR_UNSUPPORTED_ASN1); + } + if (nextByte == 0x81) { + let length = this.readByte(); + if (length < 0x80) { + throw new Error(ERROR_INVALID_LENGTH); + } + return length; + } + if (nextByte == 0x82) { + let length1 = this.readByte(); + let length2 = this.readByte(); + let length = (length1 << 8) | length2; + if (length < 256) { + throw new Error(ERROR_INVALID_LENGTH); + } + return length; + } + throw new Error(ERROR_UNSUPPORTED_LENGTH); + } + + /** + * Reads bytes of data if available. Throws if less than + * bytes are available. + * @param {Number} length the number of bytes to read. Must be non-negative. + * @return {Number[]} the next bytes of data + */ + readBytes(length) { + if (length < 0) { + throw new Error(ERROR_INVALID_LENGTH); + } + let bytes = []; + for (let i = 0; i < length; i++) { + bytes.push(this.readByte()); + } + return bytes; + } + + /** + * Given an expected next ASN.1 tag, ensures that that tag is next and returns + * the contents of that tag. Throws if a different tag is encountered or if + * the data is otherwise incorrectly encoded. + * @param {Number} tag the next expected ASN.1 tag + * @return {Number[]} the contents of the tag + */ + readTagAndGetContents(tag) { + this._readExpectedTag(tag); + let length = this._readLength(); + return this.readBytes(length); + } + + /** + * Returns the next byte without advancing the decoder. Throws if no more data + * is available. + * @return {Number} the next available byte + */ + _peekByte() { + if (this._cursor >= this._bytes.length) { + throw new Error(ERROR_DATA_TRUNCATED); + } + return this._bytes[this._cursor]; + } + + /** + * Given an expected tag, reads the next entire ASN.1 TLV tuple, asserting + * that the tag matches. + * @param {Number} tag the expected tag + * @return {Number[]} an array of bytes representing the TLV tuple + */ + _readExpectedTLV(tag) { + let mark = this._cursor; + this._readExpectedTag(tag); + let length = this._readLength(); + // read the bytes so we know they're there (also to advance the cursor) + this.readBytes(length); + return this._bytes.slice(mark, this._cursor); + } + + /** + * Reads the next ASN.1 tag, length, and value and returns them as an array of + * bytes. + * @return {Number[]} an array of bytes representing the next ASN.1 TLV + */ + readTLV() { + let nextTag = this._peekByte(); + return this._readExpectedTLV(nextTag); + } + + /** + * Convenience function for decoding a BIT STRING. Reads and returns the + * contents of the expected next BIT STRING. Throws if the next TLV isn't a + * BIT STRING or if the BIT STRING is incorrectly encoded. + * @return {BitString} the next BIT STRING + */ + readBIT_STRING() { + let contents = this.readTagAndGetContents(BIT_STRING); + if (contents.length < 1) { + throw new Error(ERROR_INVALID_BIT_STRING); + } + let unusedBits = contents[0]; + if (unusedBits > 7) { + throw new Error(ERROR_INVALID_BIT_STRING); + } + // Zero bytes of content but some amount of padding is invalid. + if (contents.length == 1 && unusedBits != 0) { + throw new Error(ERROR_INVALID_BIT_STRING); + } + return new BitString(unusedBits, contents.slice(1, contents.length)); + } + + /** + * Looks to see if the next ASN.1 tag is the expected given tag. + * @param {Number} tag the expected next ASN.1 tag + * @return {Boolean} true if the next tag is the given one and false otherwise + */ + peekTag(tag) { + if (this._cursor >= this._bytes.length) { + return false; + } + return this._bytes[this._cursor] == tag; + } + + /** + * Given a list of possible next ASN.1 tags, returns the next TLV if the next + * tag is in the list. Throws if the next tag is not in the list or if the + * data is incorrectly encoded. + * @param {Number[]} tagList the list of potential next tags + * @return {Number[]} the contents of the next TLV if the next tag is in + * + */ + readTLVChoice(tagList) { + let tag = this._peekByte(); + if (!tagList.includes(tag)) { + throw new Error( + `unexpected tag: found ${tag} instead of one of ${tagList}` + ); + } + return this._readExpectedTLV(tag); + } +} + +const DER = { + UNIVERSAL, + CONSTRUCTED, + CONTEXT_SPECIFIC, + INTEGER, + BIT_STRING, + NULL, + OBJECT_IDENTIFIER, + PrintableString, + TeletexString, + IA5String, + UTCTime, + GeneralizedTime, + UTF8String, + SEQUENCE, + SET, + DERDecoder, +}; +var EXPORTED_SYMBOLS = ["DER"]; diff --git a/security/manager/ssl/DataStorage.cpp b/security/manager/ssl/DataStorage.cpp new file mode 100644 index 0000000000..4467df0eea --- /dev/null +++ b/security/manager/ssl/DataStorage.cpp @@ -0,0 +1,1086 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "DataStorage.h" + +#include "mozilla/Assertions.h" +#include "mozilla/AppShutdown.h" +#include "mozilla/ClearOnShutdown.h" +#include "mozilla/dom/PContent.h" +#include "mozilla/dom/ContentParent.h" +#include "mozilla/FileUtils.h" +#include "mozilla/Preferences.h" +#include "mozilla/Services.h" +#include "mozilla/StaticMutex.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/TaskQueue.h" +#include "mozilla/Telemetry.h" +#include "mozilla/Unused.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsDirectoryServiceUtils.h" +#include "nsIFileStreams.h" +#include "nsIMemoryReporter.h" +#include "nsIObserverService.h" +#include "nsISerialEventTarget.h" +#include "nsITimer.h" +#include "nsIThread.h" +#include "nsNetUtil.h" +#include "nsPrintfCString.h" +#include "nsStreamUtils.h" +#include "nsThreadUtils.h" +#include "private/pprio.h" + +#if defined(XP_WIN) +# include "nsILocalFileWin.h" +#endif + +// NB: Read DataStorage.h first. + +// The default time between data changing and a write, in milliseconds. +static const uint32_t sDataStorageDefaultTimerDelay = 5u * 60u * 1000u; +// The maximum score an entry can have (prevents overflow) +static const uint32_t sMaxScore = UINT32_MAX; +// The maximum number of entries per type of data (limits resource use) +static const uint32_t sMaxDataEntries = 1024; +static const int64_t sOneDayInMicroseconds = + int64_t(24 * 60 * 60) * PR_USEC_PER_SEC; + +namespace mozilla { + +class DataStorageMemoryReporter final : public nsIMemoryReporter { + MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf) + ~DataStorageMemoryReporter() = default; + + public: + NS_DECL_ISUPPORTS + + NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport, + nsISupports* aData, bool aAnonymize) final { + nsTArray fileNames; + DataStorage::GetAllFileNames(fileNames); + for (const auto& file : fileNames) { + RefPtr ds = DataStorage::GetFromRawFileName(file); + size_t amount = ds->SizeOfIncludingThis(MallocSizeOf); + nsPrintfCString path("explicit/data-storage/%s", + NS_ConvertUTF16toUTF8(file).get()); + Unused << aHandleReport->Callback( + ""_ns, path, KIND_HEAP, UNITS_BYTES, amount, + "Memory used by PSM data storage cache."_ns, aData); + } + return NS_OK; + } +}; + +NS_IMPL_ISUPPORTS(DataStorageMemoryReporter, nsIMemoryReporter) + +NS_IMPL_ISUPPORTS(DataStorage, nsIObserver) + +mozilla::StaticAutoPtr DataStorage::sDataStorages; + +DataStorage::DataStorage(const nsString& aFilename) + : mMutex("DataStorage::mMutex"), + mPendingWrite(false), + mShuttingDown(false), + mInitCalled(false), + mReadyMonitor("DataStorage::mReadyMonitor"), + mReady(false), + mFilename(aFilename) {} + +// static +already_AddRefed DataStorage::Get(DataStorageClass aFilename) { + switch (aFilename) { +#define DATA_STORAGE(_) \ + case DataStorageClass::_: \ + return GetFromRawFileName(NS_LITERAL_STRING_FROM_CSTRING(#_ ".txt")); +#include "mozilla/DataStorageList.h" +#undef DATA_STORAGE + default: + MOZ_ASSERT_UNREACHABLE("Invalid DataStorage type passed?"); + return nullptr; + } +} + +// static +already_AddRefed DataStorage::GetFromRawFileName( + const nsString& aFilename) { + MOZ_ASSERT(NS_IsMainThread()); + if (!sDataStorages) { + sDataStorages = new DataStorages(); + ClearOnShutdown(&sDataStorages); + } + RefPtr storage; + if (!sDataStorages->Get(aFilename, getter_AddRefs(storage))) { + storage = new DataStorage(aFilename); + sDataStorages->Put(aFilename, RefPtr{storage}); + } + return storage.forget(); +} + +// static +void DataStorage::GetAllFileNames(nsTArray& aItems) { + MOZ_ASSERT(NS_IsMainThread()); + if (!sDataStorages) { + return; + } +#define DATA_STORAGE(_) \ + aItems.AppendElement(NS_LITERAL_STRING_FROM_CSTRING(#_ ".txt")); +#include "mozilla/DataStorageList.h" +#undef DATA_STORAGE +} + +// static +void DataStorage::GetAllChildProcessData( + nsTArray& aEntries) { + nsTArray storageFiles; + GetAllFileNames(storageFiles); + for (auto& file : storageFiles) { + psm::DataStorageEntry entry; + entry.filename() = file; + RefPtr storage = DataStorage::GetFromRawFileName(file); + if (!storage->mInitCalled) { + // Perhaps no consumer has initialized the DataStorage object yet, + // so do that now! + nsresult rv = storage->Init(nullptr); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + } + storage->GetAll(&entry.items()); + aEntries.AppendElement(std::move(entry)); + } +} + +// static +void DataStorage::SetCachedStorageEntries( + const nsTArray& aEntries) { + MOZ_ASSERT(XRE_IsContentProcess()); + + // Make sure to initialize all DataStorage classes. + // For each one, we look through the list of our entries and if we find + // a matching DataStorage object, we initialize it. + // + // Note that this is an O(n^2) operation, but the n here is very small + // (currently 3). There is a comment in the DataStorageList.h header + // about updating the algorithm here to something more fancy if the list + // of DataStorage items grows some day. + nsTArray entries; +#define DATA_STORAGE(_) \ + { \ + psm::DataStorageEntry entry; \ + entry.filename() = NS_LITERAL_STRING_FROM_CSTRING(#_ ".txt"); \ + for (auto& e : aEntries) { \ + if (entry.filename().Equals(e.filename())) { \ + entry.items() = e.items().Clone(); \ + break; \ + } \ + } \ + entries.AppendElement(std::move(entry)); \ + } +#include "mozilla/DataStorageList.h" +#undef DATA_STORAGE + + for (auto& entry : entries) { + RefPtr storage = + DataStorage::GetFromRawFileName(entry.filename()); + storage->Init(&entry.items()); + } +} + +size_t DataStorage::SizeOfIncludingThis( + mozilla::MallocSizeOf aMallocSizeOf) const { + size_t sizeOfExcludingThis = + mPersistentDataTable.ShallowSizeOfExcludingThis(aMallocSizeOf) + + mTemporaryDataTable.ShallowSizeOfExcludingThis(aMallocSizeOf) + + mPrivateDataTable.ShallowSizeOfExcludingThis(aMallocSizeOf) + + mFilename.SizeOfExcludingThisIfUnshared(aMallocSizeOf); + return aMallocSizeOf(this) + sizeOfExcludingThis; +} + +nsresult DataStorage::Init(const nsTArray* aItems, + mozilla::ipc::FileDescriptor aWriteFd) { + // Don't access the observer service or preferences off the main thread. + if (!NS_IsMainThread()) { + MOZ_ASSERT_UNREACHABLE("DataStorage::Init called off main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + + if (AppShutdown::IsShuttingDown()) { + // Reject new DataStorage instances if the browser is shutting down. There + // is no guarantee that DataStorage writes will be able to be persisted if + // we init during shutdown, so we return an error here to hopefully make + // this more explicit and consistent. + return NS_ERROR_NOT_AVAILABLE; + } + + MutexAutoLock lock(mMutex); + + // Ignore attempts to initialize several times. + if (mInitCalled) { + return NS_OK; + } + + mInitCalled = true; + + static bool memoryReporterRegistered = false; + if (!memoryReporterRegistered) { + nsresult rv = RegisterStrongMemoryReporter(new DataStorageMemoryReporter()); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + memoryReporterRegistered = true; + } + + if (XRE_IsParentProcess() || XRE_IsSocketProcess()) { + nsCOMPtr target; + nsresult rv = NS_CreateBackgroundTaskQueue( + "DataStorage::mBackgroundTaskQueue", getter_AddRefs(target)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + mBackgroundTaskQueue = new TaskQueue(target.forget()); + + // For test purposes, we can set the write timer to be very fast. + uint32_t timerDelayMS = Preferences::GetInt( + "test.datastorage.write_timer_ms", sDataStorageDefaultTimerDelay); + rv = NS_NewTimerWithFuncCallback( + getter_AddRefs(mTimer), DataStorage::TimerCallback, this, timerDelayMS, + nsITimer::TYPE_REPEATING_SLACK_LOW_PRIORITY, "DataStorageTimer", + mBackgroundTaskQueue); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + } + + if (XRE_IsParentProcess()) { + MOZ_ASSERT(!aItems); + + nsresult rv = AsyncReadData(lock); + if (NS_FAILED(rv)) { + return rv; + } + } else { + // In the child process and socket process, we use the data passed to us by + // the parent process to initialize. + MOZ_ASSERT(XRE_IsContentProcess() || XRE_IsSocketProcess()); + MOZ_ASSERT(aItems); + + if (XRE_IsSocketProcess() && aWriteFd.IsValid()) { + mWriteFd = aWriteFd; + } + + for (auto& item : *aItems) { + Entry entry; + entry.mValue = item.value(); + nsresult rv = PutInternal(item.key(), entry, item.type(), lock); + if (NS_FAILED(rv)) { + return rv; + } + } + mReady = true; + NotifyObservers("data-storage-ready"); + } + + nsCOMPtr os = services::GetObserverService(); + if (NS_WARN_IF(!os)) { + return NS_ERROR_FAILURE; + } + // Clear private data as appropriate. + os->AddObserver(this, "last-pb-context-exited", false); + if (XRE_IsParentProcess() || XRE_IsSocketProcess()) { + // Observe shutdown; save data and prevent any further writes. + // In the parent process, we need to write to the profile directory, so + // we should listen for profile-before-change so that we can safely write to + // the profile. + os->AddObserver(this, "profile-before-change", false); + // In the Parent process, this is a backstop for xpcshell and other cases + // where profile-before-change might not get sent. + os->AddObserver(this, "xpcom-shutdown-threads", false); + } + + return NS_OK; +} + +class DataStorage::Opener : public Runnable { + public: + explicit Opener( + nsIFile* aFile, + std::function&& aResolver) + : Runnable("DataStorage::Opener"), + mFile(aFile), + mResolver(std::move(aResolver)) { + MOZ_ASSERT(mFile); + } + ~Opener() = default; + + private: + NS_DECL_NSIRUNNABLE + + void ResolveFD(); + + nsCOMPtr mFile; + std::function mResolver; + mozilla::ipc::FileDescriptor mFd; +}; + +void DataStorage::Opener::ResolveFD() { + MOZ_ASSERT(NS_IsMainThread()); + + mResolver(std::move(mFd)); +} + +NS_IMETHODIMP +DataStorage::Opener::Run() { + AutoFDClose prFileDesc; + nsresult rv; + +#if defined(XP_WIN) + nsCOMPtr winFile = do_QueryInterface(mFile, &rv); + MOZ_ASSERT(winFile); + if (NS_SUCCEEDED(rv)) { + rv = winFile->OpenNSPRFileDescShareDelete( + PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664, &prFileDesc.rwget()); + } +#else + rv = mFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0664, + &prFileDesc.rwget()); +#endif /* XP_WIN */ + + if (NS_SUCCEEDED(rv)) { + mFd = mozilla::ipc::FileDescriptor( + mozilla::ipc::FileDescriptor::PlatformHandleType( + PR_FileDesc2NativeHandle(prFileDesc))); + } + + RefPtr self = this; + rv = NS_DispatchToMainThread( + NS_NewRunnableFunction("DataStorage::Opener::ResolveFD", + [self]() { self->ResolveFD(); }), + NS_DISPATCH_NORMAL); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + + return NS_OK; +} + +nsresult DataStorage::AsyncTakeFileDesc( + std::function&& aResolver) { + MOZ_ASSERT(XRE_IsParentProcess()); + + WaitForReady(); + MutexAutoLock lock(mMutex); + if (!mBackingFile) { + return NS_ERROR_NOT_AVAILABLE; + } + + nsCOMPtr job(new Opener(mBackingFile, std::move(aResolver))); + nsresult rv = mBackgroundTaskQueue->Dispatch(job.forget()); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + mBackingFile = nullptr; + return NS_OK; +} + +class DataStorage::Reader : public Runnable { + public: + explicit Reader(DataStorage* aDataStorage) + : Runnable("DataStorage::Reader"), mDataStorage(aDataStorage) {} + ~Reader(); + + private: + NS_DECL_NSIRUNNABLE + + static nsresult ParseLine(nsDependentCSubstring& aLine, nsCString& aKeyOut, + Entry& aEntryOut); + + RefPtr mDataStorage; +}; + +DataStorage::Reader::~Reader() { + // Notify that calls to Get can proceed. + { + MonitorAutoLock readyLock(mDataStorage->mReadyMonitor); + mDataStorage->mReady = true; + mDataStorage->mReadyMonitor.NotifyAll(); + } + + // This is for tests. + nsCOMPtr job = NewRunnableMethod( + "DataStorage::NotifyObservers", mDataStorage, + &DataStorage::NotifyObservers, "data-storage-ready"); + nsresult rv = NS_DispatchToMainThread(job, NS_DISPATCH_NORMAL); + Unused << NS_WARN_IF(NS_FAILED(rv)); +} + +NS_IMETHODIMP +DataStorage::Reader::Run() { + nsresult rv; + // Concurrent operations on nsIFile objects are not guaranteed to be safe, + // so we clone the file while holding the lock and then release the lock. + // At that point, we can safely operate on the clone. + nsCOMPtr file; + { + MutexAutoLock lock(mDataStorage->mMutex); + // If we don't have a profile, bail. + if (!mDataStorage->mBackingFile) { + return NS_OK; + } + rv = mDataStorage->mBackingFile->Clone(getter_AddRefs(file)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + } + nsCOMPtr fileInputStream; + rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), file); + // If we failed for some reason other than the file doesn't exist, bail. + if (NS_WARN_IF(NS_FAILED(rv) && + rv != NS_ERROR_FILE_TARGET_DOES_NOT_EXIST && // on Unix + rv != NS_ERROR_FILE_NOT_FOUND)) { // on Windows + return rv; + } + + // If there is a file with data in it, read it. If there isn't, + // we'll essentially fall through to notifying that we're good to go. + nsCString data; + if (fileInputStream) { + // Limit to 2MB of data, but only store sMaxDataEntries entries. + rv = NS_ConsumeStream(fileInputStream, 1u << 21, data); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + } + + // Atomically parse the data and insert the entries read. + // Don't clear existing entries - they may have been inserted between when + // this read was kicked-off and when it was run. + { + MutexAutoLock lock(mDataStorage->mMutex); + // The backing file consists of a list of + // \t\t\t\n + // The final \n is not optional; if it is not present the line is assumed + // to be corrupt. + int32_t currentIndex = 0; + int32_t newlineIndex = 0; + do { + newlineIndex = data.FindChar('\n', currentIndex); + // If there are no more newlines or the data table has too many + // entries, we are done. + if (newlineIndex < 0 || + mDataStorage->mPersistentDataTable.Count() >= sMaxDataEntries) { + break; + } + + nsDependentCSubstring line(data, currentIndex, + newlineIndex - currentIndex); + currentIndex = newlineIndex + 1; + nsCString key; + Entry entry; + nsresult parseRV = ParseLine(line, key, entry); + if (NS_SUCCEEDED(parseRV)) { + // It could be the case that a newer entry was added before + // we got around to reading the file. Don't overwrite new entries. + Entry newerEntry; + bool present = mDataStorage->mPersistentDataTable.Get(key, &newerEntry); + if (!present) { + mDataStorage->mPersistentDataTable.Put(key, entry); + } + } + } while (true); + + Telemetry::Accumulate(Telemetry::DATA_STORAGE_ENTRIES, + mDataStorage->mPersistentDataTable.Count()); + } + + return NS_OK; +} + +// The key must be a non-empty string containing no instances of '\t' or '\n', +// and must have a length no more than 256. +// The value must not contain '\n' and must have a length no more than 1024. +// The length limits are to prevent unbounded memory and disk usage. +/* static */ +nsresult DataStorage::ValidateKeyAndValue(const nsCString& aKey, + const nsCString& aValue) { + if (aKey.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + if (aKey.Length() > 256) { + return NS_ERROR_INVALID_ARG; + } + int32_t delimiterIndex = aKey.FindChar('\t', 0); + if (delimiterIndex >= 0) { + return NS_ERROR_INVALID_ARG; + } + delimiterIndex = aKey.FindChar('\n', 0); + if (delimiterIndex >= 0) { + return NS_ERROR_INVALID_ARG; + } + delimiterIndex = aValue.FindChar('\n', 0); + if (delimiterIndex >= 0) { + return NS_ERROR_INVALID_ARG; + } + if (aValue.Length() > 1024) { + return NS_ERROR_INVALID_ARG; + } + + return NS_OK; +} + +// Each line is: \t\t\t +// Where is a uint32_t as a string, is a +// int32_t as a string, and the rest are strings. +// can contain anything but a newline. +// Returns a successful status if the line can be decoded into a key and entry. +// Otherwise, an error status is returned and the values assigned to the +// output parameters are in an undefined state. +/* static */ +nsresult DataStorage::Reader::ParseLine(nsDependentCSubstring& aLine, + nsCString& aKeyOut, Entry& aEntryOut) { + // First find the indices to each part of the line. + int32_t scoreIndex; + scoreIndex = aLine.FindChar('\t', 0) + 1; + if (scoreIndex <= 0) { + return NS_ERROR_UNEXPECTED; + } + int32_t accessedIndex = aLine.FindChar('\t', scoreIndex) + 1; + if (accessedIndex <= 0) { + return NS_ERROR_UNEXPECTED; + } + int32_t valueIndex = aLine.FindChar('\t', accessedIndex) + 1; + if (valueIndex <= 0) { + return NS_ERROR_UNEXPECTED; + } + + // Now make substrings based on where each part is. + nsDependentCSubstring keyPart(aLine, 0, scoreIndex - 1); + nsDependentCSubstring scorePart(aLine, scoreIndex, + accessedIndex - scoreIndex - 1); + nsDependentCSubstring accessedPart(aLine, accessedIndex, + valueIndex - accessedIndex - 1); + nsDependentCSubstring valuePart(aLine, valueIndex); + + nsresult rv; + rv = DataStorage::ValidateKeyAndValue(nsCString(keyPart), + nsCString(valuePart)); + if (NS_FAILED(rv)) { + return NS_ERROR_UNEXPECTED; + } + + // Now attempt to decode the score part as a uint32_t. + // XXX nsDependentCSubstring doesn't support ToInteger + int32_t integer = nsCString(scorePart).ToInteger(&rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + if (integer < 0) { + return NS_ERROR_UNEXPECTED; + } + aEntryOut.mScore = (uint32_t)integer; + + integer = nsCString(accessedPart).ToInteger(&rv); + if (NS_FAILED(rv)) { + return rv; + } + if (integer < 0) { + return NS_ERROR_UNEXPECTED; + } + aEntryOut.mLastAccessed = integer; + + // Now set the key and value. + aKeyOut.Assign(keyPart); + aEntryOut.mValue.Assign(valuePart); + + return NS_OK; +} + +nsresult DataStorage::AsyncReadData(const MutexAutoLock& /*aProofOfLock*/) { + MOZ_ASSERT(XRE_IsParentProcess()); + // Allocate a Reader so that even if it isn't dispatched, + // the data-storage-ready notification will be fired and Get + // will be able to proceed (this happens in its destructor). + nsCOMPtr job(new Reader(this)); + nsresult rv; + // If we don't have a profile directory, this will fail. + // That's okay - it just means there is no persistent state. + rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, + getter_AddRefs(mBackingFile)); + if (NS_FAILED(rv)) { + mBackingFile = nullptr; + return NS_OK; + } + + rv = mBackingFile->Append(mFilename); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + rv = mBackgroundTaskQueue->Dispatch(job.forget()); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return NS_OK; +} + +bool DataStorage::IsReady() { + MonitorAutoLock readyLock(mReadyMonitor); + return mReady; +} + +void DataStorage::WaitForReady() { + MOZ_DIAGNOSTIC_ASSERT(mInitCalled, "Waiting before Init() has been called?"); + + MonitorAutoLock readyLock(mReadyMonitor); + while (!mReady) { + readyLock.Wait(); + } + MOZ_ASSERT(mReady); +} + +nsCString DataStorage::Get(const nsCString& aKey, DataStorageType aType) { + WaitForReady(); + MutexAutoLock lock(mMutex); + + Entry entry; + bool foundValue = GetInternal(aKey, &entry, aType, lock); + if (!foundValue) { + return ""_ns; + } + + // If we're here, we found a value. Maybe update its score. + if (entry.UpdateScore()) { + PutInternal(aKey, entry, aType, lock); + } + + return entry.mValue; +} + +bool DataStorage::GetInternal(const nsCString& aKey, Entry* aEntry, + DataStorageType aType, + const MutexAutoLock& aProofOfLock) { + DataStorageTable& table = GetTableForType(aType, aProofOfLock); + bool foundValue = table.Get(aKey, aEntry); + return foundValue; +} + +DataStorage::DataStorageTable& DataStorage::GetTableForType( + DataStorageType aType, const MutexAutoLock& /*aProofOfLock*/) { + switch (aType) { + case DataStorage_Persistent: + return mPersistentDataTable; + case DataStorage_Temporary: + return mTemporaryDataTable; + case DataStorage_Private: + return mPrivateDataTable; + } + + MOZ_CRASH("given bad DataStorage storage type"); +} + +void DataStorage::ReadAllFromTable(DataStorageType aType, + nsTArray* aItems, + const MutexAutoLock& aProofOfLock) { + for (auto iter = GetTableForType(aType, aProofOfLock).Iter(); !iter.Done(); + iter.Next()) { + DataStorageItem* item = aItems->AppendElement(); + item->key() = iter.Key(); + item->value() = iter.Data().mValue; + item->type() = aType; + } +} + +void DataStorage::GetAll(nsTArray* aItems) { + WaitForReady(); + MutexAutoLock lock(mMutex); + + aItems->SetCapacity(mPersistentDataTable.Count() + + mTemporaryDataTable.Count() + mPrivateDataTable.Count()); + ReadAllFromTable(DataStorage_Persistent, aItems, lock); + ReadAllFromTable(DataStorage_Temporary, aItems, lock); + ReadAllFromTable(DataStorage_Private, aItems, lock); +} + +// Limit the number of entries per table. This is to prevent unbounded +// resource use. The eviction strategy is as follows: +// - An entry's score is incremented once for every day it is accessed. +// - Evict an entry with score no more than any other entry in the table +// (this is the same as saying evict the entry with the lowest score, +// except for when there are multiple entries with the lowest score, +// in which case one of them is evicted - which one is not specified). +void DataStorage::MaybeEvictOneEntry(DataStorageType aType, + const MutexAutoLock& aProofOfLock) { + DataStorageTable& table = GetTableForType(aType, aProofOfLock); + if (table.Count() >= sMaxDataEntries) { + KeyAndEntry toEvict; + // If all entries have score sMaxScore, this won't actually remove + // anything. This will never happen, however, because having that high + // a score either means someone tampered with the backing file or every + // entry has been accessed once a day for ~4 billion days. + // The worst that will happen is there will be 1025 entries in the + // persistent data table, with the 1025th entry being replaced every time + // data with a new key is inserted into the table. This is bad but + // ultimately not that concerning, considering that if an attacker can + // modify data in the profile, they can cause much worse harm. + toEvict.mEntry.mScore = sMaxScore; + + for (auto iter = table.Iter(); !iter.Done(); iter.Next()) { + Entry entry = iter.UserData(); + if (entry.mScore < toEvict.mEntry.mScore) { + toEvict.mKey = iter.Key(); + toEvict.mEntry = entry; + } + } + + table.Remove(toEvict.mKey); + } +} + +// NB: Because this may cross a thread boundary, any variables captured by the +// Functor must be captured by copy and not by reference. +template +static void RunOnAllContentParents(Functor func) { + if (!XRE_IsParentProcess()) { + return; + } + using dom::ContentParent; + + nsCOMPtr r = + NS_NewRunnableFunction("RunOnAllContentParents", [func]() { + nsTArray parents; + ContentParent::GetAll(parents); + for (auto& parent : parents) { + func(parent); + } + }); + MOZ_ALWAYS_SUCCEEDS(NS_DispatchToMainThread(r)); +} + +nsresult DataStorage::Put(const nsCString& aKey, const nsCString& aValue, + DataStorageType aType) { + WaitForReady(); + MutexAutoLock lock(mMutex); + + nsresult rv; + rv = ValidateKeyAndValue(aKey, aValue); + if (NS_FAILED(rv)) { + return rv; + } + + Entry entry; + bool exists = GetInternal(aKey, &entry, aType, lock); + if (exists) { + entry.UpdateScore(); + } else { + MaybeEvictOneEntry(aType, lock); + } + entry.mValue = aValue; + rv = PutInternal(aKey, entry, aType, lock); + if (NS_FAILED(rv)) { + return rv; + } + + nsString filename(mFilename); + RunOnAllContentParents( + [aKey, aValue, aType, filename](dom::ContentParent* aParent) { + DataStorageItem item; + item.key() = aKey; + item.value() = aValue; + item.type() = aType; + Unused << aParent->SendDataStoragePut(filename, item); + }); + + return NS_OK; +} + +nsresult DataStorage::PutInternal(const nsCString& aKey, Entry& aEntry, + DataStorageType aType, + const MutexAutoLock& aProofOfLock) { + DataStorageTable& table = GetTableForType(aType, aProofOfLock); + table.Put(aKey, aEntry); + + if (aType == DataStorage_Persistent) { + mPendingWrite = true; + } + + return NS_OK; +} + +void DataStorage::Remove(const nsCString& aKey, DataStorageType aType) { + WaitForReady(); + MutexAutoLock lock(mMutex); + + DataStorageTable& table = GetTableForType(aType, lock); + table.Remove(aKey); + + if (aType == DataStorage_Persistent) { + mPendingWrite = true; + } + + nsString filename(mFilename); + RunOnAllContentParents([filename, aKey, aType](dom::ContentParent* aParent) { + Unused << aParent->SendDataStorageRemove(filename, aKey, aType); + }); +} + +class DataStorage::Writer final : public Runnable { + public: + Writer(nsCString& aData, DataStorage* aDataStorage) + : Runnable("DataStorage::Writer"), + mData(aData), + mDataStorage(aDataStorage) {} + + protected: + NS_DECL_NSIRUNNABLE + nsresult CreateOutputStream(nsIOutputStream** aResult); + + nsCString mData; + RefPtr mDataStorage; +}; + +nsresult DataStorage::Writer::CreateOutputStream(nsIOutputStream** aResult) { + nsresult rv; + + if (XRE_IsSocketProcess()) { + mozilla::ipc::FileDescriptor fd; + { + MutexAutoLock lock(mDataStorage->mMutex); + fd = mDataStorage->mWriteFd; + } + + if (!fd.IsValid()) { + return NS_ERROR_NOT_AVAILABLE; + } + + return NS_NewLocalFileOutputStream(aResult, fd); + } + + MOZ_ASSERT(XRE_IsParentProcess()); + + // Concurrent operations on nsIFile objects are not guaranteed to be safe, + // so we clone the file while holding the lock and then release the lock. + // At that point, we can safely operate on the clone. + nsCOMPtr file; + { + MutexAutoLock lock(mDataStorage->mMutex); + // If we don't have a profile, bail. + if (!mDataStorage->mBackingFile) { + return NS_OK; + } + rv = mDataStorage->mBackingFile->Clone(getter_AddRefs(file)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + } + + return NS_NewLocalFileOutputStream(aResult, file, + PR_CREATE_FILE | PR_TRUNCATE | PR_WRONLY); +} + +NS_IMETHODIMP +DataStorage::Writer::Run() { + nsCOMPtr outputStream; + nsresult rv = CreateOutputStream(getter_AddRefs(outputStream)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + // When the output stream is null, it means we don't have a profile. + if (!outputStream) { + return NS_OK; + } + + const char* ptr = mData.get(); + uint32_t remaining = mData.Length(); + uint32_t written = 0; + while (remaining > 0) { + rv = outputStream->Write(ptr, remaining, &written); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + remaining -= written; + ptr += written; + } + + // Observed by tests. + nsCOMPtr job = NewRunnableMethod( + "DataStorage::NotifyObservers", mDataStorage, + &DataStorage::NotifyObservers, "data-storage-written"); + rv = NS_DispatchToMainThread(job, NS_DISPATCH_NORMAL); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return NS_OK; +} + +nsresult DataStorage::AsyncWriteData(const MutexAutoLock& /*aProofOfLock*/) { + MOZ_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess()); + + if (!mPendingWrite || mShuttingDown || + (!mBackingFile && !mWriteFd.IsValid())) { + return NS_OK; + } + + nsCString output; + for (auto iter = mPersistentDataTable.Iter(); !iter.Done(); iter.Next()) { + Entry entry = iter.UserData(); + output.Append(iter.Key()); + output.Append('\t'); + output.AppendInt(entry.mScore); + output.Append('\t'); + output.AppendInt(entry.mLastAccessed); + output.Append('\t'); + output.Append(entry.mValue); + output.Append('\n'); + } + + nsCOMPtr job(new Writer(output, this)); + nsresult rv = mBackgroundTaskQueue->Dispatch(job.forget()); + mPendingWrite = false; + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return NS_OK; +} + +nsresult DataStorage::Clear() { + WaitForReady(); + MutexAutoLock lock(mMutex); + mPersistentDataTable.Clear(); + mTemporaryDataTable.Clear(); + mPrivateDataTable.Clear(); + mPendingWrite = true; + + if (XRE_IsParentProcess() || XRE_IsSocketProcess()) { + // Asynchronously clear the file. This is similar to the permission manager + // in that it doesn't wait to synchronously remove the data from its backing + // storage either. + nsresult rv = AsyncWriteData(lock); + if (NS_FAILED(rv)) { + return rv; + } + } + + nsString filename(mFilename); + RunOnAllContentParents([filename](dom::ContentParent* aParent) { + Unused << aParent->SendDataStorageClear(filename); + }); + + return NS_OK; +} + +/* static */ +void DataStorage::TimerCallback(nsITimer* aTimer, void* aClosure) { + MOZ_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess()); + + RefPtr aDataStorage = (DataStorage*)aClosure; + MutexAutoLock lock(aDataStorage->mMutex); + Unused << aDataStorage->AsyncWriteData(lock); +} + +void DataStorage::NotifyObservers(const char* aTopic) { + // Don't access the observer service off the main thread. + if (!NS_IsMainThread()) { + MOZ_ASSERT_UNREACHABLE( + "DataStorage::NotifyObservers called off main thread"); + return; + } + + nsCOMPtr os = services::GetObserverService(); + if (os) { + os->NotifyObservers(nullptr, aTopic, mFilename.get()); + } +} + +void DataStorage::ShutdownTimer() { + MOZ_ASSERT(XRE_IsParentProcess() || XRE_IsSocketProcess()); + MOZ_ASSERT(NS_IsMainThread()); + if (mTimer) { + nsresult rv = mTimer->Cancel(); + Unused << NS_WARN_IF(NS_FAILED(rv)); + mTimer = nullptr; + } +} + +//------------------------------------------------------------ +// DataStorage::nsIObserver +//------------------------------------------------------------ + +NS_IMETHODIMP +DataStorage::Observe(nsISupports* /*aSubject*/, const char* aTopic, + const char16_t* /*aData*/) { + if (!NS_IsMainThread()) { + MOZ_ASSERT_UNREACHABLE("DataStorage::Observe called off main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + + if (strcmp(aTopic, "last-pb-context-exited") == 0) { + MutexAutoLock lock(mMutex); + mPrivateDataTable.Clear(); + return NS_OK; + } + + if (!XRE_IsParentProcess() && !XRE_IsSocketProcess()) { + MOZ_ASSERT_UNREACHABLE("unexpected observation topic for content proces"); + return NS_ERROR_UNEXPECTED; + } + + if (strcmp(aTopic, "profile-before-change") == 0 || + strcmp(aTopic, "xpcom-shutdown-threads") == 0) { + RefPtr taskQueueToAwait; + { + MutexAutoLock lock(mMutex); + if (!mShuttingDown) { + nsresult rv = AsyncWriteData(lock); + Unused << NS_WARN_IF(NS_FAILED(rv)); + mShuttingDown = true; + mBackgroundTaskQueue->BeginShutdown(); + taskQueueToAwait = mBackgroundTaskQueue; + } + } + // Tasks on the background queue may take the lock, so it can't be held + // while waiting for them to finish. + if (taskQueueToAwait) { + taskQueueToAwait->AwaitShutdownAndIdle(); + } + ShutdownTimer(); + } + + return NS_OK; +} + +DataStorage::Entry::Entry() + : mScore(0), mLastAccessed((int32_t)(PR_Now() / sOneDayInMicroseconds)) {} + +// Updates this entry's score. Returns true if the score has actually changed. +// If it's been less than a day since this entry has been accessed, the score +// does not change. Otherwise, the score increases by 1. +// The default score is 0. The maximum score is the maximum value that can +// be represented by an unsigned 32 bit integer. +// This is to handle evictions from our tables, which in turn is to prevent +// unbounded resource use. +bool DataStorage::Entry::UpdateScore() { + int32_t nowInDays = (int32_t)(PR_Now() / sOneDayInMicroseconds); + int32_t daysSinceAccessed = (nowInDays - mLastAccessed); + + // Update the last accessed time. + mLastAccessed = nowInDays; + + // If it's been less than a day since we've been accessed, + // the score isn't updated. + if (daysSinceAccessed < 1) { + return false; + } + + // Otherwise, increment the score (but don't overflow). + if (mScore < sMaxScore) { + mScore++; + } + return true; +} + +} // namespace mozilla diff --git a/security/manager/ssl/DataStorage.h b/security/manager/ssl/DataStorage.h new file mode 100644 index 0000000000..7c065fa243 --- /dev/null +++ b/security/manager/ssl/DataStorage.h @@ -0,0 +1,257 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla_DataStorage_h +#define mozilla_DataStorage_h + +#include +#include "mozilla/Atomics.h" +#include "mozilla/ipc/FileDescriptor.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Monitor.h" +#include "mozilla/Mutex.h" +#include "mozilla/StaticPtr.h" +#include "nsCOMPtr.h" +#include "nsDataHashtable.h" +#include "nsIObserver.h" +#include "nsITimer.h" +#include "nsRefPtrHashtable.h" +#include "nsString.h" + +class psm_DataStorageTest; + +namespace mozilla { +class DataStorageMemoryReporter; +class TaskQueue; + +namespace dom { +class ContentChild; +} // namespace dom + +namespace psm { +class DataStorageEntry; +class DataStorageItem; +} // namespace psm + +/** + * DataStorage is a threadsafe, generic, narrow string-based hash map that + * persists data on disk and additionally handles temporary and private data. + * However, if used in a context where there is no profile directory, data + * will not be persisted. + * + * Its lifecycle is as follows: + * - Allocate with a filename (this is or will eventually be a file in the + * profile directory, if the profile exists). + * - Call Init() from the main thread. This spins off an asynchronous read + * of the backing file. + * - Eventually observers of the topic "data-storage-ready" will be notified + * with the backing filename as the data in the notification when this + * has completed. + * - Should the profile directory not be available, (e.g. in xpcshell), + * DataStorage will not initially read any persistent data. The + * "data-storage-ready" event will still be emitted. This follows semantics + * similar to the permission manager and allows tests that test unrelated + * components to proceed without a profile. + * - A timer periodically fires on a background thread that checks if any + * persistent data has changed, and if so writes all persistent data to the + * backing file. When this happens, observers will be notified with the + * topic "data-storage-written" and the backing filename as the data. + * It is possible to receive a "data-storage-written" event while there exist + * pending persistent data changes. However, those changes will eventually be + * written when the timer fires again, and eventually another + * "data-storage-written" event will be sent. + * - When a DataStorage instance observes the topic "profile-before-change" in + * anticipation of shutdown, all persistent data for that DataStorage is + * written to the backing file (this blocks the main thread). In the process + * of doing this, the background serial event target responsible for these + * writes is then shut down to prevent further writes to that file (the + * background timer is also cancelled when this happens). + * If "profile-before-change" is not observed, this happens upon observing + * "xpcom-shutdown-threads". + * - For testing purposes, the preference "test.datastorage.write_timer_ms" can + * be set to cause the asynchronous writing of data to happen more quickly. + * - To prevent unbounded memory and disk use, the number of entries in each + * table is limited to 1024. Evictions are handled in by a modified LRU scheme + * (see implementation comments). + * - NB: Instances of DataStorage have long lifetimes because they are strong + * observers of events and won't go away until the observer service does. + * + * For each key/value: + * - The key must be a non-empty string containing no instances of '\t' or '\n' + * (this is a limitation of how the data is stored and will be addressed in + * the future). + * - The key must have a length no more than 256. + * - The value must not contain '\n' and must have a length no more than 1024. + * (the length limits are to prevent unbounded disk and memory usage) + */ + +/** + * Data that is DataStorage_Persistent is saved on disk. DataStorage_Temporary + * and DataStorage_Private are not saved. DataStorage_Private is meant to + * only be set and accessed from private contexts. It will be cleared upon + * observing the event "last-pb-context-exited". + */ +enum DataStorageType { + DataStorage_Persistent, + DataStorage_Temporary, + DataStorage_Private +}; + +enum class DataStorageClass { +#define DATA_STORAGE(_) _, +#include "mozilla/DataStorageList.h" +#undef DATA_STORAGE +}; + +class DataStorage : public nsIObserver { + typedef psm::DataStorageItem DataStorageItem; + + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOBSERVER + + // If there is a profile directory, there is or will eventually be a file + // by the name specified by aFilename there. + static already_AddRefed Get(DataStorageClass aFilename); + + // Initializes the DataStorage. Must be called before using. + // aItems is used in the content process and the socket process to initialize + // a cache of the items received from the parent process over IPC. nullptr + // must be passed for the parent process. + // aWriteFd is only used in the socket process for now. The FileDesc is opened + // in parent process and send to socket process. The data storage instance in + // socket process will use this FD to write data to the backing file. + nsresult Init( + const nsTArray* aItems, + mozilla::ipc::FileDescriptor aWriteFd = mozilla::ipc::FileDescriptor()); + + // This function is used to create the file descriptor asynchronously. The FD + // will be sent via the callback. Note that after this call, mBackingFile will + // be nulled to prevent parent process to access the file. + nsresult AsyncTakeFileDesc( + std::function&& aResolver); + + // Given a key and a type of data, returns a value. Returns an empty string if + // the key is not present for that type of data. If Get is called before the + // "data-storage-ready" event is observed, it will block. NB: It is not + // currently possible to differentiate between missing data and data that is + // the empty string. + nsCString Get(const nsCString& aKey, DataStorageType aType); + // Give a key, value, and type of data, adds an entry as appropriate. + // Updates existing entries. + nsresult Put(const nsCString& aKey, const nsCString& aValue, + DataStorageType aType); + // Given a key and type of data, removes an entry if present. + void Remove(const nsCString& aKey, DataStorageType aType); + // Removes all entries of all types of data. + nsresult Clear(); + + // Read all file names that we know about. + static void GetAllFileNames(nsTArray& aItems); + + // Read all child process data that we know about. + static void GetAllChildProcessData( + nsTArray& aEntries); + + // Read all of the data items. + void GetAll(nsTArray* aItems); + + // Set the cached copy of our DataStorage entries in the content process. + static void SetCachedStorageEntries( + const nsTArray& aEntries); + + size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + + // Return true if this data storage is ready to be used. + bool IsReady(); + + void ShutdownTimer(); + + private: + explicit DataStorage(const nsString& aFilename); + virtual ~DataStorage() = default; + + static already_AddRefed GetFromRawFileName( + const nsString& aFilename); + + friend class ::psm_DataStorageTest; + friend class mozilla::dom::ContentChild; + friend class mozilla::DataStorageMemoryReporter; + + class Writer; + class Reader; + class Opener; + + class Entry { + public: + Entry(); + bool UpdateScore(); + + uint32_t mScore; + int32_t mLastAccessed; // the last accessed time in days since the epoch + nsCString mValue; + }; + + // Utility class for scanning tables for an entry to evict. + class KeyAndEntry { + public: + nsCString mKey; + Entry mEntry; + }; + + typedef nsDataHashtable DataStorageTable; + typedef nsRefPtrHashtable DataStorages; + + void WaitForReady(); + nsresult AsyncWriteData(const MutexAutoLock& aProofOfLock); + nsresult AsyncReadData(const MutexAutoLock& aProofOfLock); + + static nsresult ValidateKeyAndValue(const nsCString& aKey, + const nsCString& aValue); + static void TimerCallback(nsITimer* aTimer, void* aClosure); + void NotifyObservers(const char* aTopic); + + bool GetInternal(const nsCString& aKey, Entry* aEntry, DataStorageType aType, + const MutexAutoLock& aProofOfLock); + nsresult PutInternal(const nsCString& aKey, Entry& aEntry, + DataStorageType aType, + const MutexAutoLock& aProofOfLock); + void MaybeEvictOneEntry(DataStorageType aType, + const MutexAutoLock& aProofOfLock); + DataStorageTable& GetTableForType(DataStorageType aType, + const MutexAutoLock& aProofOfLock); + + void ReadAllFromTable(DataStorageType aType, + nsTArray* aItems, + const MutexAutoLock& aProofOfLock); + + Mutex mMutex; // This mutex protects access to the following members: + DataStorageTable mPersistentDataTable; + DataStorageTable mTemporaryDataTable; + DataStorageTable mPrivateDataTable; + nsCOMPtr mBackingFile; + bool mPendingWrite; // true if a write is needed but hasn't been dispatched + bool mShuttingDown; + RefPtr mBackgroundTaskQueue; + // (End list of members protected by mMutex) + + nsCOMPtr mTimer; // Must only be accessed on the main thread + + mozilla::Atomic mInitCalled; // Indicates that Init() has been called. + + Monitor mReadyMonitor; // Do not acquire this at the same time as mMutex. + bool mReady; // Indicates that saved data has been read and Get can proceed. + + const nsString mFilename; + + mozilla::ipc::FileDescriptor mWriteFd; + + static StaticAutoPtr sDataStorages; +}; + +} // namespace mozilla + +#endif // mozilla_DataStorage_h diff --git a/security/manager/ssl/DataStorageIPCUtils.h b/security/manager/ssl/DataStorageIPCUtils.h new file mode 100644 index 0000000000..4a8fe0cdeb --- /dev/null +++ b/security/manager/ssl/DataStorageIPCUtils.h @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef ipc_DataStorageIPCUtils_h +#define ipc_DataStorageIPCUtils_h + +#include "ipc/EnumSerializer.h" +#include "mozilla/DataStorage.h" + +namespace IPC { +template <> +struct ParamTraits + : public ContiguousEnumSerializer< + mozilla::DataStorageType, mozilla::DataStorage_Persistent, + mozilla::DataStorageType(mozilla::DataStorage_Private + 1)> {}; +} // namespace IPC + +#endif // mozilla_DataStorageIPCUtils_hh diff --git a/security/manager/ssl/DataStorageList.h b/security/manager/ssl/DataStorageList.h new file mode 100644 index 0000000000..e1978ab5af --- /dev/null +++ b/security/manager/ssl/DataStorageList.h @@ -0,0 +1,19 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +// This is the list of well-known PSM DataStorage classes that Gecko uses. +// These are key value data stores that are backed by a simple text-based +// storage in the profile directory. +// +// Please note that it is crucial for performance reasons for the number of +// these classes to remain low. If you need to add to this list, you may +// need to update the algorithm in DataStorage::SetCachedStorageEntries() +// to something faster. + +DATA_STORAGE(AlternateServices) +DATA_STORAGE(ClientAuthRememberList) +DATA_STORAGE(SecurityPreloadState) +DATA_STORAGE(SiteSecurityServiceState) diff --git a/security/manager/ssl/EnterpriseRoots.cpp b/security/manager/ssl/EnterpriseRoots.cpp new file mode 100644 index 0000000000..ddf397531f --- /dev/null +++ b/security/manager/ssl/EnterpriseRoots.cpp @@ -0,0 +1,375 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "EnterpriseRoots.h" + +#include "mozilla/ArrayUtils.h" +#include "mozilla/Logging.h" +#include "mozilla/Unused.h" +#include "mozpkix/Result.h" +#include "nsThreadUtils.h" + +#ifdef MOZ_WIDGET_ANDROID +# include "mozilla/java/EnterpriseRootsWrappers.h" +#endif // MOZ_WIDGET_ANDROID + +#ifdef XP_MACOSX +# include +# include "KeychainSecret.h" // for ScopedCFType + +# include "nsCocoaFeatures.h" +#endif // XP_MACOSX + +#ifdef XP_WIN +# include +# include +#endif // XP_WIN + +extern mozilla::LazyLogModule gPIPNSSLog; + +using namespace mozilla; + +nsresult EnterpriseCert::Init(const uint8_t* data, size_t len, bool isRoot) { + mDER.clear(); + if (!mDER.append(data, len)) { + return NS_ERROR_OUT_OF_MEMORY; + } + mIsRoot = isRoot; + + return NS_OK; +} + +nsresult EnterpriseCert::Init(const EnterpriseCert& orig) { + return Init(orig.mDER.begin(), orig.mDER.length(), orig.mIsRoot); +} + +nsresult EnterpriseCert::CopyBytes(nsTArray& dest) const { + dest.Clear(); + // XXX(Bug 1631371) Check if this should use a fallible operation as it + // pretended earlier, or change the return type to void. + dest.AppendElements(mDER.begin(), mDER.length()); + return NS_OK; +} + +pkix::Result EnterpriseCert::GetInput(pkix::Input& input) const { + return input.Init(mDER.begin(), mDER.length()); +} + +bool EnterpriseCert::GetIsRoot() const { return mIsRoot; } + +#ifdef XP_WIN +const wchar_t* kWindowsDefaultRootStoreNames[] = {L"ROOT", L"CA"}; + +// Helper function to determine if the OS considers the given certificate to be +// a trust anchor for TLS server auth certificates. This is to be used in the +// context of importing what are presumed to be root certificates from the OS. +// If this function returns true but it turns out that the given certificate is +// in some way unsuitable to issue certificates, mozilla::pkix will never build +// a valid chain that includes the certificate, so importing it even if it +// isn't a valid CA poses no risk. +static void CertIsTrustAnchorForTLSServerAuth(PCCERT_CONTEXT certificate, + bool& isTrusted, bool& isRoot) { + isTrusted = false; + isRoot = false; + MOZ_ASSERT(certificate); + if (!certificate) { + return; + } + + PCCERT_CHAIN_CONTEXT pChainContext = nullptr; + CERT_ENHKEY_USAGE enhkeyUsage; + memset(&enhkeyUsage, 0, sizeof(CERT_ENHKEY_USAGE)); + LPCSTR identifiers[] = { + "1.3.6.1.5.5.7.3.1", // id-kp-serverAuth + }; + enhkeyUsage.cUsageIdentifier = ArrayLength(identifiers); + enhkeyUsage.rgpszUsageIdentifier = + const_cast(identifiers); // -Wwritable-strings + CERT_USAGE_MATCH certUsage; + memset(&certUsage, 0, sizeof(CERT_USAGE_MATCH)); + certUsage.dwType = USAGE_MATCH_TYPE_AND; + certUsage.Usage = enhkeyUsage; + CERT_CHAIN_PARA chainPara; + memset(&chainPara, 0, sizeof(CERT_CHAIN_PARA)); + chainPara.cbSize = sizeof(CERT_CHAIN_PARA); + chainPara.RequestedUsage = certUsage; + // Disable anything that could result in network I/O. + DWORD flags = CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY | + CERT_CHAIN_CACHE_ONLY_URL_RETRIEVAL | + CERT_CHAIN_DISABLE_AUTH_ROOT_AUTO_UPDATE | + CERT_CHAIN_DISABLE_AIA; + if (!CertGetCertificateChain(nullptr, certificate, nullptr, nullptr, + &chainPara, flags, nullptr, &pChainContext)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CertGetCertificateChain failed")); + return; + } + isTrusted = pChainContext->TrustStatus.dwErrorStatus == CERT_TRUST_NO_ERROR; + if (isTrusted && pChainContext->cChain > 0) { + // The so-called "final chain" is what we're after: + // https://docs.microsoft.com/en-us/windows/desktop/api/wincrypt/ns-wincrypt-_cert_chain_context + CERT_SIMPLE_CHAIN* finalChain = + pChainContext->rgpChain[pChainContext->cChain - 1]; + // This is a root if the final chain consists of only one certificate (i.e. + // this one). + isRoot = finalChain->cElement == 1; + } + CertFreeCertificateChain(pChainContext); +} + +// Because HCERTSTORE is just a typedef void*, we can't use any of the nice +// scoped or unique pointer templates. To elaborate, any attempt would +// instantiate those templates with T = void. When T gets used in the context +// of T&, this results in void&, which isn't legal. +class ScopedCertStore final { + public: + explicit ScopedCertStore(HCERTSTORE certstore) : certstore(certstore) {} + + ~ScopedCertStore() { CertCloseStore(certstore, 0); } + + HCERTSTORE get() { return certstore; } + + private: + ScopedCertStore(const ScopedCertStore&) = delete; + ScopedCertStore& operator=(const ScopedCertStore&) = delete; + HCERTSTORE certstore; +}; + +// Loads the enterprise roots at the registry location corresponding to the +// given location flag. +// Supported flags are: +// CERT_SYSTEM_STORE_LOCAL_MACHINE +// (for HKLM\SOFTWARE\Microsoft\SystemCertificates) +// CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY +// (for HKLM\SOFTWARE\Policy\Microsoft\SystemCertificates) +// CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE +// (for HKLM\SOFTWARE\Microsoft\EnterpriseCertificates) +// CERT_SYSTEM_STORE_CURRENT_USER +// (for HKCU\SOFTWARE\Microsoft\SystemCertificates) +// CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY +// (for HKCU\SOFTWARE\Policy\Microsoft\SystemCertificates) +static void GatherEnterpriseCertsForLocation(DWORD locationFlag, + Vector& certs) { + MOZ_ASSERT(locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE || + locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY || + locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE || + locationFlag == CERT_SYSTEM_STORE_CURRENT_USER || + locationFlag == CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, + "unexpected locationFlag for GatherEnterpriseRootsForLocation"); + if (!(locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE || + locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY || + locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE || + locationFlag == CERT_SYSTEM_STORE_CURRENT_USER || + locationFlag == CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY)) { + return; + } + + DWORD flags = + locationFlag | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_READONLY_FLAG; + // The certificate store being opened should consist only of certificates + // added by a user or administrator and not any certificates that are part + // of Microsoft's root store program. + // The 3rd parameter to CertOpenStore should be NULL according to + // https://msdn.microsoft.com/en-us/library/windows/desktop/aa376559%28v=vs.85%29.aspx + for (auto name : kWindowsDefaultRootStoreNames) { + ScopedCertStore enterpriseRootStore( + CertOpenStore(CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, NULL, flags, name)); + if (!enterpriseRootStore.get()) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("failed to open enterprise root store")); + continue; + } + PCCERT_CONTEXT certificate = nullptr; + uint32_t numImported = 0; + while ((certificate = CertFindCertificateInStore( + enterpriseRootStore.get(), X509_ASN_ENCODING, 0, CERT_FIND_ANY, + nullptr, certificate))) { + bool isTrusted; + bool isRoot; + CertIsTrustAnchorForTLSServerAuth(certificate, isTrusted, isRoot); + if (!isTrusted) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("skipping cert not trusted for TLS server auth")); + continue; + } + EnterpriseCert enterpriseCert; + if (NS_FAILED(enterpriseCert.Init(certificate->pbCertEncoded, + certificate->cbCertEncoded, isRoot))) { + // Best-effort. We probably ran out of memory. + continue; + } + if (!certs.append(std::move(enterpriseCert))) { + // Best-effort again. + continue; + } + numImported++; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("imported %u certs from %S", numImported, name)); + } +} + +static void GatherEnterpriseCertsWindows(Vector& certs) { + GatherEnterpriseCertsForLocation(CERT_SYSTEM_STORE_LOCAL_MACHINE, certs); + GatherEnterpriseCertsForLocation(CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY, + certs); + GatherEnterpriseCertsForLocation(CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE, + certs); + GatherEnterpriseCertsForLocation(CERT_SYSTEM_STORE_CURRENT_USER, certs); + GatherEnterpriseCertsForLocation(CERT_SYSTEM_STORE_CURRENT_USER_GROUP_POLICY, + certs); +} +#endif // XP_WIN + +#ifdef XP_MACOSX +OSStatus GatherEnterpriseCertsMacOS(Vector& certs) { + // The following builds a search dictionary corresponding to: + // { class: "certificate", + // match limit: "match all", + // policy: "SSL (TLS)", + // only include trusted certificates: true } + // This operates on items that have been added to the keychain and thus gives + // us all 3rd party certificates that have been trusted for SSL (TLS), which + // is what we want (thus we don't import built-in root certificates that ship + // with the OS). + const CFStringRef keys[] = {kSecClass, kSecMatchLimit, kSecMatchPolicy, + kSecMatchTrustedOnly}; + // https://developer.apple.com/documentation/security/1392592-secpolicycreatessl + ScopedCFType sslPolicy(SecPolicyCreateSSL(true, nullptr)); + const void* values[] = {kSecClassCertificate, kSecMatchLimitAll, + sslPolicy.get(), kCFBooleanTrue}; + static_assert(ArrayLength(keys) == ArrayLength(values), + "mismatched SecItemCopyMatching key/value array sizes"); + // https://developer.apple.com/documentation/corefoundation/1516782-cfdictionarycreate + ScopedCFType searchDictionary(CFDictionaryCreate( + nullptr, (const void**)&keys, (const void**)&values, ArrayLength(keys), + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFTypeRef items; + // https://developer.apple.com/documentation/security/1398306-secitemcopymatching + OSStatus rv = SecItemCopyMatching(searchDictionary.get(), &items); + if (rv != errSecSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("SecItemCopyMatching failed")); + return rv; + } + // If given a match limit greater than 1 (which we did), SecItemCopyMatching + // returns a CFArrayRef. + ScopedCFType arr(reinterpret_cast(items)); + CFIndex count = CFArrayGetCount(arr.get()); + uint32_t numImported = 0; + for (CFIndex i = 0; i < count; i++) { + const CFTypeRef c = CFArrayGetValueAtIndex(arr.get(), i); + SecTrustRef trust; + rv = SecTrustCreateWithCertificates(c, sslPolicy.get(), &trust); + if (rv != errSecSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("SecTrustCreateWithCertificates failed")); + continue; + } + ScopedCFType trustHandle(trust); + // Disable AIA chasing to avoid network I/O. + rv = SecTrustSetNetworkFetchAllowed(trustHandle.get(), false); + if (rv != errSecSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("SecTrustSetNetworkFetchAllowed failed")); + continue; + } + bool isTrusted = false; + bool fallBackToDeprecatedAPI = true; +# if defined MAC_OS_X_VERSION_10_14 + if (nsCocoaFeatures::OnMojaveOrLater()) { + // This is an awkward way to express what we want, but the compiler + // complains if we try to put __builtin_available in a compound logical + // statement. + if (__builtin_available(macOS 10.14, *)) { + isTrusted = SecTrustEvaluateWithError(trustHandle.get(), nullptr); + fallBackToDeprecatedAPI = false; + } + } +# endif // MAC_OS_X_VERSION_10_14 + if (fallBackToDeprecatedAPI) { + SecTrustResultType result; + rv = SecTrustEvaluate(trustHandle.get(), &result); + if (rv != errSecSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("SecTrustEvaluate failed")); + continue; + } + // 'kSecTrustResultProceed' means the trust evaluation succeeded and that + // this is a trusted certificate. + // 'kSecTrustResultUnspecified' means the trust evaluation succeeded and + // that this certificate inherits its trust. + isTrusted = result == kSecTrustResultProceed || + result == kSecTrustResultUnspecified; + } + if (!isTrusted) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("skipping cert not trusted")); + continue; + } + CFIndex count = SecTrustGetCertificateCount(trustHandle.get()); + bool isRoot = count == 1; + + // Because we asked for certificates, each CFTypeRef in the array is really + // a SecCertificateRef. + const SecCertificateRef s = (const SecCertificateRef)c; + ScopedCFType der(SecCertificateCopyData(s)); + EnterpriseCert enterpriseCert; + if (NS_FAILED(enterpriseCert.Init(CFDataGetBytePtr(der.get()), + CFDataGetLength(der.get()), isRoot))) { + // Best-effort. We probably ran out of memory. + continue; + } + if (!certs.append(std::move(enterpriseCert))) { + // Best-effort again. + continue; + } + numImported++; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("imported %u certs", numImported)); + return errSecSuccess; +} +#endif // XP_MACOSX + +#ifdef MOZ_WIDGET_ANDROID +void GatherEnterpriseCertsAndroid(Vector& certs) { + if (!jni::IsAvailable()) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("JNI not available")); + return; + } + jni::ObjectArray::LocalRef roots = + java::EnterpriseRoots::GatherEnterpriseRoots(); + for (size_t i = 0; i < roots->Length(); i++) { + jni::ByteArray::LocalRef root = roots->GetElement(i); + EnterpriseCert cert; + // Currently we treat all certificates gleaned from the Android + // CA store as roots. + if (NS_SUCCEEDED(cert.Init( + reinterpret_cast(root->GetElements().Elements()), + root->Length(), true))) { + Unused << certs.append(std::move(cert)); + } + } +} +#endif // MOZ_WIDGET_ANDROID + +nsresult GatherEnterpriseCerts(Vector& certs) { + MOZ_ASSERT(!NS_IsMainThread()); + if (NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + certs.clear(); +#ifdef XP_WIN + GatherEnterpriseCertsWindows(certs); +#endif // XP_WIN +#ifdef XP_MACOSX + OSStatus rv = GatherEnterpriseCertsMacOS(certs); + if (rv != errSecSuccess) { + return NS_ERROR_FAILURE; + } +#endif // XP_MACOSX +#ifdef MOZ_WIDGET_ANDROID + GatherEnterpriseCertsAndroid(certs); +#endif // MOZ_WIDGET_ANDROID + return NS_OK; +} diff --git a/security/manager/ssl/EnterpriseRoots.h b/security/manager/ssl/EnterpriseRoots.h new file mode 100644 index 0000000000..7504dcec1d --- /dev/null +++ b/security/manager/ssl/EnterpriseRoots.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef EnterpriseRoots_h +#define EnterpriseRoots_h + +#include "mozilla/Vector.h" +#include "mozpkix/Input.h" +#include "mozpkix/Result.h" +#include "nsTArray.h" + +class EnterpriseCert { + public: + EnterpriseCert() : mIsRoot(false) {} + + nsresult Init(const uint8_t* data, size_t len, bool isRoot); + // Like a copy constructor but able to return a result. + nsresult Init(const EnterpriseCert& orig); + + nsresult CopyBytes(nsTArray& dest) const; + mozilla::pkix::Result GetInput(mozilla::pkix::Input& input) const; + bool GetIsRoot() const; + + private: + mozilla::Vector mDER; + bool mIsRoot; +}; + +// This may block and must not be called from the main thread. +nsresult GatherEnterpriseCerts(mozilla::Vector& certs); + +#endif // EnterpriseRoots_h diff --git a/security/manager/ssl/KeychainSecret.cpp b/security/manager/ssl/KeychainSecret.cpp new file mode 100644 index 0000000000..376e2f14c3 --- /dev/null +++ b/security/manager/ssl/KeychainSecret.cpp @@ -0,0 +1,186 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "KeychainSecret.h" + +#include + +#include "mozilla/Logging.h" + +// This is the implementation of KeychainSecret, an instantiation of OSKeyStore +// for OS X. It uses the system keychain, hence the name. + +using namespace mozilla; + +LazyLogModule gKeychainSecretLog("keychainsecret"); + +KeychainSecret::KeychainSecret() {} + +KeychainSecret::~KeychainSecret() {} + +nsresult KeychainSecret::Lock() { + // https://developer.apple.com/documentation/security/1402180-seckeychainlock + // Passing `nullptr` locks the default keychain. + OSStatus rv = SecKeychainLock(nullptr); + if (rv != errSecSuccess) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, + ("SecKeychainLock failed: %d", rv)); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult KeychainSecret::Unlock() { + // https://developer.apple.com/documentation/security/1400341-seckeychainunlock + // This attempts to unlock the default keychain. Using `false` indicates we + // aren't passing in a password (if the keychain is locked, a dialog will + // appear for the user). + OSStatus rv = SecKeychainUnlock(nullptr, 0, nullptr, false); + if (rv != errSecSuccess) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, + ("SecKeychainUnlock failed: %d", rv)); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +ScopedCFType MozillaStringToCFString(const nsACString& stringIn) { + // https://developer.apple.com/documentation/corefoundation/1543419-cfstringcreatewithbytes + ScopedCFType stringOut(CFStringCreateWithBytes( + nullptr, reinterpret_cast(stringIn.BeginReading()), + stringIn.Length(), kCFStringEncodingUTF8, false)); + return stringOut; +} + +nsresult KeychainSecret::StoreSecret(const nsACString& aSecret, + const nsACString& aLabel) { + // This creates a CFDictionary of the form: + // { class: generic password, + // account: the given label, + // value: the given secret } + // "account" is the way we differentiate different secrets. + // By default, secrets stored by the application (Firefox) in this way are not + // accessible to other applications, so we shouldn't need to worry about + // unauthorized access or namespace collisions. This will be the case as long + // as we never set the kSecAttrAccessGroup attribute on the CFDictionary. The + // platform enforces this restriction using the application-identifier + // entitlement that each application bundle should have. See + // https://developer.apple.com/documentation/security/1401659-secitemadd?language=objc#discussion + + // The keychain does not overwrite secrets by default (unlike other backends + // like libsecret and credential manager). To be consistent, we first delete + // any previously-stored secrets that use the given label. + nsresult rv = DeleteSecret(aLabel); + if (NS_FAILED(rv)) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, + ("DeleteSecret before StoreSecret failed")); + return rv; + } + const CFStringRef keys[] = {kSecClass, kSecAttrAccount, kSecValueData}; + ScopedCFType label(MozillaStringToCFString(aLabel)); + if (!label) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, + ("MozillaStringToCFString failed")); + return NS_ERROR_FAILURE; + } + ScopedCFType secret(CFDataCreate( + nullptr, reinterpret_cast(aSecret.BeginReading()), + aSecret.Length())); + if (!secret) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, ("CFDataCreate failed")); + return NS_ERROR_FAILURE; + } + const void* values[] = {kSecClassGenericPassword, label.get(), secret.get()}; + static_assert(ArrayLength(keys) == ArrayLength(values), + "mismatched SecItemAdd key/value array sizes"); + ScopedCFType addDictionary(CFDictionaryCreate( + nullptr, (const void**)&keys, (const void**)&values, ArrayLength(keys), + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + // https://developer.apple.com/documentation/security/1401659-secitemadd + OSStatus osrv = SecItemAdd(addDictionary.get(), nullptr); + if (osrv != errSecSuccess) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, + ("SecItemAdd failed: %d", osrv)); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult KeychainSecret::DeleteSecret(const nsACString& aLabel) { + // To delete a secret, we create a CFDictionary of the form: + // { class: generic password, + // account: the given label } + // and then call SecItemDelete. + const CFStringRef keys[] = {kSecClass, kSecAttrAccount}; + ScopedCFType label(MozillaStringToCFString(aLabel)); + if (!label) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, + ("MozillaStringToCFString failed")); + return NS_ERROR_FAILURE; + } + const void* values[] = {kSecClassGenericPassword, label.get()}; + static_assert(ArrayLength(keys) == ArrayLength(values), + "mismatched SecItemDelete key/value array sizes"); + ScopedCFType deleteDictionary(CFDictionaryCreate( + nullptr, (const void**)&keys, (const void**)&values, ArrayLength(keys), + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + // https://developer.apple.com/documentation/security/1395547-secitemdelete + OSStatus rv = SecItemDelete(deleteDictionary.get()); + if (rv != errSecSuccess && rv != errSecItemNotFound) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, + ("SecItemDelete failed: %d", rv)); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult KeychainSecret::RetrieveSecret(const nsACString& aLabel, + /* out */ nsACString& aSecret) { + // To retrieve a secret, we create a CFDictionary of the form: + // { class: generic password, + // account: the given label, + // match limit: match one, + // return attributes: true, + // return data: true } + // This searches for and returns the attributes and data for the secret + // matching the given label. We then extract the data (i.e. the secret) and + // return it. + const CFStringRef keys[] = {kSecClass, kSecAttrAccount, kSecMatchLimit, + kSecReturnAttributes, kSecReturnData}; + ScopedCFType label(MozillaStringToCFString(aLabel)); + if (!label) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, + ("MozillaStringToCFString failed")); + return NS_ERROR_FAILURE; + } + const void* values[] = {kSecClassGenericPassword, label.get(), + kSecMatchLimitOne, kCFBooleanTrue, kCFBooleanTrue}; + static_assert(ArrayLength(keys) == ArrayLength(values), + "mismatched SecItemCopyMatching key/value array sizes"); + ScopedCFType searchDictionary(CFDictionaryCreate( + nullptr, (const void**)&keys, (const void**)&values, ArrayLength(keys), + &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFTypeRef item; + // https://developer.apple.com/documentation/security/1398306-secitemcopymatching + OSStatus rv = SecItemCopyMatching(searchDictionary.get(), &item); + if (rv != errSecSuccess) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, + ("SecItemCopyMatching failed: %d", rv)); + return NS_ERROR_FAILURE; + } + ScopedCFType dictionary( + reinterpret_cast(item)); + CFDataRef secret = reinterpret_cast( + CFDictionaryGetValue(dictionary.get(), kSecValueData)); + if (!secret) { + MOZ_LOG(gKeychainSecretLog, LogLevel::Debug, + ("CFDictionaryGetValue failed")); + return NS_ERROR_FAILURE; + } + aSecret.Assign(reinterpret_cast(CFDataGetBytePtr(secret)), + CFDataGetLength(secret)); + return NS_OK; +} diff --git a/security/manager/ssl/KeychainSecret.h b/security/manager/ssl/KeychainSecret.h new file mode 100644 index 0000000000..a54f2915c9 --- /dev/null +++ b/security/manager/ssl/KeychainSecret.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef KeychainSecret_h +#define KeychainSecret_h + +#include "CoreFoundation/CFBase.h" + +#include "OSKeyStore.h" +#include "nsString.h" + +template +class ScopedCFType { + public: + explicit ScopedCFType(T value) : mValue(value) {} + + ~ScopedCFType() { CFRelease((CFTypeRef)mValue); } + + T get() { return mValue; } + + explicit operator bool() const { return mValue != nullptr; } + + private: + T mValue; +}; + +class KeychainSecret final : public AbstractOSKeyStore { + public: + KeychainSecret(); + + virtual nsresult RetrieveSecret(const nsACString& label, + /* out */ nsACString& secret) override; + virtual nsresult StoreSecret(const nsACString& secret, + const nsACString& label) override; + virtual nsresult DeleteSecret(const nsACString& label) override; + virtual nsresult Lock() override; + virtual nsresult Unlock() override; + + virtual ~KeychainSecret(); +}; + +#endif // KeychainSecret_h diff --git a/security/manager/ssl/LibSecret.cpp b/security/manager/ssl/LibSecret.cpp new file mode 100644 index 0000000000..29e105e02e --- /dev/null +++ b/security/manager/ssl/LibSecret.cpp @@ -0,0 +1,383 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "LibSecret.h" + +#include +#include +#include + +#include "mozilla/Base64.h" +#include "prlink.h" + +// This is the implementation of LibSecret, an instantiation of OSKeyStore for +// Linux. + +using namespace mozilla; + +LazyLogModule gLibSecretLog("libsecret"); + +static PRLibrary* libsecret = nullptr; + +typedef struct _SecretService SecretService; +typedef struct _SecretCollection SecretCollection; + +typedef enum { + SECRET_SCHEMA_NONE = 0, + SECRET_SCHEMA_DONT_MATCH_NAME = 1 << 1 +} SecretSchemaFlags; + +typedef enum { + SECRET_SCHEMA_ATTRIBUTE_STRING = 0, + SECRET_SCHEMA_ATTRIBUTE_INTEGER = 1, + SECRET_SCHEMA_ATTRIBUTE_BOOLEAN = 2, +} SecretSchemaAttributeType; + +typedef struct { + const gchar* name; + SecretSchemaAttributeType type; +} SecretSchemaAttribute; + +typedef struct { + const gchar* name; + SecretSchemaFlags flags; + SecretSchemaAttribute attributes[32]; + + /* */ + gint reserved; + gpointer reserved1; + gpointer reserved2; + gpointer reserved3; + gpointer reserved4; + gpointer reserved5; + gpointer reserved6; + gpointer reserved7; +} SecretSchema; + +typedef enum { + SECRET_COLLECTION_NONE = 0 << 0, + SECRET_COLLECTION_LOAD_ITEMS = 1 << 1, +} SecretCollectionFlags; + +typedef enum { + SECRET_SERVICE_NONE = 0, + SECRET_SERVICE_OPEN_SESSION = 1 << 1, + SECRET_SERVICE_LOAD_COLLECTIONS = 1 << 2, +} SecretServiceFlags; + +typedef enum { + SECRET_ERROR_PROTOCOL = 1, + SECRET_ERROR_IS_LOCKED = 2, + SECRET_ERROR_NO_SUCH_OBJECT = 3, + SECRET_ERROR_ALREADY_EXISTS = 4, +} SecretError; + +#define SECRET_COLLECTION_DEFAULT "default" + +typedef SecretCollection* (*secret_collection_for_alias_sync_fn)( + SecretService*, const gchar*, SecretCollectionFlags, GCancellable*, + GError**); +typedef SecretService* (*secret_service_get_sync_fn)(SecretServiceFlags, + GCancellable*, GError**); +typedef gint (*secret_service_lock_sync_fn)(SecretService*, GList*, + GCancellable*, GList**, GError**); +typedef gint (*secret_service_unlock_sync_fn)(SecretService*, GList*, + GCancellable*, GList**, GError**); +typedef gboolean (*secret_password_clear_sync_fn)(const SecretSchema*, + GCancellable*, GError**, ...); +typedef gchar* (*secret_password_lookup_sync_fn)(const SecretSchema*, + GCancellable*, GError**, ...); +typedef gboolean (*secret_password_store_sync_fn)(const SecretSchema*, + const gchar*, const gchar*, + const gchar*, GCancellable*, + GError**, ...); +typedef void (*secret_password_free_fn)(const gchar*); +typedef GQuark (*secret_error_get_quark_fn)(); + +static secret_collection_for_alias_sync_fn secret_collection_for_alias_sync = + nullptr; +static secret_service_get_sync_fn secret_service_get_sync = nullptr; +static secret_service_lock_sync_fn secret_service_lock_sync = nullptr; +static secret_service_unlock_sync_fn secret_service_unlock_sync = nullptr; +static secret_password_clear_sync_fn secret_password_clear_sync = nullptr; +static secret_password_lookup_sync_fn secret_password_lookup_sync = nullptr; +static secret_password_store_sync_fn secret_password_store_sync = nullptr; +static secret_password_free_fn secret_password_free = nullptr; +static secret_error_get_quark_fn secret_error_get_quark = nullptr; + +nsresult MaybeLoadLibSecret() { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + if (!libsecret) { + libsecret = PR_LoadLibrary("libsecret-1.so.0"); + if (!libsecret) { + return NS_ERROR_NOT_AVAILABLE; + } + +// With TSan, we cannot unload libsecret once we have loaded it because +// TSan does not support unloading libraries that are matched from its +// suppression list. Hence we just keep the library loaded in TSan builds. +#ifdef MOZ_TSAN +# define UNLOAD_LIBSECRET(x) \ + do { \ + } while (0) +#else +# define UNLOAD_LIBSECRET(x) PR_UnloadLibrary(x) +#endif + +#define FIND_FUNCTION_SYMBOL(function) \ + function = (function##_fn)PR_FindFunctionSymbol(libsecret, #function); \ + if (!(function)) { \ + UNLOAD_LIBSECRET(libsecret); \ + libsecret = nullptr; \ + return NS_ERROR_NOT_AVAILABLE; \ + } + FIND_FUNCTION_SYMBOL(secret_collection_for_alias_sync); + FIND_FUNCTION_SYMBOL(secret_service_get_sync); + FIND_FUNCTION_SYMBOL(secret_service_lock_sync); + FIND_FUNCTION_SYMBOL(secret_service_unlock_sync); + FIND_FUNCTION_SYMBOL(secret_password_clear_sync); + FIND_FUNCTION_SYMBOL(secret_password_lookup_sync); + FIND_FUNCTION_SYMBOL(secret_password_store_sync); + FIND_FUNCTION_SYMBOL(secret_password_free); + FIND_FUNCTION_SYMBOL(secret_error_get_quark); +#undef FIND_FUNCTION_SYMBOL + } + + return NS_OK; +} + +struct ScopedDelete { + void operator()(SecretService* ss) { + if (ss) g_object_unref(ss); + } + void operator()(SecretCollection* sc) { + if (sc) g_object_unref(sc); + } + void operator()(GError* error) { + if (error) g_error_free(error); + } + void operator()(GList* list) { + if (list) g_list_free(list); + } + void operator()(char* val) { + if (val) secret_password_free(val); + } +}; + +template +struct ScopedMaybeDelete { + void operator()(T* ptr) { + if (ptr) { + ScopedDelete del; + del(ptr); + } + } +}; + +typedef std::unique_ptr> ScopedGError; +typedef std::unique_ptr> ScopedGList; +typedef std::unique_ptr> ScopedPassword; +typedef std::unique_ptr> + ScopedSecretCollection; +typedef std::unique_ptr> + ScopedSecretService; + +LibSecret::LibSecret() = default; + +LibSecret::~LibSecret() { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return; + } + if (libsecret) { + secret_collection_for_alias_sync = nullptr; + secret_service_get_sync = nullptr; + secret_service_lock_sync = nullptr; + secret_service_unlock_sync = nullptr; + secret_password_clear_sync = nullptr; + secret_password_lookup_sync = nullptr; + secret_password_store_sync = nullptr; + secret_password_free = nullptr; + secret_error_get_quark = nullptr; + UNLOAD_LIBSECRET(libsecret); + libsecret = nullptr; + } +} + +static const SecretSchema kSchema = { + "mozilla.firefox", + SECRET_SCHEMA_NONE, + {{"string", SECRET_SCHEMA_ATTRIBUTE_STRING}, /* the label */ + {"NULL", SECRET_SCHEMA_ATTRIBUTE_STRING}}}; + +nsresult GetScopedServices(ScopedSecretService& aSs, + ScopedSecretCollection& aSc) { + MOZ_ASSERT(secret_service_get_sync && secret_collection_for_alias_sync); + if (!secret_service_get_sync || !secret_collection_for_alias_sync) { + return NS_ERROR_FAILURE; + } + GError* raw_error = nullptr; + aSs = ScopedSecretService(secret_service_get_sync( + static_cast( + SECRET_SERVICE_OPEN_SESSION), // SecretServiceFlags + nullptr, // GCancellable + &raw_error)); + ScopedGError error(raw_error); + if (error || !aSs) { + MOZ_LOG(gLibSecretLog, LogLevel::Debug, ("Couldn't get a secret service")); + return NS_ERROR_FAILURE; + } + + aSc = ScopedSecretCollection(secret_collection_for_alias_sync( + aSs.get(), "default", static_cast(0), + nullptr, // GCancellable + &raw_error)); + error.reset(raw_error); + if (!aSc) { + MOZ_LOG(gLibSecretLog, LogLevel::Debug, + ("Couldn't get a secret collection")); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult LibSecret::Lock() { + MOZ_ASSERT(secret_service_lock_sync); + if (!secret_service_lock_sync) { + return NS_ERROR_FAILURE; + } + ScopedSecretService ss; + ScopedSecretCollection sc; + if (NS_FAILED(GetScopedServices(ss, sc))) { + return NS_ERROR_FAILURE; + } + + GError* raw_error = nullptr; + GList* collections = nullptr; + ScopedGList collectionList(g_list_append(collections, sc.get())); + int numLocked = secret_service_lock_sync(ss.get(), collectionList.get(), + nullptr, // GCancellable + nullptr, // list of locked items + &raw_error); + ScopedGError error(raw_error); + if (numLocked != 1) { + MOZ_LOG(gLibSecretLog, LogLevel::Debug, + ("Couldn't lock secret collection")); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult LibSecret::Unlock() { + MOZ_ASSERT(secret_service_unlock_sync); + if (!secret_service_unlock_sync) { + return NS_ERROR_FAILURE; + } + // Accessing the secret service might unlock it. + ScopedSecretService ss; + ScopedSecretCollection sc; + if (NS_FAILED(GetScopedServices(ss, sc))) { + return NS_ERROR_FAILURE; + } + GError* raw_error = nullptr; + GList* collections = nullptr; + ScopedGList collectionList(g_list_append(collections, sc.get())); + int numLocked = secret_service_unlock_sync(ss.get(), collectionList.get(), + nullptr, // GCancellable + nullptr, // list of unlocked items + &raw_error); + ScopedGError error(raw_error); + if (numLocked != 1) { + MOZ_LOG(gLibSecretLog, LogLevel::Debug, + ("Couldn't unlock secret collection")); + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +nsresult LibSecret::StoreSecret(const nsACString& aSecret, + const nsACString& aLabel) { + MOZ_ASSERT(secret_password_store_sync); + if (!secret_password_store_sync) { + return NS_ERROR_FAILURE; + } + // libsecret expects a null-terminated string, so to be safe we store the + // secret (which could be arbitrary bytes) base64-encoded. + nsAutoCString base64; + nsresult rv = Base64Encode(aSecret, base64); + if (NS_FAILED(rv)) { + MOZ_LOG(gLibSecretLog, LogLevel::Debug, ("Error base64-encoding secret")); + return rv; + } + GError* raw_error = nullptr; + bool stored = secret_password_store_sync( + &kSchema, SECRET_COLLECTION_DEFAULT, PromiseFlatCString(aLabel).get(), + PromiseFlatCString(base64).get(), + nullptr, // GCancellable + &raw_error, "string", PromiseFlatCString(aLabel).get(), nullptr); + ScopedGError error(raw_error); + if (raw_error) { + MOZ_LOG(gLibSecretLog, LogLevel::Debug, ("Error storing secret")); + return NS_ERROR_FAILURE; + } + + return stored ? NS_OK : NS_ERROR_FAILURE; +} + +nsresult LibSecret::DeleteSecret(const nsACString& aLabel) { + MOZ_ASSERT(secret_password_clear_sync && secret_error_get_quark); + if (!secret_password_clear_sync || !secret_error_get_quark) { + return NS_ERROR_FAILURE; + } + GError* raw_error = nullptr; + Unused << secret_password_clear_sync( + &kSchema, + nullptr, // GCancellable + &raw_error, "string", PromiseFlatCString(aLabel).get(), nullptr); + ScopedGError error(raw_error); + if (raw_error && !(raw_error->domain == secret_error_get_quark() && + raw_error->code == SECRET_ERROR_NO_SUCH_OBJECT)) { + MOZ_LOG(gLibSecretLog, LogLevel::Debug, ("Error deleting secret")); + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult LibSecret::RetrieveSecret(const nsACString& aLabel, + /* out */ nsACString& aSecret) { + MOZ_ASSERT(secret_password_lookup_sync && secret_password_free); + if (!secret_password_lookup_sync || !secret_password_free) { + return NS_ERROR_FAILURE; + } + GError* raw_error = nullptr; + aSecret.Truncate(); + ScopedPassword s(secret_password_lookup_sync( + &kSchema, + nullptr, // GCancellable + &raw_error, "string", PromiseFlatCString(aLabel).get(), nullptr)); + ScopedGError error(raw_error); + if (raw_error || !s) { + MOZ_LOG(gLibSecretLog, LogLevel::Debug, + ("Error retrieving secret or didn't find it")); + return NS_ERROR_FAILURE; + } + // libsecret expects a null-terminated string, so to be safe we store the + // secret (which could be arbitrary bytes) base64-encoded, which means we have + // to base64-decode it here. + nsAutoCString base64Encoded(s.get()); + nsresult rv = Base64Decode(base64Encoded, aSecret); + if (NS_FAILED(rv)) { + MOZ_LOG(gLibSecretLog, LogLevel::Debug, ("Error base64-decoding secret")); + return rv; + } + + return NS_OK; +} diff --git a/security/manager/ssl/LibSecret.h b/security/manager/ssl/LibSecret.h new file mode 100644 index 0000000000..bd2814de04 --- /dev/null +++ b/security/manager/ssl/LibSecret.h @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef LibSecret_h +#define LibSecret_h + +#include "OSKeyStore.h" + +#include "nsString.h" + +nsresult MaybeLoadLibSecret(); + +class LibSecret final : public AbstractOSKeyStore { + public: + LibSecret(); + + virtual nsresult RetrieveSecret(const nsACString& label, + /* out */ nsACString& secret) override; + virtual nsresult StoreSecret(const nsACString& secret, + const nsACString& label) override; + virtual nsresult DeleteSecret(const nsACString& label) override; + virtual nsresult Lock() override; + virtual nsresult Unlock() override; + + virtual ~LibSecret(); +}; + +#endif // LibSecret_h diff --git a/security/manager/ssl/LocalCertService.cpp b/security/manager/ssl/LocalCertService.cpp new file mode 100644 index 0000000000..88ead93f3a --- /dev/null +++ b/security/manager/ssl/LocalCertService.cpp @@ -0,0 +1,444 @@ +/* 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/. */ + +#include "LocalCertService.h" + +#include "CryptoTask.h" +#include "ScopedNSSTypes.h" +#include "cert.h" +#include "mozilla/Casting.h" +#include "mozilla/ModuleUtils.h" +#include "mozilla/RefPtr.h" +#include "nsIPK11Token.h" +#include "nsIPK11TokenDB.h" +#include "nsIX509Cert.h" +#include "nsIX509CertValidity.h" +#include "nsLiteralString.h" +#include "nsNSSCertificate.h" +#include "nsProxyRelease.h" +#include "nsServiceManagerUtils.h" +#include "nsString.h" +#include "pk11pub.h" + +namespace mozilla { + +// Given a name, searches the internal certificate/key database for a +// self-signed certificate with subject and issuer distinguished name equal to +// "CN={name}". This assumes that the user has already authenticated to the +// internal DB if necessary. +static nsresult FindLocalCertByName(const nsACString& aName, + /*out*/ UniqueCERTCertificate& aResult) { + aResult.reset(nullptr); + constexpr auto commonNamePrefix = "CN="_ns; + nsAutoCString expectedDistinguishedName(commonNamePrefix + aName); + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + UniqueCERTCertList certList(PK11_ListCertsInSlot(slot.get())); + if (!certList) { + return NS_ERROR_UNEXPECTED; + } + for (const CERTCertListNode* node = CERT_LIST_HEAD(certList); + !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)) { + // If this isn't a self-signed cert, it's not what we're interested in. + if (!node->cert->isRoot) { + continue; + } + if (!expectedDistinguishedName.Equals(node->cert->subjectName)) { + continue; // Subject should match nickname + } + if (!expectedDistinguishedName.Equals(node->cert->issuerName)) { + continue; // Issuer should match nickname + } + // We found a match. + aResult.reset(CERT_DupCertificate(node->cert)); + return NS_OK; + } + return NS_OK; +} + +class LocalCertTask : public CryptoTask { + protected: + explicit LocalCertTask(const nsACString& aNickname) : mNickname(aNickname) {} + + nsresult RemoveExisting() { + // Search for any existing self-signed certs with this name and remove them + for (;;) { + UniqueCERTCertificate cert; + nsresult rv = FindLocalCertByName(mNickname, cert); + if (NS_FAILED(rv)) { + return rv; + } + // If we didn't find a match, we're done. + if (!cert) { + return NS_OK; + } + rv = MapSECStatus(PK11_DeleteTokenCertAndKey(cert.get(), nullptr)); + if (NS_FAILED(rv)) { + return rv; + } + } + } + + nsCString mNickname; +}; + +class LocalCertGetTask final : public LocalCertTask { + public: + LocalCertGetTask(const nsACString& aNickname, + nsILocalCertGetCallback* aCallback) + : LocalCertTask(aNickname), + mCallback(new nsMainThreadPtrHolder( + "LocalCertGetTask::mCallback", aCallback)), + mCert(nullptr) {} + + private: + virtual nsresult CalculateResult() override { + // Try to lookup an existing cert in the DB + nsresult rv = GetFromDB(); + // Make a new one if getting fails + if (NS_FAILED(rv)) { + rv = Generate(); + } + // If generation fails, we're out of luck + if (NS_FAILED(rv)) { + return rv; + } + + // Validate cert, make a new one if it fails + rv = Validate(); + if (NS_FAILED(rv)) { + rv = Generate(); + } + // If generation fails, we're out of luck + if (NS_FAILED(rv)) { + return rv; + } + + return NS_OK; + } + + nsresult Generate() { + nsresult rv; + + // Get the key slot for generation later + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + // Remove existing certs with this name (if any) + rv = RemoveExisting(); + if (NS_FAILED(rv)) { + return rv; + } + + // Generate a new cert + constexpr auto commonNamePrefix = "CN="_ns; + nsAutoCString subjectNameStr(commonNamePrefix + mNickname); + UniqueCERTName subjectName(CERT_AsciiToName(subjectNameStr.get())); + if (!subjectName) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + // Use the well-known NIST P-256 curve + SECOidData* curveOidData = SECOID_FindOIDByTag(SEC_OID_SECG_EC_SECP256R1); + if (!curveOidData) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + // Get key params from the curve + ScopedAutoSECItem keyParams(2 + curveOidData->oid.len); + keyParams.data[0] = SEC_ASN1_OBJECT_ID; + keyParams.data[1] = curveOidData->oid.len; + memcpy(keyParams.data + 2, curveOidData->oid.data, curveOidData->oid.len); + + // Generate cert key pair + SECKEYPublicKey* tempPublicKey; + UniqueSECKEYPrivateKey privateKey(PK11_GenerateKeyPair( + slot.get(), CKM_EC_KEY_PAIR_GEN, &keyParams, &tempPublicKey, + true /* token */, true /* sensitive */, nullptr)); + UniqueSECKEYPublicKey publicKey(tempPublicKey); + tempPublicKey = nullptr; + if (!privateKey || !publicKey) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + // Create subject public key info and cert request + UniqueCERTSubjectPublicKeyInfo spki( + SECKEY_CreateSubjectPublicKeyInfo(publicKey.get())); + if (!spki) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + UniqueCERTCertificateRequest certRequest( + CERT_CreateCertificateRequest(subjectName.get(), spki.get(), nullptr)); + if (!certRequest) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + // Valid from one day before to 1 year after + static const PRTime oneDay = PRTime(PR_USEC_PER_SEC) * PRTime(60) // sec + * PRTime(60) // min + * PRTime(24); // hours + + PRTime now = PR_Now(); + PRTime notBefore = now - oneDay; + PRTime notAfter = now + (PRTime(365) * oneDay); + UniqueCERTValidity validity(CERT_CreateValidity(notBefore, notAfter)); + if (!validity) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + // Generate random serial + unsigned long serial; + // This serial in principle could collide, but it's unlikely + rv = MapSECStatus(PK11_GenerateRandomOnSlot( + slot.get(), BitwiseCast(&serial), + sizeof(serial))); + if (NS_FAILED(rv)) { + return rv; + } + + // Create the cert from these pieces + UniqueCERTCertificate cert(CERT_CreateCertificate( + serial, subjectName.get(), validity.get(), certRequest.get())); + if (!cert) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + // Update the cert version to X509v3 + if (!cert->version.data) { + return NS_ERROR_INVALID_POINTER; + } + *(cert->version.data) = SEC_CERTIFICATE_VERSION_3; + cert->version.len = 1; + + // Set cert signature algorithm + PLArenaPool* arena = cert->arena; + if (!arena) { + return NS_ERROR_INVALID_POINTER; + } + rv = MapSECStatus(SECOID_SetAlgorithmID( + arena, &cert->signature, SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE, 0)); + if (NS_FAILED(rv)) { + return rv; + } + + // Encode and self-sign the cert + UniqueSECItem certDER(SEC_ASN1EncodeItem( + nullptr, nullptr, cert.get(), SEC_ASN1_GET(CERT_CertificateTemplate))); + if (!certDER) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + rv = MapSECStatus(SEC_DerSignData(arena, &cert->derCert, certDER->data, + certDER->len, privateKey.get(), + SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE)); + if (NS_FAILED(rv)) { + return rv; + } + + // Create a CERTCertificate from the signed data + UniqueCERTCertificate certFromDER( + CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &cert->derCert, + nullptr, true /* perm */, true /* copyDER */)); + if (!certFromDER) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + // Save the cert in the DB + rv = MapSECStatus(PK11_ImportCert(slot.get(), certFromDER.get(), + CK_INVALID_HANDLE, mNickname.get(), + false /* unused */)); + if (NS_FAILED(rv)) { + return rv; + } + + // We should now have cert in the DB, read it back in nsIX509Cert form + return GetFromDB(); + } + + nsresult GetFromDB() { + UniqueCERTCertificate cert; + nsresult rv = FindLocalCertByName(mNickname, cert); + if (NS_FAILED(rv)) { + return rv; + } + if (!cert) { + return NS_ERROR_FAILURE; + } + mCert = nsNSSCertificate::Create(cert.get()); + return NS_OK; + } + + nsresult Validate() { + // Check that subject and issuer match nickname + nsAutoString subjectName; + nsAutoString issuerName; + mCert->GetSubjectName(subjectName); + mCert->GetIssuerName(issuerName); + if (!subjectName.Equals(issuerName)) { + return NS_ERROR_FAILURE; + } + constexpr auto commonNamePrefix = u"CN="_ns; + nsAutoString subjectNameFromNickname(commonNamePrefix + + NS_ConvertASCIItoUTF16(mNickname)); + if (!subjectName.Equals(subjectNameFromNickname)) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr validity; + mCert->GetValidity(getter_AddRefs(validity)); + + PRTime notBefore, notAfter; + validity->GetNotBefore(¬Before); + validity->GetNotAfter(¬After); + + // Ensure cert will last at least one more day + static const PRTime oneDay = PRTime(PR_USEC_PER_SEC) * PRTime(60) // sec + * PRTime(60) // min + * PRTime(24); // hours + PRTime now = PR_Now(); + if (notBefore > now || notAfter < (now - oneDay)) { + return NS_ERROR_FAILURE; + } + + return NS_OK; + } + + virtual void CallCallback(nsresult rv) override { + (void)mCallback->HandleCert(mCert, rv); + } + + nsMainThreadPtrHandle mCallback; + nsCOMPtr mCert; // out +}; + +class LocalCertRemoveTask final : public LocalCertTask { + public: + LocalCertRemoveTask(const nsACString& aNickname, + nsILocalCertCallback* aCallback) + : LocalCertTask(aNickname), + mCallback(new nsMainThreadPtrHolder( + "LocalCertRemoveTask::mCallback", aCallback)) {} + + private: + virtual nsresult CalculateResult() override { return RemoveExisting(); } + + virtual void CallCallback(nsresult rv) override { + (void)mCallback->HandleResult(rv); + } + + nsMainThreadPtrHandle mCallback; +}; + +NS_IMPL_ISUPPORTS(LocalCertService, nsILocalCertService) + +LocalCertService::LocalCertService() = default; + +LocalCertService::~LocalCertService() = default; + +nsresult LocalCertService::LoginToKeySlot() { + nsresult rv; + + // Get access to key slot + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + // If no user password yet, set it an empty one + if (PK11_NeedUserInit(slot.get())) { + rv = MapSECStatus(PK11_InitPin(slot.get(), "", "")); + if (NS_FAILED(rv)) { + return rv; + } + } + + // If user has a password set, prompt to login + if (PK11_NeedLogin(slot.get()) && !PK11_IsLoggedIn(slot.get(), nullptr)) { + // Switching to XPCOM to get the UI prompt that PSM owns + nsCOMPtr tokenDB = do_GetService(NS_PK11TOKENDB_CONTRACTID); + if (!tokenDB) { + return NS_ERROR_FAILURE; + } + nsCOMPtr keyToken; + tokenDB->GetInternalKeyToken(getter_AddRefs(keyToken)); + if (!keyToken) { + return NS_ERROR_FAILURE; + } + // Prompt the user to login + return keyToken->Login(false /* force */); + } + + return NS_OK; +} + +NS_IMETHODIMP +LocalCertService::GetOrCreateCert(const nsACString& aNickname, + nsILocalCertGetCallback* aCallback) { + if (NS_WARN_IF(aNickname.IsEmpty())) { + return NS_ERROR_INVALID_ARG; + } + if (NS_WARN_IF(!aCallback)) { + return NS_ERROR_INVALID_POINTER; + } + + // Before sending off the task, login to key slot if needed + nsresult rv = LoginToKeySlot(); + if (NS_FAILED(rv)) { + aCallback->HandleCert(nullptr, rv); + return NS_OK; + } + + RefPtr task(new LocalCertGetTask(aNickname, aCallback)); + return task->Dispatch(); +} + +NS_IMETHODIMP +LocalCertService::RemoveCert(const nsACString& aNickname, + nsILocalCertCallback* aCallback) { + if (NS_WARN_IF(aNickname.IsEmpty())) { + return NS_ERROR_INVALID_ARG; + } + if (NS_WARN_IF(!aCallback)) { + return NS_ERROR_INVALID_POINTER; + } + + // Before sending off the task, login to key slot if needed + nsresult rv = LoginToKeySlot(); + if (NS_FAILED(rv)) { + aCallback->HandleResult(rv); + return NS_OK; + } + + RefPtr task( + new LocalCertRemoveTask(aNickname, aCallback)); + return task->Dispatch(); +} + +NS_IMETHODIMP +LocalCertService::GetLoginPromptRequired(bool* aRequired) { + nsresult rv; + + // Get access to key slot + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + // If no user password yet, set it an empty one + if (PK11_NeedUserInit(slot.get())) { + rv = MapSECStatus(PK11_InitPin(slot.get(), "", "")); + if (NS_FAILED(rv)) { + return rv; + } + } + + *aRequired = + PK11_NeedLogin(slot.get()) && !PK11_IsLoggedIn(slot.get(), nullptr); + return NS_OK; +} + +} // namespace mozilla diff --git a/security/manager/ssl/LocalCertService.h b/security/manager/ssl/LocalCertService.h new file mode 100644 index 0000000000..9bcea96cc2 --- /dev/null +++ b/security/manager/ssl/LocalCertService.h @@ -0,0 +1,26 @@ +/* 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/. */ + +#ifndef LocalCertService_h +#define LocalCertService_h + +#include "nsILocalCertService.h" + +namespace mozilla { + +class LocalCertService final : public nsILocalCertService { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSILOCALCERTSERVICE + + LocalCertService(); + + private: + nsresult LoginToKeySlot(); + ~LocalCertService(); +}; + +} // namespace mozilla + +#endif // LocalCertService_h diff --git a/security/manager/ssl/NSSErrorsService.cpp b/security/manager/ssl/NSSErrorsService.cpp new file mode 100644 index 0000000000..06c0b1e790 --- /dev/null +++ b/security/manager/ssl/NSSErrorsService.cpp @@ -0,0 +1,212 @@ +/* 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/. */ + +#include "NSSErrorsService.h" + +#include "nsIStringBundle.h" +#include "nsNSSComponent.h" +#include "nsServiceManagerUtils.h" +#include "mozpkix/pkixnss.h" +#include "secerr.h" +#include "sslerr.h" + +#define PIPNSS_STRBUNDLE_URL "chrome://pipnss/locale/pipnss.properties" +#define NSSERR_STRBUNDLE_URL "chrome://pipnss/locale/nsserrors.properties" + +namespace mozilla { +namespace psm { + +static_assert(mozilla::pkix::ERROR_BASE == + nsINSSErrorsService::MOZILLA_PKIX_ERROR_BASE, + "MOZILLA_PKIX_ERROR_BASE and " + "nsINSSErrorsService::MOZILLA_PKIX_ERROR_BASE do not match."); +static_assert(mozilla::pkix::ERROR_LIMIT == + nsINSSErrorsService::MOZILLA_PKIX_ERROR_LIMIT, + "MOZILLA_PKIX_ERROR_LIMIT and " + "nsINSSErrorsService::MOZILLA_PKIX_ERROR_LIMIT do not match."); + +static bool IsPSMError(PRErrorCode error) { + return (error >= mozilla::pkix::ERROR_BASE && + error < mozilla::pkix::ERROR_LIMIT); +} + +NS_IMPL_ISUPPORTS(NSSErrorsService, nsINSSErrorsService) + +NSSErrorsService::~NSSErrorsService() = default; + +nsresult NSSErrorsService::Init() { + nsresult rv; + nsCOMPtr bundleService( + do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv)); + if (NS_FAILED(rv) || !bundleService) return NS_ERROR_FAILURE; + + bundleService->CreateBundle(PIPNSS_STRBUNDLE_URL, + getter_AddRefs(mPIPNSSBundle)); + if (!mPIPNSSBundle) rv = NS_ERROR_FAILURE; + + bundleService->CreateBundle(NSSERR_STRBUNDLE_URL, + getter_AddRefs(mNSSErrorsBundle)); + if (!mNSSErrorsBundle) rv = NS_ERROR_FAILURE; + + return rv; +} + +#define EXPECTED_SEC_ERROR_BASE (-0x2000) +#define EXPECTED_SSL_ERROR_BASE (-0x3000) + +#if SEC_ERROR_BASE != EXPECTED_SEC_ERROR_BASE || \ + SSL_ERROR_BASE != EXPECTED_SSL_ERROR_BASE +# error \ + "Unexpected change of error code numbers in lib NSS, please adjust the mapping code" +/* + * Please ensure the NSS error codes are mapped into the positive range 0x1000 + * to 0xf000 Search for NS_ERROR_MODULE_SECURITY to ensure there are no + * conflicts. The current code also assumes that NSS library error codes are + * negative. + */ +#endif + +bool IsNSSErrorCode(PRErrorCode code) { + return IS_SEC_ERROR(code) || IS_SSL_ERROR(code) || IsPSMError(code); +} + +nsresult GetXPCOMFromNSSError(PRErrorCode code) { + if (!code) { + MOZ_CRASH("Function failed without calling PR_GetError"); + } + + // The error codes within each module must be a 16 bit value. + // For simplicity we use the positive value of the NSS code. + return (nsresult)NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY, + -1 * code); +} + +NS_IMETHODIMP +NSSErrorsService::IsNSSErrorCode(int32_t aNSPRCode, bool* _retval) { + if (!_retval) { + return NS_ERROR_INVALID_ARG; + } + + *_retval = mozilla::psm::IsNSSErrorCode(aNSPRCode); + return NS_OK; +} + +NS_IMETHODIMP +NSSErrorsService::GetXPCOMFromNSSError(int32_t aNSPRCode, + nsresult* aXPCOMErrorCode) { + if (!aXPCOMErrorCode) { + return NS_ERROR_INVALID_ARG; + } + + if (!mozilla::psm::IsNSSErrorCode(aNSPRCode)) { + return NS_ERROR_INVALID_ARG; + } + + *aXPCOMErrorCode = mozilla::psm::GetXPCOMFromNSSError(aNSPRCode); + + return NS_OK; +} + +NS_IMETHODIMP +NSSErrorsService::GetErrorClass(nsresult aXPCOMErrorCode, + uint32_t* aErrorClass) { + NS_ENSURE_ARG(aErrorClass); + + if (NS_ERROR_GET_MODULE(aXPCOMErrorCode) != NS_ERROR_MODULE_SECURITY || + NS_ERROR_GET_SEVERITY(aXPCOMErrorCode) != NS_ERROR_SEVERITY_ERROR) { + return NS_ERROR_FAILURE; + } + + int32_t aNSPRCode = -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode); + + if (!mozilla::psm::IsNSSErrorCode(aNSPRCode)) { + return NS_ERROR_FAILURE; + } + + if (mozilla::psm::ErrorIsOverridable(aNSPRCode)) { + *aErrorClass = ERROR_CLASS_BAD_CERT; + } else { + *aErrorClass = ERROR_CLASS_SSL_PROTOCOL; + } + + return NS_OK; +} + +bool ErrorIsOverridable(PRErrorCode code) { + switch (code) { + // Overridable errors. + case mozilla::pkix::MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED: + case mozilla::pkix::MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY: + case mozilla::pkix::MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME: + case mozilla::pkix::MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE: + case mozilla::pkix::MOZILLA_PKIX_ERROR_MITM_DETECTED: + case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE: + case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE: + case mozilla::pkix::MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT: + case mozilla::pkix::MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA: + case SEC_ERROR_CA_CERT_INVALID: + case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: + case SEC_ERROR_EXPIRED_CERTIFICATE: + case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: + case SEC_ERROR_INVALID_TIME: + case SEC_ERROR_UNKNOWN_ISSUER: + case SSL_ERROR_BAD_CERT_DOMAIN: + return true; + // Non-overridable errors. + default: + return false; + } +} + +static const char* getOverrideErrorStringName(PRErrorCode aErrorCode) { + switch (aErrorCode) { + case SSL_ERROR_SSL_DISABLED: + return "PSMERR_SSL_Disabled"; + case SSL_ERROR_SSL2_DISABLED: + return "PSMERR_SSL2_Disabled"; + case SEC_ERROR_REUSED_ISSUER_AND_SERIAL: + return "PSMERR_HostReusedIssuerSerial"; + case mozilla::pkix::MOZILLA_PKIX_ERROR_MITM_DETECTED: + return "certErrorTrust_MitM"; + default: + return nullptr; + } +} + +NS_IMETHODIMP +NSSErrorsService::GetErrorMessage(nsresult aXPCOMErrorCode, + nsAString& aErrorMessage) { + if (NS_ERROR_GET_MODULE(aXPCOMErrorCode) != NS_ERROR_MODULE_SECURITY || + NS_ERROR_GET_SEVERITY(aXPCOMErrorCode) != NS_ERROR_SEVERITY_ERROR) { + return NS_ERROR_FAILURE; + } + + int32_t aNSPRCode = -1 * NS_ERROR_GET_CODE(aXPCOMErrorCode); + + if (!mozilla::psm::IsNSSErrorCode(aNSPRCode)) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr theBundle = mPIPNSSBundle; + const char* idStr = getOverrideErrorStringName(aNSPRCode); + + if (!idStr) { + idStr = PR_ErrorToName(aNSPRCode); + theBundle = mNSSErrorsBundle; + } + + if (!idStr || !theBundle) { + return NS_ERROR_FAILURE; + } + + nsAutoString msg; + nsresult rv = theBundle->GetStringFromName(idStr, msg); + if (NS_SUCCEEDED(rv)) { + aErrorMessage = msg; + } + return rv; +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/NSSErrorsService.h b/security/manager/ssl/NSSErrorsService.h new file mode 100644 index 0000000000..a19bea9e5f --- /dev/null +++ b/security/manager/ssl/NSSErrorsService.h @@ -0,0 +1,56 @@ +/* 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/. */ + +#ifndef NSSErrorsService_h +#define NSSErrorsService_h + +#include "mozilla/Attributes.h" +#include "nsCOMPtr.h" +#include "nsILineInputStream.h" +#include "nsINSSErrorsService.h" +#include "nsISafeOutputStream.h" +#include "nsIStringBundle.h" +#include "prerror.h" + +class nsIStringBundle; + +namespace mozilla { +namespace psm { + +class NSSErrorsService final : public nsINSSErrorsService { + NS_DECL_ISUPPORTS + NS_DECL_NSINSSERRORSSERVICE + + public: + nsresult Init(); + + private: + // For XPCOM implementations that are not a base class for some other + // class, it is good practice to make the destructor non-virtual and + // private. Then the only way to delete the object is via Release. +#ifdef _MSC_VER + // C4265: Class has virtual members but destructor is not virtual + __pragma(warning(disable : 4265)) +#endif + ~NSSErrorsService(); + + nsCOMPtr mPIPNSSBundle; + nsCOMPtr mNSSErrorsBundle; +}; + +bool IsNSSErrorCode(PRErrorCode code); +nsresult GetXPCOMFromNSSError(PRErrorCode code); +bool ErrorIsOverridable(PRErrorCode code); + +} // namespace psm +} // namespace mozilla + +#define NS_NSSERRORSSERVICE_CID \ + { \ + 0x9ef18451, 0xa157, 0x4d17, { \ + 0x81, 0x32, 0x47, 0xaf, 0xef, 0x21, 0x36, 0x89 \ + } \ + } + +#endif // NSSErrorsService_h diff --git a/security/manager/ssl/NSSKeyStore.cpp b/security/manager/ssl/NSSKeyStore.cpp new file mode 100644 index 0000000000..984e305061 --- /dev/null +++ b/security/manager/ssl/NSSKeyStore.cpp @@ -0,0 +1,225 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "NSSKeyStore.h" + +#include "mozilla/Base64.h" +#include "mozilla/SyncRunnable.h" +#include "nsNSSComponent.h" +#include "nsPK11TokenDB.h" +#include "nsXULAppAPI.h" + +/* Implementing OSKeyStore when there is no platform specific one. + * This key store instead puts the keys into the NSS DB. + */ + +using namespace mozilla; +using mozilla::SyncRunnable; + +LazyLogModule gNSSKeyStoreLog("nsskeystore"); + +NSSKeyStore::NSSKeyStore() { + MOZ_ASSERT(XRE_IsParentProcess()); + if (!XRE_IsParentProcess()) { + // This shouldn't happen as this is only initialised when creating the + // OSKeyStore, which is ParentProcessOnly. + return; + } + Unused << EnsureNSSInitializedChromeOrContent(); + Unused << InitToken(); +} +NSSKeyStore::~NSSKeyStore() = default; + +nsresult NSSKeyStore::InitToken() { + if (!mSlot) { + mSlot = UniquePK11SlotInfo(PK11_GetInternalKeySlot()); + if (!mSlot) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, + ("Error getting internal key slot")); + return NS_ERROR_NOT_AVAILABLE; + } + } + return NS_OK; +} + +nsresult NSSKeyStoreMainThreadLock(PK11SlotInfo* aSlot) { + nsCOMPtr token = new nsPK11Token(aSlot); + return token->LogoutSimple(); +} + +nsresult NSSKeyStore::Lock() { + NS_ENSURE_STATE(mSlot); + + if (!NS_IsMainThread()) { + nsCOMPtr mainThread; + nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread)); + if (NS_FAILED(rv)) { + return NS_ERROR_FAILURE; + } + + // Forward to the main thread synchronously. + SyncRunnable::DispatchToThread( + mainThread, new SyncRunnable(NS_NewRunnableFunction( + "NSSKeyStoreMainThreadLock", [slot = mSlot.get()]() { + NSSKeyStoreMainThreadLock(slot); + }))); + + return NS_OK; + } + + return NSSKeyStoreMainThreadLock(mSlot.get()); +} + +nsresult NSSKeyStoreMainThreadUnlock(PK11SlotInfo* aSlot) { + nsCOMPtr token = new nsPK11Token(aSlot); + return NS_FAILED(token->Login(false /* force */)) ? NS_ERROR_FAILURE : NS_OK; +} + +nsresult NSSKeyStore::Unlock() { + NS_ENSURE_STATE(mSlot); + + if (!NS_IsMainThread()) { + nsCOMPtr mainThread; + nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread)); + if (NS_FAILED(rv)) { + return NS_ERROR_FAILURE; + } + + // Forward to the main thread synchronously. + nsresult result = NS_ERROR_FAILURE; + SyncRunnable::DispatchToThread( + mainThread, new SyncRunnable(NS_NewRunnableFunction( + "NSSKeyStoreMainThreadUnlock", + [slot = mSlot.get(), result = &result]() { + *result = NSSKeyStoreMainThreadUnlock(slot); + }))); + + return result; + } + + return NSSKeyStoreMainThreadUnlock(mSlot.get()); +} + +nsresult NSSKeyStore::StoreSecret(const nsACString& aSecret, + const nsACString& aLabel) { + NS_ENSURE_STATE(mSlot); + if (NS_FAILED(Unlock())) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, ("Error unlocking NSS key db")); + return NS_ERROR_FAILURE; + } + + // It is possible for multiple keys to have the same nickname in NSS. To + // prevent the problem of not knowing which key to use in the future, simply + // delete all keys with this nickname before storing a new one. + nsresult rv = DeleteSecret(aLabel); + if (NS_FAILED(rv)) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, + ("DeleteSecret before StoreSecret failed")); + return rv; + } + + uint8_t* p = BitwiseCast(aSecret.BeginReading()); + UniqueSECItem key(SECITEM_AllocItem(nullptr, nullptr, aSecret.Length())); + if (!key) { + return NS_ERROR_OUT_OF_MEMORY; + } + key->type = siBuffer; + memcpy(key->data, p, aSecret.Length()); + key->len = aSecret.Length(); + UniquePK11SymKey symKey( + PK11_ImportSymKey(mSlot.get(), CKM_AES_GCM, PK11_OriginUnwrap, + CKA_DECRYPT | CKA_ENCRYPT, key.get(), nullptr)); + if (!symKey) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, ("Error creating NSS SymKey")); + return NS_ERROR_FAILURE; + } + UniquePK11SymKey storedKey( + PK11_ConvertSessionSymKeyToTokenSymKey(symKey.get(), nullptr)); + if (!storedKey) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, + ("Error storing NSS SymKey in DB")); + return NS_ERROR_FAILURE; + } + SECStatus srv = + PK11_SetSymKeyNickname(storedKey.get(), PromiseFlatCString(aLabel).get()); + if (srv != SECSuccess) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, ("Error naming NSS SymKey")); + (void)PK11_DeleteTokenSymKey(storedKey.get()); + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult NSSKeyStore::DeleteSecret(const nsACString& aLabel) { + NS_ENSURE_STATE(mSlot); + if (NS_FAILED(Unlock())) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, ("Error unlocking NSS key db")); + return NS_ERROR_FAILURE; + } + + UniquePK11SymKey symKey(PK11_ListFixedKeysInSlot( + mSlot.get(), const_cast(PromiseFlatCString(aLabel).get()), + nullptr)); + if (!symKey) { + // Couldn't find the key or something is wrong. Be nice. + return NS_OK; + } + for (PK11SymKey* tmp = symKey.get(); tmp; tmp = PK11_GetNextSymKey(tmp)) { + SECStatus srv = PK11_DeleteTokenSymKey(tmp); + if (srv != SECSuccess) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, ("Error deleting NSS SymKey")); + return NS_ERROR_FAILURE; + } + } + return NS_OK; +} + +bool NSSKeyStore::SecretAvailable(const nsACString& aLabel) { + if (!mSlot) { + return false; + } + if (NS_FAILED(Unlock())) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, ("Error unlocking NSS key db")); + return false; + } + + UniquePK11SymKey symKey(PK11_ListFixedKeysInSlot( + mSlot.get(), const_cast(PromiseFlatCString(aLabel).get()), + nullptr)); + if (!symKey) { + return false; + } + return true; +} + +nsresult NSSKeyStore::EncryptDecrypt(const nsACString& aLabel, + const std::vector& inBytes, + std::vector& outBytes, + bool encrypt) { + NS_ENSURE_STATE(mSlot); + if (NS_FAILED(Unlock())) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, ("Error unlocking NSS key db")); + return NS_ERROR_FAILURE; + } + + UniquePK11SymKey symKey(PK11_ListFixedKeysInSlot( + mSlot.get(), const_cast(PromiseFlatCString(aLabel).get()), + nullptr)); + if (!symKey) { + MOZ_LOG(gNSSKeyStoreLog, LogLevel::Debug, + ("Error finding key for given label")); + return NS_ERROR_FAILURE; + } + return DoCipher(symKey, inBytes, outBytes, encrypt); +} + +// Because NSSKeyStore overrides AbstractOSKeyStore's EncryptDecrypt and +// SecretAvailable functions, this isn't necessary. +nsresult NSSKeyStore::RetrieveSecret(const nsACString& aLabel, + /* out */ nsACString& aSecret) { + return NS_ERROR_NOT_IMPLEMENTED; +} diff --git a/security/manager/ssl/NSSKeyStore.h b/security/manager/ssl/NSSKeyStore.h new file mode 100644 index 0000000000..2506f91b0b --- /dev/null +++ b/security/manager/ssl/NSSKeyStore.h @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef NSSKeyStore_h +#define NSSKeyStore_h + +#include "OSKeyStore.h" +#include "nsString.h" + +class NSSKeyStore final : public AbstractOSKeyStore { + public: + NSSKeyStore(); + + virtual nsresult RetrieveSecret(const nsACString& aLabel, + /* out */ nsACString& aSecret) override; + virtual nsresult StoreSecret(const nsACString& secret, + const nsACString& label) override; + virtual nsresult DeleteSecret(const nsACString& label) override; + virtual nsresult Lock() override; + virtual nsresult Unlock() override; + virtual nsresult EncryptDecrypt(const nsACString& label, + const std::vector& inBytes, + std::vector& outBytes, + bool encrypt) override; + virtual bool SecretAvailable(const nsACString& label) override; + virtual ~NSSKeyStore(); + + private: + nsresult InitToken(); + mozilla::UniquePK11SlotInfo mSlot = nullptr; +}; + +#endif // NSSKeyStore_h diff --git a/security/manager/ssl/OSKeyStore.cpp b/security/manager/ssl/OSKeyStore.cpp new file mode 100644 index 0000000000..f2f1537ce4 --- /dev/null +++ b/security/manager/ssl/OSKeyStore.cpp @@ -0,0 +1,726 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "OSKeyStore.h" + +#include "mozilla/Base64.h" +#include "mozilla/dom/Promise.h" +#include "nsThreadUtils.h" +#include "nsXPCOM.h" +#include "pk11pub.h" + +#if defined(XP_MACOSX) +# include "KeychainSecret.h" +#elif defined(XP_WIN) +# include "CredentialManagerSecret.h" +#elif defined(MOZ_WIDGET_GTK) +# include "LibSecret.h" +# include "NSSKeyStore.h" +#else +# include "NSSKeyStore.h" +#endif + +NS_IMPL_ISUPPORTS(OSKeyStore, nsIOSKeyStore) + +using namespace mozilla; +using dom::Promise; + +OSKeyStore::OSKeyStore() : mKs(nullptr), mKsIsNSSKeyStore(false) { + MOZ_ASSERT(NS_IsMainThread()); + if (NS_WARN_IF(!NS_IsMainThread())) { + return; + } + +#if defined(XP_MACOSX) + mKs.reset(new KeychainSecret()); +#elif defined(XP_WIN) + mKs.reset(new CredentialManagerSecret()); +#elif defined(MOZ_WIDGET_GTK) + if (NS_SUCCEEDED(MaybeLoadLibSecret())) { + mKs.reset(new LibSecret()); + } else { + mKs.reset(new NSSKeyStore()); + mKsIsNSSKeyStore = true; + } +#else + mKs.reset(new NSSKeyStore()); + mKsIsNSSKeyStore = true; +#endif +} + +static nsresult GenerateRandom(std::vector& r) { + if (r.empty()) { + return NS_ERROR_INVALID_ARG; + } + UniquePK11SlotInfo slot(PK11_GetInternalSlot()); + if (!slot) { + return NS_ERROR_FAILURE; + } + + SECStatus srv = PK11_GenerateRandomOnSlot(slot.get(), r.data(), r.size()); + if (srv != SECSuccess) { + r.clear(); + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +nsresult OSKeyStore::SecretAvailable(const nsACString& aLabel, + /* out */ bool* aAvailable) { + NS_ENSURE_STATE(mKs); + *aAvailable = mKs->SecretAvailable(aLabel); + return NS_OK; +} + +nsresult OSKeyStore::GenerateSecret(const nsACString& aLabel, + /* out */ nsACString& aRecoveryPhrase) { + NS_ENSURE_STATE(mKs); + size_t keyByteLength = mKs->GetKeyByteLength(); + std::vector secret(keyByteLength); + nsresult rv = GenerateRandom(secret); + if (NS_FAILED(rv) || secret.size() != keyByteLength) { + return NS_ERROR_FAILURE; + } + nsAutoCString secretString; + secretString.Assign(BitwiseCast(secret.data()), + secret.size()); + + nsCString base64; + rv = Base64Encode(secretString, base64); + if (NS_FAILED(rv)) { + return rv; + } + + rv = mKs->StoreSecret(secretString, aLabel); + if (NS_FAILED(rv)) { + return rv; + } + + aRecoveryPhrase = std::move(base64); + return NS_OK; +} + +nsresult OSKeyStore::RecoverSecret(const nsACString& aLabel, + const nsACString& aRecoveryPhrase) { + NS_ENSURE_STATE(mKs); + nsAutoCString secret; + nsresult rv = Base64Decode(aRecoveryPhrase, secret); + if (NS_FAILED(rv)) { + return rv; + } + if (secret.Length() != mKs->GetKeyByteLength()) { + return NS_ERROR_INVALID_ARG; + } + rv = mKs->StoreSecret(secret, aLabel); + if (NS_FAILED(rv)) { + return rv; + } + + return NS_OK; +} + +nsresult OSKeyStore::DeleteSecret(const nsACString& aLabel) { + NS_ENSURE_STATE(mKs); + return mKs->DeleteSecret(aLabel); +} + +enum Cipher { Encrypt = true, Decrypt = false }; + +nsresult OSKeyStore::EncryptBytes(const nsACString& aLabel, + const std::vector& aInBytes, + /*out*/ nsACString& aEncryptedBase64Text) { + NS_ENSURE_STATE(mKs); + + aEncryptedBase64Text.Truncate(); + std::vector outBytes; + nsresult rv = + mKs->EncryptDecrypt(aLabel, aInBytes, outBytes, Cipher::Encrypt); + if (NS_FAILED(rv)) { + return rv; + } + nsAutoCString ciphertext; + ciphertext.Assign(BitwiseCast(outBytes.data()), + outBytes.size()); + + nsCString base64ciphertext; + rv = Base64Encode(ciphertext, base64ciphertext); + if (NS_FAILED(rv)) { + return rv; + } + aEncryptedBase64Text = std::move(base64ciphertext); + return NS_OK; +} + +nsresult OSKeyStore::DecryptBytes(const nsACString& aLabel, + const nsACString& aEncryptedBase64Text, + /*out*/ uint32_t* outLen, + /*out*/ uint8_t** outBytes) { + NS_ENSURE_STATE(mKs); + NS_ENSURE_ARG_POINTER(outLen); + NS_ENSURE_ARG_POINTER(outBytes); + *outLen = 0; + *outBytes = nullptr; + + nsAutoCString ciphertext; + nsresult rv = Base64Decode(aEncryptedBase64Text, ciphertext); + if (NS_FAILED(rv)) { + return rv; + } + uint8_t* tmp = BitwiseCast(ciphertext.BeginReading()); + const std::vector ciphertextBytes(tmp, tmp + ciphertext.Length()); + std::vector plaintextBytes; + rv = mKs->EncryptDecrypt(aLabel, ciphertextBytes, plaintextBytes, + Cipher::Decrypt); + if (NS_FAILED(rv)) { + return rv; + } + + *outBytes = (uint8_t*)moz_xmalloc(plaintextBytes.size()); + memcpy(*outBytes, plaintextBytes.data(), plaintextBytes.size()); + *outLen = plaintextBytes.size(); + return NS_OK; +} + +nsresult OSKeyStore::Lock() { + NS_ENSURE_STATE(mKs); + return mKs->Lock(); +} + +nsresult OSKeyStore::Unlock() { + NS_ENSURE_STATE(mKs); + return mKs->Unlock(); +} + +NS_IMETHODIMP +OSKeyStore::GetIsNSSKeyStore(bool* aNSSKeyStore) { + NS_ENSURE_ARG_POINTER(aNSSKeyStore); + *aNSSKeyStore = mKsIsNSSKeyStore; + return NS_OK; +} + +// Async interfaces that return promises because the key store implementation +// might block, e.g. asking for a password. + +nsresult GetPromise(JSContext* aCx, /* out */ RefPtr& aPromise) { + nsIGlobalObject* globalObject = xpc::CurrentNativeGlobal(aCx); + if (NS_WARN_IF(!globalObject)) { + return NS_ERROR_UNEXPECTED; + } + ErrorResult result; + aPromise = Promise::Create(globalObject, result); + if (NS_WARN_IF(result.Failed())) { + return result.StealNSResult(); + } + return NS_OK; +} + +void BackgroundUnlock(RefPtr& aPromise, RefPtr self) { + nsAutoCString recovery; + nsresult rv = self->Unlock(); + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundUnlockOSKSResolve", [rv, aPromise = std::move(aPromise)]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolveWithUndefined(); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +NS_IMETHODIMP +OSKeyStore::AsyncUnlock(JSContext* aCx, Promise** promiseOut) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + NS_ENSURE_ARG_POINTER(aCx); + + RefPtr promiseHandle; + nsresult rv = GetPromise(aCx, promiseHandle); + if (NS_FAILED(rv)) { + return rv; + } + + RefPtr self = this; + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundUnlock", [self, promiseHandle]() mutable { + BackgroundUnlock(promiseHandle, self); + })); + + promiseHandle.forget(promiseOut); + return NS_DispatchBackgroundTask(runnable.forget(), + NS_DISPATCH_EVENT_MAY_BLOCK); +} + +void BackgroundLock(RefPtr& aPromise, RefPtr self) { + nsresult rv = self->Lock(); + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundLockOSKSResolve", [rv, aPromise = std::move(aPromise)]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolveWithUndefined(); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +NS_IMETHODIMP +OSKeyStore::AsyncLock(JSContext* aCx, Promise** promiseOut) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + NS_ENSURE_ARG_POINTER(aCx); + + RefPtr promiseHandle; + nsresult rv = GetPromise(aCx, promiseHandle); + if (NS_FAILED(rv)) { + return rv; + } + + RefPtr self = this; + nsCOMPtr runnable( + NS_NewRunnableFunction("BackgroundLock", [self, promiseHandle]() mutable { + BackgroundLock(promiseHandle, self); + })); + + promiseHandle.forget(promiseOut); + return NS_DispatchBackgroundTask(runnable.forget(), + NS_DISPATCH_EVENT_MAY_BLOCK); +} + +void BackgroundGenerateSecret(const nsACString& aLabel, + RefPtr& aPromise, + RefPtr self) { + nsAutoCString recovery; + nsresult rv = self->GenerateSecret(aLabel, recovery); + nsAutoString recoveryString; + if (NS_SUCCEEDED(rv)) { + CopyUTF8toUTF16(recovery, recoveryString); + } + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundGenerateSecreteOSKSResolve", + [rv, aPromise = std::move(aPromise), recoveryString]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolve(recoveryString); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +NS_IMETHODIMP +OSKeyStore::AsyncGenerateSecret(const nsACString& aLabel, JSContext* aCx, + Promise** promiseOut) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + NS_ENSURE_ARG_POINTER(aCx); + + RefPtr promiseHandle; + nsresult rv = GetPromise(aCx, promiseHandle); + if (NS_FAILED(rv)) { + return rv; + } + + RefPtr self = this; + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundGenerateSecret", + [self, promiseHandle, aLabel = nsAutoCString(aLabel)]() mutable { + BackgroundGenerateSecret(aLabel, promiseHandle, self); + })); + + promiseHandle.forget(promiseOut); + return NS_DispatchBackgroundTask(runnable.forget(), + NS_DISPATCH_EVENT_MAY_BLOCK); +} + +void BackgroundSecretAvailable(const nsACString& aLabel, + RefPtr& aPromise, + RefPtr self) { + bool available = false; + nsresult rv = self->SecretAvailable(aLabel, &available); + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundSecreteAvailableOSKSResolve", + [rv, aPromise = std::move(aPromise), available = available]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolve(available); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +NS_IMETHODIMP +OSKeyStore::AsyncSecretAvailable(const nsACString& aLabel, JSContext* aCx, + Promise** promiseOut) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + NS_ENSURE_ARG_POINTER(aCx); + + RefPtr promiseHandle; + nsresult rv = GetPromise(aCx, promiseHandle); + if (NS_FAILED(rv)) { + return rv; + } + + RefPtr self = this; + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundSecretAvailable", + [self, promiseHandle, aLabel = nsAutoCString(aLabel)]() mutable { + BackgroundSecretAvailable(aLabel, promiseHandle, self); + })); + + promiseHandle.forget(promiseOut); + return NS_DispatchBackgroundTask(runnable.forget(), + NS_DISPATCH_EVENT_MAY_BLOCK); +} + +void BackgroundRecoverSecret(const nsACString& aLabel, + const nsACString& aRecoveryPhrase, + RefPtr& aPromise, + RefPtr self) { + nsresult rv = self->RecoverSecret(aLabel, aRecoveryPhrase); + nsCOMPtr runnable( + NS_NewRunnableFunction("BackgroundRecoverSecreteOSKSResolve", + [rv, aPromise = std::move(aPromise)]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolveWithUndefined(); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +NS_IMETHODIMP +OSKeyStore::AsyncRecoverSecret(const nsACString& aLabel, + const nsACString& aRecoveryPhrase, + JSContext* aCx, Promise** promiseOut) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + NS_ENSURE_ARG_POINTER(aCx); + + RefPtr promiseHandle; + nsresult rv = GetPromise(aCx, promiseHandle); + if (NS_FAILED(rv)) { + return rv; + } + + RefPtr self = this; + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundRecoverSecret", + [self, promiseHandle, aLabel = nsAutoCString(aLabel), + aRecoveryPhrase = nsAutoCString(aRecoveryPhrase)]() mutable { + BackgroundRecoverSecret(aLabel, aRecoveryPhrase, promiseHandle, self); + })); + + promiseHandle.forget(promiseOut); + return NS_DispatchBackgroundTask(runnable.forget(), + NS_DISPATCH_EVENT_MAY_BLOCK); +} + +void BackgroundDeleteSecret(const nsACString& aLabel, RefPtr& aPromise, + RefPtr self) { + nsresult rv = self->DeleteSecret(aLabel); + nsCOMPtr runnable( + NS_NewRunnableFunction("BackgroundDeleteSecreteOSKSResolve", + [rv, aPromise = std::move(aPromise)]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolveWithUndefined(); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +NS_IMETHODIMP +OSKeyStore::AsyncDeleteSecret(const nsACString& aLabel, JSContext* aCx, + Promise** promiseOut) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + NS_ENSURE_ARG_POINTER(aCx); + + RefPtr promiseHandle; + nsresult rv = GetPromise(aCx, promiseHandle); + if (NS_FAILED(rv)) { + return rv; + } + + RefPtr self = this; + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundDeleteSecret", + [self, promiseHandle, aLabel = nsAutoCString(aLabel)]() mutable { + BackgroundDeleteSecret(aLabel, promiseHandle, self); + })); + + promiseHandle.forget(promiseOut); + return NS_DispatchBackgroundTask(runnable.forget(), + NS_DISPATCH_EVENT_MAY_BLOCK); +} + +static void BackgroundEncryptBytes(const nsACString& aLabel, + const std::vector& aInBytes, + RefPtr& aPromise, + RefPtr self) { + nsAutoCString ciphertext; + nsresult rv = self->EncryptBytes(aLabel, aInBytes, ciphertext); + nsAutoString ctext; + CopyUTF8toUTF16(ciphertext, ctext); + + nsCOMPtr runnable( + NS_NewRunnableFunction("BackgroundEncryptOSKSResolve", + [rv, aPromise = std::move(aPromise), ctext]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolve(ctext); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +NS_IMETHODIMP +OSKeyStore::AsyncEncryptBytes(const nsACString& aLabel, + const nsTArray& inBytes, JSContext* aCx, + Promise** promiseOut) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + NS_ENSURE_ARG_POINTER(aCx); + + RefPtr promiseHandle; + nsresult rv = GetPromise(aCx, promiseHandle); + if (NS_FAILED(rv)) { + return rv; + } + + RefPtr self = this; + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundEncryptBytes", + [promiseHandle, + inBytes = std::vector(inBytes.Elements(), + inBytes.Elements() + inBytes.Length()), + aLabel = nsAutoCString(aLabel), self]() mutable { + BackgroundEncryptBytes(aLabel, inBytes, promiseHandle, self); + })); + + promiseHandle.forget(promiseOut); + return NS_DispatchBackgroundTask(runnable.forget(), + NS_DISPATCH_EVENT_MAY_BLOCK); +} + +void BackgroundDecryptBytes(const nsACString& aLabel, + const nsACString& aEncryptedBase64Text, + RefPtr& aPromise, + RefPtr self) { + uint8_t* plaintext = nullptr; + uint32_t plaintextLen = 0; + nsresult rv = self->DecryptBytes(aLabel, aEncryptedBase64Text, &plaintextLen, + &plaintext); + nsTArray plain; + if (plaintext) { + MOZ_ASSERT(plaintextLen > 0); + plain.AppendElements(plaintext, plaintextLen); + free(plaintext); + } + + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundDecryptOSKSResolve", + [rv, aPromise = std::move(aPromise), plain = std::move(plain)]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolve(plain); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +NS_IMETHODIMP +OSKeyStore::AsyncDecryptBytes(const nsACString& aLabel, + const nsACString& aEncryptedBase64Text, + JSContext* aCx, Promise** promiseOut) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + NS_ENSURE_ARG_POINTER(aCx); + + RefPtr promiseHandle; + nsresult rv = GetPromise(aCx, promiseHandle); + if (NS_FAILED(rv)) { + return rv; + } + + RefPtr self = this; + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundDecryptBytes", + [promiseHandle, self, + aEncryptedBase64Text = nsAutoCString(aEncryptedBase64Text), + aLabel = nsAutoCString(aLabel)]() mutable { + BackgroundDecryptBytes(aLabel, aEncryptedBase64Text, promiseHandle, + self); + })); + + promiseHandle.forget(promiseOut); + return NS_DispatchBackgroundTask(runnable.forget(), + NS_DISPATCH_EVENT_MAY_BLOCK); +} + +// Generic AES-GCM cipher wrapper for NSS functions. + +nsresult AbstractOSKeyStore::BuildAesGcmKey(std::vector aKeyBytes, + /* out */ UniquePK11SymKey& aKey) { + if (aKeyBytes.size() != mKeyByteLength) { + return NS_ERROR_INVALID_ARG; + } + + UniquePK11SlotInfo slot(PK11_GetInternalSlot()); + if (!slot) { + return NS_ERROR_FAILURE; + } + + UniqueSECItem key = + UniqueSECItem(SECITEM_AllocItem(nullptr, nullptr, mKeyByteLength)); + if (!key) { + return NS_ERROR_FAILURE; + } + key->type = siBuffer; + memcpy(key->data, aKeyBytes.data(), mKeyByteLength); + key->len = mKeyByteLength; + + UniquePK11SymKey symKey( + PK11_ImportSymKey(slot.get(), CKM_AES_GCM, PK11_OriginUnwrap, + CKA_DECRYPT | CKA_ENCRYPT, key.get(), nullptr)); + + if (!symKey) { + return NS_ERROR_FAILURE; + } + aKey.swap(symKey); + + return NS_OK; +} + +nsresult AbstractOSKeyStore::DoCipher(const UniquePK11SymKey& aSymKey, + const std::vector& inBytes, + std::vector& outBytes, + bool encrypt) { + NS_ENSURE_ARG_POINTER(aSymKey); + outBytes.clear(); + + // Build params. + // We need to get the IV from inBytes if we decrypt. + if (!encrypt && (inBytes.size() < mIVLength || inBytes.size() == 0)) { + return NS_ERROR_INVALID_ARG; + } + + const uint8_t* ivp = nullptr; + std::vector ivBuf; + if (encrypt) { + // Generate a new IV. + ivBuf.resize(mIVLength); + nsresult rv = GenerateRandom(ivBuf); + if (NS_FAILED(rv) || ivBuf.size() != mIVLength) { + return NS_ERROR_FAILURE; + } + ivp = ivBuf.data(); + } else { + // An IV was passed in. Use the first mIVLength bytes from inBytes as IV. + ivp = inBytes.data(); + } + + CK_GCM_PARAMS gcm_params; + gcm_params.pIv = const_cast(ivp); + gcm_params.ulIvLen = mIVLength; + gcm_params.ulIvBits = gcm_params.ulIvLen * 8; + gcm_params.ulTagBits = 128; + gcm_params.pAAD = nullptr; + gcm_params.ulAADLen = 0; + + SECItem paramsItem = {siBuffer, reinterpret_cast(&gcm_params), + sizeof(CK_GCM_PARAMS)}; + + size_t blockLength = 16; + outBytes.resize(inBytes.size() + blockLength); + unsigned int outLen = 0; + SECStatus srv = SECFailure; + if (encrypt) { + srv = PK11_Encrypt(aSymKey.get(), CKM_AES_GCM, ¶msItem, outBytes.data(), + &outLen, inBytes.size() + blockLength, inBytes.data(), + inBytes.size()); + // Prepend the used IV to the ciphertext. + Unused << outBytes.insert(outBytes.begin(), ivp, ivp + mIVLength); + outLen += mIVLength; + } else { + // Remove the IV from the input. + std::vector input(inBytes); + input.erase(input.begin(), input.begin() + mIVLength); + srv = PK11_Decrypt(aSymKey.get(), CKM_AES_GCM, ¶msItem, outBytes.data(), + &outLen, input.size() + blockLength, input.data(), + input.size()); + } + if (srv != SECSuccess || outLen > outBytes.size()) { + outBytes.clear(); + return NS_ERROR_FAILURE; + } + if (outLen < outBytes.size()) { + outBytes.resize(outLen); + } + + return NS_OK; +} + +bool AbstractOSKeyStore::SecretAvailable(const nsACString& aLabel) { + nsAutoCString secret; + nsresult rv = RetrieveSecret(aLabel, secret); + if (NS_FAILED(rv) || secret.Length() == 0) { + return false; + } + return true; +} + +nsresult AbstractOSKeyStore::EncryptDecrypt(const nsACString& aLabel, + const std::vector& inBytes, + std::vector& outBytes, + bool encrypt) { + nsAutoCString secret; + nsresult rv = RetrieveSecret(aLabel, secret); + if (NS_FAILED(rv) || secret.Length() == 0) { + return NS_ERROR_FAILURE; + } + + uint8_t* p = BitwiseCast(secret.BeginReading()); + std::vector buf(p, p + secret.Length()); + UniquePK11SymKey symKey; + rv = BuildAesGcmKey(buf, symKey); + if (NS_FAILED(rv)) { + return NS_ERROR_FAILURE; + } + return DoCipher(symKey, inBytes, outBytes, encrypt); +} diff --git a/security/manager/ssl/OSKeyStore.h b/security/manager/ssl/OSKeyStore.h new file mode 100644 index 0000000000..5163582ead --- /dev/null +++ b/security/manager/ssl/OSKeyStore.h @@ -0,0 +1,105 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +// Generic key store implementation for platforms that we don't support with OS +// specific implementations. + +#ifndef OSKeyStore_h +#define OSKeyStore_h + +#include "nsCOMPtr.h" +#include "nsIOSKeyStore.h" +#include "nsString.h" +#include "ScopedNSSTypes.h" + +#include +#include + +class AbstractOSKeyStore { + public: + // Retrieve a secret with the given label. + virtual nsresult RetrieveSecret(const nsACString& aLabel, + /* out */ nsACString& aSecret) = 0; + // Store a new secret with the given label. + virtual nsresult StoreSecret(const nsACString& secret, + const nsACString& label) = 0; + // Delete the secret with the given label. + virtual nsresult DeleteSecret(const nsACString& label) = 0; + // Lock the key store. + virtual nsresult Lock() = 0; + // Unlock the key store. + virtual nsresult Unlock() = 0; + virtual ~AbstractOSKeyStore() = default; + + // Returns true if the secret with the given label is available in the key + // store, false otherwise. + virtual bool SecretAvailable(const nsACString& label); + // Perform encryption or decryption operation with the given secret and input + // bytes. The output is written in outBytes. This function can make use of the + // AesGcm class to use NSS for encryption and decryption. + virtual nsresult EncryptDecrypt(const nsACString& label, + const std::vector& inBytes, + std::vector& outBytes, bool encrypt); + + size_t GetKeyByteLength() { return mKeyByteLength; } + + protected: + /* These helper functions are implemented in OSKeyStore.cpp and implement + * common functionality of the abstract key store to encrypt and decrypt. + */ + nsresult DoCipher(const mozilla::UniquePK11SymKey& aSymKey, + const std::vector& inBytes, + std::vector& outBytes, bool aEncrypt); + nsresult BuildAesGcmKey(std::vector keyBytes, + /* out */ mozilla::UniquePK11SymKey& aKey); + + private: + const size_t mKeyByteLength = 16; + const size_t mIVLength = 12; +}; + +#define NS_OSKEYSTORE_CONTRACTID "@mozilla.org/security/oskeystore;1" +#define NS_OSKEYSTORE_CID \ + { \ + 0x57972956, 0x5718, 0x42d2, { \ + 0x80, 0x70, 0xb3, 0xfc, 0x72, 0x21, 0x2e, 0xaf \ + } \ + } + +nsresult GetPromise(JSContext* aCx, + /* out */ RefPtr& aPromise); + +class OSKeyStore final : public nsIOSKeyStore { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOSKEYSTORE + + OSKeyStore(); + nsresult GenerateSecret(const nsACString& aLabel, + /* out */ nsACString& aRecoveryPhrase); + nsresult SecretAvailable(const nsACString& aLabel, + /* out */ bool* aAvailable); + nsresult RecoverSecret(const nsACString& aLabel, + const nsACString& aRecoveryPhrase); + nsresult DeleteSecret(const nsACString& aLabel); + nsresult EncryptBytes(const nsACString& aLabel, + const std::vector& aInBytes, + /*out*/ nsACString& aEncryptedBase64Text); + nsresult DecryptBytes(const nsACString& aLabel, + const nsACString& aEncryptedBase64Text, + /*out*/ uint32_t* outLen, + /*out*/ uint8_t** outBytes); + nsresult Lock(); + nsresult Unlock(); + + private: + ~OSKeyStore() = default; + + std::unique_ptr mKs; + bool mKsIsNSSKeyStore; +}; + +#endif // OSKeyStore_h diff --git a/security/manager/ssl/OSReauthenticator.cpp b/security/manager/ssl/OSReauthenticator.cpp new file mode 100644 index 0000000000..981baf8da0 --- /dev/null +++ b/security/manager/ssl/OSReauthenticator.cpp @@ -0,0 +1,567 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "OSReauthenticator.h" + +#include "OSKeyStore.h" +#include "nsNetCID.h" +#include "mozilla/dom/Promise.h" +#include "mozilla/Logging.h" +#include "mozilla/Maybe.h" +#include "mozilla/Preferences.h" +#include "nsComponentManagerUtils.h" +#include "nsIBaseWindow.h" +#include "nsIDocShell.h" +#include "nsISupportsUtils.h" +#include "nsIWidget.h" +#include "nsPIDOMWindow.h" +#include "nsServiceManagerUtils.h" +#include "nsThreadUtils.h" +#include "mozilla/ipc/IPCTypes.h" + +NS_IMPL_ISUPPORTS(OSReauthenticator, nsIOSReauthenticator) + +extern mozilla::LazyLogModule gCredentialManagerSecretLog; + +using mozilla::LogLevel; +using mozilla::Maybe; +using mozilla::Preferences; +using mozilla::WindowsHandle; +using mozilla::dom::Promise; + +#define PREF_BLANK_PASSWORD "security.osreauthenticator.blank_password" +#define PREF_PASSWORD_LAST_CHANGED_LO \ + "security.osreauthenticator.password_last_changed_lo" +#define PREF_PASSWORD_LAST_CHANGED_HI \ + "security.osreauthenticator.password_last_changed_hi" + +#if defined(XP_WIN) +# include +# include +# include +# include +# include "nsIWindowsRegKey.h" // Must be included after for HKEY definition +# define SECURITY_WIN32 +# include +# include +# if !defined(__MINGW32__) +# include +# undef ACCESS_READ // nsWindowsRegKey defines its own ACCESS_READ +# endif // !defined(__MINGW32__) +struct HandleCloser { + typedef HANDLE pointer; + void operator()(HANDLE h) { + if (h != INVALID_HANDLE_VALUE) { + CloseHandle(h); + } + } +}; +struct BufferFreer { + typedef LPVOID pointer; + ULONG mSize; + explicit BufferFreer(ULONG size) : mSize(size) {} + void operator()(LPVOID b) { + SecureZeroMemory(b, mSize); + CoTaskMemFree(b); + } +}; +struct LsaDeregistrator { + typedef HANDLE pointer; + void operator()(HANDLE h) { + if (h != INVALID_HANDLE_VALUE) { + LsaDeregisterLogonProcess(h); + } + } +}; +typedef std::unique_ptr ScopedHANDLE; +typedef std::unique_ptr ScopedBuffer; +typedef std::unique_ptr ScopedLsaHANDLE; + +constexpr int64_t Int32Modulo = 2147483648; + +// Get the token info holding the sid. +std::unique_ptr GetTokenInfo(ScopedHANDLE& token) { + DWORD length = 0; + // https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-gettokeninformation + mozilla::Unused << GetTokenInformation(token.get(), TokenUser, nullptr, 0, + &length); + if (!length || GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Unable to obtain current token info.")); + return nullptr; + } + std::unique_ptr token_info(new char[length]); + if (!GetTokenInformation(token.get(), TokenUser, token_info.get(), length, + &length)) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Unable to obtain current token info (second call, possible " + "system error.")); + return nullptr; + } + return token_info; +} + +std::unique_ptr GetUserTokenInfo() { + // Get current user sid to make sure the same user got logged in. + HANDLE token; + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token)) { + // Couldn't get a process token. This will fail any unlock attempts later. + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Unable to obtain process token.")); + return nullptr; + } + ScopedHANDLE scopedToken(token); + return GetTokenInfo(scopedToken); +} + +Maybe GetPasswordLastChanged(const WCHAR* username) { +# if defined(__MINGW32__) + // NetUserGetInfo requires Lm.h which is not provided in MinGW builds + return mozilla::Nothing(); +# else + LPUSER_INFO_1 user_info = NULL; + DWORD passwordAgeInSeconds = 0; + + NET_API_STATUS ret = + NetUserGetInfo(NULL, username, 1, reinterpret_cast(&user_info)); + + if (ret == NERR_Success) { + // Returns seconds since last password change. + passwordAgeInSeconds = user_info->usri1_password_age; + NetApiBufferFree(user_info); + } else { + return mozilla::Nothing(); + } + + // Return the time that the password was changed so we can use this + // for future comparisons. + return mozilla::Some(PR_Now() - passwordAgeInSeconds * PR_USEC_PER_SEC); +# endif +} + +bool IsAutoAdminLogonEnabled() { + // https://support.microsoft.com/en-us/help/324737/how-to-turn-on-automatic-logon-in-windows + nsresult rv; + nsCOMPtr regKey = + do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv); + if (NS_FAILED(rv)) { + return false; + } + + rv = regKey->Open( + nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, + nsLiteralString( + u"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), + nsIWindowsRegKey::ACCESS_READ); + if (NS_FAILED(rv)) { + return false; + } + + nsAutoString value; + rv = regKey->ReadStringValue(u"AutoAdminLogon"_ns, value); + if (NS_FAILED(rv)) { + return false; + } + regKey->Close(); + + return value.Equals(u"1"_ns); +} + +bool IsRequireSignonEnabled() { + // https://docs.microsoft.com/en-us/windows-hardware/customize/power-settings/no-subgroup-settings-prompt-for-password-on-resume + nsresult rv; + nsCOMPtr regKey = + do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv); + if (NS_FAILED(rv)) { + return true; + } + + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, + u"System\\CurrentControlSet\\Control\\Power\\User\\Power" + "Schemes"_ns, + nsIWindowsRegKey::ACCESS_READ); + if (NS_FAILED(rv)) { + return true; + } + + nsAutoString activePowerScheme; + rv = regKey->ReadStringValue(u"ActivePowerScheme"_ns, activePowerScheme); + if (NS_FAILED(rv)) { + return true; + } + regKey->Close(); + + rv = regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, + u"System\\CurrentControlSet\\Control\\Power\\User\\Power" + "Schemes\\"_ns + + activePowerScheme + + u"\\0e796bdb-100d-47d6-a2d5-f7d2daa51f51"_ns, + nsIWindowsRegKey::ACCESS_READ); + if (NS_FAILED(rv)) { + return true; + } + + uint32_t value; + rv = regKey->ReadIntValue(u"ACSettingIndex"_ns, &value); + if (NS_FAILED(rv)) { + return true; + } + regKey->Close(); + + return !!value; +} + +// Use the Windows credential prompt to ask the user to authenticate the +// currently used account. +static nsresult ReauthenticateUserWindows( + const nsAString& aMessageText, const nsAString& aCaptionText, + const WindowsHandle& hwndParent, + /* out */ bool& reauthenticated, + /* inout */ bool& isBlankPassword, + /* inout */ int64_t& prefLastChanged, + /* out */ bool& isAutoAdminLogonEnabled, + /* out */ bool& isRequireSignonEnabled) { + reauthenticated = false; + isAutoAdminLogonEnabled = false; + isRequireSignonEnabled = true; + + // Check if the user has a blank password before proceeding + DWORD usernameLength = CREDUI_MAX_USERNAME_LENGTH + 1; + WCHAR username[CREDUI_MAX_USERNAME_LENGTH + 1] = {0}; + + if (!GetUserNameEx(NameSamCompatible, username, &usernameLength)) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Error getting username")); + return NS_ERROR_FAILURE; + } + +# ifdef OS_DOMAINMEMBER + bool isDomainMember = IsOS(OS_DOMAINMEMBER); +# else + // Bug 1633097 + bool isDomainMember = false; +# endif + if (!isDomainMember) { + const WCHAR* usernameNoDomain = username; + // Don't include the domain portion of the username when calling LogonUser. + LPCWSTR backslash = wcschr(username, L'\\'); + if (backslash) { + usernameNoDomain = backslash + 1; + } + + Maybe lastChanged = GetPasswordLastChanged(usernameNoDomain); + if (lastChanged.isSome()) { + bool shouldCheckAgain = lastChanged.value() > prefLastChanged; + // Update the value stored in preferences + prefLastChanged = lastChanged.value(); + + if (shouldCheckAgain) { + HANDLE logonUserHandle = INVALID_HANDLE_VALUE; + bool result = + LogonUser(usernameNoDomain, L".", L"", LOGON32_LOGON_INTERACTIVE, + LOGON32_PROVIDER_DEFAULT, &logonUserHandle); + if (result) { + CloseHandle(logonUserHandle); + } + // ERROR_ACCOUNT_RESTRICTION: Indicates a referenced user name and + // authentication information are valid, but some user account + // restriction has prevented successful authentication (such as + // time-of-day restrictions). + reauthenticated = isBlankPassword = + (result || GetLastError() == ERROR_ACCOUNT_RESTRICTION); + } else if (isBlankPassword) { + reauthenticated = true; + } + + if (reauthenticated) { + return NS_OK; + } + } else { + isBlankPassword = false; + } + } else { + // Update any preferences, assuming domain members do not have blank + // passwords + isBlankPassword = false; + } + + isAutoAdminLogonEnabled = IsAutoAdminLogonEnabled(); + + isRequireSignonEnabled = IsRequireSignonEnabled(); + + // Is used in next iteration if the previous login failed. + DWORD err = 0; + std::unique_ptr userTokenInfo = GetUserTokenInfo(); + + // CredUI prompt. + CREDUI_INFOW credui = {}; + credui.cbSize = sizeof(credui); + credui.hwndParent = reinterpret_cast(hwndParent); + const nsString& messageText = PromiseFlatString(aMessageText); + credui.pszMessageText = messageText.get(); + const nsString& captionText = PromiseFlatString(aCaptionText); + credui.pszCaptionText = captionText.get(); + credui.hbmBanner = nullptr; // ignored + + while (!reauthenticated) { + HANDLE lsa = INVALID_HANDLE_VALUE; + // Get authentication handle for future user authentications. + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsaconnectuntrusted + if (LsaConnectUntrusted(&lsa) != ERROR_SUCCESS) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Error acquiring lsa. Authentication attempts will fail.")); + return NS_ERROR_FAILURE; + } + ScopedLsaHANDLE scopedLsa(lsa); + + if (!userTokenInfo || lsa == INVALID_HANDLE_VALUE) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Error setting up login and user token.")); + return NS_ERROR_FAILURE; + } + + ULONG authPackage = 0; + ULONG outCredSize = 0; + LPVOID outCredBuffer = nullptr; + + // Get user's Windows credentials. + // https://docs.microsoft.com/en-us/windows/desktop/api/wincred/nf-wincred-creduipromptforwindowscredentialsw + err = CredUIPromptForWindowsCredentialsW( + &credui, err, &authPackage, nullptr, 0, &outCredBuffer, &outCredSize, + nullptr, CREDUIWIN_ENUMERATE_CURRENT_USER); + ScopedBuffer scopedOutCredBuffer(outCredBuffer, BufferFreer(outCredSize)); + if (err == ERROR_CANCELLED) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Error getting authPackage for user login, user cancel.")); + return NS_OK; + } + if (err != ERROR_SUCCESS) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Error getting authPackage for user login.")); + return NS_ERROR_FAILURE; + } + + // Verify the credentials. + TOKEN_SOURCE source; + PCHAR contextName = const_cast("Mozilla"); + size_t nameLength = + std::min(TOKEN_SOURCE_LENGTH, static_cast(strlen(contextName))); + // Note that the string must not be longer than TOKEN_SOURCE_LENGTH. + memcpy(source.SourceName, contextName, nameLength); + // https://docs.microsoft.com/en-us/windows/desktop/api/securitybaseapi/nf-securitybaseapi-allocatelocallyuniqueid + if (!AllocateLocallyUniqueId(&source.SourceIdentifier)) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Error allocating ID for logon process.")); + return NS_ERROR_FAILURE; + } + + NTSTATUS substs; + void* profileBuffer = nullptr; + ULONG profileBufferLength = 0; + QUOTA_LIMITS limits = {0}; + LUID luid; + HANDLE token = INVALID_HANDLE_VALUE; + LSA_STRING name; + name.Buffer = contextName; + name.Length = strlen(name.Buffer); + name.MaximumLength = name.Length; + // https://docs.microsoft.com/en-us/windows/desktop/api/ntsecapi/nf-ntsecapi-lsalogonuser + NTSTATUS sts = LsaLogonUser( + scopedLsa.get(), &name, (SECURITY_LOGON_TYPE)Interactive, authPackage, + scopedOutCredBuffer.get(), outCredSize, nullptr, &source, + &profileBuffer, &profileBufferLength, &luid, &token, &limits, &substs); + ScopedHANDLE scopedToken(token); + LsaFreeReturnBuffer(profileBuffer); + if (sts == ERROR_SUCCESS) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("User logged in successfully.")); + } else { + err = LsaNtStatusToWinError(sts); + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Login failed with %lx (%lx).", sts, err)); + continue; + } + + // The user can select any user to log-in on the authentication prompt. + // Make sure that the logged in user is the current user. + std::unique_ptr logonTokenInfo = GetTokenInfo(scopedToken); + if (!logonTokenInfo) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Error getting logon token info.")); + return NS_ERROR_FAILURE; + } + PSID logonSID = + reinterpret_cast(logonTokenInfo.get())->User.Sid; + PSID userSID = reinterpret_cast(userTokenInfo.get())->User.Sid; + if (EqualSid(userSID, logonSID)) { + MOZ_LOG(gCredentialManagerSecretLog, LogLevel::Debug, + ("Login successfully (correct user).")); + reauthenticated = true; + break; + } else { + err = ERROR_LOGON_FAILURE; + } + } + return NS_OK; +} +#endif // XP_WIN + +static nsresult ReauthenticateUser(const nsAString& prompt, + const nsAString& caption, + const WindowsHandle& hwndParent, + /* out */ bool& reauthenticated, + /* inout */ bool& isBlankPassword, + /* inout */ int64_t& prefLastChanged, + /* out */ bool& isAutoAdminLogonEnabled, + /* out */ bool& isRequireSignonEnabled) { + reauthenticated = false; +#if defined(XP_WIN) + return ReauthenticateUserWindows( + prompt, caption, hwndParent, reauthenticated, isBlankPassword, + prefLastChanged, isAutoAdminLogonEnabled, isRequireSignonEnabled); +#elif defined(XP_MACOSX) + return ReauthenticateUserMacOS(prompt, reauthenticated, isBlankPassword); +#endif // Reauthentication is not implemented for this platform. + return NS_OK; +} + +static void BackgroundReauthenticateUser(RefPtr& aPromise, + const nsAString& aMessageText, + const nsAString& aCaptionText, + const WindowsHandle& hwndParent, + bool isBlankPassword, + int64_t prefLastChanged) { + nsAutoCString recovery; + bool reauthenticated; + bool isAutoAdminLogonEnabled; + bool isRequireSignonEnabled; + nsresult rv = ReauthenticateUser( + aMessageText, aCaptionText, hwndParent, reauthenticated, isBlankPassword, + prefLastChanged, isAutoAdminLogonEnabled, isRequireSignonEnabled); + + nsTArray prefLastChangedUpdates; +#if defined(XP_WIN) + // Increase the lastChanged time to account for clock skew. + prefLastChanged += PR_USEC_PER_SEC; + // Need to split the 64bit integer to its hi and lo bits before sending it + // back to JS. + int32_t prefLastChangedHi = prefLastChanged / Int32Modulo; + int32_t prefLastChangedLo = prefLastChanged % Int32Modulo; + prefLastChangedUpdates.AppendElement(prefLastChangedHi); + prefLastChangedUpdates.AppendElement(prefLastChangedLo); +#endif + + nsTArray results; + results.AppendElement(reauthenticated); + results.AppendElement(isBlankPassword); +#if defined(XP_WIN) + results.AppendElement(isAutoAdminLogonEnabled); + results.AppendElement(isRequireSignonEnabled); +#endif + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundReauthenticateUserResolve", + [rv, results = std::move(results), + prefLastChangedUpdates = std::move(prefLastChangedUpdates), + aPromise = std::move(aPromise)]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolve(results); + } + + nsresult rv = Preferences::SetBool(PREF_BLANK_PASSWORD, results[1]); + if (NS_FAILED(rv)) { + return; + } + if (prefLastChangedUpdates.Length() > 1) { + rv = Preferences::SetInt(PREF_PASSWORD_LAST_CHANGED_HI, + prefLastChangedUpdates[0]); + if (NS_FAILED(rv)) { + return; + } + Preferences::SetInt(PREF_PASSWORD_LAST_CHANGED_LO, + prefLastChangedUpdates[1]); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +NS_IMETHODIMP +OSReauthenticator::AsyncReauthenticateUser(const nsAString& aMessageText, + const nsAString& aCaptionText, + mozIDOMWindow* aParentWindow, + JSContext* aCx, + Promise** promiseOut) { + NS_ENSURE_ARG_POINTER(aCx); + + RefPtr promiseHandle; + nsresult rv = GetPromise(aCx, promiseHandle); + if (NS_FAILED(rv)) { + return rv; + } + + WindowsHandle hwndParent = 0; + if (aParentWindow) { + nsPIDOMWindowInner* win = nsPIDOMWindowInner::From(aParentWindow); + nsIDocShell* docShell = win->GetDocShell(); + if (docShell) { + nsCOMPtr baseWindow = do_QueryInterface(docShell); + if (baseWindow) { + nsCOMPtr widget; + baseWindow->GetMainWidget(getter_AddRefs(widget)); + if (widget) { + hwndParent = reinterpret_cast( + widget->GetNativeData(NS_NATIVE_WINDOW)); + } + } + } + } + + int64_t prefLastChanged = 0; + bool isBlankPassword = false; +#if defined(XP_WIN) + // These preferences are only supported on Windows. + // Preferences are read/write main-thread only. + int32_t prefLastChangedLo; + int32_t prefLastChangedHi; + rv = Preferences::GetBool(PREF_BLANK_PASSWORD, &isBlankPassword); + if (NS_FAILED(rv)) { + return rv; + } + rv = Preferences::GetInt(PREF_PASSWORD_LAST_CHANGED_LO, &prefLastChangedLo); + if (NS_FAILED(rv)) { + return rv; + } + rv = Preferences::GetInt(PREF_PASSWORD_LAST_CHANGED_HI, &prefLastChangedHi); + if (NS_FAILED(rv)) { + return rv; + } + prefLastChanged = prefLastChangedHi * Int32Modulo + prefLastChangedLo; +#endif + + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundReauthenticateUser", + [promiseHandle, aMessageText = nsAutoString(aMessageText), + aCaptionText = nsAutoString(aCaptionText), hwndParent, isBlankPassword, + prefLastChanged]() mutable { + BackgroundReauthenticateUser(promiseHandle, aMessageText, aCaptionText, + hwndParent, isBlankPassword, + prefLastChanged); + })); + + nsCOMPtr target( + do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID)); + if (!target) { + return NS_ERROR_FAILURE; + } + rv = target->Dispatch(runnable, NS_DISPATCH_NORMAL); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + promiseHandle.forget(promiseOut); + return NS_OK; +} diff --git a/security/manager/ssl/OSReauthenticator.h b/security/manager/ssl/OSReauthenticator.h new file mode 100644 index 0000000000..837dfa91c0 --- /dev/null +++ b/security/manager/ssl/OSReauthenticator.h @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef OSReauthenticator_h +#define OSReauthenticator_h + +#include "nsIOSReauthenticator.h" + +#define NS_OSREAUTHENTICATOR_CONTRACTID \ + "@mozilla.org/security/osreauthenticator;1" +#define NS_OSREAUTHENTICATOR_CID \ + { \ + 0x4fe082ae, 0x6ff0, 0x4b41, { \ + 0xb2, 0x4f, 0xea, 0xa6, 0x64, 0xf6, 0xe4, 0x6a \ + } \ + } + +class OSReauthenticator : public nsIOSReauthenticator { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOSREAUTHENTICATOR + + private: + virtual ~OSReauthenticator() = default; +}; + +#ifdef XP_MACOSX +nsresult ReauthenticateUserMacOS(const nsAString& aPrompt, + /* out */ bool& aReauthenticated, + /* out */ bool& aIsBlankPassword); +#endif // XP_MACOSX + +#endif // OSReauthenticator_h diff --git a/security/manager/ssl/OSReauthenticatorDarwin.mm b/security/manager/ssl/OSReauthenticatorDarwin.mm new file mode 100644 index 0000000000..ac1ff66f9b --- /dev/null +++ b/security/manager/ssl/OSReauthenticatorDarwin.mm @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "OSReauthenticator.h" + +#include "nsCocoaUtils.h" + +using namespace mozilla; + +#include +#include + +static const int32_t kPasswordNotSetErrorCode = -1000; + +nsresult ReauthenticateUserMacOS(const nsAString& aPrompt, + /* out */ bool& aReauthenticated, + /* out */ bool& aIsBlankPassword) { + // The idea here is that we ask to be authorized to unlock the user's session. + // This should cause a prompt to come up for the user asking them for their + // password. If they correctly enter it, we'll set aReauthenticated to true. + + LAContext* context = [[LAContext alloc] init]; + NSString* prompt = nsCocoaUtils::ToNSString(aPrompt); + + dispatch_semaphore_t sema = dispatch_semaphore_create(0); + + __block BOOL biometricSuccess = NO; // mark variable r/w across the block + __block BOOL errorPasswordNotSet = NO; // mark variable r/w across the block + + // Note: This is an async callback in an already-async Promise chain. + [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication + localizedReason:prompt + reply:^(BOOL success, NSError* error) { + dispatch_async(dispatch_get_main_queue(), ^{ + // error is not particularly useful in this context, and we have no + // mechanism to really return it. We could use it to set the nsresult, + // but this is a best-effort mechanism and there's no particular case for + // propagating up XPCOM. The one exception being a user account that + // has no passcode set, which we handle below. + errorPasswordNotSet = error && [error code] == kPasswordNotSetErrorCode; + biometricSuccess = success || errorPasswordNotSet; + dispatch_semaphore_signal(sema); + }); + }]; + + // What we want to do here is convert this into a blocking call, since + // our calling methods expect us to block and set aReauthenticated on return. + dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER); + dispatch_release(sema); + sema = NULL; + + aReauthenticated = biometricSuccess; + aIsBlankPassword = errorPasswordNotSet; + + [context release]; + return NS_OK; +} diff --git a/security/manager/ssl/PKCS11ModuleDB.cpp b/security/manager/ssl/PKCS11ModuleDB.cpp new file mode 100644 index 0000000000..5afe69f216 --- /dev/null +++ b/security/manager/ssl/PKCS11ModuleDB.cpp @@ -0,0 +1,185 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "PKCS11ModuleDB.h" + +#include "ScopedNSSTypes.h" +#include "nsComponentManagerUtils.h" +#include "nsIMutableArray.h" +#include "nsNSSCertHelper.h" +#include "nsNSSComponent.h" +#include "nsNativeCharsetUtils.h" +#include "nsPKCS11Slot.h" +#include "nsServiceManagerUtils.h" + +namespace mozilla { +namespace psm { + +NS_IMPL_ISUPPORTS(PKCS11ModuleDB, nsIPKCS11ModuleDB) + +// Convert the UTF16 name of the module as it appears to the user to the +// internal representation. For most modules this just involves converting from +// UTF16 to UTF8. For the builtin root module, it also involves mapping from the +// localized name to the internal, non-localized name. +static nsresult NormalizeModuleNameIn(const nsAString& moduleNameIn, + nsCString& moduleNameOut) { + nsAutoString localizedRootModuleName; + nsresult rv = + GetPIPNSSBundleString("RootCertModuleName", localizedRootModuleName); + if (NS_FAILED(rv)) { + return rv; + } + if (moduleNameIn.Equals(localizedRootModuleName)) { + moduleNameOut.Assign(kRootModuleName); + return NS_OK; + } + moduleNameOut.Assign(NS_ConvertUTF16toUTF8(moduleNameIn)); + return NS_OK; +} + +// Delete a PKCS11 module from the user's profile. +NS_IMETHODIMP +PKCS11ModuleDB::DeleteModule(const nsAString& aModuleName) { + if (aModuleName.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + + nsAutoCString moduleNameNormalized; + nsresult rv = NormalizeModuleNameIn(aModuleName, moduleNameNormalized); + if (NS_FAILED(rv)) { + return rv; + } + // modType is an output variable. We ignore it. + int32_t modType; + SECStatus srv = SECMOD_DeleteModule(moduleNameNormalized.get(), &modType); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +// Add a new PKCS11 module to the user's profile. +NS_IMETHODIMP +PKCS11ModuleDB::AddModule(const nsAString& aModuleName, + const nsAString& aLibraryFullPath, + int32_t aCryptoMechanismFlags, int32_t aCipherFlags) { + if (aModuleName.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + + // "Root Certs" is the name some NSS command-line utilities will give the + // roots module if they decide to load it when there happens to be a + // `MOZ_DLL_PREFIX "nssckbi" MOZ_DLL_SUFFIX` file in the directory being + // operated on. This causes failures, so as a workaround, the PSM + // initialization code will unconditionally remove any module named "Root + // Certs". We should prevent the user from adding an unrelated module named + // "Root Certs" in the first place so PSM doesn't delete it. See bug 1406396. + if (aModuleName.EqualsLiteral("Root Certs")) { + return NS_ERROR_ILLEGAL_VALUE; + } + + // There appears to be a deadlock if we try to load modules concurrently, so + // just wait until the loadable roots module has been loaded. + nsresult rv = BlockUntilLoadableCertsLoaded(); + if (NS_FAILED(rv)) { + return rv; + } + + nsAutoCString moduleNameNormalized; + rv = NormalizeModuleNameIn(aModuleName, moduleNameNormalized); + if (NS_FAILED(rv)) { + return rv; + } + nsCString fullPath; + // NSS doesn't support Unicode path. Use native charset + NS_CopyUnicodeToNative(aLibraryFullPath, fullPath); + uint32_t mechFlags = SECMOD_PubMechFlagstoInternal(aCryptoMechanismFlags); + uint32_t cipherFlags = SECMOD_PubCipherFlagstoInternal(aCipherFlags); + SECStatus srv = SECMOD_AddNewModule(moduleNameNormalized.get(), + fullPath.get(), mechFlags, cipherFlags); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +NS_IMETHODIMP +PKCS11ModuleDB::ListModules(nsISimpleEnumerator** _retval) { + NS_ENSURE_ARG_POINTER(_retval); + + nsresult rv = BlockUntilLoadableCertsLoaded(); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr array = do_CreateInstance(NS_ARRAY_CONTRACTID); + if (!array) { + return NS_ERROR_FAILURE; + } + + /* lock down the list for reading */ + AutoSECMODListReadLock lock; + for (SECMODModuleList* list = SECMOD_GetDefaultModuleList(); list; + list = list->next) { + nsCOMPtr module = new nsPKCS11Module(list->module); + nsresult rv = array->AppendElement(module); + if (NS_FAILED(rv)) { + return rv; + } + } + + /* Get the modules in the database that didn't load */ + for (SECMODModuleList* list = SECMOD_GetDeadModuleList(); list; + list = list->next) { + nsCOMPtr module = new nsPKCS11Module(list->module); + nsresult rv = array->AppendElement(module); + if (NS_FAILED(rv)) { + return rv; + } + } + + return array->Enumerate(_retval, NS_GET_IID(nsIPKCS11Module)); +} + +NS_IMETHODIMP +PKCS11ModuleDB::GetCanToggleFIPS(bool* aCanToggleFIPS) { + NS_ENSURE_ARG_POINTER(aCanToggleFIPS); + + *aCanToggleFIPS = SECMOD_CanDeleteInternalModule(); + return NS_OK; +} + +NS_IMETHODIMP +PKCS11ModuleDB::ToggleFIPSMode() { + // The way to toggle FIPS mode in NSS is extremely obscure. Basically, we + // delete the internal module, and it gets replaced with the opposite module + // (i.e. if it was FIPS before, then it becomes non-FIPS next). + // SECMOD_GetInternalModule() returns a pointer to a local copy of the + // internal module stashed in NSS. We don't want to delete it since it will + // cause much pain in NSS. + SECMODModule* internal = SECMOD_GetInternalModule(); + if (!internal) { + return NS_ERROR_FAILURE; + } + + if (SECMOD_DeleteInternalModule(internal->commonName) != SECSuccess) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +NS_IMETHODIMP +PKCS11ModuleDB::GetIsFIPSEnabled(bool* aIsFIPSEnabled) { + NS_ENSURE_ARG_POINTER(aIsFIPSEnabled); + + *aIsFIPSEnabled = PK11_IsFIPS(); + return NS_OK; +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/PKCS11ModuleDB.h b/security/manager/ssl/PKCS11ModuleDB.h new file mode 100644 index 0000000000..c167afe410 --- /dev/null +++ b/security/manager/ssl/PKCS11ModuleDB.h @@ -0,0 +1,35 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ +#ifndef PKCS11ModuleDB_h +#define PKCS11ModuleDB_h + +#include "nsIPKCS11ModuleDB.h" + +namespace mozilla { +namespace psm { + +#define NS_PKCS11MODULEDB_CID \ + { \ + 0xff9fbcd7, 0x9517, 0x4334, { \ + 0xb9, 0x7a, 0xce, 0xed, 0x78, 0x90, 0x99, 0x74 \ + } \ + } + +class PKCS11ModuleDB : public nsIPKCS11ModuleDB { + public: + PKCS11ModuleDB() = default; + + NS_DECL_ISUPPORTS + NS_DECL_NSIPKCS11MODULEDB + + protected: + virtual ~PKCS11ModuleDB() = default; +}; + +} // namespace psm +} // namespace mozilla + +#endif // PKCS11ModuleDB_h diff --git a/security/manager/ssl/PSMIPCCommon.cpp b/security/manager/ssl/PSMIPCCommon.cpp new file mode 100644 index 0000000000..6e0ed62302 --- /dev/null +++ b/security/manager/ssl/PSMIPCCommon.cpp @@ -0,0 +1,161 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ + +/* 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/. */ + +#include "CTVerifyResult.h" +#include "PSMIPCCommon.h" + +namespace mozilla { +namespace psm { + +SECItem* WrapPrivateKeyInfoWithEmptyPassword( + SECKEYPrivateKey* pk) /* encrypt this private key */ +{ + if (!pk) { + PR_SetError(SEC_ERROR_INVALID_ARGS, 0); + return nullptr; + } + + UniquePK11SlotInfo slot(PK11_GetInternalSlot()); + if (!slot) { + return nullptr; + } + + // For private keys, NSS cannot export anything other than RSA, but we need EC + // also. So, we use the private key encryption function to serialize instead, + // using a hard-coded dummy password; this is not intended to provide any + // additional security, it just works around a limitation in NSS. + SECItem dummyPassword = {siBuffer, nullptr, 0}; + UniqueSECKEYEncryptedPrivateKeyInfo epki(PK11_ExportEncryptedPrivKeyInfo( + slot.get(), SEC_OID_AES_128_CBC, &dummyPassword, pk, 1, nullptr)); + + if (!epki) { + return nullptr; + } + + return SEC_ASN1EncodeItem( + nullptr, nullptr, epki.get(), + NSS_Get_SECKEY_EncryptedPrivateKeyInfoTemplate(nullptr, false)); +} + +SECStatus UnwrapPrivateKeyInfoWithEmptyPassword( + SECItem* derPKI, const UniqueCERTCertificate& aCert, + SECKEYPrivateKey** privk) { + if (!derPKI || !aCert || !privk) { + PR_SetError(SEC_ERROR_INVALID_ARGS, 0); + return SECFailure; + } + + UniqueSECKEYPublicKey publicKey(CERT_ExtractPublicKey(aCert.get())); + // This is a pointer to data inside publicKey + SECItem* publicValue = nullptr; + switch (publicKey->keyType) { + case dsaKey: + publicValue = &publicKey->u.dsa.publicValue; + break; + case dhKey: + publicValue = &publicKey->u.dh.publicValue; + break; + case rsaKey: + publicValue = &publicKey->u.rsa.modulus; + break; + case ecKey: + publicValue = &publicKey->u.ec.publicValue; + break; + default: + MOZ_ASSERT(false); + PR_SetError(SSL_ERROR_BAD_CERTIFICATE, 0); + return SECFailure; + } + + UniquePK11SlotInfo slot(PK11_GetInternalSlot()); + if (!slot) { + return SECFailure; + } + + UniquePLArenaPool temparena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); + if (!temparena) { + return SECFailure; + } + + SECKEYEncryptedPrivateKeyInfo* epki = + PORT_ArenaZNew(temparena.get(), SECKEYEncryptedPrivateKeyInfo); + if (!epki) { + return SECFailure; + } + + SECStatus rv = SEC_ASN1DecodeItem( + temparena.get(), epki, + NSS_Get_SECKEY_EncryptedPrivateKeyInfoTemplate(nullptr, false), derPKI); + if (rv != SECSuccess) { + // If SEC_ASN1DecodeItem fails, we cannot assume anything about the + // validity of the data in epki. The best we can do is free the arena + // and return. + return rv; + } + + // See comment in WrapPrivateKeyInfoWithEmptyPassword about this + // dummy password stuff. + SECItem dummyPassword = {siBuffer, nullptr, 0}; + return PK11_ImportEncryptedPrivateKeyInfoAndReturnKey( + slot.get(), epki, &dummyPassword, nullptr, publicValue, false, false, + publicKey->keyType, KU_ALL, privk, nullptr); +} + +void SerializeClientCertAndKey(const UniqueCERTCertificate& aCert, + const UniqueSECKEYPrivateKey& aKey, + ByteArray& aOutSerializedCert, + ByteArray& aOutSerializedKey) { + if (!aCert || !aKey) { + return; + } + + UniqueSECItem derPki(WrapPrivateKeyInfoWithEmptyPassword(aKey.get())); + if (!derPki) { + return; + } + + aOutSerializedCert.data().AppendElements(aCert->derCert.data, + aCert->derCert.len); + aOutSerializedKey.data().AppendElements(derPki->data, derPki->len); +} + +void DeserializeClientCertAndKey(const ByteArray& aSerializedCert, + const ByteArray& aSerializedKey, + UniqueCERTCertificate& aOutCert, + UniqueSECKEYPrivateKey& aOutKey) { + if (aSerializedCert.data().IsEmpty() || aSerializedKey.data().IsEmpty()) { + return; + } + + SECItem item = {siBuffer, + const_cast(aSerializedCert.data().Elements()), + static_cast(aSerializedCert.data().Length())}; + + UniqueCERTCertificate cert(CERT_NewTempCertificate( + CERT_GetDefaultCertDB(), &item, nullptr, false, true)); + + if (!cert) { + return; + } + + SECItem derPKI = {siBuffer, + const_cast(aSerializedKey.data().Elements()), + static_cast(aSerializedKey.data().Length())}; + + SECKEYPrivateKey* privateKey; + if (UnwrapPrivateKeyInfoWithEmptyPassword(&derPKI, cert, &privateKey) != + SECSuccess) { + MOZ_ASSERT(false); + return; + } + + aOutCert = std::move(cert); + aOutKey.reset(privateKey); +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/PSMIPCCommon.h b/security/manager/ssl/PSMIPCCommon.h new file mode 100644 index 0000000000..7d5455dd4b --- /dev/null +++ b/security/manager/ssl/PSMIPCCommon.h @@ -0,0 +1,34 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ + +/* 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/. */ + +#ifndef PSMIPCCommon_h__ +#define PSMIPCCommon_h__ + +#include "mozilla/psm/PSMIPCTypes.h" +#include "seccomon.h" +#include "ScopedNSSTypes.h" + +namespace mozilla { +namespace psm { + +SECItem* WrapPrivateKeyInfoWithEmptyPassword(SECKEYPrivateKey* pk); +SECStatus UnwrapPrivateKeyInfoWithEmptyPassword( + SECItem* derPKI, const UniqueCERTCertificate& aCert, + SECKEYPrivateKey** privk); +void SerializeClientCertAndKey(const UniqueCERTCertificate& aCert, + const UniqueSECKEYPrivateKey& aKey, + ByteArray& aOutSerializedCert, + ByteArray& aOutSerializedKey); +void DeserializeClientCertAndKey(const ByteArray& aSerializedCert, + const ByteArray& aSerializedKey, + UniqueCERTCertificate& aOutCert, + UniqueSECKEYPrivateKey& aOutKey); + +} // namespace psm +} // namespace mozilla + +#endif // PSMIPCCommon_h__ diff --git a/security/manager/ssl/PSMIPCTypes.ipdlh b/security/manager/ssl/PSMIPCTypes.ipdlh new file mode 100644 index 0000000000..b529638913 --- /dev/null +++ b/security/manager/ssl/PSMIPCTypes.ipdlh @@ -0,0 +1,36 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */ + +/* 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/. */ + +include "ipc/DataStorageIPCUtils.h"; + +using mozilla::DataStorageType from "mozilla/DataStorage.h"; + +namespace mozilla { +namespace psm { + +struct ByteArray{ + uint8_t[] data; +}; + +struct DelegatedCredentialInfoArg { + uint32_t scheme; + uint32_t authKeyBits; +}; + +struct DataStorageItem { + nsCString key; + nsCString value; + DataStorageType type; +}; + +struct DataStorageEntry { + DataStorageItem[] items; + nsString filename; +}; + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/PSMRunnable.cpp b/security/manager/ssl/PSMRunnable.cpp new file mode 100644 index 0000000000..b962f52af3 --- /dev/null +++ b/security/manager/ssl/PSMRunnable.cpp @@ -0,0 +1,42 @@ +/* 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/. */ + +#include "PSMRunnable.h" + +namespace mozilla { +namespace psm { + +SyncRunnableBase::SyncRunnableBase() + : Runnable("psm::SyncRunnableBase"), monitor("SyncRunnableBase::monitor") {} + +nsresult SyncRunnableBase::DispatchToMainThreadAndWait() { + nsresult rv; + if (NS_IsMainThread()) { + RunOnTargetThread(); + rv = NS_OK; + } else { + mozilla::MonitorAutoLock lock(monitor); + rv = NS_DispatchToMainThread(this); + if (NS_SUCCEEDED(rv)) { + lock.Wait(); + } + } + + return rv; +} + +NS_IMETHODIMP +SyncRunnableBase::Run() { + RunOnTargetThread(); + mozilla::MonitorAutoLock(monitor).Notify(); + return NS_OK; +} + +nsresult NotifyObserverRunnable::Run() { + mObserver->Observe(nullptr, mTopic, nullptr); + return NS_OK; +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/PSMRunnable.h b/security/manager/ssl/PSMRunnable.h new file mode 100644 index 0000000000..3e74895fe1 --- /dev/null +++ b/security/manager/ssl/PSMRunnable.h @@ -0,0 +1,48 @@ +/* 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/. */ + +#ifndef PSMRunnable_h +#define PSMRunnable_h + +#include "mozilla/Monitor.h" +#include "nsThreadUtils.h" +#include "nsIObserver.h" +#include "nsProxyRelease.h" + +namespace mozilla { +namespace psm { + +// Wait for the event to run on the target thread without spinning the event +// loop on the calling thread. (Dispatching events to a thread using +// NS_DISPATCH_SYNC would cause the event loop on the calling thread to spin.) +class SyncRunnableBase : public Runnable { + public: + NS_DECL_NSIRUNNABLE + nsresult DispatchToMainThreadAndWait(); + + protected: + SyncRunnableBase(); + virtual void RunOnTargetThread() = 0; + + private: + mozilla::Monitor monitor; +}; + +class NotifyObserverRunnable : public Runnable { + public: + NotifyObserverRunnable(nsIObserver* observer, const char* topicStringLiteral) + : Runnable("psm::NotifyObserverRunnable"), + mObserver(new nsMainThreadPtrHolder( + "psm::NotifyObserverRunnable::mObserver", observer)), + mTopic(topicStringLiteral) {} + NS_DECL_NSIRUNNABLE + private: + nsMainThreadPtrHandle mObserver; + const char* const mTopic; +}; + +} // namespace psm +} // namespace mozilla + +#endif diff --git a/security/manager/ssl/PVerifySSLServerCert.ipdl b/security/manager/ssl/PVerifySSLServerCert.ipdl new file mode 100644 index 0000000000..52f2a97e50 --- /dev/null +++ b/security/manager/ssl/PVerifySSLServerCert.ipdl @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 ft=cpp : */ + +/* 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/. */ + +include protocol PBackground; +include PSMIPCTypes; + +namespace mozilla { +namespace psm { + +refcounted protocol PVerifySSLServerCert +{ + manager PBackground; + +child: + async OnVerifiedSSLServerCertSuccess(ByteArray[] aBuiltCertChain, + uint16_t aCertTransparencyStatus, + uint8_t aEVStatus, + bool isBuiltCertChainRootBuiltInRoot); + + async OnVerifiedSSLServerCertFailure(uint32_t aFinalError, + uint32_t aCollectedErrors); + + async __delete__(); +}; + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/PublicKeyPinningService.cpp b/security/manager/ssl/PublicKeyPinningService.cpp new file mode 100644 index 0000000000..b29e74f2c6 --- /dev/null +++ b/security/manager/ssl/PublicKeyPinningService.cpp @@ -0,0 +1,346 @@ +/* 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/. */ + +#include "PublicKeyPinningService.h" + +#include "RootCertificateTelemetryUtils.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Base64.h" +#include "mozilla/BinarySearch.h" +#include "mozilla/Casting.h" +#include "mozilla/Logging.h" +#include "mozilla/Span.h" +#include "mozilla/Telemetry.h" +#include "nsDependentString.h" +#include "nsServiceManagerUtils.h" +#include "mozpkix/pkixtypes.h" +#include "mozpkix/pkixutil.h" +#include "seccomon.h" +#include "sechash.h" + +#include "StaticHPKPins.h" // autogenerated by genHPKPStaticpins.js + +using namespace mozilla; +using namespace mozilla::pkix; +using namespace mozilla::psm; + +LazyLogModule gPublicKeyPinningLog("PublicKeyPinningService"); + +/** + Computes in the location specified by base64Out the SHA256 digest + of the DER Encoded subject Public Key Info for the given cert +*/ +static nsresult GetBase64HashSPKI(const BackCert& cert, + nsACString& hashSPKIDigest) { + Input derPublicKey = cert.GetSubjectPublicKeyInfo(); + + hashSPKIDigest.Truncate(); + nsTArray digestArray; + nsresult nsrv = + Digest::DigestBuf(SEC_OID_SHA256, derPublicKey.UnsafeGetData(), + derPublicKey.GetLength(), digestArray); + if (NS_FAILED(nsrv)) { + return nsrv; + } + return Base64Encode(nsDependentCSubstring( + BitwiseCast(digestArray.Elements()), + digestArray.Length()), + hashSPKIDigest); +} + +/* + * Sets certMatchesPinset to true if a given cert matches any fingerprints from + * the given pinset and false otherwise. + */ +static nsresult EvalCert(const BackCert& cert, + const StaticFingerprints* fingerprints, + /*out*/ bool& certMatchesPinset) { + certMatchesPinset = false; + if (!fingerprints) { + MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug, + ("pkpin: No hashes found\n")); + return NS_ERROR_INVALID_ARG; + } + + nsAutoCString base64Out; + nsresult rv = GetBase64HashSPKI(cert, base64Out); + if (NS_FAILED(rv)) { + MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug, + ("pkpin: GetBase64HashSPKI failed!\n")); + return rv; + } + + if (fingerprints) { + for (size_t i = 0; i < fingerprints->size; i++) { + if (base64Out.Equals(fingerprints->data[i])) { + MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug, + ("pkpin: found pin base_64 ='%s'\n", base64Out.get())); + certMatchesPinset = true; + return NS_OK; + } + } + } + return NS_OK; +} + +/* + * Sets certListIntersectsPinset to true if a given chain matches any + * fingerprints from the given static fingerprints and false otherwise. + */ +static nsresult EvalChain(const nsTArray>& derCertList, + const StaticFingerprints* fingerprints, + /*out*/ bool& certListIntersectsPinset) { + certListIntersectsPinset = false; + if (!fingerprints) { + MOZ_ASSERT(false, "Must pass in at least one type of pinset"); + return NS_ERROR_FAILURE; + } + + EndEntityOrCA endEntityOrCA = EndEntityOrCA::MustBeEndEntity; + for (const auto& cert : derCertList) { + Input certInput; + mozilla::pkix::Result rv = certInput.Init(cert.data(), cert.size()); + if (rv != mozilla::pkix::Result::Success) { + return NS_ERROR_INVALID_ARG; + } + BackCert backCert(certInput, endEntityOrCA, nullptr); + rv = backCert.Init(); + if (rv != mozilla::pkix::Result::Success) { + return NS_ERROR_INVALID_ARG; + } + + nsresult nsrv = EvalCert(backCert, fingerprints, certListIntersectsPinset); + if (NS_FAILED(nsrv)) { + return nsrv; + } + if (certListIntersectsPinset) { + break; + } + endEntityOrCA = EndEntityOrCA::MustBeCA; + } + + if (!certListIntersectsPinset) { + MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug, + ("pkpin: no matches found\n")); + } + return NS_OK; +} + +class TransportSecurityPreloadBinarySearchComparator { + public: + explicit TransportSecurityPreloadBinarySearchComparator( + const char* aTargetHost) + : mTargetHost(aTargetHost) {} + + int operator()(const TransportSecurityPreload& val) const { + return strcmp(mTargetHost, val.mHost); + } + + private: + const char* mTargetHost; // non-owning +}; + +#ifdef DEBUG +static Atomic sValidatedPinningPreloadList(false); + +static void ValidatePinningPreloadList() { + if (sValidatedPinningPreloadList) { + return; + } + for (const auto& entry : kPublicKeyPinningPreloadList) { + // If and only if a static entry is a Mozilla entry, it has a telemetry ID. + MOZ_ASSERT((entry.mIsMoz && entry.mId != kUnknownId) || + (!entry.mIsMoz && entry.mId == kUnknownId)); + } + sValidatedPinningPreloadList = true; +} +#endif // DEBUG + +// Returns via one of the output parameters the most relevant pinning +// information that is valid for the given host at the given time. +static nsresult FindPinningInformation( + const char* hostname, mozilla::pkix::Time time, + const OriginAttributes& originAttributes, + /*out*/ const TransportSecurityPreload*& staticFingerprints) { +#ifdef DEBUG + ValidatePinningPreloadList(); +#endif + if (!hostname || hostname[0] == 0) { + return NS_ERROR_INVALID_ARG; + } + staticFingerprints = nullptr; + const TransportSecurityPreload* foundEntry = nullptr; + const char* evalHost = hostname; + const char* evalPart; + // Notice how the (xx = strchr) prevents pins for unqualified domain names. + while (!foundEntry && (evalPart = strchr(evalHost, '.'))) { + MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug, + ("pkpin: Querying pinsets for host: '%s'\n", evalHost)); + size_t foundEntryIndex; + if (BinarySearchIf(kPublicKeyPinningPreloadList, 0, + ArrayLength(kPublicKeyPinningPreloadList), + TransportSecurityPreloadBinarySearchComparator(evalHost), + &foundEntryIndex)) { + foundEntry = &kPublicKeyPinningPreloadList[foundEntryIndex]; + MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug, + ("pkpin: Found pinset for host: '%s'\n", evalHost)); + if (evalHost != hostname) { + if (!foundEntry->mIncludeSubdomains) { + // Does not apply to this host, continue iterating + foundEntry = nullptr; + } + } + } else { + MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug, + ("pkpin: Didn't find pinset for host: '%s'\n", evalHost)); + } + // Add one for '.' + evalHost = evalPart + 1; + } + + if (foundEntry && foundEntry->pinset) { + if (time > TimeFromEpochInSeconds(kPreloadPKPinsExpirationTime / + PR_USEC_PER_SEC)) { + return NS_OK; + } + staticFingerprints = foundEntry; + } + return NS_OK; +} + +// Returns true via the output parameter if the given certificate list meets +// pinning requirements for the given host at the given time. It must be the +// case that either there is an intersection between the set of hashes of +// subject public key info data in the list and the most relevant non-expired +// pinset for the host or there is no pinning information for the host. +static nsresult CheckPinsForHostname( + const nsTArray>& certList, const char* hostname, + bool enforceTestMode, mozilla::pkix::Time time, + const OriginAttributes& originAttributes, + /*out*/ bool& chainHasValidPins, + /*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo) { + chainHasValidPins = false; + if (certList.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + if (!hostname || hostname[0] == 0) { + return NS_ERROR_INVALID_ARG; + } + + const TransportSecurityPreload* staticFingerprints = nullptr; + nsresult rv = FindPinningInformation(hostname, time, originAttributes, + staticFingerprints); + // If we have no pinning information, the certificate chain trivially + // validates with respect to pinning. + if (!staticFingerprints) { + chainHasValidPins = true; + return NS_OK; + } + if (staticFingerprints) { + bool enforceTestModeResult; + rv = EvalChain(certList, staticFingerprints->pinset, enforceTestModeResult); + if (NS_FAILED(rv)) { + return rv; + } + chainHasValidPins = enforceTestModeResult; + if (staticFingerprints->mTestMode && !enforceTestMode) { + chainHasValidPins = true; + } + + if (pinningTelemetryInfo) { + // If and only if a static entry is a Mozilla entry, it has a telemetry + // ID. + if ((staticFingerprints->mIsMoz && + staticFingerprints->mId == kUnknownId) || + (!staticFingerprints->mIsMoz && + staticFingerprints->mId != kUnknownId)) { + return NS_ERROR_FAILURE; + } + + Telemetry::HistogramID histogram; + int32_t bucket; + // We can collect per-host pinning violations for this host because it is + // operationally critical to Firefox. + if (staticFingerprints->mIsMoz) { + histogram = staticFingerprints->mTestMode + ? Telemetry::CERT_PINNING_MOZ_TEST_RESULTS_BY_HOST + : Telemetry::CERT_PINNING_MOZ_RESULTS_BY_HOST; + bucket = staticFingerprints->mId * 2 + (enforceTestModeResult ? 1 : 0); + } else { + histogram = staticFingerprints->mTestMode + ? Telemetry::CERT_PINNING_TEST_RESULTS + : Telemetry::CERT_PINNING_RESULTS; + bucket = enforceTestModeResult ? 1 : 0; + } + pinningTelemetryInfo->accumulateResult = true; + pinningTelemetryInfo->certPinningResultHistogram = Some(histogram); + pinningTelemetryInfo->certPinningResultBucket = bucket; + + // We only collect per-CA pinning statistics upon failures. + if (!enforceTestModeResult) { + int32_t binNumber = RootCABinNumber(certList.LastElement()); + if (binNumber != ROOT_CERTIFICATE_UNKNOWN) { + pinningTelemetryInfo->accumulateForRoot = true; + pinningTelemetryInfo->rootBucket = binNumber; + } + } + } + + MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug, + ("pkpin: Pin check %s for %s host '%s' (mode=%s)\n", + enforceTestModeResult ? "passed" : "failed", + staticFingerprints->mIsMoz ? "mozilla" : "non-mozilla", hostname, + staticFingerprints->mTestMode ? "test" : "production")); + } + + return NS_OK; +} + +nsresult PublicKeyPinningService::ChainHasValidPins( + const nsTArray>& certList, const char* hostname, + mozilla::pkix::Time time, bool enforceTestMode, + const OriginAttributes& originAttributes, + /*out*/ bool& chainHasValidPins, + /*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo) { + chainHasValidPins = false; + if (certList.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + if (!hostname || hostname[0] == 0) { + return NS_ERROR_INVALID_ARG; + } + nsAutoCString canonicalizedHostname(CanonicalizeHostname(hostname)); + return CheckPinsForHostname(certList, canonicalizedHostname.get(), + enforceTestMode, time, originAttributes, + chainHasValidPins, pinningTelemetryInfo); +} + +nsresult PublicKeyPinningService::HostHasPins( + const char* hostname, mozilla::pkix::Time time, bool enforceTestMode, + const OriginAttributes& originAttributes, + /*out*/ bool& hostHasPins) { + hostHasPins = false; + nsAutoCString canonicalizedHostname(CanonicalizeHostname(hostname)); + const TransportSecurityPreload* staticFingerprints = nullptr; + nsresult rv = FindPinningInformation(canonicalizedHostname.get(), time, + originAttributes, staticFingerprints); + if (NS_FAILED(rv)) { + return rv; + } + if (staticFingerprints) { + hostHasPins = !staticFingerprints->mTestMode || enforceTestMode; + } + return NS_OK; +} + +nsAutoCString PublicKeyPinningService::CanonicalizeHostname( + const char* hostname) { + nsAutoCString canonicalizedHostname(hostname); + ToLowerCase(canonicalizedHostname); + while (canonicalizedHostname.Length() > 0 && + canonicalizedHostname.Last() == '.') { + canonicalizedHostname.Truncate(canonicalizedHostname.Length() - 1); + } + return canonicalizedHostname; +} diff --git a/security/manager/ssl/PublicKeyPinningService.h b/security/manager/ssl/PublicKeyPinningService.h new file mode 100644 index 0000000000..5a16d838e0 --- /dev/null +++ b/security/manager/ssl/PublicKeyPinningService.h @@ -0,0 +1,65 @@ +/* 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/. */ + +#ifndef PublicKeyPinningService_h +#define PublicKeyPinningService_h + +#include "CertVerifier.h" +#include "ScopedNSSTypes.h" +#include "cert.h" +#include "nsNSSCertificate.h" +#include "nsString.h" +#include "nsTArray.h" +#include "mozilla/Span.h" +#include "mozpkix/Time.h" + +namespace mozilla { +class OriginAttributes; +} + +using mozilla::OriginAttributes; + +namespace mozilla { +namespace psm { + +class PublicKeyPinningService { + public: + /** + * Sets chainHasValidPins to true if the given (host, certList) passes pinning + * checks, or to false otherwise. If the host is pinned, returns true via + * chainHasValidPins if one of the keys in the given certificate chain matches + * the pin set specified by the hostname. The certList's head is the EE cert + * and the tail is the trust anchor. + * Note: if an alt name is a wildcard, it won't necessarily find a pinset + * that would otherwise be valid for it + */ + static nsresult ChainHasValidPins( + const nsTArray>& certList, const char* hostname, + mozilla::pkix::Time time, bool enforceTestMode, + const OriginAttributes& originAttributes, + /*out*/ bool& chainHasValidPins, + /*optional out*/ PinningTelemetryInfo* pinningTelemetryInfo); + + /** + * Returns true via the output parameter hostHasPins if there is pinning + * information for the given host that is valid at the given time, and false + * otherwise. + */ + static nsresult HostHasPins(const char* hostname, mozilla::pkix::Time time, + bool enforceTestMode, + const OriginAttributes& originAttributes, + /*out*/ bool& hostHasPins); + + /** + * Given a hostname of potentially mixed case with potentially multiple + * trailing '.' (see bug 1118522), canonicalizes it to lowercase with no + * trailing '.'. + */ + static nsAutoCString CanonicalizeHostname(const char* hostname); +}; + +} // namespace psm +} // namespace mozilla + +#endif // PublicKeyPinningService_h diff --git a/security/manager/ssl/PublicSSL.h b/security/manager/ssl/PublicSSL.h new file mode 100644 index 0000000000..06a67fac5f --- /dev/null +++ b/security/manager/ssl/PublicSSL.h @@ -0,0 +1,24 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef mozilla_SSL_h +#define mozilla_SSL_h + +namespace mozilla { + +void ClearPrivateSSLState(); + +namespace psm { + +void InitializeSSLServerCertVerificationThreads(); +void StopSSLServerCertVerificationThreads(); +void DisableMD5(); +nsresult InitializeCipherSuite(); + +} // namespace psm +} // namespace mozilla + +#endif diff --git a/security/manager/ssl/RemoteSecuritySettings.jsm b/security/manager/ssl/RemoteSecuritySettings.jsm new file mode 100644 index 0000000000..0beca14247 --- /dev/null +++ b/security/manager/ssl/RemoteSecuritySettings.jsm @@ -0,0 +1,850 @@ +/* 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/. */ +"use strict"; + +const EXPORTED_SYMBOLS = ["RemoteSecuritySettings"]; + +const { RemoteSettings } = ChromeUtils.import( + "resource://services-settings/remote-settings.js" +); + +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +const { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); +const { X509 } = ChromeUtils.import( + "resource://gre/modules/psm/X509.jsm", + null +); + +const INTERMEDIATES_BUCKET_PREF = + "security.remote_settings.intermediates.bucket"; +const INTERMEDIATES_CHECKED_SECONDS_PREF = + "security.remote_settings.intermediates.checked"; +const INTERMEDIATES_COLLECTION_PREF = + "security.remote_settings.intermediates.collection"; +const INTERMEDIATES_DL_PER_POLL_PREF = + "security.remote_settings.intermediates.downloads_per_poll"; +const INTERMEDIATES_DL_PARALLEL_REQUESTS = + "security.remote_settings.intermediates.parallel_downloads"; +const INTERMEDIATES_ENABLED_PREF = + "security.remote_settings.intermediates.enabled"; +const INTERMEDIATES_SIGNER_PREF = + "security.remote_settings.intermediates.signer"; +const LOGLEVEL_PREF = "browser.policies.loglevel"; + +const INTERMEDIATES_ERRORS_TELEMETRY = "INTERMEDIATE_PRELOADING_ERRORS"; +const INTERMEDIATES_PENDING_TELEMETRY = + "security.intermediate_preloading_num_pending"; +const INTERMEDIATES_PRELOADED_TELEMETRY = + "security.intermediate_preloading_num_preloaded"; +const INTERMEDIATES_UPDATE_MS_TELEMETRY = + "INTERMEDIATE_PRELOADING_UPDATE_TIME_MS"; + +const ONECRL_BUCKET_PREF = "services.settings.security.onecrl.bucket"; +const ONECRL_COLLECTION_PREF = "services.settings.security.onecrl.collection"; +const ONECRL_SIGNER_PREF = "services.settings.security.onecrl.signer"; +const ONECRL_CHECKED_PREF = "services.settings.security.onecrl.checked"; + +const PINNING_ENABLED_PREF = "services.blocklist.pinning.enabled"; +const PINNING_BUCKET_PREF = "services.blocklist.pinning.bucket"; +const PINNING_COLLECTION_PREF = "services.blocklist.pinning.collection"; +const PINNING_CHECKED_SECONDS_PREF = "services.blocklist.pinning.checked"; +const PINNING_SIGNER_PREF = "services.blocklist.pinning.signer"; + +const CRLITE_FILTERS_BUCKET_PREF = + "security.remote_settings.crlite_filters.bucket"; +const CRLITE_FILTERS_CHECKED_SECONDS_PREF = + "security.remote_settings.crlite_filters.checked"; +const CRLITE_FILTERS_COLLECTION_PREF = + "security.remote_settings.crlite_filters.collection"; +const CRLITE_FILTERS_ENABLED_PREF = + "security.remote_settings.crlite_filters.enabled"; +const CRLITE_FILTERS_SIGNER_PREF = + "security.remote_settings.crlite_filters.signer"; + +XPCOMUtils.defineLazyGlobalGetters(this, ["fetch"]); + +XPCOMUtils.defineLazyGetter(this, "gTextDecoder", () => new TextDecoder()); + +XPCOMUtils.defineLazyGetter(this, "log", () => { + let { ConsoleAPI } = ChromeUtils.import("resource://gre/modules/Console.jsm"); + return new ConsoleAPI({ + prefix: "RemoteSecuritySettings.jsm", + // tip: set maxLogLevel to "debug" and use log.debug() to create detailed + // messages during development. See LOG_LEVELS in Console.jsm for details. + maxLogLevel: "error", + maxLogLevelPref: LOGLEVEL_PREF, + }); +}); + +// Converts a JS string to an array of bytes consisting of the char code at each +// index in the string. +function stringToBytes(s) { + let b = []; + for (let i = 0; i < s.length; i++) { + b.push(s.charCodeAt(i)); + } + return b; +} + +// Converts an array of bytes to a JS string using fromCharCode on each byte. +function bytesToString(bytes) { + if (bytes.length > 65535) { + throw new Error("input too long for bytesToString"); + } + return String.fromCharCode.apply(null, bytes); +} + +class CRLiteState { + constructor(subject, spkiHash, state) { + this.subject = subject; + this.spkiHash = spkiHash; + this.state = state; + } +} +CRLiteState.prototype.QueryInterface = ChromeUtils.generateQI([ + "nsICRLiteState", +]); + +class CertInfo { + constructor(cert, subject) { + this.cert = cert; + this.subject = subject; + this.trust = Ci.nsICertStorage.TRUST_INHERIT; + } +} +CertInfo.prototype.QueryInterface = ChromeUtils.generateQI(["nsICertInfo"]); + +class RevocationState { + constructor(state) { + this.state = state; + } +} + +class IssuerAndSerialRevocationState extends RevocationState { + constructor(issuer, serial, state) { + super(state); + this.issuer = issuer; + this.serial = serial; + } +} +IssuerAndSerialRevocationState.prototype.QueryInterface = ChromeUtils.generateQI( + ["nsIIssuerAndSerialRevocationState"] +); + +class SubjectAndPubKeyRevocationState extends RevocationState { + constructor(subject, pubKey, state) { + super(state); + this.subject = subject; + this.pubKey = pubKey; + } +} +SubjectAndPubKeyRevocationState.prototype.QueryInterface = ChromeUtils.generateQI( + ["nsISubjectAndPubKeyRevocationState"] +); + +function setRevocations(certStorage, revocations) { + return new Promise(resolve => + certStorage.setRevocations(revocations, resolve) + ); +} + +/** + * Helper function that returns a promise that will resolve with whether or not + * the nsICertStorage implementation has prior data of the given type. + * + * @param {Integer} dataType a Ci.nsICertStorage.DATA_TYPE_* constant + * indicating the type of data + + * @return {Promise} a promise that will resolve with true if the data type is + * present + */ +function hasPriorData(dataType) { + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + return new Promise(resolve => { + certStorage.hasPriorData(dataType, (rv, hasPriorData) => { + if (rv == Cr.NS_OK) { + resolve(hasPriorData); + } else { + // If calling hasPriorData failed, assume we need to reload everything + // (even though it's unlikely doing so will succeed). + resolve(false); + } + }); + }); +} + +/** + * Revoke the appropriate certificates based on the records from the blocklist. + * + * @param {Object} data Current records in the local db. + */ +const updateCertBlocklist = async function({ + data: { current, created, updated, deleted }, +}) { + let items = []; + + // See if we have prior revocation data (this can happen when we can't open + // the database and we have to re-create it (see bug 1546361)). + let hasPriorRevocationData = await hasPriorData( + Ci.nsICertStorage.DATA_TYPE_REVOCATION + ); + + // If we don't have prior data, make it so we re-load everything. + if (!hasPriorRevocationData) { + deleted = []; + updated = []; + created = current; + } + + for (let item of deleted) { + if (item.issuerName && item.serialNumber) { + items.push( + new IssuerAndSerialRevocationState( + item.issuerName, + item.serialNumber, + Ci.nsICertStorage.STATE_UNSET + ) + ); + } else if (item.subject && item.pubKeyHash) { + items.push( + new SubjectAndPubKeyRevocationState( + item.subject, + item.pubKeyHash, + Ci.nsICertStorage.STATE_UNSET + ) + ); + } + } + + const toAdd = created.concat(updated.map(u => u.new)); + + for (let item of toAdd) { + if (item.issuerName && item.serialNumber) { + items.push( + new IssuerAndSerialRevocationState( + item.issuerName, + item.serialNumber, + Ci.nsICertStorage.STATE_ENFORCE + ) + ); + } else if (item.subject && item.pubKeyHash) { + items.push( + new SubjectAndPubKeyRevocationState( + item.subject, + item.pubKeyHash, + Ci.nsICertStorage.STATE_ENFORCE + ) + ); + } + } + + try { + const certList = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + await setRevocations(certList, items); + } catch (e) { + Cu.reportError(e); + } +}; + +/** + * Modify the appropriate security pins based on records from the remote + * collection. + * + * @param {Object} data Current records in the local db. + */ +async function updatePinningList({ data: { current: records } }) { + if (!Services.prefs.getBoolPref(PINNING_ENABLED_PREF)) { + return; + } + + const siteSecurityService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + + // clear the current preload list + siteSecurityService.clearPreloads(); + + // write each KeyPin entry to the preload list + for (let item of records) { + try { + const { pinType, versions } = item; + if (versions.includes(Services.appinfo.version) && pinType == "STSPin") { + siteSecurityService.setHSTSPreload( + item.hostName, + item.includeSubdomains, + item.expires + ); + } + } catch (e) { + // Prevent errors relating to individual preload entries from causing sync to fail. + Cu.reportError(e); + } + } +} + +var RemoteSecuritySettings = { + /** + * Initialize the clients (cheap instantiation) and setup their sync event. + * This static method is called from BrowserGlue.jsm soon after startup. + * + * @returns {Object} intantiated clients for security remote settings. + */ + init() { + const OneCRLBlocklistClient = RemoteSettings( + Services.prefs.getCharPref(ONECRL_COLLECTION_PREF), + { + bucketNamePref: ONECRL_BUCKET_PREF, + lastCheckTimePref: ONECRL_CHECKED_PREF, + signerName: Services.prefs.getCharPref(ONECRL_SIGNER_PREF), + } + ); + OneCRLBlocklistClient.on("sync", updateCertBlocklist); + + const PinningBlocklistClient = RemoteSettings( + Services.prefs.getCharPref(PINNING_COLLECTION_PREF), + { + bucketNamePref: PINNING_BUCKET_PREF, + lastCheckTimePref: PINNING_CHECKED_SECONDS_PREF, + signerName: Services.prefs.getCharPref(PINNING_SIGNER_PREF), + } + ); + PinningBlocklistClient.on("sync", updatePinningList); + + let IntermediatePreloadsClient = new IntermediatePreloads(); + let CRLiteFiltersClient = new CRLiteFilters(); + + this.OneCRLBlocklistClient = OneCRLBlocklistClient; + this.PinningBlocklistClient = PinningBlocklistClient; + this.IntermediatePreloadsClient = IntermediatePreloadsClient; + this.CRLiteFiltersClient = CRLiteFiltersClient; + + return { + OneCRLBlocklistClient, + PinningBlocklistClient, + IntermediatePreloadsClient, + CRLiteFiltersClient, + }; + }, +}; + +class IntermediatePreloads { + constructor() { + this.client = RemoteSettings( + Services.prefs.getCharPref(INTERMEDIATES_COLLECTION_PREF), + { + bucketNamePref: INTERMEDIATES_BUCKET_PREF, + lastCheckTimePref: INTERMEDIATES_CHECKED_SECONDS_PREF, + signerName: Services.prefs.getCharPref(INTERMEDIATES_SIGNER_PREF), + localFields: ["cert_import_complete"], + } + ); + + this.client.on("sync", this.onSync.bind(this)); + Services.obs.addObserver( + this.onObservePollEnd.bind(this), + "remote-settings:changes-poll-end" + ); + + log.debug("Intermediate Preloading: constructor"); + } + + async updatePreloadedIntermediates() { + if (!Services.prefs.getBoolPref(INTERMEDIATES_ENABLED_PREF, true)) { + log.debug("Intermediate Preloading is disabled"); + Services.obs.notifyObservers( + null, + "remote-security-settings:intermediates-updated", + "disabled" + ); + return; + } + + // Download attachments that are awaiting download, up to a max. + const maxDownloadsPerRun = Services.prefs.getIntPref( + INTERMEDIATES_DL_PER_POLL_PREF, + 100 + ); + const parallelDownloads = Services.prefs.getIntPref( + INTERMEDIATES_DL_PARALLEL_REQUESTS, + 8 + ); + + // Bug 1519256: Move this to a separate method that's on a separate timer + // with a higher frequency (so we can attempt to download outstanding + // certs more than once daily) + + // See if we have prior cert data (this can happen when we can't open the database and we + // have to re-create it (see bug 1546361)). + let hasPriorCertData = await hasPriorData( + Ci.nsICertStorage.DATA_TYPE_CERTIFICATE + ); + // If we don't have prior data, make it so we re-load everything. + if (!hasPriorCertData) { + let current; + try { + current = await this.client.db.list(); + } catch (err) { + log.warn(`Unable to list intermediate preloading collection: ${err}`); + // Re-purpose the "failedToFetch" category to indicate listing the collection failed. + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("failedToFetch"); + return; + } + const toReset = current.filter(record => record.cert_import_complete); + try { + await this.client.db.importChanges( + undefined, // do not touch metadata. + undefined, // do not touch collection timestamp. + toReset.map(r => ({ ...r, cert_import_complete: false })) + ); + } catch (err) { + log.warn(`Unable to update intermediate preloading collection: ${err}`); + // Re-purpose the "unexpectedLength" category to indicate updating the collection failed. + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("unexpectedLength"); + return; + } + } + let current; + try { + current = await this.client.db.list(); + } catch (err) { + log.warn(`Unable to list intermediate preloading collection: ${err}`); + // Re-purpose the "failedToFetch" category to indicate listing the collection failed. + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("failedToFetch"); + return; + } + const waiting = current.filter(record => !record.cert_import_complete); + + log.debug(`There are ${waiting.length} intermediates awaiting download.`); + if (waiting.length == 0) { + // Nothing to do. + Services.obs.notifyObservers( + null, + "remote-security-settings:intermediates-updated", + "success" + ); + return; + } + + TelemetryStopwatch.start(INTERMEDIATES_UPDATE_MS_TELEMETRY); + + let toDownload = waiting.slice(0, maxDownloadsPerRun); + let recordsCertsAndSubjects = []; + for (let i = 0; i < toDownload.length; i += parallelDownloads) { + const chunk = toDownload.slice(i, i + parallelDownloads); + const downloaded = await Promise.all( + chunk.map(record => this.maybeDownloadAttachment(record)) + ); + recordsCertsAndSubjects = recordsCertsAndSubjects.concat(downloaded); + } + + let certInfos = []; + let recordsToUpdate = []; + for (let { record, cert, subject } of recordsCertsAndSubjects) { + if (cert && subject) { + certInfos.push(new CertInfo(cert, subject)); + recordsToUpdate.push(record); + } + } + const certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + let result = await new Promise(resolve => { + certStorage.addCerts(certInfos, resolve); + }).catch(err => err); + if (result != Cr.NS_OK) { + Cu.reportError(`certStorage.addCerts failed: ${result}`); + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("failedToUpdateDB"); + return; + } + try { + await this.client.db.importChanges( + undefined, // do not touch metadata. + undefined, // do not touch collection timestamp. + recordsToUpdate.map(r => ({ ...r, cert_import_complete: true })) + ); + } catch (err) { + log.warn(`Unable to update intermediate preloading collection: ${err}`); + // Re-purpose the "unexpectedLength" category to indicate updating the collection failed. + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("unexpectedLength"); + return; + } + + let finalCurrent; + try { + finalCurrent = await this.client.db.list(); + } catch (err) { + log.warn(`Unable to list intermediate preloading collection: ${err}`); + // Re-purpose the "failedToFetch" category to indicate listing the collection failed. + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("failedToFetch"); + return; + } + const finalWaiting = finalCurrent.filter( + record => !record.cert_import_complete + ); + + const countPreloaded = finalCurrent.length - finalWaiting.length; + + TelemetryStopwatch.finish(INTERMEDIATES_UPDATE_MS_TELEMETRY); + Services.telemetry.scalarSet( + INTERMEDIATES_PRELOADED_TELEMETRY, + countPreloaded + ); + Services.telemetry.scalarSet( + INTERMEDIATES_PENDING_TELEMETRY, + finalWaiting.length + ); + + Services.obs.notifyObservers( + null, + "remote-security-settings:intermediates-updated", + "success" + ); + } + + async onObservePollEnd(subject, topic, data) { + log.debug(`onObservePollEnd ${subject} ${topic}`); + + try { + await this.updatePreloadedIntermediates(); + } catch (err) { + log.warn(`Unable to update intermediate preloads: ${err}`); + + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("failedToObserve"); + } + } + + // This method returns a promise to RemoteSettingsClient.maybeSync method. + async onSync({ data: { current, created, updated, deleted } }) { + if (!Services.prefs.getBoolPref(INTERMEDIATES_ENABLED_PREF, true)) { + log.debug("Intermediate Preloading is disabled"); + return; + } + + log.debug(`Removing ${deleted.length} Intermediate certificates`); + await this.removeCerts(deleted); + let hasPriorCRLiteData = await hasPriorData( + Ci.nsICertStorage.DATA_TYPE_CRLITE + ); + if (!hasPriorCRLiteData) { + deleted = []; + updated = []; + created = current; + } + const toAdd = created.concat(updated.map(u => u.new)); + let entries = []; + for (let entry of deleted) { + entries.push( + new CRLiteState( + entry.subjectDN, + entry.pubKeyHash, + Ci.nsICertStorage.STATE_UNSET + ) + ); + } + for (let entry of toAdd) { + entries.push( + new CRLiteState( + entry.subjectDN, + entry.pubKeyHash, + entry.crlite_enrolled + ? Ci.nsICertStorage.STATE_ENFORCE + : Ci.nsICertStorage.STATE_UNSET + ) + ); + } + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + await new Promise(resolve => certStorage.setCRLiteState(entries, resolve)); + } + + /** + * Attempts to download the attachment, assuming it's not been processed + * already. Does not retry, and always resolves (e.g., does not reject upon + * failure.) Errors are reported via Cu.reportError. + * @param {AttachmentRecord} record defines which data to obtain + * @return {Promise} a Promise that will resolve to an object with the properties + * record, cert, and subject. record is the original record. + * cert is the base64-encoded bytes of the downloaded certificate (if + * downloading was successful), and null otherwise. + * subject is the base64-encoded bytes of the subject distinguished + * name of the same. + */ + async maybeDownloadAttachment(record) { + let result = { record, cert: null, subject: null }; + + let dataAsString = null; + try { + let buffer = await this.client.attachments.downloadAsBytes(record, { + retries: 0, + }); + dataAsString = gTextDecoder.decode(new Uint8Array(buffer)); + } catch (err) { + // Bug 1519273 - Log telemetry for these rejections + if (err.name == "BadContentError") { + log.debug(`Bad attachment content.`); + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("unexpectedHash"); + } else { + Cu.reportError(`Failed to download attachment: ${err}`); + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("failedToDownloadMisc"); + } + return result; + } + + let certBase64; + let subjectBase64; + try { + // split off the header and footer + certBase64 = dataAsString.split("-----")[2].replace(/\s/g, ""); + // get an array of bytes so we can use X509.jsm + let certBytes = stringToBytes(atob(certBase64)); + let cert = new X509.Certificate(); + cert.parse(certBytes); + // get the DER-encoded subject and get a base64-encoded string from it + // TODO(bug 1542028): add getters for _der and _bytes + subjectBase64 = btoa( + bytesToString(cert.tbsCertificate.subject._der._bytes) + ); + } catch (err) { + Cu.reportError(`Failed to decode cert: ${err}`); + + // Re-purpose the "failedToUpdateNSS" telemetry tag as "failed to + // decode preloaded intermediate certificate" + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("failedToUpdateNSS"); + + return result; + } + result.cert = certBase64; + result.subject = subjectBase64; + return result; + } + + async maybeSync(expectedTimestamp, options) { + return this.client.maybeSync(expectedTimestamp, options); + } + + async removeCerts(recordsToRemove) { + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + let hashes = recordsToRemove.map(record => record.derHash); + let result = await new Promise(resolve => { + certStorage.removeCertsByHashes(hashes, resolve); + }).catch(err => err); + if (result != Cr.NS_OK) { + Cu.reportError(`Failed to remove some intermediate certificates`); + Services.telemetry + .getHistogramById(INTERMEDIATES_ERRORS_TELEMETRY) + .add("failedToRemove"); + } + } +} + +// Helper function to compare filters. One filter is "less than" another filter (i.e. it sorts +// earlier) if its timestamp is farther in the past than the other. +function compareFilters(filterA, filterB) { + return filterA.effectiveTimestamp - filterB.effectiveTimestamp; +} + +class CRLiteFilters { + constructor() { + this.client = RemoteSettings( + Services.prefs.getCharPref(CRLITE_FILTERS_COLLECTION_PREF), + { + bucketNamePref: CRLITE_FILTERS_BUCKET_PREF, + lastCheckTimePref: CRLITE_FILTERS_CHECKED_SECONDS_PREF, + signerName: Services.prefs.getCharPref(CRLITE_FILTERS_SIGNER_PREF), + localFields: ["loaded_into_cert_storage"], + } + ); + + Services.obs.addObserver( + this.onObservePollEnd.bind(this), + "remote-settings:changes-poll-end" + ); + } + + async onObservePollEnd(subject, topic, data) { + if (!Services.prefs.getBoolPref(CRLITE_FILTERS_ENABLED_PREF, true)) { + log.debug("CRLite filter downloading is disabled"); + Services.obs.notifyObservers( + null, + "remote-security-settings:crlite-filters-downloaded", + "disabled" + ); + return; + } + + let hasPriorFilter = await hasPriorData( + Ci.nsICertStorage.DATA_TYPE_CRLITE_FILTER_FULL + ); + if (!hasPriorFilter) { + let current = await this.client.db.list(); + let toReset = current.filter( + record => !record.incremental && record.loaded_into_cert_storage + ); + await this.client.db.importChanges( + undefined, // do not touch metadata. + undefined, // do not touch collection timestamp. + toReset.map(r => ({ ...r, loaded_into_cert_storage: false })) + ); + } + let hasPriorStash = await hasPriorData( + Ci.nsICertStorage.DATA_TYPE_CRLITE_FILTER_INCREMENTAL + ); + if (!hasPriorStash) { + let current = await this.client.db.list(); + let toReset = current.filter( + record => record.incremental && record.loaded_into_cert_storage + ); + await this.client.db.importChanges( + undefined, // do not touch metadata. + undefined, // do not touch collection timestamp. + toReset.map(r => ({ ...r, loaded_into_cert_storage: false })) + ); + } + + let current = await this.client.db.list(); + let fullFilters = current.filter(filter => !filter.incremental); + if (fullFilters.length < 1) { + log.debug("no full CRLite filters to download?"); + Services.obs.notifyObservers( + null, + "remote-security-settings:crlite-filters-downloaded", + "unavailable" + ); + return; + } + fullFilters.sort(compareFilters); + log.debug("fullFilters:", fullFilters); + let fullFilter = fullFilters.pop(); // the most recent filter sorts last + let incrementalFilters = current.filter( + filter => + // Return incremental filters that are more recent than (i.e. sort later than) the full + // filter. + filter.incremental && compareFilters(filter, fullFilter) > 0 + ); + incrementalFilters.sort(compareFilters); + // Map of id to filter where that filter's parent has the given id. + let parentIdMap = {}; + for (let filter of incrementalFilters) { + if (filter.parent in parentIdMap) { + log.debug(`filter with parent id ${filter.parent} already seen?`); + } else { + parentIdMap[filter.parent] = filter; + } + } + let filtersToDownload = []; + let nextFilter = fullFilter; + while (nextFilter) { + filtersToDownload.push(nextFilter); + nextFilter = parentIdMap[nextFilter.id]; + } + const certList = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + filtersToDownload = filtersToDownload.filter( + filter => !filter.loaded_into_cert_storage + ); + log.debug("filtersToDownload:", filtersToDownload); + let filtersDownloaded = []; + for (let filter of filtersToDownload) { + try { + // If we've already downloaded this, the backend should just grab it from its cache. + let localURI = await this.client.attachments.download(filter); + let buffer = await (await fetch(localURI)).arrayBuffer(); + let bytes = new Uint8Array(buffer); + log.debug(`Downloaded ${filter.details.name}: ${bytes.length} bytes`); + filter.bytes = bytes; + filtersDownloaded.push(filter); + } catch (e) { + log.debug(e); + Cu.reportError("failed to download CRLite filter", e); + } + } + let fullFiltersDownloaded = filtersDownloaded.filter( + filter => !filter.incremental + ); + if (fullFiltersDownloaded.length > 0) { + if (fullFiltersDownloaded.length > 1) { + log.warn("trying to install more than one full CRLite filter?"); + } + let filter = fullFiltersDownloaded[0]; + let timestamp = Math.floor(filter.effectiveTimestamp / 1000); + log.debug(`setting CRLite filter timestamp to ${timestamp}`); + await new Promise(resolve => { + certList.setFullCRLiteFilter(filter.bytes, timestamp, rv => { + log.debug(`setFullCRLiteFilter: ${rv}`); + resolve(); + }); + }); + } + let stashes = filtersDownloaded.filter(filter => filter.incremental); + let totalLength = stashes.reduce( + (sum, filter) => sum + filter.bytes.length, + 0 + ); + let concatenatedStashes = new Uint8Array(totalLength); + let offset = 0; + for (let filter of stashes) { + concatenatedStashes.set(filter.bytes, offset); + offset += filter.bytes.length; + } + if (concatenatedStashes.length > 0) { + log.debug( + `adding concatenated incremental updates of total length ${concatenatedStashes.length}` + ); + await new Promise(resolve => { + certList.addCRLiteStash(concatenatedStashes, rv => { + log.debug(`addCRLiteStash: ${rv}`); + resolve(); + }); + }); + } + + for (let filter of filtersDownloaded) { + delete filter.bytes; + } + + await this.client.db.importChanges( + undefined, // do not touch metadata. + undefined, // do not touch collection timestamp. + filtersDownloaded.map(r => ({ ...r, loaded_into_cert_storage: true })) + ); + + Services.obs.notifyObservers( + null, + "remote-security-settings:crlite-filters-downloaded", + `finished;${filtersDownloaded + .map(filter => filter.details.name) + .join(",")}` + ); + } +} diff --git a/security/manager/ssl/RootCertificateTelemetryUtils.cpp b/security/manager/ssl/RootCertificateTelemetryUtils.cpp new file mode 100644 index 0000000000..d500a880c9 --- /dev/null +++ b/security/manager/ssl/RootCertificateTelemetryUtils.cpp @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "RootCertificateTelemetryUtils.h" + +#include "RootHashes.inc" // Note: Generated by genRootCAHashes.js +#include "ScopedNSSTypes.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Logging.h" +#include "nsINSSComponent.h" +#include "nsNSSCertHelper.h" +#include "nsServiceManagerUtils.h" +#include "pk11pub.h" + +namespace mozilla { +namespace psm { + +mozilla::LazyLogModule gPublicKeyPinningTelemetryLog( + "PublicKeyPinningTelemetryService"); + +// Used in the BinarySearch method, this does a memcmp between the pointer +// provided to its construtor and whatever the binary search is looking for. +// +// This implementation assumes everything to be of HASH_LEN, so it should not +// be used generically. +class BinaryHashSearchArrayComparator { + public: + explicit BinaryHashSearchArrayComparator(const uint8_t* aTarget, size_t len) + : mTarget(aTarget) { + MOZ_ASSERT(len == HASH_LEN, "Hashes should be of the same length."); + } + + int operator()(const CertAuthorityHash val) const { + return memcmp(mTarget, val.hash, HASH_LEN); + } + + private: + const uint8_t* mTarget; +}; + +// Perform a hash of the provided cert, then search in the RootHashes.inc data +// structure for a matching bin number. +// If no matching root is found, this may be a CA from the softoken (cert9.db), +// it may be a CA from an external PKCS#11 token, or it may be a CA from OS +// storage (Enterprise Root). +// See also the constants in RootCertificateTelemetryUtils.h. +int32_t RootCABinNumber(Span cert) { + nsTArray digestArray; + + // Compute SHA256 hash of the certificate + nsresult rv = Digest::DigestBuf(SEC_OID_SHA256, cert, digestArray); + if (NS_WARN_IF(NS_FAILED(rv))) { + return ROOT_CERTIFICATE_HASH_FAILURE; + } + + // Compare against list of stored hashes + size_t idx; + + MOZ_LOG(gPublicKeyPinningTelemetryLog, LogLevel::Debug, + ("pkpinTelem: First bytes %02x %02x %02x %02x\n", + digestArray.ElementAt(0), digestArray.ElementAt(1), + digestArray.ElementAt(2), digestArray.ElementAt(3))); + + if (mozilla::BinarySearchIf(ROOT_TABLE, 0, ArrayLength(ROOT_TABLE), + BinaryHashSearchArrayComparator( + digestArray.Elements(), digestArray.Length()), + &idx)) { + MOZ_LOG(gPublicKeyPinningTelemetryLog, LogLevel::Debug, + ("pkpinTelem: Telemetry index was %zu, bin is %d\n", idx, + ROOT_TABLE[idx].binNumber)); + return (int32_t)ROOT_TABLE[idx].binNumber; + } + + // Didn't find this certificate in the built-in list. It may be an enterprise + // root (gathered from the OS) or it may be from the softoken or an external + // PKCS#11 token. + nsCOMPtr component(do_GetService(PSM_COMPONENT_CONTRACTID)); + if (!component) { + return ROOT_CERTIFICATE_UNKNOWN; + } + nsTArray> enterpriseRoots; + rv = component->GetEnterpriseRoots(enterpriseRoots); + if (NS_FAILED(rv)) { + return ROOT_CERTIFICATE_UNKNOWN; + } + for (const auto& enterpriseRoot : enterpriseRoots) { + if (enterpriseRoot.Length() == cert.size() && + memcmp(enterpriseRoot.Elements(), cert.data(), + enterpriseRoot.Length()) == 0) { + return ROOT_CERTIFICATE_ENTERPRISE_ROOT; + } + } + + SECItem certItem = {siBuffer, const_cast(cert.data()), + static_cast(cert.size())}; + UniquePK11SlotInfo softokenSlot(PK11_GetInternalKeySlot()); + if (!softokenSlot) { + return ROOT_CERTIFICATE_UNKNOWN; + } + CK_OBJECT_HANDLE softokenCertHandle = + PK11_FindEncodedCertInSlot(softokenSlot.get(), &certItem, nullptr); + if (softokenCertHandle != CK_INVALID_HANDLE) { + return ROOT_CERTIFICATE_SOFTOKEN; + } + // In theory this should never find the certificate in the root module, + // because then it should have already matched our built-in list. This is + // here as a backstop to catch situations where a built-in root was added but + // the built-in telemetry information was not updated. + UniqueSECMODModule rootsModule(SECMOD_FindModule(kRootModuleName)); + if (!rootsModule || rootsModule->slotCount != 1) { + return ROOT_CERTIFICATE_UNKNOWN; + } + CK_OBJECT_HANDLE builtinCertHandle = + PK11_FindEncodedCertInSlot(rootsModule->slots[0], &certItem, nullptr); + if (builtinCertHandle == CK_INVALID_HANDLE) { + return ROOT_CERTIFICATE_EXTERNAL_TOKEN; + } + + // We have no idea what this is. + return ROOT_CERTIFICATE_UNKNOWN; +} + +// Attempt to increment the appropriate bin in the provided Telemetry probe ID. +// If there was a hash failure, we do nothing. +void AccumulateTelemetryForRootCA(mozilla::Telemetry::HistogramID probe, + const Span cert) { + int32_t binId = RootCABinNumber(cert); + + if (binId != ROOT_CERTIFICATE_HASH_FAILURE) { + Accumulate(probe, binId); + } +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/RootCertificateTelemetryUtils.h b/security/manager/ssl/RootCertificateTelemetryUtils.h new file mode 100644 index 0000000000..01d033ec59 --- /dev/null +++ b/security/manager/ssl/RootCertificateTelemetryUtils.h @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef RootCertificateTelemetryUtils_h +#define RootCertificateTelemetryUtils_h + +#include "mozilla/Span.h" +#include "mozilla/Telemetry.h" + +namespace mozilla { +namespace psm { + +// Note: New CAs will show up as UNKNOWN_ROOT until +// RootHashes.inc is updated to include them. 0 is reserved by +// genRootCAHashes.js for the unknowns. +#define ROOT_CERTIFICATE_UNKNOWN 0 +// 1 indicates the CA is not a built-in and comes from the softoken (cert9.db) +#define ROOT_CERTIFICATE_SOFTOKEN 1 +// 2 indicates the CA is not a bilt-in and comes from an external PKCS#11 token +#define ROOT_CERTIFICATE_EXTERNAL_TOKEN 2 +// 3 indicates the CA is not a built-in and comes from the OS via the +// "Enterprise Roots" feature +#define ROOT_CERTIFICATE_ENTERPRISE_ROOT 3 +#define ROOT_CERTIFICATE_HASH_FAILURE -1 + +int32_t RootCABinNumber(Span cert); + +void AccumulateTelemetryForRootCA(mozilla::Telemetry::HistogramID probe, + const Span cert); + +} // namespace psm +} // namespace mozilla + +#endif // RootCertificateTelemetryUtils_h diff --git a/security/manager/ssl/RootHashes.inc b/security/manager/ssl/RootHashes.inc new file mode 100644 index 0000000000..b97aece8dd --- /dev/null +++ b/security/manager/ssl/RootHashes.inc @@ -0,0 +1,1315 @@ +/* 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/. */ + +/*****************************************************************************/ +/* This is an automatically generated file. If you're not */ +/* RootCertificateTelemetryUtils.cpp, you shouldn't be #including it. */ +/*****************************************************************************/ + +#define HASH_LEN 32 +struct CertAuthorityHash { + // See bug 1338873 about making these fields const. + uint8_t hash[HASH_LEN]; + int32_t binNumber; +}; + +static const struct CertAuthorityHash ROOT_TABLE[] = { + { + /* Entrust_Root_Certification_Authority___EC1 */ + { 0x02, 0xED, 0x0E, 0xB2, 0x8C, 0x14, 0xDA, 0x45, 0x16, 0x5C, 0x56, 0x67, 0x91, 0x70, 0x0D, 0x64, + 0x51, 0xD7, 0xFB, 0x56, 0xF0, 0xB2, 0xAB, 0x1D, 0x3B, 0x8E, 0xB0, 0x70, 0xE5, 0x6E, 0xDF, 0xF5 }, + 164 /* Bin Number */ + }, + { + /* AffirmTrust_Commercial */ + { 0x03, 0x76, 0xAB, 0x1D, 0x54, 0xC5, 0xF9, 0x80, 0x3C, 0xE4, 0xB2, 0xE2, 0x01, 0xA0, 0xEE, 0x7E, + 0xEF, 0x7B, 0x57, 0xB6, 0x36, 0xE8, 0xA9, 0x3C, 0x9B, 0x8D, 0x48, 0x60, 0xC9, 0x6F, 0x5F, 0xA7 }, + 109 /* Bin Number */ + }, + { + /* ACEDICOM_Root */ + { 0x03, 0x95, 0x0F, 0xB4, 0x9A, 0x53, 0x1F, 0x3E, 0x19, 0x91, 0x94, 0x23, 0x98, 0xDF, 0xA9, 0xE0, + 0xEA, 0x32, 0xD7, 0xBA, 0x1C, 0xDD, 0x9B, 0xC8, 0x5D, 0xB5, 0x7E, 0xD9, 0x40, 0x0B, 0x43, 0x4A }, + 98 /* Bin Number */ + }, + { + /* Autoridad_de_Certificacion_Firmaprofesional_CIF_A62634068 */ + { 0x04, 0x04, 0x80, 0x28, 0xBF, 0x1F, 0x28, 0x64, 0xD4, 0x8F, 0x9A, 0xD4, 0xD8, 0x32, 0x94, 0x36, + 0x6A, 0x82, 0x88, 0x56, 0x55, 0x3F, 0x3B, 0x14, 0x30, 0x3F, 0x90, 0x14, 0x7F, 0x5D, 0x40, 0xEF }, + 102 /* Bin Number */ + }, + { + /* Chambers_of_Commerce_Root___2008 */ + { 0x06, 0x3E, 0x4A, 0xFA, 0xC4, 0x91, 0xDF, 0xD3, 0x32, 0xF3, 0x08, 0x9B, 0x85, 0x42, 0xE9, 0x46, + 0x17, 0xD8, 0x93, 0xD7, 0xFE, 0x94, 0x4E, 0x10, 0xA7, 0x93, 0x7E, 0xE2, 0x9D, 0x96, 0x93, 0xC0 }, + 104 /* Bin Number */ + }, + { + /* DST_Root_CA_X3 */ + { 0x06, 0x87, 0x26, 0x03, 0x31, 0xA7, 0x24, 0x03, 0xD9, 0x09, 0xF1, 0x05, 0xE6, 0x9B, 0xCF, 0x0D, + 0x32, 0xE1, 0xBD, 0x24, 0x93, 0xFF, 0xC6, 0xD9, 0x20, 0x6D, 0x11, 0xBC, 0xD6, 0x77, 0x07, 0x39 }, + 52 /* Bin Number */ + }, + { + /* TrustCor_RootCert_CA_2 */ + { 0x07, 0x53, 0xE9, 0x40, 0x37, 0x8C, 0x1B, 0xD5, 0xE3, 0x83, 0x6E, 0x39, 0x5D, 0xAE, 0xA5, 0xCB, + 0x83, 0x9E, 0x50, 0x46, 0xF1, 0xBD, 0x0E, 0xAE, 0x19, 0x51, 0xCF, 0x10, 0xFE, 0xC7, 0xC9, 0x65 }, + 191 /* Bin Number */ + }, + { + /* AddTrust_Public_CA_Root */ + { 0x07, 0x91, 0xCA, 0x07, 0x49, 0xB2, 0x07, 0x82, 0xAA, 0xD3, 0xC7, 0xD7, 0xBD, 0x0C, 0xDF, 0xC9, + 0x48, 0x58, 0x35, 0x84, 0x3E, 0xB2, 0xD7, 0x99, 0x60, 0x09, 0xCE, 0x43, 0xAB, 0x6C, 0x69, 0x27 }, + 16 /* Bin Number */ + }, + { + /* OU_Equifax_Secure_Certificate_Authority_O_Equifax_C_US */ + { 0x08, 0x29, 0x7A, 0x40, 0x47, 0xDB, 0xA2, 0x36, 0x80, 0xC7, 0x31, 0xDB, 0x6E, 0x31, 0x76, 0x53, + 0xCA, 0x78, 0x48, 0xE1, 0xBE, 0xBD, 0x3A, 0x0B, 0x01, 0x79, 0xA7, 0x07, 0xF9, 0x2C, 0xF1, 0x78 }, + 4 /* Bin Number */ + }, + { + /* AffirmTrust_Networking */ + { 0x0A, 0x81, 0xEC, 0x5A, 0x92, 0x97, 0x77, 0xF1, 0x45, 0x90, 0x4A, 0xF3, 0x8D, 0x5D, 0x50, 0x9F, + 0x66, 0xB5, 0xE2, 0xC5, 0x8F, 0xCD, 0xB5, 0x31, 0x05, 0x8B, 0x0E, 0x17, 0xF3, 0xF0, 0xB4, 0x1B }, + 110 /* Bin Number */ + }, + { + /* Chambers_of_Commerce_Root */ + { 0x0C, 0x25, 0x8A, 0x12, 0xA5, 0x67, 0x4A, 0xEF, 0x25, 0xF2, 0x8B, 0xA7, 0xDC, 0xFA, 0xEC, 0xEE, + 0xA3, 0x48, 0xE5, 0x41, 0xE6, 0xF5, 0xCC, 0x4E, 0xE6, 0x3B, 0x71, 0xB3, 0x61, 0x60, 0x6A, 0xC3 }, + 39 /* Bin Number */ + }, + { + /* COMODO_Certification_Authority */ + { 0x0C, 0x2C, 0xD6, 0x3D, 0xF7, 0x80, 0x6F, 0xA3, 0x99, 0xED, 0xE8, 0x09, 0x11, 0x6B, 0x57, 0x5B, + 0xF8, 0x79, 0x89, 0xF0, 0x65, 0x18, 0xF9, 0x80, 0x8C, 0x86, 0x05, 0x03, 0x17, 0x8B, 0xAF, 0x66 }, + 63 /* Bin Number */ + }, + { + /* Buypass_Class_2_CA_1 */ + { 0x0F, 0x4E, 0x9C, 0xDD, 0x26, 0x4B, 0x02, 0x55, 0x50, 0xD1, 0x70, 0x80, 0x63, 0x40, 0x21, 0x4F, + 0xE9, 0x44, 0x34, 0xC9, 0xB0, 0x2F, 0x69, 0x7E, 0xC7, 0x10, 0xFC, 0x5F, 0xEA, 0xFB, 0x5E, 0x38 }, + 80 /* Bin Number */ + }, + { + /* Class_2_Primary_CA */ + { 0x0F, 0x99, 0x3C, 0x8A, 0xEF, 0x97, 0xBA, 0xAF, 0x56, 0x87, 0x14, 0x0E, 0xD5, 0x9A, 0xD1, 0x82, + 0x1B, 0xB4, 0xAF, 0xAC, 0xF0, 0xAA, 0x9A, 0x58, 0xB5, 0xD5, 0x7A, 0x33, 0x8A, 0x3A, 0xFB, 0xCB }, + 51 /* Bin Number */ + }, + { + /* emSign_Root_CA___C1 */ + { 0x12, 0x56, 0x09, 0xAA, 0x30, 0x1D, 0xA0, 0xA2, 0x49, 0xB9, 0x7A, 0x82, 0x39, 0xCB, 0x6A, 0x34, + 0x21, 0x6F, 0x44, 0xDC, 0xAC, 0x9F, 0x39, 0x54, 0xB1, 0x42, 0x92, 0xF2, 0xE8, 0xC8, 0x60, 0x8F }, + 208 /* Bin Number */ + }, + { + /* Global_Chambersign_Root___2008 */ + { 0x13, 0x63, 0x35, 0x43, 0x93, 0x34, 0xA7, 0x69, 0x80, 0x16, 0xA0, 0xD3, 0x24, 0xDE, 0x72, 0x28, + 0x4E, 0x07, 0x9D, 0x7B, 0x52, 0x20, 0xBB, 0x8F, 0xBD, 0x74, 0x78, 0x16, 0xEE, 0xBE, 0xBA, 0xCA }, + 105 /* Bin Number */ + }, + { + /* OU_Starfield_Class_2_Certification_Authority_O__Starfield_Technologies__Inc___C_US */ + { 0x14, 0x65, 0xFA, 0x20, 0x53, 0x97, 0xB8, 0x76, 0xFA, 0xA6, 0xF0, 0xA9, 0x95, 0x8E, 0x55, 0x90, + 0xE4, 0x0F, 0xCC, 0x7F, 0xAA, 0x4F, 0xB7, 0xC2, 0xC8, 0x67, 0x75, 0x21, 0xFB, 0x5F, 0xB6, 0x58 }, + 44 /* Bin Number */ + }, + { + /* Certplus_Root_CA_G1 */ + { 0x15, 0x2A, 0x40, 0x2B, 0xFC, 0xDF, 0x2C, 0xD5, 0x48, 0x05, 0x4D, 0x22, 0x75, 0xB3, 0x9C, 0x7F, + 0xCA, 0x3E, 0xC0, 0x97, 0x80, 0x78, 0xB0, 0xF0, 0xEA, 0x76, 0xE5, 0x61, 0xA6, 0xC7, 0x43, 0x3E }, + 176 /* Bin Number */ + }, + { + /* GTS_Root_R3 */ + { 0x15, 0xD5, 0xB8, 0x77, 0x46, 0x19, 0xEA, 0x7D, 0x54, 0xCE, 0x1C, 0xA6, 0xD0, 0xB0, 0xC4, 0x03, + 0xE0, 0x37, 0xA9, 0x17, 0xF1, 0x31, 0xE8, 0xA0, 0x4E, 0x1E, 0x6B, 0x7A, 0x71, 0xBA, 0xBC, 0xE5 }, + 201 /* Bin Number */ + }, + { + /* Network_Solutions_Certificate_Authority */ + { 0x15, 0xF0, 0xBA, 0x00, 0xA3, 0xAC, 0x7A, 0xF3, 0xAC, 0x88, 0x4C, 0x07, 0x2B, 0x10, 0x11, 0xA0, + 0x77, 0xBD, 0x77, 0xC0, 0x97, 0xF4, 0x01, 0x64, 0xB2, 0xF8, 0x59, 0x8A, 0xBD, 0x83, 0x86, 0x0C }, + 64 /* Bin Number */ + }, + { + /* Baltimore_CyberTrust_Root */ + { 0x16, 0xAF, 0x57, 0xA9, 0xF6, 0x76, 0xB0, 0xAB, 0x12, 0x60, 0x95, 0xAA, 0x5E, 0xBA, 0xDE, 0xF2, + 0x2A, 0xB3, 0x11, 0x19, 0xD6, 0x44, 0xAC, 0x95, 0xCD, 0x4B, 0x93, 0xDB, 0xF3, 0xF2, 0x6A, 0xEB }, + 11 /* Bin Number */ + }, + { + /* COMODO_ECC_Certification_Authority */ + { 0x17, 0x93, 0x92, 0x7A, 0x06, 0x14, 0x54, 0x97, 0x89, 0xAD, 0xCE, 0x2F, 0x8F, 0x34, 0xF7, 0xF0, + 0xB6, 0x6D, 0x0F, 0x3A, 0xE3, 0xA3, 0xB8, 0x4D, 0x21, 0xEC, 0x15, 0xDB, 0xBA, 0x4F, 0xAD, 0xC7 }, + 66 /* Bin Number */ + }, + { + /* GlobalSign */ + { 0x17, 0x9F, 0xBC, 0x14, 0x8A, 0x3D, 0xD0, 0x0F, 0xD2, 0x4E, 0xA1, 0x34, 0x58, 0xCC, 0x43, 0xBF, + 0xA7, 0xF5, 0x9C, 0x81, 0x82, 0xD7, 0x83, 0xA5, 0x13, 0xF6, 0xEB, 0xEC, 0x10, 0x0C, 0x89, 0x24 }, + 158 /* Bin Number */ + }, + { + /* Amazon_Root_CA_3 */ + { 0x18, 0xCE, 0x6C, 0xFE, 0x7B, 0xF1, 0x4E, 0x60, 0xB2, 0xE3, 0x47, 0xB8, 0xDF, 0xE8, 0x68, 0xCB, + 0x31, 0xD0, 0x2E, 0xBB, 0x3A, 0xDA, 0x27, 0x15, 0x69, 0xF5, 0x03, 0x43, 0xB4, 0x6D, 0xB3, 0xA4 }, + 185 /* Bin Number */ + }, + { + /* QuoVadis_Root_CA_3 */ + { 0x18, 0xF1, 0xFC, 0x7F, 0x20, 0x5D, 0xF8, 0xAD, 0xDD, 0xEB, 0x7F, 0xE0, 0x07, 0xDD, 0x57, 0xE3, + 0xAF, 0x37, 0x5A, 0x9C, 0x4D, 0x8D, 0x73, 0x54, 0x6B, 0xF4, 0xF1, 0xFE, 0xD1, 0xE1, 0x8D, 0x35 }, + 33 /* Bin Number */ + }, + { + /* Amazon_Root_CA_2 */ + { 0x1B, 0xA5, 0xB2, 0xAA, 0x8C, 0x65, 0x40, 0x1A, 0x82, 0x96, 0x01, 0x18, 0xF8, 0x0B, 0xEC, 0x4F, + 0x62, 0x30, 0x4D, 0x83, 0xCE, 0xC4, 0x71, 0x3A, 0x19, 0xC3, 0x9C, 0x01, 0x1E, 0xA4, 0x6D, 0xB4 }, + 184 /* Bin Number */ + }, + { + /* China_Internet_Network_Information_Center_EV_Certificates_Root */ + { 0x1C, 0x01, 0xC6, 0xF4, 0xDB, 0xB2, 0xFE, 0xFC, 0x22, 0x55, 0x8B, 0x2B, 0xCA, 0x32, 0x56, 0x3F, + 0x49, 0x84, 0x4A, 0xCF, 0xC3, 0x2B, 0x7B, 0xE4, 0xB0, 0xFF, 0x59, 0x9F, 0x9E, 0x8C, 0x7A, 0xF7 }, + 133 /* Bin Number */ + }, + { + /* Swisscom_Root_CA_1 */ + { 0x21, 0xDB, 0x20, 0x12, 0x36, 0x60, 0xBB, 0x2E, 0xD4, 0x18, 0x20, 0x5D, 0xA1, 0x1E, 0xE7, 0xA8, + 0x5A, 0x65, 0xE2, 0xBC, 0x6E, 0x55, 0xB5, 0xAF, 0x7E, 0x78, 0x99, 0xC8, 0xA2, 0x66, 0xD9, 0x2E }, + 47 /* Bin Number */ + }, + { + /* SSL_com_EV_Root_Certification_Authority_ECC */ + { 0x22, 0xA2, 0xC1, 0xF7, 0xBD, 0xED, 0x70, 0x4C, 0xC1, 0xE7, 0x01, 0xB5, 0xF4, 0x08, 0xC3, 0x10, + 0x88, 0x0F, 0xE9, 0x56, 0xB5, 0xDE, 0x2A, 0x4A, 0x44, 0xF9, 0x9C, 0x87, 0x3A, 0x25, 0xA7, 0xC8 }, + 196 /* Bin Number */ + }, + { + /* VeriSign_Universal_Root_Certification_Authority */ + { 0x23, 0x99, 0x56, 0x11, 0x27, 0xA5, 0x71, 0x25, 0xDE, 0x8C, 0xEF, 0xEA, 0x61, 0x0D, 0xDF, 0x2F, + 0xA0, 0x78, 0xB5, 0xC8, 0x06, 0x7F, 0x4E, 0x82, 0x82, 0x90, 0xBF, 0xB8, 0x60, 0xE8, 0x4B, 0x3C }, + 90 /* Bin Number */ + }, + { + /* Izenpe_com */ + { 0x25, 0x30, 0xCC, 0x8E, 0x98, 0x32, 0x15, 0x02, 0xBA, 0xD9, 0x6F, 0x9B, 0x1F, 0xBA, 0x1B, 0x09, + 0x9E, 0x2D, 0x29, 0x9E, 0x0F, 0x45, 0x48, 0xBB, 0x91, 0x4F, 0x36, 0x3B, 0xC0, 0xD4, 0x53, 0x1F }, + 103 /* Bin Number */ + }, + { + /* OpenTrust_Root_CA_G2 */ + { 0x27, 0x99, 0x58, 0x29, 0xFE, 0x6A, 0x75, 0x15, 0xC1, 0xBF, 0xE8, 0x48, 0xF9, 0xC4, 0x76, 0x1D, + 0xB1, 0x6C, 0x22, 0x59, 0x29, 0x25, 0x7B, 0xF4, 0x0D, 0x08, 0x94, 0xF2, 0x9E, 0xA8, 0xBA, 0xF2 }, + 179 /* Bin Number */ + }, + { + /* GTS_Root_R1 */ + { 0x2A, 0x57, 0x54, 0x71, 0xE3, 0x13, 0x40, 0xBC, 0x21, 0x58, 0x1C, 0xBD, 0x2C, 0xF1, 0x3E, 0x15, + 0x84, 0x63, 0x20, 0x3E, 0xCE, 0x94, 0xBC, 0xF9, 0xD3, 0xCC, 0x19, 0x6B, 0xF0, 0x9A, 0x54, 0x72 }, + 199 /* Bin Number */ + }, + { + /* Certinomis___Root_CA */ + { 0x2A, 0x99, 0xF5, 0xBC, 0x11, 0x74, 0xB7, 0x3C, 0xBB, 0x1D, 0x62, 0x08, 0x84, 0xE0, 0x1C, 0x34, + 0xE5, 0x1C, 0xCB, 0x39, 0x78, 0xDA, 0x12, 0x5F, 0x0E, 0x33, 0x26, 0x88, 0x83, 0xBF, 0x41, 0x58 }, + 168 /* Bin Number */ + }, + { + /* GlobalSign */ + { 0x2C, 0xAB, 0xEA, 0xFE, 0x37, 0xD0, 0x6C, 0xA2, 0x2A, 0xBA, 0x73, 0x91, 0xC0, 0x03, 0x3D, 0x25, + 0x98, 0x29, 0x52, 0xC4, 0x53, 0x64, 0x73, 0x49, 0x76, 0x3A, 0x3A, 0xB5, 0xAD, 0x6C, 0xCF, 0x69 }, + 197 /* Bin Number */ + }, + { + /* Starfield_Root_Certificate_Authority___G2 */ + { 0x2C, 0xE1, 0xCB, 0x0B, 0xF9, 0xD2, 0xF9, 0xE1, 0x02, 0x99, 0x3F, 0xBE, 0x21, 0x51, 0x52, 0xC3, + 0xB2, 0xDD, 0x0C, 0xAB, 0xDE, 0x1C, 0x68, 0xE5, 0x31, 0x9B, 0x83, 0x91, 0x54, 0xDB, 0xB7, 0xF5 }, + 107 /* Bin Number */ + }, + { + /* OU_ApplicationCA_O_Japanese_Government_C_JP */ + { 0x2D, 0x47, 0x43, 0x7D, 0xE1, 0x79, 0x51, 0x21, 0x5A, 0x12, 0xF3, 0xC5, 0x8E, 0x51, 0xC7, 0x29, + 0xA5, 0x80, 0x26, 0xEF, 0x1F, 0xCC, 0x0A, 0x5F, 0xB3, 0xD9, 0xDC, 0x01, 0x2F, 0x60, 0x0D, 0x19 }, + 85 /* Bin Number */ + }, + { + /* SSL_com_EV_Root_Certification_Authority_RSA_R2 */ + { 0x2E, 0x7B, 0xF1, 0x6C, 0xC2, 0x24, 0x85, 0xA7, 0xBB, 0xE2, 0xAA, 0x86, 0x96, 0x75, 0x07, 0x61, + 0xB0, 0xAE, 0x39, 0xBE, 0x3B, 0x2F, 0xE9, 0xD0, 0xCC, 0x6D, 0x4E, 0xF7, 0x34, 0x91, 0x42, 0x5C }, + 195 /* Bin Number */ + }, + { + /* IdenTrust_Public_Sector_Root_CA_1 */ + { 0x30, 0xD0, 0x89, 0x5A, 0x9A, 0x44, 0x8A, 0x26, 0x20, 0x91, 0x63, 0x55, 0x22, 0xD1, 0xF5, 0x20, + 0x10, 0xB5, 0x86, 0x7A, 0xCA, 0xE1, 0x2C, 0x78, 0xEF, 0x95, 0x8F, 0xD4, 0xF4, 0x38, 0x9F, 0x2F }, + 162 /* Bin Number */ + }, + { + /* DigiCert_Global_Root_G3 */ + { 0x31, 0xAD, 0x66, 0x48, 0xF8, 0x10, 0x41, 0x38, 0xC7, 0x38, 0xF3, 0x9E, 0xA4, 0x32, 0x01, 0x33, + 0x39, 0x3E, 0x3A, 0x18, 0xCC, 0x02, 0x29, 0x6E, 0xF9, 0x7C, 0x2A, 0xC9, 0xEF, 0x67, 0x31, 0xD0 }, + 150 /* Bin Number */ + }, + { + /* Microsec_e_Szigno_Root_CA */ + { 0x32, 0x7A, 0x3D, 0x76, 0x1A, 0xBA, 0xDE, 0xA0, 0x34, 0xEB, 0x99, 0x84, 0x06, 0x27, 0x5C, 0xB1, + 0xA4, 0x77, 0x6E, 0xFD, 0xAE, 0x2F, 0xDF, 0x6D, 0x01, 0x68, 0xEA, 0x1C, 0x4F, 0x55, 0x67, 0xD0 }, + 70 /* Bin Number */ + }, + { + /* SSL_com_Root_Certification_Authority_ECC */ + { 0x34, 0x17, 0xBB, 0x06, 0xCC, 0x60, 0x07, 0xDA, 0x1B, 0x96, 0x1C, 0x92, 0x0B, 0x8A, 0xB4, 0xCE, + 0x3F, 0xAD, 0x82, 0x0E, 0x4A, 0xA3, 0x0B, 0x9A, 0xCB, 0xC4, 0xA7, 0x4E, 0xBD, 0xCE, 0xBC, 0x65 }, + 194 /* Bin Number */ + }, + { + /* Microsoft_ECC_Root_Certificate_Authority_2017 */ + { 0x35, 0x8D, 0xF3, 0x9D, 0x76, 0x4A, 0xF9, 0xE1, 0xB7, 0x66, 0xE9, 0xC9, 0x72, 0xDF, 0x35, 0x2E, + 0xE1, 0x5C, 0xFA, 0xC2, 0x27, 0xAF, 0x6A, 0xD1, 0xD7, 0x0E, 0x8E, 0x4A, 0x6E, 0xDC, 0xBA, 0x02 }, + 212 /* Bin Number */ + }, + { + /* EBG_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_ */ + { 0x35, 0xAE, 0x5B, 0xDD, 0xD8, 0xF7, 0xAE, 0x63, 0x5C, 0xFF, 0xBA, 0x56, 0x82, 0xA8, 0xF0, 0x0B, + 0x95, 0xF4, 0x84, 0x62, 0xC7, 0x10, 0x8E, 0xE9, 0xA0, 0xE5, 0x29, 0x2B, 0x07, 0x4A, 0xAF, 0xB2 }, + 82 /* Bin Number */ + }, + { + /* GeoTrust_Primary_Certification_Authority */ + { 0x37, 0xD5, 0x10, 0x06, 0xC5, 0x12, 0xEA, 0xAB, 0x62, 0x64, 0x21, 0xF1, 0xEC, 0x8C, 0x92, 0x01, + 0x3F, 0xC5, 0xF8, 0x2A, 0xE9, 0x8E, 0xE5, 0x33, 0xEB, 0x46, 0x19, 0xB8, 0xDE, 0xB4, 0xD0, 0x6C }, + 58 /* Bin Number */ + }, + { + /* Staat_der_Nederlanden_Root_CA___G3 */ + { 0x3C, 0x4F, 0xB0, 0xB9, 0x5A, 0xB8, 0xB3, 0x00, 0x32, 0xF4, 0x32, 0xB8, 0x6F, 0x53, 0x5F, 0xE1, + 0x72, 0xC1, 0x85, 0xD0, 0xFD, 0x39, 0x86, 0x58, 0x37, 0xCF, 0x36, 0x18, 0x7F, 0xA6, 0xF4, 0x28 }, + 159 /* Bin Number */ + }, + { + /* Microsec_e_Szigno_Root_CA_2009 */ + { 0x3C, 0x5F, 0x81, 0xFE, 0xA5, 0xFA, 0xB8, 0x2C, 0x64, 0xBF, 0xA2, 0xEA, 0xEC, 0xAF, 0xCD, 0xE8, + 0xE0, 0x77, 0xFC, 0x86, 0x20, 0xA7, 0xCA, 0xE5, 0x37, 0x16, 0x3D, 0xF3, 0x6E, 0xDB, 0xF3, 0x78 }, + 99 /* Bin Number */ + }, + { + /* PSCProcert */ + { 0x3C, 0xFC, 0x3C, 0x14, 0xD1, 0xF6, 0x84, 0xFF, 0x17, 0xE3, 0x8C, 0x43, 0xCA, 0x44, 0x0C, 0x00, + 0xB9, 0x67, 0xEC, 0x93, 0x3E, 0x8B, 0xFE, 0x06, 0x4C, 0xA1, 0xD7, 0x2C, 0x90, 0xF2, 0xAD, 0xB0 }, + 132 /* Bin Number */ + }, + { + /* EE_Certification_Centre_Root_CA */ + { 0x3E, 0x84, 0xBA, 0x43, 0x42, 0x90, 0x85, 0x16, 0xE7, 0x75, 0x73, 0xC0, 0x99, 0x2F, 0x09, 0x79, + 0xCA, 0x08, 0x4E, 0x46, 0x85, 0x68, 0x1F, 0xF1, 0x95, 0xCC, 0xBA, 0x8A, 0x22, 0x9B, 0x8A, 0x76 }, + 128 /* Bin Number */ + }, + { + /* DigiCert_Assured_ID_Root_CA */ + { 0x3E, 0x90, 0x99, 0xB5, 0x01, 0x5E, 0x8F, 0x48, 0x6C, 0x00, 0xBC, 0xEA, 0x9D, 0x11, 0x1E, 0xE7, + 0x21, 0xFA, 0xBA, 0x35, 0x5A, 0x89, 0xBC, 0xF1, 0xDF, 0x69, 0x56, 0x1E, 0x3D, 0xC6, 0x32, 0x5C }, + 48 /* Bin Number */ + }, + { + /* Trusted_Certificate_Services */ + { 0x3F, 0x06, 0xE5, 0x56, 0x81, 0xD4, 0x96, 0xF5, 0xBE, 0x16, 0x9E, 0xB5, 0x38, 0x9F, 0x9F, 0x2B, + 0x8F, 0xF6, 0x1E, 0x17, 0x08, 0xDF, 0x68, 0x81, 0x72, 0x48, 0x49, 0xCD, 0x5D, 0x27, 0xCB, 0x69 }, + 30 /* Bin Number */ + }, + { + /* emSign_Root_CA___G1 */ + { 0x40, 0xF6, 0xAF, 0x03, 0x46, 0xA9, 0x9A, 0xA1, 0xCD, 0x1D, 0x55, 0x5A, 0x4E, 0x9C, 0xCE, 0x62, + 0xC7, 0xF9, 0x63, 0x46, 0x03, 0xEE, 0x40, 0x66, 0x15, 0x83, 0x3D, 0xC8, 0xC8, 0xD0, 0x03, 0x67 }, + 206 /* Bin Number */ + }, + { + /* OISTE_WISeKey_Global_Root_GA_CA */ + { 0x41, 0xC9, 0x23, 0x86, 0x6A, 0xB4, 0xCA, 0xD6, 0xB7, 0xAD, 0x57, 0x80, 0x81, 0x58, 0x2E, 0x02, + 0x07, 0x97, 0xA6, 0xCB, 0xDF, 0x4F, 0xFF, 0x78, 0xCE, 0x83, 0x96, 0xB3, 0x89, 0x37, 0xD7, 0xF5 }, + 69 /* Bin Number */ + }, + { + /* Secure_Global_CA */ + { 0x42, 0x00, 0xF5, 0x04, 0x3A, 0xC8, 0x59, 0x0E, 0xBB, 0x52, 0x7D, 0x20, 0x9E, 0xD1, 0x50, 0x30, + 0x29, 0xFB, 0xCB, 0xD4, 0x1C, 0xA1, 0xB5, 0x06, 0xEC, 0x27, 0xF1, 0x5A, 0xDE, 0x7D, 0xAC, 0x69 }, + 62 /* Bin Number */ + }, + { + /* DigiCert_Global_Root_CA */ + { 0x43, 0x48, 0xA0, 0xE9, 0x44, 0x4C, 0x78, 0xCB, 0x26, 0x5E, 0x05, 0x8D, 0x5E, 0x89, 0x44, 0xB4, + 0xD8, 0x4F, 0x96, 0x62, 0xBD, 0x26, 0xDB, 0x25, 0x7F, 0x89, 0x34, 0xA4, 0x43, 0xC7, 0x01, 0x61 }, + 49 /* Bin Number */ + }, + { + /* Entrust_Root_Certification_Authority___G2 */ + { 0x43, 0xDF, 0x57, 0x74, 0xB0, 0x3E, 0x7F, 0xEF, 0x5F, 0xE4, 0x0D, 0x93, 0x1A, 0x7B, 0xED, 0xF1, + 0xBB, 0x2E, 0x6B, 0x42, 0x73, 0x8C, 0x4E, 0x6D, 0x38, 0x41, 0x10, 0x3D, 0x3A, 0xA7, 0xF3, 0x39 }, + 163 /* Bin Number */ + }, + { + /* T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_ */ + { 0x44, 0x04, 0xE3, 0x3B, 0x5E, 0x14, 0x0D, 0xCF, 0x99, 0x80, 0x51, 0xFD, 0xFC, 0x80, 0x28, 0xC7, + 0xC8, 0x16, 0x15, 0xC5, 0xEE, 0x73, 0x7B, 0x11, 0x1B, 0x58, 0x82, 0x33, 0xA9, 0xB5, 0x35, 0xA0 }, + 54 /* Bin Number */ + }, + { + /* Hellenic_Academic_and_Research_Institutions_ECC_RootCA_2015 */ + { 0x44, 0xB5, 0x45, 0xAA, 0x8A, 0x25, 0xE6, 0x5A, 0x73, 0xCA, 0x15, 0xDC, 0x27, 0xFC, 0x36, 0xD2, + 0x4C, 0x1C, 0xB9, 0x95, 0x3A, 0x06, 0x65, 0x39, 0xB1, 0x15, 0x82, 0xDC, 0x48, 0x7B, 0x48, 0x33 }, + 175 /* Bin Number */ + }, + { + /* Go_Daddy_Root_Certificate_Authority___G2 */ + { 0x45, 0x14, 0x0B, 0x32, 0x47, 0xEB, 0x9C, 0xC8, 0xC5, 0xB4, 0xF0, 0xD7, 0xB5, 0x30, 0x91, 0xF7, + 0x32, 0x92, 0x08, 0x9E, 0x6E, 0x5A, 0x63, 0xE2, 0x74, 0x9D, 0xD3, 0xAC, 0xA9, 0x19, 0x8E, 0xDA }, + 106 /* Bin Number */ + }, + { + /* TUBITAK_Kamu_SM_SSL_Kok_Sertifikasi___Surum_1 */ + { 0x46, 0xED, 0xC3, 0x68, 0x90, 0x46, 0xD5, 0x3A, 0x45, 0x3F, 0xB3, 0x10, 0x4A, 0xB8, 0x0D, 0xCA, + 0xEC, 0x65, 0x8B, 0x26, 0x60, 0xEA, 0x16, 0x29, 0xDD, 0x7E, 0x86, 0x79, 0x90, 0x64, 0x87, 0x16 }, + 188 /* Bin Number */ + }, + { + /* T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s__H5 */ + { 0x49, 0x35, 0x1B, 0x90, 0x34, 0x44, 0xC1, 0x85, 0xCC, 0xDC, 0x5C, 0x69, 0x3D, 0x24, 0xD8, 0x55, + 0x5C, 0xB2, 0x08, 0xD6, 0xA8, 0x14, 0x13, 0x07, 0x69, 0x9F, 0x4A, 0xF0, 0x63, 0x19, 0x9D, 0x78 }, + 166 /* Bin Number */ + }, + { + /* D_TRUST_Root_Class_3_CA_2_2009 */ + { 0x49, 0xE7, 0xA4, 0x42, 0xAC, 0xF0, 0xEA, 0x62, 0x87, 0x05, 0x00, 0x54, 0xB5, 0x25, 0x64, 0xB6, + 0x50, 0xE4, 0xF4, 0x9E, 0x42, 0xE3, 0x48, 0xD6, 0xAA, 0x38, 0xE0, 0x39, 0xE9, 0x57, 0xB1, 0xC1 }, + 130 /* Bin Number */ + }, + { + /* thawte_Primary_Root_CA___G3 */ + { 0x4B, 0x03, 0xF4, 0x58, 0x07, 0xAD, 0x70, 0xF2, 0x1B, 0xFC, 0x2C, 0xAE, 0x71, 0xC9, 0xFD, 0xE4, + 0x60, 0x4C, 0x06, 0x4C, 0xF5, 0xFF, 0xB6, 0x86, 0xBA, 0xE5, 0xDB, 0xAA, 0xD7, 0xFD, 0xD3, 0x4C }, + 88 /* Bin Number */ + }, + { + /* Certification_Authority_of_WoSign */ + { 0x4B, 0x22, 0xD5, 0xA6, 0xAE, 0xC9, 0x9F, 0x3C, 0xDB, 0x79, 0xAA, 0x5E, 0xC0, 0x68, 0x38, 0x47, + 0x9C, 0xD5, 0xEC, 0xBA, 0x71, 0x64, 0xF7, 0xF2, 0x2D, 0xC1, 0xD6, 0x5F, 0x63, 0xD8, 0x57, 0x08 }, + 152 /* Bin Number */ + }, + { + /* Staat_der_Nederlanden_EV_Root_CA */ + { 0x4D, 0x24, 0x91, 0x41, 0x4C, 0xFE, 0x95, 0x67, 0x46, 0xEC, 0x4C, 0xEF, 0xA6, 0xCF, 0x6F, 0x72, + 0xE2, 0x8A, 0x13, 0x29, 0x43, 0x2F, 0x9D, 0x8A, 0x90, 0x7A, 0xC4, 0xCB, 0x5D, 0xAD, 0xC1, 0x5A }, + 160 /* Bin Number */ + }, + { + /* USERTrust_ECC_Certification_Authority */ + { 0x4F, 0xF4, 0x60, 0xD5, 0x4B, 0x9C, 0x86, 0xDA, 0xBF, 0xBC, 0xFC, 0x57, 0x12, 0xE0, 0x40, 0x0D, + 0x2B, 0xED, 0x3F, 0xBC, 0x4D, 0x4F, 0xBD, 0xAA, 0x86, 0xE0, 0x6A, 0xDC, 0xD2, 0xA9, 0xAD, 0x7A }, + 156 /* Bin Number */ + }, + { + /* ComSign_Secured_CA */ + { 0x50, 0x79, 0x41, 0xC7, 0x44, 0x60, 0xA0, 0xB4, 0x70, 0x86, 0x22, 0x0D, 0x4E, 0x99, 0x32, 0x57, + 0x2A, 0xB5, 0xD1, 0xB5, 0xBB, 0xCB, 0x89, 0x80, 0xAB, 0x1C, 0xB1, 0x76, 0x51, 0xA8, 0x44, 0xD2 }, + 76 /* Bin Number */ + }, + { + /* OU_Security_Communication_RootCA2_O__SECOM_Trust_Systems_CO__LTD___C_JP */ + { 0x51, 0x3B, 0x2C, 0xEC, 0xB8, 0x10, 0xD4, 0xCD, 0xE5, 0xDD, 0x85, 0x39, 0x1A, 0xDF, 0xC6, 0xC2, + 0xDD, 0x60, 0xD8, 0x7B, 0xB7, 0x36, 0xD2, 0xB5, 0x21, 0x48, 0x4A, 0xA4, 0x7A, 0x0E, 0xBE, 0xF6 }, + 118 /* Bin Number */ + }, + { + /* COMODO_RSA_Certification_Authority */ + { 0x52, 0xF0, 0xE1, 0xC4, 0xE5, 0x8E, 0xC6, 0x29, 0x29, 0x1B, 0x60, 0x31, 0x7F, 0x07, 0x46, 0x71, + 0xB8, 0x5D, 0x7E, 0xA8, 0x0D, 0x5B, 0x07, 0x27, 0x34, 0x63, 0x53, 0x4B, 0x32, 0xB4, 0x02, 0x34 }, + 154 /* Bin Number */ + }, + { + /* LuxTrust_Global_Root_2 */ + { 0x54, 0x45, 0x5F, 0x71, 0x29, 0xC2, 0x0B, 0x14, 0x47, 0xC4, 0x18, 0xF9, 0x97, 0x16, 0x8F, 0x24, + 0xC5, 0x8F, 0xC5, 0x02, 0x3B, 0xF5, 0xDA, 0x5B, 0xE2, 0xEB, 0x6E, 0x1D, 0xD8, 0x90, 0x2E, 0xD5 }, + 187 /* Bin Number */ + }, + { + /* DigiCert_Trusted_Root_G4 */ + { 0x55, 0x2F, 0x7B, 0xDC, 0xF1, 0xA7, 0xAF, 0x9E, 0x6C, 0xE6, 0x72, 0x01, 0x7F, 0x4F, 0x12, 0xAB, + 0xF7, 0x72, 0x40, 0xC7, 0x8E, 0x76, 0x1A, 0xC2, 0x03, 0xD1, 0xD9, 0xD2, 0x0A, 0xC8, 0x99, 0x88 }, + 151 /* Bin Number */ + }, + { + /* Trustwave_Global_ECC_P384_Certification_Authority */ + { 0x55, 0x90, 0x38, 0x59, 0xC8, 0xC0, 0xC3, 0xEB, 0xB8, 0x75, 0x9E, 0xCE, 0x4E, 0x25, 0x57, 0x22, + 0x5F, 0xF5, 0x75, 0x8B, 0xBD, 0x38, 0xEB, 0xD4, 0x82, 0x76, 0x60, 0x1E, 0x1B, 0xD5, 0x80, 0x97 }, + 218 /* Bin Number */ + }, + { + /* Actalis_Authentication_Root_CA */ + { 0x55, 0x92, 0x60, 0x84, 0xEC, 0x96, 0x3A, 0x64, 0xB9, 0x6E, 0x2A, 0xBE, 0x01, 0xCE, 0x0B, 0xA8, + 0x6A, 0x64, 0xFB, 0xFE, 0xBC, 0xC7, 0xAA, 0xB5, 0xAF, 0xC1, 0x55, 0xB3, 0x7F, 0xD7, 0x60, 0x66 }, + 121 /* Bin Number */ + }, + { + /* Starfield_Services_Root_Certificate_Authority___G2 */ + { 0x56, 0x8D, 0x69, 0x05, 0xA2, 0xC8, 0x87, 0x08, 0xA4, 0xB3, 0x02, 0x51, 0x90, 0xED, 0xCF, 0xED, + 0xB1, 0x97, 0x4A, 0x60, 0x6A, 0x13, 0xC6, 0xE5, 0x29, 0x0F, 0xCB, 0x2A, 0xE6, 0x3E, 0xDA, 0xB5 }, + 108 /* Bin Number */ + }, + { + /* OpenTrust_Root_CA_G1 */ + { 0x56, 0xC7, 0x71, 0x28, 0xD9, 0x8C, 0x18, 0xD9, 0x1B, 0x4C, 0xFD, 0xFF, 0xBC, 0x25, 0xEE, 0x91, + 0x03, 0xD4, 0x75, 0x8E, 0xA2, 0xAB, 0xAD, 0x82, 0x6A, 0x90, 0xF3, 0x45, 0x7D, 0x46, 0x0E, 0xB4 }, + 178 /* Bin Number */ + }, + { + /* TWCA_Global_Root_CA */ + { 0x59, 0x76, 0x90, 0x07, 0xF7, 0x68, 0x5D, 0x0F, 0xCD, 0x50, 0x87, 0x2F, 0x9F, 0x95, 0xD5, 0x75, + 0x5A, 0x5B, 0x2B, 0x45, 0x7D, 0x81, 0xF3, 0x69, 0x2B, 0x61, 0x0A, 0x98, 0x67, 0x2F, 0x0E, 0x1B }, + 139 /* Bin Number */ + }, + { + /* Hongkong_Post_Root_CA_3 */ + { 0x5A, 0x2F, 0xC0, 0x3F, 0x0C, 0x83, 0xB0, 0x90, 0xBB, 0xFA, 0x40, 0x60, 0x4B, 0x09, 0x88, 0x44, + 0x6C, 0x76, 0x36, 0x18, 0x3D, 0xF9, 0x84, 0x6E, 0x17, 0x10, 0x1A, 0x44, 0x7F, 0xB8, 0xEF, 0xD6 }, + 210 /* Bin Number */ + }, + { + /* TrustCor_ECA_1 */ + { 0x5A, 0x88, 0x5D, 0xB1, 0x9C, 0x01, 0xD9, 0x12, 0xC5, 0x75, 0x93, 0x88, 0x93, 0x8C, 0xAF, 0xBB, + 0xDF, 0x03, 0x1A, 0xB2, 0xD4, 0x8E, 0x91, 0xEE, 0x15, 0x58, 0x9B, 0x42, 0x97, 0x1D, 0x03, 0x9C }, + 192 /* Bin Number */ + }, + { + /* Certum_Trusted_Network_CA */ + { 0x5C, 0x58, 0x46, 0x8D, 0x55, 0xF5, 0x8E, 0x49, 0x7E, 0x74, 0x39, 0x82, 0xD2, 0xB5, 0x00, 0x10, + 0xB6, 0xD1, 0x65, 0x37, 0x4A, 0xCF, 0x83, 0xA7, 0xD4, 0xA3, 0x2D, 0xB7, 0x68, 0xC4, 0x40, 0x8E }, + 113 /* Bin Number */ + }, + { + /* CFCA_EV_ROOT */ + { 0x5C, 0xC3, 0xD7, 0x8E, 0x4E, 0x1D, 0x5E, 0x45, 0x54, 0x7A, 0x04, 0xE6, 0x87, 0x3E, 0x64, 0xF9, + 0x0C, 0xF9, 0x53, 0x6D, 0x1C, 0xCC, 0x2E, 0xF8, 0x00, 0xF3, 0x55, 0xC4, 0xC5, 0xFD, 0x70, 0xFD }, + 165 /* Bin Number */ + }, + { + /* IdenTrust_Commercial_Root_CA_1 */ + { 0x5D, 0x56, 0x49, 0x9B, 0xE4, 0xD2, 0xE0, 0x8B, 0xCF, 0xCA, 0xD0, 0x8A, 0x3E, 0x38, 0x72, 0x3D, + 0x50, 0x50, 0x3B, 0xDE, 0x70, 0x69, 0x48, 0xE4, 0x2F, 0x55, 0x60, 0x30, 0x19, 0xE5, 0x28, 0xAE }, + 161 /* Bin Number */ + }, + { + /* GeoTrust_Primary_Certification_Authority___G2 */ + { 0x5E, 0xDB, 0x7A, 0xC4, 0x3B, 0x82, 0xA0, 0x6A, 0x87, 0x61, 0xE8, 0xD7, 0xBE, 0x49, 0x79, 0xEB, + 0xF2, 0x61, 0x1F, 0x7D, 0xD7, 0x9B, 0xF9, 0x1C, 0x1C, 0x6B, 0x56, 0x6A, 0x21, 0x9E, 0xD7, 0x66 }, + 89 /* Bin Number */ + }, + { + /* Equifax_Secure_Global_eBusiness_CA_1 */ + { 0x5F, 0x0B, 0x62, 0xEA, 0xB5, 0xE3, 0x53, 0xEA, 0x65, 0x21, 0x65, 0x16, 0x58, 0xFB, 0xB6, 0x53, + 0x59, 0xF4, 0x43, 0x28, 0x0A, 0x4A, 0xFB, 0xD1, 0x04, 0xD7, 0x7D, 0x10, 0xF9, 0xF0, 0x4C, 0x07 }, + 12 /* Bin Number */ + }, + { + /* SwissSign_Gold_CA___G2 */ + { 0x62, 0xDD, 0x0B, 0xE9, 0xB9, 0xF5, 0x0A, 0x16, 0x3E, 0xA0, 0xF8, 0xE7, 0x5C, 0x05, 0x3B, 0x1E, + 0xCA, 0x57, 0xEA, 0x55, 0xC8, 0x68, 0x8F, 0x64, 0x7C, 0x68, 0x81, 0xF2, 0xC8, 0x35, 0x7B, 0x95 }, + 56 /* Bin Number */ + }, + { + /* OU_certSIGN_ROOT_CA_G2_O_CERTSIGN_SA_C_RO */ + { 0x65, 0x7C, 0xFE, 0x2F, 0xA7, 0x3F, 0xAA, 0x38, 0x46, 0x25, 0x71, 0xF3, 0x32, 0xA2, 0x36, 0x3A, + 0x46, 0xFC, 0xE7, 0x02, 0x09, 0x51, 0x71, 0x07, 0x02, 0xCD, 0xFB, 0xB6, 0xEE, 0xDA, 0x33, 0x05 }, + 215 /* Bin Number */ + }, + { + /* Staat_der_Nederlanden_Root_CA___G2 */ + { 0x66, 0x8C, 0x83, 0x94, 0x7D, 0xA6, 0x3B, 0x72, 0x4B, 0xEC, 0xE1, 0x74, 0x3C, 0x31, 0xA0, 0xE6, + 0xAE, 0xD0, 0xDB, 0x8E, 0xC5, 0xB3, 0x1B, 0xE3, 0x77, 0xBB, 0x78, 0x4F, 0x91, 0xB6, 0x71, 0x6F }, + 93 /* Bin Number */ + }, + { + /* AddTrust_External_CA_Root */ + { 0x68, 0x7F, 0xA4, 0x51, 0x38, 0x22, 0x78, 0xFF, 0xF0, 0xC8, 0xB1, 0x1F, 0x8D, 0x43, 0xD5, 0x76, + 0x67, 0x1C, 0x6E, 0xB2, 0xBC, 0xEA, 0xB4, 0x13, 0xFB, 0x83, 0xD9, 0x65, 0xD0, 0x6D, 0x2F, 0xF2 }, + 15 /* Bin Number */ + }, + { + /* VeriSign_Class_3_Public_Primary_Certification_Authority___G4 */ + { 0x69, 0xDD, 0xD7, 0xEA, 0x90, 0xBB, 0x57, 0xC9, 0x3E, 0x13, 0x5D, 0xC8, 0x5E, 0xA6, 0xFC, 0xD5, + 0x48, 0x0B, 0x60, 0x32, 0x39, 0xBD, 0xC4, 0x54, 0xFC, 0x75, 0x8B, 0x2A, 0x26, 0xCF, 0x7F, 0x79 }, + 91 /* Bin Number */ + }, + { + /* Visa_eCommerce_Root */ + { 0x69, 0xFA, 0xC9, 0xBD, 0x55, 0xFB, 0x0A, 0xC7, 0x8D, 0x53, 0xBB, 0xEE, 0x5C, 0xF1, 0xD5, 0x97, + 0x98, 0x9F, 0xD0, 0xAA, 0xAB, 0x20, 0xA2, 0x51, 0x51, 0xBD, 0xF1, 0x73, 0x3E, 0xE7, 0xD1, 0x22 }, + 26 /* Bin Number */ + }, + { + /* OISTE_WISeKey_Global_Root_GB_CA */ + { 0x6B, 0x9C, 0x08, 0xE8, 0x6E, 0xB0, 0xF7, 0x67, 0xCF, 0xAD, 0x65, 0xCD, 0x98, 0xB6, 0x21, 0x49, + 0xE5, 0x49, 0x4A, 0x67, 0xF5, 0x84, 0x5E, 0x7B, 0xD1, 0xED, 0x01, 0x9F, 0x27, 0xB8, 0x6B, 0xD6 }, + 169 /* Bin Number */ + }, + { + /* NetLock_Arany__Class_Gold__F_tan_s_tv_ny */ + { 0x6C, 0x61, 0xDA, 0xC3, 0xA2, 0xDE, 0xF0, 0x31, 0x50, 0x6B, 0xE0, 0x36, 0xD2, 0xA6, 0xFE, 0x40, + 0x19, 0x94, 0xFB, 0xD1, 0x3D, 0xF9, 0xC8, 0xD4, 0x66, 0x59, 0x92, 0x74, 0xC4, 0x46, 0xEC, 0x98 }, + 92 /* Bin Number */ + }, + { + /* Certplus_Root_CA_G2 */ + { 0x6C, 0xC0, 0x50, 0x41, 0xE6, 0x44, 0x5E, 0x74, 0x69, 0x6C, 0x4C, 0xFB, 0xC9, 0xF8, 0x0F, 0x54, + 0x3B, 0x7E, 0xAB, 0xBB, 0x44, 0xB4, 0xCE, 0x6F, 0x78, 0x7C, 0x6A, 0x99, 0x71, 0xC4, 0x2F, 0x17 }, + 177 /* Bin Number */ + }, + { + /* Entrust_net_Certification_Authority__2048_ */ + { 0x6D, 0xC4, 0x71, 0x72, 0xE0, 0x1C, 0xBC, 0xB0, 0xBF, 0x62, 0x58, 0x0D, 0x89, 0x5F, 0xE2, 0xB8, + 0xAC, 0x9A, 0xD4, 0xF8, 0x73, 0x80, 0x1E, 0x0C, 0x10, 0xB9, 0xC8, 0x37, 0xD2, 0x1E, 0xB1, 0x77 }, + 10 /* Bin Number */ + }, + { + /* UTN_USERFirst_Hardware */ + { 0x6E, 0xA5, 0x47, 0x41, 0xD0, 0x04, 0x66, 0x7E, 0xED, 0x1B, 0x48, 0x16, 0x63, 0x4A, 0xA3, 0xA7, + 0x9E, 0x6E, 0x4B, 0x96, 0x95, 0x0F, 0x82, 0x79, 0xDA, 0xFC, 0x8D, 0x9B, 0xD8, 0x81, 0x21, 0x37 }, + 38 /* Bin Number */ + }, + { + /* AffirmTrust_Premium */ + { 0x70, 0xA7, 0x3F, 0x7F, 0x37, 0x6B, 0x60, 0x07, 0x42, 0x48, 0x90, 0x45, 0x34, 0xB1, 0x14, 0x82, + 0xD5, 0xBF, 0x0E, 0x69, 0x8E, 0xCC, 0x49, 0x8D, 0xF5, 0x25, 0x77, 0xEB, 0xF2, 0xE9, 0x3B, 0x9A }, + 111 /* Bin Number */ + }, + { + /* GTS_Root_R4 */ + { 0x71, 0xCC, 0xA5, 0x39, 0x1F, 0x9E, 0x79, 0x4B, 0x04, 0x80, 0x25, 0x30, 0xB3, 0x63, 0xE1, 0x21, + 0xDA, 0x8A, 0x30, 0x43, 0xBB, 0x26, 0x66, 0x2F, 0xEA, 0x4D, 0xCA, 0x7F, 0xC9, 0x51, 0xA4, 0xBD }, + 202 /* Bin Number */ + }, + { + /* Entrust_Root_Certification_Authority */ + { 0x73, 0xC1, 0x76, 0x43, 0x4F, 0x1B, 0xC6, 0xD5, 0xAD, 0xF4, 0x5B, 0x0E, 0x76, 0xE7, 0x27, 0x28, + 0x7C, 0x8D, 0xE5, 0x76, 0x16, 0xC1, 0xE6, 0xE6, 0x14, 0x1A, 0x2B, 0x2C, 0xBC, 0x7D, 0x8E, 0x4C }, + 18 /* Bin Number */ + }, + { + /* DigiCert_High_Assurance_EV_Root_CA */ + { 0x74, 0x31, 0xE5, 0xF4, 0xC3, 0xC1, 0xCE, 0x46, 0x90, 0x77, 0x4F, 0x0B, 0x61, 0xE0, 0x54, 0x40, + 0x88, 0x3B, 0xA9, 0xA0, 0x1E, 0xD0, 0x0B, 0xA6, 0xAB, 0xD7, 0x80, 0x6E, 0xD3, 0xB1, 0x18, 0xCF }, + 50 /* Bin Number */ + }, + { + /* O_Government_Root_Certification_Authority_C_TW */ + { 0x76, 0x00, 0x29, 0x5E, 0xEF, 0xE8, 0x5B, 0x9E, 0x1F, 0xD6, 0x24, 0xDB, 0x76, 0x06, 0x2A, 0xAA, + 0xAE, 0x59, 0x81, 0x8A, 0x54, 0xD2, 0x77, 0x4C, 0xD4, 0xC0, 0xB2, 0xC0, 0x11, 0x31, 0xE1, 0xB3 }, + 46 /* Bin Number */ + }, + { + /* DST_ACES_CA_X6 */ + { 0x76, 0x7C, 0x95, 0x5A, 0x76, 0x41, 0x2C, 0x89, 0xAF, 0x68, 0x8E, 0x90, 0xA1, 0xC7, 0x0F, 0x55, + 0x6C, 0xFD, 0x6B, 0x60, 0x25, 0xDB, 0xEA, 0x10, 0x41, 0x6D, 0x7E, 0xB6, 0x83, 0x1F, 0x8C, 0x40 }, + 53 /* Bin Number */ + }, + { + /* America_Online_Root_Certification_Authority_1 */ + { 0x77, 0x40, 0x73, 0x12, 0xC6, 0x3A, 0x15, 0x3D, 0x5B, 0xC0, 0x0B, 0x4E, 0x51, 0x75, 0x9C, 0xDF, + 0xDA, 0xC2, 0x37, 0xDC, 0x2A, 0x33, 0xB6, 0x79, 0x46, 0xE9, 0x8E, 0x9B, 0xFA, 0x68, 0x0A, 0xE3 }, + 24 /* Bin Number */ + }, + { + /* Sonera_Class2_CA */ + { 0x79, 0x08, 0xB4, 0x03, 0x14, 0xC1, 0x38, 0x10, 0x0B, 0x51, 0x8D, 0x07, 0x35, 0x80, 0x7F, 0xFB, + 0xFC, 0xF8, 0x51, 0x8A, 0x00, 0x95, 0x33, 0x71, 0x05, 0xBA, 0x38, 0x6B, 0x15, 0x3D, 0xD9, 0x27 }, + 35 /* Bin Number */ + }, + { + /* A_Trust_nQual_03 */ + { 0x79, 0x3C, 0xBF, 0x45, 0x59, 0xB9, 0xFD, 0xE3, 0x8A, 0xB2, 0x2D, 0xF1, 0x68, 0x69, 0xF6, 0x98, + 0x81, 0xAE, 0x14, 0xC4, 0xB0, 0x13, 0x9A, 0xC7, 0x88, 0xA7, 0x8A, 0x1A, 0xFC, 0xCA, 0x02, 0xFB }, + 116 /* Bin Number */ + }, + { + /* DigiCert_Assured_ID_Root_G2 */ + { 0x7D, 0x05, 0xEB, 0xB6, 0x82, 0x33, 0x9F, 0x8C, 0x94, 0x51, 0xEE, 0x09, 0x4E, 0xEB, 0xFE, 0xFA, + 0x79, 0x53, 0xA1, 0x14, 0xED, 0xB2, 0xF4, 0x49, 0x49, 0x45, 0x2F, 0xAB, 0x7D, 0x2F, 0xC1, 0x85 }, + 147 /* Bin Number */ + }, + { + /* America_Online_Root_Certification_Authority_2 */ + { 0x7D, 0x3B, 0x46, 0x5A, 0x60, 0x14, 0xE5, 0x26, 0xC0, 0xAF, 0xFC, 0xEE, 0x21, 0x27, 0xD2, 0x31, + 0x17, 0x27, 0xAD, 0x81, 0x1C, 0x26, 0x84, 0x2D, 0x00, 0x6A, 0xF3, 0x73, 0x06, 0xCC, 0x80, 0xBD }, + 25 /* Bin Number */ + }, + { + /* DigiCert_Assured_ID_Root_G3 */ + { 0x7E, 0x37, 0xCB, 0x8B, 0x4C, 0x47, 0x09, 0x0C, 0xAB, 0x36, 0x55, 0x1B, 0xA6, 0xF4, 0x5D, 0xB8, + 0x40, 0x68, 0x0F, 0xBA, 0x16, 0x6A, 0x95, 0x2D, 0xB1, 0x00, 0x71, 0x7F, 0x43, 0x05, 0x3F, 0xC2 }, + 148 /* Bin Number */ + }, + { + /* NetLock_Kozjegyzoi__Class_A__Tanusitvanykiado */ + { 0x7F, 0x12, 0xCD, 0x5F, 0x7E, 0x5E, 0x29, 0x0E, 0xC7, 0xD8, 0x51, 0x79, 0xD5, 0xB7, 0x2C, 0x20, + 0xA5, 0xBE, 0x75, 0x08, 0xFF, 0xDB, 0x5B, 0xF8, 0x1A, 0xB9, 0x68, 0x4A, 0x7F, 0xC9, 0xF6, 0x67 }, + 41 /* Bin Number */ + }, + { + /* AddTrust_Qualified_CA_Root */ + { 0x80, 0x95, 0x21, 0x08, 0x05, 0xDB, 0x4B, 0xBC, 0x35, 0x5E, 0x44, 0x28, 0xD8, 0xFD, 0x6E, 0xC2, + 0xCD, 0xE3, 0xAB, 0x5F, 0xB9, 0x7A, 0x99, 0x42, 0x98, 0x8E, 0xB8, 0xF4, 0xDC, 0xD0, 0x60, 0x16 }, + 17 /* Bin Number */ + }, + { + /* OU_VeriSign_Trust_Network_OU___c__1998_VeriSign__Inc____For_authorized_use_only__OU_Class_3_Public_Primary_Certification_Authority___G2_O__VeriSign__Inc___C_US */ + { 0x83, 0xCE, 0x3C, 0x12, 0x29, 0x68, 0x8A, 0x59, 0x3D, 0x48, 0x5F, 0x81, 0x97, 0x3C, 0x0F, 0x91, + 0x95, 0x43, 0x1E, 0xDA, 0x37, 0xCC, 0x5E, 0x36, 0x43, 0x0E, 0x79, 0xC7, 0xA8, 0x88, 0x63, 0x8B }, + 5 /* Bin Number */ + }, + { + /* OISTE_WISeKey_Global_Root_GC_CA */ + { 0x85, 0x60, 0xF9, 0x1C, 0x36, 0x24, 0xDA, 0xBA, 0x95, 0x70, 0xB5, 0xFE, 0xA0, 0xDB, 0xE3, 0x6F, + 0xF1, 0x1A, 0x83, 0x23, 0xBE, 0x94, 0x86, 0x85, 0x4F, 0xB3, 0xF3, 0x4A, 0x55, 0x71, 0x19, 0x8D }, + 198 /* Bin Number */ + }, + { + /* SSL_com_Root_Certification_Authority_RSA */ + { 0x85, 0x66, 0x6A, 0x56, 0x2E, 0xE0, 0xBE, 0x5C, 0xE9, 0x25, 0xC1, 0xD8, 0x89, 0x0A, 0x6F, 0x76, + 0xA8, 0x7E, 0xC1, 0x6D, 0x4D, 0x7D, 0x5F, 0x29, 0xEA, 0x74, 0x19, 0xCF, 0x20, 0x12, 0x3B, 0x69 }, + 193 /* Bin Number */ + }, + { + /* QuoVadis_Root_CA_2 */ + { 0x85, 0xA0, 0xDD, 0x7D, 0xD7, 0x20, 0xAD, 0xB7, 0xFF, 0x05, 0xF8, 0x3D, 0x54, 0x2B, 0x20, 0x9D, + 0xC7, 0xFF, 0x45, 0x28, 0xF7, 0xD6, 0x77, 0xB1, 0x83, 0x89, 0xFE, 0xA5, 0xE5, 0xC4, 0x9E, 0x86 }, + 32 /* Bin Number */ + }, + { + /* UTN___DATACorp_SGC */ + { 0x85, 0xFB, 0x2F, 0x91, 0xDD, 0x12, 0x27, 0x5A, 0x01, 0x45, 0xB6, 0x36, 0x53, 0x4F, 0x84, 0x02, + 0x4A, 0xD6, 0x8B, 0x69, 0xB8, 0xEE, 0x88, 0x68, 0x4F, 0xF7, 0x11, 0x37, 0x58, 0x05, 0xB3, 0x48 }, + 37 /* Bin Number */ + }, + { + /* emSign_ECC_Root_CA___G3 */ + { 0x86, 0xA1, 0xEC, 0xBA, 0x08, 0x9C, 0x4A, 0x8D, 0x3B, 0xBE, 0x27, 0x34, 0xC6, 0x12, 0xBA, 0x34, + 0x1D, 0x81, 0x3E, 0x04, 0x3C, 0xF9, 0xE8, 0xA8, 0x62, 0xCD, 0x5C, 0x57, 0xA3, 0x6B, 0xBE, 0x6B }, + 207 /* Bin Number */ + }, + { + /* EC_ACC */ + { 0x88, 0x49, 0x7F, 0x01, 0x60, 0x2F, 0x31, 0x54, 0x24, 0x6A, 0xE2, 0x8C, 0x4D, 0x5A, 0xEF, 0x10, + 0xF1, 0xD8, 0x7E, 0xBB, 0x76, 0x62, 0x6F, 0x4A, 0xE0, 0xB7, 0xF9, 0x5B, 0xA7, 0x96, 0x87, 0x99 }, + 119 /* Bin Number */ + }, + { + /* QuoVadis_Root_CA_3_G3 */ + { 0x88, 0xEF, 0x81, 0xDE, 0x20, 0x2E, 0xB0, 0x18, 0x45, 0x2E, 0x43, 0xF8, 0x64, 0x72, 0x5C, 0xEA, + 0x5F, 0xBD, 0x1F, 0xC2, 0xD9, 0xD2, 0x05, 0x73, 0x07, 0x09, 0xC5, 0xD8, 0xB8, 0x69, 0x0F, 0x46 }, + 146 /* Bin Number */ + }, + { + /* NAVER_Global_Root_Certification_Authority */ + { 0x88, 0xF4, 0x38, 0xDC, 0xF8, 0xFF, 0xD1, 0xFA, 0x8F, 0x42, 0x91, 0x15, 0xFF, 0xE5, 0xF8, 0x2A, + 0xE1, 0xE0, 0x6E, 0x0C, 0x70, 0xC3, 0x75, 0xFA, 0xAD, 0x71, 0x7B, 0x34, 0xA4, 0x9E, 0x72, 0x65 }, + 219 /* Bin Number */ + }, + { + /* QuoVadis_Root_CA_1_G3 */ + { 0x8A, 0x86, 0x6F, 0xD1, 0xB2, 0x76, 0xB5, 0x7E, 0x57, 0x8E, 0x92, 0x1C, 0x65, 0x82, 0x8A, 0x2B, + 0xED, 0x58, 0xE9, 0xF2, 0xF2, 0x88, 0x05, 0x41, 0x34, 0xB7, 0xF1, 0xF4, 0xBF, 0xC9, 0xCC, 0x74 }, + 144 /* Bin Number */ + }, + { + /* CA_WoSign_ECC_Root */ + { 0x8B, 0x45, 0xDA, 0x1C, 0x06, 0xF7, 0x91, 0xEB, 0x0C, 0xAB, 0xF2, 0x6B, 0xE5, 0x88, 0xF5, 0xFB, + 0x23, 0x16, 0x5C, 0x2E, 0x61, 0x4B, 0xF8, 0x85, 0x56, 0x2D, 0x0D, 0xCE, 0x50, 0xB2, 0x9B, 0x02 }, + 171 /* Bin Number */ + }, + { + /* Root_CA_Generalitat_Valenciana */ + { 0x8C, 0x4E, 0xDF, 0xD0, 0x43, 0x48, 0xF3, 0x22, 0x96, 0x9E, 0x7E, 0x29, 0xA4, 0xCD, 0x4D, 0xCA, + 0x00, 0x46, 0x55, 0x06, 0x1C, 0x16, 0xE1, 0xB0, 0x76, 0x42, 0x2E, 0xF3, 0x42, 0xAD, 0x63, 0x0E }, + 115 /* Bin Number */ + }, + { + /* AddTrust_Class_1_CA_Root */ + { 0x8C, 0x72, 0x09, 0x27, 0x9A, 0xC0, 0x4E, 0x27, 0x5E, 0x16, 0xD0, 0x7F, 0xD3, 0xB7, 0x75, 0xE8, + 0x01, 0x54, 0xB5, 0x96, 0x80, 0x46, 0xE3, 0x1F, 0x52, 0xDD, 0x25, 0x76, 0x63, 0x24, 0xE9, 0xA7 }, + 14 /* Bin Number */ + }, + { + /* thawte_Primary_Root_CA */ + { 0x8D, 0x72, 0x2F, 0x81, 0xA9, 0xC1, 0x13, 0xC0, 0x79, 0x1D, 0xF1, 0x36, 0xA2, 0x96, 0x6D, 0xB2, + 0x6C, 0x95, 0x0A, 0x97, 0x1D, 0xB4, 0x6B, 0x41, 0x99, 0xF4, 0xEA, 0x54, 0xB7, 0x8B, 0xFB, 0x9F }, + 59 /* Bin Number */ + }, + { + /* TC_TrustCenter_Class_3_CA_II */ + { 0x8D, 0xA0, 0x84, 0xFC, 0xF9, 0x9C, 0xE0, 0x77, 0x22, 0xF8, 0x9B, 0x32, 0x05, 0x93, 0x98, 0x06, + 0xFA, 0x5C, 0xB8, 0x11, 0xE1, 0xC8, 0x13, 0xF6, 0xA1, 0x08, 0xC7, 0xD3, 0x36, 0xB3, 0x40, 0x8E }, + 73 /* Bin Number */ + }, + { + /* T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s__H6 */ + { 0x8D, 0xE7, 0x86, 0x55, 0xE1, 0xBE, 0x7F, 0x78, 0x47, 0x80, 0x0B, 0x93, 0xF6, 0x94, 0xD2, 0x1D, + 0x36, 0x8C, 0xC0, 0x6E, 0x03, 0x3E, 0x7F, 0xAB, 0x04, 0xBB, 0x5E, 0xB9, 0x9D, 0xA6, 0xB7, 0x00 }, + 167 /* Bin Number */ + }, + { + /* Amazon_Root_CA_1 */ + { 0x8E, 0xCD, 0xE6, 0x88, 0x4F, 0x3D, 0x87, 0xB1, 0x12, 0x5B, 0xA3, 0x1A, 0xC3, 0xFC, 0xB1, 0x3D, + 0x70, 0x16, 0xDE, 0x7F, 0x57, 0xCC, 0x90, 0x4F, 0xE1, 0xCB, 0x97, 0xC6, 0xAE, 0x98, 0x19, 0x6E }, + 183 /* Bin Number */ + }, + { + /* QuoVadis_Root_CA_2_G3 */ + { 0x8F, 0xE4, 0xFB, 0x0A, 0xF9, 0x3A, 0x4D, 0x0D, 0x67, 0xDB, 0x0B, 0xEB, 0xB2, 0x3E, 0x37, 0xC7, + 0x1B, 0xF3, 0x25, 0xDC, 0xBC, 0xDD, 0x24, 0x0E, 0xA0, 0x4D, 0xAF, 0x58, 0xB4, 0x7E, 0x18, 0x40 }, + 145 /* Bin Number */ + }, + { + /* T_TeleSec_GlobalRoot_Class_2 */ + { 0x91, 0xE2, 0xF5, 0x78, 0x8D, 0x58, 0x10, 0xEB, 0xA7, 0xBA, 0x58, 0x73, 0x7D, 0xE1, 0x54, 0x8A, + 0x8E, 0xCA, 0xCD, 0x01, 0x45, 0x98, 0xBC, 0x0B, 0x14, 0x3E, 0x04, 0x1B, 0x17, 0x05, 0x25, 0x52 }, + 142 /* Bin Number */ + }, + { + /* CA_Disig */ + { 0x92, 0xBF, 0x51, 0x19, 0xAB, 0xEC, 0xCA, 0xD0, 0xB1, 0x33, 0x2D, 0xC4, 0xE1, 0xD0, 0x5F, 0xBA, + 0x75, 0xB5, 0x67, 0x90, 0x44, 0xEE, 0x0C, 0xA2, 0x6E, 0x93, 0x1F, 0x74, 0x4F, 0x2F, 0x33, 0xCF }, + 94 /* Bin Number */ + }, + { + /* Trustwave_Global_ECC_P256_Certification_Authority */ + { 0x94, 0x5B, 0xBC, 0x82, 0x5E, 0xA5, 0x54, 0xF4, 0x89, 0xD1, 0xFD, 0x51, 0xA7, 0x3D, 0xDF, 0x2E, + 0xA6, 0x24, 0xAC, 0x70, 0x19, 0xA0, 0x52, 0x05, 0x22, 0x5C, 0x22, 0xA7, 0x8C, 0xCF, 0xA8, 0xB4 }, + 217 /* Bin Number */ + }, + { + /* Cybertrust_Global_Root */ + { 0x96, 0x0A, 0xDF, 0x00, 0x63, 0xE9, 0x63, 0x56, 0x75, 0x0C, 0x29, 0x65, 0xDD, 0x0A, 0x08, 0x67, + 0xDA, 0x0B, 0x9C, 0xBD, 0x6E, 0x77, 0x71, 0x4A, 0xEA, 0xFB, 0x23, 0x49, 0xAB, 0x39, 0x3D, 0xA3 }, + 77 /* Bin Number */ + }, + { + /* ISRG_Root_X1 */ + { 0x96, 0xBC, 0xEC, 0x06, 0x26, 0x49, 0x76, 0xF3, 0x74, 0x60, 0x77, 0x9A, 0xCF, 0x28, 0xC5, 0xA7, + 0xCF, 0xE8, 0xA3, 0xC0, 0xAA, 0xE1, 0x1A, 0x8F, 0xFC, 0xEE, 0x05, 0xC0, 0xBD, 0xDF, 0x08, 0xC6 }, + 181 /* Bin Number */ + }, + { + /* Trustwave_Global_Certification_Authority */ + { 0x97, 0x55, 0x20, 0x15, 0xF5, 0xDD, 0xFC, 0x3C, 0x87, 0x88, 0xC0, 0x06, 0x94, 0x45, 0x55, 0x40, + 0x88, 0x94, 0x45, 0x00, 0x84, 0xF1, 0x00, 0x86, 0x70, 0x86, 0xBC, 0x1A, 0x2B, 0xB5, 0x8D, 0xC8 }, + 216 /* Bin Number */ + }, + { + /* T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_ */ + { 0x97, 0x8C, 0xD9, 0x66, 0xF2, 0xFA, 0xA0, 0x7B, 0xA7, 0xAA, 0x95, 0x00, 0xD9, 0xC0, 0x2E, 0x9D, + 0x77, 0xF2, 0xCD, 0xAD, 0xA6, 0xAD, 0x6B, 0xA7, 0x4A, 0xF4, 0xB9, 0x1C, 0x66, 0x59, 0x3C, 0x50 }, + 129 /* Bin Number */ + }, + { + /* Buypass_Class_2_Root_CA */ + { 0x9A, 0x11, 0x40, 0x25, 0x19, 0x7C, 0x5B, 0xB9, 0x5D, 0x94, 0xE6, 0x3D, 0x55, 0xCD, 0x43, 0x79, + 0x08, 0x47, 0xB6, 0x46, 0xB2, 0x3C, 0xDF, 0x11, 0xAD, 0xA4, 0xA0, 0x0E, 0xFF, 0x15, 0xFB, 0x48 }, + 125 /* Bin Number */ + }, + { + /* ACCVRAIZ1 */ + { 0x9A, 0x6E, 0xC0, 0x12, 0xE1, 0xA7, 0xDA, 0x9D, 0xBE, 0x34, 0x19, 0x4D, 0x47, 0x8A, 0xD7, 0xC0, + 0xDB, 0x18, 0x22, 0xFB, 0x07, 0x1D, 0xF1, 0x29, 0x81, 0x49, 0x6E, 0xD1, 0x04, 0x38, 0x41, 0x13 }, + 138 /* Bin Number */ + }, + { + /* VeriSign_Class_3_Public_Primary_Certification_Authority___G5 */ + { 0x9A, 0xCF, 0xAB, 0x7E, 0x43, 0xC8, 0xD8, 0x80, 0xD0, 0x6B, 0x26, 0x2A, 0x94, 0xDE, 0xEE, 0xE4, + 0xB4, 0x65, 0x99, 0x89, 0xC3, 0xD0, 0xCA, 0xF1, 0x9B, 0xAF, 0x64, 0x05, 0xE4, 0x1A, 0xB7, 0xDF }, + 60 /* Bin Number */ + }, + { + /* UCA_Global_G2_Root */ + { 0x9B, 0xEA, 0x11, 0xC9, 0x76, 0xFE, 0x01, 0x47, 0x64, 0xC1, 0xBE, 0x56, 0xA6, 0xF9, 0x14, 0xB5, + 0xA5, 0x60, 0x31, 0x7A, 0xBD, 0x99, 0x88, 0x39, 0x33, 0x82, 0xE5, 0x16, 0x1A, 0xA0, 0x49, 0x3C }, + 203 /* Bin Number */ + }, + { + /* GeoTrust_Universal_CA_2 */ + { 0xA0, 0x23, 0x4F, 0x3B, 0xC8, 0x52, 0x7C, 0xA5, 0x62, 0x8E, 0xEC, 0x81, 0xAD, 0x5D, 0x69, 0x89, + 0x5D, 0xA5, 0x68, 0x0D, 0xC9, 0x1D, 0x1C, 0xB8, 0x47, 0x7F, 0x33, 0xF8, 0x78, 0xB9, 0x5B, 0x0B }, + 23 /* Bin Number */ + }, + { + /* Hellenic_Academic_and_Research_Institutions_RootCA_2015 */ + { 0xA0, 0x40, 0x92, 0x9A, 0x02, 0xCE, 0x53, 0xB4, 0xAC, 0xF4, 0xF2, 0xFF, 0xC6, 0x98, 0x1C, 0xE4, + 0x49, 0x6F, 0x75, 0x5E, 0x6D, 0x45, 0xFE, 0x0B, 0x2A, 0x69, 0x2B, 0xCD, 0x52, 0x52, 0x3F, 0x36 }, + 174 /* Bin Number */ + }, + { + /* GeoTrust_Universal_CA */ + { 0xA0, 0x45, 0x9B, 0x9F, 0x63, 0xB2, 0x25, 0x59, 0xF5, 0xFA, 0x5D, 0x4C, 0x6D, 0xB3, 0xF9, 0xF7, + 0x2F, 0xF1, 0x93, 0x42, 0x03, 0x35, 0x78, 0xF0, 0x73, 0xBF, 0x1D, 0x1B, 0x46, 0xCB, 0xB9, 0x12 }, + 22 /* Bin Number */ + }, + { + /* SZAFIR_ROOT_CA2 */ + { 0xA1, 0x33, 0x9D, 0x33, 0x28, 0x1A, 0x0B, 0x56, 0xE5, 0x57, 0xD3, 0xD3, 0x2B, 0x1C, 0xE7, 0xF9, + 0x36, 0x7E, 0xB0, 0x94, 0xBD, 0x5F, 0xA7, 0x2A, 0x7E, 0x50, 0x04, 0xC8, 0xDE, 0xD7, 0xCA, 0xFE }, + 172 /* Bin Number */ + }, + { + /* OU_Security_Communication_EV_RootCA1_O__SECOM_Trust_Systems_CO__LTD___C_JP */ + { 0xA2, 0x2D, 0xBA, 0x68, 0x1E, 0x97, 0x37, 0x6E, 0x2D, 0x39, 0x7D, 0x72, 0x8A, 0xAE, 0x3A, 0x9B, + 0x62, 0x96, 0xB9, 0xFD, 0xBA, 0x60, 0xBC, 0x2E, 0x11, 0xF6, 0x47, 0xF2, 0xC6, 0x75, 0xFB, 0x37 }, + 68 /* Bin Number */ + }, + { + /* thawte_Primary_Root_CA___G2 */ + { 0xA4, 0x31, 0x0D, 0x50, 0xAF, 0x18, 0xA6, 0x44, 0x71, 0x90, 0x37, 0x2A, 0x86, 0xAF, 0xAF, 0x8B, + 0x95, 0x1F, 0xFB, 0x43, 0x1D, 0x83, 0x7F, 0x1E, 0x56, 0x88, 0xB4, 0x59, 0x71, 0xED, 0x15, 0x57 }, + 87 /* Bin Number */ + }, + { + /* QuoVadis_Root_Certification_Authority */ + { 0xA4, 0x5E, 0xDE, 0x3B, 0xBB, 0xF0, 0x9C, 0x8A, 0xE1, 0x5C, 0x72, 0xEF, 0xC0, 0x72, 0x68, 0xD6, + 0x93, 0xA2, 0x1C, 0x99, 0x6F, 0xD5, 0x1E, 0x67, 0xCA, 0x07, 0x94, 0x60, 0xFD, 0x6D, 0x88, 0x73 }, + 31 /* Bin Number */ + }, + { + /* WellsSecure_Public_Root_Certificate_Authority */ + { 0xA7, 0x12, 0x72, 0xAE, 0xAA, 0xA3, 0xCF, 0xE8, 0x72, 0x7F, 0x7F, 0xB3, 0x9F, 0x0F, 0xB3, 0xD1, + 0xE5, 0x42, 0x6E, 0x90, 0x60, 0xB0, 0x6E, 0xE6, 0xF1, 0x3E, 0x9A, 0x3C, 0x58, 0x33, 0xCD, 0x43 }, + 65 /* Bin Number */ + }, + { + /* OU_RSA_Security_2048_V3_O_RSA_Security_Inc */ + { 0xAF, 0x8B, 0x67, 0x62, 0xA1, 0xE5, 0x28, 0x22, 0x81, 0x61, 0xA9, 0x5D, 0x5C, 0x55, 0x9E, 0xE2, + 0x66, 0x27, 0x8F, 0x75, 0xD7, 0x9E, 0x83, 0x01, 0x89, 0xA5, 0x03, 0x50, 0x6A, 0xBD, 0x6B, 0x4C }, + 19 /* Bin Number */ + }, + { + /* E_Tugra_Certification_Authority */ + { 0xB0, 0xBF, 0xD5, 0x2B, 0xB0, 0xD7, 0xD9, 0xBD, 0x92, 0xBF, 0x5D, 0x4D, 0xC1, 0x3D, 0xA2, 0x55, + 0xC0, 0x2C, 0x54, 0x2F, 0x37, 0x83, 0x65, 0xEA, 0x89, 0x39, 0x11, 0xF5, 0x5E, 0x55, 0xF2, 0x3C }, + 141 /* Bin Number */ + }, + { + /* GeoTrust_Primary_Certification_Authority___G3 */ + { 0xB4, 0x78, 0xB8, 0x12, 0x25, 0x0D, 0xF8, 0x78, 0x63, 0x5C, 0x2A, 0xA7, 0xEC, 0x7D, 0x15, 0x5E, + 0xAA, 0x62, 0x5E, 0xE8, 0x29, 0x16, 0xE2, 0xCD, 0x29, 0x43, 0x61, 0x88, 0x6C, 0xD1, 0xFB, 0xD4 }, + 86 /* Bin Number */ + }, + { + /* Deutsche_Telekom_Root_CA_2 */ + { 0xB6, 0x19, 0x1A, 0x50, 0xD0, 0xC3, 0x97, 0x7F, 0x7D, 0xA9, 0x9B, 0xCD, 0xAA, 0xC8, 0x6A, 0x22, + 0x7D, 0xAE, 0xB9, 0x67, 0x9E, 0xC7, 0x0B, 0xA3, 0xB0, 0xC9, 0xD9, 0x22, 0x71, 0xC1, 0x70, 0xD3 }, + 75 /* Bin Number */ + }, + { + /* Certum_Trusted_Network_CA_2 */ + { 0xB6, 0x76, 0xF2, 0xED, 0xDA, 0xE8, 0x77, 0x5C, 0xD3, 0x6C, 0xB0, 0xF6, 0x3C, 0xD1, 0xD4, 0x60, + 0x39, 0x61, 0xF4, 0x9E, 0x62, 0x65, 0xBA, 0x01, 0x3A, 0x2F, 0x03, 0x07, 0xB6, 0xD0, 0xB8, 0x04 }, + 173 /* Bin Number */ + }, + { + /* Buypass_Class_3_CA_1 */ + { 0xB7, 0xB1, 0x2B, 0x17, 0x1F, 0x82, 0x1D, 0xAA, 0x99, 0x0C, 0xD0, 0xFE, 0x50, 0x87, 0xB1, 0x28, + 0x44, 0x8B, 0xA8, 0xE5, 0x18, 0x4F, 0x84, 0xC5, 0x1E, 0x02, 0xB5, 0xC8, 0xFB, 0x96, 0x2B, 0x24 }, + 81 /* Bin Number */ + }, + { + /* OpenTrust_Root_CA_G3 */ + { 0xB7, 0xC3, 0x62, 0x31, 0x70, 0x6E, 0x81, 0x07, 0x8C, 0x36, 0x7C, 0xB8, 0x96, 0x19, 0x8F, 0x1E, + 0x32, 0x08, 0xDD, 0x92, 0x69, 0x49, 0xDD, 0x8F, 0x57, 0x09, 0xA4, 0x10, 0xF7, 0x5B, 0x62, 0x92 }, + 180 /* Bin Number */ + }, + { + /* IGC_A */ + { 0xB9, 0xBE, 0xA7, 0x86, 0x0A, 0x96, 0x2E, 0xA3, 0x61, 0x1D, 0xAB, 0x97, 0xAB, 0x6D, 0xA3, 0xE2, + 0x1C, 0x10, 0x68, 0xB9, 0x7D, 0x55, 0x57, 0x5E, 0xD0, 0xE1, 0x12, 0x79, 0xC1, 0x1C, 0x89, 0x32 }, + 67 /* Bin Number */ + }, + { + /* Hellenic_Academic_and_Research_Institutions_RootCA_2011 */ + { 0xBC, 0x10, 0x4F, 0x15, 0xA4, 0x8B, 0xE7, 0x09, 0xDC, 0xA5, 0x42, 0xA7, 0xE1, 0xD4, 0xB9, 0xDF, + 0x6F, 0x05, 0x45, 0x27, 0xE8, 0x02, 0xEA, 0xA9, 0x2D, 0x59, 0x54, 0x44, 0x25, 0x8A, 0xFE, 0x71 }, + 120 /* Bin Number */ + }, + { + /* emSign_ECC_Root_CA___C3 */ + { 0xBC, 0x4D, 0x80, 0x9B, 0x15, 0x18, 0x9D, 0x78, 0xDB, 0x3E, 0x1D, 0x8C, 0xF4, 0xF9, 0x72, 0x6A, + 0x79, 0x5D, 0xA1, 0x64, 0x3C, 0xA5, 0xF1, 0x35, 0x8E, 0x1D, 0xDB, 0x0E, 0xDC, 0x0D, 0x7E, 0xB3 }, + 209 /* Bin Number */ + }, + { + /* AffirmTrust_Premium_ECC */ + { 0xBD, 0x71, 0xFD, 0xF6, 0xDA, 0x97, 0xE4, 0xCF, 0x62, 0xD1, 0x64, 0x7A, 0xDD, 0x25, 0x81, 0xB0, + 0x7D, 0x79, 0xAD, 0xF8, 0x39, 0x7E, 0xB4, 0xEC, 0xBA, 0x9C, 0x5E, 0x84, 0x88, 0x82, 0x14, 0x23 }, + 112 /* Bin Number */ + }, + { + /* Secure_Certificate_Services */ + { 0xBD, 0x81, 0xCE, 0x3B, 0x4F, 0x65, 0x91, 0xD1, 0x1A, 0x67, 0xB5, 0xFC, 0x7A, 0x47, 0xFD, 0xEF, + 0x25, 0x52, 0x1B, 0xF9, 0xAA, 0x4E, 0x18, 0xB9, 0xE3, 0xDF, 0x2E, 0x34, 0xA7, 0x80, 0x3B, 0xE8 }, + 29 /* Bin Number */ + }, + { + /* SwissSign_Silver_CA___G2 */ + { 0xBE, 0x6C, 0x4D, 0xA2, 0xBB, 0xB9, 0xBA, 0x59, 0xB6, 0xF3, 0x93, 0x97, 0x68, 0x37, 0x42, 0x46, + 0xC3, 0xC0, 0x05, 0x99, 0x3F, 0xA9, 0x8F, 0x02, 0x0D, 0x1D, 0xED, 0xBE, 0xD4, 0x8A, 0x81, 0xD5 }, + 57 /* Bin Number */ + }, + { + /* e_Szigno_Root_CA_2017 */ + { 0xBE, 0xB0, 0x0B, 0x30, 0x83, 0x9B, 0x9B, 0xC3, 0x2C, 0x32, 0xE4, 0x44, 0x79, 0x05, 0x95, 0x06, + 0x41, 0xF2, 0x64, 0x21, 0xB1, 0x5E, 0xD0, 0x89, 0x19, 0x8B, 0x51, 0x8A, 0xE2, 0xEA, 0x1B, 0x99 }, + 214 /* Bin Number */ + }, + { + /* GlobalSign */ + { 0xBE, 0xC9, 0x49, 0x11, 0xC2, 0x95, 0x56, 0x76, 0xDB, 0x6C, 0x0A, 0x55, 0x09, 0x86, 0xD7, 0x6E, + 0x3B, 0xA0, 0x05, 0x66, 0x7C, 0x44, 0x2C, 0x97, 0x62, 0xB4, 0xFB, 0xB7, 0x73, 0xDE, 0x22, 0x8C }, + 157 /* Bin Number */ + }, + { + /* SecureSign_RootCA11 */ + { 0xBF, 0x0F, 0xEE, 0xFB, 0x9E, 0x3A, 0x58, 0x1A, 0xD5, 0xF9, 0xE9, 0xDB, 0x75, 0x89, 0x98, 0x57, + 0x43, 0xD2, 0x61, 0x08, 0x5C, 0x4D, 0x31, 0x4F, 0x6F, 0x5D, 0x72, 0x59, 0xAA, 0x42, 0x16, 0x12 }, + 97 /* Bin Number */ + }, + { + /* TWCA_Root_Certification_Authority */ + { 0xBF, 0xD8, 0x8F, 0xE1, 0x10, 0x1C, 0x41, 0xAE, 0x3E, 0x80, 0x1B, 0xF8, 0xBE, 0x56, 0x35, 0x0E, + 0xE9, 0xBA, 0xD1, 0xA6, 0xB9, 0xBD, 0x51, 0x5E, 0xDC, 0x5C, 0x6D, 0x5B, 0x87, 0x11, 0xAC, 0x44 }, + 117 /* Bin Number */ + }, + { + /* GDCA_TrustAUTH_R5_ROOT */ + { 0xBF, 0xFF, 0x8F, 0xD0, 0x44, 0x33, 0x48, 0x7D, 0x6A, 0x8A, 0xA6, 0x0C, 0x1A, 0x29, 0x76, 0x7A, + 0x9F, 0xC2, 0xBB, 0xB0, 0x5E, 0x42, 0x0F, 0x71, 0x3A, 0x13, 0xB9, 0x92, 0x89, 0x1D, 0x38, 0x93 }, + 189 /* Bin Number */ + }, + { + /* OU_ePKI_Root_Certification_Authority_O__Chunghwa_Telecom_Co___Ltd___C_TW */ + { 0xC0, 0xA6, 0xF4, 0xDC, 0x63, 0xA2, 0x4B, 0xFD, 0xCF, 0x54, 0xEF, 0x2A, 0x6A, 0x08, 0x2A, 0x0A, + 0x72, 0xDE, 0x35, 0x80, 0x3E, 0x2F, 0xF5, 0xFF, 0x52, 0x7A, 0xE5, 0xD8, 0x72, 0x06, 0xDF, 0xD5 }, + 78 /* Bin Number */ + }, + { + /* OU_Trustis_FPS_Root_CA_O_Trustis_Limited_C_GB */ + { 0xC1, 0xB4, 0x82, 0x99, 0xAB, 0xA5, 0x20, 0x8F, 0xE9, 0x63, 0x0A, 0xCE, 0x55, 0xCA, 0x68, 0xA0, + 0x3E, 0xDA, 0x5A, 0x51, 0x9C, 0x88, 0x02, 0xA0, 0xD3, 0xA6, 0x73, 0xBE, 0x8F, 0x8E, 0x55, 0x7D }, + 122 /* Bin Number */ + }, + { + /* OU_Go_Daddy_Class_2_Certification_Authority_O__The_Go_Daddy_Group__Inc___C_US */ + { 0xC3, 0x84, 0x6B, 0xF2, 0x4B, 0x9E, 0x93, 0xCA, 0x64, 0x27, 0x4C, 0x0E, 0xC6, 0x7C, 0x1E, 0xCC, + 0x5E, 0x02, 0x4F, 0xFC, 0xAC, 0xD2, 0xD7, 0x40, 0x19, 0x35, 0x0E, 0x81, 0xFE, 0x54, 0x6A, 0xE4 }, + 43 /* Bin Number */ + }, + { + /* GTS_Root_R2 */ + { 0xC4, 0x5D, 0x7B, 0xB0, 0x8E, 0x6D, 0x67, 0xE6, 0x2E, 0x42, 0x35, 0x11, 0x0B, 0x56, 0x4E, 0x5F, + 0x78, 0xFD, 0x92, 0xEF, 0x05, 0x8C, 0x84, 0x0A, 0xEA, 0x4E, 0x64, 0x55, 0xD7, 0x58, 0x5C, 0x60 }, + 200 /* Bin Number */ + }, + { + /* T_RKTRUST_Elektronik_Sertifika_Hizmet_Sa_lay_c_s_ */ + { 0xC4, 0x70, 0xCF, 0x54, 0x7E, 0x23, 0x02, 0xB9, 0x77, 0xFB, 0x29, 0xDD, 0x71, 0xA8, 0x9A, 0x7B, + 0x6C, 0x1F, 0x60, 0x77, 0x7B, 0x03, 0x29, 0xF5, 0x60, 0x17, 0xF3, 0x28, 0xBF, 0x4F, 0x6B, 0xE6 }, + 55 /* Bin Number */ + }, + { + /* Microsoft_RSA_Root_Certificate_Authority_2017 */ + { 0xC7, 0x41, 0xF7, 0x0F, 0x4B, 0x2A, 0x8D, 0x88, 0xBF, 0x2E, 0x71, 0xC1, 0x41, 0x22, 0xEF, 0x53, + 0xEF, 0x10, 0xEB, 0xA0, 0xCF, 0xA5, 0xE6, 0x4C, 0xFA, 0x20, 0xF4, 0x18, 0x85, 0x30, 0x73, 0xE0 }, + 213 /* Bin Number */ + }, + { + /* StartCom_Certification_Authority */ + { 0xC7, 0x66, 0xA9, 0xBE, 0xF2, 0xD4, 0x07, 0x1C, 0x86, 0x3A, 0x31, 0xAA, 0x49, 0x20, 0xE8, 0x13, + 0xB2, 0xD1, 0x98, 0x60, 0x8C, 0xB7, 0xB7, 0xCF, 0xE2, 0x11, 0x43, 0xB8, 0x36, 0xDF, 0x09, 0xEA }, + 45 /* Bin Number */ + }, + { + /* StartCom_Certification_Authority_G2 */ + { 0xC7, 0xBA, 0x65, 0x67, 0xDE, 0x93, 0xA7, 0x98, 0xAE, 0x1F, 0xAA, 0x79, 0x1E, 0x71, 0x2D, 0x37, + 0x8F, 0xAE, 0x1F, 0x93, 0xC4, 0x39, 0x7F, 0xEA, 0x44, 0x1B, 0xB7, 0xCB, 0xE6, 0xFD, 0x59, 0x95 }, + 124 /* Bin Number */ + }, + { + /* GeoTrust_Global_CA_2 */ + { 0xCA, 0x2D, 0x82, 0xA0, 0x86, 0x77, 0x07, 0x2F, 0x8A, 0xB6, 0x76, 0x4F, 0xF0, 0x35, 0x67, 0x6C, + 0xFE, 0x3E, 0x5E, 0x32, 0x5E, 0x01, 0x21, 0x72, 0xDF, 0x3F, 0x92, 0x09, 0x6D, 0xB7, 0x9B, 0x85 }, + 21 /* Bin Number */ + }, + { + /* GlobalSign */ + { 0xCA, 0x42, 0xDD, 0x41, 0x74, 0x5F, 0xD0, 0xB8, 0x1E, 0xB9, 0x02, 0x36, 0x2C, 0xF9, 0xD8, 0xBF, + 0x71, 0x9D, 0xA1, 0xBD, 0x1B, 0x1E, 0xFC, 0x94, 0x6F, 0x5B, 0x4C, 0x99, 0xF4, 0x2C, 0x1B, 0x9E }, + 7 /* Bin Number */ + }, + { + /* DigiCert_Global_Root_G2 */ + { 0xCB, 0x3C, 0xCB, 0xB7, 0x60, 0x31, 0xE5, 0xE0, 0x13, 0x8F, 0x8D, 0xD3, 0x9A, 0x23, 0xF9, 0xDE, + 0x47, 0xFF, 0xC3, 0x5E, 0x43, 0xC1, 0x14, 0x4C, 0xEA, 0x27, 0xD4, 0x6A, 0x5A, 0xB1, 0xCB, 0x5F }, + 149 /* Bin Number */ + }, + { + /* GlobalSign */ + { 0xCB, 0xB5, 0x22, 0xD7, 0xB7, 0xF1, 0x27, 0xAD, 0x6A, 0x01, 0x13, 0x86, 0x5B, 0xDF, 0x1C, 0xD4, + 0x10, 0x2E, 0x7D, 0x07, 0x59, 0xAF, 0x63, 0x5A, 0x7C, 0xF4, 0x72, 0x0D, 0xC9, 0x63, 0xC5, 0x3B }, + 101 /* Bin Number */ + }, + { + /* XRamp_Global_Certification_Authority */ + { 0xCE, 0xCD, 0xDC, 0x90, 0x50, 0x99, 0xD8, 0xDA, 0xDF, 0xC5, 0xB1, 0xD2, 0x09, 0xB7, 0x37, 0xCB, + 0xE2, 0xC1, 0x8C, 0xFB, 0x2C, 0x10, 0xC0, 0xFF, 0x0B, 0xCF, 0x0D, 0x32, 0x86, 0xFC, 0x1A, 0xA2 }, + 42 /* Bin Number */ + }, + { + /* Equifax_Secure_eBusiness_CA_1 */ + { 0xCF, 0x56, 0xFF, 0x46, 0xA4, 0xA1, 0x86, 0x10, 0x9D, 0xD9, 0x65, 0x84, 0xB5, 0xEE, 0xB5, 0x8A, + 0x51, 0x0C, 0x42, 0x75, 0xB0, 0xE5, 0xF9, 0x4F, 0x40, 0xBB, 0xAE, 0x86, 0x5E, 0x19, 0xF6, 0x73 }, + 13 /* Bin Number */ + }, + { + /* TrustCor_RootCert_CA_1 */ + { 0xD4, 0x0E, 0x9C, 0x86, 0xCD, 0x8F, 0xE4, 0x68, 0xC1, 0x77, 0x69, 0x59, 0xF4, 0x9E, 0xA7, 0x74, + 0xFA, 0x54, 0x86, 0x84, 0xB6, 0xC4, 0x06, 0xF3, 0x90, 0x92, 0x61, 0xF4, 0xDC, 0xE2, 0x57, 0x5C }, + 190 /* Bin Number */ + }, + { + /* Staat_der_Nederlanden_Root_CA */ + { 0xD4, 0x1D, 0x82, 0x9E, 0x8C, 0x16, 0x59, 0x82, 0x2A, 0xF9, 0x3F, 0xCE, 0x62, 0xBF, 0xFC, 0xDE, + 0x26, 0x4F, 0xC8, 0x4E, 0x8B, 0x95, 0x0C, 0x5F, 0xF2, 0x75, 0xD0, 0x52, 0x35, 0x46, 0x95, 0xA3 }, + 36 /* Bin Number */ + }, + { + /* UCA_Extended_Validation_Root */ + { 0xD4, 0x3A, 0xF9, 0xB3, 0x54, 0x73, 0x75, 0x5C, 0x96, 0x84, 0xFC, 0x06, 0xD7, 0xD8, 0xCB, 0x70, + 0xEE, 0x5C, 0x28, 0xE7, 0x73, 0xFB, 0x29, 0x4E, 0xB4, 0x1E, 0xE7, 0x17, 0x22, 0x92, 0x4D, 0x24 }, + 204 /* Bin Number */ + }, + { + /* Certification_Authority_of_WoSign_G2 */ + { 0xD4, 0x87, 0xA5, 0x6F, 0x83, 0xB0, 0x74, 0x82, 0xE8, 0x5E, 0x96, 0x33, 0x94, 0xC1, 0xEC, 0xC2, + 0xC9, 0xE5, 0x1D, 0x09, 0x03, 0xEE, 0x94, 0x6B, 0x02, 0xC3, 0x01, 0x58, 0x1E, 0xD9, 0x9E, 0x16 }, + 170 /* Bin Number */ + }, + { + /* Certigna_Root_CA */ + { 0xD4, 0x8D, 0x3D, 0x23, 0xEE, 0xDB, 0x50, 0xA4, 0x59, 0xE5, 0x51, 0x97, 0x60, 0x1C, 0x27, 0x77, + 0x4B, 0x9D, 0x7B, 0x18, 0xC9, 0x4D, 0x5A, 0x05, 0x95, 0x11, 0xA1, 0x02, 0x50, 0xB9, 0x31, 0x68 }, + 205 /* Bin Number */ + }, + { + /* CA______ */ + { 0xD6, 0xF0, 0x34, 0xBD, 0x94, 0xAA, 0x23, 0x3F, 0x02, 0x97, 0xEC, 0xA4, 0x24, 0x5B, 0x28, 0x39, + 0x73, 0xE4, 0x47, 0xAA, 0x59, 0x0F, 0x31, 0x0C, 0x77, 0xF4, 0x8F, 0xDF, 0x83, 0x11, 0x22, 0x54 }, + 153 /* Bin Number */ + }, + { + /* AAA_Certificate_Services */ + { 0xD7, 0xA7, 0xA0, 0xFB, 0x5D, 0x7E, 0x27, 0x31, 0xD7, 0x71, 0xE9, 0x48, 0x4E, 0xBC, 0xDE, 0xF7, + 0x1D, 0x5F, 0x0C, 0x3E, 0x0A, 0x29, 0x48, 0x78, 0x2B, 0xC8, 0x3E, 0xE0, 0xEA, 0x69, 0x9E, 0xF4 }, + 28 /* Bin Number */ + }, + { + /* Certum_CA */ + { 0xD8, 0xE0, 0xFE, 0xBC, 0x1D, 0xB2, 0xE3, 0x8D, 0x00, 0x94, 0x0F, 0x37, 0xD2, 0x7D, 0x41, 0x34, + 0x4D, 0x99, 0x3E, 0x73, 0x4B, 0x99, 0xD5, 0x65, 0x6D, 0x97, 0x78, 0xD4, 0xD8, 0x14, 0x36, 0x24 }, + 27 /* Bin Number */ + }, + { + /* Swisscom_Root_EV_CA_2 */ + { 0xD9, 0x5F, 0xEA, 0x3C, 0xA4, 0xEE, 0xDC, 0xE7, 0x4C, 0xD7, 0x6E, 0x75, 0xFC, 0x6D, 0x1F, 0xF6, + 0x2C, 0x44, 0x1F, 0x0F, 0xA8, 0xBC, 0x77, 0xF0, 0x34, 0xB1, 0x9E, 0x5D, 0xB2, 0x58, 0x01, 0x5D }, + 135 /* Bin Number */ + }, + { + /* Entrust_Root_Certification_Authority___G4 */ + { 0xDB, 0x35, 0x17, 0xD1, 0xF6, 0x73, 0x2A, 0x2D, 0x5A, 0xB9, 0x7C, 0x53, 0x3E, 0xC7, 0x07, 0x79, + 0xEE, 0x32, 0x70, 0xA6, 0x2F, 0xB4, 0xAC, 0x42, 0x38, 0x37, 0x24, 0x60, 0xE6, 0xF0, 0x1E, 0x88 }, + 211 /* Bin Number */ + }, + { + /* TeliaSonera_Root_CA_v1 */ + { 0xDD, 0x69, 0x36, 0xFE, 0x21, 0xF8, 0xF0, 0x77, 0xC1, 0x23, 0xA1, 0xA5, 0x21, 0xC1, 0x22, 0x24, + 0xF7, 0x22, 0x55, 0xB7, 0x3E, 0x03, 0xA7, 0x26, 0x06, 0x93, 0xE8, 0xA2, 0x4B, 0x0F, 0xA3, 0x89 }, + 140 /* Bin Number */ + }, + { + /* StartCom_Certification_Authority */ + { 0xE1, 0x78, 0x90, 0xEE, 0x09, 0xA3, 0xFB, 0xF4, 0xF4, 0x8B, 0x9C, 0x41, 0x4A, 0x17, 0xD6, 0x37, + 0xB7, 0xA5, 0x06, 0x47, 0xE9, 0xBC, 0x75, 0x23, 0x22, 0x72, 0x7F, 0xCC, 0x17, 0x42, 0xA9, 0x11 }, + 123 /* Bin Number */ + }, + { + /* CA_Disig_Root_R2 */ + { 0xE2, 0x3D, 0x4A, 0x03, 0x6D, 0x7B, 0x70, 0xE9, 0xF5, 0x95, 0xB1, 0x42, 0x20, 0x79, 0xD2, 0xB9, + 0x1E, 0xDF, 0xBB, 0x1F, 0xB6, 0x51, 0xA0, 0x63, 0x3E, 0xAA, 0x8A, 0x9D, 0xC5, 0xF8, 0x07, 0x03 }, + 137 /* Bin Number */ + }, + { + /* CNNIC_ROOT */ + { 0xE2, 0x83, 0x93, 0x77, 0x3D, 0xA8, 0x45, 0xA6, 0x79, 0xF2, 0x08, 0x0C, 0xC7, 0xFB, 0x44, 0xA3, + 0xB7, 0xA1, 0xC3, 0x79, 0x2C, 0xB7, 0xEB, 0x77, 0x29, 0xFD, 0xCB, 0x6A, 0x8D, 0x99, 0xAE, 0xA7 }, + 84 /* Bin Number */ + }, + { + /* Amazon_Root_CA_4 */ + { 0xE3, 0x5D, 0x28, 0x41, 0x9E, 0xD0, 0x20, 0x25, 0xCF, 0xA6, 0x90, 0x38, 0xCD, 0x62, 0x39, 0x62, + 0x45, 0x8D, 0xA5, 0xC6, 0x95, 0xFB, 0xDE, 0xA3, 0xC2, 0x2B, 0x0B, 0xFB, 0x25, 0x89, 0x70, 0x92 }, + 186 /* Bin Number */ + }, + { + /* VeriSign_Class_4_Public_Primary_Certification_Authority___G3 */ + { 0xE3, 0x89, 0x36, 0x0D, 0x0F, 0xDB, 0xAE, 0xB3, 0xD2, 0x50, 0x58, 0x4B, 0x47, 0x30, 0x31, 0x4E, + 0x22, 0x2F, 0x39, 0xC1, 0x56, 0xA0, 0x20, 0x14, 0x4E, 0x8D, 0x96, 0x05, 0x61, 0x79, 0x15, 0x06 }, + 9 /* Bin Number */ + }, + { + /* Certigna */ + { 0xE3, 0xB6, 0xA2, 0xDB, 0x2E, 0xD7, 0xCE, 0x48, 0x84, 0x2F, 0x7A, 0xC5, 0x32, 0x41, 0xC7, 0xB7, + 0x1D, 0x54, 0x14, 0x4B, 0xFB, 0x40, 0xC1, 0x1F, 0x3F, 0x1D, 0x0B, 0x42, 0xF5, 0xEE, 0xA1, 0x2D }, + 71 /* Bin Number */ + }, + { + /* T_B_TAK_UEKAE_K_k_Sertifika_Hizmet_Sa_lay_c_s____S_r_m_3 */ + { 0xE4, 0xC7, 0x34, 0x30, 0xD7, 0xA5, 0xB5, 0x09, 0x25, 0xDF, 0x43, 0x37, 0x0A, 0x0D, 0x21, 0x6E, + 0x9A, 0x79, 0xB9, 0xD6, 0xDB, 0x83, 0x73, 0xA0, 0xC6, 0x9E, 0xB1, 0xCC, 0x31, 0xC7, 0xC5, 0x2A }, + 79 /* Bin Number */ + }, + { + /* e_Guven_Kok_Elektronik_Sertifika_Hizmet_Saglayicisi */ + { 0xE6, 0x09, 0x07, 0x84, 0x65, 0xA4, 0x19, 0x78, 0x0C, 0xB6, 0xAC, 0x4C, 0x1C, 0x0B, 0xFB, 0x46, + 0x53, 0xD9, 0xD9, 0xCC, 0x6E, 0xB3, 0x94, 0x6E, 0xB7, 0xF3, 0xD6, 0x99, 0x97, 0xBA, 0xD5, 0x98 }, + 100 /* Bin Number */ + }, + { + /* TC_TrustCenter_Class_2_CA_II */ + { 0xE6, 0xB8, 0xF8, 0x76, 0x64, 0x85, 0xF8, 0x07, 0xAE, 0x7F, 0x8D, 0xAC, 0x16, 0x70, 0x46, 0x1F, + 0x07, 0xC0, 0xA1, 0x3E, 0xEF, 0x3A, 0x1F, 0xF7, 0x17, 0x53, 0x8D, 0x7A, 0xBA, 0xD3, 0x91, 0xB4 }, + 72 /* Bin Number */ + }, + { + /* OU_Security_Communication_RootCA1_O_SECOM_Trust_net_C_JP */ + { 0xE7, 0x5E, 0x72, 0xED, 0x9F, 0x56, 0x0E, 0xEC, 0x6E, 0xB4, 0x80, 0x00, 0x73, 0xA4, 0x3F, 0xC3, + 0xAD, 0x19, 0x19, 0x5A, 0x39, 0x22, 0x82, 0x01, 0x78, 0x95, 0x97, 0x4A, 0x99, 0x02, 0x6B, 0x6C }, + 34 /* Bin Number */ + }, + { + /* USERTrust_RSA_Certification_Authority */ + { 0xE7, 0x93, 0xC9, 0xB0, 0x2F, 0xD8, 0xAA, 0x13, 0xE2, 0x1C, 0x31, 0x22, 0x8A, 0xCC, 0xB0, 0x81, + 0x19, 0x64, 0x3B, 0x74, 0x9C, 0x89, 0x89, 0x64, 0xB1, 0x74, 0x6D, 0x46, 0xC3, 0xD4, 0xCB, 0xD2 }, + 155 /* Bin Number */ + }, + { + /* OU_certSIGN_ROOT_CA_O_certSIGN_C_RO */ + { 0xEA, 0xA9, 0x62, 0xC4, 0xFA, 0x4A, 0x6B, 0xAF, 0xEB, 0xE4, 0x15, 0x19, 0x6D, 0x35, 0x1C, 0xCD, + 0x88, 0x8D, 0x4F, 0x53, 0xF3, 0xFA, 0x8A, 0xE6, 0xD7, 0xC4, 0x66, 0xA9, 0x4E, 0x60, 0x42, 0xBB }, + 83 /* Bin Number */ + }, + { + /* VeriSign_Class_3_Public_Primary_Certification_Authority___G3 */ + { 0xEB, 0x04, 0xCF, 0x5E, 0xB1, 0xF3, 0x9A, 0xFA, 0x76, 0x2F, 0x2B, 0xB1, 0x20, 0xF2, 0x96, 0xCB, + 0xA5, 0x20, 0xC1, 0xB9, 0x7D, 0xB1, 0x58, 0x95, 0x65, 0xB8, 0x1C, 0xB9, 0xA1, 0x7B, 0x72, 0x44 }, + 8 /* Bin Number */ + }, + { + /* OU_AC_RAIZ_FNMT_RCM_O_FNMT_RCM_C_ES */ + { 0xEB, 0xC5, 0x57, 0x0C, 0x29, 0x01, 0x8C, 0x4D, 0x67, 0xB1, 0xAA, 0x12, 0x7B, 0xAF, 0x12, 0xF7, + 0x03, 0xB4, 0x61, 0x1E, 0xBC, 0x17, 0xB7, 0xDA, 0xB5, 0x57, 0x38, 0x94, 0x17, 0x9B, 0x93, 0xFA }, + 182 /* Bin Number */ + }, + { + /* GlobalSign_Root_CA */ + { 0xEB, 0xD4, 0x10, 0x40, 0xE4, 0xBB, 0x3E, 0xC7, 0x42, 0xC9, 0xE3, 0x81, 0xD3, 0x1E, 0xF2, 0xA4, + 0x1A, 0x48, 0xB6, 0x68, 0x5C, 0x96, 0xE7, 0xCE, 0xF3, 0xC1, 0xDF, 0x6C, 0xD4, 0x33, 0x1C, 0x99 }, + 6 /* Bin Number */ + }, + { + /* TC_TrustCenter_Universal_CA_I */ + { 0xEB, 0xF3, 0xC0, 0x2A, 0x87, 0x89, 0xB1, 0xFB, 0x7D, 0x51, 0x19, 0x95, 0xD6, 0x63, 0xB7, 0x29, + 0x06, 0xD9, 0x13, 0xCE, 0x0D, 0x5E, 0x10, 0x56, 0x8A, 0x8A, 0x77, 0xE2, 0x58, 0x61, 0x67, 0xE7 }, + 74 /* Bin Number */ + }, + { + /* Juur_SK */ + { 0xEC, 0xC3, 0xE9, 0xC3, 0x40, 0x75, 0x03, 0xBE, 0xE0, 0x91, 0xAA, 0x95, 0x2F, 0x41, 0x34, 0x8F, + 0xF8, 0x8B, 0xAA, 0x86, 0x3B, 0x22, 0x64, 0xBE, 0xFA, 0xC8, 0x07, 0x90, 0x15, 0x74, 0xE9, 0x39 }, + 95 /* Bin Number */ + }, + { + /* Buypass_Class_3_Root_CA */ + { 0xED, 0xF7, 0xEB, 0xBC, 0xA2, 0x7A, 0x2A, 0x38, 0x4D, 0x38, 0x7B, 0x7D, 0x40, 0x10, 0xC6, 0x66, + 0xE2, 0xED, 0xB4, 0x84, 0x3E, 0x4C, 0x29, 0xB4, 0xAE, 0x1D, 0x5B, 0x93, 0x32, 0xE6, 0xB2, 0x4D }, + 126 /* Bin Number */ + }, + { + /* D_TRUST_Root_Class_3_CA_2_EV_2009 */ + { 0xEE, 0xC5, 0x49, 0x6B, 0x98, 0x8C, 0xE9, 0x86, 0x25, 0xB9, 0x34, 0x09, 0x2E, 0xEC, 0x29, 0x08, + 0xBE, 0xD0, 0xB0, 0xF3, 0x16, 0xC2, 0xD4, 0x73, 0x0C, 0x84, 0xEA, 0xF1, 0xF3, 0xD3, 0x48, 0x81 }, + 131 /* Bin Number */ + }, + { + /* Global_Chambersign_Root */ + { 0xEF, 0x3C, 0xB4, 0x17, 0xFC, 0x8E, 0xBF, 0x6F, 0x97, 0x87, 0x6C, 0x9E, 0x4E, 0xCE, 0x39, 0xDE, + 0x1E, 0xA5, 0xFE, 0x64, 0x91, 0x41, 0xD1, 0x02, 0x8B, 0x7D, 0x11, 0xC0, 0xB2, 0x29, 0x8C, 0xED }, + 40 /* Bin Number */ + }, + { + /* Swisscom_Root_CA_2 */ + { 0xF0, 0x9B, 0x12, 0x2C, 0x71, 0x14, 0xF4, 0xA0, 0x9B, 0xD4, 0xEA, 0x4F, 0x4A, 0x99, 0xD5, 0x58, + 0xB4, 0x6E, 0x4C, 0x25, 0xCD, 0x81, 0x14, 0x0D, 0x29, 0xC0, 0x56, 0x13, 0x91, 0x4C, 0x38, 0x41 }, + 134 /* Bin Number */ + }, + { + /* SecureTrust_CA */ + { 0xF1, 0xC1, 0xB5, 0x0A, 0xE5, 0xA2, 0x0D, 0xD8, 0x03, 0x0E, 0xC9, 0xF6, 0xBC, 0x24, 0x82, 0x3D, + 0xD3, 0x67, 0xB5, 0x25, 0x57, 0x59, 0xB4, 0xE7, 0x1B, 0x61, 0xFC, 0xE9, 0xF7, 0x37, 0x5D, 0x73 }, + 61 /* Bin Number */ + }, + { + /* Atos_TrustedRoot_2011 */ + { 0xF3, 0x56, 0xBE, 0xA2, 0x44, 0xB7, 0xA9, 0x1E, 0xB3, 0x5D, 0x53, 0xCA, 0x9A, 0xD7, 0x86, 0x4A, + 0xCE, 0x01, 0x8E, 0x2D, 0x35, 0xD5, 0xF8, 0xF9, 0x6D, 0xDF, 0x68, 0xA6, 0xF4, 0x1A, 0xA4, 0x74 }, + 143 /* Bin Number */ + }, + { + /* CA_Disig_Root_R1 */ + { 0xF9, 0x6F, 0x23, 0xF4, 0xC3, 0xE7, 0x9C, 0x07, 0x7A, 0x46, 0x98, 0x8D, 0x5A, 0xF5, 0x90, 0x06, + 0x76, 0xA0, 0xF0, 0x39, 0xCB, 0x64, 0x5D, 0xD1, 0x75, 0x49, 0xB2, 0x16, 0xC8, 0x24, 0x40, 0xCE }, + 136 /* Bin Number */ + }, + { + /* Hongkong_Post_Root_CA_1 */ + { 0xF9, 0xE6, 0x7D, 0x33, 0x6C, 0x51, 0x00, 0x2A, 0xC0, 0x54, 0xC6, 0x32, 0x02, 0x2D, 0x66, 0xDD, + 0xA2, 0xE7, 0xE3, 0xFF, 0xF1, 0x0A, 0xD0, 0x61, 0xED, 0x31, 0xD8, 0xBB, 0xB4, 0x10, 0xCF, 0xB2 }, + 96 /* Bin Number */ + }, + { + /* Certinomis___Autorit__Racine */ + { 0xFC, 0xBF, 0xE2, 0x88, 0x62, 0x06, 0xF7, 0x2B, 0x27, 0x59, 0x3C, 0x8B, 0x07, 0x02, 0x97, 0xE1, + 0x2D, 0x76, 0x9E, 0xD1, 0x0E, 0xD7, 0x93, 0x07, 0x05, 0xA8, 0x09, 0x8E, 0xFF, 0xC1, 0x4D, 0x17 }, + 114 /* Bin Number */ + }, + { + /* T_TeleSec_GlobalRoot_Class_3 */ + { 0xFD, 0x73, 0xDA, 0xD3, 0x1C, 0x64, 0x4F, 0xF1, 0xB4, 0x3B, 0xEF, 0x0C, 0xCD, 0xDA, 0x96, 0x71, + 0x0B, 0x9C, 0xD9, 0x87, 0x5E, 0xCA, 0x7E, 0x31, 0x70, 0x7A, 0xF3, 0xE9, 0x6D, 0x52, 0x2B, 0xBD }, + 127 /* Bin Number */ + }, + { + /* GeoTrust_Global_CA */ + { 0xFF, 0x85, 0x6A, 0x2D, 0x25, 0x1D, 0xCD, 0x88, 0xD3, 0x66, 0x56, 0xF4, 0x50, 0x12, 0x67, 0x98, + 0xCF, 0xAB, 0xAA, 0xDE, 0x40, 0x79, 0x9C, 0x72, 0x2D, 0xE4, 0xD2, 0xB5, 0xDB, 0x36, 0xA7, 0x3A }, + 20 /* Bin Number */ + }, +}; + diff --git a/security/manager/ssl/SSLServerCertVerification.cpp b/security/manager/ssl/SSLServerCertVerification.cpp new file mode 100644 index 0000000000..3c5512c95e --- /dev/null +++ b/security/manager/ssl/SSLServerCertVerification.cpp @@ -0,0 +1,1422 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +// During certificate authentication, we call CertVerifier::VerifySSLServerCert. +// This function may make zero or more HTTP requests (e.g. to gather revocation +// information). Our fetching logic for these requests processes them on the +// socket transport service thread. +// +// Because the connection for which we are verifying the certificate is +// happening on the socket transport thread, if our cert auth hook were to call +// VerifySSLServerCert directly, there would be a deadlock: VerifySSLServerCert +// would cause an event to be asynchronously posted to the socket transport +// thread, and then it would block the socket transport thread waiting to be +// notified of the HTTP response. However, the HTTP request would never actually +// be processed because the socket transport thread would be blocked and so it +// wouldn't be able process HTTP requests. +// +// Consequently, when we are asked to verify a certificate, we must always call +// VerifySSLServerCert on another thread. To accomplish this, our auth cert hook +// dispatches a SSLServerCertVerificationJob to a pool of background threads, +// and then immediately returns SECWouldBlock to libssl. These jobs are where +// VerifySSLServerCert is actually called. +// +// When our auth cert hook returns SECWouldBlock, libssl will carry on the +// handshake while we validate the certificate. This will free up the socket +// transport thread so that HTTP requests--including the OCSP requests needed +// for cert verification as mentioned above--can be processed. +// +// Once VerifySSLServerCert returns, the cert verification job dispatches a +// SSLServerCertVerificationResult to the socket transport thread; the +// SSLServerCertVerificationResult will notify libssl that the certificate +// authentication is complete. Once libssl is notified that the authentication +// is complete, it will continue the TLS handshake (if it hasn't already +// finished) and it will begin allowing us to send/receive data on the +// connection. +// +// Timeline of events (for connections managed by the socket transport service): +// +// * libssl calls SSLServerCertVerificationJob::Dispatch on the socket +// transport thread. +// * SSLServerCertVerificationJob::Dispatch queues a job +// (instance of SSLServerCertVerificationJob) to its background thread +// pool and returns. +// * One of the background threads calls CertVerifier::VerifySSLServerCert, +// which may enqueue some HTTP request(s) onto the socket transport thread, +// and then blocks that background thread waiting for the responses and/or +// timeouts or errors for those requests. +// * Once those HTTP responses have all come back or failed, the +// CertVerifier::VerifySSLServerCert function returns a result indicating +// that the validation succeeded or failed. +// * If the validation succeeded, then a SSLServerCertVerificationResult +// event is posted to the socket transport thread, and the cert +// verification thread becomes free to verify other certificates. +// * Otherwise, we do cert override processing to see if the validation +// error can be convered by override rules. The result of this processing +// is similarly dispatched in a SSLServerCertVerificationResult. +// * The SSLServerCertVerificationResult event will either wake up the +// socket (using SSL_AuthCertificateComplete) if validation succeeded or +// there was an error override, or it will set an error flag so that the +// next I/O operation on the socket will fail, causing the socket transport +// thread to close the connection. +// +// SSLServerCertVerificationResult must be dispatched to the socket transport +// thread because we must only call SSL_* functions on the socket transport +// thread since they may do I/O, because many parts of nsNSSSocketInfo (the +// subclass of TransportSecurityInfo used when validating certificates during +// an SSL handshake) and the PSM NSS I/O layer are not thread-safe, and because +// we need the event to interrupt the PR_Poll that may waiting for I/O on the +// socket for which we are validating the cert. +// +// When socket process is enabled, libssl is running on socket process. To +// perform certificate authentication with CertVerifier, we have to send all +// needed information to parent process and send the result back to socket +// process via IPC. The workflow is described below. +// 1. In AuthCertificateHookInternal(), we call RemoteProcessCertVerification() +// instead of SSLServerCertVerificationJob::Dispatch when we are on socket +// process. +// 2. In RemoteProcessCertVerification(), PVerifySSLServerCert actors will be +// created on IPDL background thread for carrying needed information via IPC. +// 3. On parent process, VerifySSLServerCertParent is created and it calls +// SSLServerCertVerificationJob::Dispatch for doing certificate verification +// on one of CertVerificationThreads. +// 4. When validation is done, OnVerifiedSSLServerCertSuccess IPC message is +// sent through the IPDL background thread when +// CertVerifier::VerifySSLServerCert returns Success. Otherwise, +// OnVerifiedSSLServerCertFailure is sent. +// 5. After setp 4, PVerifySSLServerCert actors will be released. The +// verification result will be dispatched via +// SSLServerCertVerificationResult. + +#include "SSLServerCertVerification.h" + +#include + +#include "BRNameMatchingPolicy.h" +#include "CertVerifier.h" +#include "CryptoTask.h" +#include "ExtendedValidation.h" +#include "NSSCertDBTrustDomain.h" +#include "PSMRunnable.h" +#include "RootCertificateTelemetryUtils.h" +#include "ScopedNSSTypes.h" +#include "SharedCertVerifier.h" +#include "SharedSSLState.h" +#include "TransportSecurityInfo.h" // For RememberCertErrorsTable +#include "VerifySSLServerCertChild.h" +#include "cert.h" +#include "mozilla/Assertions.h" +#include "mozilla/Casting.h" +#include "mozilla/RefPtr.h" +#include "mozilla/Telemetry.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/Unused.h" +#include "nsComponentManagerUtils.h" +#include "nsContentUtils.h" +#include "nsICertOverrideService.h" +#include "nsISiteSecurityService.h" +#include "nsISocketProvider.h" +#include "nsThreadPool.h" +#include "nsNetUtil.h" +#include "nsNSSCertificate.h" +#include "nsNSSComponent.h" +#include "nsNSSIOLayer.h" +#include "nsServiceManagerUtils.h" +#include "nsString.h" +#include "nsURLHelper.h" +#include "nsXPCOMCIDInternal.h" +#include "mozpkix/pkix.h" +#include "mozpkix/pkixnss.h" +#include "secerr.h" +#include "secport.h" +#include "ssl.h" +#include "sslerr.h" +#include "sslexp.h" + +extern mozilla::LazyLogModule gPIPNSSLog; + +using namespace mozilla::pkix; + +namespace mozilla { +namespace psm { + +namespace { + +// do not use a nsCOMPtr to avoid static initializer/destructor +nsIThreadPool* gCertVerificationThreadPool = nullptr; + +} // unnamed namespace + +// Called when the socket transport thread starts, to initialize the SSL cert +// verification thread pool. By tying the thread pool startup/shutdown directly +// to the STS thread's lifetime, we ensure that they are *always* available for +// SSL connections and that there are no races during startup and especially +// shutdown. (Previously, we have had multiple problems with races in PSM +// background threads, and the race-prevention/shutdown logic used there is +// brittle. Since this service is critical to things like downloading updates, +// we take no chances.) Also, by doing things this way, we avoid the need for +// locks, since gCertVerificationThreadPool is only ever accessed on the socket +// transport thread. +void InitializeSSLServerCertVerificationThreads() { + // TODO: tuning, make parameters preferences + gCertVerificationThreadPool = new nsThreadPool(); + NS_ADDREF(gCertVerificationThreadPool); + + (void)gCertVerificationThreadPool->SetIdleThreadLimit(5); + (void)gCertVerificationThreadPool->SetIdleThreadTimeout(30 * 1000); + (void)gCertVerificationThreadPool->SetThreadLimit(5); + (void)gCertVerificationThreadPool->SetName("SSL Cert"_ns); +} + +// Called when the socket transport thread finishes, to destroy the thread +// pool. Since the socket transport service has stopped processing events, it +// will not attempt any more SSL I/O operations, so it is clearly safe to shut +// down the SSL cert verification infrastructure. Also, the STS will not +// dispatch many SSL verification result events at this point, so any pending +// cert verifications will (correctly) fail at the point they are dispatched. +// +// The other shutdown race condition that is possible is a race condition with +// shutdown of the nsNSSComponent service. We use the +// nsNSSShutdownPreventionLock where needed (not here) to prevent that. +void StopSSLServerCertVerificationThreads() { + if (gCertVerificationThreadPool) { + gCertVerificationThreadPool->Shutdown(); + NS_RELEASE(gCertVerificationThreadPool); + } +} + +namespace { + +// A probe value of 1 means "no error". +uint32_t MapOverridableErrorToProbeValue(PRErrorCode errorCode) { + switch (errorCode) { + case SEC_ERROR_UNKNOWN_ISSUER: + return 2; + case SEC_ERROR_CA_CERT_INVALID: + return 3; + case SEC_ERROR_UNTRUSTED_ISSUER: + return 4; + case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: + return 5; + case SEC_ERROR_UNTRUSTED_CERT: + return 6; + case SEC_ERROR_INADEQUATE_KEY_USAGE: + return 7; + case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: + return 8; + case SSL_ERROR_BAD_CERT_DOMAIN: + return 9; + case SEC_ERROR_EXPIRED_CERTIFICATE: + return 10; + case mozilla::pkix::MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY: + return 11; + case mozilla::pkix::MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA: + return 12; + case mozilla::pkix::MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE: + return 13; + case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE: + return 14; + case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE: + return 15; + case SEC_ERROR_INVALID_TIME: + return 16; + case mozilla::pkix::MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME: + return 17; + case mozilla::pkix::MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED: + return 18; + case mozilla::pkix::MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT: + return 19; + case mozilla::pkix::MOZILLA_PKIX_ERROR_MITM_DETECTED: + return 20; + } + NS_WARNING( + "Unknown certificate error code. Does MapOverridableErrorToProbeValue " + "handle everything in DetermineCertOverrideErrors?"); + return 0; +} + +static uint32_t MapCertErrorToProbeValue(PRErrorCode errorCode) { + uint32_t probeValue; + switch (errorCode) { + // see security/pkix/include/pkix/Result.h +#define MOZILLA_PKIX_MAP(name, value, nss_name) \ + case nss_name: \ + probeValue = value; \ + break; + MOZILLA_PKIX_MAP_LIST +#undef MOZILLA_PKIX_MAP + default: + return 0; + } + + // Since FATAL_ERROR_FLAG is 0x800, fatal error values are much larger than + // non-fatal error values. To conserve space, we remap these so they start at + // (decimal) 90 instead of 0x800. Currently there are ~50 non-fatal errors + // mozilla::pkix might return, so saving space for 90 should be sufficient + // (similarly, there are 4 fatal errors, so saving space for 10 should also + // be sufficient). + static_assert( + FATAL_ERROR_FLAG == 0x800, + "mozilla::pkix::FATAL_ERROR_FLAG is not what we were expecting"); + if (probeValue & FATAL_ERROR_FLAG) { + probeValue ^= FATAL_ERROR_FLAG; + probeValue += 90; + } + return probeValue; +} + +SECStatus DetermineCertOverrideErrors(const UniqueCERTCertificate& cert, + const nsACString& hostName, PRTime now, + PRErrorCode defaultErrorCodeToReport, + /*out*/ uint32_t& collectedErrors, + /*out*/ PRErrorCode& errorCodeTrust, + /*out*/ PRErrorCode& errorCodeMismatch, + /*out*/ PRErrorCode& errorCodeTime) { + MOZ_ASSERT(cert); + MOZ_ASSERT(collectedErrors == 0); + MOZ_ASSERT(errorCodeTrust == 0); + MOZ_ASSERT(errorCodeMismatch == 0); + MOZ_ASSERT(errorCodeTime == 0); + + // Assumes the error prioritization described in mozilla::pkix's + // BuildForward function. Also assumes that CheckCertHostname was only + // called if CertVerifier::VerifyCert succeeded. + switch (defaultErrorCodeToReport) { + case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: + case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: + case SEC_ERROR_UNKNOWN_ISSUER: + case SEC_ERROR_CA_CERT_INVALID: + case mozilla::pkix::MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED: + case mozilla::pkix::MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY: + case mozilla::pkix::MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME: + case mozilla::pkix::MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE: + case mozilla::pkix::MOZILLA_PKIX_ERROR_MITM_DETECTED: + case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE: + case mozilla::pkix::MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT: + case mozilla::pkix::MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA: { + collectedErrors = nsICertOverrideService::ERROR_UNTRUSTED; + errorCodeTrust = defaultErrorCodeToReport; + + SECCertTimeValidity validity = + CERT_CheckCertValidTimes(cert.get(), now, false); + if (validity == secCertTimeUndetermined) { + // This only happens if cert is null. CERT_CheckCertValidTimes will + // have set the error code to SEC_ERROR_INVALID_ARGS. We should really + // be using mozilla::pkix here anyway. + MOZ_ASSERT(PR_GetError() == SEC_ERROR_INVALID_ARGS); + return SECFailure; + } + if (validity == secCertTimeExpired) { + collectedErrors |= nsICertOverrideService::ERROR_TIME; + errorCodeTime = SEC_ERROR_EXPIRED_CERTIFICATE; + } else if (validity == secCertTimeNotValidYet) { + collectedErrors |= nsICertOverrideService::ERROR_TIME; + errorCodeTime = + mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE; + } + break; + } + + case SEC_ERROR_INVALID_TIME: + case SEC_ERROR_EXPIRED_CERTIFICATE: + case mozilla::pkix::MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE: + collectedErrors = nsICertOverrideService::ERROR_TIME; + errorCodeTime = defaultErrorCodeToReport; + break; + + case SSL_ERROR_BAD_CERT_DOMAIN: + collectedErrors = nsICertOverrideService::ERROR_MISMATCH; + errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN; + break; + + case 0: + NS_ERROR("No error code set during certificate validation failure."); + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return SECFailure; + + default: + PR_SetError(defaultErrorCodeToReport, 0); + return SECFailure; + } + + if (defaultErrorCodeToReport != SSL_ERROR_BAD_CERT_DOMAIN) { + Input certInput; + if (certInput.Init(cert->derCert.data, cert->derCert.len) != Success) { + PR_SetError(SEC_ERROR_BAD_DER, 0); + return SECFailure; + } + Input hostnameInput; + Result result = hostnameInput.Init( + BitwiseCast(hostName.BeginReading()), + hostName.Length()); + if (result != Success) { + PR_SetError(SEC_ERROR_INVALID_ARGS, 0); + return SECFailure; + } + // Use a lax policy so as to not generate potentially spurious name + // mismatch "hints". + BRNameMatchingPolicy nameMatchingPolicy( + BRNameMatchingPolicy::Mode::DoNotEnforce); + // CheckCertHostname expects that its input represents a certificate that + // has already been successfully validated by BuildCertChain. This is + // obviously not the case, however, because we're in the error path of + // certificate verification. Thus, this is problematic. In the future, it + // would be nice to remove this optimistic additional error checking and + // simply punt to the front-end, which can more easily (and safely) perform + // extra checks to give the user hints as to why verification failed. + result = CheckCertHostname(certInput, hostnameInput, nameMatchingPolicy); + // Treat malformed name information as a domain mismatch. + if (result == Result::ERROR_BAD_DER || + result == Result::ERROR_BAD_CERT_DOMAIN) { + collectedErrors |= nsICertOverrideService::ERROR_MISMATCH; + errorCodeMismatch = SSL_ERROR_BAD_CERT_DOMAIN; + } else if (IsFatalError(result)) { + // Because its input has not been validated by BuildCertChain, + // CheckCertHostname can return an error that is less important than the + // original certificate verification error. Only return an error result + // from this function if we've encountered a fatal error. + PR_SetError(MapResultToPRErrorCode(result), 0); + return SECFailure; + } + } + + return SECSuccess; +} + +// Helper function to determine if overrides are allowed for this host. +// Overrides are not allowed for known HSTS hosts or hosts with pinning +// information. However, IP addresses can never be HSTS hosts and don't have +// pinning information. +static nsresult OverrideAllowedForHost( + uint64_t aPtrForLog, const nsACString& aHostname, + const OriginAttributes& aOriginAttributes, uint32_t aProviderFlags, + /*out*/ bool& aOverrideAllowed) { + aOverrideAllowed = false; + + // If this is an IP address, overrides are allowed, because an IP address is + // never an HSTS host. nsISiteSecurityService takes this into account + // already, but the real problem here is that calling NS_NewURI with an IPv6 + // address fails. We do this to avoid that. A more comprehensive fix would be + // to have Necko provide an nsIURI to PSM and to use that here (and + // everywhere). However, that would be a wide-spanning change. + if (net_IsValidIPv6Addr(aHostname)) { + aOverrideAllowed = true; + return NS_OK; + } + + // If this is an HTTP Strict Transport Security host or a pinned host and the + // certificate is bad, don't allow overrides (RFC 6797 section 12.1). + bool strictTransportSecurityEnabled = false; + bool isStaticallyPinned = false; + nsCOMPtr sss(do_GetService(NS_SSSERVICE_CONTRACTID)); + if (!sss) { + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("[0x%" PRIx64 "] Couldn't get nsISiteSecurityService to check HSTS", + aPtrForLog)); + return NS_ERROR_FAILURE; + } + + nsCOMPtr uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), "https://"_ns + aHostname); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[0x%" PRIx64 "] Creating new URI failed", aPtrForLog)); + return rv; + } + + rv = sss->IsSecureURI(nsISiteSecurityService::HEADER_HSTS, uri, + aProviderFlags, aOriginAttributes, nullptr, nullptr, + &strictTransportSecurityEnabled); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[0x%" PRIx64 "] checking for HSTS failed", aPtrForLog)); + return rv; + } + + rv = sss->IsSecureURI(nsISiteSecurityService::STATIC_PINNING, uri, + aProviderFlags, aOriginAttributes, nullptr, nullptr, + &isStaticallyPinned); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[0x%" PRIx64 "] checking for static pin failed", aPtrForLog)); + return rv; + } + + aOverrideAllowed = !strictTransportSecurityEnabled && !isStaticallyPinned; + return NS_OK; +} + +// This function assumes that we will only use the SPDY connection coalescing +// feature on connections where we have negotiated SPDY using NPN. If we ever +// talk SPDY without having negotiated it with SPDY, this code will give wrong +// and perhaps unsafe results. +// +// Returns SECSuccess on the initial handshake of all connections, on +// renegotiations for any connections where we did not negotiate SPDY, or on any +// SPDY connection where the server's certificate did not change. +// +// Prohibit changing the server cert only if we negotiated SPDY, +// in order to support SPDY's cross-origin connection pooling. +static SECStatus BlockServerCertChangeForSpdy( + nsNSSSocketInfo* infoObject, const UniqueCERTCertificate& serverCert) { + // Get the existing cert. If there isn't one, then there is + // no cert change to worry about. + nsCOMPtr cert; + + if (!infoObject->IsHandshakeCompleted()) { + // first handshake on this connection, not a + // renegotiation. + return SECSuccess; + } + + infoObject->GetServerCert(getter_AddRefs(cert)); + if (!cert) { + MOZ_ASSERT_UNREACHABLE( + "TransportSecurityInfo must have a cert implementing nsIX509Cert"); + PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); + return SECFailure; + } + + // Filter out sockets that did not neogtiate SPDY via NPN + nsAutoCString negotiatedNPN; + nsresult rv = infoObject->GetNegotiatedNPN(negotiatedNPN); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "GetNegotiatedNPN() failed during renegotiation"); + + if (NS_SUCCEEDED(rv) && !StringBeginsWith(negotiatedNPN, "spdy/"_ns)) { + return SECSuccess; + } + // If GetNegotiatedNPN() failed we will assume spdy for safety's safe + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("BlockServerCertChangeForSpdy failed GetNegotiatedNPN() call." + " Assuming spdy.\n")); + } + + // Check to see if the cert has actually changed + UniqueCERTCertificate c(cert->GetCert()); + MOZ_ASSERT(c, "Somehow couldn't get underlying cert from nsIX509Cert"); + bool sameCert = CERT_CompareCerts(c.get(), serverCert.get()); + if (sameCert) { + return SECSuccess; + } + + // Report an error - changed cert is confirmed + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("SPDY Refused to allow new cert during renegotiation\n")); + PR_SetError(SSL_ERROR_RENEGOTIATION_NOT_ALLOWED, 0); + return SECFailure; +} + +// Gather telemetry on whether the end-entity cert for a server has the +// required TLS Server Authentication EKU, or any others +void GatherEKUTelemetry(const UniqueCERTCertList& certList) { + CERTCertListNode* endEntityNode = CERT_LIST_HEAD(certList); + CERTCertListNode* rootNode = CERT_LIST_TAIL(certList); + MOZ_ASSERT(!(CERT_LIST_END(endEntityNode, certList) || + CERT_LIST_END(rootNode, certList))); + if (CERT_LIST_END(endEntityNode, certList) || + CERT_LIST_END(rootNode, certList)) { + return; + } + CERTCertificate* endEntityCert = endEntityNode->cert; + MOZ_ASSERT(endEntityCert); + if (!endEntityCert) { + return; + } + + // Only log telemetry if the root CA is built-in + CERTCertificate* rootCert = rootNode->cert; + MOZ_ASSERT(rootCert); + if (!rootCert) { + return; + } + bool isBuiltIn = false; + Result rv = IsCertBuiltInRoot(rootCert, isBuiltIn); + if (rv != Success || !isBuiltIn) { + return; + } + + // Find the EKU extension, if present + bool foundEKU = false; + SECOidTag oidTag; + CERTCertExtension* ekuExtension = nullptr; + for (size_t i = 0; endEntityCert->extensions && endEntityCert->extensions[i]; + i++) { + oidTag = SECOID_FindOIDTag(&endEntityCert->extensions[i]->id); + if (oidTag == SEC_OID_X509_EXT_KEY_USAGE) { + foundEKU = true; + ekuExtension = endEntityCert->extensions[i]; + } + } + + if (!foundEKU) { + Telemetry::Accumulate(Telemetry::SSL_SERVER_AUTH_EKU, 0); + return; + } + + // Parse the EKU extension + UniqueCERTOidSequence ekuSequence( + CERT_DecodeOidSequence(&ekuExtension->value)); + if (!ekuSequence) { + return; + } + + // Search through the available EKUs + bool foundServerAuth = false; + bool foundOther = false; + for (SECItem** oids = ekuSequence->oids; oids && *oids; oids++) { + oidTag = SECOID_FindOIDTag(*oids); + if (oidTag == SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) { + foundServerAuth = true; + } else { + foundOther = true; + } + } + + // Cases 3 is included only for completeness. It should never + // appear in these statistics, because CheckExtendedKeyUsage() + // should require the EKU extension, if present, to contain the + // value id_kp_serverAuth. + if (foundServerAuth && !foundOther) { + Telemetry::Accumulate(Telemetry::SSL_SERVER_AUTH_EKU, 1); + } else if (foundServerAuth && foundOther) { + Telemetry::Accumulate(Telemetry::SSL_SERVER_AUTH_EKU, 2); + } else if (!foundServerAuth) { + Telemetry::Accumulate(Telemetry::SSL_SERVER_AUTH_EKU, 3); + } +} + +// Gathers telemetry on which CA is the root of a given cert chain. +// If the root is a built-in root, then the telemetry makes a count +// by root. Roots that are not built-in are counted in one bin. +void GatherRootCATelemetry(const UniqueCERTCertList& certList) { + CERTCertListNode* rootNode = CERT_LIST_TAIL(certList); + MOZ_ASSERT(rootNode); + if (!rootNode) { + return; + } + MOZ_ASSERT(!CERT_LIST_END(rootNode, certList)); + if (CERT_LIST_END(rootNode, certList)) { + return; + } + CERTCertificate* rootCert = rootNode->cert; + MOZ_ASSERT(rootCert); + if (!rootCert) { + return; + } + Span certSpan = {rootCert->derCert.data, rootCert->derCert.len}; + AccumulateTelemetryForRootCA(Telemetry::CERT_VALIDATION_SUCCESS_BY_CA, + certSpan); +} + +// There are various things that we want to measure about certificate +// chains that we accept. This is a single entry point for all of them. +void GatherSuccessfulValidationTelemetry(const UniqueCERTCertList& certList) { + GatherEKUTelemetry(certList); + GatherRootCATelemetry(certList); +} + +void GatherTelemetryForSingleSCT(const ct::VerifiedSCT& verifiedSct) { + // See SSL_SCTS_ORIGIN in Histograms.json. + uint32_t origin = 0; + switch (verifiedSct.origin) { + case ct::VerifiedSCT::Origin::Embedded: + origin = 1; + break; + case ct::VerifiedSCT::Origin::TLSExtension: + origin = 2; + break; + case ct::VerifiedSCT::Origin::OCSPResponse: + origin = 3; + break; + default: + MOZ_ASSERT_UNREACHABLE("Unexpected VerifiedSCT::Origin type"); + } + Telemetry::Accumulate(Telemetry::SSL_SCTS_ORIGIN, origin); + + // See SSL_SCTS_VERIFICATION_STATUS in Histograms.json. + uint32_t verificationStatus = 0; + switch (verifiedSct.status) { + case ct::VerifiedSCT::Status::Valid: + verificationStatus = 1; + break; + case ct::VerifiedSCT::Status::UnknownLog: + verificationStatus = 2; + break; + case ct::VerifiedSCT::Status::InvalidSignature: + verificationStatus = 3; + break; + case ct::VerifiedSCT::Status::InvalidTimestamp: + verificationStatus = 4; + break; + case ct::VerifiedSCT::Status::ValidFromDisqualifiedLog: + verificationStatus = 5; + break; + default: + MOZ_ASSERT_UNREACHABLE("Unexpected VerifiedSCT::Status type"); + } + Telemetry::Accumulate(Telemetry::SSL_SCTS_VERIFICATION_STATUS, + verificationStatus); +} + +void GatherCertificateTransparencyTelemetry( + const UniqueCERTCertList& certList, bool isEV, + const CertificateTransparencyInfo& info) { + if (!info.enabled) { + // No telemetry is gathered when CT is disabled. + return; + } + + for (const ct::VerifiedSCT& sct : info.verifyResult.verifiedScts) { + GatherTelemetryForSingleSCT(sct); + } + + // Decoding errors are reported to the 0th bucket + // of the SSL_SCTS_VERIFICATION_STATUS enumerated probe. + for (size_t i = 0; i < info.verifyResult.decodingErrors; ++i) { + Telemetry::Accumulate(Telemetry::SSL_SCTS_VERIFICATION_STATUS, 0); + } + + // Handle the histogram of SCTs counts. + uint32_t sctsCount = + static_cast(info.verifyResult.verifiedScts.size()); + // Note that sctsCount can also be 0 in case we've received SCT binary data, + // but it failed to parse (e.g. due to unsupported CT protocol version). + Telemetry::Accumulate(Telemetry::SSL_SCTS_PER_CONNECTION, sctsCount); + + // Report CT Policy compliance of EV certificates. + if (isEV) { + uint32_t evCompliance = 0; + switch (info.policyCompliance) { + case ct::CTPolicyCompliance::Compliant: + evCompliance = 1; + break; + case ct::CTPolicyCompliance::NotEnoughScts: + evCompliance = 2; + break; + case ct::CTPolicyCompliance::NotDiverseScts: + evCompliance = 3; + break; + case ct::CTPolicyCompliance::Unknown: + default: + MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type"); + } + Telemetry::Accumulate(Telemetry::SSL_CT_POLICY_COMPLIANCE_OF_EV_CERTS, + evCompliance); + } + + // Get the root cert. + CERTCertListNode* rootNode = CERT_LIST_TAIL(certList); + MOZ_ASSERT(rootNode); + if (!rootNode) { + return; + } + MOZ_ASSERT(!CERT_LIST_END(rootNode, certList)); + if (CERT_LIST_END(rootNode, certList)) { + return; + } + CERTCertificate* rootCert = rootNode->cert; + MOZ_ASSERT(rootCert); + if (!rootCert) { + return; + } + + // Report CT Policy compliance by CA. + Span certSpan = {rootCert->derCert.data, rootCert->derCert.len}; + switch (info.policyCompliance) { + case ct::CTPolicyCompliance::Compliant: + AccumulateTelemetryForRootCA( + Telemetry::SSL_CT_POLICY_COMPLIANT_CONNECTIONS_BY_CA, certSpan); + break; + case ct::CTPolicyCompliance::NotEnoughScts: + case ct::CTPolicyCompliance::NotDiverseScts: + AccumulateTelemetryForRootCA( + Telemetry::SSL_CT_POLICY_NON_COMPLIANT_CONNECTIONS_BY_CA, certSpan); + break; + case ct::CTPolicyCompliance::Unknown: + default: + MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type"); + } +} + +// This function collects telemetry about certs. It will be called on one of +// CertVerificationThread. When the socket process is used this will be called +// on the parent process. +static void CollectCertTelemetry( + mozilla::pkix::Result aCertVerificationResult, SECOidTag aEvOidPolicy, + CertVerifier::OCSPStaplingStatus aOcspStaplingStatus, + KeySizeStatus aKeySizeStatus, SHA1ModeResult aSha1ModeResult, + const PinningTelemetryInfo& aPinningTelemetryInfo, + const UniqueCERTCertList& aBuiltCertChain, + const CertificateTransparencyInfo& aCertificateTransparencyInfo, + const CRLiteLookupResult& aCRLiteLookupResult) { + uint32_t evStatus = (aCertVerificationResult != Success) ? 0 // 0 = Failure + : (aEvOidPolicy == SEC_OID_UNKNOWN) ? 1 // 1 = DV + : 2; // 2 = EV + Telemetry::Accumulate(Telemetry::CERT_EV_STATUS, evStatus); + + if (aOcspStaplingStatus != CertVerifier::OCSP_STAPLING_NEVER_CHECKED) { + Telemetry::Accumulate(Telemetry::SSL_OCSP_STAPLING, aOcspStaplingStatus); + } + + if (aKeySizeStatus != KeySizeStatus::NeverChecked) { + Telemetry::Accumulate(Telemetry::CERT_CHAIN_KEY_SIZE_STATUS, + static_cast(aKeySizeStatus)); + } + + if (aSha1ModeResult != SHA1ModeResult::NeverChecked) { + Telemetry::Accumulate(Telemetry::CERT_CHAIN_SHA1_POLICY_STATUS, + static_cast(aSha1ModeResult)); + } + + if (aPinningTelemetryInfo.accumulateForRoot) { + Telemetry::Accumulate(Telemetry::CERT_PINNING_FAILURES_BY_CA, + aPinningTelemetryInfo.rootBucket); + } + + if (aPinningTelemetryInfo.accumulateResult) { + MOZ_ASSERT(aPinningTelemetryInfo.certPinningResultHistogram.isSome()); + Telemetry::Accumulate( + aPinningTelemetryInfo.certPinningResultHistogram.value(), + aPinningTelemetryInfo.certPinningResultBucket); + } + + if (aCertVerificationResult == Success) { + GatherSuccessfulValidationTelemetry(aBuiltCertChain); + GatherCertificateTransparencyTelemetry( + aBuiltCertChain, + /*isEV*/ aEvOidPolicy != SEC_OID_UNKNOWN, aCertificateTransparencyInfo); + } + + switch (aCRLiteLookupResult) { + case CRLiteLookupResult::FilterNotAvailable: + Telemetry::AccumulateCategorical( + Telemetry::LABELS_CRLITE_RESULT::FilterNotAvailable); + break; + case CRLiteLookupResult::IssuerNotEnrolled: + Telemetry::AccumulateCategorical( + Telemetry::LABELS_CRLITE_RESULT::IssuerNotEnrolled); + break; + case CRLiteLookupResult::CertificateTooNew: + Telemetry::AccumulateCategorical( + Telemetry::LABELS_CRLITE_RESULT::CertificateTooNew); + break; + case CRLiteLookupResult::CertificateValid: + Telemetry::AccumulateCategorical( + Telemetry::LABELS_CRLITE_RESULT::CertificateValid); + break; + case CRLiteLookupResult::CertificateRevoked: + Telemetry::AccumulateCategorical( + Telemetry::LABELS_CRLITE_RESULT::CertificateRevoked); + break; + case CRLiteLookupResult::LibraryFailure: + Telemetry::AccumulateCategorical( + Telemetry::LABELS_CRLITE_RESULT::LibraryFailure); + break; + case CRLiteLookupResult::CertRevokedByStash: + Telemetry::AccumulateCategorical( + Telemetry::LABELS_CRLITE_RESULT::CertRevokedByStash); + break; + case CRLiteLookupResult::NeverChecked: + break; + default: + MOZ_ASSERT_UNREACHABLE("Unhandled CRLiteLookupResult value?"); + break; + } +} + +static void AuthCertificateSetResults( + TransportSecurityInfo* aInfoObject, nsNSSCertificate* aCert, + nsTArray>&& aBuiltCertChain, + nsTArray>&& aPeerCertChain, + uint16_t aCertificateTransparencyStatus, EVStatus aEvStatus, + bool aSucceeded, bool aIsCertChainRootBuiltInRoot) { + MOZ_ASSERT(aInfoObject); + + if (aSucceeded) { + // Certificate verification succeeded. Delete any potential record of + // certificate error bits. + RememberCertErrorsTable::GetInstance().RememberCertHasError(aInfoObject, + SECSuccess); + + aInfoObject->SetServerCert(aCert, aEvStatus); + aInfoObject->SetSucceededCertChain(std::move(aBuiltCertChain)); + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("AuthCertificate setting NEW cert %p", aCert)); + + aInfoObject->SetIsBuiltCertChainRootBuiltInRoot( + aIsCertChainRootBuiltInRoot); + aInfoObject->SetCertificateTransparencyStatus( + aCertificateTransparencyStatus); + } else { + // Certificate validation failed; store the peer certificate chain on + // infoObject so it can be used for error reporting. + aInfoObject->SetFailedCertChain(std::move(aPeerCertChain)); + } +} + +// Note: Takes ownership of |peerCertChain| if SECSuccess is not returned. +Result AuthCertificate( + CertVerifier& certVerifier, void* aPinArg, + const UniqueCERTCertificate& cert, + const nsTArray>& peerCertChain, + const nsACString& aHostName, const OriginAttributes& aOriginAttributes, + const Maybe>& stapledOCSPResponse, + const Maybe>& sctsFromTLSExtension, + const Maybe& dcInfo, uint32_t providerFlags, + Time time, uint32_t certVerifierFlags, + /*out*/ UniqueCERTCertList& builtCertChain, + /*out*/ SECOidTag& evOidPolicy, + /*out*/ CertificateTransparencyInfo& certificateTransparencyInfo, + /*out*/ bool& aIsCertChainRootBuiltInRoot) { + MOZ_ASSERT(cert); + + // We want to avoid storing any intermediate cert information when browsing + // in private, transient contexts. + bool saveIntermediates = + !(providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE); + + CertVerifier::OCSPStaplingStatus ocspStaplingStatus = + CertVerifier::OCSP_STAPLING_NEVER_CHECKED; + KeySizeStatus keySizeStatus = KeySizeStatus::NeverChecked; + SHA1ModeResult sha1ModeResult = SHA1ModeResult::NeverChecked; + PinningTelemetryInfo pinningTelemetryInfo; + CRLiteLookupResult crliteTelemetryInfo; + + nsTArray> peerCertsBytes; + // Don't include the end-entity certificate. + if (!peerCertChain.IsEmpty()) { + std::transform( + peerCertChain.cbegin() + 1, peerCertChain.cend(), + MakeBackInserter(peerCertsBytes), + [](const auto& elementArray) { return elementArray.Clone(); }); + } + + Result rv = certVerifier.VerifySSLServerCert( + cert, time, aPinArg, aHostName, builtCertChain, certVerifierFlags, + Some(std::move(peerCertsBytes)), stapledOCSPResponse, + sctsFromTLSExtension, dcInfo, aOriginAttributes, saveIntermediates, + &evOidPolicy, &ocspStaplingStatus, &keySizeStatus, &sha1ModeResult, + &pinningTelemetryInfo, &certificateTransparencyInfo, &crliteTelemetryInfo, + &aIsCertChainRootBuiltInRoot); + + CollectCertTelemetry(rv, evOidPolicy, ocspStaplingStatus, keySizeStatus, + sha1ModeResult, pinningTelemetryInfo, builtCertChain, + certificateTransparencyInfo, crliteTelemetryInfo); + + return rv; +} + +PRErrorCode AuthCertificateParseResults( + uint64_t aPtrForLog, const nsACString& aHostName, int32_t aPort, + const OriginAttributes& aOriginAttributes, + const UniqueCERTCertificate& aCert, uint32_t aProviderFlags, PRTime aPRTime, + PRErrorCode aDefaultErrorCodeToReport, + /* out */ uint32_t& aCollectedErrors) { + if (aDefaultErrorCodeToReport == 0) { + MOZ_ASSERT_UNREACHABLE( + "No error set during certificate validation failure"); + return SEC_ERROR_LIBRARY_FAILURE; + } + + uint32_t probeValue = MapCertErrorToProbeValue(aDefaultErrorCodeToReport); + Telemetry::Accumulate(Telemetry::SSL_CERT_VERIFICATION_ERRORS, probeValue); + + aCollectedErrors = 0; + PRErrorCode errorCodeTrust = 0; + PRErrorCode errorCodeMismatch = 0; + PRErrorCode errorCodeTime = 0; + if (DetermineCertOverrideErrors(aCert, aHostName, aPRTime, + aDefaultErrorCodeToReport, aCollectedErrors, + errorCodeTrust, errorCodeMismatch, + errorCodeTime) != SECSuccess) { + PRErrorCode errorCode = PR_GetError(); + MOZ_ASSERT(!ErrorIsOverridable(errorCode)); + if (errorCode == 0) { + MOZ_ASSERT_UNREACHABLE( + "No error set during DetermineCertOverrideErrors failure"); + return SEC_ERROR_LIBRARY_FAILURE; + } + return errorCode; + } + + if (!aCollectedErrors) { + MOZ_ASSERT_UNREACHABLE("aCollectedErrors should not be 0"); + return SEC_ERROR_LIBRARY_FAILURE; + } + + bool overrideAllowed = false; + if (NS_FAILED(OverrideAllowedForHost(aPtrForLog, aHostName, aOriginAttributes, + aProviderFlags, overrideAllowed))) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[0x%" PRIx64 "] AuthCertificateParseResults - " + "OverrideAllowedForHost failed\n", + aPtrForLog)); + return aDefaultErrorCodeToReport; + } + + if (overrideAllowed) { + nsCOMPtr overrideService = + do_GetService(NS_CERTOVERRIDE_CONTRACTID); + + uint32_t overrideBits = 0; + uint32_t remainingDisplayErrors = aCollectedErrors; + + // it is fine to continue without the nsICertOverrideService + if (overrideService) { + bool haveOverride; + bool isTemporaryOverride; // we don't care + RefPtr nssCert(nsNSSCertificate::Create(aCert.get())); + if (!nssCert) { + MOZ_ASSERT(false, "nsNSSCertificate::Create failed"); + return SEC_ERROR_NO_MEMORY; + } + nsresult rv = overrideService->HasMatchingOverride( + aHostName, aPort, nssCert, &overrideBits, &isTemporaryOverride, + &haveOverride); + if (NS_SUCCEEDED(rv) && haveOverride) { + // remove the errors that are already overriden + remainingDisplayErrors &= ~overrideBits; + } + } + + if (!remainingDisplayErrors) { + // This can double- or triple-count one certificate with multiple + // different types of errors. Since this is telemetry and we just + // want a ballpark answer, we don't care. + if (errorCodeTrust != 0) { + uint32_t probeValue = MapOverridableErrorToProbeValue(errorCodeTrust); + Telemetry::Accumulate(Telemetry::SSL_CERT_ERROR_OVERRIDES, probeValue); + } + if (errorCodeMismatch != 0) { + uint32_t probeValue = + MapOverridableErrorToProbeValue(errorCodeMismatch); + Telemetry::Accumulate(Telemetry::SSL_CERT_ERROR_OVERRIDES, probeValue); + } + if (errorCodeTime != 0) { + uint32_t probeValue = MapOverridableErrorToProbeValue(errorCodeTime); + Telemetry::Accumulate(Telemetry::SSL_CERT_ERROR_OVERRIDES, probeValue); + } + + // all errors are covered by override rules, so let's accept the cert + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("[0x%" PRIx64 "] All errors covered by override rules", aPtrForLog)); + return 0; + } + } else { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[0x%" PRIx64 "] HSTS or pinned host - no overrides allowed\n", + aPtrForLog)); + } + + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("[0x%" PRIx64 "] Certificate error was not overridden\n", aPtrForLog)); + + // pick the error code to report by priority + return errorCodeTrust ? errorCodeTrust + : errorCodeMismatch ? errorCodeMismatch + : errorCodeTime ? errorCodeTime + : aDefaultErrorCodeToReport; +} + +} // unnamed namespace + +/*static*/ +SECStatus SSLServerCertVerificationJob::Dispatch( + uint64_t addrForLogging, void* aPinArg, + const UniqueCERTCertificate& serverCert, + nsTArray>&& peerCertChain, const nsACString& aHostName, + int32_t aPort, const OriginAttributes& aOriginAttributes, + Maybe>& stapledOCSPResponse, + Maybe>& sctsFromTLSExtension, + Maybe& dcInfo, uint32_t providerFlags, Time time, + PRTime prtime, uint32_t certVerifierFlags, + BaseSSLServerCertVerificationResult* aResultTask) { + // Runs on the socket transport thread + if (!aResultTask || !serverCert) { + NS_ERROR("Invalid parameters for SSL server cert validation"); + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return SECFailure; + } + + if (!gCertVerificationThreadPool) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return SECFailure; + } + + RefPtr job(new SSLServerCertVerificationJob( + addrForLogging, aPinArg, serverCert, std::move(peerCertChain), aHostName, + aPort, aOriginAttributes, stapledOCSPResponse, sctsFromTLSExtension, + dcInfo, providerFlags, time, prtime, certVerifierFlags, aResultTask)); + + nsresult nrv = gCertVerificationThreadPool->Dispatch(job, NS_DISPATCH_NORMAL); + if (NS_FAILED(nrv)) { + // We can't call SetCertVerificationResult here to change + // mCertVerificationState because SetCertVerificationResult will call + // libssl functions that acquire SSL locks that are already being held at + // this point. However, we can set an error with PR_SetError and return + // SECFailure, and the correct thing will happen (the error will be + // propagated and this connection will be terminated). + PRErrorCode error = nrv == NS_ERROR_OUT_OF_MEMORY ? PR_OUT_OF_MEMORY_ERROR + : PR_INVALID_STATE_ERROR; + PR_SetError(error, 0); + return SECFailure; + } + + PR_SetError(PR_WOULD_BLOCK_ERROR, 0); + return SECWouldBlock; +} + +NS_IMETHODIMP +SSLServerCertVerificationJob::Run() { + // Runs on a cert verification thread and only on parent process. + MOZ_ASSERT(XRE_IsParentProcess()); + + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("[%" PRIx64 "] SSLServerCertVerificationJob::Run\n", mAddrForLogging)); + + RefPtr certVerifier(GetDefaultCertVerifier()); + if (!certVerifier) { + PR_SetError(SEC_ERROR_NOT_INITIALIZED, 0); + return NS_OK; + } + + TimeStamp jobStartTime = TimeStamp::Now(); + UniqueCERTCertList builtCertChain; + SECOidTag evOidPolicy; + CertificateTransparencyInfo certificateTransparencyInfo; + bool isCertChainRootBuiltInRoot = false; + Result rv = AuthCertificate( + *certVerifier, mPinArg, mCert, mPeerCertChain, mHostName, + mOriginAttributes, mStapledOCSPResponse, mSCTsFromTLSExtension, mDCInfo, + mProviderFlags, mTime, mCertVerifierFlags, builtCertChain, evOidPolicy, + certificateTransparencyInfo, isCertChainRootBuiltInRoot); + + RefPtr nsc = nsNSSCertificate::Create(mCert.get()); + nsTArray> certBytesArray; + if (rv == Success) { + Telemetry::AccumulateTimeDelta( + Telemetry::SSL_SUCCESFUL_CERT_VALIDATION_TIME_MOZILLAPKIX, jobStartTime, + TimeStamp::Now()); + Telemetry::Accumulate(Telemetry::SSL_CERT_ERROR_OVERRIDES, 1); + + certBytesArray = + TransportSecurityInfo::CreateCertBytesArray(builtCertChain); + EVStatus evStatus = + evOidPolicy == SEC_OID_UNKNOWN ? EVStatus::NotEV : EVStatus::EV; + mResultTask->Dispatch( + nsc, std::move(certBytesArray), std::move(mPeerCertChain), + TransportSecurityInfo::ConvertCertificateTransparencyInfoToStatus( + certificateTransparencyInfo), + evStatus, true, 0, 0, isCertChainRootBuiltInRoot); + return NS_OK; + } + + Telemetry::AccumulateTimeDelta( + Telemetry::SSL_INITIAL_FAILED_CERT_VALIDATION_TIME_MOZILLAPKIX, + jobStartTime, TimeStamp::Now()); + + PRErrorCode error = MapResultToPRErrorCode(rv); + uint32_t collectedErrors = 0; + PRErrorCode finalError = AuthCertificateParseResults( + mAddrForLogging, mHostName, mPort, mOriginAttributes, mCert, + mProviderFlags, mPRTime, error, collectedErrors); + + // NB: finalError may be 0 here, in which the connection will continue. + mResultTask->Dispatch( + nsc, std::move(certBytesArray), std::move(mPeerCertChain), + nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE, + EVStatus::NotEV, false, finalError, collectedErrors, false); + return NS_OK; +} + +// Takes information needed for cert verification, does some consistency +// checks and calls SSLServerCertVerificationJob::Dispatch. +SECStatus AuthCertificateHookInternal( + TransportSecurityInfo* infoObject, const void* aPtrForLogging, + const UniqueCERTCertificate& serverCert, const nsACString& hostName, + nsTArray>&& peerCertChain, + Maybe>& stapledOCSPResponse, + Maybe>& sctsFromTLSExtension, + Maybe& dcInfo, uint32_t providerFlags, + uint32_t certVerifierFlags) { + // Runs on the socket transport thread + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] starting AuthCertificateHookInternal\n", aPtrForLogging)); + + if (!infoObject || !serverCert) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return SECFailure; + } + + bool onSTSThread; + nsresult nrv; + nsCOMPtr sts = + do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &nrv); + if (NS_SUCCEEDED(nrv)) { + nrv = sts->IsOnCurrentThread(&onSTSThread); + } + + if (NS_FAILED(nrv)) { + NS_ERROR("Could not get STS service or IsOnCurrentThread failed"); + PR_SetError(PR_UNKNOWN_ERROR, 0); + return SECFailure; + } + + MOZ_ASSERT(onSTSThread); + + if (!onSTSThread) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return SECFailure; + } + + uint64_t addr = reinterpret_cast(aPtrForLogging); + RefPtr resultTask = + new SSLServerCertVerificationResult(infoObject); + + if (XRE_IsSocketProcess()) { + return RemoteProcessCertVerification( + serverCert, std::move(peerCertChain), hostName, infoObject->GetPort(), + infoObject->GetOriginAttributes(), stapledOCSPResponse, + sctsFromTLSExtension, dcInfo, providerFlags, certVerifierFlags, + resultTask); + } + + // We *must* do certificate verification on a background thread because + // we need the socket transport thread to be free for our OCSP requests, + // and we *want* to do certificate verification on a background thread + // because of the performance benefits of doing so. + return SSLServerCertVerificationJob::Dispatch( + addr, infoObject, serverCert, std::move(peerCertChain), hostName, + infoObject->GetPort(), infoObject->GetOriginAttributes(), + stapledOCSPResponse, sctsFromTLSExtension, dcInfo, providerFlags, Now(), + PR_Now(), certVerifierFlags, resultTask); +} + +// Extracts whatever information we need out of fd (using SSL_*) and passes it +// to AuthCertificateHookInternal. AuthCertificateHookInternal will call +// SSLServerCertVerificationJob::Dispatch. SSLServerCertVerificationJob +// should never do anything with fd except logging. +SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, + PRBool isServer) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] starting AuthCertificateHook\n", fd)); + + // Modern libssl always passes PR_TRUE for checkSig, and we have no means of + // doing verification without checking signatures. + MOZ_ASSERT(checkSig, "AuthCertificateHook: checkSig unexpectedly false"); + + // PSM never causes libssl to call this function with PR_TRUE for isServer, + // and many things in PSM assume that we are a client. + MOZ_ASSERT(!isServer, "AuthCertificateHook: isServer unexpectedly true"); + + nsNSSSocketInfo* socketInfo = static_cast(arg); + + UniqueCERTCertificate serverCert(SSL_PeerCertificate(fd)); + + if (!checkSig || isServer || !socketInfo || !serverCert) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return SECFailure; + } + socketInfo->SetFullHandshake(); + + if (BlockServerCertChangeForSpdy(socketInfo, serverCert) != SECSuccess) { + return SECFailure; + } + + UniqueCERTCertList peerCertChain(SSL_PeerCertificateChain(fd)); + if (!peerCertChain) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return SECFailure; + } + + nsTArray> peerCertsBytes = + TransportSecurityInfo::CreateCertBytesArray(peerCertChain); + + // SSL_PeerStapledOCSPResponses will never return a non-empty response if + // OCSP stapling wasn't enabled because libssl wouldn't have let the server + // return a stapled OCSP response. + // We don't own these pointers. + const SECItemArray* csa = SSL_PeerStapledOCSPResponses(fd); + Maybe> stapledOCSPResponse; + // we currently only support single stapled responses + if (csa && csa->len == 1) { + stapledOCSPResponse.emplace(); + stapledOCSPResponse->SetCapacity(csa->items[0].len); + stapledOCSPResponse->AppendElements(csa->items[0].data, csa->items[0].len); + } + + Maybe> sctsFromTLSExtension; + const SECItem* sctsFromTLSExtensionSECItem = SSL_PeerSignedCertTimestamps(fd); + if (sctsFromTLSExtensionSECItem) { + sctsFromTLSExtension.emplace(); + sctsFromTLSExtension->SetCapacity(sctsFromTLSExtensionSECItem->len); + sctsFromTLSExtension->AppendElements(sctsFromTLSExtensionSECItem->data, + sctsFromTLSExtensionSECItem->len); + } + + uint32_t providerFlags = 0; + socketInfo->GetProviderFlags(&providerFlags); + + uint32_t certVerifierFlags = 0; + if (!socketInfo->SharedState().IsOCSPStaplingEnabled() || + !socketInfo->SharedState().IsOCSPMustStapleEnabled()) { + certVerifierFlags |= CertVerifier::FLAG_TLS_IGNORE_STATUS_REQUEST; + } + + // Get DC information + Maybe dcInfo; + SSLPreliminaryChannelInfo channelPreInfo; + SECStatus rv = SSL_GetPreliminaryChannelInfo(fd, &channelPreInfo, + sizeof(channelPreInfo)); + if (rv != SECSuccess) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return SECFailure; + } + if (channelPreInfo.peerDelegCred) { + dcInfo.emplace(DelegatedCredentialInfo(channelPreInfo.signatureScheme, + channelPreInfo.authKeyBits)); + } + + // If we configured an ECHConfig and NSS returned the public name + // for verification, ECH was rejected. Proceed, verifying to the + // public name. The result determines how NSS will fail (i.e. with + // any provided retry_configs if successful). See draft-ietf-tls-esni-08. + nsCString echConfig; + nsresult nsrv = socketInfo->GetEchConfig(echConfig); + bool verifyToEchPublicName = + NS_SUCCEEDED(nsrv) && echConfig.Length() && channelPreInfo.echPublicName; + + const nsCString echPublicName(channelPreInfo.echPublicName); + const nsACString& hostname = + verifyToEchPublicName ? echPublicName : socketInfo->GetHostName(); + socketInfo->SetCertVerificationWaiting(); + rv = AuthCertificateHookInternal( + socketInfo, static_cast(fd), serverCert, hostname, + std::move(peerCertsBytes), stapledOCSPResponse, sctsFromTLSExtension, + dcInfo, providerFlags, certVerifierFlags); + return rv; +} + +// Takes information needed for cert verification, does some consistency +// checks and calls SSLServerCertVerificationJob::Dispatch. +// This function is used for Quic. +SECStatus AuthCertificateHookWithInfo( + TransportSecurityInfo* infoObject, const void* aPtrForLogging, + nsTArray>&& peerCertChain, + Maybe>>& stapledOCSPResponses, + Maybe>& sctsFromTLSExtension, uint32_t providerFlags) { + if (peerCertChain.IsEmpty()) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return SECFailure; + } + + SECItem der = {SECItemType::siBuffer, peerCertChain[0].Elements(), + (uint32_t)peerCertChain[0].Length()}; + UniqueCERTCertificate cert(CERT_NewTempCertificate( + CERT_GetDefaultCertDB(), &der, nullptr, false, true)); + if (!cert) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("AuthCertificateHookWithInfo: cert failed")); + return SECFailure; + } + + // we currently only support single stapled responses + Maybe> stapledOCSPResponse; + if (stapledOCSPResponses && (stapledOCSPResponses->Length() == 1)) { + stapledOCSPResponse.emplace(stapledOCSPResponses->ElementAt(0).Clone()); + } + + uint32_t certVerifierFlags = 0; + // QuicTransportSecInfo does not have a SharedState as nsNSSSocketInfo. + // Here we need prefs for ocsp. This are prefs they are the same for + // PublicSSLState and PrivateSSLState, just take them from one of them. + if (!PublicSSLState()->IsOCSPStaplingEnabled() || + !PublicSSLState()->IsOCSPMustStapleEnabled()) { + certVerifierFlags |= CertVerifier::FLAG_TLS_IGNORE_STATUS_REQUEST; + } + + // Need to update Quic stack to reflect the PreliminaryInfo fields + // for Delegated Credentials. + Maybe dcInfo; + + return AuthCertificateHookInternal( + infoObject, aPtrForLogging, cert, infoObject->GetHostName(), + std::move(peerCertChain), stapledOCSPResponse, sctsFromTLSExtension, + dcInfo, providerFlags, certVerifierFlags); +} + +NS_IMPL_ISUPPORTS_INHERITED0(SSLServerCertVerificationResult, Runnable) + +SSLServerCertVerificationResult::SSLServerCertVerificationResult( + TransportSecurityInfo* infoObject) + : Runnable("psm::SSLServerCertVerificationResult"), + mInfoObject(infoObject), + mCertificateTransparencyStatus(0), + mEVStatus(EVStatus::NotEV), + mSucceeded(false), + mFinalError(0), + mCollectedErrors(0) {} + +void SSLServerCertVerificationResult::Dispatch( + nsNSSCertificate* aCert, nsTArray>&& aBuiltChain, + nsTArray>&& aPeerCertChain, + uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus, + bool aSucceeded, PRErrorCode aFinalError, uint32_t aCollectedErrors, + bool aIsCertChainRootBuiltInRoot) { + mCert = aCert; + mBuiltChain = std::move(aBuiltChain); + mPeerCertChain = std::move(aPeerCertChain); + mCertificateTransparencyStatus = aCertificateTransparencyStatus; + mEVStatus = aEVStatus; + mSucceeded = aSucceeded; + mFinalError = aFinalError; + mCollectedErrors = aCollectedErrors; + mIsBuiltCertChainRootBuiltInRoot = aIsCertChainRootBuiltInRoot; + + nsresult rv; + nsCOMPtr stsTarget = + do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); + MOZ_ASSERT(stsTarget, "Failed to get socket transport service event target"); + rv = stsTarget->Dispatch(this, NS_DISPATCH_NORMAL); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "Failed to dispatch SSLServerCertVerificationResult"); +} + +NS_IMETHODIMP +SSLServerCertVerificationResult::Run() { +#ifdef DEBUG + bool onSTSThread = false; + nsresult nrv; + nsCOMPtr sts = + do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &nrv); + if (NS_SUCCEEDED(nrv)) { + nrv = sts->IsOnCurrentThread(&onSTSThread); + } + + MOZ_ASSERT(onSTSThread); +#endif + + AuthCertificateSetResults(mInfoObject, mCert, std::move(mBuiltChain), + std::move(mPeerCertChain), + mCertificateTransparencyStatus, mEVStatus, + mSucceeded, mIsBuiltCertChainRootBuiltInRoot); + + if (!mSucceeded && mCollectedErrors != 0) { + mInfoObject->SetStatusErrorBits(mCert, mCollectedErrors); + } + mInfoObject->SetCertVerificationResult(mFinalError); + return NS_OK; +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/SSLServerCertVerification.h b/security/manager/ssl/SSLServerCertVerification.h new file mode 100644 index 0000000000..06c5755584 --- /dev/null +++ b/security/manager/ssl/SSLServerCertVerification.h @@ -0,0 +1,163 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ +#ifndef _SSLSERVERCERTVERIFICATION_H +#define _SSLSERVERCERTVERIFICATION_H + +#include "CertVerifier.h" +#include "ScopedNSSTypes.h" +#include "mozilla/Maybe.h" +#include "mozpkix/pkix.h" +#include "nsTArray.h" +#include "nsThreadUtils.h" +#include "prerror.h" +#include "prio.h" +#include "seccomon.h" +#include "secoidt.h" + +class nsNSSCertificate; + +using namespace mozilla::pkix; + +namespace mozilla { +namespace psm { + +class TransportSecurityInfo; +enum class EVStatus : uint8_t; + +SECStatus AuthCertificateHook(void* arg, PRFileDesc* fd, PRBool checkSig, + PRBool isServer); + +// This function triggers the certificate verification. The verification is +// asynchronous and the info object will be notified when the verification has +// completed via SetCertVerificationResult. +SECStatus AuthCertificateHookWithInfo( + TransportSecurityInfo* infoObject, const void* aPtrForLogging, + nsTArray>&& peerCertChain, + Maybe>>& stapledOCSPResponses, + Maybe>& sctsFromTLSExtension, uint32_t providerFlags); + +// Base class for dispatching the certificate verification result. +class BaseSSLServerCertVerificationResult { + public: + NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING + + virtual void Dispatch(nsNSSCertificate* aCert, + nsTArray>&& aBuiltChain, + nsTArray>&& aPeerCertChain, + uint16_t aCertificateTransparencyStatus, + EVStatus aEVStatus, bool aSucceeded, + PRErrorCode aFinalError, uint32_t aCollectedErrors, + bool aIsBuiltCertChainRootBuiltInRoot) = 0; +}; + +// Dispatched to the STS thread to notify the infoObject of the verification +// result. +// +// This will cause the PR_Poll in the STS thread to return, so things work +// correctly even if the STS thread is blocked polling (only) on the file +// descriptor that is waiting for this result. +class SSLServerCertVerificationResult final + : public BaseSSLServerCertVerificationResult, + public Runnable { + public: + NS_DECL_ISUPPORTS_INHERITED + NS_DECL_NSIRUNNABLE + + explicit SSLServerCertVerificationResult(TransportSecurityInfo* infoObject); + + void Dispatch(nsNSSCertificate* aCert, + nsTArray>&& aBuiltChain, + nsTArray>&& aPeerCertChain, + uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus, + bool aSucceeded, PRErrorCode aFinalError, + uint32_t aCollectedErrors, + bool aIsBuiltCertChainRootBuiltInRoot) override; + + private: + ~SSLServerCertVerificationResult() = default; + + const RefPtr mInfoObject; + RefPtr mCert; + nsTArray> mBuiltChain; + nsTArray> mPeerCertChain; + uint16_t mCertificateTransparencyStatus; + EVStatus mEVStatus; + bool mSucceeded; + PRErrorCode mFinalError; + uint32_t mCollectedErrors; + bool mIsBuiltCertChainRootBuiltInRoot; +}; + +class SSLServerCertVerificationJob : public Runnable { + public: + SSLServerCertVerificationJob(const SSLServerCertVerificationJob&) = delete; + + // Must be called only on the socket transport thread + static SECStatus Dispatch(uint64_t addrForLogging, void* aPinArg, + const UniqueCERTCertificate& serverCert, + nsTArray>&& peerCertChain, + const nsACString& aHostName, int32_t aPort, + const OriginAttributes& aOriginAttributes, + Maybe>& stapledOCSPResponse, + Maybe>& sctsFromTLSExtension, + Maybe& dcInfo, + uint32_t providerFlags, Time time, PRTime prtime, + uint32_t certVerifierFlags, + BaseSSLServerCertVerificationResult* aResultTask); + + private: + NS_DECL_NSIRUNNABLE + + // Must be called only on the socket transport thread + SSLServerCertVerificationJob(uint64_t addrForLogging, void* aPinArg, + const UniqueCERTCertificate& cert, + nsTArray>&& peerCertChain, + const nsACString& aHostName, int32_t aPort, + const OriginAttributes& aOriginAttributes, + Maybe>& stapledOCSPResponse, + Maybe>& sctsFromTLSExtension, + Maybe& dcInfo, + uint32_t providerFlags, Time time, PRTime prtime, + uint32_t certVerifierFlags, + BaseSSLServerCertVerificationResult* aResultTask) + : Runnable("psm::SSLServerCertVerificationJob"), + mAddrForLogging(addrForLogging), + mPinArg(aPinArg), + mCert(CERT_DupCertificate(cert.get())), + mPeerCertChain(std::move(peerCertChain)), + mHostName(aHostName), + mPort(aPort), + mOriginAttributes(aOriginAttributes), + mProviderFlags(providerFlags), + mCertVerifierFlags(certVerifierFlags), + mTime(time), + mPRTime(prtime), + mStapledOCSPResponse(std::move(stapledOCSPResponse)), + mSCTsFromTLSExtension(std::move(sctsFromTLSExtension)), + mDCInfo(std::move(dcInfo)), + mResultTask(aResultTask) {} + + uint64_t mAddrForLogging; + void* mPinArg; + const UniqueCERTCertificate mCert; + nsTArray> mPeerCertChain; + nsCString mHostName; + int32_t mPort; + OriginAttributes mOriginAttributes; + const uint32_t mProviderFlags; + const uint32_t mCertVerifierFlags; + const Time mTime; + const PRTime mPRTime; + Maybe> mStapledOCSPResponse; + Maybe> mSCTsFromTLSExtension; + Maybe mDCInfo; + RefPtr mResultTask; +}; + +} // namespace psm +} // namespace mozilla + +#endif diff --git a/security/manager/ssl/ScopedNSSTypes.h b/security/manager/ssl/ScopedNSSTypes.h new file mode 100644 index 0000000000..4465a445b8 --- /dev/null +++ b/security/manager/ssl/ScopedNSSTypes.h @@ -0,0 +1,368 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +// This header provides smart pointers and various helpers for code that needs +// to interact with NSS. + +#ifndef ScopedNSSTypes_h +#define ScopedNSSTypes_h + +#include +#include + +#include "cert.h" +#include "cms.h" +#include "cryptohi.h" +#include "keyhi.h" +#include "mozilla/Likely.h" +#include "mozilla/UniquePtr.h" +#include "nsDebug.h" +#include "nsError.h" +#include "NSSErrorsService.h" +#include "pk11pub.h" +#include "pkcs12.h" +#include "prerror.h" +#include "prio.h" +#include "prmem.h" +#include "sechash.h" +#include "secmod.h" +#include "secpkcs7.h" +#include "secport.h" + +#ifndef MOZ_NO_MOZALLOC +# include "mozilla/mozalloc_oom.h" +#endif + +namespace mozilla { + +// NSPR APIs use PRStatus/PR_GetError and NSS APIs use SECStatus/PR_GetError to +// report success/failure. This function makes it more convenient and *safer* +// to translate NSPR/NSS results to nsresult. It is safer because it +// refuses to translate any bad PRStatus/SECStatus into an NS_OK, even when the +// NSPR/NSS function forgot to call PR_SetError. The actual enforcement of +// this happens in mozilla::psm::GetXPCOMFromNSSError. +// IMPORTANT: This must be called immediately after the function returning the +// SECStatus result. The recommended usage is: +// nsresult rv = MapSECStatus(f(x, y, z)); +inline nsresult MapSECStatus(SECStatus rv) { + if (rv == SECSuccess) { + return NS_OK; + } + + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); +} + +namespace internal { + +inline void PK11_DestroyContext_true(PK11Context* ctx) { + PK11_DestroyContext(ctx, true); +} + +inline void SECKEYEncryptedPrivateKeyInfo_true( + SECKEYEncryptedPrivateKeyInfo* epki) { + SECKEY_DestroyEncryptedPrivateKeyInfo(epki, true); +} + +} // namespace internal + +// Emulates MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE, but for UniquePtrs. +#define MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(name, Type, Deleter) \ + struct name##DeletePolicy { \ + void operator()(Type* aValue) { Deleter(aValue); } \ + }; \ + typedef std::unique_ptr name; + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePK11Context, PK11Context, + internal::PK11_DestroyContext_true) + +/** A more convenient way of dealing with digests calculated into + * stack-allocated buffers. NSS must be initialized on the main thread before + * use, and the caller must ensure NSS isn't shut down, typically by + * being within the lifetime of XPCOM. + * + * Typical usage, for digesting a buffer in memory: + * + * nsCOMPtr nssDummy = do_GetService("@mozilla.org/psm;1", &rv); + * nsTArray digestArray; + * nsresult rv = Digest::DigestBuf(SEC_OID_SHA256, mybuffer, myBufferLen, + * digestArray); + * NS_ENSURE_SUCCESS(rv, rv); + * + * Less typical usage, for digesting while doing streaming I/O and similar: + * + * Digest digest; + * nsresult rv = digest.Begin(SEC_OID_SHA256); + * NS_ENSURE_SUCCESS(rv, rv); + * for (...) { + * rv = digest.Update(buf, len); + * NS_ENSURE_SUCCESS(rv, rv); + * } + * nsTArray digestArray; + * rv = digest.End(digestArray); + * NS_ENSURE_SUCCESS(rv, rv) + */ +class Digest { + public: + explicit Digest() : mLen(0), mDigestContext(nullptr) {} + + static nsresult DigestBuf(SECOidTag hashAlg, Span buf, + /*out*/ nsTArray& out) { + return Digest::DigestBuf(hashAlg, buf.Elements(), buf.Length(), out); + } + + static nsresult DigestBuf(SECOidTag hashAlg, const uint8_t* buf, uint32_t len, + /*out*/ nsTArray& out) { + Digest digest; + + nsresult rv = digest.Begin(hashAlg); + if (NS_FAILED(rv)) { + return rv; + } + + rv = digest.Update(buf, len); + if (NS_FAILED(rv)) { + return rv; + } + + rv = digest.End(out); + if (NS_FAILED(rv)) { + return rv; + } + + return rv; + } + + nsresult Begin(SECOidTag hashAlg) { + if (hashAlg != SEC_OID_SHA1 && hashAlg != SEC_OID_SHA256) { + return NS_ERROR_INVALID_ARG; + } + + mDigestContext = UniquePK11Context(PK11_CreateDigestContext(hashAlg)); + if (!mDigestContext) { + return mozilla::psm::GetXPCOMFromNSSError(PR_GetError()); + } + + nsresult rv = SetLength(hashAlg); + NS_ENSURE_SUCCESS(rv, rv); + return MapSECStatus(PK11_DigestBegin(mDigestContext.get())); + } + + nsresult Update(Span in) { + return Update(in.Elements(), in.Length()); + } + + nsresult Update(const unsigned char* buf, const uint32_t len) { + if (!mDigestContext) { + return NS_ERROR_NOT_INITIALIZED; + } + return MapSECStatus(PK11_DigestOp(mDigestContext.get(), buf, len)); + } + + nsresult End(/*out*/ nsTArray& out) { + if (!mDigestContext) { + return NS_ERROR_NOT_INITIALIZED; + } + out.SetLength(mLen); + uint32_t len; + nsresult rv = MapSECStatus( + PK11_DigestFinal(mDigestContext.get(), out.Elements(), &len, mLen)); + NS_ENSURE_SUCCESS(rv, rv); + mDigestContext = nullptr; + NS_ENSURE_TRUE(len == mLen, NS_ERROR_UNEXPECTED); + + return NS_OK; + } + + private: + nsresult SetLength(SECOidTag hashType) { +#ifdef _MSC_VER +# pragma warning(push) + // C4061: enumerator 'symbol' in switch of enum 'symbol' is not + // explicitly handled. +# pragma warning(disable : 4061) +#endif + switch (hashType) { + case SEC_OID_SHA1: + mLen = SHA1_LENGTH; + break; + case SEC_OID_SHA256: + mLen = SHA256_LENGTH; + break; + default: + return NS_ERROR_INVALID_ARG; + } +#ifdef _MSC_VER +# pragma warning(pop) +#endif + + return NS_OK; + } + + uint8_t mLen; + UniquePK11Context mDigestContext; +}; + +namespace internal { + +inline void PORT_FreeArena_false(PLArenaPool* arena) { + // PL_FreeArenaPool can't be used because it doesn't actually free the + // memory, which doesn't work well with memory analysis tools. + return PORT_FreeArena(arena, false); +} + +} // namespace internal + +// Wrapper around NSS's SECItem_AllocItem that handles OOM the same way as +// other allocators. +inline void SECITEM_AllocItem(SECItem& item, uint32_t len) { + if (MOZ_UNLIKELY(!SECITEM_AllocItem(nullptr, &item, len))) { +#ifndef MOZ_NO_MOZALLOC + mozalloc_handle_oom(len); + if (MOZ_UNLIKELY(!SECITEM_AllocItem(nullptr, &item, len))) +#endif + { + MOZ_CRASH(); + } + } +} + +class ScopedAutoSECItem final : public SECItem { + public: + explicit ScopedAutoSECItem(uint32_t initialAllocatedLen = 0) { + data = nullptr; + len = 0; + if (initialAllocatedLen > 0) { + SECITEM_AllocItem(*this, initialAllocatedLen); + } + } + + void reset() { SECITEM_FreeItem(this, false); } + + ~ScopedAutoSECItem() { reset(); } +}; + +class MOZ_RAII AutoSECMODListReadLock final { + public: + AutoSECMODListReadLock() : mLock(SECMOD_GetDefaultModuleListLock()) { + MOZ_ASSERT(mLock, "should have SECMOD lock (has NSS been initialized?)"); + SECMOD_GetReadLock(mLock); + } + + ~AutoSECMODListReadLock() { SECMOD_ReleaseReadLock(mLock); } + + private: + SECMODListLock* mLock; +}; + +namespace internal { + +inline void SECITEM_FreeItem_true(SECItem* s) { + return SECITEM_FreeItem(s, true); +} + +inline void SECOID_DestroyAlgorithmID_true(SECAlgorithmID* a) { + return SECOID_DestroyAlgorithmID(a, true); +} + +inline void VFY_DestroyContext_true(VFYContext* ctx) { + VFY_DestroyContext(ctx, true); +} + +// If this was created via PK11_ListFixedKeysInSlot, we may have a list of keys, +// in which case we have to free them all (and if not, this will still free the +// one key). +inline void FreeOneOrMoreSymKeys(PK11SymKey* keys) { + PK11SymKey* next; + while (keys) { + next = PK11_GetNextSymKey(keys); + PK11_FreeSymKey(keys); + keys = next; + } +} + +} // namespace internal + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTCertificate, CERTCertificate, + CERT_DestroyCertificate) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTCertificateList, + CERTCertificateList, + CERT_DestroyCertificateList) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTCertificatePolicies, + CERTCertificatePolicies, + CERT_DestroyCertificatePoliciesExtension) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTCertificateRequest, + CERTCertificateRequest, + CERT_DestroyCertificateRequest) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTCertList, CERTCertList, + CERT_DestroyCertList) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTName, CERTName, + CERT_DestroyName) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTOidSequence, CERTOidSequence, + CERT_DestroyOidSequence) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTSubjectPublicKeyInfo, + CERTSubjectPublicKeyInfo, + SECKEY_DestroySubjectPublicKeyInfo) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTUserNotice, CERTUserNotice, + CERT_DestroyUserNotice) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueCERTValidity, CERTValidity, + CERT_DestroyValidity) + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueHASHContext, HASHContext, + HASH_Destroy) + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueNSSCMSMessage, NSSCMSMessage, + NSS_CMSMessage_Destroy) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueNSSCMSSignedData, NSSCMSSignedData, + NSS_CMSSignedData_Destroy) + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePK11GenericObject, + PK11GenericObject, + PK11_DestroyGenericObject) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePK11SlotInfo, PK11SlotInfo, + PK11_FreeSlot) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePK11SlotList, PK11SlotList, + PK11_FreeSlotList) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePK11SymKey, PK11SymKey, + internal::FreeOneOrMoreSymKeys) + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePLArenaPool, PLArenaPool, + internal::PORT_FreeArena_false) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePORTString, char, PORT_Free) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePRFileDesc, PRFileDesc, PR_Close) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePRString, char, PR_Free) + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSECAlgorithmID, SECAlgorithmID, + internal::SECOID_DestroyAlgorithmID_true) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSECItem, SECItem, + internal::SECITEM_FreeItem_true) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSECKEYPrivateKey, SECKEYPrivateKey, + SECKEY_DestroyPrivateKey) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSECKEYPrivateKeyList, + SECKEYPrivateKeyList, + SECKEY_DestroyPrivateKeyList) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSECKEYPublicKey, SECKEYPublicKey, + SECKEY_DestroyPublicKey) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSECMODModule, SECMODModule, + SECMOD_DestroyModule) + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSGNDigestInfo, SGNDigestInfo, + SGN_DestroyDigestInfo) + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueVFYContext, VFYContext, + internal::VFY_DestroyContext_true) + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSEC_PKCS12DecoderContext, + SEC_PKCS12DecoderContext, + SEC_PKCS12DecoderFinish) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniqueSEC_PKCS12ExportContext, + SEC_PKCS12ExportContext, + SEC_PKCS12DestroyExportContext) +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE( + UniqueSECKEYEncryptedPrivateKeyInfo, SECKEYEncryptedPrivateKeyInfo, + internal::SECKEYEncryptedPrivateKeyInfo_true) +} // namespace mozilla + +#endif // ScopedNSSTypes_h diff --git a/security/manager/ssl/SecretDecoderRing.cpp b/security/manager/ssl/SecretDecoderRing.cpp new file mode 100644 index 0000000000..da1750c6ae --- /dev/null +++ b/security/manager/ssl/SecretDecoderRing.cpp @@ -0,0 +1,343 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "SecretDecoderRing.h" + +#include "ScopedNSSTypes.h" +#include "mozilla/Base64.h" +#include "mozilla/Casting.h" +#include "mozilla/Services.h" +#include "mozilla/ErrorResult.h" +#include "mozilla/dom/Promise.h" +#include "nsCOMPtr.h" +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsIObserverService.h" +#include "nsITokenPasswordDialogs.h" +#include "nsNSSComponent.h" +#include "nsNSSHelper.h" +#include "nsNetCID.h" +#include "nsPK11TokenDB.h" +#include "pk11func.h" +#include "pk11sdr.h" // For PK11SDR_Encrypt, PK11SDR_Decrypt + +static mozilla::LazyLogModule gSDRLog("sdrlog"); + +using namespace mozilla; +using dom::Promise; + +NS_IMPL_ISUPPORTS(SecretDecoderRing, nsISecretDecoderRing) + +void BackgroundSdrEncryptStrings(const nsTArray& plaintexts, + RefPtr& aPromise) { + nsCOMPtr sdrService = + do_GetService(NS_SECRETDECODERRING_CONTRACTID); + nsTArray cipherTexts(plaintexts.Length()); + + nsresult rv = NS_ERROR_FAILURE; + for (const auto& plaintext : plaintexts) { + nsCString cipherText; + rv = sdrService->EncryptString(plaintext, cipherText); + + if (NS_WARN_IF(NS_FAILED(rv))) { + break; + } + + cipherTexts.AppendElement(NS_ConvertASCIItoUTF16(cipherText)); + } + + nsCOMPtr runnable( + NS_NewRunnableFunction("BackgroundSdrEncryptStringsResolve", + [rv, aPromise = std::move(aPromise), + cipherTexts = std::move(cipherTexts)]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolve(cipherTexts); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +void BackgroundSdrDecryptStrings(const nsTArray& encryptedStrings, + RefPtr& aPromise) { + nsCOMPtr sdrService = + do_GetService(NS_SECRETDECODERRING_CONTRACTID); + nsTArray plainTexts(encryptedStrings.Length()); + + nsresult rv = NS_ERROR_FAILURE; + for (const auto& encryptedString : encryptedStrings) { + nsCString plainText; + rv = sdrService->DecryptString(encryptedString, plainText); + + if (NS_FAILED(rv)) { + if (rv == NS_ERROR_NOT_AVAILABLE) { + // Master Password entry was canceled. Don't keep prompting again. + break; + } + + // NS_ERROR_ILLEGAL_VALUE or NS_ERROR_FAILURE could be due to bad data for + // a single string but we still want to decrypt the others. + // Callers of `decryptMany` in crypto-SDR.js assume there will be an + // equal number of usernames and passwords so use an empty string to keep + // this assumption true. + MOZ_LOG(gSDRLog, LogLevel::Warning, + ("Couldn't decrypt string: %s", encryptedString.get())); + plainTexts.AppendElement(nullptr); + rv = NS_OK; + continue; + } + + plainTexts.AppendElement(NS_ConvertUTF8toUTF16(plainText)); + } + + nsCOMPtr runnable( + NS_NewRunnableFunction("BackgroundSdrDecryptStringsResolve", + [rv, aPromise = std::move(aPromise), + plainTexts = std::move(plainTexts)]() { + if (NS_FAILED(rv)) { + aPromise->MaybeReject(rv); + } else { + aPromise->MaybeResolve(plainTexts); + } + })); + NS_DispatchToMainThread(runnable.forget()); +} + +nsresult SecretDecoderRing::Encrypt(const nsACString& data, + /*out*/ nsACString& result) { + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return NS_ERROR_NOT_AVAILABLE; + } + + /* Make sure token is initialized. */ + nsCOMPtr ctx = new PipUIContext(); + nsresult rv = setPassword(slot.get(), ctx); + if (NS_FAILED(rv)) { + return rv; + } + + /* Force authentication */ + if (PK11_Authenticate(slot.get(), true, ctx) != SECSuccess) { + return NS_ERROR_FAILURE; + } + + /* Use default key id */ + SECItem keyid; + keyid.data = nullptr; + keyid.len = 0; + SECItem request; + request.data = BitwiseCast(data.BeginReading()); + request.len = data.Length(); + ScopedAutoSECItem reply; + if (PK11SDR_Encrypt(&keyid, &request, &reply, ctx) != SECSuccess) { + return NS_ERROR_FAILURE; + } + + result.Assign(BitwiseCast(reply.data), reply.len); + return NS_OK; +} + +nsresult SecretDecoderRing::Decrypt(const nsACString& data, + /*out*/ nsACString& result) { + /* Find token with SDR key */ + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return NS_ERROR_NOT_AVAILABLE; + } + + /* Force authentication */ + nsCOMPtr ctx = new PipUIContext(); + if (PK11_Authenticate(slot.get(), true, ctx) != SECSuccess) { + return NS_ERROR_NOT_AVAILABLE; + } + + SECItem request; + request.data = BitwiseCast(data.BeginReading()); + request.len = data.Length(); + ScopedAutoSECItem reply; + if (PK11SDR_Decrypt(&request, &reply, ctx) != SECSuccess) { + return NS_ERROR_FAILURE; + } + + result.Assign(BitwiseCast(reply.data), reply.len); + return NS_OK; +} + +NS_IMETHODIMP +SecretDecoderRing::EncryptString(const nsACString& text, + /*out*/ nsACString& encryptedBase64Text) { + nsAutoCString encryptedText; + nsresult rv = Encrypt(text, encryptedText); + if (NS_FAILED(rv)) { + return rv; + } + + rv = Base64Encode(encryptedText, encryptedBase64Text); + if (NS_FAILED(rv)) { + return rv; + } + + return NS_OK; +} + +NS_IMETHODIMP +SecretDecoderRing::AsyncEncryptStrings(const nsTArray& plaintexts, + JSContext* aCx, Promise** aPromise) { + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + NS_ENSURE_ARG(!plaintexts.IsEmpty()); + NS_ENSURE_ARG_POINTER(aCx); + NS_ENSURE_ARG_POINTER(aPromise); + + nsIGlobalObject* globalObject = xpc::CurrentNativeGlobal(aCx); + if (NS_WARN_IF(!globalObject)) { + return NS_ERROR_UNEXPECTED; + } + + ErrorResult result; + RefPtr promise = Promise::Create(globalObject, result); + if (NS_WARN_IF(result.Failed())) { + return result.StealNSResult(); + } + + // plaintexts are already expected to be UTF-8. + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundSdrEncryptStrings", + [promise, plaintexts = plaintexts.Clone()]() mutable { + BackgroundSdrEncryptStrings(plaintexts, promise); + })); + + nsCOMPtr target( + do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID)); + if (!target) { + return NS_ERROR_FAILURE; + } + nsresult rv = target->Dispatch(runnable, NS_DISPATCH_NORMAL); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + promise.forget(aPromise); + return NS_OK; +} + +NS_IMETHODIMP +SecretDecoderRing::DecryptString(const nsACString& encryptedBase64Text, + /*out*/ nsACString& decryptedText) { + nsAutoCString encryptedText; + nsresult rv = Base64Decode(encryptedBase64Text, encryptedText); + if (NS_FAILED(rv)) { + return rv; + } + + rv = Decrypt(encryptedText, decryptedText); + if (NS_FAILED(rv)) { + return rv; + } + + return NS_OK; +} + +NS_IMETHODIMP +SecretDecoderRing::AsyncDecryptStrings( + const nsTArray& encryptedStrings, JSContext* aCx, + Promise** aPromise) { + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + NS_ENSURE_ARG(!encryptedStrings.IsEmpty()); + NS_ENSURE_ARG_POINTER(aCx); + NS_ENSURE_ARG_POINTER(aPromise); + + nsIGlobalObject* globalObject = xpc::CurrentNativeGlobal(aCx); + if (NS_WARN_IF(!globalObject)) { + return NS_ERROR_UNEXPECTED; + } + + ErrorResult result; + RefPtr promise = Promise::Create(globalObject, result); + if (NS_WARN_IF(result.Failed())) { + return result.StealNSResult(); + } + + // encryptedStrings are expected to be base64. + nsCOMPtr runnable(NS_NewRunnableFunction( + "BackgroundSdrDecryptStrings", + [promise, encryptedStrings = encryptedStrings.Clone()]() mutable { + BackgroundSdrDecryptStrings(encryptedStrings, promise); + })); + + nsCOMPtr target( + do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID)); + if (!target) { + return NS_ERROR_FAILURE; + } + nsresult rv = target->Dispatch(runnable, NS_DISPATCH_NORMAL); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + promise.forget(aPromise); + return NS_OK; +} + +NS_IMETHODIMP +SecretDecoderRing::ChangePassword() { + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return NS_ERROR_NOT_AVAILABLE; + } + + // nsPK11Token::nsPK11Token takes its own reference to slot, so we pass a + // non-owning pointer here. + nsCOMPtr token = new nsPK11Token(slot.get()); + + nsCOMPtr dialogs; + nsresult rv = getNSSDialogs(getter_AddRefs(dialogs), + NS_GET_IID(nsITokenPasswordDialogs), + NS_TOKENPASSWORDSDIALOG_CONTRACTID); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr ctx = new PipUIContext(); + bool canceled; // Ignored + return dialogs->SetPassword(ctx, token, &canceled); +} + +NS_IMETHODIMP +SecretDecoderRing::Logout() { + PK11_LogoutAll(); + nsCOMPtr nssComponent(do_GetService(NS_NSSCOMPONENT_CID)); + if (!nssComponent) { + return NS_ERROR_NOT_AVAILABLE; + } + return nssComponent->ClearSSLExternalAndInternalSessionCache(); +} + +NS_IMETHODIMP +SecretDecoderRing::LogoutAndTeardown() { + PK11_LogoutAll(); + nsCOMPtr nssComponent(do_GetService(NS_NSSCOMPONENT_CID)); + if (!nssComponent) { + return NS_ERROR_NOT_AVAILABLE; + } + + // LogoutAuthenticatedPK11 also clears the SSL caches. + nsresult rv = nssComponent->LogoutAuthenticatedPK11(); + if (NS_FAILED(rv)) { + return rv; + } + + // After we just logged out, we need to prune dead connections to make + // sure that all connections that should be stopped, are stopped. See + // bug 517584. + nsCOMPtr os = mozilla::services::GetObserverService(); + if (os) { + os->NotifyObservers(nullptr, "net:prune-dead-connections", nullptr); + } + + return NS_OK; +} diff --git a/security/manager/ssl/SecretDecoderRing.h b/security/manager/ssl/SecretDecoderRing.h new file mode 100644 index 0000000000..23187ae45d --- /dev/null +++ b/security/manager/ssl/SecretDecoderRing.h @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef SecretDecoderRing_h +#define SecretDecoderRing_h + +#include "nsISecretDecoderRing.h" +#include "nsString.h" + +#define NS_SECRETDECODERRING_CONTRACTID "@mozilla.org/security/sdr;1" + +#define NS_SECRETDECODERRING_CID \ + { \ + 0x0c4f1ddc, 0x1dd2, 0x11b2, { \ + 0x9d, 0x95, 0xf2, 0xfd, 0xf1, 0x13, 0x04, 0x4b \ + } \ + } + +class SecretDecoderRing : public nsISecretDecoderRing { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSISECRETDECODERRING + + SecretDecoderRing() = default; + + protected: + virtual ~SecretDecoderRing() = default; + + private: + nsresult Encrypt(const nsACString& data, /*out*/ nsACString& result); + nsresult Decrypt(const nsACString& data, /*out*/ nsACString& result); +}; + +#endif // SecretDecoderRing_h diff --git a/security/manager/ssl/SharedCertVerifier.h b/security/manager/ssl/SharedCertVerifier.h new file mode 100644 index 0000000000..6771dab16b --- /dev/null +++ b/security/manager/ssl/SharedCertVerifier.h @@ -0,0 +1,42 @@ +/* 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/. */ + +#ifndef SharedCertVerifier_h +#define SharedCertVerifier_h + +#include "CertVerifier.h" +#include "EnterpriseRoots.h" +#include "mozilla/RefPtr.h" +#include "mozilla/TimeStamp.h" + +namespace mozilla { +namespace psm { + +class SharedCertVerifier : public mozilla::psm::CertVerifier { + protected: + ~SharedCertVerifier(); + + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedCertVerifier) + + SharedCertVerifier(OcspDownloadConfig odc, OcspStrictConfig osc, + mozilla::TimeDuration ocspSoftTimeout, + mozilla::TimeDuration ocspHardTimeout, + uint32_t certShortLifetimeInDays, PinningMode pinningMode, + SHA1Mode sha1Mode, + BRNameMatchingPolicy::Mode nameMatchingMode, + NetscapeStepUpPolicy netscapeStepUpPolicy, + CertificateTransparencyMode ctMode, CRLiteMode crliteMode, + uint64_t crliteCTMergeDelaySeconds, + const Vector& thirdPartyCerts) + : mozilla::psm::CertVerifier( + odc, osc, ocspSoftTimeout, ocspHardTimeout, certShortLifetimeInDays, + pinningMode, sha1Mode, nameMatchingMode, netscapeStepUpPolicy, + ctMode, crliteMode, crliteCTMergeDelaySeconds, thirdPartyCerts) {} +}; + +} // namespace psm +} // namespace mozilla + +#endif // SharedCertVerifier_h diff --git a/security/manager/ssl/SharedSSLState.cpp b/security/manager/ssl/SharedSSLState.cpp new file mode 100644 index 0000000000..7dbab96ebf --- /dev/null +++ b/security/manager/ssl/SharedSSLState.cpp @@ -0,0 +1,189 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "SharedSSLState.h" +#include "nsClientAuthRemember.h" +#include "nsComponentManagerUtils.h" +#include "nsICertOverrideService.h" +#include "nsIObserverService.h" +#include "mozilla/Services.h" +#include "nsThreadUtils.h" +#include "nsCRT.h" +#include "nsServiceManagerUtils.h" +#include "PSMRunnable.h" +#include "PublicSSL.h" +#include "ssl.h" +#include "nsNetCID.h" +#include "mozilla/Atomics.h" +#include "mozilla/Unused.h" + +using mozilla::Atomic; +using mozilla::Unused; +using mozilla::psm::SyncRunnableBase; + +namespace { + +static Atomic sCertOverrideSvcExists(false); + +class MainThreadClearer : public SyncRunnableBase { + public: + MainThreadClearer() : mShouldClearSessionCache(false) {} + + void RunOnTargetThread() override { + // In some cases it's possible to cause PSM/NSS to initialize while XPCOM + // shutdown is in progress. We want to avoid this, since they do not handle + // the situation well, hence the flags to avoid instantiating the services + // if they don't already exist. + + bool certOverrideSvcExists = sCertOverrideSvcExists.exchange(false); + if (certOverrideSvcExists) { + sCertOverrideSvcExists = true; + nsCOMPtr icos = + do_GetService(NS_CERTOVERRIDE_CONTRACTID); + if (icos) { + icos->ClearValidityOverride("all:temporary-certificates"_ns, 0); + } + } + + // This needs to be checked on the main thread to avoid racing with NSS + // initialization. + mShouldClearSessionCache = mozilla::psm::PrivateSSLState() && + mozilla::psm::PrivateSSLState()->SocketCreated(); + } + bool mShouldClearSessionCache; +}; + +} // namespace + +namespace mozilla { + +void ClearPrivateSSLState() { + // This only works if it is called on the socket transport + // service thread immediately after closing all private SSL + // connections. +#ifdef DEBUG + nsresult rv; + nsCOMPtr sts = + do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + bool onSTSThread; + rv = sts->IsOnCurrentThread(&onSTSThread); + MOZ_ASSERT(NS_SUCCEEDED(rv) && onSTSThread); +#endif + + RefPtr runnable = new MainThreadClearer; + runnable->DispatchToMainThreadAndWait(); + + // If NSS isn't initialized, this throws an assertion. We guard it by checking + // if the session cache might even have anything worth clearing. + if (runnable->mShouldClearSessionCache) { + nsNSSComponent::DoClearSSLExternalAndInternalSessionCache(); + } +} + +namespace psm { + +namespace { +class PrivateBrowsingObserver : public nsIObserver { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + explicit PrivateBrowsingObserver(SharedSSLState* aOwner) : mOwner(aOwner) {} + + protected: + virtual ~PrivateBrowsingObserver() = default; + + private: + SharedSSLState* mOwner; +}; + +SharedSSLState* gPublicState; +SharedSSLState* gPrivateState; +} // namespace + +NS_IMPL_ISUPPORTS(PrivateBrowsingObserver, nsIObserver) + +NS_IMETHODIMP +PrivateBrowsingObserver::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* aData) { + if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { + mOwner->ResetStoredData(); + } + return NS_OK; +} + +SharedSSLState::SharedSSLState(uint32_t aTlsFlags) + : mIOLayerHelpers(aTlsFlags), + mMutex("SharedSSLState::mMutex"), + mSocketCreated(false), + mOCSPStaplingEnabled(false), + mOCSPMustStapleEnabled(false), + mSignedCertTimestampsEnabled(false) { + mIOLayerHelpers.Init(); +} + +SharedSSLState::~SharedSSLState() = default; + +void SharedSSLState::NotePrivateBrowsingStatus() { + MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); + mObserver = new PrivateBrowsingObserver(this); + nsCOMPtr obsSvc = mozilla::services::GetObserverService(); + obsSvc->AddObserver(mObserver, "last-pb-context-exited", false); +} + +void SharedSSLState::ResetStoredData() { + MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); + mIOLayerHelpers.clearStoredData(); +} + +void SharedSSLState::NoteSocketCreated() { + MutexAutoLock lock(mMutex); + mSocketCreated = true; +} + +bool SharedSSLState::SocketCreated() { + MutexAutoLock lock(mMutex); + return mSocketCreated; +} + +/*static*/ +void SharedSSLState::GlobalInit() { + MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); + gPublicState = new SharedSSLState(); + gPrivateState = new SharedSSLState(); + gPrivateState->NotePrivateBrowsingStatus(); +} + +/*static*/ +void SharedSSLState::GlobalCleanup() { + MOZ_ASSERT(NS_IsMainThread(), "Not on main thread"); + + if (gPrivateState) { + gPrivateState->Cleanup(); + delete gPrivateState; + gPrivateState = nullptr; + } + + if (gPublicState) { + gPublicState->Cleanup(); + delete gPublicState; + gPublicState = nullptr; + } +} + +/*static*/ +void SharedSSLState::NoteCertOverrideServiceInstantiated() { + sCertOverrideSvcExists = true; +} + +void SharedSSLState::Cleanup() { mIOLayerHelpers.Cleanup(); } + +SharedSSLState* PublicSSLState() { return gPublicState; } + +SharedSSLState* PrivateSSLState() { return gPrivateState; } + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/SharedSSLState.h b/security/manager/ssl/SharedSSLState.h new file mode 100644 index 0000000000..9431abeab9 --- /dev/null +++ b/security/manager/ssl/SharedSSLState.h @@ -0,0 +1,84 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef SharedSSLState_h +#define SharedSSLState_h + +#include "nsNSSIOLayer.h" + +class nsIObserver; + +namespace mozilla { +namespace psm { + +class SharedSSLState { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(SharedSSLState) + explicit SharedSSLState(uint32_t aTlsFlags = 0); + + static void GlobalInit(); + static void GlobalCleanup(); + + nsSSLIOLayerHelpers& IOLayerHelpers() { return mIOLayerHelpers; } + + // Main-thread only + void ResetStoredData(); + void NotePrivateBrowsingStatus(); + void SetOCSPStaplingEnabled(bool staplingEnabled) { + mOCSPStaplingEnabled = staplingEnabled; + } + void SetOCSPMustStapleEnabled(bool mustStapleEnabled) { + mOCSPMustStapleEnabled = mustStapleEnabled; + } + void SetSignedCertTimestampsEnabled(bool signedCertTimestampsEnabled) { + mSignedCertTimestampsEnabled = signedCertTimestampsEnabled; + } + void SetPinningMode(CertVerifier::PinningMode aPinningMode) { + mPinningMode = aPinningMode; + } + void SetNameMatchingMode(BRNameMatchingPolicy::Mode aMode) { + mNameMatchingMode = aMode; + } + + // The following methods may be called from any thread + bool SocketCreated(); + void NoteSocketCreated(); + static void NoteCertOverrideServiceInstantiated(); + bool IsOCSPStaplingEnabled() const { return mOCSPStaplingEnabled; } + bool IsOCSPMustStapleEnabled() const { return mOCSPMustStapleEnabled; } + bool IsSignedCertTimestampsEnabled() const { + return mSignedCertTimestampsEnabled; + } + CertVerifier::PinningMode PinningMode() { return mPinningMode; } + BRNameMatchingPolicy::Mode NameMatchingMode() { return mNameMatchingMode; } + + private: + ~SharedSSLState(); + + void Cleanup(); + + nsCOMPtr mObserver; + nsSSLIOLayerHelpers mIOLayerHelpers; + + // True if any sockets have been created that use this shared data. + // Requires synchronization between the socket and main threads for + // reading/writing. + Mutex mMutex; + bool mSocketCreated; + bool mOCSPStaplingEnabled; + bool mOCSPMustStapleEnabled; + bool mSignedCertTimestampsEnabled; + CertVerifier::PinningMode mPinningMode; + BRNameMatchingPolicy::Mode mNameMatchingMode; +}; + +SharedSSLState* PublicSSLState(); +SharedSSLState* PrivateSSLState(); + +} // namespace psm +} // namespace mozilla + +#endif diff --git a/security/manager/ssl/StaticHPKPins.errors b/security/manager/ssl/StaticHPKPins.errors new file mode 100644 index 0000000000..72958f2291 --- /dev/null +++ b/security/manager/ssl/StaticHPKPins.errors @@ -0,0 +1,33 @@ +Can't find hash in builtin certs for Chrome nickname GoogleG2, inserting GOOGLE_PIN_GoogleG2 +Can't find hash in builtin certs for Chrome nickname RapidSSL, inserting GOOGLE_PIN_RapidSSL +Can't find hash in builtin certs for Chrome nickname DigiCertSHA2HighAssuranceServerCA, inserting GOOGLE_PIN_DigiCertSHA2HighAssuranceServerCA +Can't find hash in builtin certs for Chrome nickname VeriSignClass1, inserting GOOGLE_PIN_VeriSignClass1 +Can't find hash in builtin certs for Chrome nickname VeriSignClass4_G3, inserting GOOGLE_PIN_VeriSignClass4_G3 +Can't find hash in builtin certs for Chrome nickname VeriSignClass3_G2, inserting GOOGLE_PIN_VeriSignClass3_G2 +Can't find hash in builtin certs for Chrome nickname VeriSignClass2_G2, inserting GOOGLE_PIN_VeriSignClass2_G2 +Can't find hash in builtin certs for Chrome nickname GeoTrustGlobal2, inserting GOOGLE_PIN_GeoTrustGlobal2 +Can't find hash in builtin certs for Chrome nickname Entrust_SSL, inserting GOOGLE_PIN_Entrust_SSL +Can't find hash in builtin certs for Chrome nickname AddTrustPublicCARoot, inserting GOOGLE_PIN_AddTrustPublicCARoot +Can't find hash in builtin certs for Chrome nickname AddTrustQualifiedCARoot, inserting GOOGLE_PIN_AddTrustQualifiedCARoot +Can't find hash in builtin certs for Chrome nickname SecureCertificateServices, inserting GOOGLE_PIN_SecureCertificateServices +Can't find hash in builtin certs for Chrome nickname TrustedCertificateServices, inserting GOOGLE_PIN_TrustedCertificateServices +Can't find hash in builtin certs for Chrome nickname UTNDATACorpSGC, inserting GOOGLE_PIN_UTNDATACorpSGC +Can't find hash in builtin certs for Chrome nickname UTNUSERFirstHardware, inserting GOOGLE_PIN_UTNUSERFirstHardware +Can't find hash in builtin certs for Chrome nickname UTNUSERFirstObject, inserting GOOGLE_PIN_UTNUSERFirstObject +Can't find hash in builtin certs for Chrome nickname GTECyberTrustGlobalRoot, inserting GOOGLE_PIN_GTECyberTrustGlobalRoot +Can't find hash in builtin certs for Chrome nickname GoDaddySecure, inserting GOOGLE_PIN_GoDaddySecure +Can't find hash in builtin certs for Chrome nickname SymantecClass3EVG3, inserting GOOGLE_PIN_SymantecClass3EVG3 +Can't find hash in builtin certs for Chrome nickname DigiCertECCSecureServerCA, inserting GOOGLE_PIN_DigiCertECCSecureServerCA +Can't find hash in builtin certs for Chrome nickname COMODORSADomainValidationSecureServerCA, inserting GOOGLE_PIN_COMODORSADomainValidationSecureServerCA +Writing pinset test +Writing pinset google +Writing pinset tor +Writing pinset twitterCom +Writing pinset twitterCDN +Writing pinset dropbox +Writing pinset facebook +Writing pinset spideroak +Writing pinset yahoo +Writing pinset swehackCom +Writing pinset ncsccs +Writing pinset tumblr diff --git a/security/manager/ssl/StaticHPKPins.h b/security/manager/ssl/StaticHPKPins.h new file mode 100644 index 0000000000..815bf8a782 --- /dev/null +++ b/security/manager/ssl/StaticHPKPins.h @@ -0,0 +1,1149 @@ +/* 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/. */ + +/*****************************************************************************/ +/* This is an automatically generated file. If you're not */ +/* PublicKeyPinningService.cpp, you shouldn't be #including it. */ +/*****************************************************************************/ +#include +/* AffirmTrust Commercial */ +static const char kAffirmTrust_CommercialFingerprint[] = + "bEZLmlsjOl6HTadlwm8EUBDS3c/0V5TwtMfkqvpQFJU="; + +/* AffirmTrust Networking */ +static const char kAffirmTrust_NetworkingFingerprint[] = + "lAcq0/WPcPkwmOWl9sBMlscQvYSdgxhJGa6Q64kK5AA="; + +/* AffirmTrust Premium */ +static const char kAffirmTrust_PremiumFingerprint[] = + "x/Q7TPW3FWgpT4IrU3YmBfbd0Vyt7Oc56eLDy6YenWc="; + +/* AffirmTrust Premium ECC */ +static const char kAffirmTrust_Premium_ECCFingerprint[] = + "MhmwkRT/SVo+tusAwu/qs0ACrl8KVsdnnqCHo/oDfk8="; + +/* Baltimore CyberTrust Root */ +static const char kBaltimore_CyberTrust_RootFingerprint[] = + "Y9mvm0exBk1JoQ57f9Vm28jKo5lFm/woKcVxrYxu80o="; + +/* COMODO Certification Authority */ +static const char kCOMODO_Certification_AuthorityFingerprint[] = + "AG1751Vd2CAmRCxPGieoDomhmJy4ezREjtIZTBgZbV4="; + +/* COMODO ECC Certification Authority */ +static const char kCOMODO_ECC_Certification_AuthorityFingerprint[] = + "58qRu/uxh4gFezqAcERupSkRYBlBAvfcw7mEjGPLnNU="; + +/* COMODO RSA Certification Authority */ +static const char kCOMODO_RSA_Certification_AuthorityFingerprint[] = + "grX4Ta9HpZx6tSHkmCrvpApTQGo67CYDnvprLg5yRME="; + +/* Comodo AAA Services root */ +static const char kComodo_AAA_Services_rootFingerprint[] = + "vRU+17BDT2iGsXvOi76E7TQMcTLXAqj0+jGPdW7L1vM="; + +/* Cybertrust Global Root */ +static const char kCybertrust_Global_RootFingerprint[] = + "foeCwVDOOVL4AuY2AjpdPpW7XWjjPoWtsroXgSXOvxU="; + +/* DST Root CA X3 */ +static const char kDST_Root_CA_X3Fingerprint[] = + "Vjs8r4z+80wjNcr1YKepWQboSIRi63WsWXhIMN+eWys="; + +/* DigiCert Assured ID Root CA */ +static const char kDigiCert_Assured_ID_Root_CAFingerprint[] = + "I/Lt/z7ekCWanjD0Cvj5EqXls2lOaThEA0H2Bg4BT/o="; + +/* DigiCert Assured ID Root G2 */ +static const char kDigiCert_Assured_ID_Root_G2Fingerprint[] = + "8ca6Zwz8iOTfUpc8rkIPCgid1HQUT+WAbEIAZOFZEik="; + +/* DigiCert Assured ID Root G3 */ +static const char kDigiCert_Assured_ID_Root_G3Fingerprint[] = + "Fe7TOVlLME+M+Ee0dzcdjW/sYfTbKwGvWJ58U7Ncrkw="; + +/* DigiCert Global Root CA */ +static const char kDigiCert_Global_Root_CAFingerprint[] = + "r/mIkG3eEpVdm+u/ko/cwxzOMo1bk4TyHIlByibiA5E="; + +/* DigiCert Global Root G2 */ +static const char kDigiCert_Global_Root_G2Fingerprint[] = + "i7WTqTvh0OioIruIfFR4kMPnBqrS2rdiVPl/s2uC/CY="; + +/* DigiCert Global Root G3 */ +static const char kDigiCert_Global_Root_G3Fingerprint[] = + "uUwZgwDOxcBXrQcntwu+kYFpkiVkOaezL0WYEZ3anJc="; + +/* DigiCert High Assurance EV Root CA */ +static const char kDigiCert_High_Assurance_EV_Root_CAFingerprint[] = + "WoiWRyIOVNa9ihaBciRSC7XHjliYS9VwUGOIud4PB18="; + +/* DigiCert Trusted Root G4 */ +static const char kDigiCert_Trusted_Root_G4Fingerprint[] = + "Wd8xe/qfTwq3ylFNd3IpaqLHZbh2ZNCLluVzmeNkcpw="; + +/* End Entity Test Cert */ +static const char kEnd_Entity_Test_CertFingerprint[] = + "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8="; + +/* Entrust Root Certification Authority */ +static const char kEntrust_Root_Certification_AuthorityFingerprint[] = + "bb+uANN7nNc/j7R95lkXrwDg3d9C286sIMF8AnXuIJU="; + +/* Entrust Root Certification Authority - EC1 */ +static const char kEntrust_Root_Certification_Authority___EC1Fingerprint[] = + "/qK31kX7pz11PB7Jp4cMQOH3sMVh6Se5hb9xGGbjbyI="; + +/* Entrust Root Certification Authority - G2 */ +static const char kEntrust_Root_Certification_Authority___G2Fingerprint[] = + "du6FkDdMcVQ3u8prumAo6t3i3G27uMP2EOhR8R0at/U="; + +/* Entrust.net Premium 2048 Secure Server CA */ +static const char kEntrust_net_Premium_2048_Secure_Server_CAFingerprint[] = + "HqPF5D7WbC2imDpCpKebHpBnhs6fG1hiFBmgBGOofTg="; + +/* FacebookBackup */ +static const char kFacebookBackupFingerprint[] = + "q4PO2G2cbkZhZ82+JgmRUyGMoAeozA+BSXVXQWB8XWQ="; + +/* GOOGLE_PIN_AddTrustClass1CARoot */ +static const char kGOOGLE_PIN_AddTrustClass1CARootFingerprint[] = + "BStocQfshOhzA4JFLsKidFF0XXSFpX1vRk4Np6G2ryo="; + +/* GOOGLE_PIN_AddTrustExternalCARoot */ +static const char kGOOGLE_PIN_AddTrustExternalCARootFingerprint[] = + "lCppFqbkrlJ3EcVFAkeip0+44VaoJUymbnOaEUk7tEU="; + +/* GOOGLE_PIN_AddTrustPublicCARoot */ +static const char kGOOGLE_PIN_AddTrustPublicCARootFingerprint[] = + "OGHXtpYfzbISBFb/b8LrdwSxp0G0vZM6g3b14ZFcppg="; + +/* GOOGLE_PIN_AddTrustQualifiedCARoot */ +static const char kGOOGLE_PIN_AddTrustQualifiedCARootFingerprint[] = + "xzr8Lrp3DQy8HuQfJStS6Kk9ErctzOwDHY2DnL+Bink="; + +/* GOOGLE_PIN_COMODORSADomainValidationSecureServerCA */ +static const char kGOOGLE_PIN_COMODORSADomainValidationSecureServerCAFingerprint[] = + "klO23nT2ehFDXCfx3eHTDRESMz3asj1muO+4aIdjiuY="; + +/* GOOGLE_PIN_DigiCertECCSecureServerCA */ +static const char kGOOGLE_PIN_DigiCertECCSecureServerCAFingerprint[] = + "PZXN3lRAy+8tBKk2Ox6F7jIlnzr2Yzmwqc3JnyfXoCw="; + +/* GOOGLE_PIN_Entrust_SSL */ +static const char kGOOGLE_PIN_Entrust_SSLFingerprint[] = + "nsxRNo6G40YPZsKV5JQt1TCA8nseQQr/LRqp1Oa8fnw="; + +/* GOOGLE_PIN_GTECyberTrustGlobalRoot */ +static const char kGOOGLE_PIN_GTECyberTrustGlobalRootFingerprint[] = + "EGn6R6CqT4z3ERscrqNl7q7RC//zJmDe9uBhS/rnCHU="; + +/* GOOGLE_PIN_GTSCA1O1 */ +static const char kGOOGLE_PIN_GTSCA1O1Fingerprint[] = + "YZPgTZ+woNCCCIW3LH2CxQeLzB/1m42QcCTBSdgayjs="; + +/* GOOGLE_PIN_GeoTrustGlobal */ +static const char kGOOGLE_PIN_GeoTrustGlobalFingerprint[] = + "h6801m+z8v3zbgkRHpq6L29Esgfzhj89C1SyUCOQmqU="; + +/* GOOGLE_PIN_GeoTrustGlobal2 */ +static const char kGOOGLE_PIN_GeoTrustGlobal2Fingerprint[] = + "F3VaXClfPS1y5vAxofB/QAxYi55YKyLxfq4xoVkNEYU="; + +/* GOOGLE_PIN_GeoTrustPrimary */ +static const char kGOOGLE_PIN_GeoTrustPrimaryFingerprint[] = + "SQVGZiOrQXi+kqxcvWWE96HhfydlLVqFr4lQTqI5qqo="; + +/* GOOGLE_PIN_GeoTrustPrimary_G3 */ +static const char kGOOGLE_PIN_GeoTrustPrimary_G3Fingerprint[] = + "q5hJUnat8eyv8o81xTBIeB5cFxjaucjmelBPT2pRMo8="; + +/* GOOGLE_PIN_GeoTrustUniversal */ +static const char kGOOGLE_PIN_GeoTrustUniversalFingerprint[] = + "lpkiXF3lLlbN0y3y6W0c/qWqPKC7Us2JM8I7XCdEOCA="; + +/* GOOGLE_PIN_GeoTrustUniversal2 */ +static const char kGOOGLE_PIN_GeoTrustUniversal2Fingerprint[] = + "fKoDRlEkWQxgHlZ+UhSOlSwM/+iQAFMP4NlbbVDqrkE="; + +/* GOOGLE_PIN_GoDaddySecure */ +static const char kGOOGLE_PIN_GoDaddySecureFingerprint[] = + "MrZLZnJ6IGPkBm87lYywqu5Xal7O/ZUzmbuIdHMdlYc="; + +/* GOOGLE_PIN_R3LetsEncrypt */ +static const char kGOOGLE_PIN_R3LetsEncryptFingerprint[] = + "jQJTbIh0grw0/1TkHSumWb+Fs0Ggogr621gT3PvPKG0="; + +/* GOOGLE_PIN_R4LetsEncrypt */ +static const char kGOOGLE_PIN_R4LetsEncryptFingerprint[] = + "5VReIRNHJBiRxVSgOTTN6bdJZkpZ0m1hX+WPd5kPLQM="; + +/* GOOGLE_PIN_RapidSSL */ +static const char kGOOGLE_PIN_RapidSSLFingerprint[] = + "lT09gPUeQfbYrlxRtpsHrjDblj9Rpz+u7ajfCrg4qDM="; + +/* GOOGLE_PIN_SecureCertificateServices */ +static const char kGOOGLE_PIN_SecureCertificateServicesFingerprint[] = + "RpHL/ehKa2BS3b4VK7DCFq4lqG5XR4E9vA8UfzOFcL4="; + +/* GOOGLE_PIN_SymantecClass3EVG3 */ +static const char kGOOGLE_PIN_SymantecClass3EVG3Fingerprint[] = + "gMxWOrX4PMQesK9qFNbYBxjBfjUvlkn/vN1n+L9lE5E="; + +/* GOOGLE_PIN_TrustedCertificateServices */ +static const char kGOOGLE_PIN_TrustedCertificateServicesFingerprint[] = + "4tiR77c4ZpEF1TDeXtcuKyrD9KZweLU0mz/ayklvXrg="; + +/* GOOGLE_PIN_UTNDATACorpSGC */ +static const char kGOOGLE_PIN_UTNDATACorpSGCFingerprint[] = + "QAL80xHQczFWfnG82XHkYEjI3OjRZZcRdTs9qiommvo="; + +/* GOOGLE_PIN_UTNUSERFirstClientAuthenticationandEmail */ +static const char kGOOGLE_PIN_UTNUSERFirstClientAuthenticationandEmailFingerprint[] = + "Laj56jRU0hFGRko/nQKNxMf7tXscUsc8KwVyovWZotM="; + +/* GOOGLE_PIN_UTNUSERFirstHardware */ +static const char kGOOGLE_PIN_UTNUSERFirstHardwareFingerprint[] = + "TUDnr0MEoJ3of7+YliBMBVFB4/gJsv5zO7IxD9+YoWI="; + +/* GOOGLE_PIN_UTNUSERFirstObject */ +static const char kGOOGLE_PIN_UTNUSERFirstObjectFingerprint[] = + "D+FMJksXu28NZT56cOs2Pb9UvhWAOe3a5cJXEd9IwQM="; + +/* GOOGLE_PIN_VeriSignClass1 */ +static const char kGOOGLE_PIN_VeriSignClass1Fingerprint[] = + "LclHC+Y+9KzxvYKGCUArt7h72ZY4pkOTTohoLRvowwg="; + +/* GOOGLE_PIN_VeriSignClass2_G2 */ +static const char kGOOGLE_PIN_VeriSignClass2_G2Fingerprint[] = + "2oALgLKofTmeZvoZ1y/fSZg7R9jPMix8eVA6DH4o/q8="; + +/* GOOGLE_PIN_VeriSignClass3_G2 */ +static const char kGOOGLE_PIN_VeriSignClass3_G2Fingerprint[] = + "AjyBzOjnxk+pQtPBUEhwfTXZu1uH9PVExb8bxWQ68vo="; + +/* GOOGLE_PIN_VeriSignClass3_G3 */ +static const char kGOOGLE_PIN_VeriSignClass3_G3Fingerprint[] = + "SVqWumuteCQHvVIaALrOZXuzVVVeS7f4FGxxu6V+es4="; + +/* GOOGLE_PIN_VeriSignClass3_G4 */ +static const char kGOOGLE_PIN_VeriSignClass3_G4Fingerprint[] = + "UZJDjsNp1+4M5x9cbbdflB779y5YRBcV6Z6rBMLIrO4="; + +/* GOOGLE_PIN_VeriSignClass3_G5 */ +static const char kGOOGLE_PIN_VeriSignClass3_G5Fingerprint[] = + "JbQbUG5JMJUoI6brnx0x3vZF6jilxsapbXGVfjhN8Fg="; + +/* GOOGLE_PIN_VeriSignClass4_G3 */ +static const char kGOOGLE_PIN_VeriSignClass4_G3Fingerprint[] = + "VnuCEf0g09KD7gzXzgZyy52ZvFtIeljJ1U7Gf3fUqPU="; + +/* GTS Root R1 */ +static const char kGTS_Root_R1Fingerprint[] = + "hxqRlPTu1bMS/0DITB1SSu0vd4u/8l8TjPgfaAp63Gc="; + +/* GTS Root R2 */ +static const char kGTS_Root_R2Fingerprint[] = + "Vfd95BwDeSQo+NUYxVEEIlvkOlWY2SalKK1lPhzOx78="; + +/* GTS Root R3 */ +static const char kGTS_Root_R3Fingerprint[] = + "QXnt2YHvdHR3tJYmQIr0Paosp6t/nggsEGD4QJZ3Q0g="; + +/* GTS Root R4 */ +static const char kGTS_Root_R4Fingerprint[] = + "mEflZT5enoR1FuXLgYYGqnVEoZvmf9c2bVBpiOjYQ0c="; + +/* GeoTrust Primary Certification Authority - G2 */ +static const char kGeoTrust_Primary_Certification_Authority___G2Fingerprint[] = + "vPtEqrmtAhAVcGtBIep2HIHJ6IlnWQ9vlK50TciLePs="; + +/* GlobalSign ECC Root CA - R4 */ +static const char kGlobalSign_ECC_Root_CA___R4Fingerprint[] = + "CLOmM1/OXvSPjw5UOYbAf9GKOxImEp9hhku9W90fHMk="; + +/* GlobalSign ECC Root CA - R5 */ +static const char kGlobalSign_ECC_Root_CA___R5Fingerprint[] = + "fg6tdrtoGdwvVFEahDVPboswe53YIFjqbABPAdndpd8="; + +/* GlobalSign Root CA */ +static const char kGlobalSign_Root_CAFingerprint[] = + "K87oWBWM9UZfyddvDfoxL+8lpNyoUB2ptGtn0fv6G2Q="; + +/* GlobalSign Root CA - R2 */ +static const char kGlobalSign_Root_CA___R2Fingerprint[] = + "iie1VXtL7HzAMF+/PVPR9xzT80kQxdZeJ+zduCB3uj0="; + +/* GlobalSign Root CA - R3 */ +static const char kGlobalSign_Root_CA___R3Fingerprint[] = + "cGuxAXyFXFkWm61cF4HPWX8S0srS9j0aSqN0k4AP+4A="; + +/* GlobalSign Root CA - R6 */ +static const char kGlobalSign_Root_CA___R6Fingerprint[] = + "aCdH+LpiG4fN07wpXtXKvOciocDANj0daLOJKNJ4fx4="; + +/* Go Daddy Class 2 CA */ +static const char kGo_Daddy_Class_2_CAFingerprint[] = + "VjLZe/p3W/PJnd6lL8JVNBCGQBZynFLdZSTIqcO0SJ8="; + +/* Go Daddy Root Certificate Authority - G2 */ +static const char kGo_Daddy_Root_Certificate_Authority___G2Fingerprint[] = + "Ko8tivDrEjiY90yGasP6ZpBU4jwXvHqVvQI0GS3GNdA="; + +/* GoogleBackup2048 */ +static const char kGoogleBackup2048Fingerprint[] = + "IPMbDAjLVSGntGO3WP53X/zilCVndez5YJ2+vJvhJsA="; + +/* ISRG Root X1 */ +static const char kISRG_Root_X1Fingerprint[] = + "C5+lpZ7tcVwmwQIMcRtPbsQtWLABXhQzejna0wHFr8M="; + +/* Let's Encrypt Authority X3 */ +static const char kLet_s_Encrypt_Authority_X3Fingerprint[] = + "YLh1dUR9y6Kja30RrAn7JKnbQG/uEtLMkBgFF2Fuihg="; + +/* Let's Encrypt Authority X4 */ +static const char kLet_s_Encrypt_Authority_X4Fingerprint[] = + "sRHdihwgkaib1P1gxX8HFszlD+7/gTfNvuAybgLPNis="; + +/* SpiderOak2 */ +static const char kSpiderOak2Fingerprint[] = + "7Y3UnxbffL8aFPXsOJBpGasgpDmngpIhAxGKdQRklQQ="; + +/* SpiderOak3 */ +static const char kSpiderOak3Fingerprint[] = + "LkER54vOdlygpTsbYvlpMq1CE/lDAG1AP9xmdtwvV2A="; + +/* Starfield Class 2 CA */ +static const char kStarfield_Class_2_CAFingerprint[] = + "FfFKxFycfaIz00eRZOgTf+Ne4POK6FgYPwhBDqgqxLQ="; + +/* Starfield Root Certificate Authority - G2 */ +static const char kStarfield_Root_Certificate_Authority___G2Fingerprint[] = + "gI1os/q0iEpflxrOfRBVDXqVoWN3Tz7Dav/7IT++THQ="; + +/* Swehack */ +static const char kSwehackFingerprint[] = + "FdaffE799rVb3oyAuhJ2mBW/XJwD07Uajb2G6YwSAEw="; + +/* SwehackBackup */ +static const char kSwehackBackupFingerprint[] = + "z6cuswA6E1vgFkCjUsbEYo0Lf3aP8M8YOvwkoiGzDCo="; + +/* TestSPKI */ +static const char kTestSPKIFingerprint[] = + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + +/* Tor1 */ +static const char kTor1Fingerprint[] = + "bYz9JTDk89X3qu3fgswG+lBQso5vI0N1f0Rx4go4nLo="; + +/* Tor2 */ +static const char kTor2Fingerprint[] = + "xXCxhTdn7uxXneJSbQCqoAvuW3ZtQl2pDVTf2sewS8w="; + +/* Tor3 */ +static const char kTor3Fingerprint[] = + "CleC1qwUR8JPgH1nXvSe2VHxDe5/KfNs96EusbfSOfo="; + +/* Twitter1 */ +static const char kTwitter1Fingerprint[] = + "vU9M48LzD/CF34wE5PPf4nBwRyosy06X21J0ap8yS5s="; + +/* USERTrust ECC Certification Authority */ +static const char kUSERTrust_ECC_Certification_AuthorityFingerprint[] = + "ICGRfpgmOUXIWcQ/HXPLQTkFPEFPoDyjvH7ohhQpjzs="; + +/* USERTrust RSA Certification Authority */ +static const char kUSERTrust_RSA_Certification_AuthorityFingerprint[] = + "x4QzPSC810K5/cMjb05Qm4k3Bw5zBn4lTdO/nEW/Td4="; + +/* VeriSign Universal Root Certification Authority */ +static const char kVeriSign_Universal_Root_Certification_AuthorityFingerprint[] = + "lnsM2T/O9/J84sJFdnrpsFp3awZJ+ZZbYpCWhGloaHI="; + +/* Verisign Class 1 Public Primary Certification Authority - G3 */ +static const char kVerisign_Class_1_Public_Primary_Certification_Authority___G3Fingerprint[] = + "IgduWu9Eu5pBaii30cRDItcFn2D+/6XK9sW+hEeJEwM="; + +/* Verisign Class 2 Public Primary Certification Authority - G3 */ +static const char kVerisign_Class_2_Public_Primary_Certification_Authority___G3Fingerprint[] = + "cAajgxHlj7GTSEIzIYIQxmEloOSoJq7VOaxWHfv72QM="; + +/* YahooBackup1 */ +static const char kYahooBackup1Fingerprint[] = + "2fRAUXyxl4A1/XHrKNBmc8bTkzA7y4FB/GLJuNAzCqY="; + +/* YahooBackup2 */ +static const char kYahooBackup2Fingerprint[] = + "dolnbtzEBnELx/9lOEQ22e6OZO/QNb6VSSX2XHA3E7A="; + +/* Pinsets are each an ordered list by the actual value of the fingerprint */ +struct StaticFingerprints { + // See bug 1338873 about making these fields const. + size_t size; + const char* const* data; +}; + +/* PreloadedHPKPins.json pinsets */ +static const char* const kPinset_google_root_pems_Data[] = { + kEntrust_Root_Certification_Authority___EC1Fingerprint, + kCOMODO_ECC_Certification_AuthorityFingerprint, + kDigiCert_Assured_ID_Root_G2Fingerprint, + kCOMODO_Certification_AuthorityFingerprint, + kGlobalSign_ECC_Root_CA___R4Fingerprint, + kDigiCert_Assured_ID_Root_G3Fingerprint, + kStarfield_Class_2_CAFingerprint, + kEntrust_net_Premium_2048_Secure_Server_CAFingerprint, + kDigiCert_Assured_ID_Root_CAFingerprint, + kUSERTrust_ECC_Certification_AuthorityFingerprint, + kGlobalSign_Root_CAFingerprint, + kGo_Daddy_Root_Certificate_Authority___G2Fingerprint, + kAffirmTrust_Premium_ECCFingerprint, + kGTS_Root_R3Fingerprint, + kGTS_Root_R2Fingerprint, + kGo_Daddy_Class_2_CAFingerprint, + kDigiCert_Trusted_Root_G4Fingerprint, + kDigiCert_High_Assurance_EV_Root_CAFingerprint, + kBaltimore_CyberTrust_RootFingerprint, + kGlobalSign_Root_CA___R6Fingerprint, + kAffirmTrust_CommercialFingerprint, + kEntrust_Root_Certification_AuthorityFingerprint, + kGlobalSign_Root_CA___R3Fingerprint, + kEntrust_Root_Certification_Authority___G2Fingerprint, + kGlobalSign_ECC_Root_CA___R5Fingerprint, + kCybertrust_Global_RootFingerprint, + kStarfield_Root_Certificate_Authority___G2Fingerprint, + kCOMODO_RSA_Certification_AuthorityFingerprint, + kGTS_Root_R1Fingerprint, + kDigiCert_Global_Root_G2Fingerprint, + kGlobalSign_Root_CA___R2Fingerprint, + kAffirmTrust_NetworkingFingerprint, + kGTS_Root_R4Fingerprint, + kDigiCert_Global_Root_CAFingerprint, + kDigiCert_Global_Root_G3Fingerprint, + kComodo_AAA_Services_rootFingerprint, + kAffirmTrust_PremiumFingerprint, + kUSERTrust_RSA_Certification_AuthorityFingerprint, +}; +static const StaticFingerprints kPinset_google_root_pems = { + sizeof(kPinset_google_root_pems_Data) / sizeof(const char*), + kPinset_google_root_pems_Data +}; + +static const char* const kPinset_mozilla_services_Data[] = { + kISRG_Root_X1Fingerprint, + kDigiCert_High_Assurance_EV_Root_CAFingerprint, + kDigiCert_Global_Root_CAFingerprint, +}; +static const StaticFingerprints kPinset_mozilla_services = { + sizeof(kPinset_mozilla_services_Data) / sizeof(const char*), + kPinset_mozilla_services_Data +}; + +static const char* const kPinset_mozilla_test_Data[] = { + kEnd_Entity_Test_CertFingerprint, +}; +static const StaticFingerprints kPinset_mozilla_test = { + sizeof(kPinset_mozilla_test_Data) / sizeof(const char*), + kPinset_mozilla_test_Data +}; + +/* Chrome static pinsets */ +static const char* const kPinset_test_Data[] = { + kTestSPKIFingerprint, +}; +static const StaticFingerprints kPinset_test = { + sizeof(kPinset_test_Data) / sizeof(const char*), + kPinset_test_Data +}; + +static const char* const kPinset_google_Data[] = { + kGoogleBackup2048Fingerprint, + kGTS_Root_R3Fingerprint, + kGTS_Root_R2Fingerprint, + kGOOGLE_PIN_GTSCA1O1Fingerprint, + kGTS_Root_R1Fingerprint, + kGlobalSign_Root_CA___R2Fingerprint, + kGTS_Root_R4Fingerprint, +}; +static const StaticFingerprints kPinset_google = { + sizeof(kPinset_google_Data) / sizeof(const char*), + kPinset_google_Data +}; + +static const char* const kPinset_tor_Data[] = { + kGOOGLE_PIN_R4LetsEncryptFingerprint, + kTor3Fingerprint, + kDigiCert_High_Assurance_EV_Root_CAFingerprint, + kLet_s_Encrypt_Authority_X3Fingerprint, + kTor1Fingerprint, + kGOOGLE_PIN_R3LetsEncryptFingerprint, + kGOOGLE_PIN_RapidSSLFingerprint, + kLet_s_Encrypt_Authority_X4Fingerprint, + kTor2Fingerprint, +}; +static const StaticFingerprints kPinset_tor = { + sizeof(kPinset_tor_Data) / sizeof(const char*), + kPinset_tor_Data +}; + +static const char* const kPinset_twitterCom_Data[] = { + kGOOGLE_PIN_VeriSignClass2_G2Fingerprint, + kGOOGLE_PIN_VeriSignClass3_G2Fingerprint, + kGOOGLE_PIN_GeoTrustGlobal2Fingerprint, + kDigiCert_Assured_ID_Root_CAFingerprint, + kVerisign_Class_1_Public_Primary_Certification_Authority___G3Fingerprint, + kGOOGLE_PIN_VeriSignClass3_G5Fingerprint, + kGOOGLE_PIN_VeriSignClass1Fingerprint, + kGOOGLE_PIN_GeoTrustPrimaryFingerprint, + kGOOGLE_PIN_VeriSignClass3_G3Fingerprint, + kGOOGLE_PIN_VeriSignClass3_G4Fingerprint, + kGOOGLE_PIN_VeriSignClass4_G3Fingerprint, + kDigiCert_High_Assurance_EV_Root_CAFingerprint, + kVerisign_Class_2_Public_Primary_Certification_Authority___G3Fingerprint, + kGOOGLE_PIN_GeoTrustUniversal2Fingerprint, + kGOOGLE_PIN_GeoTrustGlobalFingerprint, + kVeriSign_Universal_Root_Certification_AuthorityFingerprint, + kGOOGLE_PIN_GeoTrustUniversalFingerprint, + kGOOGLE_PIN_GeoTrustPrimary_G3Fingerprint, + kDigiCert_Global_Root_CAFingerprint, + kGeoTrust_Primary_Certification_Authority___G2Fingerprint, + kTwitter1Fingerprint, +}; +static const StaticFingerprints kPinset_twitterCom = { + sizeof(kPinset_twitterCom_Data) / sizeof(const char*), + kPinset_twitterCom_Data +}; + +static const char* const kPinset_twitterCDN_Data[] = { + kGOOGLE_PIN_VeriSignClass2_G2Fingerprint, + kGOOGLE_PIN_TrustedCertificateServicesFingerprint, + kCOMODO_Certification_AuthorityFingerprint, + kGOOGLE_PIN_VeriSignClass3_G2Fingerprint, + kGOOGLE_PIN_AddTrustClass1CARootFingerprint, + kGOOGLE_PIN_UTNUSERFirstObjectFingerprint, + kGOOGLE_PIN_GTECyberTrustGlobalRootFingerprint, + kGOOGLE_PIN_GeoTrustGlobal2Fingerprint, + kEntrust_net_Premium_2048_Secure_Server_CAFingerprint, + kDigiCert_Assured_ID_Root_CAFingerprint, + kVerisign_Class_1_Public_Primary_Certification_Authority___G3Fingerprint, + kGOOGLE_PIN_VeriSignClass3_G5Fingerprint, + kGlobalSign_Root_CAFingerprint, + kGOOGLE_PIN_UTNUSERFirstClientAuthenticationandEmailFingerprint, + kGOOGLE_PIN_VeriSignClass1Fingerprint, + kGOOGLE_PIN_AddTrustPublicCARootFingerprint, + kGOOGLE_PIN_UTNDATACorpSGCFingerprint, + kGOOGLE_PIN_SecureCertificateServicesFingerprint, + kGOOGLE_PIN_GeoTrustPrimaryFingerprint, + kGOOGLE_PIN_VeriSignClass3_G3Fingerprint, + kGOOGLE_PIN_UTNUSERFirstHardwareFingerprint, + kGOOGLE_PIN_VeriSignClass3_G4Fingerprint, + kGOOGLE_PIN_VeriSignClass4_G3Fingerprint, + kDigiCert_High_Assurance_EV_Root_CAFingerprint, + kBaltimore_CyberTrust_RootFingerprint, + kEntrust_Root_Certification_AuthorityFingerprint, + kVerisign_Class_2_Public_Primary_Certification_Authority___G3Fingerprint, + kGlobalSign_Root_CA___R3Fingerprint, + kEntrust_Root_Certification_Authority___G2Fingerprint, + kGOOGLE_PIN_GeoTrustUniversal2Fingerprint, + kGOOGLE_PIN_GeoTrustGlobalFingerprint, + kGlobalSign_Root_CA___R2Fingerprint, + kGOOGLE_PIN_AddTrustExternalCARootFingerprint, + kVeriSign_Universal_Root_Certification_AuthorityFingerprint, + kGOOGLE_PIN_GeoTrustUniversalFingerprint, + kGOOGLE_PIN_Entrust_SSLFingerprint, + kGOOGLE_PIN_GeoTrustPrimary_G3Fingerprint, + kDigiCert_Global_Root_CAFingerprint, + kGeoTrust_Primary_Certification_Authority___G2Fingerprint, + kComodo_AAA_Services_rootFingerprint, + kTwitter1Fingerprint, + kGOOGLE_PIN_AddTrustQualifiedCARootFingerprint, +}; +static const StaticFingerprints kPinset_twitterCDN = { + sizeof(kPinset_twitterCDN_Data) / sizeof(const char*), + kPinset_twitterCDN_Data +}; + +static const char* const kPinset_dropbox_Data[] = { + kEntrust_Root_Certification_Authority___EC1Fingerprint, + kEntrust_net_Premium_2048_Secure_Server_CAFingerprint, + kDigiCert_Assured_ID_Root_CAFingerprint, + kGo_Daddy_Root_Certificate_Authority___G2Fingerprint, + kGOOGLE_PIN_GoDaddySecureFingerprint, + kGo_Daddy_Class_2_CAFingerprint, + kDigiCert_High_Assurance_EV_Root_CAFingerprint, + kEntrust_Root_Certification_AuthorityFingerprint, + kEntrust_Root_Certification_Authority___G2Fingerprint, + kDigiCert_Global_Root_CAFingerprint, +}; +static const StaticFingerprints kPinset_dropbox = { + sizeof(kPinset_dropbox_Data) / sizeof(const char*), + kPinset_dropbox_Data +}; + +static const char* const kPinset_facebook_Data[] = { + kGOOGLE_PIN_DigiCertECCSecureServerCAFingerprint, + kDigiCert_High_Assurance_EV_Root_CAFingerprint, + kGOOGLE_PIN_SymantecClass3EVG3Fingerprint, + kFacebookBackupFingerprint, +}; +static const StaticFingerprints kPinset_facebook = { + sizeof(kPinset_facebook_Data) / sizeof(const char*), + kPinset_facebook_Data +}; + +static const char* const kPinset_spideroak_Data[] = { + kSpiderOak2Fingerprint, + kSpiderOak3Fingerprint, + kDigiCert_High_Assurance_EV_Root_CAFingerprint, + kGOOGLE_PIN_GeoTrustGlobalFingerprint, +}; +static const StaticFingerprints kPinset_spideroak = { + sizeof(kPinset_spideroak_Data) / sizeof(const char*), + kPinset_spideroak_Data +}; + +static const char* const kPinset_yahoo_Data[] = { + kYahooBackup1Fingerprint, + kDigiCert_Assured_ID_Root_CAFingerprint, + kGlobalSign_Root_CAFingerprint, + kDigiCert_Trusted_Root_G4Fingerprint, + kDigiCert_High_Assurance_EV_Root_CAFingerprint, + kGlobalSign_Root_CA___R3Fingerprint, + kYahooBackup2Fingerprint, + kDigiCert_Global_Root_G2Fingerprint, + kDigiCert_Global_Root_CAFingerprint, + kDigiCert_Global_Root_G3Fingerprint, +}; +static const StaticFingerprints kPinset_yahoo = { + sizeof(kPinset_yahoo_Data) / sizeof(const char*), + kPinset_yahoo_Data +}; + +static const char* const kPinset_swehackCom_Data[] = { + kSwehackFingerprint, + kDST_Root_CA_X3Fingerprint, + kLet_s_Encrypt_Authority_X3Fingerprint, + kGOOGLE_PIN_COMODORSADomainValidationSecureServerCAFingerprint, + kLet_s_Encrypt_Authority_X4Fingerprint, + kSwehackBackupFingerprint, +}; +static const StaticFingerprints kPinset_swehackCom = { + sizeof(kPinset_swehackCom_Data) / sizeof(const char*), + kPinset_swehackCom_Data +}; + +/* Domainlist */ +struct TransportSecurityPreload { + // See bug 1338873 about making these fields const. + const char* mHost; + bool mIncludeSubdomains; + bool mTestMode; + bool mIsMoz; + int32_t mId; + const StaticFingerprints* pinset; +}; + +/* Sort hostnames for binary search. */ +static const TransportSecurityPreload kPublicKeyPinningPreloadList[] = { + { "2mdn.net", true, false, false, -1, &kPinset_google_root_pems }, + { "accounts.firefox.com", true, false, true, 4, &kPinset_mozilla_services }, + { "accounts.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "addons.mozilla.net", true, false, true, 2, &kPinset_mozilla_services }, + { "addons.mozilla.org", true, false, true, 1, &kPinset_mozilla_services }, + { "admin.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "android.com", true, false, false, -1, &kPinset_google_root_pems }, + { "api.accounts.firefox.com", true, false, true, 5, &kPinset_mozilla_services }, + { "api.twitter.com", true, false, false, -1, &kPinset_twitterCDN }, + { "apis.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "appengine.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "apps.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "at.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "au.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "aus4.mozilla.org", true, true, true, 3, &kPinset_mozilla_services }, + { "aus5.mozilla.org", true, true, true, 7, &kPinset_mozilla_services }, + { "az.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "be.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "bi.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "blog.torproject.org", true, false, false, -1, &kPinset_tor }, + { "blogger.com", true, false, false, -1, &kPinset_google_root_pems }, + { "blogspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "br.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "bugs.chromium.org", true, false, false, -1, &kPinset_google_root_pems }, + { "build.chromium.org", true, false, false, -1, &kPinset_google_root_pems }, + { "business.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "business.twitter.com", true, false, false, -1, &kPinset_twitterCom }, + { "ca.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "calendar.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "cd.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "cdn.ampproject.org", true, false, false, -1, &kPinset_google_root_pems }, + { "cdn.mozilla.net", true, false, true, 16, &kPinset_mozilla_services }, + { "cdn.mozilla.org", true, false, true, 17, &kPinset_mozilla_services }, + { "cg.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "ch.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "check.torproject.org", true, false, false, -1, &kPinset_tor }, + { "checkout.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "chfr.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "chit.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "chrome-devtools-frontend.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "chrome.com", true, false, false, -1, &kPinset_google_root_pems }, + { "chrome.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "chromereporting-pa.googleapis.com", true, false, false, -1, &kPinset_google_root_pems }, + { "chromiumbugs.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "chromiumcodereview.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "cl.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "classroom.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "cloud.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "cn.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "co.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "code.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "code.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "codereview.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "codereview.chromium.org", true, false, false, -1, &kPinset_google_root_pems }, + { "contributor.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "corp.goog", true, false, false, -1, &kPinset_google_root_pems }, + { "cr.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "crash-reports-xpsp2.mozilla.com", false, false, true, 11, &kPinset_mozilla_services }, + { "crash-reports.mozilla.com", false, false, true, 10, &kPinset_mozilla_services }, + { "crash-stats.mozilla.org", false, false, true, 12, &kPinset_mozilla_services }, + { "crbug.com", true, false, false, -1, &kPinset_google_root_pems }, + { "crosbug.com", true, false, false, -1, &kPinset_google_root_pems }, + { "crrev.com", true, false, false, -1, &kPinset_google_root_pems }, + { "ct.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "datastudio.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "de.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "dev.twitter.com", true, false, false, -1, &kPinset_twitterCom }, + { "developer.android.com", true, false, false, -1, &kPinset_google_root_pems }, + { "developers.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "dist.torproject.org", true, false, false, -1, &kPinset_tor }, + { "dk.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "dl.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "dns.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "do.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "docs.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "domains.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "doubleclick.net", true, false, false, -1, &kPinset_google_root_pems }, + { "download.mozilla.org", false, false, true, 14, &kPinset_mozilla_services }, + { "drive.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "dropbox.com", true, false, false, -1, &kPinset_dropbox }, + { "dropboxstatic.com", false, true, false, -1, &kPinset_dropbox }, + { "dropboxusercontent.com", false, true, false, -1, &kPinset_dropbox }, + { "edit.yahoo.com", true, true, false, -1, &kPinset_yahoo }, + { "en-maktoob.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "encrypted.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "es.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "espanol.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "example.test", true, true, false, -1, &kPinset_test }, + { "exclude-subdomains.pinning.example.com", false, false, false, -1, &kPinset_mozilla_test }, + { "facebook.com", false, false, false, -1, &kPinset_facebook }, + { "fi.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "fi.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "firebaseio.com", true, false, false, -1, &kPinset_google_root_pems }, + { "firefox.com", true, true, true, 15, &kPinset_mozilla_services }, + { "fj.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "fr.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "g.co", false, false, false, -1, &kPinset_google_root_pems }, + { "g4w.co", true, false, false, -1, &kPinset_google_root_pems }, + { "ggpht.com", true, false, false, -1, &kPinset_google_root_pems }, + { "gl.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "glass.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "gm.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "gmail.com", false, false, false, -1, &kPinset_google_root_pems }, + { "goo.gl", true, false, false, -1, &kPinset_google_root_pems }, + { "google", true, false, false, -1, &kPinset_google_root_pems }, + { "google-analytics.com", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ac", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ad", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ae", true, false, false, -1, &kPinset_google_root_pems }, + { "google.af", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ag", true, false, false, -1, &kPinset_google_root_pems }, + { "google.am", true, false, false, -1, &kPinset_google_root_pems }, + { "google.as", true, false, false, -1, &kPinset_google_root_pems }, + { "google.at", true, false, false, -1, &kPinset_google_root_pems }, + { "google.az", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ba", true, false, false, -1, &kPinset_google_root_pems }, + { "google.be", true, false, false, -1, &kPinset_google_root_pems }, + { "google.bf", true, false, false, -1, &kPinset_google_root_pems }, + { "google.bg", true, false, false, -1, &kPinset_google_root_pems }, + { "google.bi", true, false, false, -1, &kPinset_google_root_pems }, + { "google.bj", true, false, false, -1, &kPinset_google_root_pems }, + { "google.bs", true, false, false, -1, &kPinset_google_root_pems }, + { "google.by", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ca", true, false, false, -1, &kPinset_google_root_pems }, + { "google.cat", true, false, false, -1, &kPinset_google_root_pems }, + { "google.cc", true, false, false, -1, &kPinset_google_root_pems }, + { "google.cd", true, false, false, -1, &kPinset_google_root_pems }, + { "google.cf", true, false, false, -1, &kPinset_google_root_pems }, + { "google.cg", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ch", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ci", true, false, false, -1, &kPinset_google_root_pems }, + { "google.cl", true, false, false, -1, &kPinset_google_root_pems }, + { "google.cm", true, false, false, -1, &kPinset_google_root_pems }, + { "google.cn", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.ao", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.bw", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.ck", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.cr", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.hu", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.id", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.il", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.im", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.in", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.je", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.jp", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.ke", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.kr", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.ls", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.ma", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.mz", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.nz", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.th", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.tz", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.ug", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.uk", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.uz", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.ve", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.vi", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.za", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.zm", true, false, false, -1, &kPinset_google_root_pems }, + { "google.co.zw", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.af", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ag", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ai", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ar", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.au", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.bd", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.bh", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.bn", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.bo", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.br", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.by", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.bz", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.cn", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.co", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.cu", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.cy", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.do", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ec", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.eg", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.et", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.fj", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ge", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.gh", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.gi", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.gr", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.gt", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.hk", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.iq", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.jm", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.jo", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.kh", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.kw", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.lb", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ly", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.mt", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.mx", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.my", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.na", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.nf", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ng", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ni", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.np", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.nr", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.om", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.pa", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.pe", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ph", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.pk", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.pl", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.pr", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.py", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.qa", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ru", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.sa", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.sb", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.sg", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.sl", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.sv", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.tj", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.tn", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.tr", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.tw", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ua", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.uy", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.vc", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.ve", true, false, false, -1, &kPinset_google_root_pems }, + { "google.com.vn", true, false, false, -1, &kPinset_google_root_pems }, + { "google.cv", true, false, false, -1, &kPinset_google_root_pems }, + { "google.cz", true, false, false, -1, &kPinset_google_root_pems }, + { "google.de", true, false, false, -1, &kPinset_google_root_pems }, + { "google.dj", true, false, false, -1, &kPinset_google_root_pems }, + { "google.dk", true, false, false, -1, &kPinset_google_root_pems }, + { "google.dm", true, false, false, -1, &kPinset_google_root_pems }, + { "google.dz", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ee", true, false, false, -1, &kPinset_google_root_pems }, + { "google.es", true, false, false, -1, &kPinset_google_root_pems }, + { "google.fi", true, false, false, -1, &kPinset_google_root_pems }, + { "google.fm", true, false, false, -1, &kPinset_google_root_pems }, + { "google.fr", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ga", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ge", true, false, false, -1, &kPinset_google_root_pems }, + { "google.gg", true, false, false, -1, &kPinset_google_root_pems }, + { "google.gl", true, false, false, -1, &kPinset_google_root_pems }, + { "google.gm", true, false, false, -1, &kPinset_google_root_pems }, + { "google.gp", true, false, false, -1, &kPinset_google_root_pems }, + { "google.gr", true, false, false, -1, &kPinset_google_root_pems }, + { "google.gy", true, false, false, -1, &kPinset_google_root_pems }, + { "google.hk", true, false, false, -1, &kPinset_google_root_pems }, + { "google.hn", true, false, false, -1, &kPinset_google_root_pems }, + { "google.hr", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ht", true, false, false, -1, &kPinset_google_root_pems }, + { "google.hu", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ie", true, false, false, -1, &kPinset_google_root_pems }, + { "google.im", true, false, false, -1, &kPinset_google_root_pems }, + { "google.info", true, false, false, -1, &kPinset_google_root_pems }, + { "google.iq", true, false, false, -1, &kPinset_google_root_pems }, + { "google.is", true, false, false, -1, &kPinset_google_root_pems }, + { "google.it", true, false, false, -1, &kPinset_google_root_pems }, + { "google.it.ao", true, false, false, -1, &kPinset_google_root_pems }, + { "google.je", true, false, false, -1, &kPinset_google_root_pems }, + { "google.jo", true, false, false, -1, &kPinset_google_root_pems }, + { "google.jobs", true, false, false, -1, &kPinset_google_root_pems }, + { "google.jp", true, false, false, -1, &kPinset_google_root_pems }, + { "google.kg", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ki", true, false, false, -1, &kPinset_google_root_pems }, + { "google.kz", true, false, false, -1, &kPinset_google_root_pems }, + { "google.la", true, false, false, -1, &kPinset_google_root_pems }, + { "google.li", true, false, false, -1, &kPinset_google_root_pems }, + { "google.lk", true, false, false, -1, &kPinset_google_root_pems }, + { "google.lt", true, false, false, -1, &kPinset_google_root_pems }, + { "google.lu", true, false, false, -1, &kPinset_google_root_pems }, + { "google.lv", true, false, false, -1, &kPinset_google_root_pems }, + { "google.md", true, false, false, -1, &kPinset_google_root_pems }, + { "google.me", true, false, false, -1, &kPinset_google_root_pems }, + { "google.mg", true, false, false, -1, &kPinset_google_root_pems }, + { "google.mk", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ml", true, false, false, -1, &kPinset_google_root_pems }, + { "google.mn", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ms", true, false, false, -1, &kPinset_google_root_pems }, + { "google.mu", true, false, false, -1, &kPinset_google_root_pems }, + { "google.mv", true, false, false, -1, &kPinset_google_root_pems }, + { "google.mw", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ne", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ne.jp", true, false, false, -1, &kPinset_google_root_pems }, + { "google.net", true, false, false, -1, &kPinset_google_root_pems }, + { "google.nl", true, false, false, -1, &kPinset_google_root_pems }, + { "google.no", true, false, false, -1, &kPinset_google_root_pems }, + { "google.nr", true, false, false, -1, &kPinset_google_root_pems }, + { "google.nu", true, false, false, -1, &kPinset_google_root_pems }, + { "google.off.ai", true, false, false, -1, &kPinset_google_root_pems }, + { "google.pk", true, false, false, -1, &kPinset_google_root_pems }, + { "google.pl", true, false, false, -1, &kPinset_google_root_pems }, + { "google.pn", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ps", true, false, false, -1, &kPinset_google_root_pems }, + { "google.pt", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ro", true, false, false, -1, &kPinset_google_root_pems }, + { "google.rs", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ru", true, false, false, -1, &kPinset_google_root_pems }, + { "google.rw", true, false, false, -1, &kPinset_google_root_pems }, + { "google.sc", true, false, false, -1, &kPinset_google_root_pems }, + { "google.se", true, false, false, -1, &kPinset_google_root_pems }, + { "google.sh", true, false, false, -1, &kPinset_google_root_pems }, + { "google.si", true, false, false, -1, &kPinset_google_root_pems }, + { "google.sk", true, false, false, -1, &kPinset_google_root_pems }, + { "google.sm", true, false, false, -1, &kPinset_google_root_pems }, + { "google.sn", true, false, false, -1, &kPinset_google_root_pems }, + { "google.so", true, false, false, -1, &kPinset_google_root_pems }, + { "google.st", true, false, false, -1, &kPinset_google_root_pems }, + { "google.td", true, false, false, -1, &kPinset_google_root_pems }, + { "google.tg", true, false, false, -1, &kPinset_google_root_pems }, + { "google.tk", true, false, false, -1, &kPinset_google_root_pems }, + { "google.tl", true, false, false, -1, &kPinset_google_root_pems }, + { "google.tm", true, false, false, -1, &kPinset_google_root_pems }, + { "google.tn", true, false, false, -1, &kPinset_google_root_pems }, + { "google.to", true, false, false, -1, &kPinset_google_root_pems }, + { "google.tt", true, false, false, -1, &kPinset_google_root_pems }, + { "google.us", true, false, false, -1, &kPinset_google_root_pems }, + { "google.uz", true, false, false, -1, &kPinset_google_root_pems }, + { "google.vg", true, false, false, -1, &kPinset_google_root_pems }, + { "google.vu", true, false, false, -1, &kPinset_google_root_pems }, + { "google.ws", true, false, false, -1, &kPinset_google_root_pems }, + { "googleadservices.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googleapis.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googlecode.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googlecommerce.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googlegroups.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googlemail.com", false, false, false, -1, &kPinset_google_root_pems }, + { "googleplex.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googlesource.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googlesyndication.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googletagmanager.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googletagservices.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googleusercontent.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googlevideo.com", true, false, false, -1, &kPinset_google_root_pems }, + { "googleweblight.com", true, false, false, -1, &kPinset_google_root_pems }, + { "goto.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "gr.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "groups.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "gstatic.cn", true, false, false, -1, &kPinset_google_root_pems }, + { "gstatic.com", true, false, false, -1, &kPinset_google_root_pems }, + { "gvt1.com", true, false, false, -1, &kPinset_google_root_pems }, + { "gvt2.com", true, false, false, -1, &kPinset_google_root_pems }, + { "gvt3.com", true, false, false, -1, &kPinset_google_root_pems }, + { "hangout", true, false, false, -1, &kPinset_google_root_pems }, + { "hangouts.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "history.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "hk.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "hn.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "hostedtalkgadget.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "hu.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "id.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "ie.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "in.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "inbox.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "include-subdomains.pinning.example.com", true, false, false, -1, &kPinset_mozilla_test }, + { "it.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "kr.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "kz.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "li.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "login.corp.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "login.yahoo.com", true, true, false, -1, &kPinset_yahoo }, + { "lt.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "lu.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "lv.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "m.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "mail-settings.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "mail.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "mail.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "maktoob.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "malaysia.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "market.android.com", true, false, false, -1, &kPinset_google_root_pems }, + { "mbasic.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "meet.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "messenger.com", false, false, false, -1, &kPinset_facebook }, + { "mobile.twitter.com", true, false, false, -1, &kPinset_twitterCom }, + { "mt.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "mtouch.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "mu.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "mw.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "mx.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "myaccount.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "myactivity.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "ni.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "nl.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "no.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "np.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "nz.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "oauth.twitter.com", true, false, false, -1, &kPinset_twitterCom }, + { "oauthaccountmanager.googleapis.com", true, false, false, -1, &kPinset_google_root_pems }, + { "pa.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "passwords.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "passwordsleakcheck-pa.googleapis.com", true, false, false, -1, &kPinset_google_root_pems }, + { "payments.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "pe.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "ph.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "pinning-test.badssl.com", true, false, false, -1, &kPinset_test }, + { "pinningtest.appspot.com", true, false, false, -1, &kPinset_test }, + { "pixel.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "pixel.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "pk.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "pl.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "platform.twitter.com", true, false, false, -1, &kPinset_twitterCDN }, + { "play.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "plus.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "plus.sandbox.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "pr.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "profiles.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "py.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "qc.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "remotedesktop.corp.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "research.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "ro.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "ru.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "rw.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "script.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "se.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "secure.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "security.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "services.mozilla.com", true, false, true, 6, &kPinset_mozilla_services }, + { "sg.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "sites.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "spideroak.com", true, false, false, -1, &kPinset_spideroak }, + { "spreadsheets.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "static.googleadsserving.cn", true, false, false, -1, &kPinset_google_root_pems }, + { "stats.g.doubleclick.net", true, false, false, -1, &kPinset_google_root_pems }, + { "sv.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "swehack.org", true, true, false, -1, &kPinset_swehackCom }, + { "sync.services.mozilla.com", true, false, true, 13, &kPinset_mozilla_services }, + { "t.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "tablet.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "talk.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "talkgadget.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "telemetry.mozilla.org", true, true, true, 8, &kPinset_mozilla_services }, + { "test-mode.pinning.example.com", true, true, false, -1, &kPinset_mozilla_test }, + { "testpilot.firefox.com", false, false, true, 9, &kPinset_mozilla_services }, + { "th.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "torproject.org", false, false, false, -1, &kPinset_tor }, + { "touch.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "tr.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "translate.googleapis.com", true, false, false, -1, &kPinset_google_root_pems }, + { "tv.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "tw.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "twimg.com", true, false, false, -1, &kPinset_twitterCDN }, + { "twitter.com", true, false, false, -1, &kPinset_twitterCDN }, + { "ua.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "ua5v.com", true, false, false, -1, &kPinset_google_root_pems }, + { "uk.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "upload.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "urchin.com", true, false, false, -1, &kPinset_google_root_pems }, + { "uy.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "uz.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "ve.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "vn.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "w-spotlight.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "wallet.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "webfilings-eu-mirror.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "webfilings-eu.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "webfilings-mirror-hrd.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "webfilings.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "wf-bigsky-master.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "wf-demo-eu.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "wf-demo-hrd.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "wf-dogfood-hrd.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "wf-pentest.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "wf-staging-hr.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "wf-training-hrd.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "wf-training-master.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "wf-trial-hrd.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "withgoogle.com", true, false, false, -1, &kPinset_google_root_pems }, + { "withyoutube.com", true, false, false, -1, &kPinset_google_root_pems }, + { "www.dropbox.com", true, false, false, -1, &kPinset_dropbox }, + { "www.facebook.com", true, false, false, -1, &kPinset_facebook }, + { "www.g.co", false, false, false, -1, &kPinset_google_root_pems }, + { "www.gmail.com", false, false, false, -1, &kPinset_google_root_pems }, + { "www.googlegroups.com", true, false, false, -1, &kPinset_google_root_pems }, + { "www.googlemail.com", false, false, false, -1, &kPinset_google_root_pems }, + { "www.messenger.com", true, false, false, -1, &kPinset_facebook }, + { "www.torproject.org", true, false, false, -1, &kPinset_tor }, + { "www.twitter.com", true, false, false, -1, &kPinset_twitterCom }, + { "xa.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "xbrlsuccess.appspot.com", true, false, false, -1, &kPinset_google_root_pems }, + { "xn--7xa.google.com", true, false, false, -1, &kPinset_google_root_pems }, + { "youtu.be", true, false, false, -1, &kPinset_google_root_pems }, + { "youtube-nocookie.com", true, false, false, -1, &kPinset_google_root_pems }, + { "youtube.com", true, false, false, -1, &kPinset_google_root_pems }, + { "ytimg.com", true, false, false, -1, &kPinset_google_root_pems }, + { "za.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, + { "zh.search.yahoo.com", false, true, false, -1, &kPinset_yahoo }, +}; + +// Pinning Preload List Length = 492; + +static const int32_t kUnknownId = -1; + +static const PRTime kPreloadPKPinsExpirationTime = INT64_C(1621521692039000); diff --git a/security/manager/ssl/TransportSecurityInfo.cpp b/security/manager/ssl/TransportSecurityInfo.cpp new file mode 100644 index 0000000000..defb672a0e --- /dev/null +++ b/security/manager/ssl/TransportSecurityInfo.cpp @@ -0,0 +1,1240 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "TransportSecurityInfo.h" + +#include "DateTimeFormat.h" +#include "PSMRunnable.h" +#include "ipc/IPCMessageUtils.h" +#include "mozilla/Casting.h" +#include "nsComponentManagerUtils.h" +#include "nsICertOverrideService.h" +#include "nsIObjectInputStream.h" +#include "nsIObjectOutputStream.h" +#include "nsIWebProgressListener.h" +#include "nsNSSCertHelper.h" +#include "nsNSSCertificate.h" +#include "nsNSSComponent.h" +#include "nsNSSHelper.h" +#include "nsReadableUtils.h" +#include "nsServiceManagerUtils.h" +#include "nsXULAppAPI.h" +#include "mozpkix/pkixtypes.h" +#include "secerr.h" +#include "ssl.h" + +//#define DEBUG_SSL_VERBOSE //Enable this define to get minimal +// reports when doing SSL read/write + +//#define DUMP_BUFFER //Enable this define along with +// DEBUG_SSL_VERBOSE to dump SSL +// read/write buffer to a log. +// Uses PR_LOG except on Mac where +// we always write out to our own +// file. + +namespace mozilla { +namespace psm { + +TransportSecurityInfo::TransportSecurityInfo() + : mCipherSuite(0), + mProtocolVersion(0), + mCertificateTransparencyStatus( + nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE), + mKeaGroup(), + mSignatureSchemeName(), + mIsAcceptedEch(false), + mIsDelegatedCredential(false), + mIsDomainMismatch(false), + mIsNotValidAtThisTime(false), + mIsUntrusted(false), + mIsEV(false), + mHasIsEVStatus(false), + mHaveCipherSuiteAndProtocol(false), + mHaveCertErrorBits(false), + mCanceled(false), + mMutex("TransportSecurityInfo::mMutex"), + mNPNCompleted(false), + mResumed(false), + mIsBuiltCertChainRootBuiltInRoot(false), + mSecurityState(nsIWebProgressListener::STATE_IS_INSECURE), + mErrorCode(0), + mPort(0) {} + +NS_IMPL_ISUPPORTS(TransportSecurityInfo, nsITransportSecurityInfo, + nsIInterfaceRequestor, nsISerializable, nsIClassInfo) + +void TransportSecurityInfo::SetHostName(const char* host) { + MutexAutoLock lock(mMutex); + + mHostName.Assign(host); +} + +void TransportSecurityInfo::SetPort(int32_t aPort) { mPort = aPort; } + +void TransportSecurityInfo::SetOriginAttributes( + const OriginAttributes& aOriginAttributes) { + MutexAutoLock lock(mMutex); + + mOriginAttributes = aOriginAttributes; +} + +// NB: GetErrorCode may be called before an error code is set (if ever). In that +// case, this returns (by pointer) 0, which is treated as a successful value. +NS_IMETHODIMP +TransportSecurityInfo::GetErrorCode(int32_t* state) { + // We're in an inconsistent state if we think we've been canceled but no error + // code was set or we haven't been canceled but an error code was set. + MOZ_ASSERT( + !((mCanceled && mErrorCode == 0) || (!mCanceled && mErrorCode != 0))); + if ((mCanceled && mErrorCode == 0) || (!mCanceled && mErrorCode != 0)) { + mCanceled = true; + mErrorCode = SEC_ERROR_LIBRARY_FAILURE; + } + + *state = mErrorCode; + return NS_OK; +} + +void TransportSecurityInfo::SetCanceled(PRErrorCode errorCode) { + MOZ_ASSERT(errorCode != 0); + if (errorCode == 0) { + errorCode = SEC_ERROR_LIBRARY_FAILURE; + } + + mErrorCode = errorCode; + mCanceled = true; +} + +bool TransportSecurityInfo::IsCanceled() { return mCanceled; } + +NS_IMETHODIMP +TransportSecurityInfo::GetSecurityState(uint32_t* state) { + *state = mSecurityState; + return NS_OK; +} + +void TransportSecurityInfo::SetSecurityState(uint32_t aState) { + mSecurityState = aState; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetErrorCodeString(nsAString& aErrorString) { + const char* codeName = PR_ErrorToName(mErrorCode); + aErrorString.Truncate(); + if (codeName) { + aErrorString = NS_ConvertASCIItoUTF16(codeName); + } + + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetInterface(const nsIID& uuid, void** result) { + if (!NS_IsMainThread()) { + NS_ERROR("nsNSSSocketInfo::GetInterface called off the main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + MutexAutoLock lock(mMutex); + + nsresult rv; + if (!mCallbacks) { + nsCOMPtr ir = new PipUIContext(); + rv = ir->GetInterface(uuid, result); + } else { + rv = mCallbacks->GetInterface(uuid, result); + } + return rv; +} + +// This is a new magic value. However, it re-uses the first 4 bytes +// of the previous value. This is so when older versions attempt to +// read a newer serialized TransportSecurityInfo, they will actually +// fail and return NS_ERROR_FAILURE instead of silently failing. +#define TRANSPORTSECURITYINFOMAGIC \ + { \ + 0xa9863a23, 0x1faa, 0x4169, { \ + 0xb0, 0xd2, 0x81, 0x29, 0xec, 0x7c, 0xb1, 0xde \ + } \ + } +static NS_DEFINE_CID(kTransportSecurityInfoMagic, TRANSPORTSECURITYINFOMAGIC); + +// NB: Any updates (except disk-only fields) must be kept in sync with +// |SerializeToIPC|. +NS_IMETHODIMP +TransportSecurityInfo::Write(nsIObjectOutputStream* aStream) { + nsresult rv = aStream->WriteID(kTransportSecurityInfoMagic); + if (NS_FAILED(rv)) { + return rv; + } + + MutexAutoLock lock(mMutex); + + rv = aStream->Write32(mSecurityState); + if (NS_FAILED(rv)) { + return rv; + } + // mSubRequestsBrokenSecurity was removed in bug 748809 + rv = aStream->Write32(0); + if (NS_FAILED(rv)) { + return rv; + } + // mSubRequestsNoSecurity was removed in bug 748809 + rv = aStream->Write32(0); + if (NS_FAILED(rv)) { + return rv; + } + rv = aStream->Write32(static_cast(mErrorCode)); + if (NS_FAILED(rv)) { + return rv; + } + + // Re-purpose mErrorMessageCached to represent serialization version + // If string doesn't match exact version it will be treated as older + // serialization. + rv = aStream->WriteWStringZ(NS_ConvertUTF8toUTF16("6").get()); + if (NS_FAILED(rv)) { + return rv; + } + + // moved from nsISSLStatus + rv = NS_WriteOptionalCompoundObject(aStream, mServerCert, + NS_GET_IID(nsIX509Cert), true); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->Write16(mCipherSuite); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->Write16(mProtocolVersion); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->WriteBoolean(mIsDomainMismatch); + NS_ENSURE_SUCCESS(rv, rv); + rv = aStream->WriteBoolean(mIsNotValidAtThisTime); + NS_ENSURE_SUCCESS(rv, rv); + rv = aStream->WriteBoolean(mIsUntrusted); + NS_ENSURE_SUCCESS(rv, rv); + rv = aStream->WriteBoolean(mIsEV); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->WriteBoolean(mHasIsEVStatus); + NS_ENSURE_SUCCESS(rv, rv); + rv = aStream->WriteBoolean(mHaveCipherSuiteAndProtocol); + NS_ENSURE_SUCCESS(rv, rv); + rv = aStream->WriteBoolean(mHaveCertErrorBits); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->Write16(mCertificateTransparencyStatus); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->WriteStringZ(mKeaGroup.get()); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->WriteStringZ(mSignatureSchemeName.get()); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->Write16(mSucceededCertChain.Length()); + NS_ENSURE_SUCCESS(rv, rv); + + for (const auto& cert : mSucceededCertChain) { + rv = aStream->WriteCompoundObject(cert, NS_GET_IID(nsIX509Cert), true); + NS_ENSURE_SUCCESS(rv, rv); + } + // END moved from nsISSLStatus + rv = aStream->Write16(mFailedCertChain.Length()); + NS_ENSURE_SUCCESS(rv, rv); + for (const auto& cert : mFailedCertChain) { + rv = aStream->WriteCompoundObject(cert, NS_GET_IID(nsIX509Cert), true); + NS_ENSURE_SUCCESS(rv, rv); + } + + rv = aStream->WriteBoolean(mIsDelegatedCredential); + if (NS_FAILED(rv)) { + return rv; + } + + rv = aStream->WriteBoolean(mNPNCompleted); + if (NS_FAILED(rv)) { + return rv; + } + + rv = aStream->WriteStringZ(mNegotiatedNPN.get()); + if (NS_FAILED(rv)) { + return rv; + } + + rv = aStream->WriteBoolean(mResumed); + if (NS_FAILED(rv)) { + return rv; + } + + rv = aStream->WriteBoolean(mIsBuiltCertChainRootBuiltInRoot); + if (NS_FAILED(rv)) { + return rv; + } + + rv = aStream->WriteBoolean(mIsAcceptedEch); + if (NS_FAILED(rv)) { + return rv; + } + + return NS_OK; +} + +#define CHILD_DIAGNOSTIC_ASSERT(condition, message) \ + if (XRE_GetProcessType() == GeckoProcessType_Content) { \ + MOZ_DIAGNOSTIC_ASSERT(condition, message); \ + } + +// This is for backward compatibility to be able to read nsISSLStatus +// serialized object. +nsresult TransportSecurityInfo::ReadSSLStatus(nsIObjectInputStream* aStream, + MutexAutoLock& aProofOfLock) { + bool nsISSLStatusPresent; + nsresult rv = aStream->ReadBoolean(&nsISSLStatusPresent); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + if (!nsISSLStatusPresent) { + return NS_OK; + } + // nsISSLStatus present. Prepare to read elements. + // Throw away cid, validate iid + nsCID cid; + nsIID iid; + rv = aStream->ReadID(&cid); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = aStream->ReadID(&iid); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + static const nsIID nsSSLStatusIID = { + 0xfa9ba95b, + 0xca3b, + 0x498a, + {0xb8, 0x89, 0x7c, 0x79, 0xcf, 0x28, 0xfe, 0xe8}}; + if (!iid.Equals(nsSSLStatusIID)) { + CHILD_DIAGNOSTIC_ASSERT(false, "Deserialization should not fail"); + return NS_ERROR_UNEXPECTED; + } + + nsCOMPtr cert; + rv = aStream->ReadObject(true, getter_AddRefs(cert)); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + if (cert) { + mServerCert = do_QueryInterface(cert); + if (!mServerCert) { + CHILD_DIAGNOSTIC_ASSERT(false, "Deserialization should not fail"); + return NS_NOINTERFACE; + } + } + + rv = aStream->Read16(&mCipherSuite); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + // The code below is a workaround to allow serializing new fields + // while preserving binary compatibility with older streams. For more details + // on the binary compatibility requirement, refer to bug 1248628. + // Here, we take advantage of the fact that mProtocolVersion was originally + // stored as a 16 bits integer, but the highest 8 bits were never used. + // These bits are now used for stream versioning. + uint16_t protocolVersionAndStreamFormatVersion; + rv = aStream->Read16(&protocolVersionAndStreamFormatVersion); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + mProtocolVersion = protocolVersionAndStreamFormatVersion & 0xFF; + const uint8_t streamFormatVersion = + (protocolVersionAndStreamFormatVersion >> 8) & 0xFF; + + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mIsDomainMismatch); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mIsNotValidAtThisTime); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mIsUntrusted); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mIsEV); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mHasIsEVStatus); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mHaveCipherSuiteAndProtocol); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mHaveCertErrorBits); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + // Added in version 1 (see bug 1305289). + if (streamFormatVersion >= 1) { + rv = aStream->Read16(&mCertificateTransparencyStatus); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + } + + // Added in version 2 (see bug 1304923). + if (streamFormatVersion >= 2) { + rv = aStream->ReadCString(mKeaGroup); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->ReadCString(mSignatureSchemeName); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + } + + // Added in version 3 (see bug 1406856). + if (streamFormatVersion >= 3) { + rv = ReadCertList(aStream, mSucceededCertChain, aProofOfLock); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + + // Read only to consume bytes from the stream. + nsTArray> failedCertChain; + rv = ReadCertList(aStream, failedCertChain, aProofOfLock); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + } + return rv; +} + +// This is for backward compatability to be able to read nsIX509CertList +// serialized object. +nsresult TransportSecurityInfo::ReadCertList( + nsIObjectInputStream* aStream, nsTArray>& aCertList, + MutexAutoLock& aProofOfLock) { + bool nsIX509CertListPresent; + + nsresult rv = aStream->ReadBoolean(&nsIX509CertListPresent); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + if (!nsIX509CertListPresent) { + return NS_OK; + } + // nsIX509CertList present. Prepare to read elements. + // Throw away cid, validate iid + nsCID cid; + nsIID iid; + rv = aStream->ReadID(&cid); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = aStream->ReadID(&iid); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + static const nsIID nsIX509CertListIID = { + 0xae74cda5, + 0xcd2f, + 0x473f, + {0x96, 0xf5, 0xf0, 0xb7, 0xff, 0xf6, 0x2c, 0x68}}; + + if (!iid.Equals(nsIX509CertListIID)) { + CHILD_DIAGNOSTIC_ASSERT(false, "Deserialization should not fail"); + return NS_ERROR_UNEXPECTED; + } + + uint32_t certListSize; + rv = aStream->Read32(&certListSize); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + return ReadCertificatesFromStream(aStream, certListSize, aCertList, + aProofOfLock); +} + +nsresult TransportSecurityInfo::ReadCertificatesFromStream( + nsIObjectInputStream* aStream, uint32_t aSize, + nsTArray>& aCertList, MutexAutoLock& aProofOfLock) { + nsresult rv; + for (uint32_t i = 0; i < aSize; ++i) { + nsCOMPtr support; + rv = aStream->ReadObject(true, getter_AddRefs(support)); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr cert = do_QueryInterface(support); + if (!cert) { + return NS_ERROR_UNEXPECTED; + } + RefPtr castedCert(cert.get()); + aCertList.AppendElement(castedCert); + } + return NS_OK; +} + +// NB: Any updates (except disk-only fields) must be kept in sync with +// |DeserializeFromIPC|. +NS_IMETHODIMP +TransportSecurityInfo::Read(nsIObjectInputStream* aStream) { + nsID id; + nsresult rv = aStream->ReadID(&id); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + if (!id.Equals(kTransportSecurityInfoMagic)) { + CHILD_DIAGNOSTIC_ASSERT(false, "Deserialization should not fail"); + return NS_ERROR_UNEXPECTED; + } + + MutexAutoLock lock(mMutex); + + rv = ReadUint32AndSetAtomicFieldHelper(aStream, mSecurityState); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + // mSubRequestsBrokenSecurity was removed in bug 748809 + uint32_t unusedSubRequestsBrokenSecurity; + rv = aStream->Read32(&unusedSubRequestsBrokenSecurity); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + // mSubRequestsNoSecurity was removed in bug 748809 + uint32_t unusedSubRequestsNoSecurity; + rv = aStream->Read32(&unusedSubRequestsNoSecurity); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + uint32_t errorCode; + rv = aStream->Read32(&errorCode); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + // PRErrorCode will be a negative value + mErrorCode = static_cast(errorCode); + // If mErrorCode is non-zero, SetCanceled was called on the + // TransportSecurityInfo that was serialized. + if (mErrorCode != 0) { + mCanceled = true; + } + + // Re-purpose mErrorMessageCached to represent serialization version + // If string doesn't match exact version it will be treated as older + // serialization. + nsAutoString serVersion; + rv = aStream->ReadString(serVersion); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + + // moved from nsISSLStatus + if (!serVersion.EqualsASCII("1") && !serVersion.EqualsASCII("2") && + !serVersion.EqualsASCII("3") && !serVersion.EqualsASCII("4") && + !serVersion.EqualsASCII("5") && !serVersion.EqualsASCII("6")) { + // nsISSLStatus may be present + rv = ReadSSLStatus(aStream, lock); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + } else { + nsCOMPtr cert; + rv = NS_ReadOptionalObject(aStream, true, getter_AddRefs(cert)); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + if (cert != nullptr) { + mServerCert = do_QueryInterface(cert); + if (!mServerCert) { + CHILD_DIAGNOSTIC_ASSERT(false, "Deserialization should not fail"); + return NS_NOINTERFACE; + } + } + + rv = aStream->Read16(&mCipherSuite); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->Read16(&mProtocolVersion); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mIsDomainMismatch); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mIsNotValidAtThisTime); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mIsUntrusted); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mIsEV); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mHasIsEVStatus); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mHaveCipherSuiteAndProtocol); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mHaveCertErrorBits); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->Read16(&mCertificateTransparencyStatus); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->ReadCString(mKeaGroup); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = aStream->ReadCString(mSignatureSchemeName); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + if (!serVersion.EqualsASCII("3") && !serVersion.EqualsASCII("4") && + !serVersion.EqualsASCII("5") && !serVersion.EqualsASCII("6")) { + // The old data structure of certList(nsIX509CertList) presents + rv = ReadCertList(aStream, mSucceededCertChain, lock); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + } else { + uint16_t certCount; + rv = aStream->Read16(&certCount); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = ReadCertificatesFromStream(aStream, certCount, mSucceededCertChain, + lock); + NS_ENSURE_SUCCESS(rv, rv); + } + } + // END moved from nsISSLStatus + if (!serVersion.EqualsASCII("3") && !serVersion.EqualsASCII("4") && + !serVersion.EqualsASCII("5") && !serVersion.EqualsASCII("6")) { + // The old data structure of certList(nsIX509CertList) presents + rv = ReadCertList(aStream, mFailedCertChain, lock); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + } else { + uint16_t certCount; + rv = aStream->Read16(&certCount); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + NS_ENSURE_SUCCESS(rv, rv); + + rv = ReadCertificatesFromStream(aStream, certCount, mFailedCertChain, lock); + NS_ENSURE_SUCCESS(rv, rv); + } + + // mIsDelegatedCredential added in bug 1562773 + if (serVersion.EqualsASCII("2") || serVersion.EqualsASCII("3") || + serVersion.EqualsASCII("4") || serVersion.EqualsASCII("5") || + serVersion.EqualsASCII("6")) { + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mIsDelegatedCredential); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + } + + // mNPNCompleted, mNegotiatedNPN, mResumed added in bug 1584104 + if (serVersion.EqualsASCII("4") || serVersion.EqualsASCII("5") || + serVersion.EqualsASCII("6")) { + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mNPNCompleted); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + + rv = aStream->ReadCString(mNegotiatedNPN); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mResumed); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + } + + // mIsBuiltCertChainRootBuiltInRoot added in bug 1485652 + if (serVersion.EqualsASCII("5") || serVersion.EqualsASCII("6")) { + rv = ReadBoolAndSetAtomicFieldHelper(aStream, + mIsBuiltCertChainRootBuiltInRoot); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + } + + // mIsAcceptedEch added in bug 1678079 + if (serVersion.EqualsASCII("6")) { + rv = ReadBoolAndSetAtomicFieldHelper(aStream, mIsAcceptedEch); + CHILD_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv), + "Deserialization should not fail"); + if (NS_FAILED(rv)) { + return rv; + } + } + + return NS_OK; +} + +#undef CHILD_DIAGNOSTIC_ASSERT + +void TransportSecurityInfo::SerializeToIPC(IPC::Message* aMsg) { + MutexAutoLock guard(mMutex); + + int32_t errorCode = static_cast(mErrorCode); + + WriteParam(aMsg, static_cast(mSecurityState)); + WriteParam(aMsg, errorCode); + WriteParam(aMsg, mServerCert); + WriteParam(aMsg, mCipherSuite); + WriteParam(aMsg, mProtocolVersion); + WriteParam(aMsg, static_cast(mIsDomainMismatch)); + WriteParam(aMsg, static_cast(mIsNotValidAtThisTime)); + WriteParam(aMsg, static_cast(mIsUntrusted)); + WriteParam(aMsg, static_cast(mIsEV)); + WriteParam(aMsg, static_cast(mHasIsEVStatus)); + WriteParam(aMsg, static_cast(mHaveCipherSuiteAndProtocol)); + WriteParam(aMsg, static_cast(mHaveCertErrorBits)); + WriteParam(aMsg, mCertificateTransparencyStatus); + WriteParam(aMsg, mKeaGroup); + WriteParam(aMsg, mSignatureSchemeName); + WriteParam(aMsg, mSucceededCertChain); + WriteParam(aMsg, mFailedCertChain); + WriteParam(aMsg, static_cast(mIsDelegatedCredential)); + WriteParam(aMsg, static_cast(mNPNCompleted)); + WriteParam(aMsg, mNegotiatedNPN); + WriteParam(aMsg, static_cast(mResumed)); + WriteParam(aMsg, static_cast(mIsBuiltCertChainRootBuiltInRoot)); + WriteParam(aMsg, static_cast(mIsAcceptedEch)); +} + +bool TransportSecurityInfo::DeserializeFromIPC(const IPC::Message* aMsg, + PickleIterator* aIter) { + MutexAutoLock guard(mMutex); + + int32_t errorCode = 0; + + if (!ReadParamAtomicHelper(aMsg, aIter, mSecurityState) || + !ReadParam(aMsg, aIter, &errorCode) || + !ReadParam(aMsg, aIter, &mServerCert) || + !ReadParam(aMsg, aIter, &mCipherSuite) || + !ReadParam(aMsg, aIter, &mProtocolVersion) || + !ReadParamAtomicHelper(aMsg, aIter, mIsDomainMismatch) || + !ReadParamAtomicHelper(aMsg, aIter, mIsNotValidAtThisTime) || + !ReadParamAtomicHelper(aMsg, aIter, mIsUntrusted) || + !ReadParamAtomicHelper(aMsg, aIter, mIsEV) || + !ReadParamAtomicHelper(aMsg, aIter, mHasIsEVStatus) || + !ReadParamAtomicHelper(aMsg, aIter, mHaveCipherSuiteAndProtocol) || + !ReadParamAtomicHelper(aMsg, aIter, mHaveCertErrorBits) || + !ReadParam(aMsg, aIter, &mCertificateTransparencyStatus) || + !ReadParam(aMsg, aIter, &mKeaGroup) || + !ReadParam(aMsg, aIter, &mSignatureSchemeName) || + !ReadParam(aMsg, aIter, &mSucceededCertChain) || + !ReadParam(aMsg, aIter, &mFailedCertChain) || + !ReadParamAtomicHelper(aMsg, aIter, mIsDelegatedCredential) || + !ReadParamAtomicHelper(aMsg, aIter, mNPNCompleted) || + !ReadParam(aMsg, aIter, &mNegotiatedNPN) || + !ReadParamAtomicHelper(aMsg, aIter, mResumed) || + !ReadParamAtomicHelper(aMsg, aIter, mIsBuiltCertChainRootBuiltInRoot) || + !ReadParamAtomicHelper(aMsg, aIter, mIsAcceptedEch)) { + return false; + } + + mErrorCode = static_cast(errorCode); + if (mErrorCode != 0) { + mCanceled = true; + } + + return true; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetInterfaces(nsTArray& array) { + array.Clear(); + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetScriptableHelper(nsIXPCScriptable** _retval) { + *_retval = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetContractID(nsACString& aContractID) { + aContractID.SetIsVoid(true); + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetClassDescription(nsACString& aClassDescription) { + aClassDescription.SetIsVoid(true); + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetClassID(nsCID** aClassID) { + *aClassID = (nsCID*)moz_xmalloc(sizeof(nsCID)); + return GetClassIDNoAlloc(*aClassID); +} + +NS_IMETHODIMP +TransportSecurityInfo::GetFlags(uint32_t* aFlags) { + *aFlags = 0; + return NS_OK; +} + +static NS_DEFINE_CID(kNSSSocketInfoCID, TRANSPORTSECURITYINFO_CID); + +NS_IMETHODIMP +TransportSecurityInfo::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) { + *aClassIDNoAlloc = kNSSSocketInfoCID; + return NS_OK; +} + +// RememberCertErrorsTable + +/*static*/ +RememberCertErrorsTable* RememberCertErrorsTable::sInstance = nullptr; + +RememberCertErrorsTable::RememberCertErrorsTable() + : mErrorHosts(), mMutex("RememberCertErrorsTable::mMutex") {} + +static nsresult GetHostPortKey(TransportSecurityInfo* infoObject, + /*out*/ nsCString& result) { + MOZ_ASSERT(infoObject); + NS_ENSURE_ARG(infoObject); + + result.Truncate(); + + result.Assign(infoObject->GetHostName()); + result.Append(':'); + result.AppendInt(infoObject->GetPort()); + + return NS_OK; +} + +void RememberCertErrorsTable::RememberCertHasError( + TransportSecurityInfo* infoObject, SECStatus certVerificationResult) { + nsresult rv; + + nsAutoCString hostPortKey; + rv = GetHostPortKey(infoObject, hostPortKey); + if (NS_FAILED(rv)) { + return; + } + + if (certVerificationResult != SECSuccess) { + MOZ_ASSERT(infoObject->mHaveCertErrorBits, + "Must have error bits when remembering flags"); + if (!infoObject->mHaveCertErrorBits) { + return; + } + + CertStateBits bits; + bits.mIsDomainMismatch = infoObject->mIsDomainMismatch; + bits.mIsNotValidAtThisTime = infoObject->mIsNotValidAtThisTime; + bits.mIsUntrusted = infoObject->mIsUntrusted; + + MutexAutoLock lock(mMutex); + mErrorHosts.Put(hostPortKey, bits); + } else { + MutexAutoLock lock(mMutex); + mErrorHosts.Remove(hostPortKey); + } +} + +void RememberCertErrorsTable::LookupCertErrorBits( + TransportSecurityInfo* infoObject) { + // Get remembered error bits from our cache, because of SSL session caching + // the NSS library potentially hasn't notified us for this socket. + if (infoObject->mHaveCertErrorBits) { + // Rather do not modify bits if already set earlier + return; + } + + nsresult rv; + + nsAutoCString hostPortKey; + rv = GetHostPortKey(infoObject, hostPortKey); + if (NS_FAILED(rv)) { + return; + } + + CertStateBits bits; + { + MutexAutoLock lock(mMutex); + if (!mErrorHosts.Get(hostPortKey, &bits)) { + // No record was found, this host had no cert errors + return; + } + } + + // This host had cert errors, update the bits correctly + infoObject->mHaveCertErrorBits = true; + infoObject->mIsDomainMismatch = bits.mIsDomainMismatch; + infoObject->mIsNotValidAtThisTime = bits.mIsNotValidAtThisTime; + infoObject->mIsUntrusted = bits.mIsUntrusted; +} + +void TransportSecurityInfo::SetStatusErrorBits(nsNSSCertificate* cert, + uint32_t collected_errors) { + SetServerCert(cert, EVStatus::NotEV); + + mHaveCertErrorBits = true; + mIsDomainMismatch = collected_errors & nsICertOverrideService::ERROR_MISMATCH; + mIsNotValidAtThisTime = collected_errors & nsICertOverrideService::ERROR_TIME; + mIsUntrusted = collected_errors & nsICertOverrideService::ERROR_UNTRUSTED; + + RememberCertErrorsTable::GetInstance().RememberCertHasError(this, SECFailure); +} + +NS_IMETHODIMP +TransportSecurityInfo::GetFailedCertChain( + nsTArray>& aFailedCertChain) { + MOZ_ASSERT(aFailedCertChain.IsEmpty()); + MutexAutoLock lock(mMutex); + if (!aFailedCertChain.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + aFailedCertChain.AppendElements(mFailedCertChain); + return NS_OK; +} + +static nsresult CreateCertChain(nsTArray>& aOutput, + nsTArray>&& aCertList) { + nsTArray> certList = std::move(aCertList); + aOutput.Clear(); + for (auto& certBytes : certList) { + RefPtr cert = nsNSSCertificate::ConstructFromDER( + BitwiseCast(certBytes.Elements()), certBytes.Length()); + if (!cert) { + return NS_ERROR_FAILURE; + } + aOutput.AppendElement(cert); + } + return NS_OK; +} + +nsresult TransportSecurityInfo::SetFailedCertChain( + nsTArray>&& aCertList) { + MutexAutoLock lock(mMutex); + + return CreateCertChain(mFailedCertChain, std::move(aCertList)); +} + +NS_IMETHODIMP TransportSecurityInfo::GetServerCert(nsIX509Cert** aServerCert) { + NS_ENSURE_ARG_POINTER(aServerCert); + MutexAutoLock lock(mMutex); + + nsCOMPtr cert = mServerCert; + cert.forget(aServerCert); + return NS_OK; +} + +void TransportSecurityInfo::SetServerCert(nsNSSCertificate* aServerCert, + EVStatus aEVStatus) { + MOZ_ASSERT(aServerCert); + MutexAutoLock lock(mMutex); + + mServerCert = aServerCert; + mIsEV = (aEVStatus == EVStatus::EV); + mHasIsEVStatus = true; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetSucceededCertChain( + nsTArray>& aSucceededCertChain) { + MOZ_ASSERT(aSucceededCertChain.IsEmpty()); + MutexAutoLock lock(mMutex); + if (!aSucceededCertChain.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + aSucceededCertChain.AppendElements(mSucceededCertChain); + return NS_OK; +} + +nsresult TransportSecurityInfo::SetSucceededCertChain( + nsTArray>&& aCertList) { + MutexAutoLock lock(mMutex); + return CreateCertChain(mSucceededCertChain, std::move(aCertList)); +} + +NS_IMETHODIMP TransportSecurityInfo::SetIsBuiltCertChainRootBuiltInRoot( + bool aIsBuiltInRoot) { + mIsBuiltCertChainRootBuiltInRoot = aIsBuiltInRoot; + return NS_OK; +} + +NS_IMETHODIMP TransportSecurityInfo::GetIsBuiltCertChainRootBuiltInRoot( + bool* aIsBuiltInRoot) { + NS_ENSURE_ARG_POINTER(aIsBuiltInRoot); + *aIsBuiltInRoot = mIsBuiltCertChainRootBuiltInRoot; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetCipherName(nsACString& aCipherName) { + MutexAutoLock lock(mMutex); + + if (!mHaveCipherSuiteAndProtocol) { + return NS_ERROR_NOT_AVAILABLE; + } + + SSLCipherSuiteInfo cipherInfo; + if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo, sizeof(cipherInfo)) != + SECSuccess) { + return NS_ERROR_FAILURE; + } + + aCipherName.Assign(cipherInfo.cipherSuiteName); + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetKeyLength(uint32_t* aKeyLength) { + NS_ENSURE_ARG_POINTER(aKeyLength); + MutexAutoLock lock(mMutex); + if (!mHaveCipherSuiteAndProtocol) { + return NS_ERROR_NOT_AVAILABLE; + } + + SSLCipherSuiteInfo cipherInfo; + if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo, sizeof(cipherInfo)) != + SECSuccess) { + return NS_ERROR_FAILURE; + } + + *aKeyLength = cipherInfo.symKeyBits; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetSecretKeyLength(uint32_t* aSecretKeyLength) { + NS_ENSURE_ARG_POINTER(aSecretKeyLength); + MutexAutoLock lock(mMutex); + if (!mHaveCipherSuiteAndProtocol) { + return NS_ERROR_NOT_AVAILABLE; + } + + SSLCipherSuiteInfo cipherInfo; + if (SSL_GetCipherSuiteInfo(mCipherSuite, &cipherInfo, sizeof(cipherInfo)) != + SECSuccess) { + return NS_ERROR_FAILURE; + } + + *aSecretKeyLength = cipherInfo.effectiveKeyBits; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetKeaGroupName(nsACString& aKeaGroup) { + MutexAutoLock lock(mMutex); + + if (!mHaveCipherSuiteAndProtocol) { + return NS_ERROR_NOT_AVAILABLE; + } + + aKeaGroup.Assign(mKeaGroup); + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetSignatureSchemeName(nsACString& aSignatureScheme) { + MutexAutoLock lock(mMutex); + + if (!mHaveCipherSuiteAndProtocol) { + return NS_ERROR_NOT_AVAILABLE; + } + + aSignatureScheme.Assign(mSignatureSchemeName); + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetProtocolVersion(uint16_t* aProtocolVersion) { + MutexAutoLock lock(mMutex); + + NS_ENSURE_ARG_POINTER(aProtocolVersion); + if (!mHaveCipherSuiteAndProtocol) { + return NS_ERROR_NOT_AVAILABLE; + } + + *aProtocolVersion = mProtocolVersion; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetCertificateTransparencyStatus( + uint16_t* aCertificateTransparencyStatus) { + NS_ENSURE_ARG_POINTER(aCertificateTransparencyStatus); + MutexAutoLock lock(mMutex); + + *aCertificateTransparencyStatus = mCertificateTransparencyStatus; + return NS_OK; +} + +// static +uint16_t TransportSecurityInfo::ConvertCertificateTransparencyInfoToStatus( + const mozilla::psm::CertificateTransparencyInfo& info) { + using mozilla::ct::CTPolicyCompliance; + + if (!info.enabled) { + // CT disabled. + return nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE; + } + + switch (info.policyCompliance) { + case CTPolicyCompliance::Compliant: + return nsITransportSecurityInfo:: + CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT; + case CTPolicyCompliance::NotEnoughScts: + return nsITransportSecurityInfo :: + CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS; + case CTPolicyCompliance::NotDiverseScts: + return nsITransportSecurityInfo :: + CERTIFICATE_TRANSPARENCY_POLICY_NOT_DIVERSE_SCTS; + case CTPolicyCompliance::Unknown: + default: + MOZ_ASSERT_UNREACHABLE("Unexpected CTPolicyCompliance type"); + } + + return nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE; +} + +// static +nsTArray> TransportSecurityInfo::CreateCertBytesArray( + const UniqueCERTCertList& aCertChain) { + nsTArray> certsBytes; + for (CERTCertListNode* n = CERT_LIST_HEAD(aCertChain); + !CERT_LIST_END(n, aCertChain); n = CERT_LIST_NEXT(n)) { + nsTArray certBytes; + certBytes.AppendElements(n->cert->derCert.data, n->cert->derCert.len); + certsBytes.AppendElement(std::move(certBytes)); + } + return certsBytes; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetIsDomainMismatch(bool* aIsDomainMismatch) { + NS_ENSURE_ARG_POINTER(aIsDomainMismatch); + *aIsDomainMismatch = mHaveCertErrorBits && mIsDomainMismatch; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetIsNotValidAtThisTime(bool* aIsNotValidAtThisTime) { + NS_ENSURE_ARG_POINTER(aIsNotValidAtThisTime); + *aIsNotValidAtThisTime = mHaveCertErrorBits && mIsNotValidAtThisTime; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetIsUntrusted(bool* aIsUntrusted) { + NS_ENSURE_ARG_POINTER(aIsUntrusted); + *aIsUntrusted = mHaveCertErrorBits && mIsUntrusted; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetIsExtendedValidation(bool* aIsEV) { + NS_ENSURE_ARG_POINTER(aIsEV); + *aIsEV = false; + // Never allow bad certs for EV, regardless of overrides. + if (mHaveCertErrorBits) { + return NS_OK; + } + + if (mHasIsEVStatus) { + *aIsEV = mIsEV; + return NS_OK; + } + + return NS_ERROR_NOT_AVAILABLE; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetIsAcceptedEch(bool* aIsAcceptedEch) { + NS_ENSURE_ARG_POINTER(aIsAcceptedEch); + if (!mHaveCipherSuiteAndProtocol) { + return NS_ERROR_NOT_AVAILABLE; + } + *aIsAcceptedEch = mIsAcceptedEch; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetIsDelegatedCredential(bool* aIsDelegCred) { + NS_ENSURE_ARG_POINTER(aIsDelegCred); + if (!mHaveCipherSuiteAndProtocol) { + return NS_ERROR_NOT_AVAILABLE; + } + *aIsDelegCred = mIsDelegatedCredential; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetNegotiatedNPN(nsACString& aNegotiatedNPN) { + MutexAutoLock lock(mMutex); + + if (!mNPNCompleted) { + return NS_ERROR_NOT_CONNECTED; + } + + aNegotiatedNPN = mNegotiatedNPN; + return NS_OK; +} + +NS_IMETHODIMP +TransportSecurityInfo::GetResumed(bool* aResumed) { + *aResumed = mResumed; + return NS_OK; +} + +void TransportSecurityInfo::SetResumed(bool aResumed) { mResumed = aResumed; } + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/TransportSecurityInfo.h b/security/manager/ssl/TransportSecurityInfo.h new file mode 100644 index 0000000000..3680956a03 --- /dev/null +++ b/security/manager/ssl/TransportSecurityInfo.h @@ -0,0 +1,255 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef TransportSecurityInfo_h +#define TransportSecurityInfo_h + +#include "CertVerifier.h" // For CertificateTransparencyInfo +#include "ScopedNSSTypes.h" +#include "certt.h" +#include "mozilla/Assertions.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/Mutex.h" +#include "mozilla/RefPtr.h" +#include "mozilla/ipc/TransportSecurityInfoUtils.h" +#include "mozpkix/pkixtypes.h" +#include "nsDataHashtable.h" +#include "nsIClassInfo.h" +#include "nsIObjectInputStream.h" +#include "nsIInterfaceRequestor.h" +#include "nsITransportSecurityInfo.h" +#include "nsNSSCertificate.h" +#include "nsString.h" + +namespace mozilla { +namespace psm { + +enum class EVStatus : uint8_t { + NotEV = 0, + EV = 1, +}; + +class TransportSecurityInfo : public nsITransportSecurityInfo, + public nsIInterfaceRequestor, + public nsISerializable, + public nsIClassInfo { + protected: + virtual ~TransportSecurityInfo() = default; + + public: + TransportSecurityInfo(); + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSITRANSPORTSECURITYINFO + NS_DECL_NSIINTERFACEREQUESTOR + NS_DECL_NSISERIALIZABLE + NS_DECL_NSICLASSINFO + + void SetSecurityState(uint32_t aState); + + inline int32_t GetErrorCode() { + int32_t result; + mozilla::DebugOnly rv = GetErrorCode(&result); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + return result; + } + + const nsACString& GetHostName() const { + MutexAutoLock lock(mMutex); + return mHostName; + } + + void SetHostName(const char* host); + + int32_t GetPort() const { return mPort; } + void SetPort(int32_t aPort); + + const OriginAttributes& GetOriginAttributes() const { + MutexAutoLock lock(mMutex); + return mOriginAttributes; + } + const OriginAttributes& GetOriginAttributes(MutexAutoLock& aProofOfLock) const { + return mOriginAttributes; + } + void SetOriginAttributes(const OriginAttributes& aOriginAttributes); + + void SetCanceled(PRErrorCode errorCode); + bool IsCanceled(); + + void SetStatusErrorBits(nsNSSCertificate* cert, uint32_t collected_errors); + + nsresult SetFailedCertChain(nsTArray>&& certList); + + void SetServerCert(nsNSSCertificate* aServerCert, EVStatus aEVStatus); + + nsresult SetSucceededCertChain(nsTArray>&& certList); + + bool HasServerCert() { + MutexAutoLock lock(mMutex); + return mServerCert != nullptr; + } + + static uint16_t ConvertCertificateTransparencyInfoToStatus( + const mozilla::psm::CertificateTransparencyInfo& info); + + static nsTArray> CreateCertBytesArray( + const UniqueCERTCertList& aCertChain); + + // Use errorCode == 0 to indicate success; + virtual void SetCertVerificationResult(PRErrorCode errorCode){}; + + void SetCertificateTransparencyStatus( + uint16_t aCertificateTransparencyStatus) { + MutexAutoLock lock(mMutex); + mCertificateTransparencyStatus = aCertificateTransparencyStatus; + } + + void SetResumed(bool aResumed); + + uint16_t mCipherSuite; + uint16_t mProtocolVersion; + uint16_t mCertificateTransparencyStatus; + nsCString mKeaGroup; + nsCString mSignatureSchemeName; + + Atomic mIsAcceptedEch; + Atomic mIsDelegatedCredential; + Atomic mIsDomainMismatch; + Atomic mIsNotValidAtThisTime; + Atomic mIsUntrusted; + Atomic mIsEV; + + Atomic mHasIsEVStatus; + Atomic mHaveCipherSuiteAndProtocol; + + /* mHaveCertErrrorBits is relied on to determine whether or not a SPDY + connection is eligible for joining in nsNSSSocketInfo::JoinConnection() */ + Atomic mHaveCertErrorBits; + + private: + // True if SetCanceled has been called (or if this was deserialized with a + // non-zero mErrorCode, which can only be the case if SetCanceled was called + // on the original TransportSecurityInfo). + Atomic mCanceled; + + protected: + mutable ::mozilla::Mutex mMutex; + + nsCOMPtr mCallbacks; + nsTArray> mSucceededCertChain; + Atomic mNPNCompleted; + nsCString mNegotiatedNPN; + Atomic mResumed; + Atomic mIsBuiltCertChainRootBuiltInRoot; + + private: + static nsresult ReadBoolAndSetAtomicFieldHelper(nsIObjectInputStream* stream, + Atomic& atomic) { + bool tmpBool; + nsresult rv = stream->ReadBoolean(&tmpBool); + if (NS_FAILED(rv)) { + return rv; + } + atomic = tmpBool; + return rv; + } + + static nsresult ReadUint32AndSetAtomicFieldHelper( + nsIObjectInputStream* stream, Atomic& atomic) { + uint32_t tmpInt; + nsresult rv = stream->Read32(&tmpInt); + if (NS_FAILED(rv)) { + return rv; + } + atomic = tmpInt; + return rv; + } + + template + static bool ReadParamAtomicHelper(const IPC::Message* aMsg, + PickleIterator* aIter, Atomic

& atomic) { + P tmpStore; + bool result = ReadParam(aMsg, aIter, &tmpStore); + if (result == false) { + return result; + } + atomic = tmpStore; + return result; + } + + Atomic mSecurityState; + + Atomic mErrorCode; + + Atomic mPort; + nsCString mHostName; + OriginAttributes mOriginAttributes; + + nsCOMPtr mServerCert; + + /* Peer cert chain for failed connections (for error reporting) */ + nsTArray> mFailedCertChain; + + nsresult ReadSSLStatus(nsIObjectInputStream* aStream, + MutexAutoLock& aProofOfLock); + + // This function is used to read the binary that are serialized + // by using nsIX509CertList + nsresult ReadCertList(nsIObjectInputStream* aStream, + nsTArray>& aCertList, + MutexAutoLock& aProofOfLock); + nsresult ReadCertificatesFromStream(nsIObjectInputStream* aStream, + uint32_t aSize, + nsTArray>& aCertList, + MutexAutoLock& aProofOfLock); +}; + +class RememberCertErrorsTable { + private: + RememberCertErrorsTable(); + + struct CertStateBits { + bool mIsDomainMismatch; + bool mIsNotValidAtThisTime; + bool mIsUntrusted; + }; + nsDataHashtable mErrorHosts; + + public: + void RememberCertHasError(TransportSecurityInfo* infoObject, + SECStatus certVerificationResult); + void LookupCertErrorBits(TransportSecurityInfo* infoObject); + + static void Init() { sInstance = new RememberCertErrorsTable(); } + + static RememberCertErrorsTable& GetInstance() { + MOZ_ASSERT(sInstance); + return *sInstance; + } + + static void Cleanup() { + delete sInstance; + sInstance = nullptr; + } + + private: + Mutex mMutex; + + static RememberCertErrorsTable* sInstance; +}; + +} // namespace psm +} // namespace mozilla + +// 16786594-0296-4471-8096-8f84497ca428 +#define TRANSPORTSECURITYINFO_CID \ + { \ + 0x16786594, 0x0296, 0x4471, { \ + 0x80, 0x96, 0x8f, 0x84, 0x49, 0x7c, 0xa4, 0x28 \ + } \ + } + +#endif // TransportSecurityInfo_h diff --git a/security/manager/ssl/VerifySSLServerCertChild.cpp b/security/manager/ssl/VerifySSLServerCertChild.cpp new file mode 100644 index 0000000000..019a513463 --- /dev/null +++ b/security/manager/ssl/VerifySSLServerCertChild.cpp @@ -0,0 +1,129 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ + +/* 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/. */ + +#include "VerifySSLServerCertChild.h" + +#include "CertVerifier.h" +#include "mozilla/ipc/BackgroundChild.h" +#include "mozilla/ipc/PBackgroundChild.h" +#include "nsNSSIOLayer.h" +#include "nsSerializationHelper.h" + +extern mozilla::LazyLogModule gPIPNSSLog; + +namespace mozilla { +namespace psm { + +VerifySSLServerCertChild::VerifySSLServerCertChild( + const UniqueCERTCertificate& aCert, + SSLServerCertVerificationResult* aResultTask, + nsTArray>&& aPeerCertChain) + : mCert(CERT_DupCertificate(aCert.get())), + mResultTask(aResultTask), + mPeerCertChain(std::move(aPeerCertChain)) {} + +ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess( + nsTArray&& aBuiltCertChain, + const uint16_t& aCertTransparencyStatus, const uint8_t& aEVStatus, + const bool& aIsBuiltCertChainRootBuiltInRoot) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertSuccess", + this)); + + RefPtr nsc = nsNSSCertificate::Create(mCert.get()); + nsTArray> certBytesArray; + for (auto& cert : aBuiltCertChain) { + certBytesArray.AppendElement(std::move(cert.data())); + } + + mResultTask->Dispatch(nsc, std::move(certBytesArray), + std::move(mPeerCertChain), aCertTransparencyStatus, + static_cast(aEVStatus), true, 0, 0, + aIsBuiltCertChainRootBuiltInRoot); + return IPC_OK(); +} + +ipc::IPCResult VerifySSLServerCertChild::RecvOnVerifiedSSLServerCertFailure( + const uint32_t& aFinalError, const uint32_t& aCollectedErrors) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p]VerifySSLServerCertChild::" + "RecvOnVerifiedSSLServerCertFailure - aFinalError=%u, " + "aCollectedErrors=%u", + this, aFinalError, aCollectedErrors)); + + RefPtr nsc = nsNSSCertificate::Create(mCert.get()); + mResultTask->Dispatch( + nsc, nsTArray>(), std::move(mPeerCertChain), + nsITransportSecurityInfo::CERTIFICATE_TRANSPARENCY_NOT_APPLICABLE, + EVStatus::NotEV, false, aFinalError, aCollectedErrors, false); + return IPC_OK(); +} + +SECStatus RemoteProcessCertVerification( + const UniqueCERTCertificate& aCert, + nsTArray>&& aPeerCertChain, const nsACString& aHostName, + int32_t aPort, const OriginAttributes& aOriginAttributes, + Maybe>& aStapledOCSPResponse, + Maybe>& aSctsFromTLSExtension, + Maybe& aDcInfo, uint32_t aProviderFlags, + uint32_t aCertVerifierFlags, SSLServerCertVerificationResult* aResultTask) { + if (!aResultTask) { + PR_SetError(SEC_ERROR_INVALID_ARGS, 0); + return SECFailure; + } + + const ByteArray serverCertSerialized = + CopyableTArray{aCert->derCert.data, aCert->derCert.len}; + + nsTArray peerCertBytes; + for (auto& certBytes : aPeerCertChain) { + peerCertBytes.AppendElement(ByteArray(certBytes)); + } + + Maybe stapledOCSPResponse; + if (aStapledOCSPResponse) { + stapledOCSPResponse.emplace(); + stapledOCSPResponse->data().Assign(*aStapledOCSPResponse); + } + + Maybe sctsFromTLSExtension; + if (aSctsFromTLSExtension) { + sctsFromTLSExtension.emplace(); + sctsFromTLSExtension->data().Assign(*aSctsFromTLSExtension); + } + + Maybe dcInfo; + if (aDcInfo) { + dcInfo.emplace(); + dcInfo.ref().scheme() = static_cast(aDcInfo->scheme); + dcInfo.ref().authKeyBits() = static_cast(aDcInfo->authKeyBits); + } + + mozilla::ipc::PBackgroundChild* actorChild = mozilla::ipc::BackgroundChild:: + GetOrCreateForSocketParentBridgeForCurrentThread(); + if (!actorChild) { + PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); + return SECFailure; + } + + RefPtr authCert = new VerifySSLServerCertChild( + aCert, aResultTask, std::move(aPeerCertChain)); + if (!actorChild->SendPVerifySSLServerCertConstructor( + authCert, serverCertSerialized, peerCertBytes, + PromiseFlatCString(aHostName), aPort, aOriginAttributes, + stapledOCSPResponse, sctsFromTLSExtension, dcInfo, aProviderFlags, + aCertVerifierFlags)) { + PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); + return SECFailure; + } + + PR_SetError(PR_WOULD_BLOCK_ERROR, 0); + return SECWouldBlock; +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/VerifySSLServerCertChild.h b/security/manager/ssl/VerifySSLServerCertChild.h new file mode 100644 index 0000000000..e904dbaa92 --- /dev/null +++ b/security/manager/ssl/VerifySSLServerCertChild.h @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ + +/* 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/. */ + +#ifndef mozilla_psm_VerifySSLServerCertChild_h__ +#define mozilla_psm_VerifySSLServerCertChild_h__ + +#include "mozilla/psm/PVerifySSLServerCertChild.h" + +#include "SSLServerCertVerification.h" +#include "mozilla/RefPtr.h" +#include "nsISupportsImpl.h" +#include "nsString.h" +#include "seccomon.h" + +namespace mozilla { +namespace psm { + +class DelegatedCredentialInfo; + +// This class implements the socket process part of the server certificate +// verification IPC protocol. +class VerifySSLServerCertChild : public PVerifySSLServerCertChild { + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VerifySSLServerCertChild, override); + + explicit VerifySSLServerCertChild( + const UniqueCERTCertificate& aCert, + SSLServerCertVerificationResult* aResultTask, + nsTArray>&& aPeerCertChain); + + ipc::IPCResult RecvOnVerifiedSSLServerCertSuccess( + nsTArray&& aBuiltCertChain, + const uint16_t& aCertTransparencyStatus, const uint8_t& aEVStatus, + const bool& aIsBuiltCertChainRootBuiltInRoot); + + ipc::IPCResult RecvOnVerifiedSSLServerCertFailure( + const uint32_t& aFinalError, const uint32_t& aCollectedErrors); + + private: + ~VerifySSLServerCertChild() = default; + + UniqueCERTCertificate mCert; + RefPtr mResultTask; + nsTArray> mPeerCertChain; +}; + +SECStatus RemoteProcessCertVerification( + const UniqueCERTCertificate& aCert, + nsTArray>&& aPeerCertChain, const nsACString& aHostName, + int32_t aPort, const OriginAttributes& aOriginAttributes, + Maybe>& aStapledOCSPResponse, + Maybe>& aSctsFromTLSExtension, + Maybe& aDcInfo, uint32_t aProviderFlags, + uint32_t aCertVerifierFlags, SSLServerCertVerificationResult* aResultTask); + +} // namespace psm +} // namespace mozilla + +#endif diff --git a/security/manager/ssl/VerifySSLServerCertParent.cpp b/security/manager/ssl/VerifySSLServerCertParent.cpp new file mode 100644 index 0000000000..f85a0cd827 --- /dev/null +++ b/security/manager/ssl/VerifySSLServerCertParent.cpp @@ -0,0 +1,180 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ + +/* 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/. */ + +#include "VerifySSLServerCertParent.h" + +#include "cert.h" +#include "nsNSSComponent.h" +#include "secerr.h" +#include "SharedCertVerifier.h" +#include "SSLServerCertVerification.h" +#include "nsNSSIOLayer.h" +#include "mozilla/ipc/BackgroundParent.h" +#include "mozilla/Unused.h" + +extern mozilla::LazyLogModule gPIPNSSLog; + +using mozilla::ipc::AssertIsOnBackgroundThread; +using mozilla::ipc::IsOnBackgroundThread; + +using namespace mozilla::pkix; + +namespace mozilla { +namespace psm { + +VerifySSLServerCertParent::VerifySSLServerCertParent() {} + +void VerifySSLServerCertParent::OnVerifiedSSLServerCert( + const nsTArray& aBuiltCertChain, + uint16_t aCertificateTransparencyStatus, uint8_t aEVStatus, bool aSucceeded, + PRErrorCode aFinalError, uint32_t aCollectedErrors, + bool aIsBuiltCertChainRootBuiltInRoot) { + AssertIsOnBackgroundThread(); + + if (!CanSend()) { + return; + } + + if (aSucceeded) { + Unused << SendOnVerifiedSSLServerCertSuccess( + aBuiltCertChain, aCertificateTransparencyStatus, aEVStatus, + aIsBuiltCertChainRootBuiltInRoot); + } else { + Unused << SendOnVerifiedSSLServerCertFailure(aFinalError, aCollectedErrors); + } + Unused << Send__delete__(this); +} + +namespace { + +class IPCServerCertVerificationResult final + : public BaseSSLServerCertVerificationResult { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(IPCServerCertVerificationResult, + override) + + IPCServerCertVerificationResult(nsIEventTarget* aTarget, + VerifySSLServerCertParent* aParent) + : mTarget(aTarget), mParent(aParent) {} + + void Dispatch(nsNSSCertificate* aCert, + nsTArray>&& aBuiltChain, + nsTArray>&& aPeerCertChain, + uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus, + bool aSucceeded, PRErrorCode aFinalError, + uint32_t aCollectedErrors, + bool aIsBuiltCertChainRootBuiltInRoot) override; + + private: + ~IPCServerCertVerificationResult() = default; + + nsCOMPtr mTarget; + RefPtr mParent; +}; + +void IPCServerCertVerificationResult::Dispatch( + nsNSSCertificate* aCert, nsTArray>&& aBuiltChain, + nsTArray>&& aPeerCertChain, + uint16_t aCertificateTransparencyStatus, EVStatus aEVStatus, + bool aSucceeded, PRErrorCode aFinalError, uint32_t aCollectedErrors, + bool aIsBuiltCertChainRootBuiltInRoot) { + nsTArray builtCertChain; + if (aSucceeded) { + for (auto& cert : aBuiltChain) { + builtCertChain.AppendElement(ByteArray(cert)); + } + } + + nsresult nrv = mTarget->Dispatch( + NS_NewRunnableFunction( + "psm::VerifySSLServerCertParent::OnVerifiedSSLServerCert", + [parent(mParent), builtCertChain{std::move(builtCertChain)}, + aCertificateTransparencyStatus, aEVStatus, aSucceeded, aFinalError, + aCollectedErrors, aIsBuiltCertChainRootBuiltInRoot]() { + parent->OnVerifiedSSLServerCert( + builtCertChain, aCertificateTransparencyStatus, + static_cast(aEVStatus), aSucceeded, aFinalError, + aCollectedErrors, aIsBuiltCertChainRootBuiltInRoot); + }), + NS_DISPATCH_NORMAL); + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(nrv)); + Unused << nrv; +} + +} // anonymous namespace + +bool VerifySSLServerCertParent::Dispatch( + const ByteArray& aServerCert, nsTArray&& aPeerCertChain, + const nsCString& aHostName, const int32_t& aPort, + const OriginAttributes& aOriginAttributes, + const Maybe& aStapledOCSPResponse, + const Maybe& aSctsFromTLSExtension, + const Maybe& aDcInfo, + const uint32_t& aProviderFlags, const uint32_t& aCertVerifierFlags) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("VerifySSLServerCertParent::Dispatch")); + AssertIsOnBackgroundThread(); + + mBackgroundThread = NS_GetCurrentThread(); + + SECItem serverCertItem = { + siBuffer, const_cast(aServerCert.data().Elements()), + static_cast(aServerCert.data().Length())}; + UniqueCERTCertificate serverCert(CERT_NewTempCertificate( + CERT_GetDefaultCertDB(), &serverCertItem, nullptr, false, true)); + if (!serverCert) { + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("VerifySSLServerCertParent::Dispatch - CERT_NewTempCertificate cert " + "failed.")); + return false; + } + + nsTArray> peerCertBytes; + for (auto& certBytes : aPeerCertChain) { + nsTArray bytes; + peerCertBytes.AppendElement(std::move(certBytes.data())); + } + + Maybe> stapledOCSPResponse; + if (aStapledOCSPResponse) { + stapledOCSPResponse.emplace(aStapledOCSPResponse->data().Clone()); + } + + Maybe> sctsFromTLSExtension; + if (aSctsFromTLSExtension) { + sctsFromTLSExtension.emplace(aSctsFromTLSExtension->data().Clone()); + } + + Maybe dcInfo; + if (aDcInfo) { + dcInfo.emplace(); + dcInfo->scheme = static_cast(aDcInfo->scheme()); + dcInfo->authKeyBits = aDcInfo->authKeyBits(); + } + + RefPtr resultTask = + new IPCServerCertVerificationResult(mBackgroundThread, this); + SECStatus status = SSLServerCertVerificationJob::Dispatch( + 0, nullptr, serverCert, std::move(peerCertBytes), aHostName, aPort, + aOriginAttributes, stapledOCSPResponse, sctsFromTLSExtension, dcInfo, + aProviderFlags, Now(), PR_Now(), aCertVerifierFlags, resultTask); + + if (status != SECWouldBlock) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("VerifySSLServerCertParent::Dispatch - dispatch failed")); + return false; + } + + return true; +} + +void VerifySSLServerCertParent::ActorDestroy(ActorDestroyReason aWhy) {} + +VerifySSLServerCertParent::~VerifySSLServerCertParent() = default; + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/VerifySSLServerCertParent.h b/security/manager/ssl/VerifySSLServerCertParent.h new file mode 100644 index 0000000000..dd967dc5e4 --- /dev/null +++ b/security/manager/ssl/VerifySSLServerCertParent.h @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set sw=2 ts=8 et tw=80 : */ + +/* 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/. */ + +#ifndef mozilla_psm_VerifySSLServerCertParent_h__ +#define mozilla_psm_VerifySSLServerCertParent_h__ + +#include "mozilla/psm/PVerifySSLServerCertParent.h" +#include "mozpkix/Time.h" +#include "ScopedNSSTypes.h" +#include "SharedCertVerifier.h" + +class nsNSSSocketInfo; + +namespace mozilla { +namespace psm { + +// This class implements the main process side of the server certificate +// verification for socket process. +// SSLServerCertVerificationJob::Dispatch is called in +// VerifySSLServerCertParent::Dispatch with IPCServerCertVerificationResult and +// the result of the certificate verification will be sent to the socket process +// via IPC. +class VerifySSLServerCertParent : public PVerifySSLServerCertParent { + public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VerifySSLServerCertParent, override) + + VerifySSLServerCertParent(); + + bool Dispatch(const ByteArray& aServerCert, + nsTArray&& aPeerCertChain, + const nsCString& aHostName, const int32_t& aPort, + const OriginAttributes& aOriginAttributes, + const Maybe& aStapledOCSPResponse, + const Maybe& aSctsFromTLSExtension, + const Maybe& aDcInfo, + const uint32_t& aProviderFlags, + const uint32_t& aCertVerifierFlags); + + void OnVerifiedSSLServerCert(const nsTArray& aBuiltCertChain, + uint16_t aCertificateTransparencyStatus, + uint8_t aEVStatus, bool aSucceeded, + PRErrorCode aFinalError, + uint32_t aCollectedErrors, + bool aIsBuiltCertChainRootBuiltInRoot); + + private: + virtual ~VerifySSLServerCertParent(); + + // PVerifySSLServerCertParent + void ActorDestroy(ActorDestroyReason aWhy) override; + + nsCOMPtr mBackgroundThread; +}; + +} // namespace psm +} // namespace mozilla + +#endif // mozilla_psm_VerifySSLServerCertParent_h__ diff --git a/security/manager/ssl/X509.jsm b/security/manager/ssl/X509.jsm new file mode 100644 index 0000000000..f797c7929e --- /dev/null +++ b/security/manager/ssl/X509.jsm @@ -0,0 +1,637 @@ +/* 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/. */ + +"use strict"; + +var { DER } = ChromeUtils.import("resource://gre/modules/psm/DER.jsm"); + +const ERROR_UNSUPPORTED_ASN1 = "unsupported asn.1"; +const ERROR_TIME_NOT_VALID = "Time not valid"; +const ERROR_LIBRARY_FAILURE = "library failure"; + +const X509v3 = 2; + +/** + * Helper function to read a NULL tag from the given DER. + * @param {DER} der a DER object to read a NULL from + * @return {NULL} an object representing an ASN.1 NULL + */ +function readNULL(der) { + return new NULL(der.readTagAndGetContents(DER.NULL)); +} + +/** + * Class representing an ASN.1 NULL. When encoded as DER, the only valid value + * is 05 00, and thus the contents should always be an empty array. + */ +class NULL { + /** + * @param {Number[]} bytes the contents of the NULL tag (should be empty) + */ + constructor(bytes) { + // Lint TODO: bytes should be an empty array + this._contents = bytes; + } +} + +/** + * Helper function to read an OBJECT IDENTIFIER from the given DER. + * @param {DER} der the DER to read an OBJECT IDENTIFIER from + * @return {OID} the value of the OBJECT IDENTIFIER + */ +function readOID(der) { + return new OID(der.readTagAndGetContents(DER.OBJECT_IDENTIFIER)); +} + +/** Class representing an ASN.1 OBJECT IDENTIFIER */ +class OID { + /** + * @param {Number[]} bytes the encoded contents of the OBJECT IDENTIFIER + * (not including the ASN.1 tag or length bytes) + */ + constructor(bytes) { + this._values = []; + // First octet has value 40 * value1 + value2 + // Lint TODO: validate that value1 is one of {0, 1, 2} + // Lint TODO: validate that value2 is in [0, 39] if value1 is 0 or 1 + let value1 = Math.floor(bytes[0] / 40); + let value2 = bytes[0] - 40 * value1; + this._values.push(value1); + this._values.push(value2); + bytes.shift(); + let accumulator = 0; + // Lint TODO: prevent overflow here + while (bytes.length > 0) { + let value = bytes.shift(); + accumulator *= 128; + if (value > 128) { + accumulator += value - 128; + } else { + accumulator += value; + this._values.push(accumulator); + accumulator = 0; + } + } + } +} + +/** + * Class that serves as an abstract base class for more specific classes that + * represent datatypes from RFC 5280 and others. Given an array of bytes + * representing the DER encoding of such types, this framework simplifies the + * process of making a new DER object, attempting to parse the given bytes, and + * catching and stashing thrown exceptions. Subclasses are to implement + * parseOverride, which should read from this._der to fill out the structure's + * values. + */ +class DecodedDER { + constructor() { + this._der = null; + this._error = null; + } + + /** + * Returns the first exception encountered when decoding or null if none has + * been encountered. + * @return {Error} the first exception encountered when decoding or null + */ + get error() { + return this._error; + } + + /** + * Does the actual work of parsing the data. To be overridden by subclasses. + * If an implementation of parseOverride throws an exception, parse will catch + * that exception and stash it in the error property. This enables parent + * levels in a nested decoding hierarchy to continue to decode as much as + * possible. + */ + parseOverride() { + throw new Error(ERROR_LIBRARY_FAILURE); + } + + /** + * Public interface to be called to parse all data. Calls parseOverride inside + * a try/catch block. If an exception is thrown, stashes the error, which can + * be obtained via the error getter (above). + * @param {Number[]} bytes encoded DER to be decoded + */ + parse(bytes) { + this._der = new DER.DERDecoder(bytes); + try { + this.parseOverride(); + } catch (e) { + this._error = e; + } + } +} + +/** + * Helper function for reading the next SEQUENCE out of a DER and creating a new + * DER out of the resulting bytes. + * @param {DER} der the underlying DER object + * @return {DER} the contents of the SEQUENCE + */ +function readSEQUENCEAndMakeDER(der) { + return new DER.DERDecoder(der.readTagAndGetContents(DER.SEQUENCE)); +} + +/** + * Helper function for reading the next item identified by tag out of a DER and + * creating a new DER out of the resulting bytes. + * @param {DER} der the underlying DER object + * @param {Number} tag the expected next tag in the DER + * @return {DER} the contents of the tag + */ +function readTagAndMakeDER(der, tag) { + return new DER.DERDecoder(der.readTagAndGetContents(tag)); +} + +// Certificate ::= SEQUENCE { +// tbsCertificate TBSCertificate, +// signatureAlgorithm AlgorithmIdentifier, +// signatureValue BIT STRING } +class Certificate extends DecodedDER { + constructor() { + super(); + this._tbsCertificate = new TBSCertificate(); + this._signatureAlgorithm = new AlgorithmIdentifier(); + this._signatureValue = []; + } + + get tbsCertificate() { + return this._tbsCertificate; + } + + get signatureAlgorithm() { + return this._signatureAlgorithm; + } + + get signatureValue() { + return this._signatureValue; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + this._tbsCertificate.parse(contents.readTLV()); + this._signatureAlgorithm.parse(contents.readTLV()); + + let signatureValue = contents.readBIT_STRING(); + if (signatureValue.unusedBits != 0) { + throw new Error(ERROR_UNSUPPORTED_ASN1); + } + this._signatureValue = signatureValue.contents; + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// TBSCertificate ::= SEQUENCE { +// version [0] EXPLICIT Version DEFAULT v1, +// serialNumber CertificateSerialNumber, +// signature AlgorithmIdentifier, +// issuer Name, +// validity Validity, +// subject Name, +// subjectPublicKeyInfo SubjectPublicKeyInfo, +// issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, +// -- If present, version MUST be v2 or v3 +// subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, +// -- If present, version MUST be v2 or v3 +// extensions [3] EXPLICIT Extensions OPTIONAL +// -- If present, version MUST be v3 +// } +class TBSCertificate extends DecodedDER { + constructor() { + super(); + this._version = null; + this._serialNumber = []; + this._signature = new AlgorithmIdentifier(); + this._issuer = new Name(); + this._validity = new Validity(); + this._subject = new Name(); + this._subjectPublicKeyInfo = new SubjectPublicKeyInfo(); + this._extensions = []; + } + + get version() { + return this._version; + } + + get serialNumber() { + return this._serialNumber; + } + + get signature() { + return this._signature; + } + + get issuer() { + return this._issuer; + } + + get validity() { + return this._validity; + } + + get subject() { + return this._subject; + } + + get subjectPublicKeyInfo() { + return this._subjectPublicKeyInfo; + } + + get extensions() { + return this._extensions; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + + let versionTag = DER.CONTEXT_SPECIFIC | DER.CONSTRUCTED | 0; + if (!contents.peekTag(versionTag)) { + this._version = 1; + } else { + let versionContents = readTagAndMakeDER(contents, versionTag); + let versionBytes = versionContents.readTagAndGetContents(DER.INTEGER); + if (versionBytes.length == 1 && versionBytes[0] == X509v3) { + this._version = 3; + } else { + // Lint TODO: warn about non-v3 certificates (this INTEGER could take up + // multiple bytes, be negative, and so on). + this._version = versionBytes; + } + versionContents.assertAtEnd(); + } + + let serialNumberBytes = contents.readTagAndGetContents(DER.INTEGER); + this._serialNumber = serialNumberBytes; + this._signature.parse(contents.readTLV()); + this._issuer.parse(contents.readTLV()); + this._validity.parse(contents.readTLV()); + this._subject.parse(contents.readTLV()); + this._subjectPublicKeyInfo.parse(contents.readTLV()); + + // Lint TODO: warn about unsupported features + let issuerUniqueIDTag = DER.CONTEXT_SPECIFIC | DER.CONSTRUCTED | 1; + if (contents.peekTag(issuerUniqueIDTag)) { + contents.readTagAndGetContents(issuerUniqueIDTag); + } + let subjectUniqueIDTag = DER.CONTEXT_SPECIFIC | DER.CONSTRUCTED | 2; + if (contents.peekTag(subjectUniqueIDTag)) { + contents.readTagAndGetContents(subjectUniqueIDTag); + } + + let extensionsTag = DER.CONTEXT_SPECIFIC | DER.CONSTRUCTED | 3; + if (contents.peekTag(extensionsTag)) { + let extensionsSequence = readTagAndMakeDER(contents, extensionsTag); + let extensionsContents = readSEQUENCEAndMakeDER(extensionsSequence); + while (!extensionsContents.atEnd()) { + // TODO: parse extensions + this._extensions.push(extensionsContents.readTLV()); + } + extensionsContents.assertAtEnd(); + extensionsSequence.assertAtEnd(); + } + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// AlgorithmIdentifier ::= SEQUENCE { +// algorithm OBJECT IDENTIFIER, +// parameters ANY DEFINED BY algorithm OPTIONAL } +class AlgorithmIdentifier extends DecodedDER { + constructor() { + super(); + this._algorithm = null; + this._parameters = null; + } + + get algorithm() { + return this._algorithm; + } + + get parameters() { + return this._parameters; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + this._algorithm = readOID(contents); + if (!contents.atEnd()) { + if (contents.peekTag(DER.NULL)) { + this._parameters = readNULL(contents); + } else if (contents.peekTag(DER.OBJECT_IDENTIFIER)) { + this._parameters = readOID(contents); + } + } + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// Name ::= CHOICE { -- only one possibility for now -- +// rdnSequence RDNSequence } +// +// RDNSequence ::= SEQUENCE OF RelativeDistinguishedName +class Name extends DecodedDER { + constructor() { + super(); + this._rdns = []; + } + + get rdns() { + return this._rdns; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + while (!contents.atEnd()) { + let rdn = new RelativeDistinguishedName(); + rdn.parse(contents.readTLV()); + this._rdns.push(rdn); + } + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// RelativeDistinguishedName ::= +// SET SIZE (1..MAX) OF AttributeTypeAndValue +class RelativeDistinguishedName extends DecodedDER { + constructor() { + super(); + this._avas = []; + } + + get avas() { + return this._avas; + } + + parseOverride() { + let contents = readTagAndMakeDER(this._der, DER.SET); + // Lint TODO: enforce SET SIZE restrictions + while (!contents.atEnd()) { + let ava = new AttributeTypeAndValue(); + ava.parse(contents.readTLV()); + this._avas.push(ava); + } + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// AttributeTypeAndValue ::= SEQUENCE { +// type AttributeType, +// value AttributeValue } +// +// AttributeType ::= OBJECT IDENTIFIER +// +// AttributeValue ::= ANY -- DEFINED BY AttributeType +class AttributeTypeAndValue extends DecodedDER { + constructor() { + super(); + this._type = null; + this._value = new DirectoryString(); + } + + get type() { + return this._type; + } + + get value() { + return this._value; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + this._type = readOID(contents); + // We don't support universalString or bmpString. + // IA5String is supported because it is valid if `type == id-emailaddress`. + // Lint TODO: validate that the type of string is valid given `type`. + this._value.parse( + contents.readTLVChoice([ + DER.UTF8String, + DER.PrintableString, + DER.TeletexString, + DER.IA5String, + ]) + ); + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// DirectoryString ::= CHOICE { +// teletexString TeletexString (SIZE (1..MAX)), +// printableString PrintableString (SIZE (1..MAX)), +// universalString UniversalString (SIZE (1..MAX)), +// utf8String UTF8String (SIZE (1..MAX)), +// bmpString BMPString (SIZE (1..MAX)) } +class DirectoryString extends DecodedDER { + constructor() { + super(); + this._type = null; + this._value = null; + } + + get type() { + return this._type; + } + + get value() { + return this._value; + } + + parseOverride() { + if (this._der.peekTag(DER.UTF8String)) { + this._type = DER.UTF8String; + } else if (this._der.peekTag(DER.PrintableString)) { + this._type = DER.PrintableString; + } else if (this._der.peekTag(DER.TeletexString)) { + this._type = DER.TeletexString; + } else if (this._der.peekTag(DER.IA5String)) { + this._type = DER.IA5String; + } + // Lint TODO: validate that the contents are actually valid for the type + this._value = this._der.readTagAndGetContents(this._type); + this._der.assertAtEnd(); + } +} + +// Time ::= CHOICE { +// utcTime UTCTime, +// generalTime GeneralizedTime } +class Time extends DecodedDER { + constructor() { + super(); + this._type = null; + this._time = null; + } + + get time() { + return this._time; + } + + parseOverride() { + if (this._der.peekTag(DER.UTCTime)) { + this._type = DER.UTCTime; + } else if (this._der.peekTag(DER.GeneralizedTime)) { + this._type = DER.GeneralizedTime; + } + let contents = readTagAndMakeDER(this._der, this._type); + let year; + // Lint TODO: validate that the appropriate one of {UTCTime,GeneralizedTime} + // is used according to RFC 5280 and what the value of the date is. + // TODO TODO: explain this better (just quote the rfc). + if (this._type == DER.UTCTime) { + // UTCTime is YYMMDDHHMMSSZ in RFC 5280. If YY is greater than or equal + // to 50, the year is 19YY. Otherwise, it is 20YY. + let y1 = this._validateDigit(contents.readByte()); + let y2 = this._validateDigit(contents.readByte()); + let yy = y1 * 10 + y2; + if (yy >= 50) { + year = 1900 + yy; + } else { + year = 2000 + yy; + } + } else { + // GeneralizedTime is YYYYMMDDHHMMSSZ in RFC 5280. + year = 0; + for (let i = 0; i < 4; i++) { + let y = this._validateDigit(contents.readByte()); + year = year * 10 + y; + } + } + + let m1 = this._validateDigit(contents.readByte()); + let m2 = this._validateDigit(contents.readByte()); + let month = m1 * 10 + m2; + if (month == 0 || month > 12) { + throw new Error(ERROR_TIME_NOT_VALID); + } + + let d1 = this._validateDigit(contents.readByte()); + let d2 = this._validateDigit(contents.readByte()); + let day = d1 * 10 + d2; + if (day == 0 || day > 31) { + throw new Error(ERROR_TIME_NOT_VALID); + } + + let h1 = this._validateDigit(contents.readByte()); + let h2 = this._validateDigit(contents.readByte()); + let hour = h1 * 10 + h2; + if (hour > 23) { + throw new Error(ERROR_TIME_NOT_VALID); + } + + let min1 = this._validateDigit(contents.readByte()); + let min2 = this._validateDigit(contents.readByte()); + let minute = min1 * 10 + min2; + if (minute > 59) { + throw new Error(ERROR_TIME_NOT_VALID); + } + + let s1 = this._validateDigit(contents.readByte()); + let s2 = this._validateDigit(contents.readByte()); + let second = s1 * 10 + s2; + if (second > 60) { + // leap-seconds mean this can be as much as 60 + throw new Error(ERROR_TIME_NOT_VALID); + } + + let z = contents.readByte(); + if (z != "Z".charCodeAt(0)) { + throw new Error(ERROR_TIME_NOT_VALID); + } + // Lint TODO: verify that the Time doesn't specify a nonsensical + // month/day/etc. + // months are zero-indexed in JS + this._time = new Date(Date.UTC(year, month - 1, day, hour, minute, second)); + + contents.assertAtEnd(); + this._der.assertAtEnd(); + } + + /** + * Takes a byte that is supposed to be in the ASCII range for "0" to "9". + * Validates the range and then converts it to the range 0 to 9. + * @param {Number} d the digit in question (as ASCII in the range ["0", "9"]) + * @return {Number} the numerical value of the digit (in the range [0, 9]) + */ + _validateDigit(d) { + if (d < "0".charCodeAt(0) || d > "9".charCodeAt(0)) { + throw new Error(ERROR_TIME_NOT_VALID); + } + return d - "0".charCodeAt(0); + } +} + +// Validity ::= SEQUENCE { +// notBefore Time, +// notAfter Time } +class Validity extends DecodedDER { + constructor() { + super(); + this._notBefore = new Time(); + this._notAfter = new Time(); + } + + get notBefore() { + return this._notBefore; + } + + get notAfter() { + return this._notAfter; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + this._notBefore.parse( + contents.readTLVChoice([DER.UTCTime, DER.GeneralizedTime]) + ); + this._notAfter.parse( + contents.readTLVChoice([DER.UTCTime, DER.GeneralizedTime]) + ); + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +// SubjectPublicKeyInfo ::= SEQUENCE { +// algorithm AlgorithmIdentifier, +// subjectPublicKey BIT STRING } +class SubjectPublicKeyInfo extends DecodedDER { + constructor() { + super(); + this._algorithm = new AlgorithmIdentifier(); + this._subjectPublicKey = null; + } + + get algorithm() { + return this._algorithm; + } + + get subjectPublicKey() { + return this._subjectPublicKey; + } + + parseOverride() { + let contents = readSEQUENCEAndMakeDER(this._der); + this._algorithm.parse(contents.readTLV()); + let subjectPublicKeyBitString = contents.readBIT_STRING(); + if (subjectPublicKeyBitString.unusedBits != 0) { + throw new Error(ERROR_UNSUPPORTED_ASN1); + } + this._subjectPublicKey = subjectPublicKeyBitString.contents; + + contents.assertAtEnd(); + this._der.assertAtEnd(); + } +} + +var X509 = { Certificate }; +var EXPORTED_SYMBOLS = ["X509"]; diff --git a/security/manager/ssl/X509CertValidity.cpp b/security/manager/ssl/X509CertValidity.cpp new file mode 100644 index 0000000000..8c09326bb6 --- /dev/null +++ b/security/manager/ssl/X509CertValidity.cpp @@ -0,0 +1,146 @@ +/* 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/. */ + +#include "X509CertValidity.h" + +#include "mozilla/Assertions.h" +#include "mozpkix/pkixder.h" +#include "mozpkix/pkixutil.h" +#include "nsCOMPtr.h" +#include "nsComponentManagerUtils.h" +#include "nsReadableUtils.h" +#include "seccomon.h" +#include "secder.h" + +NS_IMPL_ISUPPORTS(X509CertValidity, nsIX509CertValidity) + +using namespace mozilla; +using namespace mozilla::pkix; +using namespace mozilla::pkix::der; + +X509CertValidity::X509CertValidity(Input certDER) + : mNotBefore(0), mNotAfter(0), mTimesInitialized(false) { + // We're not building a verified certificate chain, so the EndEntityOrCA + // parameter doesn't matter. + BackCert cert(certDER, EndEntityOrCA::MustBeEndEntity, nullptr); + pkix::Result rv = cert.Init(); + if (rv != Success) { + return; + } + // Validity ::= SEQUENCE { + // notBefore Time, + // notAfter Time } + // + // Time ::= CHOICE { + // utcTime UTCTime, + // generalTime GeneralizedTime } + // + // NB: BackCert::GetValidity returns the value of the Validity of the + // certificate (i.e. notBefore and notAfter, without the enclosing SEQUENCE + // and length) + Reader reader(cert.GetValidity()); + uint8_t expectedTag = reader.Peek(UTCTime) ? UTCTime : GENERALIZED_TIME; + Input notBefore; + pkix::Result result = ExpectTagAndGetValue(reader, expectedTag, notBefore); + if (result != Success) { + return; + } + SECItemType notBeforeType = + expectedTag == UTCTime ? siUTCTime : siGeneralizedTime; + SECItem notBeforeItem = { + notBeforeType, const_cast(notBefore.UnsafeGetData()), + notBefore.GetLength()}; + SECStatus srv = DER_DecodeTimeChoice(&mNotBefore, ¬BeforeItem); + if (srv != SECSuccess) { + return; + } + expectedTag = reader.Peek(UTCTime) ? UTCTime : GENERALIZED_TIME; + Input notAfter; + result = ExpectTagAndGetValue(reader, expectedTag, notAfter); + if (result != Success) { + return; + } + SECItemType notAfterType = + expectedTag == UTCTime ? siUTCTime : siGeneralizedTime; + SECItem notAfterItem = {notAfterType, + const_cast(notAfter.UnsafeGetData()), + notAfter.GetLength()}; + srv = DER_DecodeTimeChoice(&mNotAfter, ¬AfterItem); + if (srv != SECSuccess) { + return; + } + + mTimesInitialized = true; +} + +NS_IMETHODIMP +X509CertValidity::GetNotBefore(PRTime* aNotBefore) { + NS_ENSURE_ARG(aNotBefore); + + if (!mTimesInitialized) { + return NS_ERROR_FAILURE; + } + + *aNotBefore = mNotBefore; + return NS_OK; +} + +nsresult X509CertValidity::FormatTime( + const PRTime& aTimeDate, PRTimeParamFn aParamFn, + const nsTimeFormatSelector aTimeFormatSelector, + nsAString& aFormattedTimeDate) { + if (!mTimesInitialized) return NS_ERROR_FAILURE; + + PRExplodedTime explodedTime; + PR_ExplodeTime(const_cast(aTimeDate), aParamFn, &explodedTime); + return mozilla::DateTimeFormat::FormatPRExplodedTime( + kDateFormatLong, aTimeFormatSelector, &explodedTime, aFormattedTimeDate); +} + +NS_IMETHODIMP +X509CertValidity::GetNotBeforeLocalTime(nsAString& aNotBeforeLocalTime) { + return FormatTime(mNotBefore, PR_LocalTimeParameters, kTimeFormatLong, + aNotBeforeLocalTime); +} + +NS_IMETHODIMP +X509CertValidity::GetNotBeforeLocalDay(nsAString& aNotBeforeLocalDay) { + return FormatTime(mNotBefore, PR_LocalTimeParameters, kTimeFormatNone, + aNotBeforeLocalDay); +} + +NS_IMETHODIMP +X509CertValidity::GetNotBeforeGMT(nsAString& aNotBeforeGMT) { + return FormatTime(mNotBefore, PR_GMTParameters, kTimeFormatLong, + aNotBeforeGMT); +} + +NS_IMETHODIMP +X509CertValidity::GetNotAfter(PRTime* aNotAfter) { + NS_ENSURE_ARG(aNotAfter); + + if (!mTimesInitialized) { + return NS_ERROR_FAILURE; + } + + *aNotAfter = mNotAfter; + return NS_OK; +} + +NS_IMETHODIMP +X509CertValidity::GetNotAfterLocalTime(nsAString& aNotAfterLocaltime) { + return FormatTime(mNotAfter, PR_LocalTimeParameters, kTimeFormatLong, + aNotAfterLocaltime); +} + +NS_IMETHODIMP +X509CertValidity::GetNotAfterLocalDay(nsAString& aNotAfterLocalDay) { + return FormatTime(mNotAfter, PR_LocalTimeParameters, kTimeFormatNone, + aNotAfterLocalDay); +} + +NS_IMETHODIMP +X509CertValidity::GetNotAfterGMT(nsAString& aNotAfterGMT) { + return FormatTime(mNotAfter, PR_GMTParameters, kTimeFormatLong, aNotAfterGMT); +} diff --git a/security/manager/ssl/X509CertValidity.h b/security/manager/ssl/X509CertValidity.h new file mode 100644 index 0000000000..c3a7c95f87 --- /dev/null +++ b/security/manager/ssl/X509CertValidity.h @@ -0,0 +1,35 @@ +/* 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/. */ + +#ifndef X509CertValidity_h +#define X509CertValidity_h + +#include "DateTimeFormat.h" +#include "mozpkix/Input.h" +#include "nsIX509CertValidity.h" + +class X509CertValidity : public nsIX509CertValidity { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIX509CERTVALIDITY + + explicit X509CertValidity(mozilla::pkix::Input certDER); + + X509CertValidity(const X509CertValidity& x) = delete; + X509CertValidity& operator=(const X509CertValidity& x) = delete; + + protected: + virtual ~X509CertValidity() = default; + + private: + nsresult FormatTime(const PRTime& aTime, PRTimeParamFn aParamFn, + const mozilla::nsTimeFormatSelector aTimeFormatSelector, + nsAString& aFormattedTimeDate); + + PRTime mNotBefore; + PRTime mNotAfter; + bool mTimesInitialized; +}; + +#endif // X509CertValidity_h diff --git a/security/manager/ssl/cert_storage/Cargo.toml b/security/manager/ssl/cert_storage/Cargo.toml new file mode 100644 index 0000000000..39295b37e3 --- /dev/null +++ b/security/manager/ssl/cert_storage/Cargo.toml @@ -0,0 +1,24 @@ +[package] +name = "cert_storage" +version = "0.0.1" +authors = ["Dana Keeler ", "Mark Goodwin ; +type SingleStore = rkv::SingleStore; + +macro_rules! make_key { + ( $prefix:expr, $( $part:expr ),+ ) => { + { + let mut key = $prefix.as_bytes().to_owned(); + $( key.extend_from_slice($part); )+ + key + } + } +} + +#[allow(non_camel_case_types, non_snake_case)] + +/// `SecurityStateError` is a type to represent errors in accessing or +/// modifying security state. +#[derive(Debug)] +struct SecurityStateError { + message: String, +} + +impl From for SecurityStateError { + /// Creates a new instance of `SecurityStateError` from something that + /// implements the `Display` trait. + fn from(err: T) -> SecurityStateError { + SecurityStateError { + message: format!("{}", err), + } + } +} + +struct EnvAndStore { + env: Rkv, + store: SingleStore, +} + +// In Rust, structs cannot have self references (if a struct gets moved, the compiler has no +// guarantees that the references are still valid). In our case, since the memmapped data is at a +// particular place in memory (and that's what we're referencing), we can use the rental crate to +// create a struct that does reference itself. +rental! { + mod holding { + use super::{Cascade, Mmap}; + + #[rental] + pub struct CRLiteFilter { + backing_file: Box, + cascade: Box>, + } + } +} + +/// `SecurityState` +struct SecurityState { + profile_path: PathBuf, + env_and_store: Option, + int_prefs: HashMap, + crlite_filter: Option, + /// Maps issuer spki hashes to sets of seiral numbers. + crlite_stash: HashMap, HashSet>>, + /// Tracks the number of asynchronous operations which have been dispatched but not completed. + remaining_ops: i32, +} + +impl SecurityState { + pub fn new(profile_path: PathBuf) -> Result { + // Since this gets called on the main thread, we don't actually want to open the DB yet. + // We do this on-demand later, when we're probably on a certificate verification thread. + Ok(SecurityState { + profile_path, + env_and_store: None, + int_prefs: HashMap::new(), + crlite_filter: None, + crlite_stash: HashMap::new(), + remaining_ops: 0, + }) + } + + pub fn db_needs_opening(&self) -> bool { + self.env_and_store.is_none() + } + + pub fn open_db(&mut self) -> Result<(), SecurityStateError> { + if self.env_and_store.is_some() { + return Ok(()); + } + + let store_path = get_store_path(&self.profile_path)?; + + // Open the store in read-write mode to create it (if needed) and migrate data from the old + // store (if any). + // If opening initially fails, try to remove and recreate the database. Consumers will + // repopulate the database as necessary if this happens (see bug 1546361). + let env = make_env(store_path.as_path()).or_else(|_| { + remove_db(store_path.as_path())?; + make_env(store_path.as_path()) + })?; + let store = env.open_single("cert_storage", StoreOptions::create())?; + + // if the profile has a revocations.txt, migrate it and remove the file + let mut revocations_path = self.profile_path.clone(); + revocations_path.push("revocations.txt"); + if revocations_path.exists() { + SecurityState::migrate(&revocations_path, &env, &store)?; + remove_file(revocations_path)?; + } + + // We already returned early if env_and_store was Some, so this should take the None branch. + match self.env_and_store.replace(EnvAndStore { env, store }) { + Some(_) => Err(SecurityStateError::from( + "env and store already initialized? (did we mess up our threading model?)", + )), + None => Ok(()), + }?; + self.load_crlite_filter()?; + self.load_crlite_stash()?; + Ok(()) + } + + fn migrate( + revocations_path: &PathBuf, + env: &Rkv, + store: &SingleStore, + ) -> Result<(), SecurityStateError> { + let f = File::open(revocations_path)?; + let file = BufReader::new(f); + let value = Value::I64(nsICertStorage::STATE_ENFORCE as i64); + let mut writer = env.write()?; + + // Add the data from revocations.txt + let mut dn: Option> = None; + for line in file.lines() { + let l = match line.map_err(|_| SecurityStateError::from("io error reading line data")) { + Ok(data) => data, + Err(e) => return Err(e), + }; + if l.len() == 0 || l.starts_with("#") { + continue; + } + let leading_char = match l.chars().next() { + Some(c) => c, + None => { + return Err(SecurityStateError::from( + "couldn't get char from non-empty str?", + )); + } + }; + // In future, we can maybe log migration failures. For now, ignore decoding and storage + // errors and attempt to continue. + // Check if we have a new DN + if leading_char != '\t' && leading_char != ' ' { + if let Ok(decoded_dn) = base64::decode(&l) { + dn = Some(decoded_dn); + } + continue; + } + let l_sans_prefix = match base64::decode(&l[1..]) { + Ok(decoded) => decoded, + Err(_) => continue, + }; + if let Some(name) = &dn { + if leading_char == '\t' { + let _ = store.put( + &mut writer, + &make_key!(PREFIX_REV_SPK, name, &l_sans_prefix), + &value, + ); + } else { + let _ = store.put( + &mut writer, + &make_key!(PREFIX_REV_IS, name, &l_sans_prefix), + &value, + ); + } + } + } + + writer.commit()?; + Ok(()) + } + + fn read_entry(&self, key: &[u8]) -> Result, SecurityStateError> { + let env_and_store = match self.env_and_store.as_ref() { + Some(env_and_store) => env_and_store, + None => return Err(SecurityStateError::from("env and store not initialized?")), + }; + let reader = env_and_store.env.read()?; + match env_and_store.store.get(&reader, key) { + Ok(Some(Value::I64(i))) + if i <= (std::i16::MAX as i64) && i >= (std::i16::MIN as i64) => + { + Ok(Some(i as i16)) + } + Ok(None) => Ok(None), + Ok(_) => Err(SecurityStateError::from( + "Unexpected type when trying to get a Value::I64", + )), + Err(_) => Err(SecurityStateError::from( + "There was a problem getting the value", + )), + } + } + + pub fn get_has_prior_data(&self, data_type: u8) -> Result { + if data_type == nsICertStorage::DATA_TYPE_CRLITE_FILTER_FULL as u8 { + return Ok(self.crlite_filter.is_some()); + } + if data_type == nsICertStorage::DATA_TYPE_CRLITE_FILTER_INCREMENTAL as u8 { + return Ok(self.crlite_stash.len() != 0); + } + + let env_and_store = match self.env_and_store.as_ref() { + Some(env_and_store) => env_and_store, + None => return Err(SecurityStateError::from("env and store not initialized?")), + }; + let reader = env_and_store.env.read()?; + match env_and_store + .store + .get(&reader, &make_key!(PREFIX_DATA_TYPE, &[data_type])) + { + Ok(Some(Value::Bool(true))) => Ok(true), + Ok(None) => Ok(false), + Ok(_) => Err(SecurityStateError::from( + "Unexpected type when trying to get a Value::Bool", + )), + Err(_) => Err(SecurityStateError::from( + "There was a problem getting the value", + )), + } + } + + pub fn set_batch_state( + &mut self, + entries: &[EncodedSecurityState], + typ: u8, + ) -> Result<(), SecurityStateError> { + let env_and_store = match self.env_and_store.as_mut() { + Some(env_and_store) => env_and_store, + None => return Err(SecurityStateError::from("env and store not initialized?")), + }; + let mut writer = env_and_store.env.write()?; + // Make a note that we have prior data of the given type now. + env_and_store.store.put( + &mut writer, + &make_key!(PREFIX_DATA_TYPE, &[typ]), + &Value::Bool(true), + )?; + + for entry in entries { + let key = match entry.key() { + Ok(key) => key, + Err(e) => { + warn!("error base64-decoding key parts - ignoring: {}", e.message); + continue; + } + }; + env_and_store + .store + .put(&mut writer, &key, &Value::I64(entry.state() as i64))?; + } + + writer.commit()?; + Ok(()) + } + + pub fn get_revocation_state( + &self, + issuer: &[u8], + serial: &[u8], + subject: &[u8], + pub_key: &[u8], + ) -> Result { + let mut digest = Sha256::default(); + digest.input(pub_key); + let pub_key_hash = digest.result(); + + let subject_pubkey = make_key!(PREFIX_REV_SPK, subject, &pub_key_hash); + let issuer_serial = make_key!(PREFIX_REV_IS, issuer, serial); + + let st: i16 = match self.read_entry(&issuer_serial) { + Ok(Some(value)) => value, + Ok(None) => nsICertStorage::STATE_UNSET as i16, + Err(_) => { + return Err(SecurityStateError::from( + "problem reading revocation state (from issuer / serial)", + )); + } + }; + + if st != nsICertStorage::STATE_UNSET as i16 { + return Ok(st); + } + + match self.read_entry(&subject_pubkey) { + Ok(Some(value)) => Ok(value), + Ok(None) => Ok(nsICertStorage::STATE_UNSET as i16), + Err(_) => { + return Err(SecurityStateError::from( + "problem reading revocation state (from subject / pubkey)", + )); + } + } + } + + pub fn get_crlite_state( + &self, + subject: &[u8], + pub_key: &[u8], + ) -> Result { + let mut digest = Sha256::default(); + digest.input(pub_key); + let pub_key_hash = digest.result(); + + let subject_pubkey = make_key!(PREFIX_CRLITE, subject, &pub_key_hash); + match self.read_entry(&subject_pubkey) { + Ok(Some(value)) => Ok(value), + Ok(None) => Ok(nsICertStorage::STATE_UNSET as i16), + Err(_) => Err(SecurityStateError::from("problem reading crlite state")), + } + } + + pub fn set_full_crlite_filter( + &mut self, + filter: Vec, + timestamp: u64, + ) -> Result<(), SecurityStateError> { + // First drop any existing crlite filter and clear the accumulated stash. + { + let _ = self.crlite_filter.take(); + self.crlite_stash.clear(); + let mut path = get_store_path(&self.profile_path)?; + path.push("crlite.stash"); + // Truncate the stash file if it exists. + if path.exists() { + File::create(path).map_err(|e| { + SecurityStateError::from(format!("couldn't truncate stash file: {}", e)) + })?; + } + } + // Write the new full filter. + let mut path = get_store_path(&self.profile_path)?; + path.push("crlite.filter"); + { + let mut filter_file = File::create(&path)?; + filter_file.write_all(&filter)?; + } + self.load_crlite_filter()?; + let env_and_store = match self.env_and_store.as_mut() { + Some(env_and_store) => env_and_store, + None => return Err(SecurityStateError::from("env and store not initialized?")), + }; + let mut writer = env_and_store.env.write()?; + // Make a note of the timestamp of the full filter. + env_and_store.store.put( + &mut writer, + &make_key!( + PREFIX_DATA_TYPE, + &[nsICertStorage::DATA_TYPE_CRLITE_FILTER_FULL as u8] + ), + &Value::U64(timestamp), + )?; + writer.commit()?; + Ok(()) + } + + fn load_crlite_filter(&mut self) -> Result<(), SecurityStateError> { + if self.crlite_filter.is_some() { + return Err(SecurityStateError::from( + "crlite_filter should be None here", + )); + } + let mut path = get_store_path(&self.profile_path)?; + path.push("crlite.filter"); + // Before we've downloaded any filters, this file won't exist. + if !path.exists() { + return Ok(()); + } + let filter_file = File::open(path)?; + let mmap = unsafe { Mmap::map(&filter_file)? }; + let crlite_filter = holding::CRLiteFilter::try_new(Box::new(mmap), |mmap| { + match Cascade::from_bytes(mmap)? { + Some(cascade) => Ok(cascade), + None => Err(SecurityStateError::from("invalid CRLite filter")), + } + }) + .map_err(|_| SecurityStateError::from("unable to initialize CRLite filter"))?; + let old_crlite_filter_should_be_none = self.crlite_filter.replace(crlite_filter); + assert!(old_crlite_filter_should_be_none.is_none()); + Ok(()) + } + + pub fn add_crlite_stash(&mut self, stash: Vec) -> Result<(), SecurityStateError> { + // Append the update to the previously-seen stashes. + let mut path = get_store_path(&self.profile_path)?; + path.push("crlite.stash"); + let mut stash_file = OpenOptions::new().append(true).create(true).open(path)?; + stash_file.write_all(&stash)?; + self.load_crlite_stash_from(&mut stash.as_slice())?; + Ok(()) + } + + fn load_crlite_stash(&mut self) -> Result<(), SecurityStateError> { + self.crlite_stash.clear(); + let mut path = get_store_path(&self.profile_path)?; + path.push("crlite.stash"); + // Before we've downloaded any stashes, this file won't exist. + if !path.exists() { + return Ok(()); + } + let mut stash_file = File::open(path)?; + self.load_crlite_stash_from(&mut stash_file)?; + Ok(()) + } + + fn load_crlite_stash_from(&mut self, reader: &mut dyn Read) -> Result<(), SecurityStateError> { + // The basic unit of the stash file is an issuer subject public key info + // hash (sha-256) followed by a number of serial numbers corresponding + // to revoked certificates issued by that issuer. More specifically, + // each unit consists of: + // 4 bytes little-endian: the number of serial numbers following the issuer spki hash + // 1 byte: the length of the issuer spki hash + // issuer spki hash length bytes: the issuer spki hash + // as many times as the indicated serial numbers: + // 1 byte: the length of the serial number + // serial number length bytes: the serial number + // The stash file consists of any number of these units concatenated + // together. + loop { + let num_serials = match reader.read_u32::() { + Ok(num_serials) => num_serials, + Err(_) => break, // end-of-file, presumably + }; + let issuer_spki_hash_len = reader.read_u8().map_err(|e| { + SecurityStateError::from(format!("error reading stash issuer_spki_hash_len: {}", e)) + })?; + let mut issuer_spki_hash = vec![0; issuer_spki_hash_len as usize]; + reader.read_exact(&mut issuer_spki_hash).map_err(|e| { + SecurityStateError::from(format!("error reading stash issuer_spki_hash: {}", e)) + })?; + let serials = self + .crlite_stash + .entry(issuer_spki_hash) + .or_insert(HashSet::new()); + for _ in 0..num_serials { + let serial_len = reader.read_u8().map_err(|e| { + SecurityStateError::from(format!("error reading stash serial_len: {}", e)) + })?; + let mut serial = vec![0; serial_len as usize]; + reader.read_exact(&mut serial).map_err(|e| { + SecurityStateError::from(format!("error reading stash serial: {}", e)) + })?; + let _ = serials.insert(serial); + } + } + Ok(()) + } + + pub fn is_cert_revoked_by_stash( + &self, + issuer_spki: &[u8], + serial: &[u8], + ) -> Result { + let mut digest = Sha256::default(); + digest.input(issuer_spki); + let lookup_key = digest.result().as_slice().to_vec(); + let serials = match self.crlite_stash.get(&lookup_key) { + Some(serials) => serials, + None => return Ok(false), + }; + Ok(serials.contains(&serial.to_vec())) + } + + pub fn get_crlite_revocation_state( + &self, + issuer: &[u8], + issuer_spki: &[u8], + serial_number: &[u8], + ) -> Result<(u64, i16), SecurityStateError> { + let timestamp = { + let env_and_store = match self.env_and_store.as_ref() { + Some(env_and_store) => env_and_store, + None => return Err(SecurityStateError::from("env and store not initialized?")), + }; + let reader = env_and_store.env.read()?; + match env_and_store.store.get( + &reader, + &make_key!( + PREFIX_DATA_TYPE, + &[nsICertStorage::DATA_TYPE_CRLITE_FILTER_FULL as u8] + ), + ) { + Ok(Some(Value::U64(timestamp))) => timestamp, + // If we don't have a timestamp yet, we won't have a filter. Return the earliest + // timestamp possible to indicate this to callers. + Ok(None) => return Ok((0, nsICertStorage::STATE_UNSET as i16)), + Ok(_) => { + return Err(SecurityStateError::from( + "unexpected type when trying to get Value::U64", + )) + } + Err(_) => return Err(SecurityStateError::from("error getting CRLite timestamp")), + } + }; + let enrollment_state = self.get_crlite_state(issuer, issuer_spki)?; + if enrollment_state != nsICertStorage::STATE_ENFORCE as i16 { + return Ok((timestamp, nsICertStorage::STATE_NOT_ENROLLED as i16)); + } + let mut digest = Sha256::default(); + digest.input(issuer_spki); + let mut lookup_key = digest.result().as_slice().to_vec(); + lookup_key.extend_from_slice(serial_number); + debug!("CRLite lookup key: {:?}", lookup_key); + let result = match &self.crlite_filter { + Some(crlite_filter) => crlite_filter.rent(|filter| filter.has(&lookup_key)), + // This can only happen if the backing file was deleted or if it or our database has + // become corrupted. In any case, we have no information, so again return the earliest + // timestamp to indicate this to the user. + None => return Ok((0, nsICertStorage::STATE_UNSET as i16)), + }; + match result { + true => Ok((timestamp, nsICertStorage::STATE_ENFORCE as i16)), + false => Ok((timestamp, nsICertStorage::STATE_UNSET as i16)), + } + } + + pub fn is_data_fresh( + &self, + update_pref: &str, + allowed_staleness: &str, + ) -> Result { + let checked = match self.int_prefs.get(update_pref) { + Some(ch) => *ch, + None => 0, + }; + let staleness_seconds = match self.int_prefs.get(allowed_staleness) { + Some(st) => *st, + None => 0, + }; + + let update = SystemTime::UNIX_EPOCH + Duration::new(checked as u64, 0); + let staleness = Duration::new(staleness_seconds as u64, 0); + + Ok(match SystemTime::now().duration_since(update) { + Ok(duration) => duration <= staleness, + Err(_) => false, + }) + } + + pub fn is_blocklist_fresh(&self) -> Result { + self.is_data_fresh( + "services.settings.security.onecrl.checked", + "security.onecrl.maximum_staleness_in_seconds", + ) + } + + pub fn pref_seen(&mut self, name: &str, value: u32) { + self.int_prefs.insert(name.to_owned(), value); + } + + // To store certificates, we create a Cert out of each given cert, subject, and trust tuple. We + // hash each certificate with sha-256 to obtain a unique* key for that certificate, and we store + // the Cert in the database. We also look up or create a CertHashList for the given subject and + // add the new certificate's hash if it isn't present in the list. If it wasn't present, we + // write out the updated CertHashList. + // *By the pigeon-hole principle, there exist collisions for sha-256, so this key is not + // actually unique. We rely on the assumption that sha-256 is a cryptographically strong hash. + // If an adversary can find two different certificates with the same sha-256 hash, they can + // probably forge a sha-256-based signature, so assuming the keys we create here are unique is + // not a security issue. + pub fn add_certs( + &mut self, + certs: &[(nsCString, nsCString, i16)], + ) -> Result<(), SecurityStateError> { + let env_and_store = match self.env_and_store.as_mut() { + Some(env_and_store) => env_and_store, + None => return Err(SecurityStateError::from("env and store not initialized?")), + }; + let mut writer = env_and_store.env.write()?; + // Make a note that we have prior cert data now. + env_and_store.store.put( + &mut writer, + &make_key!( + PREFIX_DATA_TYPE, + &[nsICertStorage::DATA_TYPE_CERTIFICATE as u8] + ), + &Value::Bool(true), + )?; + + for (cert_der_base64, subject_base64, trust) in certs { + let cert_der = match base64::decode(&cert_der_base64) { + Ok(cert_der) => cert_der, + Err(e) => { + warn!("error base64-decoding cert - skipping: {}", e); + continue; + } + }; + let subject = match base64::decode(&subject_base64) { + Ok(subject) => subject, + Err(e) => { + warn!("error base64-decoding subject - skipping: {}", e); + continue; + } + }; + let mut digest = Sha256::default(); + digest.input(&cert_der); + let cert_hash = digest.result(); + let cert_key = make_key!(PREFIX_CERT, &cert_hash); + let cert = Cert::new(&cert_der, &subject, *trust)?; + env_and_store + .store + .put(&mut writer, &cert_key, &Value::Blob(&cert.to_bytes()?))?; + let subject_key = make_key!(PREFIX_SUBJECT, &subject); + let empty_vec = Vec::new(); + let old_cert_hash_list = match env_and_store.store.get(&writer, &subject_key)? { + Some(Value::Blob(hashes)) => hashes.to_owned(), + Some(_) => empty_vec, + None => empty_vec, + }; + let new_cert_hash_list = CertHashList::add(&old_cert_hash_list, &cert_hash)?; + if new_cert_hash_list.len() != old_cert_hash_list.len() { + env_and_store.store.put( + &mut writer, + &subject_key, + &Value::Blob(&new_cert_hash_list), + )?; + } + } + + writer.commit()?; + Ok(()) + } + + // Given a list of certificate sha-256 hashes, we can look up each Cert entry in the database. + // We use this to find the corresponding subject so we can look up the CertHashList it should + // appear in. If that list contains the given hash, we remove it and update the CertHashList. + // Finally we delete the Cert entry. + pub fn remove_certs_by_hashes( + &mut self, + hashes_base64: &[nsCString], + ) -> Result<(), SecurityStateError> { + let env_and_store = match self.env_and_store.as_mut() { + Some(env_and_store) => env_and_store, + None => return Err(SecurityStateError::from("env and store not initialized?")), + }; + let mut writer = env_and_store.env.write()?; + let reader = env_and_store.env.read()?; + + for hash in hashes_base64 { + let hash = match base64::decode(&hash) { + Ok(hash) => hash, + Err(e) => { + warn!("error decoding hash - ignoring: {}", e); + continue; + } + }; + let cert_key = make_key!(PREFIX_CERT, &hash); + if let Some(Value::Blob(cert_bytes)) = env_and_store.store.get(&reader, &cert_key)? { + if let Ok(cert) = Cert::from_bytes(cert_bytes) { + let subject_key = make_key!(PREFIX_SUBJECT, &cert.subject); + let empty_vec = Vec::new(); + // We have to use the writer here to make sure we have an up-to-date view of + // the cert hash list. + let old_cert_hash_list = match env_and_store.store.get(&writer, &subject_key)? { + Some(Value::Blob(hashes)) => hashes.to_owned(), + Some(_) => empty_vec, + None => empty_vec, + }; + let new_cert_hash_list = CertHashList::remove(&old_cert_hash_list, &hash)?; + if new_cert_hash_list.len() != old_cert_hash_list.len() { + env_and_store.store.put( + &mut writer, + &subject_key, + &Value::Blob(&new_cert_hash_list), + )?; + } + } + } + match env_and_store.store.delete(&mut writer, &cert_key) { + Ok(()) => {} + Err(StoreError::KeyValuePairNotFound) => {} + Err(e) => return Err(SecurityStateError::from(e)), + }; + } + writer.commit()?; + Ok(()) + } + + // Given a certificate's subject, we look up the corresponding CertHashList. In theory, each + // hash in that list corresponds to a certificate with the given subject, so we look up each of + // these (assuming the database is consistent and contains them) and add them to the given list. + // If we encounter an inconsistency, we continue looking as best we can. + pub fn find_certs_by_subject( + &self, + subject: &[u8], + certs: &mut ThinVec>, + ) -> Result<(), SecurityStateError> { + let env_and_store = match self.env_and_store.as_ref() { + Some(env_and_store) => env_and_store, + None => return Err(SecurityStateError::from("env and store not initialized?")), + }; + let reader = env_and_store.env.read()?; + certs.clear(); + let subject_key = make_key!(PREFIX_SUBJECT, subject); + let empty_vec = Vec::new(); + let cert_hash_list_bytes = match env_and_store.store.get(&reader, &subject_key)? { + Some(Value::Blob(hashes)) => hashes, + Some(_) => &empty_vec, + None => &empty_vec, + }; + let cert_hash_list = CertHashList::new(cert_hash_list_bytes)?; + for cert_hash in cert_hash_list.into_iter() { + let cert_key = make_key!(PREFIX_CERT, cert_hash); + // If there's some inconsistency, we don't want to fail the whole operation - just go + // for best effort and find as many certificates as we can. + if let Some(Value::Blob(cert_bytes)) = env_and_store.store.get(&reader, &cert_key)? { + if let Ok(cert) = Cert::from_bytes(cert_bytes) { + let mut thin_vec_cert = ThinVec::with_capacity(cert.der.len()); + thin_vec_cert.extend_from_slice(&cert.der); + certs.push(thin_vec_cert); + } + } + } + Ok(()) + } +} + +const CERT_SERIALIZATION_VERSION_1: u8 = 1; + +// A Cert consists of its DER encoding, its DER-encoded subject, and its trust (currently +// nsICertStorage::TRUST_INHERIT, but in the future nsICertStorage::TRUST_ANCHOR may also be used). +// The length of each encoding must be representable by a u16 (so 65535 bytes is the longest a +// certificate can be). +struct Cert<'a> { + der: &'a [u8], + subject: &'a [u8], + trust: i16, +} + +impl<'a> Cert<'a> { + fn new(der: &'a [u8], subject: &'a [u8], trust: i16) -> Result, SecurityStateError> { + if der.len() > u16::max as usize { + return Err(SecurityStateError::from("certificate is too long")); + } + if subject.len() > u16::max as usize { + return Err(SecurityStateError::from("subject is too long")); + } + Ok(Cert { + der, + subject, + trust, + }) + } + + fn from_bytes(encoded: &'a [u8]) -> Result, SecurityStateError> { + if encoded.len() < size_of::() { + return Err(SecurityStateError::from("invalid Cert: no version?")); + } + let (mut version, rest) = encoded.split_at(size_of::()); + let version = version.read_u8()?; + if version != CERT_SERIALIZATION_VERSION_1 { + return Err(SecurityStateError::from("invalid Cert: unexpected version")); + } + + if rest.len() < size_of::() { + return Err(SecurityStateError::from("invalid Cert: no der len?")); + } + let (mut der_len, rest) = rest.split_at(size_of::()); + let der_len = der_len.read_u16::()? as usize; + if rest.len() < der_len { + return Err(SecurityStateError::from("invalid Cert: no der?")); + } + let (der, rest) = rest.split_at(der_len); + + if rest.len() < size_of::() { + return Err(SecurityStateError::from("invalid Cert: no subject len?")); + } + let (mut subject_len, rest) = rest.split_at(size_of::()); + let subject_len = subject_len.read_u16::()? as usize; + if rest.len() < subject_len { + return Err(SecurityStateError::from("invalid Cert: no subject?")); + } + let (subject, mut rest) = rest.split_at(subject_len); + + if rest.len() < size_of::() { + return Err(SecurityStateError::from("invalid Cert: no trust?")); + } + let trust = rest.read_i16::()?; + if rest.len() > 0 { + return Err(SecurityStateError::from("invalid Cert: trailing data?")); + } + + Ok(Cert { + der, + subject, + trust, + }) + } + + fn to_bytes(&self) -> Result, SecurityStateError> { + let mut bytes = Vec::with_capacity( + size_of::() + + size_of::() + + self.der.len() + + size_of::() + + self.subject.len() + + size_of::(), + ); + bytes.write_u8(CERT_SERIALIZATION_VERSION_1)?; + if self.der.len() > u16::max as usize { + return Err(SecurityStateError::from("certificate is too long")); + } + bytes.write_u16::(self.der.len() as u16)?; + bytes.extend_from_slice(&self.der); + if self.subject.len() > u16::max as usize { + return Err(SecurityStateError::from("subject is too long")); + } + bytes.write_u16::(self.subject.len() as u16)?; + bytes.extend_from_slice(&self.subject); + bytes.write_i16::(self.trust)?; + Ok(bytes) + } +} + +// A CertHashList is a list of sha-256 hashes of DER-encoded certificates. +struct CertHashList<'a> { + hashes: Vec<&'a [u8]>, +} + +impl<'a> CertHashList<'a> { + fn new(hashes_bytes: &'a [u8]) -> Result, SecurityStateError> { + if hashes_bytes.len() % Sha256::output_size() != 0 { + return Err(SecurityStateError::from( + "unexpected length for cert hash list", + )); + } + let mut hashes = Vec::with_capacity(hashes_bytes.len() / Sha256::output_size()); + for hash in hashes_bytes.chunks_exact(Sha256::output_size()) { + hashes.push(hash); + } + Ok(CertHashList { hashes }) + } + + fn add(hashes_bytes: &[u8], new_hash: &[u8]) -> Result, SecurityStateError> { + if hashes_bytes.len() % Sha256::output_size() != 0 { + return Err(SecurityStateError::from( + "unexpected length for cert hash list", + )); + } + if new_hash.len() != Sha256::output_size() { + return Err(SecurityStateError::from("unexpected cert hash length")); + } + for hash in hashes_bytes.chunks_exact(Sha256::output_size()) { + if hash == new_hash { + return Ok(hashes_bytes.to_owned()); + } + } + let mut combined = hashes_bytes.to_owned(); + combined.extend_from_slice(new_hash); + Ok(combined) + } + + fn remove(hashes_bytes: &[u8], cert_hash: &[u8]) -> Result, SecurityStateError> { + if hashes_bytes.len() % Sha256::output_size() != 0 { + return Err(SecurityStateError::from( + "unexpected length for cert hash list", + )); + } + if cert_hash.len() != Sha256::output_size() { + return Err(SecurityStateError::from("unexpected cert hash length")); + } + let mut result = Vec::with_capacity(hashes_bytes.len()); + for hash in hashes_bytes.chunks_exact(Sha256::output_size()) { + if hash != cert_hash { + result.extend_from_slice(hash); + } + } + Ok(result) + } +} + +impl<'a> IntoIterator for CertHashList<'a> { + type Item = &'a [u8]; + type IntoIter = std::vec::IntoIter<&'a [u8]>; + + fn into_iter(self) -> Self::IntoIter { + self.hashes.into_iter() + } +} + +// Helper struct for set_batch_state. Takes a prefix, two base64-encoded key +// parts, and a security state value. +struct EncodedSecurityState { + prefix: &'static str, + key_part_1_base64: nsCString, + key_part_2_base64: nsCString, + state: i16, +} + +impl EncodedSecurityState { + fn new( + prefix: &'static str, + key_part_1_base64: nsCString, + key_part_2_base64: nsCString, + state: i16, + ) -> EncodedSecurityState { + EncodedSecurityState { + prefix, + key_part_1_base64, + key_part_2_base64, + state, + } + } + + fn key(&self) -> Result, SecurityStateError> { + let key_part_1 = base64::decode(&self.key_part_1_base64)?; + let key_part_2 = base64::decode(&self.key_part_2_base64)?; + Ok(make_key!(self.prefix, &key_part_1, &key_part_2)) + } + + fn state(&self) -> i16 { + self.state + } +} + +fn get_path_from_directory_service(key: &str) -> Result { + let directory_service = match xpcom::services::get_DirectoryService() { + Some(ds) => ds, + _ => return Err(SecurityStateError::from("None")), + }; + + let cs_key = CString::new(key)?; + let mut requested_dir = GetterAddrefs::::new(); + + unsafe { + (*directory_service) + .Get( + (&cs_key).as_ptr(), + &nsIFile::IID as *const nsIID, + requested_dir.void_ptr(), + ) + .to_result() + .map_err(|res| SecurityStateError { + message: (*res.error_name()).as_str_unchecked().to_owned(), + }) + }?; + + let dir_path = match requested_dir.refptr() { + None => return Err(SecurityStateError::from("directory service failure")), + Some(refptr) => refptr, + }; + + let mut path = nsString::new(); + + unsafe { + (*dir_path) + .GetPath(&mut path as &mut nsAString) + // For reasons that aren't clear to me, NsresultExt does not + // implement std::error::Error (or Debug / Display). This map_err + // hack is a way to get an error with a useful message. + .to_result() + .map_err(|res| SecurityStateError { + message: (*res.error_name()).as_str_unchecked().to_owned(), + })?; + } + + Ok(PathBuf::from(format!("{}", path))) +} + +fn get_profile_path() -> Result { + Ok(get_path_from_directory_service("ProfD") + .or_else(|_| get_path_from_directory_service("TmpD"))?) +} + +fn get_store_path(profile_path: &PathBuf) -> Result { + let mut store_path = profile_path.clone(); + store_path.push("security_state"); + create_dir_all(store_path.as_path())?; + Ok(store_path) +} + +fn make_env(path: &Path) -> Result { + let mut builder = Rkv::environment_builder::(); + builder.set_max_dbs(2); + + // 16MB is a little over twice the size of the current dataset. When we + // eventually switch to the LMDB backend to create the builder above, + // we should set this as the map size, since it cannot currently resize. + // (The SafeMode backend warns when a map size is specified, so we skip it + // for now to avoid console spam.) + + // builder.set_map_size(16777216); + + // Bug 1595004: Migrate databases between backends in the future, + // and handle 32 and 64 bit architectures in case of LMDB. + Rkv::from_builder(path, builder).map_err(SecurityStateError::from) +} + +fn unconditionally_remove_file(path: &Path) -> Result<(), SecurityStateError> { + match remove_file(path) { + Ok(()) => Ok(()), + Err(e) => match e.kind() { + std::io::ErrorKind::NotFound => Ok(()), + _ => Err(SecurityStateError::from(e)), + }, + } +} + +fn remove_db(path: &Path) -> Result<(), SecurityStateError> { + // Remove LMDB-related files. + let db = path.join("data.mdb"); + unconditionally_remove_file(&db)?; + let lock = path.join("lock.mdb"); + unconditionally_remove_file(&lock)?; + + // Remove SafeMode-related files. + let db = path.join("data.safe.bin"); + unconditionally_remove_file(&db)?; + + Ok(()) +} + +fn do_construct_cert_storage( + _outer: *const nsISupports, + iid: *const xpcom::nsIID, + result: *mut *mut xpcom::reexports::libc::c_void, +) -> Result<(), SecurityStateError> { + let path_buf = get_profile_path()?; + + let cert_storage = CertStorage::allocate(InitCertStorage { + security_state: Arc::new(RwLock::new(SecurityState::new(path_buf)?)), + queue: create_background_task_queue(cstr!("cert_storage"))?, + }); + + unsafe { + cert_storage + .QueryInterface(iid, result) + // As above; greasy hack because NsresultExt + .to_result() + .map_err(|res| SecurityStateError { + message: (*res.error_name()).as_str_unchecked().to_owned(), + })?; + + return cert_storage.setup_prefs(); + }; +} + +fn read_int_pref(name: &str) -> Result { + let pref_service = match xpcom::services::get_PrefService() { + Some(ps) => ps, + _ => { + return Err(SecurityStateError::from( + "could not get preferences service", + )); + } + }; + + let prefs: RefPtr = match (*pref_service).query_interface() { + Some(pb) => pb, + _ => return Err(SecurityStateError::from("could not QI to nsIPrefBranch")), + }; + let pref_name = match CString::new(name) { + Ok(n) => n, + _ => return Err(SecurityStateError::from("could not build pref name string")), + }; + + let mut pref_value: i32 = 0; + // We can't use GetIntPrefWithDefault because optional_argc is not + // supported. No matter, we can just check for failure and ignore + // any NS_ERROR_UNEXPECTED result. + let res = unsafe { (*prefs).GetIntPref((&pref_name).as_ptr(), (&mut pref_value) as *mut i32) }; + let pref_value = match res { + NS_OK => pref_value, + NS_ERROR_UNEXPECTED => 0, + _ => return Err(SecurityStateError::from("could not read pref")), + }; + if pref_value < 0 { + Ok(0) + } else { + Ok(pref_value as u32) + } +} + +// This is a helper for creating a task that will perform a specific action on a background thread. +struct SecurityStateTask< + T: Default + VariantType, + F: FnOnce(&mut SecurityState) -> Result, +> { + callback: AtomicCell>>, + security_state: Arc>, + result: AtomicCell<(nserror::nsresult, T)>, + task_action: AtomicCell>, +} + +impl Result> + SecurityStateTask +{ + fn new( + callback: &nsICertStorageCallback, + security_state: &Arc>, + task_action: F, + ) -> Result, nsresult> { + let mut ss = security_state.write().or(Err(NS_ERROR_FAILURE))?; + ss.remaining_ops = ss.remaining_ops.wrapping_add(1); + + Ok(SecurityStateTask { + callback: AtomicCell::new(Some(ThreadBoundRefPtr::new(RefPtr::new(callback)))), + security_state: Arc::clone(security_state), + result: AtomicCell::new((NS_ERROR_FAILURE, T::default())), + task_action: AtomicCell::new(Some(task_action)), + }) + } +} + +impl Result> Task + for SecurityStateTask +{ + fn run(&self) { + let mut ss = match self.security_state.write() { + Ok(ss) => ss, + Err(_) => return, + }; + // this is a no-op if the DB is already open + if ss.open_db().is_err() { + return; + } + if let Some(task_action) = self.task_action.swap(None) { + let rv = task_action(&mut ss) + .and_then(|v| Ok((NS_OK, v))) + .unwrap_or((NS_ERROR_FAILURE, T::default())); + self.result.store(rv); + } + } + + fn done(&self) -> Result<(), nsresult> { + let threadbound = self.callback.swap(None).ok_or(NS_ERROR_FAILURE)?; + let callback = threadbound.get_ref().ok_or(NS_ERROR_FAILURE)?; + let result = self.result.swap((NS_ERROR_FAILURE, T::default())); + let variant = result.1.into_variant(); + let nsrv = unsafe { callback.Done(result.0, &*variant) }; + + let mut ss = self.security_state.write().or(Err(NS_ERROR_FAILURE))?; + ss.remaining_ops = ss.remaining_ops.wrapping_sub(1); + + match nsrv { + NS_OK => Ok(()), + e => Err(e), + } + } +} + +#[no_mangle] +pub extern "C" fn cert_storage_constructor( + outer: *const nsISupports, + iid: *const xpcom::nsIID, + result: *mut *mut xpcom::reexports::libc::c_void, +) -> nserror::nsresult { + if !outer.is_null() { + return NS_ERROR_NO_AGGREGATION; + } + + if !is_main_thread() { + return NS_ERROR_NOT_SAME_THREAD; + } + + match do_construct_cert_storage(outer, iid, result) { + Ok(_) => NS_OK, + Err(_) => { + // In future: log something so we know what went wrong? + NS_ERROR_FAILURE + } + } +} + +macro_rules! try_ns { + ($e:expr) => { + match $e { + Ok(value) => value, + Err(_) => return NS_ERROR_FAILURE, + } + }; + ($e:expr, or continue) => { + match $e { + Ok(value) => value, + Err(err) => { + error!("{}", err); + continue; + } + } + }; +} + +// This macro is a way to ensure the DB has been opened while minimizing lock acquisitions in the +// common (read-only) case. First we acquire a read lock and see if we even need to open the DB. If +// not, we can continue with the read lock we already have. Otherwise, we drop the read lock, +// acquire the write lock, open the DB, drop the write lock, and re-acquire the read lock. While it +// is possible for two or more threads to all come to the conclusion that they need to open the DB, +// this isn't ultimately an issue - `open_db` will exit early if another thread has already done the +// work. +macro_rules! get_security_state { + ($self:expr) => {{ + let ss_read_only = try_ns!($self.security_state.read()); + if !ss_read_only.db_needs_opening() { + ss_read_only + } else { + drop(ss_read_only); + { + let mut ss_write = try_ns!($self.security_state.write()); + try_ns!(ss_write.open_db()); + } + try_ns!($self.security_state.read()) + } + }}; +} + +#[derive(xpcom)] +#[xpimplements(nsICertStorage, nsIObserver)] +#[refcnt = "atomic"] +struct InitCertStorage { + security_state: Arc>, + queue: RefPtr, +} + +/// CertStorage implements the nsICertStorage interface. The actual work is done by the +/// SecurityState. To handle any threading issues, we have an atomic-refcounted read/write lock on +/// the one and only SecurityState. So, only one thread can use SecurityState's &mut self functions +/// at a time, while multiple threads can use &self functions simultaneously (as long as there are +/// no threads using an &mut self function). The Arc is to allow for the creation of background +/// tasks that use the SecurityState on the queue owned by CertStorage. This allows us to not block +/// the main thread. +#[allow(non_snake_case)] +impl CertStorage { + unsafe fn setup_prefs(&self) -> Result<(), SecurityStateError> { + let int_prefs = [ + "services.settings.security.onecrl.checked", + "security.onecrl.maximum_staleness_in_seconds", + ]; + + // Fetch add observers for relevant prefs + let pref_service = xpcom::services::get_PrefService().unwrap(); + let prefs: RefPtr = match (*pref_service).query_interface() { + Some(pb) => pb, + _ => return Err(SecurityStateError::from("could not QI to nsIPrefBranch")), + }; + + for pref in int_prefs.iter() { + let pref_nscstr = &nsCStr::from(pref.to_owned()) as &nsACString; + let rv = (*prefs).AddObserverImpl(pref_nscstr, self.coerce::(), false); + match read_int_pref(pref) { + Ok(up) => { + let mut ss = self.security_state.write()?; + // This doesn't use the DB, so no need to open it first. (Also since we do this + // upon initialization, it would defeat the purpose of lazily opening the DB.) + ss.pref_seen(pref, up); + } + Err(_) => return Err(SecurityStateError::from("could not read pref")), + }; + assert!(rv.succeeded()); + } + + Ok(()) + } + + unsafe fn HasPriorData( + &self, + data_type: u8, + callback: *const nsICertStorageCallback, + ) -> nserror::nsresult { + if !is_main_thread() { + return NS_ERROR_NOT_SAME_THREAD; + } + if callback.is_null() { + return NS_ERROR_NULL_POINTER; + } + let task = Box::new(try_ns!(SecurityStateTask::new( + &*callback, + &self.security_state, + move |ss| ss.get_has_prior_data(data_type), + ))); + let runnable = try_ns!(TaskRunnable::new("HasPriorData", task)); + try_ns!(TaskRunnable::dispatch(runnable, self.queue.coerce())); + NS_OK + } + + unsafe fn GetRemainingOperationCount(&self, state: *mut i32) -> nserror::nsresult { + if !is_main_thread() { + return NS_ERROR_NOT_SAME_THREAD; + } + if state.is_null() { + return NS_ERROR_NULL_POINTER; + } + let ss = try_ns!(self.security_state.read()); + *state = ss.remaining_ops; + NS_OK + } + + unsafe fn SetRevocations( + &self, + revocations: *const ThinVec>, + callback: *const nsICertStorageCallback, + ) -> nserror::nsresult { + if !is_main_thread() { + return NS_ERROR_NOT_SAME_THREAD; + } + if revocations.is_null() || callback.is_null() { + return NS_ERROR_NULL_POINTER; + } + + let revocations = &*revocations; + let mut entries = Vec::with_capacity(revocations.len()); + + // By continuing when an nsIRevocationState attribute value is invalid, + // we prevent errors relating to individual blocklist entries from + // causing sync to fail. We will accumulate telemetry on these failures + // in bug 1254099. + + for revocation in revocations { + let mut state: i16 = 0; + try_ns!(revocation.GetState(&mut state).to_result(), or continue); + + if let Some(revocation) = + (*revocation).query_interface::() + { + let mut issuer = nsCString::new(); + try_ns!(revocation.GetIssuer(&mut *issuer).to_result(), or continue); + + let mut serial = nsCString::new(); + try_ns!(revocation.GetSerial(&mut *serial).to_result(), or continue); + + entries.push(EncodedSecurityState::new( + PREFIX_REV_IS, + issuer, + serial, + state, + )); + } else if let Some(revocation) = + (*revocation).query_interface::() + { + let mut subject = nsCString::new(); + try_ns!(revocation.GetSubject(&mut *subject).to_result(), or continue); + + let mut pub_key_hash = nsCString::new(); + try_ns!(revocation.GetPubKey(&mut *pub_key_hash).to_result(), or continue); + + entries.push(EncodedSecurityState::new( + PREFIX_REV_SPK, + subject, + pub_key_hash, + state, + )); + } + } + + let task = Box::new(try_ns!(SecurityStateTask::new( + &*callback, + &self.security_state, + move |ss| ss.set_batch_state(&entries, nsICertStorage::DATA_TYPE_REVOCATION as u8), + ))); + let runnable = try_ns!(TaskRunnable::new("SetRevocations", task)); + try_ns!(TaskRunnable::dispatch(runnable, self.queue.coerce())); + NS_OK + } + + unsafe fn GetRevocationState( + &self, + issuer: *const ThinVec, + serial: *const ThinVec, + subject: *const ThinVec, + pub_key: *const ThinVec, + state: *mut i16, + ) -> nserror::nsresult { + // TODO (bug 1541212): We really want to restrict this to non-main-threads only, but we + // can't do so until bug 1406854 is fixed. + if issuer.is_null() || serial.is_null() || subject.is_null() || pub_key.is_null() { + return NS_ERROR_NULL_POINTER; + } + *state = nsICertStorage::STATE_UNSET as i16; + let ss = get_security_state!(self); + match ss.get_revocation_state(&*issuer, &*serial, &*subject, &*pub_key) { + Ok(st) => { + *state = st; + NS_OK + } + _ => NS_ERROR_FAILURE, + } + } + + unsafe fn IsBlocklistFresh(&self, fresh: *mut bool) -> nserror::nsresult { + *fresh = false; + let ss = try_ns!(self.security_state.read()); + // This doesn't use the db -> don't need to make sure it's open. + *fresh = match ss.is_blocklist_fresh() { + Ok(is_fresh) => is_fresh, + Err(_) => false, + }; + + NS_OK + } + + unsafe fn SetCRLiteState( + &self, + crlite_state: *const ThinVec>, + callback: *const nsICertStorageCallback, + ) -> nserror::nsresult { + if !is_main_thread() { + return NS_ERROR_NOT_SAME_THREAD; + } + if crlite_state.is_null() || callback.is_null() { + return NS_ERROR_NULL_POINTER; + } + + let crlite_state = &*crlite_state; + let mut crlite_entries = Vec::with_capacity(crlite_state.len()); + + // By continuing when an nsICRLiteState attribute value is invalid, we prevent errors + // relating to individual entries from causing sync to fail. + for crlite_entry in crlite_state { + let mut state: i16 = 0; + try_ns!(crlite_entry.GetState(&mut state).to_result(), or continue); + + let mut subject = nsCString::new(); + try_ns!(crlite_entry.GetSubject(&mut *subject).to_result(), or continue); + + let mut pub_key_hash = nsCString::new(); + try_ns!(crlite_entry.GetSpkiHash(&mut *pub_key_hash).to_result(), or continue); + + crlite_entries.push(EncodedSecurityState::new( + PREFIX_CRLITE, + subject, + pub_key_hash, + state, + )); + } + + let task = Box::new(try_ns!(SecurityStateTask::new( + &*callback, + &self.security_state, + move |ss| ss.set_batch_state(&crlite_entries, nsICertStorage::DATA_TYPE_CRLITE as u8), + ))); + let runnable = try_ns!(TaskRunnable::new("SetCRLiteState", task)); + try_ns!(TaskRunnable::dispatch(runnable, self.queue.coerce())); + NS_OK + } + + unsafe fn GetCRLiteState( + &self, + subject: *const ThinVec, + pub_key: *const ThinVec, + state: *mut i16, + ) -> nserror::nsresult { + // TODO (bug 1541212): We really want to restrict this to non-main-threads only, but we + // can't do so until bug 1406854 is fixed. + if subject.is_null() || pub_key.is_null() { + return NS_ERROR_NULL_POINTER; + } + *state = nsICertStorage::STATE_UNSET as i16; + let ss = get_security_state!(self); + match ss.get_crlite_state(&*subject, &*pub_key) { + Ok(st) => { + *state = st; + NS_OK + } + _ => NS_ERROR_FAILURE, + } + } + + unsafe fn SetFullCRLiteFilter( + &self, + filter: *const ThinVec, + timestamp: u64, + callback: *const nsICertStorageCallback, + ) -> nserror::nsresult { + if !is_main_thread() { + return NS_ERROR_NOT_SAME_THREAD; + } + if filter.is_null() || callback.is_null() { + return NS_ERROR_NULL_POINTER; + } + let filter_owned = (*filter).to_vec(); + let task = Box::new(try_ns!(SecurityStateTask::new( + &*callback, + &self.security_state, + move |ss| ss.set_full_crlite_filter(filter_owned, timestamp), + ))); + let runnable = try_ns!(TaskRunnable::new("SetFullCRLiteFilter", task)); + try_ns!(TaskRunnable::dispatch(runnable, self.queue.coerce())); + NS_OK + } + + unsafe fn AddCRLiteStash( + &self, + stash: *const ThinVec, + callback: *const nsICertStorageCallback, + ) -> nserror::nsresult { + if !is_main_thread() { + return NS_ERROR_NOT_SAME_THREAD; + } + if stash.is_null() || callback.is_null() { + return NS_ERROR_NULL_POINTER; + } + let stash_owned = (*stash).to_vec(); + let task = Box::new(try_ns!(SecurityStateTask::new( + &*callback, + &self.security_state, + move |ss| ss.add_crlite_stash(stash_owned), + ))); + let runnable = try_ns!(TaskRunnable::new("AddCRLiteStash", task)); + try_ns!(TaskRunnable::dispatch(runnable, self.queue.coerce())); + NS_OK + } + + unsafe fn IsCertRevokedByStash( + &self, + issuer_spki: *const ThinVec, + serial_number: *const ThinVec, + is_revoked: *mut bool, + ) -> nserror::nsresult { + if issuer_spki.is_null() || serial_number.is_null() || is_revoked.is_null() { + return NS_ERROR_NULL_POINTER; + } + let ss = get_security_state!(self); + *is_revoked = match ss.is_cert_revoked_by_stash(&*issuer_spki, &*serial_number) { + Ok(is_revoked) => is_revoked, + Err(_) => return NS_ERROR_FAILURE, + }; + NS_OK + } + + unsafe fn GetCRLiteRevocationState( + &self, + issuer: *const ThinVec, + issuerSPKI: *const ThinVec, + serialNumber: *const ThinVec, + valid_before: *mut u64, + state: *mut i16, + ) -> nserror::nsresult { + // TODO (bug 1541212): We really want to restrict this to non-main-threads only, but we + // can't do so until bug 1406854 is fixed. + if issuer.is_null() + || issuerSPKI.is_null() + || serialNumber.is_null() + || valid_before.is_null() + || state.is_null() + { + return NS_ERROR_NULL_POINTER; + } + *valid_before = 0; + *state = nsICertStorage::STATE_UNSET as i16; + let ss = get_security_state!(self); + match ss.get_crlite_revocation_state(&*issuer, &*issuerSPKI, &*serialNumber) { + Ok((crlite_timestamp, st)) => { + *valid_before = crlite_timestamp; + *state = st; + NS_OK + } + _ => NS_ERROR_FAILURE, + } + } + + unsafe fn AddCerts( + &self, + certs: *const ThinVec>, + callback: *const nsICertStorageCallback, + ) -> nserror::nsresult { + if !is_main_thread() { + return NS_ERROR_NOT_SAME_THREAD; + } + if certs.is_null() || callback.is_null() { + return NS_ERROR_NULL_POINTER; + } + let certs = &*certs; + let mut cert_entries = Vec::with_capacity(certs.len()); + for cert in certs { + let mut der = nsCString::new(); + try_ns!((*cert).GetCert(&mut *der).to_result(), or continue); + let mut subject = nsCString::new(); + try_ns!((*cert).GetSubject(&mut *subject).to_result(), or continue); + let mut trust: i16 = 0; + try_ns!((*cert).GetTrust(&mut trust).to_result(), or continue); + cert_entries.push((der, subject, trust)); + } + let task = Box::new(try_ns!(SecurityStateTask::new( + &*callback, + &self.security_state, + move |ss| ss.add_certs(&cert_entries), + ))); + let runnable = try_ns!(TaskRunnable::new("AddCerts", task)); + try_ns!(TaskRunnable::dispatch(runnable, self.queue.coerce())); + NS_OK + } + + unsafe fn RemoveCertsByHashes( + &self, + hashes: *const ThinVec, + callback: *const nsICertStorageCallback, + ) -> nserror::nsresult { + if !is_main_thread() { + return NS_ERROR_NOT_SAME_THREAD; + } + if hashes.is_null() || callback.is_null() { + return NS_ERROR_NULL_POINTER; + } + let hashes = (*hashes).to_vec(); + let task = Box::new(try_ns!(SecurityStateTask::new( + &*callback, + &self.security_state, + move |ss| ss.remove_certs_by_hashes(&hashes), + ))); + let runnable = try_ns!(TaskRunnable::new("RemoveCertsByHashes", task)); + try_ns!(TaskRunnable::dispatch(runnable, self.queue.coerce())); + NS_OK + } + + unsafe fn FindCertsBySubject( + &self, + subject: *const ThinVec, + certs: *mut ThinVec>, + ) -> nserror::nsresult { + // TODO (bug 1541212): We really want to restrict this to non-main-threads only, but we + // can't do so until bug 1406854 is fixed. + if subject.is_null() || certs.is_null() { + return NS_ERROR_NULL_POINTER; + } + let ss = get_security_state!(self); + match ss.find_certs_by_subject(&*subject, &mut *certs) { + Ok(()) => NS_OK, + Err(_) => NS_ERROR_FAILURE, + } + } + + unsafe fn Observe( + &self, + subject: *const nsISupports, + topic: *const c_char, + pref_name: *const i16, + ) -> nserror::nsresult { + match CStr::from_ptr(topic).to_str() { + Ok("nsPref:changed") => { + let prefs: RefPtr = match (*subject).query_interface() { + Some(pb) => pb, + _ => return NS_ERROR_FAILURE, + }; + + // Convert our wstring pref_name to a cstring (via nsCString's + // utf16 to utf8 conversion) + let mut len: usize = 0; + while (*(pref_name.offset(len as isize))) != 0 { + len += 1; + } + let name_slice = slice::from_raw_parts(pref_name as *const u16, len); + let mut name_string = nsCString::new(); + name_string.assign_utf16_to_utf8(name_slice); + + let pref_name = match CString::new(name_string.as_str_unchecked()) { + Ok(n) => n, + _ => return NS_ERROR_FAILURE, + }; + + let mut pref_value: i32 = 0; + let res = prefs.GetIntPref((&pref_name).as_ptr(), (&mut pref_value) as *mut i32); + if !res.succeeded() { + return res; + } + let pref_value = if pref_value < 0 { 0 } else { pref_value as u32 }; + + let mut ss = try_ns!(self.security_state.write()); + // This doesn't use the db -> don't need to make sure it's open. + ss.pref_seen(name_string.as_str_unchecked(), pref_value); + } + _ => (), + } + NS_OK + } +} diff --git a/security/manager/ssl/components.conf b/security/manager/ssl/components.conf new file mode 100644 index 0000000000..e76ed7edbd --- /dev/null +++ b/security/manager/ssl/components.conf @@ -0,0 +1,160 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +Headers = [ + '/security/manager/ssl/nsNSSModule.h', +] + +Classes = [ + { + 'cid': '{4cb64dfd-ca98-4e24-befd-0d9285a33bcb}', + 'contract_ids': ['@mozilla.org/psm;1'], + 'type': 'nsNSSComponent', + 'headers': ['nsNSSComponent.h'], + 'init_method': 'Init', + }, + { + 'cid': '{9ef18451-a157-4d17-8132-47afef213689}', + 'contract_ids': ['@mozilla.org/nss_errors_service;1'], + 'type': 'mozilla::psm::NSSErrorsService', + 'headers': ['NSSErrorsService.h'], + 'init_method': 'Init', + }, + { + 'cid': '{23ad3531-11d2-4e8e-805a-6a752e91681a}', + 'contract_ids': ['@mozilla.org/security/nssversion;1'], + 'type': 'nsNSSVersion', + 'headers': ['/security/manager/ssl/nsNSSVersion.h'], + }, + { + 'cid': '{47402be2-e653-45d0-8daa-9f0dce0ac148}', + 'contract_ids': ['@mozilla.org/security/local-cert-service;1'], + 'type': 'mozilla::LocalCertService', + 'headers': ['/security/manager/ssl/LocalCertService.h'], + }, + { + 'cid': '{0c4f1ddc-1dd2-11b2-9d95-f2fdf113044b}', + 'contract_ids': ['@mozilla.org/security/sdr;1'], + 'type': 'SecretDecoderRing', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{b084a2ce-1dd1-11b2-bf10-8324f8e065cc}', + 'contract_ids': ['@mozilla.org/security/pk11tokendb;1'], + 'type': 'nsPK11TokenDB', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{ff9fbcd7-9517-4334-b97a-ceed78909974}', + 'contract_ids': ['@mozilla.org/security/pkcs11moduledb;1'], + 'type': 'mozilla::psm::PKCS11ModuleDB', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{660a3226-915c-4ffb-bb20-8985a632df05}', + 'contract_ids': [], + 'type': 'nsNSSCertificate', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{fb0bbc5c-452e-4783-b32c-80124693d871}', + 'contract_ids': ['@mozilla.org/security/x509certdb;1'], + 'type': 'nsNSSCertificateDB', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{1dbc6eb6-0972-4bdb-9dc4-acd0abf72369}', + 'contract_ids': ['@mozilla.org/security/clientAuthRememberService;1'], + 'type': 'nsClientAuthRememberService', + 'headers': ['nsClientAuthRemember.h'], + 'init_method': 'Init', + }, + { + 'cid': '{36a1d3b3-d886-4317-96ff-87b0005cfef7}', + 'contract_ids': ['@mozilla.org/security/hash;1'], + 'type': 'nsCryptoHash', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{a496d0a2-dff7-4e23-bd65-1ca742fa178a}', + 'contract_ids': ['@mozilla.org/security/hmac;1'], + 'type': 'nsCryptoHMAC', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{9d383ddd-6856-4187-8485-f36195b29a0e}', + 'contract_ids': ['@mozilla.org/security/keyobject;1'], + 'type': 'nsKeyObject', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{2a35dd47-b026-4e8d-b6b7-5740f61ab902}', + 'contract_ids': ['@mozilla.org/security/keyobjectfactory;1'], + 'type': 'nsKeyObjectFactory', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{45a5fe2f-c350-4b86-962d-02d5aaaa955a}', + 'contract_ids': ['@mozilla.org/security/contentsignatureverifier;1'], + 'type': 'ContentSignatureVerifier', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{67ba681d-5485-4fff-952c-2ee337ffdcd6}', + 'contract_ids': ['@mozilla.org/security/certoverride;1'], + 'type': 'nsCertOverrideService', + 'headers': ['/security/manager/ssl/nsCertOverrideService.h'], + 'init_method': 'Init', + }, + { + 'cid': '{be65e2b7-fe46-4e0f-88e0-4b385db4d68a}', + 'contract_ids': ['@mozilla.org/security/random-generator;1'], + 'type': 'nsRandomGenerator', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{16786594-0296-4471-8096-8f84497ca428}', + 'contract_ids': ['@mozilla.org/security/transportsecurityinfo;1'], + 'type': 'mozilla::psm::TransportSecurityInfo', + 'legacy_constructor': + 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{16955eee-6c48-4152-9309-c42a465138a1}', + 'contract_ids': ['@mozilla.org/ssservice;1'], + 'type': 'nsSiteSecurityService', + 'headers': ['/security/manager/ssl/nsSiteSecurityService.h'], + 'init_method': 'Init', + }, + { + 'cid': '{57972956-5718-42d2-8070-b3fc72212eaf}', + 'contract_ids': ['@mozilla.org/security/oskeystore;1'], + 'type': 'OSKeyStore', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{4fe082ae-6ff0-4b41-b24f-eaa664f6e46a}', + 'contract_ids': ['@mozilla.org/security/osreauthenticator;1'], + 'type': 'OSReauthenticator', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + { + 'cid': '{16e5c837-f877-4e23-9c64-eddf905e30e6}', + 'contract_ids': ['@mozilla.org/security/certstorage;1'], + 'headers': ['/security/manager/ssl/cert_storage/src/cert_storage.h'], + 'legacy_constructor': 'cert_storage_constructor', + }, +] + +if defined('MOZ_XUL'): + Classes += [ + { + 'cid': '{4ea60761-31d6-491d-9e34-4b53a26c416c}', + 'contract_ids': ['@mozilla.org/security/nsCertTree;1'], + 'type': 'nsCertTree', + 'legacy_constructor': 'mozilla::psm::NSSConstructor', + }, + ] diff --git a/security/manager/ssl/crashtests/398665-1.html b/security/manager/ssl/crashtests/398665-1.html new file mode 100644 index 0000000000..85afb1137f --- /dev/null +++ b/security/manager/ssl/crashtests/398665-1.html @@ -0,0 +1 @@ + diff --git a/security/manager/ssl/crashtests/crashtests.list b/security/manager/ssl/crashtests/crashtests.list new file mode 100644 index 0000000000..fbc5b85043 --- /dev/null +++ b/security/manager/ssl/crashtests/crashtests.list @@ -0,0 +1 @@ +load 398665-1.html diff --git a/security/manager/ssl/md4.c b/security/manager/ssl/md4.c new file mode 100644 index 0000000000..ed2369f1fa --- /dev/null +++ b/security/manager/ssl/md4.c @@ -0,0 +1,179 @@ +/* vim:set ts=2 sw=2 et cindent: */ +/* 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/. */ + +/* + * "clean room" MD4 implementation (see RFC 1320) + */ + +#include +#include "md4.h" + +/* the "conditional" function */ +#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) + +/* the "majority" function */ +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) + +/* the "parity" function */ +#define H(x, y, z) ((x) ^ (y) ^ (z)) + +/* rotate n-bits to the left */ +#define ROTL(x, n) (((x) << (n)) | ((x) >> (0x20 - n))) + +/* round 1: [abcd k s]: a = (a + F(b,c,d) + X[k]) <<< s */ +#define RD1(a, b, c, d, k, s) \ + a += F(b, c, d) + X[k]; \ + a = ROTL(a, s) + +/* round 2: [abcd k s]: a = (a + G(b,c,d) + X[k] + MAGIC) <<< s */ +#define RD2(a, b, c, d, k, s) \ + a += G(b, c, d) + X[k] + 0x5A827999; \ + a = ROTL(a, s) + +/* round 3: [abcd k s]: a = (a + H(b,c,d) + X[k] + MAGIC) <<< s */ +#define RD3(a, b, c, d, k, s) \ + a += H(b, c, d) + X[k] + 0x6ED9EBA1; \ + a = ROTL(a, s) + +/* converts from word array to byte array, len is number of bytes */ +static void w2b(uint8_t* out, const uint32_t* in, uint32_t len) { + uint8_t* bp; + const uint32_t *wp, *wpend; + + bp = out; + wp = in; + wpend = wp + (len >> 2); + + for (; wp != wpend; ++wp, bp += 4) { + bp[0] = (uint8_t)((*wp) & 0xFF); + bp[1] = (uint8_t)((*wp >> 8) & 0xFF); + bp[2] = (uint8_t)((*wp >> 16) & 0xFF); + bp[3] = (uint8_t)((*wp >> 24) & 0xFF); + } +} + +/* converts from byte array to word array, len is number of bytes */ +static void b2w(uint32_t* out, const uint8_t* in, uint32_t len) { + uint32_t* wp; + const uint8_t *bp, *bpend; + + wp = out; + bp = in; + bpend = in + len; + + for (; bp != bpend; bp += 4, ++wp) { + *wp = (uint32_t)bp[0] | ((uint32_t)bp[1] << 8) | ((uint32_t)bp[2] << 16) | + ((uint32_t)bp[3] << 24); + } +} + +/* update state: data is 64 bytes in length */ +static void md4step(uint32_t state[4], const uint8_t* data) { + uint32_t A, B, C, D, X[16]; + + b2w(X, data, 64); + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + + RD1(A, B, C, D, 0, 3); + RD1(D, A, B, C, 1, 7); + RD1(C, D, A, B, 2, 11); + RD1(B, C, D, A, 3, 19); + RD1(A, B, C, D, 4, 3); + RD1(D, A, B, C, 5, 7); + RD1(C, D, A, B, 6, 11); + RD1(B, C, D, A, 7, 19); + RD1(A, B, C, D, 8, 3); + RD1(D, A, B, C, 9, 7); + RD1(C, D, A, B, 10, 11); + RD1(B, C, D, A, 11, 19); + RD1(A, B, C, D, 12, 3); + RD1(D, A, B, C, 13, 7); + RD1(C, D, A, B, 14, 11); + RD1(B, C, D, A, 15, 19); + + RD2(A, B, C, D, 0, 3); + RD2(D, A, B, C, 4, 5); + RD2(C, D, A, B, 8, 9); + RD2(B, C, D, A, 12, 13); + RD2(A, B, C, D, 1, 3); + RD2(D, A, B, C, 5, 5); + RD2(C, D, A, B, 9, 9); + RD2(B, C, D, A, 13, 13); + RD2(A, B, C, D, 2, 3); + RD2(D, A, B, C, 6, 5); + RD2(C, D, A, B, 10, 9); + RD2(B, C, D, A, 14, 13); + RD2(A, B, C, D, 3, 3); + RD2(D, A, B, C, 7, 5); + RD2(C, D, A, B, 11, 9); + RD2(B, C, D, A, 15, 13); + + RD3(A, B, C, D, 0, 3); + RD3(D, A, B, C, 8, 9); + RD3(C, D, A, B, 4, 11); + RD3(B, C, D, A, 12, 15); + RD3(A, B, C, D, 2, 3); + RD3(D, A, B, C, 10, 9); + RD3(C, D, A, B, 6, 11); + RD3(B, C, D, A, 14, 15); + RD3(A, B, C, D, 1, 3); + RD3(D, A, B, C, 9, 9); + RD3(C, D, A, B, 5, 11); + RD3(B, C, D, A, 13, 15); + RD3(A, B, C, D, 3, 3); + RD3(D, A, B, C, 11, 9); + RD3(C, D, A, B, 7, 11); + RD3(B, C, D, A, 15, 15); + + state[0] += A; + state[1] += B; + state[2] += C; + state[3] += D; +} + +void md4sum(const uint8_t* input, uint32_t inputLen, uint8_t* result) { + uint8_t final[128]; + uint32_t i, n, m, state[4]; + uint64_t inputLenBits; + uint32_t inputLenBitsLow; + uint32_t inputLenBitsHigh; + + /* magic initial states */ + state[0] = 0x67452301; + state[1] = 0xEFCDAB89; + state[2] = 0x98BADCFE; + state[3] = 0x10325476; + + /* compute number of complete 64-byte segments contained in input */ + m = inputLen >> 6; + + /* digest first m segments */ + for (i = 0; i < m; ++i) md4step(state, (input + (i << 6))); + + /* build final buffer */ + n = inputLen % 64; + memcpy(final, input + (m << 6), n); + final[n] = 0x80; + memset(final + n + 1, 0, 120 - (n + 1)); + + /* Append the original input length in bits as a 64-bit number. This is done + * in two 32-bit chunks, with the least-significant 32 bits first. + * w2b will handle endianness. */ + inputLenBits = inputLen << 3; + inputLenBitsLow = (uint32_t)(inputLenBits & 0xFFFFFFFF); + w2b(final + (n >= 56 ? 120 : 56), &inputLenBitsLow, 4); + inputLenBitsHigh = (uint32_t)((inputLenBits >> 32) & 0xFFFFFFFF); + w2b(final + (n >= 56 ? 124 : 60), &inputLenBitsHigh, 4); + + md4step(state, final); + if (n >= 56) md4step(state, final + 64); + + /* copy state to result */ + w2b(result, state, 16); +} diff --git a/security/manager/ssl/md4.h b/security/manager/ssl/md4.h new file mode 100644 index 0000000000..6e56a4ffdc --- /dev/null +++ b/security/manager/ssl/md4.h @@ -0,0 +1,38 @@ +/* vim:set ts=2 sw=2 et cindent: */ +/* 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/. */ + +#ifndef md4_h__ +#define md4_h__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * md4sum - computes the MD4 sum over the input buffer per RFC 1320 + * + * @param input + * buffer containing input data + * @param inputLen + * length of input buffer (number of bytes) + * @param result + * 16-byte buffer that will contain the MD4 sum upon return + * + * NOTE: MD4 is superceded by MD5. do not use MD4 unless required by the + * protocol you are implementing (e.g., NTLM requires MD4). + * + * NOTE: this interface is designed for relatively small buffers. A streaming + * interface would make more sense if that were a requirement. Currently, this + * is good enough for the applications we care about. + */ +void md4sum(const uint8_t* input, uint32_t inputLen, uint8_t* result); + +#ifdef __cplusplus +} +#endif + +#endif /* md4_h__ */ diff --git a/security/manager/ssl/moz.build b/security/manager/ssl/moz.build new file mode 100644 index 0000000000..76be81582d --- /dev/null +++ b/security/manager/ssl/moz.build @@ -0,0 +1,246 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# osclientcerts is currently only implemented for Windows +# osclientcerts transitively depends on winapi 0.2.8, which doesn't work with +# AArch64 +if (CONFIG["OS_ARCH"] == "WINNT" and CONFIG["CPU_ARCH"] != "aarch64") or CONFIG[ + "OS_ARCH" +] == "Darwin": + DIRS += ["osclientcerts"] + +TEST_DIRS += ["tests"] + +XPIDL_SOURCES += [ + "nsICertificateDialogs.idl", + "nsICertOverrideService.idl", + "nsICertStorage.idl", + "nsIClientAuthDialogs.idl", + "nsIClientAuthRememberService.idl", + "nsIContentSignatureVerifier.idl", + "nsICryptoHash.idl", + "nsICryptoHMAC.idl", + "nsIKeyModule.idl", + "nsILocalCertService.idl", + "nsINSSComponent.idl", + "nsINSSErrorsService.idl", + "nsINSSVersion.idl", + "nsIOSKeyStore.idl", + "nsIOSReauthenticator.idl", + "nsIPK11Token.idl", + "nsIPK11TokenDB.idl", + "nsIPKCS11Module.idl", + "nsIPKCS11ModuleDB.idl", + "nsIPKCS11Slot.idl", + "nsIProtectedAuthThread.idl", + "nsISecretDecoderRing.idl", + "nsISecurityUITelemetry.idl", + "nsISiteSecurityService.idl", + "nsITokenDialogs.idl", + "nsITokenPasswordDialogs.idl", + "nsIX509Cert.idl", + "nsIX509CertDB.idl", + "nsIX509CertValidity.idl", +] + +if CONFIG["MOZ_XUL"]: + XPIDL_SOURCES += [ + "nsICertTree.idl", + ] + +XPIDL_MODULE = "pipnss" + +XPCOM_MANIFESTS += [ + "components.conf", +] + +EXTRA_JS_MODULES.psm += [ + "DER.jsm", + "RemoteSecuritySettings.jsm", + "X509.jsm", +] + +EXPORTS += [ + "CommonSocketControl.h", + "CryptoTask.h", + "EnterpriseRoots.h", + "nsClientAuthRemember.h", + "nsNSSCallbacks.h", + "nsNSSCertificate.h", + "nsNSSComponent.h", + "nsNSSHelper.h", + "nsRandomGenerator.h", + "nsSecureBrowserUI.h", + "nsSecurityHeaderParser.h", + "NSSErrorsService.h", + "nsSSLSocketProvider.h", + "nsTLSSocketProvider.h", + "RootCertificateTelemetryUtils.h", + "ScopedNSSTypes.h", + "SharedCertVerifier.h", + "SSLServerCertVerification.h", + "TransportSecurityInfo.h", +] + +EXPORTS.mozilla += [ + "DataStorage.h", + "DataStorageList.h", + "PublicSSL.h", +] + +EXPORTS.mozilla.psm += [ + "PSMIPCCommon.h", + "TransportSecurityInfo.h", + "VerifySSLServerCertChild.h", + "VerifySSLServerCertParent.h", +] + +EXPORTS.ipc += [ + "DataStorageIPCUtils.h", +] + +UNIFIED_SOURCES += [ + "CommonSocketControl.cpp", + "ContentSignatureVerifier.cpp", + "CryptoTask.cpp", + "CSTrustDomain.cpp", + "DataStorage.cpp", + "EnterpriseRoots.cpp", + "LocalCertService.cpp", + "nsCertOverrideService.cpp", + "nsClientAuthRemember.cpp", + "nsCryptoHash.cpp", + "nsKeyModule.cpp", + "nsNSSCallbacks.cpp", + "nsNSSCertHelper.cpp", + "nsNSSCertificate.cpp", + "nsNSSCertificateDB.cpp", + "nsNSSCertTrust.cpp", + "nsNSSComponent.cpp", + "nsNSSIOLayer.cpp", + "nsNSSModule.cpp", + "nsNSSVersion.cpp", + "nsNTLMAuthModule.cpp", + "nsPK11TokenDB.cpp", + "nsPKCS11Slot.cpp", + "nsPKCS12Blob.cpp", + "nsProtectedAuthThread.cpp", + "nsRandomGenerator.cpp", + "nsSecureBrowserUI.cpp", + "nsSecurityHeaderParser.cpp", + "NSSErrorsService.cpp", + "nsSiteSecurityService.cpp", + "NSSKeyStore.cpp", + "nsSSLSocketProvider.cpp", + "nsTLSSocketProvider.cpp", + "OSKeyStore.cpp", + "PKCS11ModuleDB.cpp", + "PSMIPCCommon.cpp", + "PSMRunnable.cpp", + "PublicKeyPinningService.cpp", + "RootCertificateTelemetryUtils.cpp", + "SecretDecoderRing.cpp", + "SharedSSLState.cpp", + "SSLServerCertVerification.cpp", + "TransportSecurityInfo.cpp", + "VerifySSLServerCertChild.cpp", + "VerifySSLServerCertParent.cpp", + "X509CertValidity.cpp", +] + +if CONFIG["OS_ARCH"] == "WINNT": + # On Windows this file includes ntsecapi.h, which contains definitions that + # conflict with headers included in remaining source files. We compile this + # one independently to prevent that interferance. + SOURCES += [ + "OSReauthenticator.cpp", + ] +else: + UNIFIED_SOURCES += [ + "OSReauthenticator.cpp", + ] + +if CONFIG["MOZ_WIDGET_TOOLKIT"] == "gtk": + UNIFIED_SOURCES += [ + "LibSecret.cpp", + ] + CFLAGS += CONFIG["GLIB_CFLAGS"] + CXXFLAGS += CONFIG["GLIB_CFLAGS"] + +if CONFIG["OS_ARCH"] == "Darwin": + UNIFIED_SOURCES += [ + "KeychainSecret.cpp", + "OSReauthenticatorDarwin.mm", + ] + OS_LIBS += [ + "-framework LocalAuthentication", + "-framework Security", + ] + +if CONFIG["OS_ARCH"] == "WINNT": + OS_LIBS += ["credui"] + UNIFIED_SOURCES += [ + "CredentialManagerSecret.cpp", + ] + +IPDL_SOURCES += [ + "PSMIPCTypes.ipdlh", + "PVerifySSLServerCert.ipdl", +] + +if CONFIG["MOZ_XUL"]: + UNIFIED_SOURCES += [ + "nsCertTree.cpp", + ] + +UNIFIED_SOURCES += [ + "md4.c", +] + +FINAL_LIBRARY = "xul" + +LOCAL_INCLUDES += [ + "/dom/base", + "/dom/crypto", + "/netwerk/base", + "/security/certverifier", +] + +LOCAL_INCLUDES += [ + "!/dist/public/nss", +] + +GeneratedFile( + "nsSTSPreloadListGenerated.inc", + script="../../../xpcom/ds/tools/make_dafsa.py", + inputs=["nsSTSPreloadList.inc"], +) + +DEFINES["SSL_DISABLE_DEPRECATED_CIPHER_SUITE_NAMES"] = "True" +DEFINES["NSS_ENABLE_ECC"] = "True" + +if not CONFIG["MOZ_SYSTEM_NSS"]: + USE_LIBS += [ + "crmf", + ] + +# mozpkix is linked statically from the in-tree sources independent of whether +# system NSS is used or not. +USE_LIBS += ["mozpkix"] + +include("/ipc/chromium/chromium-config.mozbuild") + +if CONFIG["CC_TYPE"] in ("clang", "gcc"): + CXXFLAGS += [ + "-Wextra", + # -Wextra enables this warning, but it's too noisy to be useful. + "-Wno-missing-field-initializers", + ] + + # Gecko headers aren't warning-free enough for us to enable these warnings. + CXXFLAGS += [ + "-Wno-unused-parameter", + ] diff --git a/security/manager/ssl/nsCertOverrideService.cpp b/security/manager/ssl/nsCertOverrideService.cpp new file mode 100644 index 0000000000..04fdc8b475 --- /dev/null +++ b/security/manager/ssl/nsCertOverrideService.cpp @@ -0,0 +1,806 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "nsCertOverrideService.h" + +#include "NSSCertDBTrustDomain.h" +#include "ScopedNSSTypes.h" +#include "SharedSSLState.h" +#include "mozilla/Assertions.h" +#include "mozilla/ScopeExit.h" +#include "mozilla/TaskQueue.h" +#include "mozilla/Telemetry.h" +#include "mozilla/TextUtils.h" +#include "mozilla/Unused.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsCRT.h" +#include "nsILineInputStream.h" +#include "nsIMarionette.h" +#include "nsIObserver.h" +#include "nsIObserverService.h" +#include "nsIOutputStream.h" +#ifdef ENABLE_REMOTE_AGENT +# include "nsIRemoteAgent.h" +#endif +#include "nsISafeOutputStream.h" +#include "nsIX509Cert.h" +#include "nsNSSCertHelper.h" +#include "nsNSSCertificate.h" +#include "nsNSSComponent.h" +#include "nsNetUtil.h" +#include "nsStreamUtils.h" +#include "nsStringBuffer.h" +#include "nsThreadUtils.h" + +using namespace mozilla; +using namespace mozilla::psm; + +#define CERT_OVERRIDE_FILE_NAME "cert_override.txt" + +class WriterRunnable : public Runnable { + public: + WriterRunnable(nsCertOverrideService* aService, nsCString& aData, + nsCOMPtr aFile) + : Runnable("nsCertOverrideService::WriterRunnable"), + mCertOverrideService(aService), + mData(aData), + mFile(std::move(aFile)) {} + + NS_IMETHOD + Run() override { + mCertOverrideService->AssertOnTaskQueue(); + nsresult rv; + + auto removeShutdownBlockerOnExit = + MakeScopeExit([certOverrideService = mCertOverrideService]() { + NS_DispatchToMainThread(NS_NewRunnableFunction( + "nsCertOverrideService::RemoveShutdownBlocker", + [certOverrideService] { + certOverrideService->RemoveShutdownBlocker(); + })); + }); + + nsCOMPtr outputStream; + rv = NS_NewSafeLocalFileOutputStream( + getter_AddRefs(outputStream), mFile, + PR_CREATE_FILE | PR_TRUNCATE | PR_WRONLY); + NS_ENSURE_SUCCESS(rv, rv); + + const char* ptr = mData.get(); + uint32_t remaining = mData.Length(); + uint32_t written = 0; + while (remaining > 0) { + rv = outputStream->Write(ptr, remaining, &written); + NS_ENSURE_SUCCESS(rv, rv); + remaining -= written; + ptr += written; + } + + nsCOMPtr safeStream = do_QueryInterface(outputStream); + MOZ_ASSERT(safeStream); + rv = safeStream->Finish(); + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; + } + + private: + const RefPtr mCertOverrideService; + nsCString mData; + const nsCOMPtr mFile; +}; + +NS_IMPL_ISUPPORTS(nsCertOverride, nsICertOverride) + +NS_IMETHODIMP +nsCertOverride::GetAsciiHost(/*out*/ nsACString& aAsciiHost) { + aAsciiHost = mAsciiHost; + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverride::GetDbKey(/*out*/ nsACString& aDBKey) { + aDBKey = mDBKey; + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverride::GetPort(/*out*/ int32_t* aPort) { + *aPort = mPort; + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverride::GetIsTemporary(/*out*/ bool* aIsTemporary) { + *aIsTemporary = mIsTemporary; + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverride::GetHostPort(/*out*/ nsACString& aHostPort) { + nsCertOverrideService::GetHostWithPort(mAsciiHost, mPort, aHostPort); + return NS_OK; +} + +void nsCertOverride::convertBitsToString(OverrideBits ob, + /*out*/ nsACString& str) { + str.Truncate(); + + if (ob & OverrideBits::Mismatch) { + str.Append('M'); + } + + if (ob & OverrideBits::Untrusted) { + str.Append('U'); + } + + if (ob & OverrideBits::Time) { + str.Append('T'); + } +} + +void nsCertOverride::convertStringToBits(const nsACString& str, + /*out*/ OverrideBits& ob) { + ob = OverrideBits::None; + + for (uint32_t i = 0; i < str.Length(); i++) { + switch (str.CharAt(i)) { + case 'm': + case 'M': + ob |= OverrideBits::Mismatch; + break; + + case 'u': + case 'U': + ob |= OverrideBits::Untrusted; + break; + + case 't': + case 'T': + ob |= OverrideBits::Time; + break; + + default: + break; + } + } +} + +NS_IMPL_ISUPPORTS(nsCertOverrideService, nsICertOverrideService, nsIObserver, + nsISupportsWeakReference, nsIAsyncShutdownBlocker) + +nsCertOverrideService::nsCertOverrideService() + : mMutex("nsCertOverrideService.mutex"), + mDisableAllSecurityCheck(false), + mPendingWriteCount(0) { + nsCOMPtr target = + do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID); + MOZ_ASSERT(target); + + mWriterTaskQueue = new TaskQueue(target.forget()); +} + +nsCertOverrideService::~nsCertOverrideService() = default; + +static nsCOMPtr GetShutdownBarrier() { + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr svc = + mozilla::services::GetAsyncShutdownService(); + MOZ_RELEASE_ASSERT(svc); + + nsCOMPtr barrier; + nsresult rv = svc->GetProfileBeforeChange(getter_AddRefs(barrier)); + + MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); + MOZ_RELEASE_ASSERT(barrier); + return barrier; +} + +nsresult nsCertOverrideService::Init() { + if (!NS_IsMainThread()) { + MOZ_ASSERT_UNREACHABLE("nsCertOverrideService initialized off main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + + // If we cannot add ourselves as a profile change observer, then we will not + // attempt to read/write any settings file. Otherwise, we would end up + // reading/writing the wrong settings file after a profile change. + if (observerService) { + observerService->AddObserver(this, "profile-before-change", true); + observerService->AddObserver(this, "profile-do-change", true); + // simulate a profile change so we read the current profile's settings file + Observe(nullptr, "profile-do-change", nullptr); + } + + SharedSSLState::NoteCertOverrideServiceInstantiated(); + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverrideService::Observe(nsISupports*, const char* aTopic, + const char16_t* aData) { + // check the topic + if (!nsCRT::strcmp(aTopic, "profile-before-change")) { + // The profile is about to change, + // or is going away because the application is shutting down. + + RemoveAllFromMemory(); + } else if (!nsCRT::strcmp(aTopic, "profile-do-change")) { + // The profile has already changed. + // Now read from the new profile location. + // we also need to update the cached file location + + MutexAutoLock lock(mMutex); + + nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, + getter_AddRefs(mSettingsFile)); + if (NS_SUCCEEDED(rv)) { + mSettingsFile->AppendNative(nsLiteralCString(CERT_OVERRIDE_FILE_NAME)); + } else { + mSettingsFile = nullptr; + } + Read(lock); + CountPermanentOverrideTelemetry(lock); + } + + return NS_OK; +} + +void nsCertOverrideService::RemoveAllFromMemory() { + MutexAutoLock lock(mMutex); + mSettingsTable.Clear(); +} + +void nsCertOverrideService::RemoveAllTemporaryOverrides() { + MutexAutoLock lock(mMutex); + for (auto iter = mSettingsTable.Iter(); !iter.Done(); iter.Next()) { + nsCertOverrideEntry* entry = iter.Get(); + if (entry->mSettings->mIsTemporary) { + entry->mSettings->mCert = nullptr; + iter.Remove(); + } + } + // no need to write, as temporaries are never written to disk +} + +nsresult nsCertOverrideService::Read(const MutexAutoLock& aProofOfLock) { + // If we don't have a profile, then we won't try to read any settings file. + if (!mSettingsFile) return NS_OK; + + nsresult rv; + nsCOMPtr fileInputStream; + rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), + mSettingsFile); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr lineInputStream = + do_QueryInterface(fileInputStream, &rv); + if (NS_FAILED(rv)) { + return rv; + } + + nsAutoCString buffer; + bool isMore = true; + int32_t hostIndex = 0, algoIndex, fingerprintIndex, overrideBitsIndex, + dbKeyIndex; + + /* file format is: + * + * host:port \t fingerprint-algorithm \t fingerprint \t override-mask \t dbKey + * + * where override-mask is a sequence of characters, + * M meaning hostname-Mismatch-override + * U meaning Untrusted-override + * T meaning Time-error-override (expired/not yet valid) + * + * if this format isn't respected we move onto the next line in the file. + */ + + while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore))) { + if (buffer.IsEmpty() || buffer.First() == '#') { + continue; + } + + // this is a cheap, cheesy way of parsing a tab-delimited line into + // string indexes, which can be lopped off into substrings. just for + // purposes of obfuscation, it also checks that each token was found. + // todo: use iterators? + if ((algoIndex = buffer.FindChar('\t', hostIndex) + 1) == 0 || + (fingerprintIndex = buffer.FindChar('\t', algoIndex) + 1) == 0 || + (overrideBitsIndex = buffer.FindChar('\t', fingerprintIndex) + 1) == + 0 || + (dbKeyIndex = buffer.FindChar('\t', overrideBitsIndex) + 1) == 0) { + continue; + } + + const nsACString& tmp = + Substring(buffer, hostIndex, algoIndex - hostIndex - 1); + // We just ignore the algorithm string. + const nsACString& fingerprint = Substring( + buffer, fingerprintIndex, overrideBitsIndex - fingerprintIndex - 1); + const nsACString& bits_string = Substring( + buffer, overrideBitsIndex, dbKeyIndex - overrideBitsIndex - 1); + const nsACString& db_key = + Substring(buffer, dbKeyIndex, buffer.Length() - dbKeyIndex); + + nsAutoCString host(tmp); + nsCertOverride::OverrideBits bits; + nsCertOverride::convertStringToBits(bits_string, bits); + + int32_t port; + int32_t portIndex = host.RFindChar(':'); + if (portIndex == kNotFound) continue; // Ignore broken entries + + nsresult portParseError; + nsAutoCString portString(Substring(host, portIndex + 1)); + port = portString.ToInteger(&portParseError); + if (NS_FAILED(portParseError)) continue; // Ignore broken entries + + host.Truncate(portIndex); + + AddEntryToList(host, port, + nullptr, // don't have the cert + false, // not temporary + fingerprint, bits, db_key, aProofOfLock); + } + + return NS_OK; +} + +static const char sSHA256OIDString[] = "OID.2.16.840.1.101.3.4.2.1"; +nsresult nsCertOverrideService::Write(const MutexAutoLock& aProofOfLock) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + // If we don't have any profile, then we won't try to write any file + if (!mSettingsFile) { + return NS_OK; + } + + nsCString output; + + static const char kHeader[] = + "# PSM Certificate Override Settings file" NS_LINEBREAK + "# This is a generated file! Do not edit." NS_LINEBREAK; + + /* see ::Read for file format */ + + output.Append(kHeader); + + static const char kTab[] = "\t"; + for (auto iter = mSettingsTable.Iter(); !iter.Done(); iter.Next()) { + nsCertOverrideEntry* entry = iter.Get(); + + RefPtr settings = entry->mSettings; + if (settings->mIsTemporary) { + continue; + } + + nsAutoCString bits_string; + nsCertOverride::convertBitsToString(settings->mOverrideBits, bits_string); + + output.Append(entry->mHostWithPort); + output.Append(kTab); + output.Append(sSHA256OIDString); + output.Append(kTab); + output.Append(settings->mFingerprint); + output.Append(kTab); + output.Append(bits_string); + output.Append(kTab); + output.Append(settings->mDBKey); + output.Append(NS_LINEBREAK); + } + + // Make a clone of the file to pass to the WriterRunnable. + nsCOMPtr file; + nsresult rv; + rv = mSettingsFile->Clone(getter_AddRefs(file)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr runnable = new WriterRunnable(this, output, file); + rv = mWriterTaskQueue->Dispatch(runnable.forget()); + if (NS_FAILED(rv)) { + return rv; + } + mPendingWriteCount++; + + if (mPendingWriteCount == 1) { + rv = GetShutdownBarrier()->AddBlocker( + this, NS_LITERAL_STRING_FROM_CSTRING(__FILE__), __LINE__, + u"nsCertOverrideService writing data"_ns); + NS_ENSURE_SUCCESS(rv, rv); + } + + return NS_OK; +} + +static nsresult GetCertSha256Fingerprint(nsIX509Cert* aCert, + nsCString& aResult) { + nsAutoString fpStrUTF16; + nsresult rv = aCert->GetSha256Fingerprint(fpStrUTF16); + if (NS_FAILED(rv)) { + return rv; + } + aResult.Assign(NS_ConvertUTF16toUTF8(fpStrUTF16)); + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverrideService::RememberValidityOverride(const nsACString& aHostName, + int32_t aPort, + nsIX509Cert* aCert, + uint32_t aOverrideBits, + bool aTemporary) { + NS_ENSURE_ARG_POINTER(aCert); + if (aHostName.IsEmpty() || !IsAscii(aHostName)) { + return NS_ERROR_INVALID_ARG; + } + if (aPort < -1) { + return NS_ERROR_INVALID_ARG; + } + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + UniqueCERTCertificate nsscert(aCert->GetCert()); + if (!nsscert) { + return NS_ERROR_FAILURE; + } + + nsAutoCString nickname; + nsresult rv = DefaultServerNicknameForCert(nsscert.get(), nickname); + if (!aTemporary && NS_SUCCEEDED(rv)) { + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return NS_ERROR_FAILURE; + } + + // This can fail (for example, if we're in read-only mode). Luckily, we + // don't even need it to succeed - we always match on the stored hash of the + // certificate rather than the full certificate. It makes the display a bit + // less informative (since we won't have a certificate to display), but it's + // better than failing the entire operation. + Unused << PK11_ImportCert(slot.get(), nsscert.get(), CK_INVALID_HANDLE, + nickname.get(), false); + } + + nsAutoCString fpStr; + rv = GetCertSha256Fingerprint(aCert, fpStr); + if (NS_FAILED(rv)) { + return rv; + } + + nsAutoCString dbkey; + rv = aCert->GetDbKey(dbkey); + if (NS_FAILED(rv)) { + return rv; + } + + { + MutexAutoLock lock(mMutex); + AddEntryToList(aHostName, aPort, aTemporary ? aCert : nullptr, + // keep a reference to the cert for temporary overrides + aTemporary, fpStr, + (nsCertOverride::OverrideBits)aOverrideBits, dbkey, lock); + if (!aTemporary) { + Write(lock); + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverrideService::RememberTemporaryValidityOverrideUsingFingerprint( + const nsACString& aHostName, int32_t aPort, + const nsACString& aCertFingerprint, uint32_t aOverrideBits) { + if (aCertFingerprint.IsEmpty() || aHostName.IsEmpty() || + !IsAscii(aCertFingerprint) || !IsAscii(aHostName) || (aPort < -1)) { + return NS_ERROR_INVALID_ARG; + } + + MutexAutoLock lock(mMutex); + AddEntryToList(aHostName, aPort, + nullptr, // No cert to keep alive + true, // temporary + aCertFingerprint, (nsCertOverride::OverrideBits)aOverrideBits, + ""_ns, // dbkey + lock); + + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverrideService::HasMatchingOverride(const nsACString& aHostName, + int32_t aPort, nsIX509Cert* aCert, + uint32_t* aOverrideBits, + bool* aIsTemporary, bool* _retval) { + bool disableAllSecurityCheck = false; + { + MutexAutoLock lock(mMutex); + disableAllSecurityCheck = mDisableAllSecurityCheck; + } + if (disableAllSecurityCheck) { + nsCertOverride::OverrideBits all = nsCertOverride::OverrideBits::Untrusted | + nsCertOverride::OverrideBits::Mismatch | + nsCertOverride::OverrideBits::Time; + *aOverrideBits = static_cast(all); + *aIsTemporary = false; + *_retval = true; + return NS_OK; + } + + if (aHostName.IsEmpty() || !IsAscii(aHostName)) { + return NS_ERROR_INVALID_ARG; + } + if (aPort < -1) return NS_ERROR_INVALID_ARG; + + NS_ENSURE_ARG_POINTER(aCert); + NS_ENSURE_ARG_POINTER(aOverrideBits); + NS_ENSURE_ARG_POINTER(aIsTemporary); + NS_ENSURE_ARG_POINTER(_retval); + *_retval = false; + *aOverrideBits = static_cast(nsCertOverride::OverrideBits::None); + + nsAutoCString hostPort; + GetHostWithPort(aHostName, aPort, hostPort); + RefPtr settings; + + { + MutexAutoLock lock(mMutex); + nsCertOverrideEntry* entry = mSettingsTable.GetEntry(hostPort.get()); + + if (!entry) return NS_OK; + + settings = entry->mSettings; + } + + *aOverrideBits = static_cast(settings->mOverrideBits); + *aIsTemporary = settings->mIsTemporary; + + nsAutoCString fpStr; + nsresult rv = GetCertSha256Fingerprint(aCert, fpStr); + if (NS_FAILED(rv)) { + return rv; + } + + *_retval = settings->mFingerprint.Equals(fpStr); + return NS_OK; +} + +nsresult nsCertOverrideService::AddEntryToList( + const nsACString& aHostName, int32_t aPort, nsIX509Cert* aCert, + const bool aIsTemporary, const nsACString& fingerprint, + nsCertOverride::OverrideBits ob, const nsACString& dbKey, + const MutexAutoLock& aProofOfLock) { + nsAutoCString hostPort; + GetHostWithPort(aHostName, aPort, hostPort); + + nsCertOverrideEntry* entry = mSettingsTable.PutEntry(hostPort.get()); + + if (!entry) { + NS_ERROR("can't insert a null entry!"); + return NS_ERROR_OUT_OF_MEMORY; + } + + entry->mHostWithPort = hostPort; + + RefPtr settings(new nsCertOverride()); + + settings->mAsciiHost = aHostName; + settings->mPort = aPort; + settings->mIsTemporary = aIsTemporary; + settings->mFingerprint = fingerprint; + settings->mOverrideBits = ob; + settings->mDBKey = dbKey; + // remove whitespace from stored dbKey for backwards compatibility + settings->mDBKey.StripWhitespace(); + settings->mCert = aCert; + entry->mSettings = settings; + + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverrideService::ClearValidityOverride(const nsACString& aHostName, + int32_t aPort) { + if (aHostName.IsEmpty() || !IsAscii(aHostName)) { + return NS_ERROR_INVALID_ARG; + } + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + if (aPort == 0 && aHostName.EqualsLiteral("all:temporary-certificates")) { + RemoveAllTemporaryOverrides(); + return NS_OK; + } + nsAutoCString hostPort; + GetHostWithPort(aHostName, aPort, hostPort); + { + MutexAutoLock lock(mMutex); + mSettingsTable.RemoveEntry(hostPort.get()); + Write(lock); + } + + nsCOMPtr nss(do_GetService(PSM_COMPONENT_CONTRACTID)); + if (nss) { + nss->ClearSSLExternalAndInternalSessionCache(); + } else { + return NS_ERROR_NOT_AVAILABLE; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverrideService::ClearAllOverrides() { + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + { + MutexAutoLock lock(mMutex); + mSettingsTable.Clear(); + Write(lock); + } + + nsCOMPtr nss(do_GetService(PSM_COMPONENT_CONTRACTID)); + if (nss) { + nss->ClearSSLExternalAndInternalSessionCache(); + } else { + return NS_ERROR_NOT_AVAILABLE; + } + + return NS_OK; +} + +void nsCertOverrideService::CountPermanentOverrideTelemetry( + const MutexAutoLock& aProofOfLock) { + uint32_t overrideCount = 0; + for (auto iter = mSettingsTable.Iter(); !iter.Done(); iter.Next()) { + if (!iter.Get()->mSettings->mIsTemporary) { + overrideCount++; + } + } + Telemetry::Accumulate(Telemetry::SSL_PERMANENT_CERT_ERROR_OVERRIDES, + overrideCount); +} + +static bool matchesDBKey(nsIX509Cert* cert, const nsCString& matchDbKey) { + nsAutoCString dbKey; + nsresult rv = cert->GetDbKey(dbKey); + if (NS_FAILED(rv)) { + return false; + } + return dbKey.Equals(matchDbKey); +} + +NS_IMETHODIMP +nsCertOverrideService::IsCertUsedForOverrides(nsIX509Cert* aCert, + bool aCheckTemporaries, + bool aCheckPermanents, + uint32_t* _retval) { + NS_ENSURE_ARG(aCert); + NS_ENSURE_ARG(_retval); + + uint32_t counter = 0; + { + MutexAutoLock lock(mMutex); + for (auto iter = mSettingsTable.Iter(); !iter.Done(); iter.Next()) { + RefPtr settings = iter.Get()->mSettings; + + if ((settings->mIsTemporary && !aCheckTemporaries) || + (!settings->mIsTemporary && !aCheckPermanents)) { + continue; + } + + if (matchesDBKey(aCert, settings->mDBKey)) { + nsAutoCString certFingerprint; + nsresult rv = GetCertSha256Fingerprint(aCert, certFingerprint); + if (NS_SUCCEEDED(rv) && + settings->mFingerprint.Equals(certFingerprint)) { + counter++; + } + } + } + } + *_retval = counter; + return NS_OK; +} + +static bool IsDebugger() { + bool marionetteRunning = false; + bool remoteAgentListening = false; + + nsCOMPtr marionette = do_GetService(NS_MARIONETTE_CONTRACTID); + if (marionette) { + marionette->GetRunning(&marionetteRunning); + } + +#ifdef ENABLE_REMOTE_AGENT + nsCOMPtr agent = do_GetService(NS_REMOTEAGENT_CONTRACTID); + if (agent) { + agent->GetListening(&remoteAgentListening); + } +#endif + + return marionetteRunning || remoteAgentListening; +} + +NS_IMETHODIMP +nsCertOverrideService:: + SetDisableAllSecurityChecksAndLetAttackersInterceptMyData(bool aDisable) { + if (!(PR_GetEnv("XPCSHELL_TEST_PROFILE_DIR") || IsDebugger())) { + return NS_ERROR_NOT_AVAILABLE; + } + + MutexAutoLock lock(mMutex); + mDisableAllSecurityCheck = aDisable; + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverrideService::GetOverrides( + /*out*/ nsTArray>& retval) { + MutexAutoLock lock(mMutex); + for (auto iter = mSettingsTable.Iter(); !iter.Done(); iter.Next()) { + const RefPtr settings = iter.Get()->mSettings; + + retval.AppendElement(settings); + } + return NS_OK; +} + +void nsCertOverrideService::GetHostWithPort(const nsACString& aHostName, + int32_t aPort, + nsACString& _retval) { + nsAutoCString hostPort(aHostName); + if (aPort == -1) { + aPort = 443; + } + if (!hostPort.IsEmpty()) { + hostPort.Append(':'); + hostPort.AppendInt(aPort); + } + _retval.Assign(hostPort); +} + +// nsIAsyncShutdownBlocker implementation +NS_IMETHODIMP +nsCertOverrideService::GetName(nsAString& aName) { + aName = u"nsCertOverrideService: shutdown"_ns; + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverrideService::GetState(nsIPropertyBag** aState) { + if (!aState) { + return NS_ERROR_INVALID_ARG; + } + *aState = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsCertOverrideService::BlockShutdown(nsIAsyncShutdownClient*) { return NS_OK; } + +void nsCertOverrideService::RemoveShutdownBlocker() { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(mPendingWriteCount > 0); + mPendingWriteCount--; + if (mPendingWriteCount == 0) { + nsresult rv = GetShutdownBarrier()->RemoveBlocker(this); + MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv)); + } +} diff --git a/security/manager/ssl/nsCertOverrideService.h b/security/manager/ssl/nsCertOverrideService.h new file mode 100644 index 0000000000..ba995b75e6 --- /dev/null +++ b/security/manager/ssl/nsCertOverrideService.h @@ -0,0 +1,160 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef nsCertOverrideService_h +#define nsCertOverrideService_h + +#include + +#include "mozilla/HashFunctions.h" +#include "mozilla/Mutex.h" +#include "mozilla/TaskQueue.h" +#include "mozilla/TypedEnumBits.h" +#include "nsIAsyncShutdown.h" +#include "nsICertOverrideService.h" +#include "nsIFile.h" +#include "nsIObserver.h" +#include "nsString.h" +#include "nsTHashtable.h" +#include "nsWeakReference.h" +#include "secoidt.h" + +class nsCertOverride final : public nsICertOverride { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSICERTOVERRIDE + + enum class OverrideBits { + None = 0, + Untrusted = nsICertOverrideService::ERROR_UNTRUSTED, + Mismatch = nsICertOverrideService::ERROR_MISMATCH, + Time = nsICertOverrideService::ERROR_TIME, + }; + + nsCertOverride() + : mPort(-1), mIsTemporary(false), mOverrideBits(OverrideBits::None) {} + + nsCString mAsciiHost; + int32_t mPort; + bool mIsTemporary; // true: session only, false: stored on disk + nsCString mFingerprint; + OverrideBits mOverrideBits; + nsCString mDBKey; + nsCOMPtr mCert; + + static void convertBitsToString(OverrideBits ob, nsACString& str); + static void convertStringToBits(const nsACString& str, OverrideBits& ob); + + private: + ~nsCertOverride() = default; +}; + +MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsCertOverride::OverrideBits) + +// hash entry class +class nsCertOverrideEntry final : public PLDHashEntryHdr { + public: + // Hash methods + typedef const char* KeyType; + typedef const char* KeyTypePointer; + + // do nothing with aHost - we require mHead to be set before we're live! + explicit nsCertOverrideEntry(KeyTypePointer aHostWithPortUTF8) {} + + nsCertOverrideEntry(nsCertOverrideEntry&& toMove) + : PLDHashEntryHdr(std::move(toMove)), + mSettings(std::move(toMove.mSettings)), + mHostWithPort(std::move(toMove.mHostWithPort)) {} + + ~nsCertOverrideEntry() = default; + + KeyType GetKey() const { return HostWithPortPtr(); } + + KeyTypePointer GetKeyPointer() const { return HostWithPortPtr(); } + + bool KeyEquals(KeyTypePointer aKey) const { + return !strcmp(HostWithPortPtr(), aKey); + } + + static KeyTypePointer KeyToPointer(KeyType aKey) { return aKey; } + + static PLDHashNumber HashKey(KeyTypePointer aKey) { + return mozilla::HashString(aKey); + } + + enum { ALLOW_MEMMOVE = false }; + + // get methods + inline const nsCString& HostWithPort() const { return mHostWithPort; } + + inline KeyTypePointer HostWithPortPtr() const { return mHostWithPort.get(); } + + RefPtr mSettings; + nsCString mHostWithPort; +}; + +class nsCertOverrideService final : public nsICertOverrideService, + public nsIObserver, + public nsSupportsWeakReference, + public nsIAsyncShutdownBlocker { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSICERTOVERRIDESERVICE + NS_DECL_NSIOBSERVER + NS_DECL_NSIASYNCSHUTDOWNBLOCKER + + nsCertOverrideService(); + + nsresult Init(); + void RemoveAllTemporaryOverrides(); + + // Concates host name and the port number. If the port number is -1 then + // port 443 is automatically used. This method ensures there is always a port + // number separated with colon. + static void GetHostWithPort(const nsACString& aHostName, int32_t aPort, + nsACString& _retval); + + void AssertOnTaskQueue() const { + MOZ_ASSERT(mWriterTaskQueue->IsOnCurrentThread()); + } + + void RemoveShutdownBlocker(); + + private: + ~nsCertOverrideService(); + + mozilla::Mutex mMutex; + bool mDisableAllSecurityCheck; + nsCOMPtr mSettingsFile; + nsTHashtable mSettingsTable; + + void CountPermanentOverrideTelemetry( + const mozilla::MutexAutoLock& aProofOfLock); + + void RemoveAllFromMemory(); + nsresult Read(const mozilla::MutexAutoLock& aProofOfLock); + nsresult Write(const mozilla::MutexAutoLock& aProofOfLock); + nsresult AddEntryToList(const nsACString& host, int32_t port, + nsIX509Cert* aCert, const bool aIsTemporary, + const nsACString& fingerprint, + nsCertOverride::OverrideBits ob, + const nsACString& dbKey, + const mozilla::MutexAutoLock& aProofOfLock); + + RefPtr mWriterTaskQueue; + + // Only accessed on the main thread + uint64_t mPendingWriteCount; +}; + +#define NS_CERTOVERRIDE_CID \ + { /* 67ba681d-5485-4fff-952c-2ee337ffdcd6 */ \ + 0x67ba681d, 0x5485, 0x4fff, { \ + 0x95, 0x2c, 0x2e, 0xe3, 0x37, 0xff, 0xdc, 0xd6 \ + } \ + } + +#endif // nsCertOverrideService_h diff --git a/security/manager/ssl/nsCertTree.cpp b/security/manager/ssl/nsCertTree.cpp new file mode 100644 index 0000000000..10640a5af4 --- /dev/null +++ b/security/manager/ssl/nsCertTree.cpp @@ -0,0 +1,824 @@ +/* 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/. */ + +#include "nsCertTree.h" + +#include "ScopedNSSTypes.h" +#include "mozilla/Logging.h" +#include "nsArray.h" +#include "nsArrayUtils.h" +#include "nsHashKeys.h" +#include "nsISupportsPrimitives.h" +#include "nsIX509CertDB.h" +#include "nsIX509Cert.h" +#include "nsIX509CertValidity.h" +#include "nsNSSCertHelper.h" +#include "nsNSSCertificate.h" +#include "nsNSSCertificateDB.h" +#include "nsNSSHelper.h" +#include "nsReadableUtils.h" +#include "nsTHashtable.h" +#include "nsUnicharUtils.h" +#include "nsXPCOMCID.h" +#include "nsString.h" +#include "nsTreeColumns.h" +#include "mozpkix/pkixtypes.h" + +using namespace mozilla; + +extern LazyLogModule gPIPNSSLog; + +// treeArrayElStr +// +// structure used to hold map of tree. Each thread (an organization +// field from a cert) has an element in the array. The numChildren field +// stores the number of certs corresponding to that thread. +struct treeArrayElStr { + nsString orgName; /* heading for thread */ + bool open; /* toggle open state for thread */ + int32_t certIndex; /* index into cert array for 1st cert */ + int32_t numChildren; /* number of chidren (certs) for thread */ +}; + +CompareCacheHashEntryPtr::CompareCacheHashEntryPtr() { + entry = new CompareCacheHashEntry; +} + +CompareCacheHashEntryPtr::~CompareCacheHashEntryPtr() { delete entry; } + +CompareCacheHashEntry::CompareCacheHashEntry() : key(nullptr), mCritInit() { + for (int i = 0; i < max_criterions; ++i) { + mCritInit[i] = false; + mCrit[i].SetIsVoid(true); + } +} + +static bool CompareCacheMatchEntry(const PLDHashEntryHdr* hdr, + const void* key) { + const CompareCacheHashEntryPtr* entryPtr = + static_cast(hdr); + return entryPtr->entry->key == key; +} + +static void CompareCacheInitEntry(PLDHashEntryHdr* hdr, const void* key) { + new (hdr) CompareCacheHashEntryPtr(); + CompareCacheHashEntryPtr* entryPtr = + static_cast(hdr); + entryPtr->entry->key = (void*)key; +} + +static void CompareCacheClearEntry(PLDHashTable* table, PLDHashEntryHdr* hdr) { + CompareCacheHashEntryPtr* entryPtr = + static_cast(hdr); + entryPtr->~CompareCacheHashEntryPtr(); +} + +static const PLDHashTableOps gMapOps = { + PLDHashTable::HashVoidPtrKeyStub, CompareCacheMatchEntry, + PLDHashTable::MoveEntryStub, CompareCacheClearEntry, CompareCacheInitEntry}; + +NS_IMPL_ISUPPORTS(nsCertTreeDispInfo, nsICertTreeItem) + +nsCertTreeDispInfo::~nsCertTreeDispInfo() = default; + +NS_IMETHODIMP +nsCertTreeDispInfo::GetCert(nsIX509Cert** aCert) { + NS_ENSURE_ARG(aCert); + nsCOMPtr cert = mCert; + cert.forget(aCert); + return NS_OK; +} + +NS_IMPL_ISUPPORTS(nsCertTree, nsICertTree, nsITreeView) + +nsCertTree::nsCertTree() + : mTreeArray(nullptr), + mNumOrgs(0), + mNumRows(0), + mCompareCache(&gMapOps, sizeof(CompareCacheHashEntryPtr), + kInitialCacheLength) { + mCellText = nullptr; +} + +void nsCertTree::ClearCompareHash() { + mCompareCache.ClearAndPrepareForLength(kInitialCacheLength); +} + +nsCertTree::~nsCertTree() { delete[] mTreeArray; } + +void nsCertTree::FreeCertArray() { mDispInfo.Clear(); } + +CompareCacheHashEntry* nsCertTree::getCacheEntry(void* cache, void* aCert) { + PLDHashTable& aCompareCache = *static_cast(cache); + auto entryPtr = static_cast( + aCompareCache.Add(aCert, fallible)); + return entryPtr ? entryPtr->entry : nullptr; +} + +void nsCertTree::RemoveCacheEntry(void* key) { mCompareCache.Remove(key); } + +// CountOrganizations +// +// Count the number of different organizations encountered in the cert +// list. +int32_t nsCertTree::CountOrganizations() { + uint32_t i, certCount; + certCount = mDispInfo.Length(); + if (certCount == 0) return 0; + nsCOMPtr orgCert = mDispInfo.ElementAt(0)->mCert; + nsCOMPtr nextCert = nullptr; + int32_t orgCount = 1; + for (i = 1; i < certCount; i++) { + nextCert = mDispInfo.SafeElementAt(i, nullptr)->mCert; + // XXX we assume issuer org is always criterion 1 + if (CmpBy(&mCompareCache, orgCert, nextCert, sort_IssuerOrg, sort_None, + sort_None) != 0) { + orgCert = nextCert; + orgCount++; + } + } + return orgCount; +} + +// GetThreadDescAtIndex +// +// If the row at index is an organization thread, return the collection +// associated with that thread. Otherwise, return null. +treeArrayEl* nsCertTree::GetThreadDescAtIndex(int32_t index) { + int i, idx = 0; + if (index < 0) return nullptr; + for (i = 0; i < mNumOrgs; i++) { + if (index == idx) { + return &mTreeArray[i]; + } + if (mTreeArray[i].open) { + idx += mTreeArray[i].numChildren; + } + idx++; + if (idx > index) break; + } + return nullptr; +} + +// GetCertAtIndex +// +// If the row at index is a cert, return that cert. Otherwise, return null. +already_AddRefed nsCertTree::GetCertAtIndex( + int32_t index, int32_t* outAbsoluteCertOffset) { + RefPtr certdi( + GetDispInfoAtIndex(index, outAbsoluteCertOffset)); + if (!certdi) return nullptr; + + nsCOMPtr ret = certdi->mCert; + return ret.forget(); +} + +// If the row at index is a cert, return that cert. Otherwise, return null. +already_AddRefed nsCertTree::GetDispInfoAtIndex( + int32_t index, int32_t* outAbsoluteCertOffset) { + int i, idx = 0, cIndex = 0, nc; + if (index < 0) return nullptr; + // Loop over the threads + for (i = 0; i < mNumOrgs; i++) { + if (index == idx) return nullptr; // index is for thread + idx++; // get past the thread + nc = (mTreeArray[i].open) ? mTreeArray[i].numChildren : 0; + if (index < idx + nc) { // cert is within range of this thread + int32_t certIndex = cIndex + index - idx; + if (outAbsoluteCertOffset) *outAbsoluteCertOffset = certIndex; + RefPtr certdi( + mDispInfo.SafeElementAt(certIndex, nullptr)); + if (certdi) { + return certdi.forget(); + } + break; + } + if (mTreeArray[i].open) idx += mTreeArray[i].numChildren; + cIndex += mTreeArray[i].numChildren; + if (idx > index) break; + } + return nullptr; +} + +nsCertTree::nsCertCompareFunc nsCertTree::GetCompareFuncFromCertType( + uint32_t aType) { + switch (aType) { + case nsIX509Cert::ANY_CERT: + case nsIX509Cert::USER_CERT: + return CmpUserCert; + case nsIX509Cert::EMAIL_CERT: + return CmpEmailCert; + case nsIX509Cert::CA_CERT: + default: + return CmpCACert; + } +} + +nsresult nsCertTree::GetCertsByTypeFromCertList( + const nsTArray>& aCertList, uint32_t aWantedType, + nsCertCompareFunc aCertCmpFn, void* aCertCmpFnArg) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("GetCertsByTypeFromCertList")); + + nsTHashtable allHostPortOverrideKeys; + + if (aWantedType == nsIX509Cert::SERVER_CERT) { + return NS_ERROR_INVALID_ARG; + } + + int count = 0; + for (const auto& cert : aCertList) { + bool wantThisCert = (aWantedType == nsIX509Cert::ANY_CERT); + + if (!wantThisCert) { + uint32_t thisCertType; + nsresult rv = cert->GetCertType(&thisCertType); + if (NS_FAILED(rv)) { + return rv; + } + if (thisCertType == aWantedType) { + wantThisCert = true; + } + } + + if (wantThisCert) { + int InsertPosition = 0; + for (; InsertPosition < count; ++InsertPosition) { + nsCOMPtr otherCert = nullptr; + RefPtr elem( + mDispInfo.SafeElementAt(InsertPosition, nullptr)); + if (elem) { + otherCert = elem->mCert; + } + if ((*aCertCmpFn)(aCertCmpFnArg, cert, otherCert) < 0) { + break; + } + } + nsCertTreeDispInfo* certdi = new nsCertTreeDispInfo(cert); + mDispInfo.InsertElementAt(InsertPosition, certdi); + ++count; + ++InsertPosition; + } + } + + return NS_OK; +} + +// LoadCerts +// +// Load all of the certificates in the DB for this type. Sort them +// by token, organization, then common name. +NS_IMETHODIMP +nsCertTree::LoadCertsFromCache(const nsTArray>& aCache, + uint32_t aType) { + if (mTreeArray) { + FreeCertArray(); + delete[] mTreeArray; + mTreeArray = nullptr; + mNumRows = 0; + } + ClearCompareHash(); + + nsresult rv = GetCertsByTypeFromCertList( + aCache, aType, GetCompareFuncFromCertType(aType), &mCompareCache); + if (NS_FAILED(rv)) { + return rv; + } + return UpdateUIContents(); +} + +nsresult nsCertTree::UpdateUIContents() { + uint32_t count = mDispInfo.Length(); + mNumOrgs = CountOrganizations(); + mTreeArray = new treeArrayEl[mNumOrgs]; + + mCellText = nsArrayBase::Create(); + + if (count) { + uint32_t j = 0; + nsCOMPtr orgCert = mDispInfo.ElementAt(j)->mCert; + for (int32_t i = 0; i < mNumOrgs; i++) { + nsString& orgNameRef = mTreeArray[i].orgName; + if (!orgCert) { + GetPIPNSSBundleString("CertOrgUnknown", orgNameRef); + } else { + orgCert->GetIssuerOrganization(orgNameRef); + if (orgNameRef.IsEmpty()) orgCert->GetCommonName(orgNameRef); + } + mTreeArray[i].open = true; + mTreeArray[i].certIndex = j; + mTreeArray[i].numChildren = 1; + if (++j >= count) break; + nsCOMPtr nextCert = + mDispInfo.SafeElementAt(j, nullptr)->mCert; + while (0 == CmpBy(&mCompareCache, orgCert, nextCert, sort_IssuerOrg, + sort_None, sort_None)) { + mTreeArray[i].numChildren++; + if (++j >= count) break; + nextCert = mDispInfo.SafeElementAt(j, nullptr)->mCert; + } + orgCert = nextCert; + } + } + if (mTree) { + mTree->BeginUpdateBatch(); + mTree->RowCountChanged(0, -mNumRows); + } + mNumRows = count + mNumOrgs; + if (mTree) mTree->EndUpdateBatch(); + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::DeleteEntryObject(uint32_t index) { + if (!mTreeArray) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr certdb = + do_GetService("@mozilla.org/security/x509certdb;1"); + if (!certdb) { + return NS_ERROR_FAILURE; + } + + int i; + uint32_t idx = 0, cIndex = 0, nc; + // Loop over the threads + for (i = 0; i < mNumOrgs; i++) { + if (index == idx) return NS_OK; // index is for thread + idx++; // get past the thread + nc = (mTreeArray[i].open) ? mTreeArray[i].numChildren : 0; + if (index < idx + nc) { // cert is within range of this thread + int32_t certIndex = cIndex + index - idx; + + RefPtr certdi( + mDispInfo.SafeElementAt(certIndex, nullptr)); + if (certdi) { + nsCOMPtr cert = certdi->mCert; + RemoveCacheEntry(cert); + certdb->DeleteCertificate(cert); + } + + mDispInfo.RemoveElementAt(certIndex); + + delete[] mTreeArray; + mTreeArray = nullptr; + return UpdateUIContents(); + } + if (mTreeArray[i].open) idx += mTreeArray[i].numChildren; + cIndex += mTreeArray[i].numChildren; + if (idx > index) break; + } + return NS_ERROR_FAILURE; +} + +////////////////////////////////////////////////////////////////////////////// +// +// Begin nsITreeView methods +// +///////////////////////////////////////////////////////////////////////////// + +NS_IMETHODIMP +nsCertTree::GetCert(uint32_t aIndex, nsIX509Cert** _cert) { + NS_ENSURE_ARG(_cert); + *_cert = GetCertAtIndex(aIndex).take(); + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::GetTreeItem(uint32_t aIndex, nsICertTreeItem** _treeitem) { + NS_ENSURE_ARG(_treeitem); + + RefPtr certdi(GetDispInfoAtIndex(aIndex)); + if (!certdi) return NS_ERROR_FAILURE; + + *_treeitem = certdi; + NS_IF_ADDREF(*_treeitem); + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::GetRowCount(int32_t* aRowCount) { + if (!mTreeArray) return NS_ERROR_NOT_INITIALIZED; + uint32_t count = 0; + for (int32_t i = 0; i < mNumOrgs; i++) { + if (mTreeArray[i].open) { + count += mTreeArray[i].numChildren; + } + count++; + } + *aRowCount = count; + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::GetSelection(nsITreeSelection** aSelection) { + *aSelection = mSelection; + NS_IF_ADDREF(*aSelection); + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::SetSelection(nsITreeSelection* aSelection) { + mSelection = aSelection; + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::GetRowProperties(int32_t index, nsAString& aProps) { return NS_OK; } + +NS_IMETHODIMP +nsCertTree::GetCellProperties(int32_t row, nsTreeColumn* col, + nsAString& aProps) { + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::GetColumnProperties(nsTreeColumn* col, nsAString& aProps) { + return NS_OK; +} +NS_IMETHODIMP +nsCertTree::IsContainer(int32_t index, bool* _retval) { + if (!mTreeArray) return NS_ERROR_NOT_INITIALIZED; + treeArrayEl* el = GetThreadDescAtIndex(index); + if (el) { + *_retval = true; + } else { + *_retval = false; + } + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::IsContainerOpen(int32_t index, bool* _retval) { + if (!mTreeArray) return NS_ERROR_NOT_INITIALIZED; + treeArrayEl* el = GetThreadDescAtIndex(index); + if (el && el->open) { + *_retval = true; + } else { + *_retval = false; + } + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::IsContainerEmpty(int32_t index, bool* _retval) { + *_retval = !mTreeArray; + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::IsSeparator(int32_t index, bool* _retval) { + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::GetParentIndex(int32_t rowIndex, int32_t* _retval) { + if (!mTreeArray) return NS_ERROR_NOT_INITIALIZED; + int i, idx = 0; + for (i = 0; i < mNumOrgs && idx < rowIndex; i++, idx++) { + if (mTreeArray[i].open) { + if (rowIndex <= idx + mTreeArray[i].numChildren) { + *_retval = idx; + return NS_OK; + } + idx += mTreeArray[i].numChildren; + } + } + *_retval = -1; + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::HasNextSibling(int32_t rowIndex, int32_t afterIndex, + bool* _retval) { + if (!mTreeArray) return NS_ERROR_NOT_INITIALIZED; + + int i, idx = 0; + for (i = 0; i < mNumOrgs && idx <= rowIndex; i++, idx++) { + if (mTreeArray[i].open) { + idx += mTreeArray[i].numChildren; + if (afterIndex <= idx) { + *_retval = afterIndex < idx; + return NS_OK; + } + } + } + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::GetLevel(int32_t index, int32_t* _retval) { + if (!mTreeArray) return NS_ERROR_NOT_INITIALIZED; + treeArrayEl* el = GetThreadDescAtIndex(index); + if (el) { + *_retval = 0; + } else { + *_retval = 1; + } + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::GetImageSrc(int32_t row, nsTreeColumn* col, nsAString& _retval) { + _retval.Truncate(); + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::GetCellValue(int32_t row, nsTreeColumn* col, nsAString& _retval) { + _retval.Truncate(); + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::GetCellText(int32_t row, nsTreeColumn* col, nsAString& _retval) { + if (!mTreeArray) return NS_ERROR_NOT_INITIALIZED; + + nsresult rv = NS_OK; + _retval.Truncate(); + + const nsAString& colID = col->GetId(); + + treeArrayEl* el = GetThreadDescAtIndex(row); + if (el) { + if (u"certcol"_ns.Equals(colID)) + _retval.Assign(el->orgName); + else + _retval.Truncate(); + return NS_OK; + } + + int32_t absoluteCertOffset; + RefPtr certdi( + GetDispInfoAtIndex(row, &absoluteCertOffset)); + if (!certdi) return NS_ERROR_FAILURE; + + nsCOMPtr cert = certdi->mCert; + + int32_t colIndex = col->Index(); + uint32_t arrayIndex = absoluteCertOffset + colIndex * (mNumRows - mNumOrgs); + uint32_t arrayLength = 0; + if (mCellText) { + mCellText->GetLength(&arrayLength); + } + if (arrayIndex < arrayLength) { + nsCOMPtr myString( + do_QueryElementAt(mCellText, arrayIndex)); + if (myString) { + myString->GetData(_retval); + return NS_OK; + } + } + + if (u"certcol"_ns.Equals(colID)) { + if (!cert) { + rv = GetPIPNSSBundleString("CertNotStored", _retval); + } else { + rv = cert->GetDisplayName(_retval); + } + } else if (u"tokencol"_ns.Equals(colID) && cert) { + rv = cert->GetTokenName(_retval); + } else if (u"emailcol"_ns.Equals(colID) && cert) { + rv = cert->GetEmailAddress(_retval); + } else if (u"issuedcol"_ns.Equals(colID) && cert) { + nsCOMPtr validity; + + rv = cert->GetValidity(getter_AddRefs(validity)); + if (NS_SUCCEEDED(rv)) { + validity->GetNotBeforeLocalDay(_retval); + } + } else if (u"expiredcol"_ns.Equals(colID) && cert) { + nsCOMPtr validity; + + rv = cert->GetValidity(getter_AddRefs(validity)); + if (NS_SUCCEEDED(rv)) { + validity->GetNotAfterLocalDay(_retval); + } + } else if (u"serialnumcol"_ns.Equals(colID) && cert) { + rv = cert->GetSerialNumber(_retval); + } else { + return NS_ERROR_FAILURE; + } + if (mCellText) { + nsCOMPtr text( + do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + text->SetData(_retval); + mCellText->ReplaceElementAt(text, arrayIndex); + } + return rv; +} + +NS_IMETHODIMP +nsCertTree::SetTree(mozilla::dom::XULTreeElement* tree) { + mTree = tree; + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::ToggleOpenState(int32_t index) { + if (!mTreeArray) return NS_ERROR_NOT_INITIALIZED; + treeArrayEl* el = GetThreadDescAtIndex(index); + if (el) { + el->open = !el->open; + int32_t newChildren = (el->open) ? el->numChildren : -el->numChildren; + if (mTree) { + mTree->RowCountChanged(index + 1, newChildren); + mTree->InvalidateRow(index); + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::CycleHeader(nsTreeColumn* col) { return NS_OK; } + +NS_IMETHODIMP +nsCertTree::SelectionChangedXPCOM() { return NS_ERROR_NOT_IMPLEMENTED; } + +NS_IMETHODIMP +nsCertTree::CycleCell(int32_t row, nsTreeColumn* col) { return NS_OK; } + +NS_IMETHODIMP +nsCertTree::IsEditable(int32_t row, nsTreeColumn* col, bool* _retval) { + *_retval = false; + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::SetCellValue(int32_t row, nsTreeColumn* col, + const nsAString& value) { + return NS_OK; +} + +NS_IMETHODIMP +nsCertTree::SetCellText(int32_t row, nsTreeColumn* col, + const nsAString& value) { + return NS_OK; +} + +// +// CanDrop +// +NS_IMETHODIMP nsCertTree::CanDrop(int32_t index, int32_t orientation, + mozilla::dom::DataTransfer* aDataTransfer, + bool* _retval) { + NS_ENSURE_ARG_POINTER(_retval); + *_retval = false; + + return NS_OK; +} + +// +// Drop +// +NS_IMETHODIMP nsCertTree::Drop(int32_t row, int32_t orient, + mozilla::dom::DataTransfer* aDataTransfer) { + return NS_OK; +} + +// +// IsSorted +// +// ... +// +NS_IMETHODIMP nsCertTree::IsSorted(bool* _retval) { + *_retval = false; + return NS_OK; +} + +#define RETURN_NOTHING + +void nsCertTree::CmpInitCriterion(nsIX509Cert* cert, + CompareCacheHashEntry* entry, + sortCriterion crit, int32_t level) { + NS_ENSURE_TRUE(cert && entry, RETURN_NOTHING); + + entry->mCritInit[level] = true; + nsString& str = entry->mCrit[level]; + + switch (crit) { + case sort_IssuerOrg: + cert->GetIssuerOrganization(str); + if (str.IsEmpty()) cert->GetCommonName(str); + break; + case sort_Org: + cert->GetOrganization(str); + break; + case sort_Token: + cert->GetTokenName(str); + break; + case sort_CommonName: + cert->GetCommonName(str); + break; + case sort_IssuedDateDescending: { + nsresult rv; + nsCOMPtr validity; + PRTime notBefore; + + rv = cert->GetValidity(getter_AddRefs(validity)); + if (NS_SUCCEEDED(rv)) { + rv = validity->GetNotBefore(¬Before); + } + + if (NS_SUCCEEDED(rv)) { + PRExplodedTime explodedTime; + PR_ExplodeTime(notBefore, PR_GMTParameters, &explodedTime); + char datebuf[20]; // 4 + 2 + 2 + 2 + 2 + 2 + 1 = 15 + if (0 != PR_FormatTime(datebuf, sizeof(datebuf), "%Y%m%d%H%M%S", + &explodedTime)) { + str = NS_ConvertASCIItoUTF16(nsDependentCString(datebuf)); + } + } + } break; + case sort_Email: + cert->GetEmailAddress(str); + break; + case sort_None: + default: + break; + } +} + +int32_t nsCertTree::CmpByCrit(nsIX509Cert* a, CompareCacheHashEntry* ace, + nsIX509Cert* b, CompareCacheHashEntry* bce, + sortCriterion crit, int32_t level) { + NS_ENSURE_TRUE(a && ace && b && bce, 0); + + if (!ace->mCritInit[level]) { + CmpInitCriterion(a, ace, crit, level); + } + + if (!bce->mCritInit[level]) { + CmpInitCriterion(b, bce, crit, level); + } + + nsString& str_a = ace->mCrit[level]; + nsString& str_b = bce->mCrit[level]; + + int32_t result; + if (!str_a.IsVoid() && !str_b.IsVoid()) + result = Compare(str_a, str_b, nsCaseInsensitiveStringComparator); + else + result = str_a.IsVoid() ? (str_b.IsVoid() ? 0 : -1) : 1; + + if (sort_IssuedDateDescending == crit) result *= -1; // reverse compare order + + return result; +} + +int32_t nsCertTree::CmpBy(void* cache, nsIX509Cert* a, nsIX509Cert* b, + sortCriterion c0, sortCriterion c1, + sortCriterion c2) { + // This will be called when comparing items for display sorting. + // Some items might have no cert associated, so either a or b is null. + // We want all those orphans show at the top of the list, + // so we treat a null cert as "smaller" by returning -1. + // We don't try to sort within the group of no-cert entries, + // so we treat them as equal wrt sort order. + + if (!a && !b) return 0; + + if (!a) return -1; + + if (!b) return 1; + + NS_ENSURE_TRUE(cache && a && b, 0); + + CompareCacheHashEntry* ace = getCacheEntry(cache, a); + CompareCacheHashEntry* bce = getCacheEntry(cache, b); + + int32_t cmp; + cmp = CmpByCrit(a, ace, b, bce, c0, 0); + if (cmp != 0) return cmp; + + if (c1 != sort_None) { + cmp = CmpByCrit(a, ace, b, bce, c1, 1); + if (cmp != 0) return cmp; + + if (c2 != sort_None) { + return CmpByCrit(a, ace, b, bce, c2, 2); + } + } + + return cmp; +} + +int32_t nsCertTree::CmpCACert(void* cache, nsIX509Cert* a, nsIX509Cert* b) { + // XXX we assume issuer org is always criterion 1 + return CmpBy(cache, a, b, sort_IssuerOrg, sort_Org, sort_Token); +} + +int32_t nsCertTree::CmpUserCert(void* cache, nsIX509Cert* a, nsIX509Cert* b) { + // XXX we assume issuer org is always criterion 1 + return CmpBy(cache, a, b, sort_IssuerOrg, sort_Token, + sort_IssuedDateDescending); +} + +int32_t nsCertTree::CmpEmailCert(void* cache, nsIX509Cert* a, nsIX509Cert* b) { + // XXX we assume issuer org is always criterion 1 + return CmpBy(cache, a, b, sort_IssuerOrg, sort_Email, sort_CommonName); +} diff --git a/security/manager/ssl/nsCertTree.h b/security/manager/ssl/nsCertTree.h new file mode 100644 index 0000000000..d7fd86216c --- /dev/null +++ b/security/manager/ssl/nsCertTree.h @@ -0,0 +1,131 @@ +/* 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/. */ + +#ifndef _NS_CERTTREE_H_ +#define _NS_CERTTREE_H_ + +#include "nsCOMPtr.h" +#include "nsICertTree.h" +#include "nsITreeSelection.h" +#include "nsIMutableArray.h" +#include "nsNSSComponent.h" +#include "nsTArray.h" +#include "PLDHashTable.h" +#include "mozilla/Attributes.h" + +/* Disable the "base class XXX should be explicitly initialized + in the copy constructor" warning. */ +#if defined(__clang__) +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wextra" +#elif defined(__GNUC__) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wextra" +#endif // __clang__ || __GNUC__ + +#include "mozilla/dom/XULTreeElement.h" + +#if defined(__clang__) +# pragma clang diagnostic pop +#elif defined(__GNUC__) +# pragma GCC diagnostic pop +#endif // __clang__ || __GNUC__ + +typedef struct treeArrayElStr treeArrayEl; + +struct CompareCacheHashEntry { + enum { max_criterions = 3 }; + CompareCacheHashEntry(); + + void* key; // no ownership + bool mCritInit[max_criterions]; + nsString mCrit[max_criterions]; +}; + +struct CompareCacheHashEntryPtr : PLDHashEntryHdr { + CompareCacheHashEntryPtr(); + ~CompareCacheHashEntryPtr(); + CompareCacheHashEntry* entry; +}; + +class nsCertTreeDispInfo : public nsICertTreeItem { + protected: + virtual ~nsCertTreeDispInfo(); + + public: + explicit nsCertTreeDispInfo(nsIX509Cert* aCert) : mCert(aCert) {} + + NS_DECL_ISUPPORTS + NS_DECL_NSICERTTREEITEM + + nsCOMPtr mCert; +}; + +class nsCertTree : public nsICertTree { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSICERTTREE + NS_DECL_NSITREEVIEW + + nsCertTree(); + + enum sortCriterion { + sort_IssuerOrg, + sort_Org, + sort_Token, + sort_CommonName, + sort_IssuedDateDescending, + sort_Email, + sort_None + }; + + protected: + virtual ~nsCertTree(); + + void ClearCompareHash(); + void RemoveCacheEntry(void* key); + + typedef int (*nsCertCompareFunc)(void*, nsIX509Cert* a, nsIX509Cert* b); + + static CompareCacheHashEntry* getCacheEntry(void* cache, void* aCert); + static void CmpInitCriterion(nsIX509Cert* cert, CompareCacheHashEntry* entry, + sortCriterion crit, int32_t level); + static int32_t CmpByCrit(nsIX509Cert* a, CompareCacheHashEntry* ace, + nsIX509Cert* b, CompareCacheHashEntry* bce, + sortCriterion crit, int32_t level); + static int32_t CmpBy(void* cache, nsIX509Cert* a, nsIX509Cert* b, + sortCriterion c0, sortCriterion c1, sortCriterion c2); + static int32_t CmpCACert(void* cache, nsIX509Cert* a, nsIX509Cert* b); + static int32_t CmpUserCert(void* cache, nsIX509Cert* a, nsIX509Cert* b); + static int32_t CmpEmailCert(void* cache, nsIX509Cert* a, nsIX509Cert* b); + nsCertCompareFunc GetCompareFuncFromCertType(uint32_t aType); + int32_t CountOrganizations(); + + private: + static const uint32_t kInitialCacheLength = 64; + + nsTArray> mDispInfo; + RefPtr mTree; + nsCOMPtr mSelection; + treeArrayEl* mTreeArray; + int32_t mNumOrgs; + int32_t mNumRows; + PLDHashTable mCompareCache; + + treeArrayEl* GetThreadDescAtIndex(int32_t _index); + already_AddRefed GetCertAtIndex( + int32_t _index, int32_t* outAbsoluteCertOffset = nullptr); + already_AddRefed GetDispInfoAtIndex( + int32_t index, int32_t* outAbsoluteCertOffset = nullptr); + void FreeCertArray(); + nsresult UpdateUIContents(); + + nsresult GetCertsByTypeFromCertList( + const nsTArray>& aCertList, uint32_t aWantedType, + nsCertCompareFunc aCertCmpFn, void* aCertCmpFnArg); + + nsCOMPtr mCellText; +}; + +#endif /* _NS_CERTTREE_H_ */ diff --git a/security/manager/ssl/nsClientAuthRemember.cpp b/security/manager/ssl/nsClientAuthRemember.cpp new file mode 100644 index 0000000000..a61b98ce8b --- /dev/null +++ b/security/manager/ssl/nsClientAuthRemember.cpp @@ -0,0 +1,276 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsClientAuthRemember.h" + +#include "mozilla/BasePrincipal.h" +#include "mozilla/DataStorage.h" +#include "mozilla/RefPtr.h" +#include "nsCRT.h" +#include "nsNSSCertHelper.h" +#include "nsIObserverService.h" +#include "nsNetUtil.h" +#include "nsPromiseFlatString.h" +#include "nsThreadUtils.h" +#include "nsStringBuffer.h" +#include "cert.h" +#include "nspr.h" +#include "pk11pub.h" +#include "certdb.h" +#include "sechash.h" +#include "SharedSSLState.h" + +#include "nsJSUtils.h" + +using namespace mozilla; +using namespace mozilla::psm; + +NS_IMPL_ISUPPORTS(nsClientAuthRememberService, nsIClientAuthRememberService) +NS_IMPL_ISUPPORTS(nsClientAuthRemember, nsIClientAuthRememberRecord) + +const nsCString nsClientAuthRemember::SentinelValue = + "no client certificate"_ns; + +NS_IMETHODIMP +nsClientAuthRemember::GetAsciiHost(/*out*/ nsACString& aAsciiHost) { + aAsciiHost = mAsciiHost; + return NS_OK; +} + +NS_IMETHODIMP +nsClientAuthRemember::GetFingerprint(/*out*/ nsACString& aFingerprint) { + aFingerprint = mFingerprint; + return NS_OK; +} + +NS_IMETHODIMP +nsClientAuthRemember::GetDbKey(/*out*/ nsACString& aDBKey) { + aDBKey = mDBKey; + return NS_OK; +} + +NS_IMETHODIMP +nsClientAuthRemember::GetEntryKey(/*out*/ nsACString& aEntryKey) { + aEntryKey = mEntryKey; + return NS_OK; +} + +nsresult nsClientAuthRememberService::Init() { + if (!NS_IsMainThread()) { + NS_ERROR("nsClientAuthRememberService::Init called off the main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + + mClientAuthRememberList = + mozilla::DataStorage::Get(DataStorageClass::ClientAuthRememberList); + nsresult rv = mClientAuthRememberList->Init(nullptr); + + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsClientAuthRememberService::ForgetRememberedDecision(const nsACString& key) { + mClientAuthRememberList->Remove(PromiseFlatCString(key), + mozilla::DataStorage_Persistent); + + nsCOMPtr nssComponent(do_GetService(NS_NSSCOMPONENT_CID)); + if (!nssComponent) { + return NS_ERROR_NOT_AVAILABLE; + } + return nssComponent->ClearSSLExternalAndInternalSessionCache(); +} + +NS_IMETHODIMP +nsClientAuthRememberService::GetDecisions( + nsTArray>& results) { + nsTArray decisions; + mClientAuthRememberList->GetAll(&decisions); + + for (const mozilla::psm::DataStorageItem& decision : decisions) { + if (decision.type() == DataStorageType::DataStorage_Persistent) { + RefPtr tmp = + new nsClientAuthRemember(decision.key(), decision.value()); + + results.AppendElement(tmp); + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsClientAuthRememberService::ClearRememberedDecisions() { + mClientAuthRememberList->Clear(); + nsCOMPtr nssComponent(do_GetService(NS_NSSCOMPONENT_CID)); + if (!nssComponent) { + return NS_ERROR_NOT_AVAILABLE; + } + return nssComponent->ClearSSLExternalAndInternalSessionCache(); +} + +NS_IMETHODIMP +nsClientAuthRememberService::DeleteDecisionsByHost( + const nsACString& aHostName, JS::Handle aOriginAttributes, + JSContext* aCx) { + OriginAttributes attrs; + if (!aOriginAttributes.isObject() || !attrs.Init(aCx, aOriginAttributes)) { + return NS_ERROR_INVALID_ARG; + } + DataStorageType storageType = GetDataStorageType(attrs); + + nsTArray decisions; + mClientAuthRememberList->GetAll(&decisions); + + for (const mozilla::psm::DataStorageItem& decision : decisions) { + if (decision.type() == storageType) { + RefPtr tmp = + new nsClientAuthRemember(decision.key(), decision.value()); + nsAutoCString asciiHost; + tmp->GetAsciiHost(asciiHost); + if (asciiHost.Equals(aHostName)) { + mClientAuthRememberList->Remove(decision.key(), decision.type()); + } + } + } + nsCOMPtr nssComponent(do_GetService(NS_NSSCOMPONENT_CID)); + if (!nssComponent) { + return NS_ERROR_NOT_AVAILABLE; + } + return nssComponent->ClearSSLExternalAndInternalSessionCache(); +} + +static nsresult GetCertSha256Fingerprint(CERTCertificate* aNssCert, + nsCString& aResult) { + nsCOMPtr cert(nsNSSCertificate::Create(aNssCert)); + nsAutoString fpStrUTF16; + nsresult rv = cert->GetSha256Fingerprint(fpStrUTF16); + if (NS_FAILED(rv)) { + return rv; + } + aResult.Assign(NS_ConvertUTF16toUTF8(fpStrUTF16)); + return NS_OK; +} + +NS_IMETHODIMP +nsClientAuthRememberService::RememberDecision( + const nsACString& aHostName, const OriginAttributes& aOriginAttributes, + CERTCertificate* aServerCert, CERTCertificate* aClientCert) { + // aClientCert == nullptr means: remember that user does not want to use a + // cert + NS_ENSURE_ARG_POINTER(aServerCert); + if (aHostName.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + + nsAutoCString fpStr; + nsresult rv = GetCertSha256Fingerprint(aServerCert, fpStr); + if (NS_FAILED(rv)) { + return rv; + } + + if (aClientCert) { + RefPtr pipCert(new nsNSSCertificate(aClientCert)); + nsAutoCString dbkey; + rv = pipCert->GetDbKey(dbkey); + if (NS_SUCCEEDED(rv)) { + AddEntryToList(aHostName, aOriginAttributes, fpStr, dbkey); + } + } else { + AddEntryToList(aHostName, aOriginAttributes, fpStr, + nsClientAuthRemember::SentinelValue); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsClientAuthRememberService::HasRememberedDecision( + const nsACString& aHostName, const OriginAttributes& aOriginAttributes, + CERTCertificate* aCert, nsACString& aCertDBKey, bool* aRetVal) { + if (aHostName.IsEmpty()) return NS_ERROR_INVALID_ARG; + + NS_ENSURE_ARG_POINTER(aCert); + NS_ENSURE_ARG_POINTER(aRetVal); + *aRetVal = false; + aCertDBKey.Truncate(); + + nsAutoCString fpStr; + nsresult rv = GetCertSha256Fingerprint(aCert, fpStr); + if (NS_FAILED(rv)) { + return rv; + } + + nsAutoCString entryKey; + GetEntryKey(aHostName, aOriginAttributes, fpStr, entryKey); + DataStorageType storageType = GetDataStorageType(aOriginAttributes); + + nsCString listEntry = mClientAuthRememberList->Get(entryKey, storageType); + if (listEntry.IsEmpty()) { + return NS_OK; + } + + if (!listEntry.Equals(nsClientAuthRemember::SentinelValue)) { + aCertDBKey = listEntry; + } + *aRetVal = true; + + return NS_OK; +} + +nsresult nsClientAuthRememberService::AddEntryToList( + const nsACString& aHostName, const OriginAttributes& aOriginAttributes, + const nsACString& aFingerprint, const nsACString& aDBKey) { + nsAutoCString entryKey; + GetEntryKey(aHostName, aOriginAttributes, aFingerprint, entryKey); + DataStorageType storageType = GetDataStorageType(aOriginAttributes); + + nsCString tmpDbKey(aDBKey); + nsresult rv = mClientAuthRememberList->Put(entryKey, tmpDbKey, storageType); + if (NS_FAILED(rv)) { + return rv; + } + + return NS_OK; +} + +void nsClientAuthRememberService::GetEntryKey( + const nsACString& aHostName, const OriginAttributes& aOriginAttributes, + const nsACString& aFingerprint, nsACString& aEntryKey) { + nsAutoCString hostCert(aHostName); + hostCert.Append(','); + hostCert.Append(aFingerprint); + hostCert.Append(','); + + nsAutoCString suffix; + aOriginAttributes.CreateSuffix(suffix); + hostCert.Append(suffix); + + aEntryKey.Assign(hostCert); +} + +bool nsClientAuthRememberService::IsPrivateBrowsingKey( + const nsCString& entryKey) { + const int32_t separator = entryKey.Find(":", false, 0, -1); + nsCString suffix; + if (separator >= 0) { + entryKey.Left(suffix, separator); + } else { + suffix = entryKey; + } + return OriginAttributes::IsPrivateBrowsing(suffix); +} + +DataStorageType nsClientAuthRememberService::GetDataStorageType( + const OriginAttributes& aOriginAttributes) { + if (aOriginAttributes.mPrivateBrowsingId > 0) { + return DataStorage_Private; + } + return DataStorage_Persistent; +} diff --git a/security/manager/ssl/nsClientAuthRemember.h b/security/manager/ssl/nsClientAuthRemember.h new file mode 100644 index 0000000000..9ad6fb9cb8 --- /dev/null +++ b/security/manager/ssl/nsClientAuthRemember.h @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef __NSCLIENTAUTHREMEMBER_H__ +#define __NSCLIENTAUTHREMEMBER_H__ + +#include + +#include "mozilla/Attributes.h" +#include "mozilla/DataStorage.h" +#include "mozilla/HashFunctions.h" +#include "mozilla/ReentrantMonitor.h" +#include "nsIClientAuthRememberService.h" +#include "nsIObserver.h" +#include "nsNSSCertificate.h" +#include "nsString.h" +#include "nsTHashtable.h" +#include "nsWeakReference.h" + +namespace mozilla { +class OriginAttributes; +} + +using mozilla::OriginAttributes; + +class nsClientAuthRemember final : public nsIClientAuthRememberRecord { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSICLIENTAUTHREMEMBERRECORD + + nsClientAuthRemember(const nsCString& aEntryKey, const nsCString& aDBKey) { + mEntryKey = aEntryKey; + if (!aDBKey.Equals(nsClientAuthRemember::SentinelValue)) { + mDBKey = aDBKey; + } + + nsTArray fields = {&mAsciiHost, &mFingerprint}; + + auto fieldsIter = fields.begin(); + auto splitter = aEntryKey.Split(','); + auto splitterIter = splitter.begin(); + for (; fieldsIter != fields.end() && splitterIter != splitter.end(); + ++fieldsIter, ++splitterIter) { + (*fieldsIter)->Assign(*splitterIter); + } + } + + nsCString mAsciiHost; + nsCString mFingerprint; + nsCString mDBKey; + nsCString mEntryKey; + static const nsCString SentinelValue; + + protected: + ~nsClientAuthRemember() = default; +}; + +class nsClientAuthRememberService final : public nsIClientAuthRememberService { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSICLIENTAUTHREMEMBERSERVICE + + nsClientAuthRememberService() = default; + + nsresult Init(); + + static void GetEntryKey(const nsACString& aHostName, + const OriginAttributes& aOriginAttributes, + const nsACString& aFingerprint, + /*out*/ nsACString& aEntryKey); + + static bool IsPrivateBrowsingKey(const nsCString& entryKey); + + protected: + ~nsClientAuthRememberService() = default; + + static mozilla::DataStorageType GetDataStorageType( + const OriginAttributes& aOriginAttributes); + + RefPtr mClientAuthRememberList; + + nsresult AddEntryToList(const nsACString& aHost, + const OriginAttributes& aOriginAttributes, + const nsACString& aServerFingerprint, + const nsACString& aDBKey); +}; + +#endif diff --git a/security/manager/ssl/nsCryptoHash.cpp b/security/manager/ssl/nsCryptoHash.cpp new file mode 100644 index 0000000000..9304a0cd99 --- /dev/null +++ b/security/manager/ssl/nsCryptoHash.cpp @@ -0,0 +1,334 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsCryptoHash.h" + +#include + +#include "mozilla/ArrayUtils.h" +#include "mozilla/Base64.h" +#include "mozilla/Casting.h" +#include "nsDependentString.h" +#include "nsIInputStream.h" +#include "nsIKeyModule.h" +#include "nsString.h" +#include "pk11pub.h" +#include "sechash.h" + +using namespace mozilla; + +namespace { + +static const uint64_t STREAM_BUFFER_SIZE = 4096; + +} // namespace + +//--------------------------------------------- +// Implementing nsICryptoHash +//--------------------------------------------- + +nsCryptoHash::nsCryptoHash() : mHashContext(nullptr), mInitialized(false) {} + +NS_IMPL_ISUPPORTS(nsCryptoHash, nsICryptoHash) + +NS_IMETHODIMP +nsCryptoHash::Init(uint32_t algorithm) { + HASH_HashType hashType; + switch (algorithm) { + case nsICryptoHash::MD5: + hashType = HASH_AlgMD5; + break; + case nsICryptoHash::SHA1: + hashType = HASH_AlgSHA1; + break; + case nsICryptoHash::SHA256: + hashType = HASH_AlgSHA256; + break; + case nsICryptoHash::SHA384: + hashType = HASH_AlgSHA384; + break; + case nsICryptoHash::SHA512: + hashType = HASH_AlgSHA512; + break; + default: + return NS_ERROR_INVALID_ARG; + } + + if (mHashContext) { + if (!mInitialized && HASH_GetType(mHashContext.get()) == hashType) { + mInitialized = true; + HASH_Begin(mHashContext.get()); + return NS_OK; + } + + // Destroy current hash context if the type was different + // or Finish method wasn't called. + mHashContext = nullptr; + mInitialized = false; + } + + mHashContext.reset(HASH_Create(hashType)); + if (!mHashContext) { + return NS_ERROR_INVALID_ARG; + } + + HASH_Begin(mHashContext.get()); + mInitialized = true; + return NS_OK; +} + +NS_IMETHODIMP +nsCryptoHash::InitWithString(const nsACString& aAlgorithm) { + if (aAlgorithm.LowerCaseEqualsLiteral("md5")) return Init(nsICryptoHash::MD5); + + if (aAlgorithm.LowerCaseEqualsLiteral("sha1")) + return Init(nsICryptoHash::SHA1); + + if (aAlgorithm.LowerCaseEqualsLiteral("sha256")) + return Init(nsICryptoHash::SHA256); + + if (aAlgorithm.LowerCaseEqualsLiteral("sha384")) + return Init(nsICryptoHash::SHA384); + + if (aAlgorithm.LowerCaseEqualsLiteral("sha512")) + return Init(nsICryptoHash::SHA512); + + return NS_ERROR_INVALID_ARG; +} + +NS_IMETHODIMP +nsCryptoHash::Update(const uint8_t* data, uint32_t len) { + if (!mInitialized) { + return NS_ERROR_NOT_INITIALIZED; + } + + HASH_Update(mHashContext.get(), data, len); + return NS_OK; +} + +NS_IMETHODIMP +nsCryptoHash::UpdateFromStream(nsIInputStream* data, uint32_t aLen) { + if (!mInitialized) return NS_ERROR_NOT_INITIALIZED; + + if (!data) return NS_ERROR_INVALID_ARG; + + uint64_t n; + nsresult rv = data->Available(&n); + if (NS_FAILED(rv)) return rv; + + // if the user has passed UINT32_MAX, then read + // everything in the stream + + uint64_t len = aLen; + if (aLen == UINT32_MAX) len = n; + + // So, if the stream has NO data available for the hash, + // or if the data available is less then what the caller + // requested, we can not fulfill the hash update. In this + // case, just return NS_ERROR_NOT_AVAILABLE indicating + // that there is not enough data in the stream to satisify + // the request. + + if (n == 0 || n < len) { + return NS_ERROR_NOT_AVAILABLE; + } + + char buffer[STREAM_BUFFER_SIZE]; + while (len > 0) { + uint64_t readLimit = std::min(STREAM_BUFFER_SIZE, len); + uint32_t read; + rv = data->Read(buffer, AssertedCast(readLimit), &read); + if (NS_FAILED(rv)) { + return rv; + } + + rv = Update(BitwiseCast(buffer), read); + if (NS_FAILED(rv)) { + return rv; + } + + len -= read; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsCryptoHash::Finish(bool ascii, nsACString& _retval) { + if (!mInitialized) { + return NS_ERROR_NOT_INITIALIZED; + } + + uint32_t hashLen = 0; + unsigned char buffer[HASH_LENGTH_MAX]; + HASH_End(mHashContext.get(), buffer, &hashLen, HASH_LENGTH_MAX); + + mInitialized = false; + + if (ascii) { + nsDependentCSubstring dataStr(BitwiseCast(buffer), hashLen); + return Base64Encode(dataStr, _retval); + } + + _retval.Assign(BitwiseCast(buffer), hashLen); + return NS_OK; +} + +//--------------------------------------------- +// Implementing nsICryptoHMAC +//--------------------------------------------- + +NS_IMPL_ISUPPORTS(nsCryptoHMAC, nsICryptoHMAC) + +nsCryptoHMAC::nsCryptoHMAC() : mHMACContext(nullptr) {} + +NS_IMETHODIMP +nsCryptoHMAC::Init(uint32_t aAlgorithm, nsIKeyObject* aKeyObject) { + if (mHMACContext) { + mHMACContext = nullptr; + } + + CK_MECHANISM_TYPE mechType; + switch (aAlgorithm) { + case nsICryptoHMAC::MD5: + mechType = CKM_MD5_HMAC; + break; + case nsICryptoHMAC::SHA1: + mechType = CKM_SHA_1_HMAC; + break; + case nsICryptoHMAC::SHA256: + mechType = CKM_SHA256_HMAC; + break; + case nsICryptoHMAC::SHA384: + mechType = CKM_SHA384_HMAC; + break; + case nsICryptoHMAC::SHA512: + mechType = CKM_SHA512_HMAC; + break; + default: + return NS_ERROR_INVALID_ARG; + } + + NS_ENSURE_ARG_POINTER(aKeyObject); + + nsresult rv; + + int16_t keyType; + rv = aKeyObject->GetType(&keyType); + NS_ENSURE_SUCCESS(rv, rv); + + NS_ENSURE_TRUE(keyType == nsIKeyObject::SYM_KEY, NS_ERROR_INVALID_ARG); + + PK11SymKey* key; + // GetKeyObj doesn't addref the key + rv = aKeyObject->GetKeyObj(&key); + NS_ENSURE_SUCCESS(rv, rv); + + SECItem rawData; + rawData.data = 0; + rawData.len = 0; + mHMACContext.reset( + PK11_CreateContextBySymKey(mechType, CKA_SIGN, key, &rawData)); + NS_ENSURE_TRUE(mHMACContext, NS_ERROR_FAILURE); + + if (PK11_DigestBegin(mHMACContext.get()) != SECSuccess) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsCryptoHMAC::Update(const uint8_t* aData, uint32_t aLen) { + if (!mHMACContext) return NS_ERROR_NOT_INITIALIZED; + + if (!aData) return NS_ERROR_INVALID_ARG; + + if (PK11_DigestOp(mHMACContext.get(), aData, aLen) != SECSuccess) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsCryptoHMAC::UpdateFromStream(nsIInputStream* aStream, uint32_t aLen) { + if (!mHMACContext) return NS_ERROR_NOT_INITIALIZED; + + if (!aStream) return NS_ERROR_INVALID_ARG; + + uint64_t n; + nsresult rv = aStream->Available(&n); + if (NS_FAILED(rv)) return rv; + + // if the user has passed UINT32_MAX, then read + // everything in the stream + + uint64_t len = aLen; + if (aLen == UINT32_MAX) len = n; + + // So, if the stream has NO data available for the hash, + // or if the data available is less then what the caller + // requested, we can not fulfill the HMAC update. In this + // case, just return NS_ERROR_NOT_AVAILABLE indicating + // that there is not enough data in the stream to satisify + // the request. + + if (n == 0 || n < len) return NS_ERROR_NOT_AVAILABLE; + + char buffer[STREAM_BUFFER_SIZE]; + while (len > 0) { + uint64_t readLimit = std::min(STREAM_BUFFER_SIZE, len); + uint32_t read; + rv = aStream->Read(buffer, AssertedCast(readLimit), &read); + if (NS_FAILED(rv)) { + return rv; + } + + if (read == 0) { + return NS_BASE_STREAM_CLOSED; + } + + rv = Update(BitwiseCast(buffer), read); + if (NS_FAILED(rv)) { + return rv; + } + + len -= read; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsCryptoHMAC::Finish(bool aASCII, nsACString& _retval) { + if (!mHMACContext) return NS_ERROR_NOT_INITIALIZED; + + uint32_t hashLen = 0; + unsigned char buffer[HASH_LENGTH_MAX]; + SECStatus srv = + PK11_DigestFinal(mHMACContext.get(), buffer, &hashLen, HASH_LENGTH_MAX); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + + if (aASCII) { + nsDependentCSubstring dataStr(BitwiseCast(buffer), hashLen); + return Base64Encode(dataStr, _retval); + } + + _retval.Assign(BitwiseCast(buffer), hashLen); + return NS_OK; +} + +NS_IMETHODIMP +nsCryptoHMAC::Reset() { + if (PK11_DigestBegin(mHMACContext.get()) != SECSuccess) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} diff --git a/security/manager/ssl/nsCryptoHash.h b/security/manager/ssl/nsCryptoHash.h new file mode 100644 index 0000000000..12d0e108d0 --- /dev/null +++ b/security/manager/ssl/nsCryptoHash.h @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef nsCryptoHash_h +#define nsCryptoHash_h + +#include "ScopedNSSTypes.h" +#include "hasht.h" +#include "nsICryptoHMAC.h" +#include "nsICryptoHash.h" +#include "secmodt.h" + +class nsIInputStream; + +#define NS_CRYPTO_HASH_CID \ + { \ + 0x36a1d3b3, 0xd886, 0x4317, { \ + 0x96, 0xff, 0x87, 0xb0, 0x00, 0x5c, 0xfe, 0xf7 \ + } \ + } +#define NS_CRYPTO_HMAC_CID \ + { \ + 0xa496d0a2, 0xdff7, 0x4e23, { \ + 0xbd, 0x65, 0x1c, 0xa7, 0x42, 0xfa, 0x17, 0x8a \ + } \ + } + +class nsCryptoHash final : public nsICryptoHash { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSICRYPTOHASH + + nsCryptoHash(); + + private: + virtual ~nsCryptoHash() = default; + + mozilla::UniqueHASHContext mHashContext; + bool mInitialized; +}; + +class nsCryptoHMAC : public nsICryptoHMAC { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSICRYPTOHMAC + + nsCryptoHMAC(); + + private: + virtual ~nsCryptoHMAC() = default; + + mozilla::UniquePK11Context mHMACContext; +}; + +#endif // nsCryptoHash_h diff --git a/security/manager/ssl/nsICertOverrideService.idl b/security/manager/ssl/nsICertOverrideService.idl new file mode 100644 index 0000000000..23276fbe19 --- /dev/null +++ b/security/manager/ssl/nsICertOverrideService.idl @@ -0,0 +1,175 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +interface nsIArray; +interface nsIX509Cert; + +%{C++ +#define NS_CERTOVERRIDE_CONTRACTID "@mozilla.org/security/certoverride;1" +%} + +[scriptable, builtinclass, uuid(ed735e24-fa55-4163-906d-17fb78851fe1)] +interface nsICertOverride : nsISupports { + + /** + * The hostname of the server the override is used for. + */ + readonly attribute ACString asciiHost; + + /** + * The port of the server the override is used for. + */ + readonly attribute int32_t port; + + /** + * Whether or not the override is only used for this + * session (true) or stored persistently (false) + */ + readonly attribute boolean isTemporary; + + /** + * The database key for the associated certificate. + */ + readonly attribute ACString dbKey; + + /** + * A combination of hostname and port in the form host:port. + * Since the port can be -1 which is equivalent to port 433 we use an + * existing function of nsCertOverrideService to create this property. + */ + readonly attribute ACString hostPort; +}; + +/** + * This represents the global list of triples + * {host:port, cert-fingerprint, allowed-overrides} + * that the user wants to accept without further warnings. + */ +[scriptable, builtinclass, uuid(be019e47-22fc-4355-9f16-9ab047d6742d)] +interface nsICertOverrideService : nsISupports { + + /** + * Override Untrusted + */ + const short ERROR_UNTRUSTED = 1; + + /** + * Override hostname Mismatch + */ + const short ERROR_MISMATCH = 2; + + /** + * Override Time error + */ + const short ERROR_TIME = 4; + + /** + * The given cert should always be accepted for the given hostname:port, + * regardless of errors verifying the cert. + * Host:Port is a primary key, only one entry per host:port can exist. + * The implementation will store a fingerprint of the cert. + * The implementation will decide which fingerprint alg is used. + * + * Each override is specific to exactly the errors overridden, so + * overriding everything won't match certs at the given host:port + * which only exhibit some subset of errors. + * + * @param aHostName The host (punycode) this mapping belongs to + * @param aPort The port this mapping belongs to, if it is -1 then it + * is internaly treated as 443 + * @param aCert The cert that should always be accepted + * @param aOverrideBits The precise set of errors we want to be overriden + */ + [must_use] + void rememberValidityOverride(in AUTF8String aHostName, + in int32_t aPort, + in nsIX509Cert aCert, + in uint32_t aOverrideBits, + in boolean aTemporary); + + /** + * Certs with the given fingerprint should always be accepted for the + * given hostname:port, regardless of errors verifying the cert. + * Host:Port is a primary key, only one entry per host:port can exist. + * The fingerprint should be an SHA-256 hash of the certificate. + * + * @param aHostName The host (punycode) this mapping belongs to + * @param aPort The port this mapping belongs to, if it is -1 then it + * is internaly treated as 443 + * @param aCertFingerprint The cert fingerprint that should be accepted, in + * the format 'AA:BB:...' (colon-separated upper-case hex bytes). + * @param aOverrideBits The errors we want to be overriden + */ + [must_use] + void rememberTemporaryValidityOverrideUsingFingerprint( + in AUTF8String aHostName, + in int32_t aPort, + in AUTF8String aCertFingerprint, + in uint32_t aOverrideBits); + + /** + * Return whether this host, port, cert triple has a stored override. + * If so, the outparams will contain the specific errors that were + * overridden, and whether the override is permanent, or only for the current + * session. + * + * @param aHostName The host (punycode) this mapping belongs to + * @param aPort The port this mapping belongs to, if it is -1 then it + * is internally treated as 443 + * @param aCert The certificate this mapping belongs to + * @param aOverrideBits The errors that are currently overridden + * @param aIsTemporary Whether the stored override is session-only, + * or permanent + * @return Whether an override has been stored for this host+port+cert + */ + [must_use] + boolean hasMatchingOverride(in AUTF8String aHostName, + in int32_t aPort, + in nsIX509Cert aCert, + out uint32_t aOverrideBits, + out boolean aIsTemporary); + + /** + * Remove a override for the given hostname:port. + * + * @param aHostName The host (punycode) whose entry should be cleared. + * @param aPort The port whose entry should be cleared. + * If it is -1, then it is internaly treated as 443. + * If it is 0 and aHostName is "all:temporary-certificates", + * then all temporary certificates should be cleared. + */ + void clearValidityOverride(in AUTF8String aHostName, + in int32_t aPort); + + /** + * Remove all overrides. + */ + void clearAllOverrides(); + + /** + * Is the given cert used in rules? + * + * @param aCert The cert we're looking for + * @return how many override entries are currently on file + * for the given certificate + */ + [must_use] + uint32_t isCertUsedForOverrides(in nsIX509Cert aCert, + in boolean aCheckTemporaries, + in boolean aCheckPermanents); + + Array getOverrides(); + + /** + * NOTE: This function is used only for testing! + * + * @param aDisable If true, disable all security check and make + * hasMatchingOverride always return true. + */ + void setDisableAllSecurityChecksAndLetAttackersInterceptMyData(in boolean aDisable); +}; diff --git a/security/manager/ssl/nsICertStorage.idl b/security/manager/ssl/nsICertStorage.idl new file mode 100644 index 0000000000..7a82345e9d --- /dev/null +++ b/security/manager/ssl/nsICertStorage.idl @@ -0,0 +1,272 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * 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/. */ + +#include "nsISupports.idl" +#include "nsIVariant.idl" + +%{C++ +#define NS_CERTSTORAGE_CONTRACTID "@mozilla.org/security/certstorage;1" +%} + +/** + * Callback type used to notify callers that an operation performed by + * nsICertStorage has completed. Indicates the result of the requested + * operation, as well as any data returned by the operation. + */ +[scriptable, function, uuid(3f8fe26a-a436-4ad4-9c1c-a53c60973c31)] +interface nsICertStorageCallback : nsISupports { + [must_use] + void done(in nsresult rv, in nsIVariant result); +}; + +/** + * A base interface for representing the revocation state of a certificate. + * Implementing this interface by itself is insufficient; your type must + * implement an inheriting interface that specifies the certificate by issuer + * and serial number or by subject and public key hash. + * Set state to nsICertStorage.STATE_UNSET to mark the certificate as not revoked. + * Set state to nsICertStorage.STATE_ENFORCE to mark the certificate as revoked. + */ +[scriptable, uuid(96db6fd7-6b64-4a5a-955d-310bd9ca4234)] +interface nsIRevocationState : nsISupports { + readonly attribute short state; +}; + +/** + * An interface representing the revocation state of a certificate by issuer + * and serial number. Both issuer name and serial number are base64-encoded. + */ +[scriptable, uuid(23ce3546-f1b9-46f6-8de3-77704da5702f)] +interface nsIIssuerAndSerialRevocationState : nsIRevocationState { + readonly attribute ACString issuer; + readonly attribute ACString serial; +}; + +/** + * An interface representing the revocation state of a certificate by subject + * and pub key hash (the hash algorithm should be SHA-256). Both subject name + * and public key hash are base64-encoded. + */ +[scriptable, uuid(e78b51b4-6fa4-41e2-92ce-e9404f541e96)] +interface nsISubjectAndPubKeyRevocationState : nsIRevocationState { + readonly attribute ACString subject; + readonly attribute ACString pubKey; +}; + +/** + * An interface representing the CRLite enrollment state of a certificate + * identified by its subject and subject public key info hash. + * subject is a base 64-encoded DER subject distinguished name. + * spkiHash is a base 64-encoded SHA-256 hash of a DER subject public key info. + * state is nsICertStorage.STATE_ENFORCE or STATE_UNSET, meaning the certificate + * is or is not enrolled in CRLite, respectively. + */ +[scriptable, uuid(5d0d22be-185f-4cf0-b73b-c5a911273e77)] +interface nsICRLiteState : nsISupports { + readonly attribute ACString subject; + readonly attribute ACString spkiHash; + readonly attribute short state; +}; + +/** + * An interface representing a certificate to add to storage. Consists of the + * base64-encoded DER bytes of the certificate (cert), the base64-encoded DER + * bytes of the subject distinguished name of the certificate (subject), and the + * trust of the certificate (one of the nsICertStorage.TRUST_* constants). + * (Note that this implementation does not validate that the given subject DN + * actually matches the subject DN of the certificate, nor that the given cert + * is a valid DER X.509 certificate.) + */ +[scriptable, uuid(27b66f5e-0faf-403b-95b4-bc11691ac50d)] +interface nsICertInfo : nsISupports { + readonly attribute ACString cert; + readonly attribute ACString subject; + readonly attribute short trust; +}; + +[scriptable, uuid(327100a7-3401-45ef-b160-bf880f1016fd)] +interface nsICertStorage : nsISupports { + const octet DATA_TYPE_REVOCATION = 1; + const octet DATA_TYPE_CERTIFICATE = 2; + const octet DATA_TYPE_CRLITE = 3; + const octet DATA_TYPE_CRLITE_FILTER_FULL = 4; + const octet DATA_TYPE_CRLITE_FILTER_INCREMENTAL = 5; + + /** + * Asynchronously check if the backing storage has stored data of the given + * type in the past. This is useful if the backing storage may have had to + * have been deleted and recreated (as in bug 1546361 when we discovered that + * moving from a 32-bit binary to a 64-bit binary caused the DB to become + * unreadable, thus necessitating its deletion and recreation). + */ + [must_use] + void hasPriorData(in octet type, in nsICertStorageCallback callback); + + const short STATE_UNSET = 0; + const short STATE_ENFORCE = 1; + const short STATE_NOT_ENROLLED = 2; + + /** + * Asynchronously set the revocation states of a set of certificates. + * The given callback is called with the result of the operation when it + * completes. + * Must only be called from the main thread. + */ + [must_use] + void setRevocations(in Array revocations, + in nsICertStorageCallback callback); + + /** + * Get the revocation state of a certificate. STATE_UNSET indicates the + * certificate is not revoked. STATE_ENFORCE indicates the certificate is + * revoked. + * issuer - issuer name, DER encoded + * serial - serial number, DER encoded + * subject - subject name, DER encoded + * pubkey - public key, DER encoded + * Must not be called from the main thread. See bug 1541212. + */ + [must_use] + short getRevocationState(in Array issuer, + in Array serial, + in Array subject, + in Array pubkey); + + /** + * Check that the blocklist data is current. Specifically, that the current + * time is no more than security.onecrl.maximum_staleness_in_seconds seconds + * after the last blocklist update (as stored in the + * services.blocklist.onecrl.checked pref) + */ + [must_use] + boolean isBlocklistFresh(); + + /** + * Asynchronously set a batch of CRLite enrollment state. See the + * documentation for nsICRLiteState. + * Must only be called from the main thread. + */ + [must_use] + void setCRLiteState(in Array crliteState, + in nsICertStorageCallback callback); + + /** + * Get the CRLite enrollment state of a certificate identified by the given + * subject distinguished name and subject public key info (both as DER bytes). + * STATE_ENFORCE indicates the certificate is enrolled, whereas STATE_UNSET + * indicates it is not. + */ + [must_use] + short getCRLiteState(in Array subject, in Array spki); + + /** + * Given the contents of a CRLite filter and its creation date as seconds since the epoch, + * replaces any existing filter with the new one. Also clears any previously-set incremental + * revocation updates ("stashes"). + */ + [must_use] + void setFullCRLiteFilter(in Array filter, in uint64_t timestamp, + in nsICertStorageCallback callback); + + /** + * Given the DER-encoded issuer distinguished name, DER-encoded issuer subject public key info, + * and the bytes of the value of the serial number (so, not including the DER tag and length) of a + * certificate, returns the result of looking up the corresponding entry in the currently-saved + * CRLite filter (if any). Returns STATE_ENFORCE if the lookup indicates the corresponding + * certificate is revoked via CRLite. Returns STATE_UNSET if the lookup indicates the + * corresponding certificate is not revoked via CRLite. Returns STATE_NOT_ENROLLED if the issuer + * certificate is not enrolled in CRLite and thus no lookup was made. Also returns the timestamp + * before which lookups will be valid. That is, if a certificate has a notBefore value after the + * returned filter timestamp, the lookup is not trustworthy because the certificate may have been + * created after the filter, and thus it may cause a false negative or positive. If no filter is + * available (it may not have been downloaded yet), validBefore will be 0. The timestamp is + * represented as seconds since the epoch (i.e. it returns what was most recently set via + * setFullCRLiteFilter). + */ + [must_use] + short getCRLiteRevocationState(in Array issuer, + in Array issuerSPKI, + in Array serialNumber, + out uint64_t validBefore); + + /** + * Given the contents of a CRLite incremental revocation update ("stash"), adds the revocation + * information to the current set of stashed revocations. The basic unit of the stash file is an + * issuer subject public key info hash (sha-256) followed by a number of serial numbers + * corresponding to revoked certificates issued by that issuer. More specifically, each unit + * consists of: + * 4 bytes little-endian: the number of serial numbers following the issuer spki hash + * 1 byte: the length of the issuer spki hash + * issuer spki hash length bytes: the issuer spki hash + * as many times as the indicated serial numbers: + * 1 byte: the length of the serial number + * serial number length bytes: the serial number + * The stash file consists of any number of these units concatenated together. + */ + [must_use] + void addCRLiteStash(in Array stash, in nsICertStorageCallback callback); + + /** + * Given a DER-encoded issuer subject public key info and the bytes of the value of the serial + * number (so, not including the DER tag and length), determines if the certificate identified by + * this issuer SPKI and serial number is revoked according to the current set of stashed CRLite + * revocation information. + */ + [must_use] + bool isCertRevokedByStash(in Array issuerSPKI, in Array serialNumber); + + /** + * Trust flags to use when adding a adding a certificate. + * TRUST_INHERIT indicates a certificate inherits trust from another + * certificate. + * TRUST_ANCHOR indicates the certificate is a root of trust. + */ + const short TRUST_INHERIT = 0; + const short TRUST_ANCHOR = 1; + + /** + * Asynchronously add a list of certificates to the backing storage. + * See the documentation for nsICertInfo. + * The given callback is called with the result of the operation when it + * completes. + * Must only be called from the main thread. + */ + [must_use] + void addCerts(in Array certs, in nsICertStorageCallback callback); + + /** + * Asynchronously remove the certificates with the given sha-256 hashes from + * the backing storage. + * hashes is an array of base64-encoded bytes of the sha-256 hashes of each + * certificate's bytes (DER-encoded). + * The given callback is called with the result of the operation when it + * completes. + * Must only be called from the main thread. + */ + [must_use] + void removeCertsByHashes(in Array hashes, + in nsICertStorageCallback callback); + + /** + * Find all certificates in the backing storage with the given subject + * distinguished name. + * subject is the DER-encoded bytes of the subject distinguished name. + * Returns an array of arrays of bytes, where each inner array corresponds to + * the DER-encoded bytes of a certificate that has the given subject (although + * as these certificates were presumably added via addCertBySubject, this + * aspect is never actually valided by nsICertStorage). + * Must not be called from the main thread. See bug 1541212. + */ + [must_use] + Array > findCertsBySubject(in Array subject); + + /** + * Get the count of remaining async operations. Called to ensure we don't skip + * or interrupt any operations during fast shutdown. + * Must only be called from the main thread. + */ + [must_use] + int32_t GetRemainingOperationCount(); +}; diff --git a/security/manager/ssl/nsICertTree.idl b/security/manager/ssl/nsICertTree.idl new file mode 100644 index 0000000000..8b506882c3 --- /dev/null +++ b/security/manager/ssl/nsICertTree.idl @@ -0,0 +1,39 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" +#include "nsITreeView.idl" + +interface nsIX509Cert; + +[scriptable, uuid(d0180863-606e-49e6-8324-cf45ed4dd891)] +interface nsICertTreeItem : nsISupports { + [must_use] + readonly attribute nsIX509Cert cert; +}; + +[scriptable, uuid(55d5ad6b-5572-47fe-941c-f01fe723659e)] +interface nsICertTree : nsITreeView { + [must_use] + void loadCertsFromCache(in Array cache, in unsigned long type); + + [must_use] + nsIX509Cert getCert(in unsigned long index); + [must_use] + nsICertTreeItem getTreeItem(in unsigned long index); + + [must_use] + void deleteEntryObject(in unsigned long index); +}; + +%{C++ + +#define NS_CERTTREE_CID { 0x4ea60761, 0x31d6, 0x491d, \ + { 0x9e, 0x34, 0x4b, 0x53, 0xa2, 0x6c, 0x41, 0x6c } } + +#define NS_CERTTREE_CONTRACTID "@mozilla.org/security/nsCertTree;1" + +%} diff --git a/security/manager/ssl/nsICertificateDialogs.idl b/security/manager/ssl/nsICertificateDialogs.idl new file mode 100644 index 0000000000..7df24d94e0 --- /dev/null +++ b/security/manager/ssl/nsICertificateDialogs.idl @@ -0,0 +1,68 @@ +/* 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/. */ + +#include "nsISupports.idl" + +interface nsIInterfaceRequestor; +interface nsIX509Cert; + +/** + * Functions that implement user interface dialogs to manage certificates. + */ +[scriptable, uuid(da871dab-f69e-4173-ab26-99fcd47b0e85)] +interface nsICertificateDialogs : nsISupports +{ + /** + * UI shown when a user is asked to download a new CA cert. + * Provides user with ability to choose trust settings for the cert. + * Asks the user to grant permission to import the certificate. + * + * @param ctx A user interface context. + * @param cert The certificate that is about to get installed. + * @param trust A bit mask of trust flags. + * See nsIX509CertDB for possible values. + * + * @return true if the user allows to import the certificate. + */ + [must_use] + boolean confirmDownloadCACert(in nsIInterfaceRequestor ctx, + in nsIX509Cert cert, + out unsigned long trust); + + /** + * UI shown when a user's personal certificate is going to be + * exported to a backup file. + * The implementation of this dialog should make sure to prompt the user to + * type the password twice in order to confirm correct input. + * The wording in the dialog should also motivate the user to enter a strong + * password. + * + * @param ctx A user interface context. + * @param password The password provided by the user. + * + * @return false if the user requests to cancel. + */ + [must_use] + boolean setPKCS12FilePassword(in nsIInterfaceRequestor ctx, + out AString password); + + /** + * UI shown when a user is about to restore a personal + * certificate from a backup file. + * The user is requested to enter the password + * that was used in the past to protect that backup file. + * + * @param ctx A user interface context. + * @param password The password provided by the user. + * + * @return false if the user requests to cancel. + */ + [must_use] + boolean getPKCS12FilePassword(in nsIInterfaceRequestor ctx, + out AString password); +}; + +%{C++ +#define NS_CERTIFICATEDIALOGS_CONTRACTID "@mozilla.org/nsCertificateDialogs;1" +%} diff --git a/security/manager/ssl/nsIClientAuthDialogs.idl b/security/manager/ssl/nsIClientAuthDialogs.idl new file mode 100644 index 0000000000..e618ad0b73 --- /dev/null +++ b/security/manager/ssl/nsIClientAuthDialogs.idl @@ -0,0 +1,41 @@ +/* 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/. */ + +#include "nsISupports.idl" + +interface nsIArray; +interface nsIInterfaceRequestor; + +/** + * Provides UI for SSL client-auth dialogs. + */ +[scriptable, uuid(fa4c7520-1433-11d5-ba24-00108303b117)] +interface nsIClientAuthDialogs : nsISupports +{ + /** + * Called when a user is asked to choose a certificate for client auth. + * + * @param hostname Hostname of the server. + * @param port Port of the server. + * @param organization Organization field of the server cert. + * @param issuerOrg Organization field of the issuer cert of the server cert. + * @param certList List of certificates the user can choose from. + * @param selectedIndex Index of the cert in |certList| that the user chose. + * Ignored if the return value is false. + * @param rememberClientAuthCertificate Whether to remember selection. + * @return true if a certificate was chosen. false if the user canceled. + */ + [must_use] + boolean chooseCertificate(in AUTF8String hostname, + in long port, + in AUTF8String organization, + in AUTF8String issuerOrg, + in nsIArray certList, + out unsigned long selectedIndex, + out boolean rememberClientAuthCertificate); +}; + +%{C++ +#define NS_CLIENTAUTHDIALOGS_CONTRACTID "@mozilla.org/nsClientAuthDialogs;1" +%} diff --git a/security/manager/ssl/nsIClientAuthRememberService.idl b/security/manager/ssl/nsIClientAuthRememberService.idl new file mode 100644 index 0000000000..d59a800620 --- /dev/null +++ b/security/manager/ssl/nsIClientAuthRememberService.idl @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +%{C++ +#include "cert.h" +#define NS_CLIENTAUTHREMEMBERSERVICE_CONTRACTID "@mozilla.org/security/clientAuthRememberService;1" +%} + +[ptr] native CERTCertificatePtr(CERTCertificate); +[ref] native const_OriginAttributesRef(const mozilla::OriginAttributes); + +[scriptable, uuid(e92825af-7e81-4b5c-b412-8e1dd36d14fe)] +interface nsIClientAuthRememberRecord : nsISupports +{ + + readonly attribute ACString asciiHost; + + readonly attribute ACString fingerprint; + + readonly attribute ACString dbKey; + + readonly attribute ACString entryKey; + +}; + + +[scriptable, uuid(1dbc6eb6-0972-4bdb-9dc4-acd0abf72369)] +interface nsIClientAuthRememberService : nsISupports +{ + + [must_use] + void forgetRememberedDecision(in ACString key); + + + [must_use] + Array getDecisions(); + + [must_use, noscript] + void rememberDecision(in ACString aHostName, + in const_OriginAttributesRef aOriginAttributes, + in CERTCertificatePtr aServerCert, + in CERTCertificatePtr aClientCert); + + [must_use, noscript] + bool hasRememberedDecision(in ACString aHostName, + in const_OriginAttributesRef aOriginAttributes, + in CERTCertificatePtr aServerCert, + out ACString aCertDBKey); + + [must_use] + void clearRememberedDecisions(); + + [implicit_jscontext] + void deleteDecisionsByHost(in ACString aHostName, + in jsval aOriginAttributes); + +}; diff --git a/security/manager/ssl/nsIContentSignatureVerifier.idl b/security/manager/ssl/nsIContentSignatureVerifier.idl new file mode 100644 index 0000000000..24a44c7b69 --- /dev/null +++ b/security/manager/ssl/nsIContentSignatureVerifier.idl @@ -0,0 +1,39 @@ +/* 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/. */ + + +#include "nsISupports.idl" + +interface nsIContentSignatureReceiverCallback; + +/** + * An interface for verifying content-signatures, inspired by + * https://tools.ietf.org/html/draft-thomson-http-content-signature-00 + * described here https://github.com/franziskuskiefer/content-signature/tree/pki + */ +[scriptable, uuid(45a5fe2f-c350-4b86-962d-02d5aaaa955a)] +interface nsIContentSignatureVerifier : nsISupports +{ + + /** + * Verifies that the data matches the data that was used to generate the + * signature. + * + * @param aData The data to be tested. + * @param aContentSignatureHeader The content-signature header, + * url-safe base64 encoded. + * @param aCertificateChain The certificate chain to use for verification. + * PEM encoded string. + * @param aHostname The hostname for which the end entity must + be valid. + * @returns Promise that resolves with the value true if the signature + * matches the data and aCertificateChain is valid within aContext, + * and false if not. Rejects if another error occurred. + */ + [implicit_jscontext, must_use] + Promise asyncVerifyContentSignature(in ACString aData, + in ACString aContentSignatureHeader, + in ACString aCertificateChain, + in ACString aHostname); +}; diff --git a/security/manager/ssl/nsICryptoHMAC.idl b/security/manager/ssl/nsICryptoHMAC.idl new file mode 100644 index 0000000000..671d97c311 --- /dev/null +++ b/security/manager/ssl/nsICryptoHMAC.idl @@ -0,0 +1,106 @@ +/* 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/. */ + +#include "nsISupports.idl" +interface nsIInputStream; +interface nsIKeyObject; + +/** + * nsICryptoHMAC + * This interface provides HMAC signature algorithms. + */ + +[scriptable, uuid(8FEB4C7C-1641-4a7b-BC6D-1964E2099497)] +interface nsICryptoHMAC : nsISupports +{ + /** + * Hashing Algorithms. These values are to be used by the |init| method to + * indicate which hashing function to use. These values map onto the values + * defined in mozilla/security/nss/lib/softoken/pkcs11t.h and are switched + * to a CKM_*_HMAC constant. + */ + // 1 used to mean MD2. + const short MD5 = 2; + const short SHA1 = 3; + const short SHA256 = 4; + const short SHA384 = 5; + const short SHA512 = 6; + + /** + * Initialize the hashing object. This method may be + * called multiple times with different algorithm types. + * + * @param aAlgorithm the algorithm type to be used. + * This value must be one of the above valid + * algorithm types. + * + * @param aKeyObject + * Object holding a key. To create the key object use for instance: + * var keyObject = Components.classes["@mozilla.org/security/keyobjectfactory;1"] + * .getService(Components.interfaces.nsIKeyObjectFactory) + * .keyFromString(Components.interfaces.nsIKeyObject.HMAC, rawKeyData); + * + * WARNING: This approach is not FIPS compliant. + * + * @throws NS_ERROR_INVALID_ARG if an unsupported algorithm + * type is passed. + * + * NOTE: This method must be called before any other method on this + * interface is called. + */ + [must_use] + void init(in unsigned long aAlgorithm, in nsIKeyObject aKeyObject); + + /** + * @param aData a buffer to calculate the hash over + * + * @param aLen the length of the buffer |aData| + * + * @throws NS_ERROR_NOT_INITIALIZED If |init| has not been called. + */ + [must_use] + void update([const, array, size_is(aLen)] in octet aData, in unsigned long aLen); + + /** + * Calculates and updates a new hash based on a given data stream. + * + * @param aStream an input stream to read from. + * + * @param aLen How much to read from the given |aStream|. Passing UINT32_MAX + * indicates that all data available will be used to update the hash. + * + * @throws NS_ERROR_NOT_INITIALIZED If |init| has not been called. + * + * @throws NS_ERROR_NOT_AVAILABLE If the requested amount of data to be + * calculated into the hash is not available. + * + */ + [must_use] + void updateFromStream(in nsIInputStream aStream, in unsigned long aLen); + + /** + * Completes this HMAC object and produces the actual HMAC digest data. + * + * @param aASCII If true then the returned value is a base64 encoded string. + * If false, then the returned value is binary data. + * + * @return a hash of the data that was read by this object. This can + * be either binary data or base 64 encoded. + * + * @throws NS_ERROR_NOT_INITIALIZED If |init| has not been called. + * + * NOTE: This method may be called any time after |init| + * is called. This call resets the object to its + * pre-init state. + */ + [must_use] + ACString finish(in boolean aASCII); + + /** + * Reinitialize HMAC context to be reused with the same settings (the key + * and hash algorithm) but on a different set of data. + */ + [must_use] + void reset(); +}; diff --git a/security/manager/ssl/nsICryptoHash.idl b/security/manager/ssl/nsICryptoHash.idl new file mode 100644 index 0000000000..99a6f4d86d --- /dev/null +++ b/security/manager/ssl/nsICryptoHash.idl @@ -0,0 +1,103 @@ +/* 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/. */ + +#include "nsISupports.idl" +interface nsIInputStream; + +/** + * nsICryptoHash + * This interface provides crytographic hashing algorithms. + */ + +[builtinclass, scriptable, uuid(1e5b7c43-4688-45ce-92e1-77ed931e3bbe)] +interface nsICryptoHash : nsISupports +{ + /** + * Hashing Algorithms. These values are to be used by the + * |init| method to indicate which hashing function to + * use. These values must be identical to the values defined + * in security/nss/lib/util/hasht.h in type HASH_HashType. + * This allows us to use NSS mapping functions like + * HASH_GetHashOidTagByHashType with these values. + */ + const short MD5 = 2; /* String value: "md5" */ + const short SHA1 = 3; /* String value: "sha1" */ + const short SHA256 = 4; /* String value: "sha256" */ + const short SHA384 = 5; /* String value: "sha384" */ + const short SHA512 = 6; /* String value: "sha512" */ + + /** + * Initialize the hashing object. This method may be + * called multiple times with different algorithm types. + * + * @param aAlgorithm the algorithm type to be used. + * This value must be one of the above valid + * algorithm types. + * + * @throws NS_ERROR_INVALID_ARG if an unsupported algorithm + * type is passed. + * + * NOTE: This method or initWithString must be called + * before any other method on this interface is called. + */ + void init(in unsigned long aAlgorithm); + + /** + * Initialize the hashing object. This method may be + * called multiple times with different algorithm types. + * + * @param aAlgorithm the algorithm type to be used. + * + * @throws NS_ERROR_INVALID_ARG if an unsupported algorithm + * type is passed. + * + * NOTE: This method or init must be called before any + * other method on this interface is called. + */ + [must_use] + void initWithString(in ACString aAlgorithm); + + /** + * @param aData a buffer to calculate the hash over + * + * @param aLen the length of the buffer |aData| + * + * @throws NS_ERROR_NOT_INITIALIZED If |init| has not been called. + */ + void update([const, array, size_is(aLen)] in octet aData, in unsigned long aLen); + + /** + * Calculates and updates a new hash based on a given data stream. + * + * @param aStream an input stream to read from. + * + * @param aLen How much to read from the given |aStream|. Passing UINT32_MAX + * indicates that all data available will be used to update the hash. + * + * @throws NS_ERROR_NOT_INITIALIZED If |init| has not been called. + * + * @throws NS_ERROR_NOT_AVAILABLE If the requested amount of + * data to be calculated into the hash is not available. + * + */ + [must_use] + void updateFromStream(in nsIInputStream aStream, in unsigned long aLen); + + /** + * Completes this hash object and produces the actual hash data. + * + * @param aASCII If true then the returned value is a base64 encoded string. + * If false, then the returned value is binary data. + * + * @return a hash of the data that was read by this object. This can + * be either binary data or base 64 encoded. + * + * @throws NS_ERROR_NOT_INITIALIZED If |init| has not been called. + * + * NOTE: This method may be called any time after |init| + * is called. This call resets the object to its + * pre-init state. + */ + ACString finish(in boolean aASCII); +}; diff --git a/security/manager/ssl/nsIKeyModule.idl b/security/manager/ssl/nsIKeyModule.idl new file mode 100644 index 0000000000..6fb0b0d57e --- /dev/null +++ b/security/manager/ssl/nsIKeyModule.idl @@ -0,0 +1,41 @@ +/* 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/. */ + +#include "nsISupports.idl" + +%{ C++ + /* forward declaration */ + typedef struct PK11SymKeyStr PK11SymKey; +%} +[ptr] native PK11SymKeyPtr(PK11SymKey); + +// An opaque key object. +[scriptable, uuid(ee2dc516-ba7b-4e77-89fe-c43b886ef715)] +interface nsIKeyObject : nsISupports +{ + // Key types + const short SYM_KEY = 1; + + // Algorithm types + const short HMAC = 257; + + // The nsIKeyObject will take ownership of the key and be responsible + // for freeing the key memory when destroyed. + [noscript, must_use] + void initKey(in short aAlgorithm, in PK11SymKeyPtr aKey); + + // Returns a pointer to the underlying key object. + [noscript, must_use] + PK11SymKeyPtr getKeyObj(); + + [must_use] + short getType(); +}; + +[scriptable, uuid(838bdbf1-8244-448f-8bcd-cede70227d75)] +interface nsIKeyObjectFactory : nsISupports +{ + [must_use] + nsIKeyObject keyFromString(in short aAlgorithm, in ACString aKey); +}; diff --git a/security/manager/ssl/nsILocalCertService.idl b/security/manager/ssl/nsILocalCertService.idl new file mode 100644 index 0000000000..6d05be5195 --- /dev/null +++ b/security/manager/ssl/nsILocalCertService.idl @@ -0,0 +1,72 @@ +/* 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/. */ + +#include "nsISupports.idl" + +interface nsIX509Cert; +interface nsILocalCertGetCallback; +interface nsILocalCertCallback; + +[scriptable, uuid(9702fdd4-4c2c-439c-ba2e-19cda018eb99)] +interface nsILocalCertService : nsISupports +{ + /** + * Get or create a new self-signed X.509 cert to represent this device over a + * secure transport, like TLS. + * + * The cert is stored permanently in the profile's key store after first use, + * and is valid for 1 year. If an expired or otherwise invalid cert is found + * with the nickname supplied here, it is removed and a new one is made. + * + * @param nickname Nickname that identifies the cert + * @param cb Callback to be notified with the result + */ + [must_use] + void getOrCreateCert(in ACString nickname, in nsILocalCertGetCallback cb); + + /** + * Remove a X.509 cert with the given nickname. + * + * @param nickname Nickname that identifies the cert + * @param cb Callback to be notified with the result + */ + [must_use] + void removeCert(in ACString nickname, in nsILocalCertCallback cb); + + /** + * Whether calling |getOrCreateCert| or |removeCert| will trigger a login + * prompt to be displayed. Generally this happens if the user has set a + * master password, but has not yet logged in. + */ + [must_use] + readonly attribute boolean loginPromptRequired; +}; + +[scriptable, uuid(cc09633e-7c70-4093-a9cf-79ab676ca8a9)] +interface nsILocalCertGetCallback : nsISupports +{ + /** + * Called with the result of the getOrCreateCert operation above. + * + * @param cert Requested cert, or null if some error + * @param result Result code from the get operation + */ + void handleCert(in nsIX509Cert cert, in nsresult result); +}; + +[scriptable, uuid(518124e9-55e6-4e23-97c0-4995b3a1bec6)] +interface nsILocalCertCallback : nsISupports +{ + /** + * Called with the result of the removeCert operation above. + * + * @param result Result code from the operation + */ + void handleResult(in nsresult result); +}; + +%{ C++ +#define LOCALCERTSERVICE_CONTRACTID \ + "@mozilla.org/security/local-cert-service;1" +%} diff --git a/security/manager/ssl/nsINSSComponent.idl b/security/manager/ssl/nsINSSComponent.idl new file mode 100644 index 0000000000..6f8ece0bdd --- /dev/null +++ b/security/manager/ssl/nsINSSComponent.idl @@ -0,0 +1,114 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +%{C++ +#include "cert.h" +#include "SharedCertVerifier.h" +#define PSM_COMPONENT_CONTRACTID "@mozilla.org/psm;1" +%} + +[ptr] native CERTCertificatePtr(CERTCertificate); +[ptr] native SharedCertVerifierPtr(mozilla::psm::SharedCertVerifier); + +[scriptable, uuid(a0a8f52b-ea18-4abc-a3ca-eccf704ffe63)] +interface nsINSSComponent : nsISupports { + /** + * When we log out of a PKCS#11 token, any TLS connections that may have + * involved a client certificate stored on that token must be closed. Since we + * don't have a fine-grained way to do this, we basically cancel everything. + * More speficially, this clears all temporary certificate exception overrides + * and any remembered client authentication certificate decisions, and then + * cancels all network connections (strictly speaking, this last part is + * overzealous - we only need to cancel all https connections (see bug + * 1446645)). + */ + [noscript] void logoutAuthenticatedPK11(); + + /** + * Used to determine if the given CERTCertificate is the certificate we use in + * tests to simulate a built-in root certificate. Returns false in non-debug + * builds. + */ + [noscript] bool isCertTestBuiltInRoot(in CERTCertificatePtr cert); + + /** + * Used to determine if the given certificate (represented as an array of + * bytes) is the content signing root certificate. + */ + [noscript] bool isCertContentSigningRoot(in Array cert); + + /** + * If enabled by the preference "security.enterprise_roots.enabled", returns + * an array of arrays of bytes representing the imported enterprise root + * certificates (i.e. root certificates gleaned from the OS certificate + * store). Returns an empty array otherwise. + * Currently this is only implemented on Windows and MacOS X, so this + * function returns an empty array on all other platforms. + */ + Array > getEnterpriseRoots(); + + /** + * Similarly, but for intermediate certificates. + */ + Array > getEnterpriseIntermediates(); + + /** + * Test utility for adding an intermediate certificate to the current set of + * imported enterprise intermediates, if any. Additions to the set made using + * this function will be cleared when the value of the preference + * "security.enterprise_roots.enabled" changes. + */ + void addEnterpriseIntermediate(in Array intermediateBytes); + + /** + * For performance reasons, the builtin roots module is loaded on a background + * thread. When any code that depends on the builtin roots module runs, it + * must first wait for the module to be loaded. + */ + [noscript] void blockUntilLoadableCertsLoaded(); + + /** + * In theory a token on a PKCS#11 module can be inserted or removed at any + * time. Operations that may depend on resources on external tokens should + * call this to ensure they have a recent view of the token. + */ + [noscript] void checkForSmartCardChanges(); + + /** + * Used to potentially detect when a user's internet connection is being + * intercepted. When doing an update ping, if certificate verification fails, + * we make a note of the issuer distinguished name of that certificate. + * If a subsequent certificate verification fails, we compare issuer + * distinguished names. If they match, something may be intercepting the + * user's traffic (if they don't match, the server is likely misconfigured). + * This function succeeds if the given DN matches the noted DN and fails + * otherwise (e.g. if the update ping never failed). + */ + [noscript] void issuerMatchesMitmCanary(in string certIssuer); + + /** + * Returns true if the user has a PKCS#11 module with removable slots. + */ + [noscript] bool hasActiveSmartCards(); + + /** + * Returns true if the user has any client authentication certificates. + */ + [noscript] bool hasUserCertsInstalled(); + + /** + * Returns an already-adrefed handle to the currently configured shared + * certificate verifier. + */ + [noscript] SharedCertVerifierPtr getDefaultCertVerifier(); + + /** + * For clearing both SSL internal and external session cache from JS. + */ + void clearSSLExternalAndInternalSessionCache(); +}; diff --git a/security/manager/ssl/nsINSSErrorsService.idl b/security/manager/ssl/nsINSSErrorsService.idl new file mode 100644 index 0000000000..e68cba3a05 --- /dev/null +++ b/security/manager/ssl/nsINSSErrorsService.idl @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +[scriptable, uuid(12f60021-e14b-4020-99d1-ed2c795be66a)] +interface nsINSSErrorsService : nsISupports +{ + /** + * @param aNSPRCode An error code obtained using PR_GetError() + * @return True if it is error code defined by the NSS library + */ + [must_use] + boolean isNSSErrorCode(in int32_t aNSPRCode); + + /** + * Function will fail if aNSPRCode is not an NSS error code. + * @param aNSPRCode An error code obtained using PR_GetError() + * @return The result of the conversion, an XPCOM error code + */ + [must_use] + nsresult getXPCOMFromNSSError(in int32_t aNSPRCode); + + /** + * Function will fail if aXPCOMErrorCode is not an NSS error code. + * @param aXPCOMErrorCode An error code obtained using getXPCOMFromNSSError + * return A localized human readable error explanation. + */ + AString getErrorMessage(in nsresult aXPCOMErrorCode); + + /** + * Function will fail if aXPCOMErrorCode is not an NSS error code. + * @param aXPCOMErrorCode An error code obtained using getXPCOMFromNSSError + * return the error class of the code, either ERROR_CLASS_BAD_CERT + * or ERROR_CLASS_SSL_PROTOCOL + */ + [must_use] + uint32_t getErrorClass(in nsresult aXPCOMErrorCode); + + const unsigned long ERROR_CLASS_SSL_PROTOCOL = 1; + const unsigned long ERROR_CLASS_BAD_CERT = 2; + + /** + * The following values define the range of NSPR error codes used by NSS. + * NSS remains the authorative source for these numbers, as a result, + * the values might change in the future. + * The security module will perform a runtime check and assertion + * to ensure the values are in synch with NSS. + */ + const long NSS_SEC_ERROR_BASE = -(0x2000); + const long NSS_SEC_ERROR_LIMIT = (NSS_SEC_ERROR_BASE + 1000); + const long NSS_SSL_ERROR_BASE = -(0x3000); + const long NSS_SSL_ERROR_LIMIT = (NSS_SSL_ERROR_BASE + 1000); + + /** + * The error codes within each module must fit in 16 bits. We want these + * errors to fit in the same module as the NSS errors but not overlap with + * any of them. Converting an NSS SEC, NSS SSL, or mozilla::pkix error to + * an NS error involves negating the value of the error and then + * synthesizing an error in the NS_ERROR_MODULE_SECURITY module. Hence, + * mozilla::pkix errors will start at a negative value that both doesn't + * overlap with the current value ranges for NSS errors and that will fit + * in 16 bits when negated. + * + * Keep these in sync with pkixnss.h. + */ + const long MOZILLA_PKIX_ERROR_BASE = -(0x4000); + const long MOZILLA_PKIX_ERROR_LIMIT = (MOZILLA_PKIX_ERROR_BASE + 1000); +}; diff --git a/security/manager/ssl/nsINSSVersion.idl b/security/manager/ssl/nsINSSVersion.idl new file mode 100644 index 0000000000..000f221e61 --- /dev/null +++ b/security/manager/ssl/nsINSSVersion.idl @@ -0,0 +1,37 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "nsISupports.idl" + +%{C++ +#define NS_NSSVERSION_CONTRACTID "@mozilla.org/security/nssversion;1" +%} + +[scriptable, uuid(a8a53a2b-75cc-4c68-a9bb-9791dbddaa00)] +interface nsINSSVersion : nsISupports { + /* Minimal required versions as used at build time */ + [must_use] + readonly attribute AString NSPR_MinVersion; + [must_use] + readonly attribute AString NSS_MinVersion; + [must_use] + readonly attribute AString NSSUTIL_MinVersion; + [must_use] + readonly attribute AString NSSSSL_MinVersion; + [must_use] + readonly attribute AString NSSSMIME_MinVersion; + + /* Versions of libraries currently in use */ + [must_use] + readonly attribute AString NSPR_Version; + [must_use] + readonly attribute AString NSS_Version; + [must_use] + readonly attribute AString NSSUTIL_Version; + [must_use] + readonly attribute AString NSSSSL_Version; + [must_use] + readonly attribute AString NSSSMIME_Version; +}; diff --git a/security/manager/ssl/nsIOSKeyStore.idl b/security/manager/ssl/nsIOSKeyStore.idl new file mode 100644 index 0000000000..478f852d2b --- /dev/null +++ b/security/manager/ssl/nsIOSKeyStore.idl @@ -0,0 +1,144 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "nsISupports.idl" + +[scriptable, uuid(57972956-5718-42d2-8070-b3fc72212eaf)] +interface nsIOSKeyStore: nsISupports { + /** + * This interface provides encryption and decryption operations for data at + * rest. The key used to encrypt and decrypt the data is stored in the OS + * key store. + * + * Usage: + * + * // obtain the singleton OSKeyStore instance + * const oskeystore = Cc["@mozilla.org/security/oskeystore;1"].getService(Ci.nsIOSKeyStore); + * + * const PASSWORD_LABEL = "mylabel1"; + * const COOKIE_LABEL = "mylabel2"; + * + * // Unlock the key store. + * // Note that this is not necesssary. The key store will be unlocked + * // automatically when an operation is performed on it. + * await oskeystore.asyncUnlock(); + * + * // Check if there's a secret for your label already. + * if (!await oskeystore.asyncSecretAvailable(PASSWORD_LABEL)) { + * // Fail or generate a new secret for your label. + * // If you want to generate a new secret, do. + * // Hold onto `recoveryPhrase` to present to the user. + * let recoveryPhrase = await oskeystore.asyncGenerateSecret(PASSWORD_LABEL); + * } + * + * // Assuming there's a secret with your label. Encrypt/Decrypt as follows. + * let encryptedPasswordBytes = await oskeystore.asyncEncryptBytes(PASSWORD_LABEL, passwordBytes); + * let newPasswordBytes = await oskeystore.asyncDecryptBytes(PASSWORD_LABEL, encryptedPasswordBytes); + * + * // Delete the secret from the key store. + * await oskeystore.asyncDeleteSecret(PASSWORD_LABEL); + * + * // Recover a secret from a recovery code. + * await oskeystore.asyncRecoverSecret(PASSWORD_LABEL, recoveryPhrase); + * + * // Lock the key store to prompt the user to log into her OS key store again. + * await oskeystore.asyncLock(); + */ + + /** + * Generate a new secret and store it in the OS key store with the given label. + * The caller should make sure that no other secrets with the same label are + * present before calling this function. + * This invalidates all previous ciphertexts created with the key + * corresponding to the given label. + * + * @param label The label to use for the secret. + * @return Promise that resolves to the recoveryPhrase string used to generate + * the secret. + */ + [implicit_jscontext, must_use] + Promise asyncGenerateSecret(in ACString label); + + /** + * Check whether a secret for a given label exists. + * + * @param label The label to lookup. + * @return Promise that resolves to a bool (whether a secret with label is + * known or not) or an error. + */ + [implicit_jscontext, must_use] + Promise asyncSecretAvailable(in ACString label); + + /** + * Set a secret from a given recovery phrase. + * This might not be implemented on all platforms. + * This invalidates all previous ciphertexts. + * + * @param label The label to use for the secret. + * @param recoveryPhrase The recovery phrase that's used to generate the secret. + * @return Promise that resolves to undefined or an error. + */ + [implicit_jscontext, must_use] + Promise asyncRecoverSecret(in ACString label, in ACString recoveryPhrase); + + /** + * Delete secret with a given label. If there is no secret with the given + * label, no action is taken. + * + * @param label The label of the secret to delete. + * @return Promise that resolves to undefined or an error. + */ + [implicit_jscontext, must_use] + Promise asyncDeleteSecret(in ACString label); + + + /** + * Encrypt the given data and then return the result as a base64-encoded + * string. + * + * @param label The label of the key to use to encrypt. + * @param inBytes The bytes to encrypt. + * @return Promise resolving to the encrypted text, encoded as Base64, or an + * error. + */ + [implicit_jscontext, must_use] + Promise asyncEncryptBytes(in ACString label, in Array inBytes); + + /** + * Decode and then decrypt the given base64-encoded string. + * + * @param label The label of the key to use to decrypt. + * @param encryptedBase64Text Encrypted input text, encoded as Base64. + * @return Promise resolving to the plaintext bytes or an error. + */ + [implicit_jscontext, must_use] + Promise asyncDecryptBytes(in ACString label, in ACString encryptedBase64Text); + + /** + * Lock the key store. + * The actual behaviour of this depends on the OS. + * + * @return Promise resolving to undefined or an error. + */ + [implicit_jscontext, must_use] + Promise asyncLock(); + + /** + * Unlock the key store. + * The actual behaviour of this depends on the OS. + * + * @return Promise resolving to undefined or an error. + */ + [implicit_jscontext, must_use] + Promise asyncUnlock(); + + + /** + * Check if the implementation is using the NSS key store. + * This is a special case because Firefox has to handle the locking and + * unlocking. + */ + readonly attribute bool isNSSKeyStore; +}; diff --git a/security/manager/ssl/nsIOSReauthenticator.idl b/security/manager/ssl/nsIOSReauthenticator.idl new file mode 100644 index 0000000000..753322ced5 --- /dev/null +++ b/security/manager/ssl/nsIOSReauthenticator.idl @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "nsISupports.idl" + +interface mozIDOMWindow; + +[scriptable, uuid(4fe082ae-6ff0-4b41-b24f-eaa664f6e46a)] +interface nsIOSReauthenticator: nsISupports { + /** + * This interface provides an abstract way to request that the user + * reauthenticate themselves to the operating system. It may be useful in + * conjunction with nsIOSKeyStore, whereby consumers of these APIs may + * consider some secrets too sensitive to access without first + * reauthenticating the user. + * + * Usage: + * + * // obtain the singleton nsIOSReauthenticator instance + * const reauthenticator = Cc["@mozilla.org/security/osreauthenticator;1"] + * .getService(Ci.nsIOSReauthenticator); + * if (await reauthenticator.asyncReauthenticate()) { + * // do something only authenticated users are allowed to do... + * } else { + * // show a "sorry, this isn't allowed" error + * } + */ + + /** + * Asynchronously cause the operating system to request that the user + * reauthenticate. This is typically in the form of a dialog box asking the + * user for their login password. The actual behaviour of this depends on the + * OS. + * + * @param prompt A short string that may be incorporated in the dialog + * @param caption A short string that may be shown as the dialog caption (usually Product Name) + * @param parentWindow Used to associate the OS dialog with the calling window. + * @return Promise resolving to true if the user successfully authenticated + * and false otherwise. + */ + [implicit_jscontext, must_use] + Promise asyncReauthenticateUser(in AString prompt, in AString caption, in mozIDOMWindow parentWindow); +}; diff --git a/security/manager/ssl/nsIPK11Token.idl b/security/manager/ssl/nsIPK11Token.idl new file mode 100644 index 0000000000..ae8fc2e994 --- /dev/null +++ b/security/manager/ssl/nsIPK11Token.idl @@ -0,0 +1,81 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +[scriptable, uuid(51191434-1dd2-11b2-a17c-e49c4e99a4e3)] +interface nsIPK11Token : nsISupports +{ + /* + * The name of the token + */ + [must_use] + readonly attribute AUTF8String tokenName; + [must_use] + readonly attribute boolean isInternalKeyToken; + /** + * Manufacturer ID of the token. + */ + [must_use] + readonly attribute AUTF8String tokenManID; + /** + * Hardware version of the token. + */ + [must_use] + readonly attribute AUTF8String tokenHWVersion; + /** + * Firmware version of the token. + */ + [must_use] + readonly attribute AUTF8String tokenFWVersion; + [must_use] + readonly attribute AUTF8String tokenSerialNumber; + + /* + * Login information + */ + [must_use] + boolean isLoggedIn(); + [must_use] + void login(in boolean force); + [must_use] + void logoutSimple(); + [must_use] + void logoutAndDropAuthenticatedResources(); + [must_use] + boolean needsLogin(); + [must_use] + readonly attribute boolean needsUserInit; + + /* + * Reset password + */ + [must_use] + void reset(); + + /** + * Checks whether the given password is correct. Logs the token out if an + * incorrect password is given. + * + * @param password The password to check. + * @return true if the password was correct, false otherwise. + */ + [must_use] + boolean checkPassword(in AUTF8String password); + [must_use] + void initPassword(in AUTF8String initialPassword); + [must_use] + void changePassword(in AUTF8String oldPassword, in AUTF8String newPassword); + + /* + * True if a password has been configured for this token, and false otherwise. + * (Whether or not the user is currently logged in makes no difference.) + * In particular, this can be used to determine if a user has set a master + * password (if this is the internal key token). + */ + [must_use] + readonly attribute boolean hasPassword; +}; diff --git a/security/manager/ssl/nsIPK11TokenDB.idl b/security/manager/ssl/nsIPK11TokenDB.idl new file mode 100644 index 0000000000..c493e0c57c --- /dev/null +++ b/security/manager/ssl/nsIPK11TokenDB.idl @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +interface nsIPK11Token; + +/** + * The PK11 Token Database provides access to the PK11 modules + * that are installed, and the tokens that are available. + * Interfaces: nsIPK11TokenDB + * Threading: ?? + */ +%{C++ +#define NS_PK11TOKENDB_CONTRACTID "@mozilla.org/security/pk11tokendb;1" +%} + +/** + * nsIPK11TokenDB - Manages PK11 Tokens + */ +[scriptable, uuid(4ee28c82-1dd2-11b2-aabf-bb4017abe395)] +interface nsIPK11TokenDB : nsISupports +{ + /* + * Get the internal key database token + */ + nsIPK11Token getInternalKeyToken(); +}; diff --git a/security/manager/ssl/nsIPKCS11Module.idl b/security/manager/ssl/nsIPKCS11Module.idl new file mode 100644 index 0000000000..0446b7ddaa --- /dev/null +++ b/security/manager/ssl/nsIPKCS11Module.idl @@ -0,0 +1,21 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +interface nsIPKCS11Slot; +interface nsISimpleEnumerator; + +[scriptable, uuid(8a44bdf9-d1a5-4734-bd5a-34ed7fe564c2)] +interface nsIPKCS11Module : nsISupports +{ + [must_use] + readonly attribute AUTF8String name; + [must_use] + readonly attribute AUTF8String libName; + [must_use] + nsISimpleEnumerator listSlots(); +}; diff --git a/security/manager/ssl/nsIPKCS11ModuleDB.idl b/security/manager/ssl/nsIPKCS11ModuleDB.idl new file mode 100644 index 0000000000..9221fd26c6 --- /dev/null +++ b/security/manager/ssl/nsIPKCS11ModuleDB.idl @@ -0,0 +1,40 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +interface nsIPKCS11Module; +interface nsIPKCS11Slot; +interface nsISimpleEnumerator; + +%{C++ +#define NS_PKCS11MODULEDB_CONTRACTID "@mozilla.org/security/pkcs11moduledb;1" +%} + +[scriptable, uuid(ff9fbcd7-9517-4334-b97a-ceed78909974)] +interface nsIPKCS11ModuleDB : nsISupports +{ + [must_use] + void deleteModule(in AString moduleName); + + [must_use] + void addModule(in AString moduleName, + in AString libraryFullPath, + in long cryptoMechanismFlags, + in long cipherFlags); + + [must_use] + nsISimpleEnumerator listModules(); + + [must_use] + readonly attribute boolean canToggleFIPS; + + [must_use] + void toggleFIPSMode(); + + [must_use] + readonly attribute boolean isFIPSEnabled; +}; diff --git a/security/manager/ssl/nsIPKCS11Slot.idl b/security/manager/ssl/nsIPKCS11Slot.idl new file mode 100644 index 0000000000..20c82729c1 --- /dev/null +++ b/security/manager/ssl/nsIPKCS11Slot.idl @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +interface nsIPK11Token; + +[scriptable, uuid(c2d4f296-ee60-11d4-998b-00b0d02354a0)] +interface nsIPKCS11Slot : nsISupports { + [must_use] + readonly attribute AUTF8String name; + [must_use] + readonly attribute AUTF8String desc; + /** + * Manufacturer ID of the slot. + */ + [must_use] + readonly attribute AUTF8String manID; + /** + * Hardware version of the slot. + */ + [must_use] + readonly attribute AUTF8String HWVersion; + /** + * Firmware version of the slot. + */ + [must_use] + readonly attribute AUTF8String FWVersion; + + const unsigned long SLOT_DISABLED = 0; + const unsigned long SLOT_NOT_PRESENT = 1; + const unsigned long SLOT_UNINITIALIZED = 2; + const unsigned long SLOT_NOT_LOGGED_IN = 3; + const unsigned long SLOT_LOGGED_IN = 4; + const unsigned long SLOT_READY = 5; + [must_use] + readonly attribute unsigned long status; + + /* This is really a workaround for now. All of the "slot" functions + * (isTokenPresent(), etc.) are in nsIPK11Token. For now, return the + * token and handle those things there. + */ + [must_use] + nsIPK11Token getToken(); + + /* more fun with workarounds - we're referring to everything by token name */ + [must_use] + readonly attribute AUTF8String tokenName; +}; diff --git a/security/manager/ssl/nsIProtectedAuthThread.idl b/security/manager/ssl/nsIProtectedAuthThread.idl new file mode 100644 index 0000000000..3979797c0c --- /dev/null +++ b/security/manager/ssl/nsIProtectedAuthThread.idl @@ -0,0 +1,48 @@ +/* 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/. */ + +#include "nsISupports.idl" +#include "nsIObserver.idl" +#include "nsIPKCS11Slot.idl" + +/** + * Used to communicate with the thread for logging on to a token with + * CKF_PROTECTED_AUTHENTICATION_PATH set. + */ +[scriptable, uuid(4bb27cb7-8984-4cee-8ce7-9b014c3d091b)] +interface nsIProtectedAuthThread : nsISupports +{ + /** + * login - run the thread + * A user interface implementing this interface needs to + * call this method as soon as the message to the user is + * displayed. This will trigger login operation. No user + * cancellation is possible during login operation. + * + * When the login is done, the observe method of @observer will + * be called on the UI thread with a topic of "login-finished" + * and null data and subject. + */ + [must_use] + void login(in nsIObserver observer); + + /** + * The PKCS11 slot + */ + [must_use] + readonly attribute nsIPKCS11Slot slot; + + /** + * Gets token to be logged in name. + */ + [must_use] + AString getTokenName(); +}; + +%{ C++ +// {45334489-3D30-47c6-920B-0A55A313AEBF} +#define NS_PROTECTEDAUTHTHREAD_CID \ +{ 0x45334489, 0x3d30, 0x47c6, { 0x92, 0x0b, 0x0a, 0x55, 0xa3, 0x13, 0xae, 0xbf } } +#define NS_PROTECTEDAUTHTHREAD_CONTRACTID "@mozilla.org/security/protectedauththread;1" +%} diff --git a/security/manager/ssl/nsISecretDecoderRing.idl b/security/manager/ssl/nsISecretDecoderRing.idl new file mode 100644 index 0000000000..caa70b2f3b --- /dev/null +++ b/security/manager/ssl/nsISecretDecoderRing.idl @@ -0,0 +1,77 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "nsISupports.idl" + +[scriptable, uuid(0EC80360-075C-11d4-9FD4-00C04F1B83D8)] +interface nsISecretDecoderRing: nsISupports { + /** + * Encrypt to Base64 output. + * Note that the input must basically be a byte array (i.e. the code points + * must be within the range [0, 255]). Hence, using this method directly to + * encrypt passwords (or any text, really) won't work as expected. + * Instead, use something like nsIScriptableUnicodeConverter to first convert + * the desired password or text to UTF-8, then encrypt that. Remember to + * convert back when calling decryptString(). + * + * @param text The text to encrypt. + * @return The encrypted text, encoded as Base64. + */ + [must_use] + ACString encryptString(in ACString text); + + /** + * Run encryptString on multiple strings, asynchronously. This will allow you + * to not jank the browser if you need to encrypt a large number of strings + * all at once. This method accepts an array of wstrings which it will convert + * to UTF-8 internally before encrypting. + * + * @param plaintexts the strings to encrypt. + * @return A promise for the list of encrypted strings, encoded as Base64. + */ + [implicit_jscontext, must_use] + Promise asyncEncryptStrings(in Array plaintexts); + + /** + * Decrypt Base64 input. + * See the encryptString() documentation - this method has basically the same + * limitations. + * + * @param encryptedBase64Text Encrypted input text, encoded as Base64. + * @return The decoded text. + */ + [must_use] + ACString decryptString(in ACString encryptedBase64Text); + + /** + * Run decryptString on multiple strings, asynchronously. This will allow you + * to not jank the browser if you need to decrypt a large number of strings + * all at once. + * + * @param encryptedStrings the strings to decrypt, encoded as Base64. + * @return A promise that resolves with the list of decrypted strings in Unicode. + */ + [implicit_jscontext, must_use] + Promise asyncDecryptStrings(in Array encryptedStrings); + + /** + * Prompt the user to change the password on the SDR key. + */ + [must_use] + void changePassword(); + + /** + * Logout of the security device that protects the SDR key. + */ + [must_use] + void logout(); + + /** + * Logout of the security device that protects the SDR key and tear + * down authenticated objects. + */ + [must_use] + void logoutAndTeardown(); +}; diff --git a/security/manager/ssl/nsISecurityUITelemetry.idl b/security/manager/ssl/nsISecurityUITelemetry.idl new file mode 100644 index 0000000000..e29657c422 --- /dev/null +++ b/security/manager/ssl/nsISecurityUITelemetry.idl @@ -0,0 +1,138 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +[scriptable, uuid(5d1acf82-223a-46fb-a8f3-a1b16e2ceb04)] +interface nsISecurityUITelemetry : nsISupports { + +/* + * Addon installation warnings + */ + +// Firefox prevented this site from asking you to install addon +const uint32_t WARNING_ADDON_ASKING_PREVENTED = 1; +// User clicks through and allows site to ask to install addons +const uint32_t WARNING_ADDON_ASKING_PREVENTED_CLICK_THROUGH = 2; +// Are you sure you want to install this addon? Only install addons you trust +const uint32_t WARNING_CONFIRM_ADDON_INSTALL = 3; +// User clicked she is sure after waiting 3secs +const uint32_t WARNING_CONFIRM_ADDON_INSTALL_CLICK_THROUGH = 4; + + +/* + * modal dialogs/warnings + */ + +// removed WARNING_ENTERING_SECURE_SITE = 5; +// removed WARNING_ENTERING_WEAK_SITE = 6; +// removed WARNING_LEAVING_SECURE_SITE = 7; +// removed WARNING_MIXED_CONTENT = 8; + +// For confirmation dialogs, the clickthrough constant needs to be 1 +// more than the dialog constant so that +// WARNING_CONFIRM_ + 1 == WARNING_CONFIRM__CLICK_THROUGH +const uint32_t WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE = 9; +const uint32_t WARNING_CONFIRM_POST_TO_INSECURE_FROM_SECURE_CLICK_THROUGH = 10; +// removed WARNING_CONFIRM_POST_TO_INSECURE_FROM_INSECURE = 11; +// removed WARNING_CONFIRM_POST_TO_INSECURE_FROM_INSECURE_CLICK_THROUGH = 12; + +/* + * Phishing / Malware page warnings + * deprecated: we use the _TOP and _FRAME versions below + */ + +// removed WARNING_MALWARE_PAGE = 13; +// removed WARNING_MALWARE_PAGE_WHY_BLOCKED = 14; +// removed WARNING_MALWARE_PAGE_GET_ME_OUT_OF_HERE = 15; +// removed WARNING_MALWARE_PAGE_IGNORE_WARNING = 16; + +// removed WARNING_PHISHING_PAGE = 17; +// removed WARNING_PHISHING_PAGE_WHY_BLOCKED = 18; +// removed WARNING_PHISHING_PAGE_GET_ME_OUT_OF_HERE = 19; +// removed WARNING_PHISHING_PAGE_IGNORE_WARNING = 20; + +/* + * SSL Error dialogs + * deprecated: we use the _TOP versions below + */ + +// removed WARNING_BAD_CERT = 21; +// removed WARNING_BAD_CERT_STS = 22; +// removed WARNING_BAD_CERT_CLICK_ADD_EXCEPTION = 23; +// removed WARNING_BAD_CERT_CLICK_VIEW_CERT = 24; +// removed WARNING_BAD_CERT_DONT_REMEMBER_EXCEPTION = 25; +// removed WARNING_BAD_CERT_GET_ME_OUT_OF_HERE = 27; +// removed WARNING_BAD_CERT_UNDERSTAND_RISKS = 28; +// removed WARNING_BAD_CERT_TECHINICAL_DETAILS = 29; + +/* + * Note that if we add more possibilities in the warning dialogs, + * it is a new experiment and we shouldn't reuse these buckets. + */ +const uint32_t WARNING_BAD_CERT_ADD_EXCEPTION_BASE = 30; +const uint32_t WARNING_BAD_CERT_ADD_EXCEPTION_FLAG_UNTRUSTED = 1; +const uint32_t WARNING_BAD_CERT_ADD_EXCEPTION_FLAG_DOMAIN = 2; +const uint32_t WARNING_BAD_CERT_ADD_EXCEPTION_FLAG_TIME = 4; + +const uint32_t WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_BASE = 38; +const uint32_t WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_FLAG_UNTRUSTED = 1; +const uint32_t WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_FLAG_DOMAIN = 2; +const uint32_t WARNING_BAD_CERT_CONFIRM_ADD_EXCEPTION_FLAG_TIME = 4; +// This uses up buckets till 45 + +// const uint32_t WARNING_MALWARE_PAGE_TOP = 52; +// const uint32_t WARNING_MALWARE_PAGE_TOP_WHY_BLOCKED = 53; +// const uint32_t WARNING_MALWARE_PAGE_TOP_GET_ME_OUT_OF_HERE = 54; +// const uint32_t WARNING_MALWARE_PAGE_TOP_IGNORE_WARNING = 55; + +// const uint32_t WARNING_PHISHING_PAGE_TOP = 56; +// const uint32_t WARNING_PHISHING_PAGE_TOP_WHY_BLOCKED = 57; +// const uint32_t WARNING_PHISHING_PAGE_TOP_GET_ME_OUT_OF_HERE = 58; +// const uint32_t WARNING_PHISHING_PAGE_TOP_IGNORE_WARNING = 59; + +// const uint32_t WARNING_MALWARE_PAGE_FRAME = 60; +// const uint32_t WARNING_MALWARE_PAGE_FRAME_WHY_BLOCKED = 61; +// const uint32_t WARNING_MALWARE_PAGE_FRAME_GET_ME_OUT_OF_HERE = 62; +// const uint32_t WARNING_MALWARE_PAGE_FRAME_IGNORE_WARNING = 63; + +// const uint32_t WARNING_PHISHING_PAGE_FRAME = 64; +// const uint32_t WARNING_PHISHING_PAGE_FRAME_WHY_BLOCKED = 65; +// const uint32_t WARNING_PHISHING_PAGE_FRAME_GET_ME_OUT_OF_HERE = 66; +// const uint32_t WARNING_PHISHING_PAGE_FRAME_IGNORE_WARNING = 67; + +//const uint32_t WARNING_BAD_CERT_TOP = 68; +//const uint32_t WARNING_BAD_CERT_TOP_STS = 69; +//const uint32_t WARNING_BAD_CERT_TOP_CLICK_ADD_EXCEPTION = 70; +const uint32_t WARNING_BAD_CERT_TOP_CLICK_VIEW_CERT = 71; +const uint32_t WARNING_BAD_CERT_TOP_DONT_REMEMBER_EXCEPTION = 72; +//const uint32_t WARNING_BAD_CERT_TOP_GET_ME_OUT_OF_HERE = 73; +//const uint32_t WARNING_BAD_CERT_TOP_UNDERSTAND_RISKS = 74; +// removed WARNING_BAD_CERT_TOP_TECHNICAL_DETAILS = 75; + +const uint32_t WARNING_BAD_CERT_TOP_ADD_EXCEPTION_BASE = 76; +const uint32_t WARNING_BAD_CERT_TOP_ADD_EXCEPTION_FLAG_UNTRUSTED = 1; +const uint32_t WARNING_BAD_CERT_TOP_ADD_EXCEPTION_FLAG_DOMAIN = 2; +const uint32_t WARNING_BAD_CERT_TOP_ADD_EXCEPTION_FLAG_TIME = 4; + +const uint32_t WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_BASE = 84; +const uint32_t WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_FLAG_UNTRUSTED = 1; +const uint32_t WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_FLAG_DOMAIN = 2; +const uint32_t WARNING_BAD_CERT_TOP_CONFIRM_ADD_EXCEPTION_FLAG_TIME = 4; + +// Another Safe Browsing list (like malware & phishing above) +// const uint32_t WARNING_UNWANTED_PAGE_TOP = 92; +// const uint32_t WARNING_UNWANTED_PAGE_TOP_WHY_BLOCKED = 93; +// const uint32_t WARNING_UNWANTED_PAGE_TOP_GET_ME_OUT_OF_HERE = 94; +// const uint32_t WARNING_UNWANTED_PAGE_TOP_IGNORE_WARNING = 95; +// const uint32_t WARNING_UNWANTED_PAGE_FRAME = 96; +// const uint32_t WARNING_UNWANTED_PAGE_FRAME_WHY_BLOCKED = 97; +// const uint32_t WARNING_UNWANTED_PAGE_FRAME_GET_ME_OUT_OF_HERE = 98; +// const uint32_t WARNING_UNWANTED_PAGE_FRAME_IGNORE_WARNING = 99; + +// All the buckets are used so the safebrowsing-related buckets were +// moved under PAGE_LOAD_ERROR probe. See bug 1636962 for more information. +}; diff --git a/security/manager/ssl/nsISiteSecurityService.idl b/security/manager/ssl/nsISiteSecurityService.idl new file mode 100644 index 0000000000..b90a782374 --- /dev/null +++ b/security/manager/ssl/nsISiteSecurityService.idl @@ -0,0 +1,257 @@ +/* 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/. */ + +#include "nsISupports.idl" + +interface nsIURI; +interface nsIObserver; +interface nsIHttpChannel; +interface nsITransportSecurityInfo; +interface nsISimpleEnumerator; + +%{C++ +#include "nsStringFwd.h" +#include "nsTArrayForwardDeclare.h" +namespace mozilla +{ + namespace pkix + { + class Time; + } +} +%} +[ref] native nsCStringTArrayRef(nsTArray); +[ref] native mozillaPkixTime(mozilla::pkix::Time); +[ref] native const_OriginAttributesRef(const mozilla::OriginAttributes); + +// [infallible] attributes are only allowed on [builtinclass] +[scriptable, uuid(31313372-842c-4110-bdf1-6aea17c845ad), builtinclass] +interface nsISiteSecurityState : nsISupports +{ + [must_use] + readonly attribute ACString hostname; + [infallible] readonly attribute long long expireTime; + [infallible] readonly attribute short securityPropertyState; + [infallible] readonly attribute boolean includeSubdomains; + + [implicit_jscontext, must_use] + readonly attribute jsval originAttributes; + + /* + * SECURITY_PROPERTY_SET and SECURITY_PROPERTY_UNSET correspond to indicating + * a site has or does not have the security property in question, + * respectively. + * SECURITY_PROPERTY_KNOCKOUT indicates a value on a preloaded + * list is being overridden, and the associated site does not have the + * security property in question. + * SECURITY_PROPERTY_NEGATIVE is used when we've gotten a negative result from + * HSTS priming. + */ + const short SECURITY_PROPERTY_UNSET = 0; + const short SECURITY_PROPERTY_SET = 1; + const short SECURITY_PROPERTY_KNOCKOUT = 2; + const short SECURITY_PROPERTY_NEGATIVE = 3; +}; + +// This has to be a builtinclass because it derives from a builtinclass. +[scriptable, uuid(9ff16e40-1029-496c-95c2-bc819872b216), builtinclass] +interface nsISiteHSTSState : nsISiteSecurityState +{ +}; + +[scriptable, uuid(275127f8-dbd7-4681-afbf-6df0c6587a01)] +interface nsISiteSecurityService : nsISupports +{ + const uint32_t HEADER_HSTS = 0; + const uint32_t STATIC_PINNING = 1; // was HEADER_HPKP + // HEADER_OMS was 2 (but was never implemented) + + const uint32_t Success = 0; + const uint32_t ERROR_UNKNOWN = 1; + const uint32_t ERROR_UNTRUSTWORTHY_CONNECTION = 2; + const uint32_t ERROR_COULD_NOT_PARSE_HEADER = 3; + const uint32_t ERROR_NO_MAX_AGE = 4; + const uint32_t ERROR_MULTIPLE_MAX_AGES = 5; + const uint32_t ERROR_INVALID_MAX_AGE = 6; + const uint32_t ERROR_MULTIPLE_INCLUDE_SUBDOMAINS = 7; + const uint32_t ERROR_INVALID_INCLUDE_SUBDOMAINS = 8; + // The constants that were removed below were used in HPKP processing + // (which has been removed entirely). + // ERROR_INVALID_PIN was 9 + // ERROR_MULTIPLE_REPORT_URIS was 10 + // ERROR_PINSET_DOES_NOT_MATCH_CHAIN was 11 + // ERROR_NO_BACKUP_PIN was 12 + const uint32_t ERROR_COULD_NOT_SAVE_STATE = 13; + // ERROR_ROOT_NOT_BUILT_IN was 14 + + /** + * nsISiteSecurityService::IsSecureURI can optionally return a flag + * indicating the source of the HSTS cache entry, if it comes from the + * preload list, was seen naturally, or is a result of HSTS priming. + */ + const uint32_t SOURCE_UNKNOWN = 0; + const uint32_t SOURCE_PRELOAD_LIST = 1; + const uint32_t SOURCE_ORGANIC_REQUEST = 2; + + /** + * Parses a given HTTP header and records the results internally. + * Currently one header type is supported: HSTS (aka STS). + * The format of the HSTS header is defined by the HSTS specification: + * https://tools.ietf.org/html/rfc6797 + * and allows a host to specify that future HTTP requests should be + * upgraded to HTTPS. + * + * @param aType the type of security header in question. + * @param aSourceURI the URI of the resource with the HTTP header. + * @param aHeader the HTTP response header specifying security data. + * @param aSecInfo the TransportSecurityInfo of the current channel. + * @param aFlags options for this request as defined in nsISocketProvider: + * NO_PERMANENT_STORAGE + * @param aOriginAttributes the origin attributes that isolate this origin, + * (note that this implementation does not isolate + * by userContextId because of the risk of man-in- + * the-middle attacks before trust-on-second-use + * happens). + * @param aSource the source of the header, whether it was from the preload + * list, an organic header, or HSTS priming, or unknown. + * @param aMaxAge the parsed max-age directive of the header. + * @param aIncludeSubdomains the parsed includeSubdomains directive. + * @param aFailureResult a more specific failure result if NS_ERROR_FAILURE + was returned. + * @return NS_OK if it succeeds + * NS_ERROR_FAILURE if it can't be parsed + * NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA + * if there are unrecognized tokens in the header. + */ + [binaryname(ProcessHeader), noscript, must_use] + void processHeaderNative(in uint32_t aType, + in nsIURI aSourceURI, + in ACString aHeader, + in nsITransportSecurityInfo aSecInfo, + in uint32_t aFlags, + in uint32_t aSource, + in const_OriginAttributesRef aOriginAttributes, + [optional] out unsigned long long aMaxAge, + [optional] out boolean aIncludeSubdomains, + [optional] out uint32_t aFailureResult); + + [binaryname(ProcessHeaderScriptable), implicit_jscontext, optional_argc, + must_use] + void processHeader(in uint32_t aType, + in nsIURI aSourceURI, + in ACString aHeader, + in nsITransportSecurityInfo aSecInfo, + in uint32_t aFlags, + in uint32_t aSource, + [optional] in jsval aOriginAttributes, + [optional] out unsigned long long aMaxAge, + [optional] out boolean aIncludeSubdomains, + [optional] out uint32_t aFailureResult); + + /** + * Given a header type, resets state relating to that header of a host, + * including the includeSubdomains state that would affect subdomains. + * This essentially removes the state for the domain tree rooted at this + * host. If any preloaded information is present for that host, that + * information will then be used instead of any other previously existing + * state. + * + * @param aType the type of security state in question + * @param aURI the URI of the target host + * @param aFlags options for this request as defined in nsISocketProvider: + * NO_PERMANENT_STORAGE + * @param aOriginAttributes the origin attributes that isolate this origin, + * (note that this implementation does not isolate + * by userContextId because of the risk of man-in- + * the-middle attacks before trust-on-second-use + * happens). + */ + [implicit_jscontext, optional_argc, must_use] + void resetState(in uint32_t aType, + in nsIURI aURI, + in uint32_t aFlags, + [optional] in jsval aOriginAttributes); + + /** + * Checks whether or not the URI's hostname has a given security state set. + * For example, for HSTS: + * The URI is an HSTS URI if either the host has the HSTS state set, or one + * of its super-domains has the HSTS "includeSubdomains" flag set. + * NOTE: this function makes decisions based only on the + * host contained in the URI, and disregards other portions of the URI + * such as path and port. + * + * @param aType the type of security state in question. + * @param aURI the URI to query for STS state. + * @param aFlags options for this request as defined in nsISocketProvider: + * NO_PERMANENT_STORAGE + * @param aOriginAttributes the origin attributes that isolate this origin, + * (note that this implementation does not isolate + * by userContextId because of the risk of man-in- + * the-middle attacks before trust-on-second-use + * happens). + * @param aCached true if we have cached information about this host, even + * if the security state is false. + * @param aSource the source of the HSTS entry. One of SOURCE_PRELOAD_LIST, + * SOURCE_ORGANIC_REQUEST, SOURCE_HSTS_PRIMING, or + * SOURCE_UNKNOWN. + */ + [binaryname(IsSecureURI), noscript, must_use] + boolean isSecureURINative(in uint32_t aType, in nsIURI aURI, + in uint32_t aFlags, + in const_OriginAttributesRef aOriginAttributes, + [optional] out boolean aCached, + [optional] out uint32_t aSource); + + [binaryname(IsSecureURIScriptable), implicit_jscontext, optional_argc, + must_use] + boolean isSecureURI(in uint32_t aType, in nsIURI aURI, in uint32_t aFlags, + [optional] in jsval aOriginAttributes, + [optional] out boolean aCached, + [optional] out uint32_t aSource); + + /** + * Removes all non-preloaded security state by resetting to factory-original + * settings. + */ + [must_use] + void clearAll(); + + /** + * Removes all preloaded security state. + */ + [must_use] + void clearPreloads(); + + /** + * Set an HSTS preload entry for a host. The resulting entries will be + * permanent and visible from private and non-private contexts. These + * entries replace any already set by this mechanism or those built-in to + * Gecko. + * + * @param aHost the hostname (punycode) that the entry applies to + * @param aIncludeSubdomains whether this entry also applies to subdomains + * @param aExpires the time this entry should expire (millis since epoch) + */ + [must_use] + boolean setHSTSPreload(in ACString aHost, + in boolean aIncludesSubdomains, + in int64_t aExpires); + + /** + * Returns an enumerator of the nsISiteSecurityService storage. Each item in + * the enumeration is a nsISiteSecurityState that can be QueryInterfaced to + * nsISiteHSTSState. + * Doesn't include preloaded entries (either the hard-coded ones or the + * preloaded-delivered-by-kinto ones). + * + * @param aType the type of security state in question. + */ + [must_use] + nsISimpleEnumerator enumerate(in uint32_t aType); +}; + +%{C++ +#define NS_SSSERVICE_CONTRACTID "@mozilla.org/ssservice;1" +%} diff --git a/security/manager/ssl/nsITokenDialogs.idl b/security/manager/ssl/nsITokenDialogs.idl new file mode 100644 index 0000000000..0246404064 --- /dev/null +++ b/security/manager/ssl/nsITokenDialogs.idl @@ -0,0 +1,24 @@ +/* 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/. */ + +#include "nsISupports.idl" + +interface nsIInterfaceRequestor; +interface nsIProtectedAuthThread; + +[scriptable, uuid(a1cbc159-468c-495d-8068-61dd538cbcca)] +interface nsITokenDialogs : nsISupports +{ + /** + * Displays notification dialog to the user that they are expected to + * authenticate to the token using its "protected authentication path" feature. + */ + [must_use] + void displayProtectedAuth(in nsIInterfaceRequestor ctx, + in nsIProtectedAuthThread runnable); +}; + +%{C++ +#define NS_TOKENDIALOGS_CONTRACTID "@mozilla.org/nsTokenDialogs;1" +%} diff --git a/security/manager/ssl/nsITokenPasswordDialogs.idl b/security/manager/ssl/nsITokenPasswordDialogs.idl new file mode 100644 index 0000000000..1e5475e6dd --- /dev/null +++ b/security/manager/ssl/nsITokenPasswordDialogs.idl @@ -0,0 +1,30 @@ +/* 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/. */ + +#include "nsISupports.idl" + +interface nsIInterfaceRequestor; +interface nsIPK11Token; + +/** + * This is the interface for setting and changing password + * on a PKCS11 token. + */ +[scriptable, uuid(87dbd64a-4466-474e-95f5-1ad1cee5702c)] +interface nsITokenPasswordDialogs : nsISupports +{ + /** + * Brings up a dialog to set the password on a token. + * + * @param ctx A user interface context. + * @param token {nsIPK11Token} The token. + * @return true if the user canceled the dialog, false otherwise. + */ + [must_use] + boolean setPassword(in nsIInterfaceRequestor ctx, in nsIPK11Token token); +}; + +%{C++ +#define NS_TOKENPASSWORDSDIALOG_CONTRACTID "@mozilla.org/nsTokenPasswordDialogs;1" +%} diff --git a/security/manager/ssl/nsIX509Cert.idl b/security/manager/ssl/nsIX509Cert.idl new file mode 100644 index 0000000000..1ba2429027 --- /dev/null +++ b/security/manager/ssl/nsIX509Cert.idl @@ -0,0 +1,223 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +interface nsIArray; +interface nsIX509CertValidity; +interface nsICertVerificationListener; + +%{ C++ +namespace IPC { + class Message; +} +class PickleIterator; + + /* forward declaration */ + typedef struct CERTCertificateStr CERTCertificate; +%} + +[ptr] native CERTCertificatePtr(CERTCertificate); +[ptr] native IpcMessagePtr(IPC::Message); +[ptr] native PickleIteratorPtr(PickleIterator); + +/** + * This represents a X.509 certificate. + * + * NOTE: Service workers persist x.509 certs in object form on disk. If you + * change this uuid you probably need a hack in nsBinaryInputStream to + * read the old uuid. If you change the format of the object + * serialization then more complex changes will be needed. + */ +[scriptable, builtinclass, uuid(bdc3979a-5422-4cd5-8589-696b6e96ea83)] +interface nsIX509Cert : nsISupports { + + /** + * The primary email address of the certificate, if present. + */ + readonly attribute AString emailAddress; + + /** + * Did this certificate ship with the platform as a built-in root? + */ + [must_use] + readonly attribute bool isBuiltInRoot; + + /** + * Obtain a list of all email addresses + * contained in the certificate. + * + * @return An array of email addresses. + */ + [must_use] + Array getEmailAddresses(); + + /** + * Check whether a given address is contained in the certificate. + * The comparison will convert the email address to lowercase. + * The behaviour for non ASCII characters is undefined. + * + * @param aEmailAddress The address to search for. + * + * @return True if the address is contained in the certificate. + */ + [must_use] + boolean containsEmailAddress(in AString aEmailAddress); + + /** + * The subject owning the certificate. + */ + readonly attribute AString subjectName; + + /** + * The subject's common name. + */ + readonly attribute AString commonName; + + /** + * The subject's organization. + */ + readonly attribute AString organization; + + /** + * The subject's organizational unit. + */ + [must_use] + readonly attribute AString organizationalUnit; + + /** + * The fingerprint of the certificate's DER encoding, + * calculated using the SHA-256 algorithm. + */ + readonly attribute AString sha256Fingerprint; + + /** + * The fingerprint of the certificate's DER encoding, + * calculated using the SHA1 algorithm. + */ + [must_use] + readonly attribute AString sha1Fingerprint; + + /** + * A human readable name identifying the hardware or + * software token the certificate is stored on. + */ + readonly attribute AString tokenName; + + /** + * The subject identifying the issuer certificate. + */ + readonly attribute AString issuerName; + + /** + * The serial number the issuer assigned to this certificate. + */ + [must_use] + readonly attribute AString serialNumber; + + /** + * The issuer subject's common name. + */ + [must_use] + readonly attribute AString issuerCommonName; + + /** + * The issuer subject's organization. + */ + readonly attribute AString issuerOrganization; + + /** + * The issuer subject's organizational unit. + */ + [must_use] + readonly attribute AString issuerOrganizationUnit; + + /** + * This certificate's validity period. + */ + readonly attribute nsIX509CertValidity validity; + + /** + * A unique identifier of this certificate within the local storage. + */ + [must_use] + readonly attribute ACString dbKey; + + /** + * A human readable identifier to label this certificate. + */ + [must_use] + readonly attribute AString displayName; + + /** + * Constants to classify the type of a certificate. + */ + const unsigned long UNKNOWN_CERT = 0; + const unsigned long CA_CERT = 1 << 0; + const unsigned long USER_CERT = 1 << 1; + const unsigned long EMAIL_CERT = 1 << 2; + const unsigned long SERVER_CERT = 1 << 3; + const unsigned long ANY_CERT = 0xffff; + + /** + * Type of this certificate + */ + readonly attribute unsigned long certType; + + /** + * A comma separated list of localized strings representing the contents of + * the certificate's key usage extension, if present. The empty string if the + * certificate doesn't have the key usage extension, or has an empty extension. + */ + [must_use] + readonly attribute AString keyUsages; + + /** + * Obtain a raw binary encoding of this certificate + * in DER format. + * + * @return The bytes representing the DER encoded certificate. + */ + [must_use] + Array getRawDER(); + + /** + * Obtain a base 64 string representation of this certificate + * in DER format. + * + * @return The DER encoded certificate as a string. + */ + [must_use] + ACString getBase64DERString(); + + /** + * Test whether two certificate instances represent the + * same certificate. + * + * @return Whether the certificates are equal + */ + [must_use] + boolean equals(in nsIX509Cert other); + + /** + * The base64 encoding of the DER encoded public key info using the specified + * digest. + */ + [must_use] + readonly attribute ACString sha256SubjectPublicKeyInfoDigest; + + /** + * Retrieves the NSS certificate object wrapped by this interface + */ + [notxpcom, noscript, must_use] + CERTCertificatePtr getCert(); + + [notxpcom, noscript] + void SerializeToIPC(in IpcMessagePtr aMsg); + + [notxpcom, noscript] + bool DeserializeFromIPC([const] in IpcMessagePtr aMsg, in PickleIteratorPtr aIter); +}; diff --git a/security/manager/ssl/nsIX509CertDB.idl b/security/manager/ssl/nsIX509CertDB.idl new file mode 100644 index 0000000000..fe72c78f40 --- /dev/null +++ b/security/manager/ssl/nsIX509CertDB.idl @@ -0,0 +1,351 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +interface nsIArray; +interface nsIX509Cert; +interface nsIFile; +interface nsIInterfaceRequestor; +interface nsIZipReader; +interface nsIInputStream; + +%{C++ +#define NS_X509CERTDB_CONTRACTID "@mozilla.org/security/x509certdb;1" +%} + +typedef uint32_t AppTrustedRoot; + +[scriptable, function, uuid(fc2b60e5-9a07-47c2-a2cd-b83b68a660ac)] +interface nsIOpenSignedAppFileCallback : nsISupports +{ + void openSignedAppFileFinished(in nsresult rv, + in nsIZipReader aZipReader, + in nsIX509Cert aSignerCert); +}; + +[scriptable, function, uuid(07c08655-8b11-4650-b6c4-0c145595ceb5)] +interface nsIAsyncBoolCallback : nsISupports +{ + void onResult(in bool result); +}; + +/** + * Callback type for use with asyncVerifyCertAtTime. + * If aPRErrorCode is PRErrorCodeSuccess (i.e. 0), aVerifiedChain represents the + * verified certificate chain determined by asyncVerifyCertAtTime. aHasEVPolicy + * represents whether or not the end-entity certificate verified as EV. + * If aPRErrorCode is non-zero, it represents the error encountered during + * verification. aVerifiedChain is null in that case and aHasEVPolicy has no + * meaning. + */ +[scriptable, function, uuid(49e16fc8-efac-4f57-8361-956ef6b960a4)] +interface nsICertVerificationCallback : nsISupports { + void verifyCertFinished(in int32_t aPRErrorCode, + in Array aVerifiedChain, + in bool aHasEVPolicy); +}; + +/** + * This represents a service to access and manipulate + * X.509 certificates stored in a database. + */ +[scriptable, uuid(5c16cd9b-5a73-47f1-ab0f-11ede7495cce)] +interface nsIX509CertDB : nsISupports { + + /** + * Constants that define which usages a certificate + * is trusted for. + */ + const unsigned long UNTRUSTED = 0; + const unsigned long TRUSTED_SSL = 1 << 0; + const unsigned long TRUSTED_EMAIL = 1 << 1; + + /** + * Will find a certificate based on its dbkey + * retrieved by getting the dbKey attribute of + * the certificate. + * + * @param aDBkey Database internal key, as obtained using + * attribute dbkey in nsIX509Cert. + */ + [must_use] + nsIX509Cert findCertByDBKey(in ACString aDBkey); + + /** + * Use this to import a stream sent down as a mime type into + * the certificate database on the default token. + * The stream may consist of one or more certificates. + * + * @param data The raw data to be imported + * @param length The length of the data to be imported + * @param type The type of the certificate, see constants in nsIX509Cert + * @param ctx A UI context. + */ + void importCertificates([array, size_is(length)] in octet data, + in unsigned long length, + in unsigned long type, + in nsIInterfaceRequestor ctx); + + /** + * Import another person's email certificate into the database. + * + * @param data The raw data to be imported + * @param length The length of the data to be imported + * @param ctx A UI context. + */ + void importEmailCertificate([array, size_is(length)] in octet data, + in unsigned long length, + in nsIInterfaceRequestor ctx); + + /** + * Import a personal certificate into the database, assuming + * the database already contains the private key for this certificate. + * + * @param data The raw data to be imported + * @param length The length of the data to be imported + * @param ctx A UI context. + */ + void importUserCertificate([array, size_is(length)] in octet data, + in unsigned long length, + in nsIInterfaceRequestor ctx); + + /** + * Delete a certificate stored in the database. + * + * @param aCert Delete this certificate. + */ + void deleteCertificate(in nsIX509Cert aCert); + + /** + * Modify the trust that is stored and associated to a certificate within + * a database. Separate trust is stored for + * One call manipulates the trust for one trust type only. + * See the trust type constants defined within this interface. + * + * @param cert Change the stored trust of this certificate. + * @param type The type of the certificate. See nsIX509Cert. + * @param trust A bitmask. The new trust for the possible usages. + * See the trust constants defined within this interface. + */ + [must_use] + void setCertTrust(in nsIX509Cert cert, + in unsigned long type, + in unsigned long trust); + + /** + * @param cert The certificate for which to modify trust. + * @param trustString decoded by CERT_DecodeTrustString. 3 comma separated + * characters, indicating SSL, Email, and Object signing + * trust. The object signing trust flags are effectively + * ignored by gecko, but they still must be specified (at + * least by a final trailing comma) because this argument + * is passed to CERT_DecodeTrustString. + */ + [must_use] + void setCertTrustFromString(in nsIX509Cert cert, in ACString trustString); + + /** + * Query whether a certificate is trusted for a particular use. + * + * @param cert Obtain the stored trust of this certificate. + * @param certType The type of the certificate. See nsIX509Cert. + * @param trustType A single bit from the usages constants defined + * within this interface. + * + * @return Returns true if the certificate is trusted for the given use. + */ + [must_use] + boolean isCertTrusted(in nsIX509Cert cert, + in unsigned long certType, + in unsigned long trustType); + + /** + * Import certificate(s) from file + * + * @param aFile Identifies a file that contains the certificate + * to be imported. + * @param aType Describes the type of certificate that is going to + * be imported. See type constants in nsIX509Cert. + */ + [must_use] + void importCertsFromFile(in nsIFile aFile, + in unsigned long aType); + + const uint32_t Success = 0; + const uint32_t ERROR_UNKNOWN = 1; + const uint32_t ERROR_PKCS12_NOSMARTCARD_EXPORT = 2; + const uint32_t ERROR_PKCS12_RESTORE_FAILED = 3; + const uint32_t ERROR_PKCS12_BACKUP_FAILED = 4; + const uint32_t ERROR_PKCS12_CERT_COLLISION = 5; + const uint32_t ERROR_BAD_PASSWORD = 6; + const uint32_t ERROR_DECODE_ERROR = 7; + const uint32_t ERROR_PKCS12_DUPLICATE_DATA = 8; + + /** + * Import a PKCS#12 file containing cert(s) and key(s) into the database. + * + * @param aFile Identifies a file that contains the data to be imported. + * @param password The password used to protect the file. + * @return Success or the specific error code on failure. The return + * values are defined in this file. + */ + [must_use] + uint32_t importPKCS12File(in nsIFile aFile, in AString aPassword); + + /** + * Export a set of certs and keys from the database to a PKCS#12 file. + * + * @param aFile Identifies a file that will be filled with the data to be + * exported. + * @param count The number of certificates to be exported. + * @param aCerts The array of all certificates to be exported. + * @param password The password used to protect the file. + * @return Success or the specific error code on failure + */ + [must_use] + uint32_t exportPKCS12File(in nsIFile aFile, + in Array aCerts, + in AString aPassword); + + /* + * Decode a raw data presentation and instantiate an object in memory. + * + * @param base64 The raw representation of a certificate, + * encoded as Base 64. + * @return The new certificate object. + */ + [must_use] + nsIX509Cert constructX509FromBase64(in ACString base64); + + /* + * Decode a raw data presentation and instantiate an object in memory. + * + * @param certDER The raw representation of a certificate, + * encoded as raw DER. + * @return The new certificate object. + */ + [must_use] + nsIX509Cert constructX509(in Array certDER); + + /** + * Verifies the signature on the given JAR file to verify that it has a + * valid signature. To be considered valid, there must be exactly one + * signature on the JAR file and that signature must have signed every + * entry. Further, the signature must come from a certificate that + * is trusted for code signing. + * + * On success, NS_OK, a nsIZipReader, and the trusted certificate that + * signed the JAR are returned. + * + * On failure, an error code is returned. + * + * This method returns a nsIZipReader, instead of taking an nsIZipReader + * as input, to encourage users of the API to verify the signature as the + * first step in opening the JAR. + */ + // 1 used to be AppMarketplaceProdPublicRoot. + // 2 used to be AppMarketplaceProdReviewersRoot. + // 3 used to be AppMarketplaceDevPublicRoot. + // 4 used to be AppMarketplaceDevReviewersRoot. + // 5 used to be AppMarketplaceStageRoot. + const AppTrustedRoot AppXPCShellRoot = 6; + const AppTrustedRoot AddonsPublicRoot = 7; + const AppTrustedRoot AddonsStageRoot = 8; + [must_use] + void openSignedAppFileAsync(in AppTrustedRoot trustedRoot, + in nsIFile aJarFile, + in nsIOpenSignedAppFileCallback callback); + + /* + * Add a cert to a cert DB from a binary string. + * + * @param certDER The raw DER encoding of a certificate. + * @param trust String describing the trust settings to assign the + * certificate. Decoded by CERT_DecodeTrustString. Consists of 3 + * comma separated sets of characters, indicating SSL, Email, and + * Object signing trust. The object signing trust flags are + * effectively ignored by gecko, but they still must be specified + * (at least by a final trailing comma) because this argument is + * passed to CERT_DecodeTrustString. + * @return nsIX509Cert the resulting certificate + */ + [must_use] + nsIX509Cert addCert(in ACString certDER, in ACString trust); + + // Flags for asyncVerifyCertAtTime (these must match the values in + // CertVerifier.cpp): + // Prevent network traffic. + const uint32_t FLAG_LOCAL_ONLY = 1 << 0; + // Do not fall back to DV verification after attempting EV validation. + const uint32_t FLAG_MUST_BE_EV = 1 << 1; + + /* + * Asynchronously verify a certificate given a set of parameters. Calls the + * `verifyCertFinished` function on the provided `nsICertVerificationCallback` + * with the results of the verification operation. + * See the documentation for nsICertVerificationCallback. + * + * @param aCert the certificate to verify + * @param aUsage an integer representing the usage to verify for (see + * SECCertificateUsage in certt.h from NSS) + * @param aFlags flags as described above + * @param aHostname the (optional) hostname to verify for + * @param aTime the time at which to verify, in seconds since the epoch + * @param aCallback the nsICertVerificationCallback that will receive the + results of this verification + * @return a succeeding nsresult if the job was dispatched successfully + */ + [must_use] + void asyncVerifyCertAtTime(in nsIX509Cert aCert, + in int64_t /*SECCertificateUsage*/ aUsage, + in uint32_t aFlags, + in ACString aHostname, + in uint64_t aTime, + in nsICertVerificationCallback aCallback); + + // Clears the OCSP cache for the current certificate verification + // implementation. + [must_use] + void clearOCSPCache(); + + /* + * Add a cert to a cert DB from a base64 encoded string. + * + * @param base64 The raw representation of a certificate, encoded as Base 64. + * @param trust String describing the trust settings to assign the + * certificate. Decoded by CERT_DecodeTrustString. Consists of 3 + * comma separated sets of characters, indicating SSL, Email, and + * Object signing trust. The object signing trust flags are + * effectively ignored by gecko, but they still must be specified + * (at least by a final trailing comma) because this argument is + * passed to CERT_DecodeTrustString. + * @return nsIX509Cert the resulting certificate + */ + [must_use] + nsIX509Cert addCertFromBase64(in ACString base64, in ACString trust); + + /* + * Get all the known certs in the database + */ + [must_use] + Array getCerts(); + + /** + * Encode the list of certificates as a PKCS#7 SignedData structure. No data + * is actually signed - this is merely a way of exporting a collection of + * certificates. + */ + [must_use] + ACString asPKCS7Blob(in Array certList); + + /** + * Iterates through all the certs and returns false if any of the trusted + * CA certs are not built-in roots; and true otherwise. + */ + [must_use] + void asyncHasThirdPartyRoots(in nsIAsyncBoolCallback callback); +}; diff --git a/security/manager/ssl/nsIX509CertValidity.idl b/security/manager/ssl/nsIX509CertValidity.idl new file mode 100644 index 0000000000..ab7adc76e1 --- /dev/null +++ b/security/manager/ssl/nsIX509CertValidity.idl @@ -0,0 +1,72 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsISupports.idl" + +/** + * Information on the validity period of a X.509 certificate. + */ +[scriptable, uuid(e701dfd8-1dd1-11b2-a172-ffa6cc6156ad)] +interface nsIX509CertValidity : nsISupports { + + /** + * The earliest point in time where + * a certificate is valid. + */ + readonly attribute PRTime notBefore; + + /** + * "notBefore" attribute formatted as a time string + * according to the environment locale, + * according to the environment time zone. + */ + [must_use] + readonly attribute AString notBeforeLocalTime; + + /** + * The day portion of "notBefore" formatted as a time string + * according to the environment locale, + * according to the environment time zone. + */ + readonly attribute AString notBeforeLocalDay; + + /** + * "notBefore" attribute formatted as a string + * according to the environment locale, + * displayed as GMT / UTC. + */ + [must_use] + readonly attribute AString notBeforeGMT; + + /** + * The latest point in time where + * a certificate is valid. + */ + readonly attribute PRTime notAfter; + + /** + * "notAfter" attribute formatted as a time string + * according to the environment locale, + * according to the environment time zone. + */ + [must_use] + readonly attribute AString notAfterLocalTime; + + /** + * The day portion of "notAfter" formatted as a time string + * according to the environment locale, + * according to the environment time zone. + */ + readonly attribute AString notAfterLocalDay; + + /** + * "notAfter" attribute formatted as a time string + * according to the environment locale, + * displayed as GMT / UTC. + */ + [must_use] + readonly attribute AString notAfterGMT; +}; diff --git a/security/manager/ssl/nsKeyModule.cpp b/security/manager/ssl/nsKeyModule.cpp new file mode 100644 index 0000000000..177ac20301 --- /dev/null +++ b/security/manager/ssl/nsKeyModule.cpp @@ -0,0 +1,102 @@ +/* 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/. */ + +#include "nsCOMPtr.h" +#include "nsComponentManagerUtils.h" +#include "nsKeyModule.h" +#include "nsString.h" + +using namespace mozilla; +using namespace mozilla::psm; + +NS_IMPL_ISUPPORTS(nsKeyObject, nsIKeyObject) + +nsKeyObject::nsKeyObject() : mSymKey(nullptr) {} + +////////////////////////////////////////////////////////////////////////////// +// nsIKeyObject + +NS_IMETHODIMP +nsKeyObject::InitKey(int16_t aAlgorithm, PK11SymKey* aKey) { + if (!aKey || aAlgorithm != nsIKeyObject::HMAC) { + return NS_ERROR_INVALID_ARG; + } + + mSymKey.reset(aKey); + return NS_OK; +} + +NS_IMETHODIMP +nsKeyObject::GetKeyObj(PK11SymKey** _retval) { + if (!_retval) { + return NS_ERROR_INVALID_ARG; + } + + *_retval = nullptr; + + if (!mSymKey) { + return NS_ERROR_NOT_INITIALIZED; + } + + *_retval = mSymKey.get(); + return NS_OK; +} + +NS_IMETHODIMP +nsKeyObject::GetType(int16_t* _retval) { + if (!_retval) { + return NS_ERROR_INVALID_ARG; + } + *_retval = nsIKeyObject::SYM_KEY; + return NS_OK; +} + +////////////////////////////////////////////////////////////////////////////// +// nsIKeyObjectFactory + +NS_IMPL_ISUPPORTS(nsKeyObjectFactory, nsIKeyObjectFactory) + +NS_IMETHODIMP +nsKeyObjectFactory::KeyFromString(int16_t aAlgorithm, const nsACString& aKey, + nsIKeyObject** _retval) { + if (!_retval || aAlgorithm != nsIKeyObject::HMAC) { + return NS_ERROR_INVALID_ARG; + } + + CK_MECHANISM_TYPE cipherMech = CKM_GENERIC_SECRET_KEY_GEN; + CK_ATTRIBUTE_TYPE cipherOperation = CKA_SIGN; + + nsresult rv; + nsCOMPtr key( + do_CreateInstance(NS_KEYMODULEOBJECT_CONTRACTID, &rv)); + if (NS_FAILED(rv)) { + return rv; + } + + // Convert the raw string into a SECItem + const nsCString& flatKey = PromiseFlatCString(aKey); + SECItem keyItem; + keyItem.data = (unsigned char*)flatKey.get(); + keyItem.len = flatKey.Length(); + + UniquePK11SlotInfo slot(PK11_GetBestSlot(cipherMech, nullptr)); + if (!slot) { + return NS_ERROR_FAILURE; + } + + UniquePK11SymKey symKey(PK11_ImportSymKey(slot.get(), cipherMech, + PK11_OriginUnwrap, cipherOperation, + &keyItem, nullptr)); + if (!symKey) { + return NS_ERROR_FAILURE; + } + + rv = key->InitKey(aAlgorithm, symKey.release()); + if (NS_FAILED(rv)) { + return rv; + } + + key.swap(*_retval); + return NS_OK; +} diff --git a/security/manager/ssl/nsKeyModule.h b/security/manager/ssl/nsKeyModule.h new file mode 100644 index 0000000000..95524f8090 --- /dev/null +++ b/security/manager/ssl/nsKeyModule.h @@ -0,0 +1,59 @@ +/* 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/. */ + +#ifndef nsKeyModule_h +#define nsKeyModule_h + +#include "ScopedNSSTypes.h" +#include "nsIKeyModule.h" +#include "pk11pub.h" + +#define NS_KEYMODULEOBJECT_CID \ + { \ + 0x9d383ddd, 0x6856, 0x4187, { \ + 0x84, 0x85, 0xf3, 0x61, 0x95, 0xb2, 0x9a, 0x0e \ + } \ + } +#define NS_KEYMODULEOBJECT_CONTRACTID "@mozilla.org/security/keyobject;1" + +#define NS_KEYMODULEOBJECTFACTORY_CID \ + { \ + 0x2a35dd47, 0xb026, 0x4e8d, { \ + 0xb6, 0xb7, 0x57, 0x40, 0xf6, 0x1a, 0xb9, 0x02 \ + } \ + } +#define NS_KEYMODULEOBJECTFACTORY_CONTRACTID \ + "@mozilla.org/security/keyobjectfactory;1" + +class nsKeyObject final : public nsIKeyObject { + public: + nsKeyObject(); + + NS_DECL_ISUPPORTS + NS_DECL_NSIKEYOBJECT + + private: + ~nsKeyObject() = default; + + // Disallow copy constructor + nsKeyObject(nsKeyObject&); + + mozilla::UniquePK11SymKey mSymKey; +}; + +class nsKeyObjectFactory final : public nsIKeyObjectFactory { + public: + nsKeyObjectFactory() = default; + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIKEYOBJECTFACTORY + + private: + ~nsKeyObjectFactory() = default; + + // Disallow copy constructor + nsKeyObjectFactory(nsKeyObjectFactory&); +}; + +#endif // nsKeyModule_h diff --git a/security/manager/ssl/nsNSSCallbacks.cpp b/security/manager/ssl/nsNSSCallbacks.cpp new file mode 100644 index 0000000000..54e290aa91 --- /dev/null +++ b/security/manager/ssl/nsNSSCallbacks.cpp @@ -0,0 +1,1382 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsNSSCallbacks.h" + +#include "PSMRunnable.h" +#include "ScopedNSSTypes.h" +#include "SharedCertVerifier.h" +#include "SharedSSLState.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Assertions.h" +#include "mozilla/Casting.h" +#include "mozilla/RefPtr.h" +#include "mozilla/Span.h" +#include "mozilla/Telemetry.h" +#include "mozilla/Unused.h" +#include "nsContentUtils.h" +#include "nsIChannel.h" +#include "nsIHttpChannel.h" +#include "nsIHttpChannelInternal.h" +#include "nsIPrompt.h" +#include "nsIProtocolProxyService.h" +#include "nsISupportsPriority.h" +#include "nsIStreamLoader.h" +#include "nsITokenDialogs.h" +#include "nsIUploadChannel.h" +#include "nsIWebProgressListener.h" +#include "nsNSSCertHelper.h" +#include "nsNSSCertificate.h" +#include "nsNSSComponent.h" +#include "nsNSSHelper.h" +#include "nsNSSIOLayer.h" +#include "nsNetUtil.h" +#include "nsProtectedAuthThread.h" +#include "nsProxyRelease.h" +#include "nsStringStream.h" +#include "mozpkix/pkixtypes.h" +#include "ssl.h" +#include "sslproto.h" +#include "SSLTokensCache.h" + +#include "TrustOverrideUtils.h" +#include "TrustOverride-SymantecData.inc" +#include "TrustOverride-AppleGoogleDigiCertData.inc" +#include "TrustOverride-TestImminentDistrustData.inc" + +using namespace mozilla; +using namespace mozilla::pkix; +using namespace mozilla::psm; + +extern LazyLogModule gPIPNSSLog; + +static void AccumulateCipherSuite(Telemetry::HistogramID probe, + const SSLChannelInfo& channelInfo); + +namespace { + +// Bits in bit mask for SSL_REASONS_FOR_NOT_FALSE_STARTING telemetry probe +// These bits are numbered so that the least subtle issues have higher values. +// This should make it easier for us to interpret the results. +const uint32_t POSSIBLE_VERSION_DOWNGRADE = 4; +const uint32_t POSSIBLE_CIPHER_SUITE_DOWNGRADE = 2; +const uint32_t KEA_NOT_SUPPORTED = 1; + +} // namespace + +class OCSPRequest final : public nsIStreamLoaderObserver, public nsIRunnable { + public: + OCSPRequest(const nsACString& aiaLocation, + const OriginAttributes& originAttributes, + const uint8_t (&ocspRequest)[OCSP_REQUEST_MAX_LENGTH], + size_t ocspRequestLength, TimeDuration timeout); + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSISTREAMLOADEROBSERVER + NS_DECL_NSIRUNNABLE + + nsresult DispatchToMainThreadAndWait(); + nsresult GetResponse(/*out*/ Vector& response); + + private: + ~OCSPRequest() = default; + + static void OnTimeout(nsITimer* timer, void* closure); + nsresult NotifyDone(nsresult rv, MonitorAutoLock& proofOfLock); + + // mMonitor provides the memory barrier protecting these member variables. + // What happens is the originating thread creates an OCSPRequest object with + // the information necessary to perform an OCSP request. It sends the object + // to the main thread and waits on the monitor for the operation to complete. + // On the main thread, a channel is set up to perform the request. This gets + // dispatched to necko. At the same time, a timeout timer is initialized. If + // the necko request completes, the response data is filled out, mNotifiedDone + // is set to true, and the monitor is notified. The original thread then wakes + // up and continues with the results that have been filled out. If the request + // times out, again the response data is filled out, mNotifiedDone is set to + // true, and the monitor is notified. The first of these two events wins. That + // is, if the timeout timer fires but the request completes shortly after, the + // caller will see the request as having timed out. + // When the request completes (i.e. OnStreamComplete runs), the timer will be + // cancelled. This is how we know the closure in OnTimeout is valid. If the + // timer fires before OnStreamComplete runs, it should be safe to not cancel + // the request because necko has a strong reference to it. + Monitor mMonitor; + bool mNotifiedDone; + nsCOMPtr mLoader; + const nsCString mAIALocation; + const OriginAttributes mOriginAttributes; + const mozilla::Span mPOSTData; + const TimeDuration mTimeout; + nsCOMPtr mTimeoutTimer; + TimeStamp mStartTime; + nsresult mResponseResult; + Vector mResponseBytes; +}; + +NS_IMPL_ISUPPORTS(OCSPRequest, nsIStreamLoaderObserver, nsIRunnable) + +OCSPRequest::OCSPRequest(const nsACString& aiaLocation, + const OriginAttributes& originAttributes, + const uint8_t (&ocspRequest)[OCSP_REQUEST_MAX_LENGTH], + size_t ocspRequestLength, TimeDuration timeout) + : mMonitor("OCSPRequest.mMonitor"), + mNotifiedDone(false), + mLoader(nullptr), + mAIALocation(aiaLocation), + mOriginAttributes(originAttributes), + mPOSTData(reinterpret_cast(ocspRequest), ocspRequestLength), + mTimeout(timeout), + mTimeoutTimer(nullptr), + mStartTime(), + mResponseResult(NS_ERROR_FAILURE), + mResponseBytes() { + MOZ_ASSERT(ocspRequestLength <= OCSP_REQUEST_MAX_LENGTH); +} + +nsresult OCSPRequest::DispatchToMainThreadAndWait() { + MOZ_ASSERT(!NS_IsMainThread()); + if (NS_IsMainThread()) { + return NS_ERROR_FAILURE; + } + + MonitorAutoLock lock(mMonitor); + nsresult rv = NS_DispatchToMainThread(this); + if (NS_FAILED(rv)) { + return rv; + } + while (!mNotifiedDone) { + lock.Wait(); + } + + TimeStamp endTime = TimeStamp::Now(); + // CERT_VALIDATION_HTTP_REQUEST_RESULT: + // 0: request timed out + // 1: request succeeded + // 2: request failed + // 3: internal error + // If mStartTime was never set, we consider this an internal error. + // Otherwise, we managed to at least send the request. + if (mStartTime.IsNull()) { + Telemetry::Accumulate(Telemetry::CERT_VALIDATION_HTTP_REQUEST_RESULT, 3); + } else if (mResponseResult == NS_ERROR_NET_TIMEOUT) { + Telemetry::Accumulate(Telemetry::CERT_VALIDATION_HTTP_REQUEST_RESULT, 0); + Telemetry::AccumulateTimeDelta( + Telemetry::CERT_VALIDATION_HTTP_REQUEST_CANCELED_TIME, mStartTime, + endTime); + } else if (NS_SUCCEEDED(mResponseResult)) { + Telemetry::Accumulate(Telemetry::CERT_VALIDATION_HTTP_REQUEST_RESULT, 1); + Telemetry::AccumulateTimeDelta( + Telemetry::CERT_VALIDATION_HTTP_REQUEST_SUCCEEDED_TIME, mStartTime, + endTime); + } else { + Telemetry::Accumulate(Telemetry::CERT_VALIDATION_HTTP_REQUEST_RESULT, 2); + Telemetry::AccumulateTimeDelta( + Telemetry::CERT_VALIDATION_HTTP_REQUEST_FAILED_TIME, mStartTime, + endTime); + } + return rv; +} + +nsresult OCSPRequest::GetResponse(/*out*/ Vector& response) { + MOZ_ASSERT(!NS_IsMainThread()); + if (NS_IsMainThread()) { + return NS_ERROR_FAILURE; + } + + MonitorAutoLock lock(mMonitor); + if (!mNotifiedDone) { + return NS_ERROR_IN_PROGRESS; + } + if (NS_FAILED(mResponseResult)) { + return mResponseResult; + } + response.clear(); + if (!response.append(mResponseBytes.begin(), mResponseBytes.length())) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +static constexpr auto OCSP_REQUEST_MIME_TYPE = "application/ocsp-request"_ns; +static constexpr auto OCSP_REQUEST_METHOD = "POST"_ns; + +NS_IMETHODIMP +OCSPRequest::Run() { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_FAILURE; + } + + MonitorAutoLock lock(mMonitor); + + nsCOMPtr ios = do_GetIOService(); + if (!ios) { + return NotifyDone(NS_ERROR_FAILURE, lock); + } + + nsCOMPtr uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), mAIALocation); + if (NS_FAILED(rv)) { + return NotifyDone(NS_ERROR_MALFORMED_URI, lock); + } + nsAutoCString scheme; + rv = uri->GetScheme(scheme); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + if (!scheme.LowerCaseEqualsLiteral("http")) { + return NotifyDone(NS_ERROR_MALFORMED_URI, lock); + } + + // See bug 1219935. + // We should not send OCSP request if the PAC is still loading. + nsCOMPtr pps = + do_GetService(NS_PROTOCOLPROXYSERVICE_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + + if (pps->GetIsPACLoading()) { + return NotifyDone(NS_ERROR_FAILURE, lock); + } + + nsCOMPtr channel; + rv = ios->NewChannel(mAIALocation, nullptr, nullptr, + nullptr, // aLoadingNode + nsContentUtils::GetSystemPrincipal(), + nullptr, // aTriggeringPrincipal + nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL, + nsIContentPolicy::TYPE_OTHER, getter_AddRefs(channel)); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + + // Security operations scheduled through normal HTTP channels are given + // high priority to accommodate real time OCSP transactions. + nsCOMPtr priorityChannel = do_QueryInterface(channel); + if (priorityChannel) { + priorityChannel->AdjustPriority(nsISupportsPriority::PRIORITY_HIGHEST); + } + + channel->SetLoadFlags(nsIRequest::LOAD_ANONYMOUS | + nsIChannel::LOAD_BYPASS_SERVICE_WORKER | + nsIChannel::LOAD_BYPASS_URL_CLASSIFIER); + + nsCOMPtr loadInfo = channel->LoadInfo(); + + // Prevent HTTPS-Only Mode from upgrading the OCSP request. + uint32_t httpsOnlyStatus = loadInfo->GetHttpsOnlyStatus(); + httpsOnlyStatus |= nsILoadInfo::HTTPS_ONLY_EXEMPT; + loadInfo->SetHttpsOnlyStatus(httpsOnlyStatus); + + // allow deprecated HTTP request from SystemPrincipal + loadInfo->SetAllowDeprecatedSystemRequests(true); + + // For OCSP requests, only the first party domain and private browsing id + // aspects of origin attributes are used. This means that: + // a) if first party isolation is enabled, OCSP requests will be isolated + // according to the first party domain of the original https request + // b) OCSP requests are shared across different containers as long as first + // party isolation is not enabled and none of the containers are in private + // browsing mode. + if (mOriginAttributes != OriginAttributes()) { + OriginAttributes attrs; + attrs.mFirstPartyDomain = mOriginAttributes.mFirstPartyDomain; + attrs.mPrivateBrowsingId = mOriginAttributes.mPrivateBrowsingId; + + rv = loadInfo->SetOriginAttributes(attrs); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + } + + nsCOMPtr uploadStream; + rv = NS_NewByteInputStream(getter_AddRefs(uploadStream), mPOSTData, + NS_ASSIGNMENT_COPY); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + nsCOMPtr uploadChannel(do_QueryInterface(channel)); + if (!uploadChannel) { + return NotifyDone(NS_ERROR_FAILURE, lock); + } + rv = uploadChannel->SetUploadStream(uploadStream, OCSP_REQUEST_MIME_TYPE, -1); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + // Do not use SPDY or HTTP3 for internal security operations. It could result + // in the silent upgrade to ssl, which in turn could require an SSL + // operation to fulfill something like an OCSP fetch, which is an + // endless loop. + nsCOMPtr internalChannel = do_QueryInterface(channel); + if (!internalChannel) { + return NotifyDone(rv, lock); + } + rv = internalChannel->SetAllowSpdy(false); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + rv = internalChannel->SetAllowHttp3(false); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + nsCOMPtr hchan = do_QueryInterface(channel); + if (!hchan) { + return NotifyDone(NS_ERROR_FAILURE, lock); + } + rv = hchan->SetAllowSTS(false); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + rv = hchan->SetRequestMethod(OCSP_REQUEST_METHOD); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + + rv = NS_NewStreamLoader(getter_AddRefs(mLoader), this); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + + rv = NS_NewTimerWithFuncCallback( + getter_AddRefs(mTimeoutTimer), OCSPRequest::OnTimeout, this, + mTimeout.ToMilliseconds(), nsITimer::TYPE_ONE_SHOT, "OCSPRequest::Run"); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + rv = hchan->AsyncOpen(this->mLoader); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + mStartTime = TimeStamp::Now(); + return NS_OK; +} + +nsresult OCSPRequest::NotifyDone(nsresult rv, MonitorAutoLock& lock) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_FAILURE; + } + + if (mNotifiedDone) { + return mResponseResult; + } + mLoader = nullptr; + mResponseResult = rv; + if (mTimeoutTimer) { + Unused << mTimeoutTimer->Cancel(); + } + mNotifiedDone = true; + lock.Notify(); + return rv; +} + +NS_IMETHODIMP +OCSPRequest::OnStreamComplete(nsIStreamLoader* aLoader, nsISupports* aContext, + nsresult aStatus, uint32_t responseLen, + const uint8_t* responseBytes) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_FAILURE; + } + + MonitorAutoLock lock(mMonitor); + + nsCOMPtr req; + nsresult rv = aLoader->GetRequest(getter_AddRefs(req)); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + + if (NS_FAILED(aStatus)) { + return NotifyDone(aStatus, lock); + } + + nsCOMPtr hchan = do_QueryInterface(req); + if (!hchan) { + return NotifyDone(NS_ERROR_FAILURE, lock); + } + + bool requestSucceeded; + rv = hchan->GetRequestSucceeded(&requestSucceeded); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + if (!requestSucceeded) { + return NotifyDone(NS_ERROR_FAILURE, lock); + } + + unsigned int rcode; + rv = hchan->GetResponseStatus(&rcode); + if (NS_FAILED(rv)) { + return NotifyDone(rv, lock); + } + if (rcode != 200) { + return NotifyDone(NS_ERROR_FAILURE, lock); + } + + mResponseBytes.clear(); + if (!mResponseBytes.append(responseBytes, responseLen)) { + return NotifyDone(NS_ERROR_OUT_OF_MEMORY, lock); + } + mResponseResult = aStatus; + + return NotifyDone(NS_OK, lock); +} + +void OCSPRequest::OnTimeout(nsITimer* timer, void* closure) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return; + } + + // We know the OCSPRequest is still alive because if the request had completed + // (i.e. OnStreamComplete ran), the timer would have been cancelled in + // NotifyDone. + OCSPRequest* self = static_cast(closure); + MonitorAutoLock lock(self->mMonitor); + self->mTimeoutTimer = nullptr; + self->NotifyDone(NS_ERROR_NET_TIMEOUT, lock); +} + +mozilla::pkix::Result DoOCSPRequest( + const nsCString& aiaLocation, const OriginAttributes& originAttributes, + uint8_t (&ocspRequest)[OCSP_REQUEST_MAX_LENGTH], size_t ocspRequestLength, + TimeDuration timeout, /*out*/ Vector& result) { + MOZ_ASSERT(!NS_IsMainThread()); + if (NS_IsMainThread()) { + return mozilla::pkix::Result::ERROR_OCSP_UNKNOWN_CERT; + } + + if (ocspRequestLength > OCSP_REQUEST_MAX_LENGTH) { + return mozilla::pkix::Result::FATAL_ERROR_LIBRARY_FAILURE; + } + + result.clear(); + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("DoOCSPRequest to '%s'", aiaLocation.get())); + + nsCOMPtr sts = + do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID); + MOZ_ASSERT(sts); + if (!sts) { + return mozilla::pkix::Result::FATAL_ERROR_INVALID_STATE; + } + bool onSTSThread; + nsresult rv = sts->IsOnCurrentThread(&onSTSThread); + if (NS_FAILED(rv)) { + return mozilla::pkix::Result::FATAL_ERROR_LIBRARY_FAILURE; + } + MOZ_ASSERT(!onSTSThread); + if (onSTSThread) { + return mozilla::pkix::Result::FATAL_ERROR_INVALID_STATE; + } + + RefPtr request(new OCSPRequest( + aiaLocation, originAttributes, ocspRequest, ocspRequestLength, timeout)); + rv = request->DispatchToMainThreadAndWait(); + if (NS_FAILED(rv)) { + return mozilla::pkix::Result::FATAL_ERROR_LIBRARY_FAILURE; + } + rv = request->GetResponse(result); + if (NS_FAILED(rv)) { + if (rv == NS_ERROR_MALFORMED_URI) { + return mozilla::pkix::Result::ERROR_CERT_BAD_ACCESS_LOCATION; + } + return mozilla::pkix::Result::ERROR_OCSP_SERVER_ERROR; + } + return Success; +} + +static char* ShowProtectedAuthPrompt(PK11SlotInfo* slot, + nsIInterfaceRequestor* ir) { + if (!NS_IsMainThread()) { + NS_ERROR("ShowProtectedAuthPrompt called off the main thread"); + return nullptr; + } + + char* protAuthRetVal = nullptr; + + // Get protected auth dialogs + nsCOMPtr dialogs; + nsresult nsrv = + getNSSDialogs(getter_AddRefs(dialogs), NS_GET_IID(nsITokenDialogs), + NS_TOKENDIALOGS_CONTRACTID); + if (NS_SUCCEEDED(nsrv)) { + RefPtr protectedAuthRunnable = + new nsProtectedAuthThread(); + protectedAuthRunnable->SetParams(slot); + + nsrv = dialogs->DisplayProtectedAuth(ir, protectedAuthRunnable); + + // We call join on the thread, + // so we can be sure that no simultaneous access will happen. + protectedAuthRunnable->Join(); + + if (NS_SUCCEEDED(nsrv)) { + SECStatus rv = protectedAuthRunnable->GetResult(); + switch (rv) { + case SECSuccess: + protAuthRetVal = + ToNewCString(nsDependentCString(PK11_PW_AUTHENTICATED)); + break; + case SECWouldBlock: + protAuthRetVal = ToNewCString(nsDependentCString(PK11_PW_RETRY)); + break; + default: + protAuthRetVal = nullptr; + break; + } + } + } + + return protAuthRetVal; +} + +class PK11PasswordPromptRunnable : public SyncRunnableBase { + public: + PK11PasswordPromptRunnable(PK11SlotInfo* slot, nsIInterfaceRequestor* ir) + : mResult(nullptr), mSlot(slot), mIR(ir) {} + virtual ~PK11PasswordPromptRunnable() = default; + + char* mResult; // out + virtual void RunOnTargetThread() override; + + private: + PK11SlotInfo* const mSlot; // in + nsIInterfaceRequestor* const mIR; // in +}; + +void PK11PasswordPromptRunnable::RunOnTargetThread() { + nsresult rv; + nsCOMPtr prompt; + if (!mIR) { + rv = nsNSSComponent::GetNewPrompter(getter_AddRefs(prompt)); + if (NS_FAILED(rv)) { + return; + } + } else { + prompt = do_GetInterface(mIR); + MOZ_ASSERT(prompt, "Interface requestor should implement nsIPrompt"); + } + + if (!prompt) { + return; + } + + if (PK11_ProtectedAuthenticationPath(mSlot)) { + mResult = ShowProtectedAuthPrompt(mSlot, mIR); + return; + } + + nsAutoString promptString; + if (PK11_IsInternal(mSlot)) { + rv = GetPIPNSSBundleString("CertPasswordPromptDefault", promptString); + } else { + AutoTArray formatStrings = { + NS_ConvertUTF8toUTF16(PK11_GetTokenName(mSlot))}; + rv = PIPBundleFormatStringFromName("CertPasswordPrompt", formatStrings, + promptString); + } + if (NS_FAILED(rv)) { + return; + } + + nsString password; + // |checkState| is unused because |checkMsg| (the argument just before it) is + // null, but XPConnect requires it to point to a valid bool nonetheless. + bool checkState = false; + bool userClickedOK = false; + rv = prompt->PromptPassword(nullptr, promptString.get(), + getter_Copies(password), nullptr, &checkState, + &userClickedOK); + if (NS_FAILED(rv) || !userClickedOK) { + return; + } + + mResult = ToNewUTF8String(password); +} + +char* PK11PasswordPrompt(PK11SlotInfo* slot, PRBool /*retry*/, void* arg) { + RefPtr runnable(new PK11PasswordPromptRunnable( + slot, static_cast(arg))); + runnable->DispatchToMainThreadAndWait(); + return runnable->mResult; +} + +nsCString getKeaGroupName(uint32_t aKeaGroup) { + nsCString groupName; + switch (aKeaGroup) { + case ssl_grp_ec_secp256r1: + groupName = "P256"_ns; + break; + case ssl_grp_ec_secp384r1: + groupName = "P384"_ns; + break; + case ssl_grp_ec_secp521r1: + groupName = "P521"_ns; + break; + case ssl_grp_ec_curve25519: + groupName = "x25519"_ns; + break; + case ssl_grp_ffdhe_2048: + groupName = "FF 2048"_ns; + break; + case ssl_grp_ffdhe_3072: + groupName = "FF 3072"_ns; + break; + case ssl_grp_none: + groupName = "none"_ns; + break; + case ssl_grp_ffdhe_custom: + groupName = "custom"_ns; + break; + // All other groups are not enabled in Firefox. See namedGroups in + // nsNSSIOLayer.cpp. + default: + // This really shouldn't happen! + MOZ_ASSERT_UNREACHABLE("Invalid key exchange group."); + groupName = "unknown group"_ns; + } + return groupName; +} + +nsCString getSignatureName(uint32_t aSignatureScheme) { + nsCString signatureName; + switch (aSignatureScheme) { + case ssl_sig_none: + signatureName = "none"_ns; + break; + case ssl_sig_rsa_pkcs1_sha1: + signatureName = "RSA-PKCS1-SHA1"_ns; + break; + case ssl_sig_rsa_pkcs1_sha256: + signatureName = "RSA-PKCS1-SHA256"_ns; + break; + case ssl_sig_rsa_pkcs1_sha384: + signatureName = "RSA-PKCS1-SHA384"_ns; + break; + case ssl_sig_rsa_pkcs1_sha512: + signatureName = "RSA-PKCS1-SHA512"_ns; + break; + case ssl_sig_ecdsa_secp256r1_sha256: + signatureName = "ECDSA-P256-SHA256"_ns; + break; + case ssl_sig_ecdsa_secp384r1_sha384: + signatureName = "ECDSA-P384-SHA384"_ns; + break; + case ssl_sig_ecdsa_secp521r1_sha512: + signatureName = "ECDSA-P521-SHA512"_ns; + break; + case ssl_sig_rsa_pss_sha256: + signatureName = "RSA-PSS-SHA256"_ns; + break; + case ssl_sig_rsa_pss_sha384: + signatureName = "RSA-PSS-SHA384"_ns; + break; + case ssl_sig_rsa_pss_sha512: + signatureName = "RSA-PSS-SHA512"_ns; + break; + case ssl_sig_ecdsa_sha1: + signatureName = "ECDSA-SHA1"_ns; + break; + case ssl_sig_rsa_pkcs1_sha1md5: + signatureName = "RSA-PKCS1-SHA1MD5"_ns; + break; + // All other groups are not enabled in Firefox. See sEnabledSignatureSchemes + // in nsNSSIOLayer.cpp. + default: + // This really shouldn't happen! + MOZ_ASSERT_UNREACHABLE("Invalid signature scheme."); + signatureName = "unknown signature"_ns; + } + return signatureName; +} + +// call with shutdown prevention lock held +static void PreliminaryHandshakeDone(PRFileDesc* fd) { + nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*)fd->higher->secret; + if (!infoObject) return; + + SSLChannelInfo channelInfo; + if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) == SECSuccess) { + infoObject->SetSSLVersionUsed(channelInfo.protocolVersion); + infoObject->SetEarlyDataAccepted(channelInfo.earlyDataAccepted); + infoObject->SetResumed(channelInfo.resumed); + + SSLCipherSuiteInfo cipherInfo; + if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo, + sizeof cipherInfo) == SECSuccess) { + /* Set the Status information */ + infoObject->mHaveCipherSuiteAndProtocol = true; + infoObject->mCipherSuite = channelInfo.cipherSuite; + infoObject->mProtocolVersion = channelInfo.protocolVersion & 0xFF; + infoObject->mKeaGroup.Assign(getKeaGroupName(channelInfo.keaGroup)); + infoObject->mSignatureSchemeName.Assign( + getSignatureName(channelInfo.signatureScheme)); + infoObject->SetKEAUsed(channelInfo.keaType); + infoObject->SetKEAKeyBits(channelInfo.keaKeyBits); + infoObject->SetMACAlgorithmUsed(cipherInfo.macAlgorithm); + infoObject->mIsDelegatedCredential = channelInfo.peerDelegCred; + infoObject->mIsAcceptedEch = channelInfo.echAccepted; + } + } + + // Don't update NPN details on renegotiation. + if (infoObject->IsPreliminaryHandshakeDone()) { + return; + } + + // Get the NPN value. + SSLNextProtoState state; + unsigned char npnbuf[256]; + unsigned int npnlen; + + if (SSL_GetNextProto(fd, &state, npnbuf, &npnlen, + AssertedCast(ArrayLength(npnbuf))) == + SECSuccess) { + if (state == SSL_NEXT_PROTO_NEGOTIATED || + state == SSL_NEXT_PROTO_SELECTED) { + infoObject->SetNegotiatedNPN(BitwiseCast(npnbuf), + npnlen); + } else { + infoObject->SetNegotiatedNPN(nullptr, 0); + } + mozilla::Telemetry::Accumulate(Telemetry::SSL_NPN_TYPE, state); + } else { + infoObject->SetNegotiatedNPN(nullptr, 0); + } + + infoObject->SetPreliminaryHandshakeDone(); +} + +SECStatus CanFalseStartCallback(PRFileDesc* fd, void* client_data, + PRBool* canFalseStart) { + *canFalseStart = false; + + nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*)fd->higher->secret; + if (!infoObject) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + return SECFailure; + } + + infoObject->SetFalseStartCallbackCalled(); + + PreliminaryHandshakeDone(fd); + + uint32_t reasonsForNotFalseStarting = 0; + + SSLChannelInfo channelInfo; + if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) != SECSuccess) { + return SECSuccess; + } + + SSLCipherSuiteInfo cipherInfo; + if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo, + sizeof(cipherInfo)) != SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("CanFalseStartCallback [%p] failed - " + " KEA %d\n", + fd, static_cast(channelInfo.keaType))); + return SECSuccess; + } + + // Prevent version downgrade attacks from TLS 1.2, and avoid False Start for + // TLS 1.3 and later. See Bug 861310 for all the details as to why. + if (channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_2) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("CanFalseStartCallback [%p] failed - " + "SSL Version must be TLS 1.2, was %x\n", + fd, static_cast(channelInfo.protocolVersion))); + reasonsForNotFalseStarting |= POSSIBLE_VERSION_DOWNGRADE; + } + + // See bug 952863 for why ECDHE is allowed, but DHE (and RSA) are not. + if (channelInfo.keaType != ssl_kea_ecdh) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("CanFalseStartCallback [%p] failed - " + "unsupported KEA %d\n", + fd, static_cast(channelInfo.keaType))); + reasonsForNotFalseStarting |= KEA_NOT_SUPPORTED; + } + + // Prevent downgrade attacks on the symmetric cipher. We do not allow CBC + // mode due to BEAST, POODLE, and other attacks on the MAC-then-Encrypt + // design. See bug 1109766 for more details. + if (cipherInfo.macAlgorithm != ssl_mac_aead) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("CanFalseStartCallback [%p] failed - non-AEAD cipher used, %d, " + "is not supported with False Start.\n", + fd, static_cast(cipherInfo.symCipher))); + reasonsForNotFalseStarting |= POSSIBLE_CIPHER_SUITE_DOWNGRADE; + } + + // XXX: An attacker can choose which protocols are advertised in the + // NPN extension. TODO(Bug 861311): We should restrict the ability + // of an attacker leverage this capability by restricting false start + // to the same protocol we previously saw for the server, after the + // first successful connection to the server. + + Telemetry::Accumulate(Telemetry::SSL_REASONS_FOR_NOT_FALSE_STARTING, + reasonsForNotFalseStarting); + + if (reasonsForNotFalseStarting == 0) { + *canFalseStart = PR_TRUE; + infoObject->SetFalseStarted(); + infoObject->NoteTimeUntilReady(); + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("CanFalseStartCallback [%p] ok\n", fd)); + } + + return SECSuccess; +} + +static void AccumulateNonECCKeySize(Telemetry::HistogramID probe, + uint32_t bits) { + unsigned int value = bits < 512 ? 1 + : bits == 512 ? 2 + : bits < 768 ? 3 + : bits == 768 ? 4 + : bits < 1024 ? 5 + : bits == 1024 ? 6 + : bits < 1280 ? 7 + : bits == 1280 ? 8 + : bits < 1536 ? 9 + : bits == 1536 ? 10 + : bits < 2048 ? 11 + : bits == 2048 ? 12 + : bits < 3072 ? 13 + : bits == 3072 ? 14 + : bits < 4096 ? 15 + : bits == 4096 ? 16 + : bits < 8192 ? 17 + : bits == 8192 ? 18 + : bits < 16384 ? 19 + : bits == 16384 ? 20 + : 0; + Telemetry::Accumulate(probe, value); +} + +// XXX: This attempts to map a bit count to an ECC named curve identifier. In +// the vast majority of situations, we only have the Suite B curves available. +// In that case, this mapping works fine. If we were to have more curves +// available, the mapping would be ambiguous since there could be multiple +// named curves for a given size (e.g. secp256k1 vs. secp256r1). We punt on +// that for now. See also NSS bug 323674. +static void AccumulateECCCurve(Telemetry::HistogramID probe, uint32_t bits) { + unsigned int value = bits == 255 ? 29 // Curve25519 + : bits == 256 ? 23 // P-256 + : bits == 384 ? 24 // P-384 + : bits == 521 ? 25 // P-521 + : 0; // Unknown + Telemetry::Accumulate(probe, value); +} + +static void AccumulateCipherSuite(Telemetry::HistogramID probe, + const SSLChannelInfo& channelInfo) { + uint32_t value; + switch (channelInfo.cipherSuite) { + // ECDHE key exchange + case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: + value = 1; + break; + case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: + value = 2; + break; + case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: + value = 3; + break; + case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: + value = 4; + break; + case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: + value = 5; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: + value = 6; + break; + case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: + value = 7; + break; + case TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA: + value = 10; + break; + case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256: + value = 11; + break; + case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256: + value = 12; + break; + case TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384: + value = 13; + break; + case TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384: + value = 14; + break; + // DHE key exchange + case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: + value = 21; + break; + case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: + value = 22; + break; + case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: + value = 23; + break; + case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: + value = 24; + break; + case TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA: + value = 25; + break; + case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: + value = 26; + break; + case TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: + value = 27; + break; + case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: + value = 28; + break; + case TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: + value = 29; + break; + case TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA: + value = 30; + break; + // ECDH key exchange + case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: + value = 41; + break; + case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: + value = 42; + break; + case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: + value = 43; + break; + case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: + value = 44; + break; + case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: + value = 45; + break; + case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: + value = 46; + break; + // RSA key exchange + case TLS_RSA_WITH_AES_128_CBC_SHA: + value = 61; + break; + case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: + value = 62; + break; + case TLS_RSA_WITH_AES_256_CBC_SHA: + value = 63; + break; + case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: + value = 64; + break; + case SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA: + value = 65; + break; + case TLS_RSA_WITH_3DES_EDE_CBC_SHA: + value = 66; + break; + case TLS_RSA_WITH_SEED_CBC_SHA: + value = 67; + break; + case TLS_RSA_WITH_AES_128_GCM_SHA256: + value = 68; + break; + case TLS_RSA_WITH_AES_256_GCM_SHA384: + value = 69; + break; + // TLS 1.3 PSK resumption + case TLS_AES_128_GCM_SHA256: + value = 70; + break; + case TLS_CHACHA20_POLY1305_SHA256: + value = 71; + break; + case TLS_AES_256_GCM_SHA384: + value = 72; + break; + // unknown + default: + value = 0; + break; + } + MOZ_ASSERT(value != 0); + Telemetry::Accumulate(probe, value); +} + +// In the case of session resumption, the AuthCertificate hook has been bypassed +// (because we've previously successfully connected to our peer). That being the +// case, we unfortunately don't know what the verified certificate chain was, if +// the peer's server certificate verified as extended validation, or what its CT +// status is (if enabled). To address this, we attempt to build a certificate +// chain here using as much of the original context as possible (e.g. stapled +// OCSP responses, SCTs, the hostname, the first party domain, etc.). Note that +// because we are on the socket thread, this must not cause any network +// requests, hence the use of FLAG_LOCAL_ONLY. +static void RebuildVerifiedCertificateInformation(PRFileDesc* fd, + nsNSSSocketInfo* infoObject) { + MOZ_ASSERT(fd); + MOZ_ASSERT(infoObject); + + if (!fd || !infoObject) { + return; + } + + UniqueCERTCertificate cert(SSL_PeerCertificate(fd)); + MOZ_ASSERT(cert, "SSL_PeerCertificate failed in TLS handshake callback?"); + if (!cert) { + return; + } + + Maybe>> maybePeerCertsBytes; + UniqueCERTCertList peerCertChain(SSL_PeerCertificateChain(fd)); + if (!peerCertChain) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("RebuildVerifiedCertificateInformation: failed to get peer " + "certificate chain")); + } else { + nsTArray> peerCertsBytes; + for (CERTCertListNode* n = CERT_LIST_HEAD(peerCertChain); + !CERT_LIST_END(n, peerCertChain); n = CERT_LIST_NEXT(n)) { + // Don't include the end-entity certificate. + if (n == CERT_LIST_HEAD(peerCertChain)) { + continue; + } + nsTArray certBytes; + certBytes.AppendElements(n->cert->derCert.data, n->cert->derCert.len); + peerCertsBytes.AppendElement(std::move(certBytes)); + } + maybePeerCertsBytes.emplace(std::move(peerCertsBytes)); + } + + RefPtr certVerifier(GetDefaultCertVerifier()); + MOZ_ASSERT(certVerifier, + "Certificate verifier uninitialized in TLS handshake callback?"); + if (!certVerifier) { + return; + } + + // We don't own these pointers. + const SECItemArray* stapledOCSPResponses = SSL_PeerStapledOCSPResponses(fd); + Maybe> stapledOCSPResponse; + // we currently only support single stapled responses + if (stapledOCSPResponses && stapledOCSPResponses->len == 1) { + stapledOCSPResponse.emplace(); + stapledOCSPResponse->SetCapacity(stapledOCSPResponses->items[0].len); + stapledOCSPResponse->AppendElements(stapledOCSPResponses->items[0].data, + stapledOCSPResponses->items[0].len); + } + + Maybe> sctsFromTLSExtension; + const SECItem* sctsFromTLSExtensionSECItem = SSL_PeerSignedCertTimestamps(fd); + if (sctsFromTLSExtensionSECItem) { + sctsFromTLSExtension.emplace(); + sctsFromTLSExtension->SetCapacity(sctsFromTLSExtensionSECItem->len); + sctsFromTLSExtension->AppendElements(sctsFromTLSExtensionSECItem->data, + sctsFromTLSExtensionSECItem->len); + } + + int flags = mozilla::psm::CertVerifier::FLAG_LOCAL_ONLY; + if (!infoObject->SharedState().IsOCSPStaplingEnabled() || + !infoObject->SharedState().IsOCSPMustStapleEnabled()) { + flags |= CertVerifier::FLAG_TLS_IGNORE_STATUS_REQUEST; + } + + SECOidTag evOidPolicy; + CertificateTransparencyInfo certificateTransparencyInfo; + UniqueCERTCertList builtChain; + const bool saveIntermediates = false; + bool isBuiltCertChainRootBuiltInRoot = false; + mozilla::pkix::Result rv = certVerifier->VerifySSLServerCert( + cert, mozilla::pkix::Now(), infoObject, infoObject->GetHostName(), + builtChain, flags, maybePeerCertsBytes, stapledOCSPResponse, + sctsFromTLSExtension, Nothing(), infoObject->GetOriginAttributes(), + saveIntermediates, &evOidPolicy, + nullptr, // OCSP stapling telemetry + nullptr, // key size telemetry + nullptr, // SHA-1 telemetry + nullptr, // pinning telemetry + &certificateTransparencyInfo, + nullptr, // CRLite telemetry, + &isBuiltCertChainRootBuiltInRoot); + + if (rv != Success) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("HandshakeCallback: couldn't rebuild verified certificate info")); + } + + RefPtr nssc(nsNSSCertificate::Create(cert.get())); + if (rv == Success && evOidPolicy != SEC_OID_UNKNOWN) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("HandshakeCallback using NEW cert %p (is EV)", nssc.get())); + infoObject->SetServerCert(nssc, EVStatus::EV); + } else { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("HandshakeCallback using NEW cert %p (is not EV)", nssc.get())); + infoObject->SetServerCert(nssc, EVStatus::NotEV); + } + + if (rv == Success) { + uint16_t status = + TransportSecurityInfo::ConvertCertificateTransparencyInfoToStatus( + certificateTransparencyInfo); + infoObject->SetCertificateTransparencyStatus(status); + nsTArray> certBytesArray = + TransportSecurityInfo::CreateCertBytesArray(builtChain); + infoObject->SetSucceededCertChain(std::move(certBytesArray)); + infoObject->SetIsBuiltCertChainRootBuiltInRoot( + isBuiltCertChainRootBuiltInRoot); + } +} + +nsresult IsCertificateDistrustImminent( + const nsTArray>& aCertArray, + /* out */ bool& isDistrusted) { + if (aCertArray.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + + nsCOMPtr rootCert; + nsTArray> intCerts; + nsCOMPtr eeCert; + + nsresult rv = nsNSSCertificate::SegmentCertificateChain(aCertArray, rootCert, + intCerts, eeCert); + if (NS_FAILED(rv)) { + return rv; + } + + // Check the test certificate condition first; this is a special certificate + // that gets the 'imminent distrust' treatment; this is so that the distrust + // UX code does not become stale, as it will need regular use. See Bug 1409257 + // for context. Please do not remove this when adjusting the rest of the + // method. + UniqueCERTCertificate nssEECert(eeCert->GetCert()); + if (!nssEECert) { + return NS_ERROR_FAILURE; + } + isDistrusted = + CertDNIsInList(nssEECert.get(), TestImminentDistrustEndEntityDNs); + if (isDistrusted) { + // Exit early + return NS_OK; + } + + UniqueCERTCertificate nssRootCert(rootCert->GetCert()); + if (!nssRootCert) { + return NS_ERROR_FAILURE; + } + + // Proceed with the Symantec imminent distrust algorithm. This algorithm is + // to be removed in Firefox 63, when the validity period check will also be + // removed from the code in NSSCertDBTrustDomain. + if (CertDNIsInList(nssRootCert.get(), RootSymantecDNs)) { + rv = CheckForSymantecDistrust(intCerts, RootAppleAndGoogleSPKIs, + isDistrusted); + if (NS_FAILED(rv)) { + return rv; + } + } + return NS_OK; +} + +void HandshakeCallback(PRFileDesc* fd, void* client_data) { + SECStatus rv; + + nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*)fd->higher->secret; + + // Do the bookkeeping that needs to be done after the + // server's ServerHello...ServerHelloDone have been processed, but that + // doesn't need the handshake to be completed. + PreliminaryHandshakeDone(fd); + + nsSSLIOLayerHelpers& ioLayerHelpers = + infoObject->SharedState().IOLayerHelpers(); + + SSLVersionRange versions(infoObject->GetTLSVersionRange()); + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] HandshakeCallback: succeeded using TLS version range " + "(0x%04x,0x%04x)\n", + fd, static_cast(versions.min), + static_cast(versions.max))); + + // If the handshake completed, then we know the site is TLS tolerant + ioLayerHelpers.rememberTolerantAtVersion(infoObject->GetHostName(), + infoObject->GetPort(), versions.max); + + SSLChannelInfo channelInfo; + rv = SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)); + MOZ_ASSERT(rv == SECSuccess); + if (rv == SECSuccess) { + // Get the protocol version for telemetry + // 1=tls1, 2=tls1.1, 3=tls1.2 + unsigned int versionEnum = channelInfo.protocolVersion & 0xFF; + MOZ_ASSERT(versionEnum > 0); + Telemetry::Accumulate(Telemetry::SSL_HANDSHAKE_VERSION, versionEnum); + AccumulateCipherSuite(infoObject->IsFullHandshake() + ? Telemetry::SSL_CIPHER_SUITE_FULL + : Telemetry::SSL_CIPHER_SUITE_RESUMED, + channelInfo); + + SSLCipherSuiteInfo cipherInfo; + rv = SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo, + sizeof cipherInfo); + MOZ_ASSERT(rv == SECSuccess); + if (rv == SECSuccess) { + // keyExchange null=0, rsa=1, dh=2, fortezza=3, ecdh=4 + Telemetry::Accumulate(infoObject->IsFullHandshake() + ? Telemetry::SSL_KEY_EXCHANGE_ALGORITHM_FULL + : Telemetry::SSL_KEY_EXCHANGE_ALGORITHM_RESUMED, + channelInfo.keaType); + + MOZ_ASSERT(infoObject->GetKEAUsed() == channelInfo.keaType); + + if (infoObject->IsFullHandshake()) { + switch (channelInfo.keaType) { + case ssl_kea_rsa: + AccumulateNonECCKeySize(Telemetry::SSL_KEA_RSA_KEY_SIZE_FULL, + channelInfo.keaKeyBits); + break; + case ssl_kea_dh: + AccumulateNonECCKeySize(Telemetry::SSL_KEA_DHE_KEY_SIZE_FULL, + channelInfo.keaKeyBits); + break; + case ssl_kea_ecdh: + AccumulateECCCurve(Telemetry::SSL_KEA_ECDHE_CURVE_FULL, + channelInfo.keaKeyBits); + break; + default: + MOZ_CRASH("impossible KEA"); + break; + } + + Telemetry::Accumulate(Telemetry::SSL_AUTH_ALGORITHM_FULL, + channelInfo.authType); + + // RSA key exchange doesn't use a signature for auth. + if (channelInfo.keaType != ssl_kea_rsa) { + switch (channelInfo.authType) { + case ssl_auth_rsa: + case ssl_auth_rsa_sign: + AccumulateNonECCKeySize(Telemetry::SSL_AUTH_RSA_KEY_SIZE_FULL, + channelInfo.authKeyBits); + break; + case ssl_auth_ecdsa: + AccumulateECCCurve(Telemetry::SSL_AUTH_ECDSA_CURVE_FULL, + channelInfo.authKeyBits); + break; + default: + MOZ_CRASH("impossible auth algorithm"); + break; + } + } + } + + Telemetry::Accumulate(infoObject->IsFullHandshake() + ? Telemetry::SSL_SYMMETRIC_CIPHER_FULL + : Telemetry::SSL_SYMMETRIC_CIPHER_RESUMED, + cipherInfo.symCipher); + } + } + + PRBool siteSupportsSafeRenego; + if (channelInfo.protocolVersion != SSL_LIBRARY_VERSION_TLS_1_3) { + rv = SSL_HandshakeNegotiatedExtension(fd, ssl_renegotiation_info_xtn, + &siteSupportsSafeRenego); + MOZ_ASSERT(rv == SECSuccess); + if (rv != SECSuccess) { + siteSupportsSafeRenego = false; + } + } else { + // TLS 1.3 dropped support for renegotiation. + siteSupportsSafeRenego = true; + } + bool renegotiationUnsafe = !siteSupportsSafeRenego && + ioLayerHelpers.treatUnsafeNegotiationAsBroken(); + + bool deprecatedTlsVer = + (channelInfo.protocolVersion < SSL_LIBRARY_VERSION_TLS_1_2); + RememberCertErrorsTable::GetInstance().LookupCertErrorBits(infoObject); + + uint32_t state; + if (renegotiationUnsafe || deprecatedTlsVer) { + state = nsIWebProgressListener::STATE_IS_BROKEN; + } else { + state = nsIWebProgressListener::STATE_IS_SECURE; + SSLVersionRange defVersion; + rv = SSL_VersionRangeGetDefault(ssl_variant_stream, &defVersion); + if (rv == SECSuccess && versions.max >= defVersion.max) { + // we know this site no longer requires a version fallback + ioLayerHelpers.removeInsecureFallbackSite(infoObject->GetHostName(), + infoObject->GetPort()); + } + } + + if (infoObject->HasServerCert()) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("HandshakeCallback KEEPING existing cert\n")); + } else { + if (StaticPrefs::network_ssl_tokens_cache_enabled()) { + infoObject->RebuildCertificateInfoFromSSLTokenCache(); + } else { + RebuildVerifiedCertificateInformation(fd, infoObject); + } + } + + nsTArray> succeededCertArray; + // The list could be empty. Bug 731478 will reduce the incidence of empty + // succeeded cert chains through better caching. + nsresult srv = infoObject->GetSucceededCertChain(succeededCertArray); + + bool distrustImminent; + if (NS_SUCCEEDED(srv)) { + srv = IsCertificateDistrustImminent(succeededCertArray, distrustImminent); + } + + if (NS_SUCCEEDED(srv) && distrustImminent) { + state |= nsIWebProgressListener::STATE_CERT_DISTRUST_IMMINENT; + } + + bool domainMismatch; + bool untrusted; + bool notValidAtThisTime; + // These all return NS_OK, so don't even bother checking the return values. + Unused << infoObject->GetIsDomainMismatch(&domainMismatch); + Unused << infoObject->GetIsUntrusted(&untrusted); + Unused << infoObject->GetIsNotValidAtThisTime(¬ValidAtThisTime); + // If we're here, the TLS handshake has succeeded. Thus if any of these + // booleans are true, the user has added an override for a certificate error. + if (domainMismatch || untrusted || notValidAtThisTime) { + state |= nsIWebProgressListener::STATE_CERT_USER_OVERRIDDEN; + } + + infoObject->SetSecurityState(state); + + // XXX Bug 883674: We shouldn't be formatting messages here in PSM; instead, + // we should set a flag on the channel that higher (UI) level code can check + // to log the warning. In particular, these warnings should go to the web + // console instead of to the error console. Also, the warning is not + // localized. + if (!siteSupportsSafeRenego) { + NS_ConvertASCIItoUTF16 msg(infoObject->GetHostName()); + msg.AppendLiteral(" : server does not support RFC 5746, see CVE-2009-3555"); + + nsContentUtils::LogSimpleConsoleError( + msg, "SSL", !!infoObject->GetOriginAttributes().mPrivateBrowsingId, + true /* from chrome context */); + } + + infoObject->NoteTimeUntilReady(); + infoObject->SetHandshakeCompleted(); +} diff --git a/security/manager/ssl/nsNSSCallbacks.h b/security/manager/ssl/nsNSSCallbacks.h new file mode 100644 index 0000000000..18b7a83540 --- /dev/null +++ b/security/manager/ssl/nsNSSCallbacks.h @@ -0,0 +1,45 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef nsNSSCallbacks_h +#define nsNSSCallbacks_h + +#include "mozilla/Attributes.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/TimeStamp.h" +#include "mozilla/Vector.h" +#include "nspr.h" +#include "nsString.h" +#include "pk11func.h" +#include "mozpkix/pkix.h" +#include "mozpkix/pkixtypes.h" +#include "nsIX509Cert.h" + +using mozilla::OriginAttributes; +using mozilla::TimeDuration; +using mozilla::Vector; + +class nsILoadGroup; + +char* PK11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg); + +void HandshakeCallback(PRFileDesc* fd, void* client_data); +SECStatus CanFalseStartCallback(PRFileDesc* fd, void* client_data, + PRBool* canFalseStart); + +mozilla::pkix::Result DoOCSPRequest( + const nsCString& aiaLocation, const OriginAttributes& originAttributes, + uint8_t (&ocspRequest)[mozilla::pkix::OCSP_REQUEST_MAX_LENGTH], + size_t ocspRequestLength, TimeDuration timeout, + /*out*/ Vector& result); + +nsCString getKeaGroupName(uint32_t aKeaGroup); +nsCString getSignatureName(uint32_t aSignatureScheme); +nsresult IsCertificateDistrustImminent( + const nsTArray>& aCertArray, + /* out */ bool& isDistrusted); + +#endif // nsNSSCallbacks_h diff --git a/security/manager/ssl/nsNSSCertHelper.cpp b/security/manager/ssl/nsNSSCertHelper.cpp new file mode 100644 index 0000000000..faff726b7e --- /dev/null +++ b/security/manager/ssl/nsNSSCertHelper.cpp @@ -0,0 +1,100 @@ +/* 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/. */ + +#include "nsNSSCertHelper.h" + +#include + +#include "DateTimeFormat.h" +#include "ScopedNSSTypes.h" +#include "mozilla/Assertions.h" +#include "mozilla/Casting.h" +#include "mozilla/NotNull.h" +#include "mozilla/Sprintf.h" +#include "mozilla/UniquePtr.h" +#include "mozilla/Utf8.h" +#include "mozilla/net/DNS.h" +#include "nsCOMPtr.h" +#include "nsIStringBundle.h" +#include "nsNSSCertificate.h" +#include "nsReadableUtils.h" +#include "nsServiceManagerUtils.h" +#include "nsThreadUtils.h" +#include "prerror.h" +#include "prnetdb.h" +#include "secder.h" + +using namespace mozilla; + +// To avoid relying on localized strings in PSM, we hard-code the root module +// name internally. When we display it to the user in the list of modules in the +// front-end, we look up the localized value and display that instead of this. +const char* kRootModuleName = "Builtin Roots Module"; +const size_t kRootModuleNameLen = strlen(kRootModuleName); + +static nsresult GetPIPNSSBundle(nsIStringBundle** pipnssBundle) { + nsCOMPtr bundleService( + do_GetService(NS_STRINGBUNDLE_CONTRACTID)); + if (!bundleService) { + return NS_ERROR_NOT_AVAILABLE; + } + return bundleService->CreateBundle("chrome://pipnss/locale/pipnss.properties", + pipnssBundle); +} + +nsresult GetPIPNSSBundleString(const char* stringName, nsAString& result) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + MOZ_ASSERT(stringName); + if (!stringName) { + return NS_ERROR_INVALID_ARG; + } + nsCOMPtr pipnssBundle; + nsresult rv = GetPIPNSSBundle(getter_AddRefs(pipnssBundle)); + if (NS_FAILED(rv)) { + return rv; + } + result.Truncate(); + return pipnssBundle->GetStringFromName(stringName, result); +} + +nsresult GetPIPNSSBundleString(const char* stringName, nsACString& result) { + nsAutoString tmp; + nsresult rv = GetPIPNSSBundleString(stringName, tmp); + if (NS_FAILED(rv)) { + return rv; + } + result.Assign(NS_ConvertUTF16toUTF8(tmp)); + return NS_OK; +} + +nsresult PIPBundleFormatStringFromName(const char* stringName, + const nsTArray& params, + nsAString& result) { + MOZ_ASSERT(stringName); + MOZ_ASSERT(!params.IsEmpty()); + if (!stringName || params.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + nsCOMPtr pipnssBundle; + nsresult rv = GetPIPNSSBundle(getter_AddRefs(pipnssBundle)); + if (NS_FAILED(rv)) { + return rv; + } + result.Truncate(); + return pipnssBundle->FormatStringFromName(stringName, params, result); +} + +void LossyUTF8ToUTF16(const char* str, uint32_t len, + /*out*/ nsAString& result) { + auto span = Span(str, len); + if (IsUtf8(span)) { + CopyUTF8toUTF16(span, result); + } else { + // Actually Latin1 despite ASCII in the legacy name + CopyASCIItoUTF16(span, result); + } +} diff --git a/security/manager/ssl/nsNSSCertHelper.h b/security/manager/ssl/nsNSSCertHelper.h new file mode 100644 index 0000000000..453e2e21eb --- /dev/null +++ b/security/manager/ssl/nsNSSCertHelper.h @@ -0,0 +1,31 @@ +/* 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/. */ + +#ifndef nsNSSCertHelper_h +#define nsNSSCertHelper_h + +#ifndef INET6_ADDRSTRLEN +# define INET6_ADDRSTRLEN 46 +#endif + +#include "certt.h" +#include "nsString.h" + +extern const char* kRootModuleName; +extern const size_t kRootModuleNameLen; + +class nsIX509Cert; + +// If input is valid UTF-8, converts from UTF-8 to UTF-16. Otherwise, +// converts from Latin1 to UTF-16. +void LossyUTF8ToUTF16(const char* str, uint32_t len, /*out*/ nsAString& result); + +// Must be used on the main thread only. +nsresult GetPIPNSSBundleString(const char* stringName, nsAString& result); +nsresult GetPIPNSSBundleString(const char* stringName, nsACString& result); +nsresult PIPBundleFormatStringFromName(const char* stringName, + const nsTArray& params, + nsAString& result); + +#endif // nsNSSCertHelper_h diff --git a/security/manager/ssl/nsNSSCertTrust.cpp b/security/manager/ssl/nsNSSCertTrust.cpp new file mode 100644 index 0000000000..f5855c92c6 --- /dev/null +++ b/security/manager/ssl/nsNSSCertTrust.cpp @@ -0,0 +1,121 @@ +/* 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/. */ + +#include "nsNSSCertTrust.h" + +#include "certdb.h" + +void nsNSSCertTrust::AddCATrust(bool ssl, bool email) { + if (ssl) { + addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CA); + addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CLIENT_CA); + } + if (email) { + addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CA); + addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA); + } +} + +void nsNSSCertTrust::AddPeerTrust(bool ssl, bool email) { + if (ssl) addTrust(&mTrust.sslFlags, CERTDB_TRUSTED); + if (email) addTrust(&mTrust.emailFlags, CERTDB_TRUSTED); +} + +nsNSSCertTrust::nsNSSCertTrust() { memset(&mTrust, 0, sizeof(CERTCertTrust)); } + +nsNSSCertTrust::nsNSSCertTrust(unsigned int ssl, unsigned int email) { + memset(&mTrust, 0, sizeof(CERTCertTrust)); + addTrust(&mTrust.sslFlags, ssl); + addTrust(&mTrust.emailFlags, email); +} + +nsNSSCertTrust::nsNSSCertTrust(CERTCertTrust* t) { + if (t) + memcpy(&mTrust, t, sizeof(CERTCertTrust)); + else + memset(&mTrust, 0, sizeof(CERTCertTrust)); +} + +nsNSSCertTrust::~nsNSSCertTrust() = default; + +void nsNSSCertTrust::SetSSLTrust(bool peer, bool tPeer, bool ca, bool tCA, + bool tClientCA, bool user, bool warn) { + mTrust.sslFlags = 0; + if (peer || tPeer) addTrust(&mTrust.sslFlags, CERTDB_TERMINAL_RECORD); + if (tPeer) addTrust(&mTrust.sslFlags, CERTDB_TRUSTED); + if (ca || tCA) addTrust(&mTrust.sslFlags, CERTDB_VALID_CA); + if (tClientCA) addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CLIENT_CA); + if (tCA) addTrust(&mTrust.sslFlags, CERTDB_TRUSTED_CA); + if (user) addTrust(&mTrust.sslFlags, CERTDB_USER); + if (warn) addTrust(&mTrust.sslFlags, CERTDB_SEND_WARN); +} + +void nsNSSCertTrust::SetEmailTrust(bool peer, bool tPeer, bool ca, bool tCA, + bool tClientCA, bool user, bool warn) { + mTrust.emailFlags = 0; + if (peer || tPeer) addTrust(&mTrust.emailFlags, CERTDB_TERMINAL_RECORD); + if (tPeer) addTrust(&mTrust.emailFlags, CERTDB_TRUSTED); + if (ca || tCA) addTrust(&mTrust.emailFlags, CERTDB_VALID_CA); + if (tClientCA) addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA); + if (tCA) addTrust(&mTrust.emailFlags, CERTDB_TRUSTED_CA); + if (user) addTrust(&mTrust.emailFlags, CERTDB_USER); + if (warn) addTrust(&mTrust.emailFlags, CERTDB_SEND_WARN); +} + +void nsNSSCertTrust::SetValidCA() { + SetSSLTrust(false, false, true, false, false, false, false); + SetEmailTrust(false, false, true, false, false, false, false); +} + +void nsNSSCertTrust::SetValidPeer() { + SetSSLTrust(true, false, false, false, false, false, false); + SetEmailTrust(true, false, false, false, false, false, false); +} + +bool nsNSSCertTrust::HasAnyCA() { + if (hasTrust(mTrust.sslFlags, CERTDB_VALID_CA) || + hasTrust(mTrust.emailFlags, CERTDB_VALID_CA) || + hasTrust(mTrust.objectSigningFlags, CERTDB_VALID_CA)) + return true; + return false; +} + +bool nsNSSCertTrust::HasPeer(bool checkSSL, bool checkEmail) { + if (checkSSL && !hasTrust(mTrust.sslFlags, CERTDB_TERMINAL_RECORD)) + return false; + if (checkEmail && !hasTrust(mTrust.emailFlags, CERTDB_TERMINAL_RECORD)) + return false; + return true; +} + +bool nsNSSCertTrust::HasAnyUser() { + if (hasTrust(mTrust.sslFlags, CERTDB_USER) || + hasTrust(mTrust.emailFlags, CERTDB_USER) || + hasTrust(mTrust.objectSigningFlags, CERTDB_USER)) + return true; + return false; +} + +bool nsNSSCertTrust::HasTrustedCA(bool checkSSL, bool checkEmail) { + if (checkSSL && !(hasTrust(mTrust.sslFlags, CERTDB_TRUSTED_CA) || + hasTrust(mTrust.sslFlags, CERTDB_TRUSTED_CLIENT_CA))) + return false; + if (checkEmail && !(hasTrust(mTrust.emailFlags, CERTDB_TRUSTED_CA) || + hasTrust(mTrust.emailFlags, CERTDB_TRUSTED_CLIENT_CA))) + return false; + return true; +} + +bool nsNSSCertTrust::HasTrustedPeer(bool checkSSL, bool checkEmail) { + if (checkSSL && !(hasTrust(mTrust.sslFlags, CERTDB_TRUSTED))) return false; + if (checkEmail && !(hasTrust(mTrust.emailFlags, CERTDB_TRUSTED))) + return false; + return true; +} + +void nsNSSCertTrust::addTrust(unsigned int* t, unsigned int v) { *t |= v; } + +bool nsNSSCertTrust::hasTrust(unsigned int t, unsigned int v) { + return !!(t & v); +} diff --git a/security/manager/ssl/nsNSSCertTrust.h b/security/manager/ssl/nsNSSCertTrust.h new file mode 100644 index 0000000000..3f05d28993 --- /dev/null +++ b/security/manager/ssl/nsNSSCertTrust.h @@ -0,0 +1,55 @@ +/* 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/. */ + +#ifndef nsNSSCertTrust_h +#define nsNSSCertTrust_h + +#include "certt.h" + +/* + * Class for maintaining trust flags for an NSS certificate. + */ +class nsNSSCertTrust { + public: + nsNSSCertTrust(); + nsNSSCertTrust(unsigned int ssl, unsigned int email); + explicit nsNSSCertTrust(CERTCertTrust* t); + virtual ~nsNSSCertTrust(); + + /* query */ + bool HasAnyCA(); + bool HasAnyUser(); + bool HasPeer(bool checkSSL = true, bool checkEmail = true); + bool HasTrustedCA(bool checkSSL = true, bool checkEmail = true); + bool HasTrustedPeer(bool checkSSL = true, bool checkEmail = true); + + /* common defaults */ + /* equivalent to "c,c,c" */ + void SetValidCA(); + /* equivalent to "p,p,p" */ + void SetValidPeer(); + + /* general setters */ + /* read: "p, P, c, C, T, u, w" */ + void SetSSLTrust(bool peer, bool tPeer, bool ca, bool tCA, bool tClientCA, + bool user, bool warn); + + void SetEmailTrust(bool peer, bool tPeer, bool ca, bool tCA, bool tClientCA, + bool user, bool warn); + + /* set c <--> CT */ + void AddCATrust(bool ssl, bool email); + /* set p <--> P */ + void AddPeerTrust(bool ssl, bool email); + + CERTCertTrust& GetTrust() { return mTrust; } + + private: + void addTrust(unsigned int* t, unsigned int v); + void removeTrust(unsigned int* t, unsigned int v); + bool hasTrust(unsigned int t, unsigned int v); + CERTCertTrust mTrust; +}; + +#endif // nsNSSCertTrust_h diff --git a/security/manager/ssl/nsNSSCertificate.cpp b/security/manager/ssl/nsNSSCertificate.cpp new file mode 100644 index 0000000000..7e345eb866 --- /dev/null +++ b/security/manager/ssl/nsNSSCertificate.cpp @@ -0,0 +1,856 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "nsNSSCertificate.h" + +#include "CertVerifier.h" +#include "ExtendedValidation.h" +#include "NSSCertDBTrustDomain.h" +#include "X509CertValidity.h" +#include "certdb.h" +#include "ipc/IPCMessageUtils.h" +#include "mozilla/Assertions.h" +#include "mozilla/Base64.h" +#include "mozilla/Casting.h" +#include "mozilla/NotNull.h" +#include "mozilla/Span.h" +#include "mozilla/TextUtils.h" +#include "mozilla/Unused.h" +#include "mozilla/ipc/TransportSecurityInfoUtils.h" +#include "mozilla/net/DNS.h" +#include "mozpkix/Result.h" +#include "mozpkix/pkixnss.h" +#include "mozpkix/pkixtypes.h" +#include "mozpkix/pkixutil.h" +#include "nsArray.h" +#include "nsCOMPtr.h" +#include "nsIClassInfoImpl.h" +#include "nsIObjectInputStream.h" +#include "nsIObjectOutputStream.h" +#include "nsIX509Cert.h" +#include "nsNSSCertHelper.h" +#include "nsNSSCertTrust.h" +#include "nsPK11TokenDB.h" +#include "nsPKCS12Blob.h" +#include "nsProxyRelease.h" +#include "nsReadableUtils.h" +#include "nsString.h" +#include "nsThreadUtils.h" +#include "nsUnicharUtils.h" +#include "nspr.h" +#include "prerror.h" +#include "secasn1.h" +#include "secder.h" +#include "secerr.h" +#include "ssl.h" + +#ifdef XP_WIN +# include // for htonl +#endif + +using namespace mozilla; +using namespace mozilla::psm; + +extern LazyLogModule gPIPNSSLog; + +// This is being stored in an uint32_t that can otherwise +// only take values from nsIX509Cert's list of cert types. +// As nsIX509Cert is frozen, we choose a value not contained +// in the list to mean not yet initialized. +#define CERT_TYPE_NOT_YET_INITIALIZED (1 << 30) + +NS_IMPL_ISUPPORTS(nsNSSCertificate, nsIX509Cert, nsISerializable, nsIClassInfo) + +/*static*/ +nsNSSCertificate* nsNSSCertificate::Create(CERTCertificate* cert) { + if (cert) + return new nsNSSCertificate(cert); + else + return new nsNSSCertificate(); +} + +nsNSSCertificate* nsNSSCertificate::ConstructFromDER(char* certDER, + int derLen) { + nsNSSCertificate* newObject = nsNSSCertificate::Create(); + if (newObject && !newObject->InitFromDER(certDER, derLen)) { + delete newObject; + newObject = nullptr; + } + + return newObject; +} + +bool nsNSSCertificate::InitFromDER(char* certDER, int derLen) { + if (!certDER || !derLen) return false; + + CERTCertificate* aCert = CERT_DecodeCertFromPackage(certDER, derLen); + + if (!aCert) { +#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + if (XRE_GetProcessType() == GeckoProcessType_Content) { + MOZ_CRASH_UNSAFE_PRINTF("CERT_DecodeCertFromPackage failed in child: %d", + PR_GetError()); + } +#endif + return false; + } + + if (!aCert->dbhandle) { + aCert->dbhandle = CERT_GetDefaultCertDB(); + } + + mCert.reset(aCert); + return true; +} + +nsNSSCertificate::nsNSSCertificate(CERTCertificate* cert) + : mCert(nullptr), mCertType(CERT_TYPE_NOT_YET_INITIALIZED) { + if (cert) { + mCert.reset(CERT_DupCertificate(cert)); + } +} + +nsNSSCertificate::nsNSSCertificate() + : mCert(nullptr), mCertType(CERT_TYPE_NOT_YET_INITIALIZED) {} + +static uint32_t getCertType(CERTCertificate* cert) { + nsNSSCertTrust trust(cert->trust); + if (cert->nickname && trust.HasAnyUser()) { + return nsIX509Cert::USER_CERT; + } + if (trust.HasAnyCA()) { + return nsIX509Cert::CA_CERT; + } + if (trust.HasPeer(true, false)) { + return nsIX509Cert::SERVER_CERT; + } + if (trust.HasPeer(false, true) && cert->emailAddr) { + return nsIX509Cert::EMAIL_CERT; + } + if (CERT_IsCACert(cert, nullptr)) { + return nsIX509Cert::CA_CERT; + } + if (cert->emailAddr) { + return nsIX509Cert::EMAIL_CERT; + } + return nsIX509Cert::UNKNOWN_CERT; +} + +nsresult nsNSSCertificate::GetCertType(uint32_t* aCertType) { + if (mCertType == CERT_TYPE_NOT_YET_INITIALIZED) { + // only determine cert type once and cache it + mCertType = getCertType(mCert.get()); + } + *aCertType = mCertType; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetIsBuiltInRoot(bool* aIsBuiltInRoot) { + NS_ENSURE_ARG(aIsBuiltInRoot); + + pkix::Result rv = IsCertBuiltInRoot(mCert.get(), *aIsBuiltInRoot); + if (rv != pkix::Result::Success) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +/** + * Appends a pipnss bundle string to the given string. + * + * @param bundleKey Key for the string to append. + * @param currentText The text to append to, using commas as separators. + */ +template +void AppendBundleStringCommaSeparated(const char (&bundleKey)[N], + /*in/out*/ nsAString& currentText) { + nsAutoString bundleString; + nsresult rv = GetPIPNSSBundleString(bundleKey, bundleString); + if (NS_FAILED(rv)) { + return; + } + + if (!currentText.IsEmpty()) { + currentText.Append(','); + } + currentText.Append(bundleString); +} + +NS_IMETHODIMP +nsNSSCertificate::GetKeyUsages(nsAString& text) { + text.Truncate(); + + if (!mCert) { + return NS_ERROR_FAILURE; + } + + if (!mCert->extensions) { + return NS_OK; + } + + ScopedAutoSECItem keyUsageItem; + if (CERT_FindKeyUsageExtension(mCert.get(), &keyUsageItem) != SECSuccess) { + return PORT_GetError() == SEC_ERROR_EXTENSION_NOT_FOUND ? NS_OK + : NS_ERROR_FAILURE; + } + + unsigned char keyUsage = 0; + if (keyUsageItem.len) { + keyUsage = keyUsageItem.data[0]; + } + + if (keyUsage & KU_DIGITAL_SIGNATURE) { + AppendBundleStringCommaSeparated("CertDumpKUSign", text); + } + if (keyUsage & KU_NON_REPUDIATION) { + AppendBundleStringCommaSeparated("CertDumpKUNonRep", text); + } + if (keyUsage & KU_KEY_ENCIPHERMENT) { + AppendBundleStringCommaSeparated("CertDumpKUEnc", text); + } + if (keyUsage & KU_DATA_ENCIPHERMENT) { + AppendBundleStringCommaSeparated("CertDumpKUDEnc", text); + } + if (keyUsage & KU_KEY_AGREEMENT) { + AppendBundleStringCommaSeparated("CertDumpKUKA", text); + } + if (keyUsage & KU_KEY_CERT_SIGN) { + AppendBundleStringCommaSeparated("CertDumpKUCertSign", text); + } + if (keyUsage & KU_CRL_SIGN) { + AppendBundleStringCommaSeparated("CertDumpKUCRLSign", text); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetDbKey(nsACString& aDbKey) { + static_assert(sizeof(uint64_t) == 8, "type size consistency check"); + static_assert(sizeof(uint32_t) == 4, "type size consistency check"); + + pkix::Input certInput; + pkix::Result result = certInput.Init(mCert->derCert.data, mCert->derCert.len); + if (result != pkix::Result::Success) { + return NS_ERROR_INVALID_ARG; + } + // NB: since we're not building a trust path, the endEntityOrCA parameter is + // irrelevant. + pkix::BackCert cert(certInput, pkix::EndEntityOrCA::MustBeEndEntity, nullptr); + result = cert.Init(); + if (result != pkix::Result::Success) { + return NS_ERROR_INVALID_ARG; + } + + // The format of the key is the base64 encoding of the following: + // 4 bytes: {0, 0, 0, 0} (this was intended to be the module ID, but it was + // never implemented) + // 4 bytes: {0, 0, 0, 0} (this was intended to be the slot ID, but it was + // never implemented) + // 4 bytes: + // 4 bytes: + // n bytes: + // m bytes: + nsAutoCString buf; + const char leadingZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0}; + buf.Append(leadingZeroes, sizeof(leadingZeroes)); + uint32_t serialNumberLen = htonl(cert.GetSerialNumber().GetLength()); + buf.Append(BitwiseCast(&serialNumberLen), + sizeof(uint32_t)); + uint32_t issuerLen = htonl(cert.GetIssuer().GetLength()); + buf.Append(BitwiseCast(&issuerLen), + sizeof(uint32_t)); + buf.Append(BitwiseCast( + cert.GetSerialNumber().UnsafeGetData()), + cert.GetSerialNumber().GetLength()); + buf.Append(BitwiseCast( + cert.GetIssuer().UnsafeGetData()), + cert.GetIssuer().GetLength()); + + return Base64Encode(buf, aDbKey); +} + +NS_IMETHODIMP +nsNSSCertificate::GetDisplayName(nsAString& aDisplayName) { + aDisplayName.Truncate(); + + MOZ_ASSERT(mCert, "mCert should not be null in GetDisplayName"); + if (!mCert) { + return NS_ERROR_FAILURE; + } + + UniquePORTString commonName(CERT_GetCommonName(&mCert->subject)); + UniquePORTString organizationalUnitName(CERT_GetOrgUnitName(&mCert->subject)); + UniquePORTString organizationName(CERT_GetOrgName(&mCert->subject)); + + bool isBuiltInRoot; + nsresult rv = GetIsBuiltInRoot(&isBuiltInRoot); + if (NS_FAILED(rv)) { + return rv; + } + + // Only use the nickname for built-in roots where we already have a hard-coded + // reasonable display name (unfortunately we have to strip off the leading + // slot identifier followed by a ':'). Otherwise, attempt to use the following + // in order: + // - the common name, if present + // - an organizational unit name, if present + // - an organization name, if present + // - the entire subject distinguished name, if non-empty + // - an email address, if one can be found + // In the unlikely event that none of these fields are present and non-empty + // (the subject really shouldn't be empty), an empty string is returned. + nsAutoCString builtInRootNickname; + if (isBuiltInRoot) { + nsAutoCString fullNickname(mCert->nickname); + int32_t index = fullNickname.Find(":"); + if (index != kNotFound) { + // Substring will gracefully handle the case where index is the last + // character in the string (that is, if the nickname is just + // "Builtin Object Token:"). In that case, we'll get an empty string. + builtInRootNickname = + Substring(fullNickname, AssertedCast(index + 1)); + } + } + const char* nameOptions[] = { + builtInRootNickname.get(), commonName.get(), + organizationalUnitName.get(), organizationName.get(), + mCert->subjectName, mCert->emailAddr}; + + for (auto nameOption : nameOptions) { + if (nameOption) { + size_t len = strlen(nameOption); + if (len > 0) { + LossyUTF8ToUTF16(nameOption, len, aDisplayName); + return NS_OK; + } + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetEmailAddress(nsAString& aEmailAddress) { + if (mCert->emailAddr) { + CopyUTF8toUTF16(MakeStringSpan(mCert->emailAddr), aEmailAddress); + } else { + GetPIPNSSBundleString("CertNoEmailAddress", aEmailAddress); + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetEmailAddresses(nsTArray& aAddresses) { + uint32_t length = 0; + for (const char* aAddr = CERT_GetFirstEmailAddress(mCert.get()); aAddr; + aAddr = CERT_GetNextEmailAddress(mCert.get(), aAddr)) { + ++(length); + } + + aAddresses.SetCapacity(length); + + for (const char* aAddr = CERT_GetFirstEmailAddress(mCert.get()); aAddr; + aAddr = CERT_GetNextEmailAddress(mCert.get(), aAddr)) { + CopyASCIItoUTF16(MakeStringSpan(aAddr), *aAddresses.AppendElement()); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::ContainsEmailAddress(const nsAString& aEmailAddress, + bool* result) { + NS_ENSURE_ARG(result); + *result = false; + + for (const char* aAddr = CERT_GetFirstEmailAddress(mCert.get()); aAddr; + aAddr = CERT_GetNextEmailAddress(mCert.get(), aAddr)) { + nsAutoString certAddr; + LossyUTF8ToUTF16(aAddr, strlen(aAddr), certAddr); + ToLowerCase(certAddr); + + nsAutoString testAddr(aEmailAddress); + ToLowerCase(testAddr); + + if (certAddr == testAddr) { + *result = true; + break; + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetCommonName(nsAString& aCommonName) { + aCommonName.Truncate(); + if (mCert) { + UniquePORTString commonName(CERT_GetCommonName(&mCert->subject)); + if (commonName) { + LossyUTF8ToUTF16(commonName.get(), strlen(commonName.get()), aCommonName); + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetOrganization(nsAString& aOrganization) { + aOrganization.Truncate(); + if (mCert) { + UniquePORTString organization(CERT_GetOrgName(&mCert->subject)); + if (organization) { + LossyUTF8ToUTF16(organization.get(), strlen(organization.get()), + aOrganization); + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetIssuerCommonName(nsAString& aCommonName) { + aCommonName.Truncate(); + if (mCert) { + UniquePORTString commonName(CERT_GetCommonName(&mCert->issuer)); + if (commonName) { + LossyUTF8ToUTF16(commonName.get(), strlen(commonName.get()), aCommonName); + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetIssuerOrganization(nsAString& aOrganization) { + aOrganization.Truncate(); + if (mCert) { + UniquePORTString organization(CERT_GetOrgName(&mCert->issuer)); + if (organization) { + LossyUTF8ToUTF16(organization.get(), strlen(organization.get()), + aOrganization); + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetIssuerOrganizationUnit(nsAString& aOrganizationUnit) { + aOrganizationUnit.Truncate(); + if (mCert) { + UniquePORTString organizationUnit(CERT_GetOrgUnitName(&mCert->issuer)); + if (organizationUnit) { + LossyUTF8ToUTF16(organizationUnit.get(), strlen(organizationUnit.get()), + aOrganizationUnit); + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetOrganizationalUnit(nsAString& aOrganizationalUnit) { + aOrganizationalUnit.Truncate(); + if (mCert) { + UniquePORTString orgunit(CERT_GetOrgUnitName(&mCert->subject)); + if (orgunit) { + LossyUTF8ToUTF16(orgunit.get(), strlen(orgunit.get()), + aOrganizationalUnit); + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetSubjectName(nsAString& _subjectName) { + _subjectName.Truncate(); + if (mCert->subjectName) { + LossyUTF8ToUTF16(mCert->subjectName, strlen(mCert->subjectName), + _subjectName); + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetIssuerName(nsAString& _issuerName) { + _issuerName.Truncate(); + if (mCert->issuerName) { + LossyUTF8ToUTF16(mCert->issuerName, strlen(mCert->issuerName), _issuerName); + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetSerialNumber(nsAString& _serialNumber) { + _serialNumber.Truncate(); + UniquePORTString tmpstr( + CERT_Hexify(&mCert->serialNumber, true /* use colon delimiters */)); + if (tmpstr) { + _serialNumber = NS_ConvertASCIItoUTF16(tmpstr.get()); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +nsresult nsNSSCertificate::GetCertificateHash(nsAString& aFingerprint, + SECOidTag aHashAlg) { + aFingerprint.Truncate(); + nsTArray digestArray; + nsresult rv = Digest::DigestBuf(aHashAlg, mCert->derCert.data, + mCert->derCert.len, digestArray); + if (NS_FAILED(rv)) { + return rv; + } + SECItem digestItem = {siBuffer, digestArray.Elements(), + static_cast(digestArray.Length())}; + + UniquePORTString fpStr( + CERT_Hexify(&digestItem, true /* use colon delimiters */)); + if (!fpStr) { + return NS_ERROR_FAILURE; + } + + aFingerprint.AssignASCII(fpStr.get()); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetSha256Fingerprint(nsAString& aSha256Fingerprint) { + return GetCertificateHash(aSha256Fingerprint, SEC_OID_SHA256); +} + +NS_IMETHODIMP +nsNSSCertificate::GetSha1Fingerprint(nsAString& _sha1Fingerprint) { + return GetCertificateHash(_sha1Fingerprint, SEC_OID_SHA1); +} + +NS_IMETHODIMP +nsNSSCertificate::GetTokenName(nsAString& aTokenName) { + MOZ_ASSERT(mCert); + if (!mCert) { + return NS_ERROR_FAILURE; + } + UniquePK11SlotInfo internalSlot(PK11_GetInternalSlot()); + if (!internalSlot) { + return NS_ERROR_FAILURE; + } + nsCOMPtr token( + new nsPK11Token(mCert->slot ? mCert->slot : internalSlot.get())); + nsAutoCString tmp; + nsresult rv = token->GetTokenName(tmp); + if (NS_FAILED(rv)) { + return rv; + } + aTokenName.Assign(NS_ConvertUTF8toUTF16(tmp)); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetSha256SubjectPublicKeyInfoDigest( + nsACString& aSha256SPKIDigest) { + aSha256SPKIDigest.Truncate(); + + pkix::Input certInput; + pkix::Result result = certInput.Init(mCert->derCert.data, mCert->derCert.len); + if (result != pkix::Result::Success) { + return NS_ERROR_INVALID_ARG; + } + // NB: since we're not building a trust path, the endEntityOrCA parameter is + // irrelevant. + pkix::BackCert cert(certInput, pkix::EndEntityOrCA::MustBeEndEntity, nullptr); + result = cert.Init(); + if (result != pkix::Result::Success) { + return NS_ERROR_INVALID_ARG; + } + pkix::Input derPublicKey = cert.GetSubjectPublicKeyInfo(); + nsTArray digestArray; + nsresult rv = Digest::DigestBuf(SEC_OID_SHA256, derPublicKey.UnsafeGetData(), + derPublicKey.GetLength(), digestArray); + if (NS_FAILED(rv)) { + return rv; + } + rv = Base64Encode(nsDependentCSubstring( + BitwiseCast(digestArray.Elements()), + digestArray.Length()), + aSha256SPKIDigest); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetRawDER(nsTArray& aArray) { + if (mCert) { + aArray.SetLength(mCert->derCert.len); + memcpy(aArray.Elements(), mCert->derCert.data, mCert->derCert.len); + return NS_OK; + } + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsNSSCertificate::GetBase64DERString(nsACString& base64DERString) { + nsDependentCSubstring derString( + reinterpret_cast(mCert->derCert.data), mCert->derCert.len); + + nsresult rv = Base64Encode(derString, base64DERString); + + if (NS_FAILED(rv)) { + return rv; + } + + return NS_OK; +} + +CERTCertificate* nsNSSCertificate::GetCert() { + return (mCert) ? CERT_DupCertificate(mCert.get()) : nullptr; +} + +NS_IMETHODIMP +nsNSSCertificate::GetValidity(nsIX509CertValidity** aValidity) { + NS_ENSURE_ARG(aValidity); + if (!mCert) { + return NS_ERROR_FAILURE; + } + pkix::Input certInput; + pkix::Result rv = certInput.Init(mCert->derCert.data, mCert->derCert.len); + if (rv != pkix::Success) { + return NS_ERROR_FAILURE; + } + nsCOMPtr validity = new X509CertValidity(certInput); + validity.forget(aValidity); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::Equals(nsIX509Cert* other, bool* result) { + NS_ENSURE_ARG(other); + NS_ENSURE_ARG(result); + + UniqueCERTCertificate cert(other->GetCert()); + *result = (mCert.get() == cert.get()); + return NS_OK; +} + +namespace mozilla { + +// TODO(bug 1036065): It seems like we only construct CERTCertLists for the +// purpose of constructing nsNSSCertLists, so maybe we should change this +// function to output an nsNSSCertList instead. +SECStatus ConstructCERTCertListFromReversedDERArray( + const mozilla::pkix::DERArray& certArray, + /*out*/ UniqueCERTCertList& certList) { + certList = UniqueCERTCertList(CERT_NewCertList()); + if (!certList) { + return SECFailure; + } + + CERTCertDBHandle* certDB(CERT_GetDefaultCertDB()); // non-owning + + size_t numCerts = certArray.GetLength(); + for (size_t i = 0; i < numCerts; ++i) { + SECItem certDER(UnsafeMapInputToSECItem(*certArray.GetDER(i))); + UniqueCERTCertificate cert( + CERT_NewTempCertificate(certDB, &certDER, nullptr, false, true)); + if (!cert) { + return SECFailure; + } + // certArray is ordered with the root first, but we want the resulting + // certList to have the root last. + if (CERT_AddCertToListHead(certList.get(), cert.get()) != SECSuccess) { + return SECFailure; + } + Unused << cert.release(); // cert is now owned by certList. + } + + return SECSuccess; +} + +} // namespace mozilla + +nsresult nsNSSCertificate::SegmentCertificateChain( + /* in */ const nsTArray>& aCertList, + /* out */ nsCOMPtr& aRoot, + /* out */ nsTArray>& aIntermediates, + /* out */ nsCOMPtr& aEndEntity) { + if (aRoot || aEndEntity) { + // All passed-in nsCOMPtrs should be empty for the state machine to work + return NS_ERROR_UNEXPECTED; + } + + if (!aIntermediates.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + + for (size_t i = 0; i < aCertList.Length(); ++i) { + const auto& cert = aCertList[i]; + if (!aEndEntity) { + aEndEntity = cert; + } else if (i == aCertList.Length() - 1) { + aRoot = cert; + } else { + // One of (potentially many) intermediates + aIntermediates.AppendElement(cert); + } + } + + if (!aRoot || !aEndEntity) { + // No self-signed (or empty) chains allowed + return NS_ERROR_INVALID_ARG; + } + + return NS_OK; +} + +nsresult nsNSSCertificate::GetRootCertificate( + /* in */ const nsTArray>& aCertList, + /* out */ nsCOMPtr& aRoot) { + if (aRoot) { + return NS_ERROR_UNEXPECTED; + } + // If the list is empty, leave aRoot empty. + if (aCertList.IsEmpty()) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr cert(aCertList.LastElement()); + aRoot = cert; + if (!aRoot) { + return NS_ERROR_OUT_OF_MEMORY; + } + return NS_OK; +} + +// NB: Any updates (except disk-only fields) must be kept in sync with +// |SerializeToIPC|. +NS_IMETHODIMP +nsNSSCertificate::Write(nsIObjectOutputStream* aStream) { + NS_ENSURE_STATE(mCert); + // This field used to be the cached EV status, but it is no longer necessary. + nsresult rv = aStream->Write32(0); + if (NS_FAILED(rv)) { + return rv; + } + rv = aStream->Write32(mCert->derCert.len); + if (NS_FAILED(rv)) { + return rv; + } + return aStream->WriteBytes( + AsBytes(Span(mCert->derCert.data, mCert->derCert.len))); +} + +// NB: Any updates (except disk-only fields) must be kept in sync with +// |DeserializeFromIPC|. +NS_IMETHODIMP +nsNSSCertificate::Read(nsIObjectInputStream* aStream) { + NS_ENSURE_STATE(!mCert); + + // This field is no longer used. + uint32_t unusedCachedEVStatus; + nsresult rv = aStream->Read32(&unusedCachedEVStatus); + if (NS_FAILED(rv)) { + return rv; + } + + uint32_t len; + rv = aStream->Read32(&len); + if (NS_FAILED(rv)) { + return rv; + } + + nsCString str; + rv = aStream->ReadBytes(len, getter_Copies(str)); + if (NS_FAILED(rv)) { + return rv; + } + + if (!InitFromDER(const_cast(str.get()), len)) { + return NS_ERROR_UNEXPECTED; + } + + return NS_OK; +} + +void nsNSSCertificate::SerializeToIPC(IPC::Message* aMsg) { + bool hasCert = static_cast(mCert); + WriteParam(aMsg, hasCert); + + if (!hasCert) { + return; + } + + const nsDependentCSubstring certBytes( + reinterpret_cast(mCert->derCert.data), mCert->derCert.len); + + WriteParam(aMsg, certBytes); +} + +bool nsNSSCertificate::DeserializeFromIPC(const IPC::Message* aMsg, + PickleIterator* aIter) { + bool hasCert = false; + if (!ReadParam(aMsg, aIter, &hasCert)) { + return false; + } + + if (!hasCert) { + return true; + } + + nsCString derBytes; + if (!ReadParam(aMsg, aIter, &derBytes)) { + return false; + } + + if (derBytes.Length() == 0) { + return false; + } + + // NSS accepts a |char*| here, but doesn't modify the contents of the array + // and casts it back to an |unsigned char*|. + return InitFromDER(const_cast(derBytes.get()), derBytes.Length()); +} + +NS_IMETHODIMP +nsNSSCertificate::GetInterfaces(nsTArray& array) { + array.Clear(); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetScriptableHelper(nsIXPCScriptable** _retval) { + *_retval = nullptr; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetContractID(nsACString& aContractID) { + aContractID.SetIsVoid(true); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetClassDescription(nsACString& aClassDescription) { + aClassDescription.SetIsVoid(true); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetClassID(nsCID** aClassID) { + *aClassID = (nsCID*)moz_xmalloc(sizeof(nsCID)); + return GetClassIDNoAlloc(*aClassID); +} + +NS_IMETHODIMP +nsNSSCertificate::GetFlags(uint32_t* aFlags) { + *aFlags = nsIClassInfo::THREADSAFE; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificate::GetClassIDNoAlloc(nsCID* aClassIDNoAlloc) { + static NS_DEFINE_CID(kNSSCertificateCID, NS_X509CERT_CID); + + *aClassIDNoAlloc = kNSSCertificateCID; + return NS_OK; +} diff --git a/security/manager/ssl/nsNSSCertificate.h b/security/manager/ssl/nsNSSCertificate.h new file mode 100644 index 0000000000..a3c70f0bdf --- /dev/null +++ b/security/manager/ssl/nsNSSCertificate.h @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef nsNSSCertificate_h +#define nsNSSCertificate_h + +#include +#include + +#include "ScopedNSSTypes.h" +#include "certt.h" +#include "nsCOMPtr.h" +#include "nsIClassInfo.h" +#include "nsISerializable.h" +#include "nsIX509Cert.h" +#include "nsSimpleEnumerator.h" +#include "nsStringFwd.h" + +namespace mozilla { +namespace pkix { +class DERArray; +} +} // namespace mozilla + +class nsINSSComponent; + +class nsNSSCertificate final : public nsIX509Cert, + public nsISerializable, + public nsIClassInfo { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIX509CERT + NS_DECL_NSISERIALIZABLE + NS_DECL_NSICLASSINFO + + explicit nsNSSCertificate(CERTCertificate* cert); + nsNSSCertificate(); + static nsNSSCertificate* Create(CERTCertificate* cert = nullptr); + static nsNSSCertificate* ConstructFromDER(char* certDER, int derLen); + + // Split a certificate chain into the root, intermediates (if any), and end + // entity. This method does so blindly, assuming that the current list object + // is ordered [end entity, intermediates..., root]. If that isn't true, this + // method will return the certificates at the two ends without regard to the + // actual chain of trust. Callers are encouraged to check, if there's any + // doubt. + // Will return error if used on self-signed or empty chains. + // This method requires that all arguments be empty, notably the list + // `aIntermediates` must be empty. + static nsresult SegmentCertificateChain( + /* int */ const nsTArray>& aCertList, + /* out */ nsCOMPtr& aRoot, + /* out */ nsTArray>& aIntermediates, + /* out */ nsCOMPtr& aEndEntity); + + // Obtain the root certificate of a certificate chain. This method does so + // blindly, as SegmentCertificateChain; the same restrictions apply. On an + // empty list, leaves aRoot empty and returns a failure. + static nsresult GetRootCertificate( + const nsTArray>& aCertList, + /* out */ nsCOMPtr& aRoot); + + private: + virtual ~nsNSSCertificate() = default; + + mozilla::UniqueCERTCertificate mCert; + uint32_t mCertType; + nsresult GetSortableDate(PRTime aTime, nsAString& _aSortableDate); + bool InitFromDER(char* certDER, int derLen); // return false on failure + + nsresult GetCertificateHash(nsAString& aFingerprint, SECOidTag aHashAlg); +}; + +namespace mozilla { + +SECStatus ConstructCERTCertListFromReversedDERArray( + const mozilla::pkix::DERArray& certArray, + /*out*/ mozilla::UniqueCERTCertList& certList); + +} // namespace mozilla + +#define NS_X509CERT_CID \ + { /* 660a3226-915c-4ffb-bb20-8985a632df05 */ \ + 0x660a3226, 0x915c, 0x4ffb, { \ + 0xbb, 0x20, 0x89, 0x85, 0xa6, 0x32, 0xdf, 0x05 \ + } \ + } + +#endif // nsNSSCertificate_h diff --git a/security/manager/ssl/nsNSSCertificateDB.cpp b/security/manager/ssl/nsNSSCertificateDB.cpp new file mode 100644 index 0000000000..4d9e1f64c0 --- /dev/null +++ b/security/manager/ssl/nsNSSCertificateDB.cpp @@ -0,0 +1,1375 @@ +/* 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/. */ + +#include "nsNSSCertificateDB.h" + +#include "CertVerifier.h" +#include "CryptoTask.h" +#include "ExtendedValidation.h" +#include "NSSCertDBTrustDomain.h" +#include "SharedSSLState.h" +#include "certdb.h" +#include "mozilla/Assertions.h" +#include "mozilla/Base64.h" +#include "mozilla/Casting.h" +#include "mozilla/Logging.h" +#include "mozilla/Services.h" +#include "mozilla/Unused.h" +#include "mozpkix/Time.h" +#include "mozpkix/pkixnss.h" +#include "mozpkix/pkixtypes.h" +#include "nsArray.h" +#include "nsArrayUtils.h" +#include "nsCOMPtr.h" +#include "nsComponentManagerUtils.h" +#include "nsICertificateDialogs.h" +#include "nsIFile.h" +#include "nsIMutableArray.h" +#include "nsIObserverService.h" +#include "nsIPrompt.h" +#include "nsNSSCertHelper.h" +#include "nsNSSCertTrust.h" +#include "nsNSSCertificate.h" +#include "nsNSSComponent.h" +#include "nsNSSHelper.h" +#include "nsPKCS12Blob.h" +#include "nsPromiseFlatString.h" +#include "nsProxyRelease.h" +#include "nsReadableUtils.h" +#include "nsThreadUtils.h" +#include "nspr.h" +#include "secasn1.h" +#include "secder.h" +#include "secerr.h" +#include "ssl.h" + +#ifdef XP_WIN +# include // for ntohl +#endif + +using namespace mozilla; +using namespace mozilla::psm; + +extern LazyLogModule gPIPNSSLog; + +NS_IMPL_ISUPPORTS(nsNSSCertificateDB, nsIX509CertDB) + +NS_IMETHODIMP +nsNSSCertificateDB::FindCertByDBKey(const nsACString& aDBKey, + /*out*/ nsIX509Cert** _cert) { + NS_ENSURE_ARG_POINTER(_cert); + *_cert = nullptr; + + if (aDBKey.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + + nsresult rv = BlockUntilLoadableCertsLoaded(); + if (NS_FAILED(rv)) { + return rv; + } + + UniqueCERTCertificate cert; + rv = FindCertByDBKey(aDBKey, cert); + if (NS_FAILED(rv)) { + return rv; + } + // If we can't find the certificate, that's not an error. Just return null. + if (!cert) { + return NS_OK; + } + nsCOMPtr nssCert = nsNSSCertificate::Create(cert.get()); + if (!nssCert) { + return NS_ERROR_OUT_OF_MEMORY; + } + nssCert.forget(_cert); + return NS_OK; +} + +nsresult nsNSSCertificateDB::FindCertByDBKey(const nsACString& aDBKey, + UniqueCERTCertificate& cert) { + static_assert(sizeof(uint64_t) == 8, "type size sanity check"); + static_assert(sizeof(uint32_t) == 4, "type size sanity check"); + // (From nsNSSCertificate::GetDbKey) + // The format of the key is the base64 encoding of the following: + // 4 bytes: {0, 0, 0, 0} (this was intended to be the module ID, but it was + // never implemented) + // 4 bytes: {0, 0, 0, 0} (this was intended to be the slot ID, but it was + // never implemented) + // 4 bytes: + // 4 bytes: + // n bytes: + // m bytes: + nsAutoCString decoded; + nsAutoCString tmpDBKey(aDBKey); + // Filter out any whitespace for backwards compatibility. + tmpDBKey.StripWhitespace(); + nsresult rv = Base64Decode(tmpDBKey, decoded); + if (NS_FAILED(rv)) { + return rv; + } + if (decoded.Length() < 16) { + return NS_ERROR_ILLEGAL_INPUT; + } + const char* reader = decoded.BeginReading(); + uint64_t zeroes = *BitwiseCast(reader); + if (zeroes != 0) { + return NS_ERROR_ILLEGAL_INPUT; + } + reader += sizeof(uint64_t); + // Note: We surround the ntohl() argument with parentheses to stop the macro + // from thinking two arguments were passed. + uint32_t serialNumberLen = + ntohl((*BitwiseCast(reader))); + reader += sizeof(uint32_t); + uint32_t issuerLen = + ntohl((*BitwiseCast(reader))); + reader += sizeof(uint32_t); + if (decoded.Length() != 16ULL + serialNumberLen + issuerLen) { + return NS_ERROR_ILLEGAL_INPUT; + } + CERTIssuerAndSN issuerSN; + issuerSN.serialNumber.len = serialNumberLen; + issuerSN.serialNumber.data = BitwiseCast(reader); + reader += serialNumberLen; + issuerSN.derIssuer.len = issuerLen; + issuerSN.derIssuer.data = BitwiseCast(reader); + reader += issuerLen; + MOZ_ASSERT(reader == decoded.EndReading()); + + cert.reset(CERT_FindCertByIssuerAndSN(CERT_GetDefaultCertDB(), &issuerSN)); + return NS_OK; +} + +SECStatus collect_certs(void* arg, SECItem** certs, int numcerts) { + nsTArray>* certsArray = + reinterpret_cast>*>(arg); + + while (numcerts--) { + nsTArray certArray; + SECItem* cert = *certs; + certArray.AppendElements(cert->data, cert->len); + certsArray->AppendElement(std::move(certArray)); + certs++; + } + return (SECSuccess); +} + +nsresult nsNSSCertificateDB::getCertsFromPackage( + nsTArray>& collectArgs, uint8_t* data, uint32_t length) { + if (CERT_DecodeCertPackage(BitwiseCast(data), length, + collect_certs, &collectArgs) != SECSuccess) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +// When using the sql-backed softoken, trust settings are authenticated using a +// key in the secret database. Thus, if the user has a password, we need to +// authenticate to the token in order to be able to change trust settings. +SECStatus ChangeCertTrustWithPossibleAuthentication( + const UniqueCERTCertificate& cert, CERTCertTrust& trust, void* ctx) { + MOZ_ASSERT(cert, "cert must be non-null"); + if (!cert) { + PR_SetError(SEC_ERROR_LIBRARY_FAILURE, 0); + return SECFailure; + } + // NSS ignores the first argument to CERT_ChangeCertTrust + SECStatus srv = CERT_ChangeCertTrust(nullptr, cert.get(), &trust); + if (srv == SECSuccess || PR_GetError() != SEC_ERROR_TOKEN_NOT_LOGGED_IN) { + return srv; + } + if (cert->slot) { + // If this certificate is on an external PKCS#11 token, we have to + // authenticate to that token. + srv = PK11_Authenticate(cert->slot, PR_TRUE, ctx); + } else { + // Otherwise, the certificate is on the internal module. + UniquePK11SlotInfo internalSlot(PK11_GetInternalKeySlot()); + srv = PK11_Authenticate(internalSlot.get(), PR_TRUE, ctx); + } + if (srv != SECSuccess) { + return srv; + } + return CERT_ChangeCertTrust(nullptr, cert.get(), &trust); +} + +static nsresult ImportCertsIntoPermanentStorage( + const UniqueCERTCertList& certChain) { + bool encounteredFailure = false; + PRErrorCode savedErrorCode = 0; + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + for (CERTCertListNode* chainNode = CERT_LIST_HEAD(certChain); + !CERT_LIST_END(chainNode, certChain); + chainNode = CERT_LIST_NEXT(chainNode)) { + UniquePORTString nickname(CERT_MakeCANickname(chainNode->cert)); + SECStatus srv = PK11_ImportCert(slot.get(), chainNode->cert, + CK_INVALID_HANDLE, nickname.get(), + false); // this parameter is ignored by NSS + if (srv != SECSuccess) { + encounteredFailure = true; + savedErrorCode = PR_GetError(); + } + } + + if (encounteredFailure) { + return GetXPCOMFromNSSError(savedErrorCode); + } + + return NS_OK; +} + +nsresult nsNSSCertificateDB::handleCACertDownload(NotNull x509Certs, + nsIInterfaceRequestor* ctx) { + // First thing we have to do is figure out which certificate we're + // gonna present to the user. The CA may have sent down a list of + // certs which may or may not be a chained list of certs. Until + // the day we can design some solid UI for the general case, we'll + // code to the > 90% case. That case is where a CA sends down a + // list that is a hierarchy whose root is either the first or + // the last cert. What we're gonna do is compare the first + // 2 entries, if the second was signed by the first, we assume + // the root cert is the first cert and display it. Otherwise, + // we compare the last 2 entries, if the second to last cert was + // signed by the last cert, then we assume the last cert is the + // root and display it. + + uint32_t numCerts; + + x509Certs->GetLength(&numCerts); + + if (numCerts == 0) return NS_OK; // Nothing to import, so nothing to do. + + nsCOMPtr certToShow; + uint32_t selCertIndex; + if (numCerts == 1) { + // There's only one cert, so let's show it. + selCertIndex = 0; + certToShow = do_QueryElementAt(x509Certs, selCertIndex); + } else { + nsCOMPtr cert0; // first cert + nsCOMPtr cert1; // second cert + nsCOMPtr certn_2; // second to last cert + nsCOMPtr certn_1; // last cert + + cert0 = do_QueryElementAt(x509Certs, 0); + cert1 = do_QueryElementAt(x509Certs, 1); + certn_2 = do_QueryElementAt(x509Certs, numCerts - 2); + certn_1 = do_QueryElementAt(x509Certs, numCerts - 1); + + nsAutoString cert0SubjectName; + nsAutoString cert1IssuerName; + nsAutoString certn_2IssuerName; + nsAutoString certn_1SubjectName; + + cert0->GetSubjectName(cert0SubjectName); + cert1->GetIssuerName(cert1IssuerName); + certn_2->GetIssuerName(certn_2IssuerName); + certn_1->GetSubjectName(certn_1SubjectName); + + if (cert1IssuerName.Equals(cert0SubjectName)) { + // In this case, the first cert in the list signed the second, + // so the first cert is the root. Let's display it. + selCertIndex = 0; + certToShow = cert0; + } else if (certn_2IssuerName.Equals(certn_1SubjectName)) { + // In this case the last cert has signed the second to last cert. + // The last cert is the root, so let's display it. + selCertIndex = numCerts - 1; + certToShow = certn_1; + } else { + // It's not a chain, so let's just show the first one in the + // downloaded list. + selCertIndex = 0; + certToShow = cert0; + } + } + + if (!certToShow) return NS_ERROR_FAILURE; + + nsCOMPtr dialogs; + nsresult rv = ::getNSSDialogs(getter_AddRefs(dialogs), + NS_GET_IID(nsICertificateDialogs), + NS_CERTIFICATEDIALOGS_CONTRACTID); + if (NS_FAILED(rv)) { + return rv; + } + + UniqueCERTCertificate tmpCert(certToShow->GetCert()); + if (!tmpCert) { + return NS_ERROR_FAILURE; + } + + if (!CERT_IsCACert(tmpCert.get(), nullptr)) { + DisplayCertificateAlert(ctx, "NotACACert", certToShow); + return NS_ERROR_FAILURE; + } + + if (tmpCert->isperm) { + DisplayCertificateAlert(ctx, "CaCertExists", certToShow); + return NS_ERROR_FAILURE; + } + + uint32_t trustBits; + bool allows; + rv = dialogs->ConfirmDownloadCACert(ctx, certToShow, &trustBits, &allows); + if (NS_FAILED(rv)) return rv; + + if (!allows) return NS_ERROR_NOT_AVAILABLE; + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("trust is %d\n", trustBits)); + UniquePORTString nickname(CERT_MakeCANickname(tmpCert.get())); + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("Created nick \"%s\"\n", nickname.get())); + + nsNSSCertTrust trust; + trust.SetValidCA(); + trust.AddCATrust(!!(trustBits & nsIX509CertDB::TRUSTED_SSL), + !!(trustBits & nsIX509CertDB::TRUSTED_EMAIL)); + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + SECStatus srv = PK11_ImportCert(slot.get(), tmpCert.get(), CK_INVALID_HANDLE, + nickname.get(), + false); // this parameter is ignored by NSS + if (srv != SECSuccess) { + return MapSECStatus(srv); + } + srv = + ChangeCertTrustWithPossibleAuthentication(tmpCert, trust.GetTrust(), ctx); + if (srv != SECSuccess) { + return MapSECStatus(srv); + } + + // Import additional delivered certificates that can be verified. + + // build a CertList for filtering + UniqueCERTCertList certList(CERT_NewCertList()); + if (!certList) { + return NS_ERROR_FAILURE; + } + + // get all remaining certs into temp store + + for (uint32_t i = 0; i < numCerts; i++) { + if (i == selCertIndex) { + // we already processed that one + continue; + } + + nsCOMPtr remainingCert = do_QueryElementAt(x509Certs, i); + if (!remainingCert) { + continue; + } + + UniqueCERTCertificate tmpCert2(remainingCert->GetCert()); + if (!tmpCert2) { + continue; // Let's try to import the rest of 'em + } + + if (CERT_AddCertToListTail(certList.get(), tmpCert2.get()) != SECSuccess) { + continue; + } + + Unused << tmpCert2.release(); + } + + return ImportCertsIntoPermanentStorage(certList); +} + +nsresult nsNSSCertificateDB::ConstructCertArrayFromUniqueCertList( + const UniqueCERTCertList& aCertListIn, + nsTArray>& aCertListOut) { + if (!aCertListIn.get()) { + return NS_ERROR_INVALID_ARG; + } + + for (CERTCertListNode* node = CERT_LIST_HEAD(aCertListIn.get()); + !CERT_LIST_END(node, aCertListIn.get()); node = CERT_LIST_NEXT(node)) { + RefPtr cert = nsNSSCertificate::Create(node->cert); + if (!cert) { + return NS_ERROR_OUT_OF_MEMORY; + } + aCertListOut.AppendElement(cert); + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificateDB::ImportCertificates(uint8_t* data, uint32_t length, + uint32_t type, + nsIInterfaceRequestor* ctx) { + // We currently only handle CA certificates. + if (type != nsIX509Cert::CA_CERT) { + return NS_ERROR_FAILURE; + } + + nsTArray> certsArray; + + nsresult rv = getCertsFromPackage(certsArray, data, length); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr array = nsArrayBase::Create(); + if (!array) { + return NS_ERROR_FAILURE; + } + + // Now let's create some certs to work with + for (nsTArray& certDER : certsArray) { + nsCOMPtr cert = nsNSSCertificate::ConstructFromDER( + BitwiseCast(certDER.Elements()), certDER.Length()); + if (!cert) { + return NS_ERROR_FAILURE; + } + nsresult rv = array->AppendElement(cert); + if (NS_FAILED(rv)) { + return rv; + } + } + + return handleCACertDownload(WrapNotNull(array), ctx); +} + +/** + * Decodes a given array of DER-encoded certificates into temporary storage. + * + * @param certs + * Array in which the decoded certificates are stored as arrays of + * unsigned chars. + * @param temporaryCerts + * List of decoded certificates. + */ +static nsresult ImportCertsIntoTempStorage( + nsTArray>& certs, + /*out*/ const UniqueCERTCertList& temporaryCerts) { + NS_ENSURE_ARG_POINTER(temporaryCerts); + + for (nsTArray& certDER : certs) { + CERTCertificate* certificate; + SECItem certItem; + certItem.len = certDER.Length(); + certItem.data = certDER.Elements(); + certificate = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &certItem, + nullptr, false, true); + + UniqueCERTCertificate cert(certificate); + if (!cert) { + continue; + } + + if (CERT_AddCertToListTail(temporaryCerts.get(), cert.get()) == + SECSuccess) { + Unused << cert.release(); + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificateDB::ImportEmailCertificate(uint8_t* data, uint32_t length, + nsIInterfaceRequestor* ctx) { + nsTArray> certsArray; + + nsresult rv = getCertsFromPackage(certsArray, data, length); + if (NS_FAILED(rv)) { + return rv; + } + + UniqueCERTCertList temporaryCerts(CERT_NewCertList()); + if (!temporaryCerts) { + return NS_ERROR_FAILURE; + } + + rv = ImportCertsIntoTempStorage(certsArray, temporaryCerts); + if (NS_FAILED(rv)) { + return rv; + } + + return ImportCertsIntoPermanentStorage(temporaryCerts); +} + +nsresult nsNSSCertificateDB::ImportCACerts(nsTArray>& caCerts, + nsIInterfaceRequestor* ctx) { + UniqueCERTCertList temporaryCerts(CERT_NewCertList()); + if (!temporaryCerts) { + return NS_ERROR_FAILURE; + } + + nsresult rv = ImportCertsIntoTempStorage(caCerts, temporaryCerts); + if (NS_FAILED(rv)) { + return rv; + } + + return ImportCertsIntoPermanentStorage(temporaryCerts); +} + +void nsNSSCertificateDB::DisplayCertificateAlert(nsIInterfaceRequestor* ctx, + const char* stringID, + nsIX509Cert* certToShow) { + if (!NS_IsMainThread()) { + NS_ERROR( + "nsNSSCertificateDB::DisplayCertificateAlert called off the main " + "thread"); + return; + } + + nsCOMPtr my_ctx = ctx; + if (!my_ctx) { + my_ctx = new PipUIContext(); + } + + // This shall be replaced by embedding ovverridable prompts + // as discussed in bug 310446, and should make use of certToShow. + + nsAutoString tmpMessage; + GetPIPNSSBundleString(stringID, tmpMessage); + nsCOMPtr prompt(do_GetInterface(my_ctx)); + if (!prompt) { + return; + } + + prompt->Alert(nullptr, tmpMessage.get()); +} + +NS_IMETHODIMP +nsNSSCertificateDB::ImportUserCertificate(uint8_t* data, uint32_t length, + nsIInterfaceRequestor* ctx) { + if (!NS_IsMainThread()) { + NS_ERROR( + "nsNSSCertificateDB::ImportUserCertificate called off the main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + + nsTArray> certsArray; + + nsresult rv = getCertsFromPackage(certsArray, data, length); + if (NS_FAILED(rv)) { + return rv; + } + + SECItem certItem; + + if (certsArray.IsEmpty()) { + return NS_OK; + } + + certItem.len = certsArray.ElementAt(0).Length(); + certItem.data = certsArray.ElementAt(0).Elements(); + + UniqueCERTCertificate cert(CERT_NewTempCertificate( + CERT_GetDefaultCertDB(), &certItem, nullptr, false, true)); + if (!cert) { + return NS_ERROR_FAILURE; + } + + UniquePK11SlotInfo slot(PK11_KeyForCertExists(cert.get(), nullptr, ctx)); + if (!slot) { + nsCOMPtr certToShow = nsNSSCertificate::Create(cert.get()); + DisplayCertificateAlert(ctx, "UserCertIgnoredNoPrivateKey", certToShow); + return NS_ERROR_FAILURE; + } + slot = nullptr; + + /* pick a nickname for the cert */ + nsAutoCString nickname; + if (cert->nickname) { + nickname = cert->nickname; + } else { + get_default_nickname(cert.get(), ctx, nickname); + } + + /* user wants to import the cert */ + slot.reset(PK11_ImportCertForKey(cert.get(), nickname.get(), ctx)); + if (!slot) { + return NS_ERROR_FAILURE; + } + slot = nullptr; + + { + nsCOMPtr certToShow = nsNSSCertificate::Create(cert.get()); + DisplayCertificateAlert(ctx, "UserCertImported", certToShow); + } + + rv = NS_OK; + if (!certsArray.IsEmpty()) { + certsArray.RemoveElementAt(0); + rv = ImportCACerts(certsArray, ctx); + } + + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (observerService) { + observerService->NotifyObservers(nullptr, "psm:user-certificate-added", + nullptr); + } + + return rv; +} + +NS_IMETHODIMP +nsNSSCertificateDB::DeleteCertificate(nsIX509Cert* aCert) { + NS_ENSURE_ARG_POINTER(aCert); + UniqueCERTCertificate cert(aCert->GetCert()); + if (!cert) { + return NS_ERROR_FAILURE; + } + + // Temporary certificates aren't on a slot and will go away when the + // nsIX509Cert is destructed. + if (cert->slot) { + uint32_t certType; + nsresult rv = aCert->GetCertType(&certType); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + if (certType == nsIX509Cert::USER_CERT) { + SECStatus srv = PK11_Authenticate(cert->slot, true, nullptr); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + srv = PK11_DeleteTokenCertAndKey(cert.get(), nullptr); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + } else { + // For certificates that can't be deleted (e.g. built-in roots), un-set + // all trust bits. + nsNSSCertTrust trust(0, 0); + SECStatus srv = ChangeCertTrustWithPossibleAuthentication( + cert, trust.GetTrust(), nullptr); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + if (!PK11_IsReadOnly(cert->slot)) { + srv = SEC_DeletePermCertificate(cert.get()); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + } + } + } + + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (observerService) { + observerService->NotifyObservers(nullptr, "psm:user-certificate-deleted", + nullptr); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificateDB::SetCertTrust(nsIX509Cert* cert, uint32_t type, + uint32_t trusted) { + NS_ENSURE_ARG_POINTER(cert); + nsNSSCertTrust trust; + switch (type) { + case nsIX509Cert::CA_CERT: + trust.SetValidCA(); + trust.AddCATrust(!!(trusted & nsIX509CertDB::TRUSTED_SSL), + !!(trusted & nsIX509CertDB::TRUSTED_EMAIL)); + break; + case nsIX509Cert::SERVER_CERT: + trust.SetValidPeer(); + trust.AddPeerTrust(trusted & nsIX509CertDB::TRUSTED_SSL, false); + break; + case nsIX509Cert::EMAIL_CERT: + trust.SetValidPeer(); + trust.AddPeerTrust(false, !!(trusted & nsIX509CertDB::TRUSTED_EMAIL)); + break; + default: + // Ignore any other type of certificate (including invalid types). + return NS_OK; + } + + UniqueCERTCertificate nsscert(cert->GetCert()); + SECStatus srv = ChangeCertTrustWithPossibleAuthentication( + nsscert, trust.GetTrust(), nullptr); + return MapSECStatus(srv); +} + +NS_IMETHODIMP +nsNSSCertificateDB::IsCertTrusted(nsIX509Cert* cert, uint32_t certType, + uint32_t trustType, bool* _isTrusted) { + NS_ENSURE_ARG_POINTER(_isTrusted); + *_isTrusted = false; + + nsresult rv = BlockUntilLoadableCertsLoaded(); + if (NS_FAILED(rv)) { + return rv; + } + + SECStatus srv; + UniqueCERTCertificate nsscert(cert->GetCert()); + CERTCertTrust nsstrust; + srv = CERT_GetCertTrust(nsscert.get(), &nsstrust); + if (srv != SECSuccess) { + // CERT_GetCertTrust returns SECFailure if given a temporary cert that + // doesn't have any trust information yet. This isn't an error. + return NS_OK; + } + + nsNSSCertTrust trust(&nsstrust); + if (certType == nsIX509Cert::CA_CERT) { + if (trustType & nsIX509CertDB::TRUSTED_SSL) { + *_isTrusted = trust.HasTrustedCA(true, false); + } else if (trustType & nsIX509CertDB::TRUSTED_EMAIL) { + *_isTrusted = trust.HasTrustedCA(false, true); + } else { + return NS_ERROR_FAILURE; + } + } else if (certType == nsIX509Cert::SERVER_CERT) { + if (trustType & nsIX509CertDB::TRUSTED_SSL) { + *_isTrusted = trust.HasTrustedPeer(true, false); + } else if (trustType & nsIX509CertDB::TRUSTED_EMAIL) { + *_isTrusted = trust.HasTrustedPeer(false, true); + } else { + return NS_ERROR_FAILURE; + } + } else if (certType == nsIX509Cert::EMAIL_CERT) { + if (trustType & nsIX509CertDB::TRUSTED_SSL) { + *_isTrusted = trust.HasTrustedPeer(true, false); + } else if (trustType & nsIX509CertDB::TRUSTED_EMAIL) { + *_isTrusted = trust.HasTrustedPeer(false, true); + } else { + return NS_ERROR_FAILURE; + } + } /* user: ignore */ + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificateDB::ImportCertsFromFile(nsIFile* aFile, uint32_t aType) { + NS_ENSURE_ARG(aFile); + switch (aType) { + case nsIX509Cert::CA_CERT: + case nsIX509Cert::EMAIL_CERT: + // good + break; + + default: + // not supported (yet) + return NS_ERROR_FAILURE; + } + + PRFileDesc* fd = nullptr; + nsresult rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd); + if (NS_FAILED(rv)) { + return rv; + } + if (!fd) { + return NS_ERROR_FAILURE; + } + + PRFileInfo fileInfo; + if (PR_GetOpenFileInfo(fd, &fileInfo) != PR_SUCCESS) { + return NS_ERROR_FAILURE; + } + + auto buf = MakeUnique(fileInfo.size); + int32_t bytesObtained = PR_Read(fd, buf.get(), fileInfo.size); + PR_Close(fd); + + if (bytesObtained != fileInfo.size) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr cxt = new PipUIContext(); + + switch (aType) { + case nsIX509Cert::CA_CERT: + return ImportCertificates(buf.get(), bytesObtained, aType, cxt); + case nsIX509Cert::EMAIL_CERT: + return ImportEmailCertificate(buf.get(), bytesObtained, cxt); + default: + MOZ_ASSERT(false, "Unsupported type should have been filtered out"); + break; + } + + return NS_ERROR_FAILURE; +} + +NS_IMETHODIMP +nsNSSCertificateDB::ImportPKCS12File(nsIFile* aFile, const nsAString& aPassword, + uint32_t* aError) { + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + nsresult rv = BlockUntilLoadableCertsLoaded(); + if (NS_FAILED(rv)) { + return rv; + } + + NS_ENSURE_ARG(aFile); + nsPKCS12Blob blob; + rv = blob.ImportFromFile(aFile, aPassword, *aError); + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (NS_SUCCEEDED(rv) && observerService) { + observerService->NotifyObservers(nullptr, "psm:user-certificate-added", + nullptr); + } + + return rv; +} + +NS_IMETHODIMP +nsNSSCertificateDB::ExportPKCS12File( + nsIFile* aFile, const nsTArray>& aCerts, + const nsAString& aPassword, uint32_t* aError) { + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + nsresult rv = BlockUntilLoadableCertsLoaded(); + if (NS_FAILED(rv)) { + return rv; + } + + NS_ENSURE_ARG(aFile); + if (aCerts.IsEmpty()) { + return NS_OK; + } + nsPKCS12Blob blob; + return blob.ExportToFile(aFile, aCerts, aPassword, *aError); +} + +NS_IMETHODIMP +nsNSSCertificateDB::ConstructX509FromBase64(const nsACString& base64, + /*out*/ nsIX509Cert** _retval) { + if (!_retval) { + return NS_ERROR_INVALID_POINTER; + } + + // Base64Decode() doesn't consider a zero length input as an error, and just + // returns the empty string. We don't want this behavior, so the below check + // catches this case. + if (base64.Length() < 1) { + return NS_ERROR_ILLEGAL_VALUE; + } + + nsAutoCString certDER; + nsresult rv = Base64Decode(base64, certDER); + if (NS_FAILED(rv)) { + return rv; + } + + return ConstructX509FromSpan(AsBytes(Span(certDER)), _retval); +} + +NS_IMETHODIMP +nsNSSCertificateDB::ConstructX509(const nsTArray& certDER, + nsIX509Cert** _retval) { + return ConstructX509FromSpan(Span(certDER.Elements(), certDER.Length()), + _retval); +} + +nsresult nsNSSCertificateDB::ConstructX509FromSpan( + Span aInputSpan, nsIX509Cert** _retval) { + if (NS_WARN_IF(!_retval)) { + return NS_ERROR_INVALID_POINTER; + } + + if (aInputSpan.Length() > std::numeric_limits::max()) { + return NS_ERROR_ILLEGAL_VALUE; + } + + SECItem certData; + certData.type = siDERCertBuffer; + certData.data = const_cast( + reinterpret_cast(aInputSpan.Elements())); + certData.len = aInputSpan.Length(); + + UniqueCERTCertificate cert(CERT_NewTempCertificate( + CERT_GetDefaultCertDB(), &certData, nullptr, false, true)); + if (!cert) + return (PORT_GetError() == SEC_ERROR_NO_MEMORY) ? NS_ERROR_OUT_OF_MEMORY + : NS_ERROR_FAILURE; + + nsCOMPtr nssCert = nsNSSCertificate::Create(cert.get()); + if (!nssCert) { + return NS_ERROR_OUT_OF_MEMORY; + } + nssCert.forget(_retval); + return NS_OK; +} + +void nsNSSCertificateDB::get_default_nickname(CERTCertificate* cert, + nsIInterfaceRequestor* ctx, + nsCString& nickname) { + nickname.Truncate(); + + CK_OBJECT_HANDLE keyHandle; + + if (NS_FAILED(BlockUntilLoadableCertsLoaded())) { + return; + } + + CERTCertDBHandle* defaultcertdb = CERT_GetDefaultCertDB(); + nsAutoCString username; + UniquePORTString tempCN(CERT_GetCommonName(&cert->subject)); + if (tempCN) { + username = tempCN.get(); + } + + nsAutoCString caname; + UniquePORTString tempIssuerOrg(CERT_GetOrgName(&cert->issuer)); + if (tempIssuerOrg) { + caname = tempIssuerOrg.get(); + } + + nsAutoString tmpNickFmt; + GetPIPNSSBundleString("nick_template", tmpNickFmt); + NS_ConvertUTF16toUTF8 nickFmt(tmpNickFmt); + + nsAutoCString baseName; + baseName.AppendPrintf(nickFmt.get(), username.get(), caname.get()); + if (baseName.IsEmpty()) { + return; + } + + nickname = baseName; + + /* + * We need to see if the private key exists on a token, if it does + * then we need to check for nicknames that already exist on the smart + * card. + */ + UniquePK11SlotInfo slot(PK11_KeyForCertExists(cert, &keyHandle, ctx)); + if (!slot) return; + + if (!PK11_IsInternal(slot.get())) { + nsAutoCString tmp; + tmp.AppendPrintf("%s:%s", PK11_GetTokenName(slot.get()), baseName.get()); + if (tmp.IsEmpty()) { + nickname.Truncate(); + return; + } + baseName = tmp; + nickname = baseName; + } + + int count = 1; + while (true) { + if (count > 1) { + nsAutoCString tmp; + tmp.AppendPrintf("%s #%d", baseName.get(), count); + if (tmp.IsEmpty()) { + nickname.Truncate(); + return; + } + nickname = tmp; + } + + UniqueCERTCertificate dummycert; + + if (PK11_IsInternal(slot.get())) { + /* look up the nickname to make sure it isn't in use already */ + dummycert.reset(CERT_FindCertByNickname(defaultcertdb, nickname.get())); + } else { + // Check the cert against others that already live on the smart card. + dummycert.reset(PK11_FindCertFromNickname(nickname.get(), ctx)); + if (dummycert) { + // Make sure the subject names are different. + if (CERT_CompareName(&cert->subject, &dummycert->subject) == SECEqual) { + /* + * There is another certificate with the same nickname and + * the same subject name on the smart card, so let's use this + * nickname. + */ + dummycert = nullptr; + } + } + } + if (!dummycert) { + break; + } + count++; + } +} + +NS_IMETHODIMP +nsNSSCertificateDB::AddCertFromBase64(const nsACString& aBase64, + const nsACString& aTrust, + nsIX509Cert** addedCertificate) { + // Base64Decode() doesn't consider a zero length input as an error, and just + // returns the empty string. We don't want this behavior, so the below check + // catches this case. + if (aBase64.Length() < 1) { + return NS_ERROR_ILLEGAL_VALUE; + } + + nsAutoCString aCertDER; + nsresult rv = Base64Decode(aBase64, aCertDER); + if (NS_FAILED(rv)) { + return rv; + } + return AddCert(aCertDER, aTrust, addedCertificate); +} + +NS_IMETHODIMP +nsNSSCertificateDB::AddCert(const nsACString& aCertDER, + const nsACString& aTrust, + nsIX509Cert** addedCertificate) { + MOZ_ASSERT(addedCertificate); + if (!addedCertificate) { + return NS_ERROR_INVALID_ARG; + } + *addedCertificate = nullptr; + + nsNSSCertTrust trust; + if (CERT_DecodeTrustString(&trust.GetTrust(), + PromiseFlatCString(aTrust).get()) != SECSuccess) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr newCert; + nsresult rv = + ConstructX509FromSpan(AsBytes(Span(aCertDER)), getter_AddRefs(newCert)); + if (NS_FAILED(rv)) { + return rv; + } + + UniqueCERTCertificate tmpCert(newCert->GetCert()); + if (!tmpCert) { + return NS_ERROR_FAILURE; + } + + // If there's already a certificate that matches this one in the database, we + // still want to set its trust to the given value. + if (tmpCert->isperm) { + rv = SetCertTrustFromString(newCert, aTrust); + if (NS_FAILED(rv)) { + return rv; + } + newCert.forget(addedCertificate); + return NS_OK; + } + + UniquePORTString nickname(CERT_MakeCANickname(tmpCert.get())); + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("Created nick \"%s\"\n", nickname.get())); + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + SECStatus srv = PK11_ImportCert(slot.get(), tmpCert.get(), CK_INVALID_HANDLE, + nickname.get(), + false); // this parameter is ignored by NSS + if (srv != SECSuccess) { + return MapSECStatus(srv); + } + srv = ChangeCertTrustWithPossibleAuthentication(tmpCert, trust.GetTrust(), + nullptr); + if (srv != SECSuccess) { + return MapSECStatus(srv); + } + newCert.forget(addedCertificate); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificateDB::SetCertTrustFromString(nsIX509Cert* cert, + const nsACString& trustString) { + NS_ENSURE_ARG(cert); + + CERTCertTrust trust; + SECStatus srv = + CERT_DecodeTrustString(&trust, PromiseFlatCString(trustString).get()); + if (srv != SECSuccess) { + return MapSECStatus(srv); + } + UniqueCERTCertificate nssCert(cert->GetCert()); + + srv = ChangeCertTrustWithPossibleAuthentication(nssCert, trust, nullptr); + return MapSECStatus(srv); +} + +NS_IMETHODIMP nsNSSCertificateDB::AsPKCS7Blob( + const nsTArray>& certList, nsACString& _retval) { + if (certList.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + + UniqueNSSCMSMessage cmsg(NSS_CMSMessage_Create(nullptr)); + if (!cmsg) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("nsNSSCertificateDB::AsPKCS7Blob - can't create CMS message")); + return NS_ERROR_OUT_OF_MEMORY; + } + + UniqueNSSCMSSignedData sigd(nullptr); + for (const auto& cert : certList) { + // We need an owning handle when calling nsIX509Cert::GetCert(). + UniqueCERTCertificate nssCert(cert->GetCert()); + if (!sigd) { + sigd.reset( + NSS_CMSSignedData_CreateCertsOnly(cmsg.get(), nssCert.get(), false)); + if (!sigd) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("nsNSSCertificateDB::AsPKCS7Blob - can't create SignedData")); + return NS_ERROR_FAILURE; + } + } else if (NSS_CMSSignedData_AddCertificate(sigd.get(), nssCert.get()) != + SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("nsNSSCertificateDB::AsPKCS7Blob - can't add cert")); + return NS_ERROR_FAILURE; + } + } + + NSSCMSContentInfo* cinfo = NSS_CMSMessage_GetContentInfo(cmsg.get()); + if (NSS_CMSContentInfo_SetContent_SignedData(cmsg.get(), cinfo, sigd.get()) != + SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("nsNSSCertificateDB::AsPKCS7Blob - can't attach SignedData")); + return NS_ERROR_FAILURE; + } + // cmsg owns sigd now. + Unused << sigd.release(); + + UniquePLArenaPool arena(PORT_NewArena(1024)); + if (!arena) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("nsNSSCertificateDB::AsPKCS7Blob - out of memory")); + return NS_ERROR_OUT_OF_MEMORY; + } + + SECItem certP7 = {siBuffer, nullptr, 0}; + NSSCMSEncoderContext* ecx = NSS_CMSEncoder_Start( + cmsg.get(), nullptr, nullptr, &certP7, arena.get(), nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr); + if (!ecx) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("nsNSSCertificateDB::AsPKCS7Blob - can't create encoder")); + return NS_ERROR_FAILURE; + } + + if (NSS_CMSEncoder_Finish(ecx) != SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("nsNSSCertificateDB::AsPKCS7Blob - failed to add encoded data")); + return NS_ERROR_FAILURE; + } + + _retval.Assign(nsDependentCSubstring( + reinterpret_cast(certP7.data), certP7.len)); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSCertificateDB::GetCerts(nsTArray>& _retval) { + nsresult rv = BlockUntilLoadableCertsLoaded(); + if (NS_FAILED(rv)) { + return rv; + } + + rv = CheckForSmartCardChanges(); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr ctx = new PipUIContext(); + UniqueCERTCertList certList(PK11_ListCerts(PK11CertListUnique, ctx)); + if (!certList) { + return NS_ERROR_FAILURE; + } + return nsNSSCertificateDB::ConstructCertArrayFromUniqueCertList(certList, + _retval); +} + +NS_IMETHODIMP +nsNSSCertificateDB::AsyncHasThirdPartyRoots(nsIAsyncBoolCallback* aCallback) { + NS_ENSURE_ARG_POINTER(aCallback); + nsMainThreadPtrHandle callback( + new nsMainThreadPtrHolder("AsyncHasThirdPartyRoots", + aCallback)); + + return NS_DispatchBackgroundTask( + NS_NewRunnableFunction( + "nsNSSCertificateDB::AsyncHasThirdPartyRoots", + [cb = std::move(callback), self = RefPtr{this}] { + bool hasThirdPartyRoots = [self]() -> bool { + nsTArray> certs; + nsresult rv = self->GetCerts(certs); + if (NS_FAILED(rv)) { + return false; + } + + for (const auto& cert : certs) { + bool isTrusted = false; + nsresult rv = + self->IsCertTrusted(cert, nsIX509Cert::CA_CERT, + nsIX509CertDB::TRUSTED_SSL, &isTrusted); + if (NS_FAILED(rv)) { + return false; + } + + if (!isTrusted) { + continue; + } + + bool isBuiltInRoot = false; + rv = cert->GetIsBuiltInRoot(&isBuiltInRoot); + if (NS_FAILED(rv)) { + return false; + } + + if (!isBuiltInRoot) { + return true; + } + } + + return false; + }(); + + NS_DispatchToMainThread(NS_NewRunnableFunction( + "nsNSSCertificateDB::AsyncHasThirdPartyRoots callback", + [cb, hasThirdPartyRoots]() { + cb->OnResult(hasThirdPartyRoots); + })); + }), + NS_DISPATCH_EVENT_MAY_BLOCK); + + return NS_OK; +} + +nsresult VerifyCertAtTime(nsIX509Cert* aCert, + int64_t /*SECCertificateUsage*/ aUsage, + uint32_t aFlags, const nsACString& aHostname, + mozilla::pkix::Time aTime, + nsTArray>& aVerifiedChain, + bool* aHasEVPolicy, + int32_t* /*PRErrorCode*/ _retval) { + NS_ENSURE_ARG_POINTER(aCert); + NS_ENSURE_ARG_POINTER(aHasEVPolicy); + NS_ENSURE_ARG_POINTER(_retval); + + if (!aVerifiedChain.IsEmpty()) { + return NS_ERROR_INVALID_ARG; + } + + *aHasEVPolicy = false; + *_retval = PR_UNKNOWN_ERROR; + + UniqueCERTCertificate nssCert(aCert->GetCert()); + if (!nssCert) { + return NS_ERROR_INVALID_ARG; + } + + RefPtr certVerifier(GetDefaultCertVerifier()); + NS_ENSURE_TRUE(certVerifier, NS_ERROR_FAILURE); + + UniqueCERTCertList resultChain; + SECOidTag evOidPolicy; + mozilla::pkix::Result result; + + if (!aHostname.IsVoid() && aUsage == certificateUsageSSLServer) { + result = + certVerifier->VerifySSLServerCert(nssCert, aTime, + nullptr, // Assume no context + aHostname, resultChain, aFlags, + Nothing(), // extraCertificates + Nothing(), // stapledOCSPResponse + Nothing(), // sctsFromTLSExtension + Nothing(), // dcInfo + OriginAttributes(), + false, // don't save intermediates + &evOidPolicy); + } else { + const nsCString& flatHostname = PromiseFlatCString(aHostname); + result = certVerifier->VerifyCert( + nssCert.get(), aUsage, aTime, + nullptr, // Assume no context + aHostname.IsVoid() ? nullptr : flatHostname.get(), resultChain, aFlags, + Nothing(), // extraCertificates + Nothing(), // stapledOCSPResponse + Nothing(), // sctsFromTLSExtension + OriginAttributes(), &evOidPolicy); + } + + if (result == mozilla::pkix::Success) { + nsresult rv = nsNSSCertificateDB::ConstructCertArrayFromUniqueCertList( + resultChain, aVerifiedChain); + + if (NS_FAILED(rv)) { + return rv; + } + + if (evOidPolicy != SEC_OID_UNKNOWN) { + *aHasEVPolicy = true; + } + } + + *_retval = mozilla::pkix::MapResultToPRErrorCode(result); + + return NS_OK; +} + +class VerifyCertAtTimeTask final : public CryptoTask { + public: + VerifyCertAtTimeTask(nsIX509Cert* aCert, int64_t aUsage, uint32_t aFlags, + const nsACString& aHostname, uint64_t aTime, + nsICertVerificationCallback* aCallback) + : mCert(aCert), + mUsage(aUsage), + mFlags(aFlags), + mHostname(aHostname), + mTime(aTime), + mCallback(new nsMainThreadPtrHolder( + "nsICertVerificationCallback", aCallback)), + mPRErrorCode(SEC_ERROR_LIBRARY_FAILURE), + mHasEVPolicy(false) {} + + private: + virtual nsresult CalculateResult() override { + nsCOMPtr certDB = do_GetService(NS_X509CERTDB_CONTRACTID); + if (!certDB) { + return NS_ERROR_FAILURE; + } + return VerifyCertAtTime(mCert, mUsage, mFlags, mHostname, + mozilla::pkix::TimeFromEpochInSeconds(mTime), + mVerifiedCertList, &mHasEVPolicy, &mPRErrorCode); + } + + virtual void CallCallback(nsresult rv) override { + if (NS_FAILED(rv)) { + nsTArray> tmp; + Unused << mCallback->VerifyCertFinished(SEC_ERROR_LIBRARY_FAILURE, tmp, + false); + } else { + Unused << mCallback->VerifyCertFinished(mPRErrorCode, mVerifiedCertList, + mHasEVPolicy); + } + } + + nsCOMPtr mCert; + int64_t mUsage; + uint32_t mFlags; + nsCString mHostname; + uint64_t mTime; + nsMainThreadPtrHandle mCallback; + int32_t mPRErrorCode; + nsTArray> mVerifiedCertList; + bool mHasEVPolicy; +}; + +NS_IMETHODIMP +nsNSSCertificateDB::AsyncVerifyCertAtTime( + nsIX509Cert* aCert, int64_t /*SECCertificateUsage*/ aUsage, uint32_t aFlags, + const nsACString& aHostname, uint64_t aTime, + nsICertVerificationCallback* aCallback) { + RefPtr task(new VerifyCertAtTimeTask( + aCert, aUsage, aFlags, aHostname, aTime, aCallback)); + return task->Dispatch(); +} + +NS_IMETHODIMP +nsNSSCertificateDB::ClearOCSPCache() { + RefPtr certVerifier(GetDefaultCertVerifier()); + NS_ENSURE_TRUE(certVerifier, NS_ERROR_FAILURE); + certVerifier->ClearOCSPCache(); + return NS_OK; +} diff --git a/security/manager/ssl/nsNSSCertificateDB.h b/security/manager/ssl/nsNSSCertificateDB.h new file mode 100644 index 0000000000..125bb32acd --- /dev/null +++ b/security/manager/ssl/nsNSSCertificateDB.h @@ -0,0 +1,71 @@ +/* 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/. */ + +#ifndef nsNSSCertificateDB_h +#define nsNSSCertificateDB_h + +#include "ScopedNSSTypes.h" +#include "certt.h" +#include "mozilla/Mutex.h" +#include "mozilla/NotNull.h" +#include "mozilla/RefPtr.h" +#include "mozilla/UniquePtr.h" +#include "nsIX509CertDB.h" +#include "nsString.h" + +class nsIArray; + +class nsNSSCertificateDB final : public nsIX509CertDB + +{ + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIX509CERTDB + + // This is a separate static method so nsNSSComponent can use it during NSS + // initialization. Other code should probably not use it. + static nsresult FindCertByDBKey(const nsACString& aDBKey, + mozilla::UniqueCERTCertificate& cert); + + static nsresult ConstructCertArrayFromUniqueCertList( + const mozilla::UniqueCERTCertList& aCertListIn, + nsTArray>& aCertListOut); + + protected: + virtual ~nsNSSCertificateDB() = default; + + private: + // Use this function to generate a default nickname for a user + // certificate that is to be imported onto a token. + static void get_default_nickname(CERTCertificate* cert, + nsIInterfaceRequestor* ctx, + nsCString& nickname); + + static nsresult ImportCACerts(nsTArray>& CACerts, + nsIInterfaceRequestor* ctx); + + static void DisplayCertificateAlert(nsIInterfaceRequestor* ctx, + const char* stringID, + nsIX509Cert* certToShow); + + nsresult getCertsFromPackage(nsTArray>& collectArgs, + uint8_t* data, uint32_t length); + nsresult handleCACertDownload(mozilla::NotNull x509Certs, + nsIInterfaceRequestor* ctx); + nsresult ConstructX509FromSpan(const mozilla::Span aInputSpan, + nsIX509Cert** _retval); +}; + +#define NS_X509CERTDB_CID \ + { /* fb0bbc5c-452e-4783-b32c-80124693d871 */ \ + 0xfb0bbc5c, 0x452e, 0x4783, { \ + 0xb3, 0x2c, 0x80, 0x12, 0x46, 0x93, 0xd8, 0x71 \ + } \ + } + +SECStatus ChangeCertTrustWithPossibleAuthentication( + const mozilla::UniqueCERTCertificate& cert, CERTCertTrust& trust, + void* ctx); + +#endif // nsNSSCertificateDB_h diff --git a/security/manager/ssl/nsNSSComponent.cpp b/security/manager/ssl/nsNSSComponent.cpp new file mode 100644 index 0000000000..30e3dabdfc --- /dev/null +++ b/security/manager/ssl/nsNSSComponent.cpp @@ -0,0 +1,2755 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsNSSComponent.h" + +#include "CryptoTask.h" +#include "EnterpriseRoots.h" +#include "ExtendedValidation.h" +#include "GeckoProfiler.h" +#include "NSSCertDBTrustDomain.h" +#include "SSLTokensCache.h" +#include "ScopedNSSTypes.h" +#include "SharedSSLState.h" +#include "cert.h" +#include "cert_storage/src/cert_storage.h" +#include "certdb.h" +#include "mozilla/AppShutdown.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Assertions.h" +#include "mozilla/Casting.h" +#include "mozilla/PodOperations.h" +#include "mozilla/Preferences.h" +#include "mozilla/PublicSSL.h" +#include "mozilla/Services.h" +#include "mozilla/StaticMutex.h" +#include "mozilla/StaticPtr.h" +#include "mozilla/SyncRunnable.h" +#include "mozilla/Telemetry.h" +#include "mozilla/TimeStamp.h" +#include "mozilla/Unused.h" +#include "mozilla/Vector.h" +#include "mozilla/net/SocketProcessParent.h" +#include "mozpkix/pkixnss.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsCRT.h" +#include "nsClientAuthRemember.h" +#include "nsComponentManagerUtils.h" +#include "nsDirectoryServiceDefs.h" +#include "nsICertOverrideService.h" +#include "nsIFile.h" +#include "nsILocalFileWin.h" +#include "nsIOService.h" +#include "nsIObserverService.h" +#include "nsIPrompt.h" +#include "nsIProperties.h" +#include "nsISerialEventTarget.h" +#include "nsISiteSecurityService.h" +#include "nsITimer.h" +#include "nsITokenPasswordDialogs.h" +#include "nsIWindowWatcher.h" +#include "nsIXULRuntime.h" +#include "nsLiteralString.h" +#include "nsNSSCertificateDB.h" +#include "nsNSSHelper.h" +#include "nsNetCID.h" +#include "nsPK11TokenDB.h" +#include "nsPrintfCString.h" +#include "nsServiceManagerUtils.h" +#include "nsThreadUtils.h" +#include "nsXULAppAPI.h" +#include "nss.h" +#include "p12plcy.h" +#include "pk11pub.h" +#include "prmem.h" +#include "secerr.h" +#include "secmod.h" +#include "ssl.h" +#include "sslerr.h" +#include "sslproto.h" + +#if defined(XP_LINUX) && !defined(ANDROID) +# include +# include +#endif + +#ifdef XP_WIN +# include "mozilla/WindowsVersion.h" +# include "nsILocalFileWin.h" + +# include "windows.h" // this needs to be before the following includes +# include "lmcons.h" +# include "sddl.h" +# include "wincrypt.h" +# include "nsIWindowsRegKey.h" +#endif + +using namespace mozilla; +using namespace mozilla::psm; + +LazyLogModule gPIPNSSLog("pipnss"); + +int nsNSSComponent::mInstanceCount = 0; + +// Forward declaration. +nsresult CommonInit(); + +// This function can be called from chrome or content or socket processes +// to ensure that NSS is initialized. +bool EnsureNSSInitializedChromeOrContent() { + static Atomic initialized(false); + + if (initialized) { + return true; + } + + // If this is not the main thread (i.e. probably a worker) then forward this + // call to the main thread. + if (!NS_IsMainThread()) { + nsCOMPtr mainThread; + nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread)); + if (NS_FAILED(rv)) { + return false; + } + + // Forward to the main thread synchronously. + mozilla::SyncRunnable::DispatchToThread( + mainThread, new SyncRunnable(NS_NewRunnableFunction( + "EnsureNSSInitializedChromeOrContent", + []() { EnsureNSSInitializedChromeOrContent(); }))); + + return initialized; + } + + if (XRE_IsParentProcess()) { + nsCOMPtr nss = do_GetService(PSM_COMPONENT_CONTRACTID); + if (!nss) { + return false; + } + initialized = true; + return true; + } + + if (NSS_IsInitialized()) { + initialized = true; + return true; + } + + if (NSS_NoDB_Init(nullptr) != SECSuccess) { + return false; + } + + if (XRE_IsSocketProcess()) { + if (NS_FAILED(CommonInit())) { + return false; + } + initialized = true; + return true; + } + + if (NS_FAILED(mozilla::psm::InitializeCipherSuite())) { + return false; + } + + mozilla::psm::DisableMD5(); + mozilla::pkix::RegisterErrorTable(); + initialized = true; + return true; +} + +static const uint32_t OCSP_TIMEOUT_MILLISECONDS_SOFT_DEFAULT = 2000; +static const uint32_t OCSP_TIMEOUT_MILLISECONDS_SOFT_MAX = 5000; +static const uint32_t OCSP_TIMEOUT_MILLISECONDS_HARD_DEFAULT = 10000; +static const uint32_t OCSP_TIMEOUT_MILLISECONDS_HARD_MAX = 20000; + +void nsNSSComponent::GetRevocationBehaviorFromPrefs( + /*out*/ CertVerifier::OcspDownloadConfig* odc, + /*out*/ CertVerifier::OcspStrictConfig* osc, + /*out*/ uint32_t* certShortLifetimeInDays, + /*out*/ TimeDuration& softTimeout, + /*out*/ TimeDuration& hardTimeout, const MutexAutoLock& /*proofOfLock*/) { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(odc); + MOZ_ASSERT(osc); + MOZ_ASSERT(certShortLifetimeInDays); + + // 0 = disabled + // 1 = enabled for everything (default) + // 2 = enabled for EV certificates only + int32_t ocspLevel = Preferences::GetInt("security.OCSP.enabled", 1); + switch (ocspLevel) { + case 0: + *odc = CertVerifier::ocspOff; + break; + case 2: + *odc = CertVerifier::ocspEVOnly; + break; + default: + *odc = CertVerifier::ocspOn; + break; + } + + *osc = Preferences::GetBool("security.OCSP.require", false) + ? CertVerifier::ocspStrict + : CertVerifier::ocspRelaxed; + + // If we pass in just 0 as the second argument to Preferences::GetUint, there + // are two function signatures that match (given that 0 can be intepreted as + // a null pointer). Thus the compiler will complain without the cast. + *certShortLifetimeInDays = Preferences::GetUint( + "security.pki.cert_short_lifetime_in_days", static_cast(0)); + + uint32_t softTimeoutMillis = + Preferences::GetUint("security.OCSP.timeoutMilliseconds.soft", + OCSP_TIMEOUT_MILLISECONDS_SOFT_DEFAULT); + softTimeoutMillis = + std::min(softTimeoutMillis, OCSP_TIMEOUT_MILLISECONDS_SOFT_MAX); + softTimeout = TimeDuration::FromMilliseconds(softTimeoutMillis); + + uint32_t hardTimeoutMillis = + Preferences::GetUint("security.OCSP.timeoutMilliseconds.hard", + OCSP_TIMEOUT_MILLISECONDS_HARD_DEFAULT); + hardTimeoutMillis = + std::min(hardTimeoutMillis, OCSP_TIMEOUT_MILLISECONDS_HARD_MAX); + hardTimeout = TimeDuration::FromMilliseconds(hardTimeoutMillis); + + ClearSSLExternalAndInternalSessionCache(); +} + +nsNSSComponent::nsNSSComponent() + : mLoadableCertsLoadedMonitor("nsNSSComponent.mLoadableCertsLoadedMonitor"), + mLoadableCertsLoaded(false), + mLoadableCertsLoadedResult(NS_ERROR_FAILURE), + mMutex("nsNSSComponent.mMutex"), + mMitmDetecionEnabled(false), + mLoadLoadableCertsTaskDispatched(false) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::ctor\n")); + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + + MOZ_ASSERT(mInstanceCount == 0, + "nsNSSComponent is a singleton, but instantiated multiple times!"); + ++mInstanceCount; +} + +nsNSSComponent::~nsNSSComponent() { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::dtor\n")); + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + + // All cleanup code requiring services needs to happen in xpcom_shutdown + + ShutdownNSS(); + SharedSSLState::GlobalCleanup(); + RememberCertErrorsTable::Cleanup(); + --mInstanceCount; + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::dtor finished\n")); +} + +#ifdef XP_WIN +static bool GetUserSid(nsAString& sidString) { + // UNLEN is the maximum user name length (see Lmcons.h). +1 for the null + // terminator. + WCHAR lpAccountName[UNLEN + 1]; + DWORD lcAccountName = sizeof(lpAccountName) / sizeof(lpAccountName[0]); + BOOL success = GetUserName(lpAccountName, &lcAccountName); + if (!success) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("GetUserName failed")); + return false; + } + char sid_buffer[SECURITY_MAX_SID_SIZE]; + SID* sid = BitwiseCast(sid_buffer); + DWORD cbSid = ArrayLength(sid_buffer); + SID_NAME_USE eUse; + // There doesn't appear to be a defined maximum length for the domain name + // here. To deal with this, we start with a reasonable buffer length and + // see if that works. If it fails and the error indicates insufficient length, + // we use the indicated required length and try again. + DWORD cchReferencedDomainName = 128; + auto ReferencedDomainName(MakeUnique(cchReferencedDomainName)); + success = LookupAccountName(nullptr, lpAccountName, sid, &cbSid, + ReferencedDomainName.get(), + &cchReferencedDomainName, &eUse); + if (!success && GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("LookupAccountName failed")); + return false; + } + if (!success) { + ReferencedDomainName = MakeUnique(cchReferencedDomainName); + success = LookupAccountName(nullptr, lpAccountName, sid, &cbSid, + ReferencedDomainName.get(), + &cchReferencedDomainName, &eUse); + } + if (!success) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("LookupAccountName failed")); + return false; + } + LPTSTR StringSid; + success = ConvertSidToStringSid(sid, &StringSid); + if (!success) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("ConvertSidToStringSid failed")); + return false; + } + sidString.Assign(StringSid); + LocalFree(StringSid); + return true; +} + +// This is a specialized helper function to read the value of a registry key +// that might not be present. If it is present, returns (via the output +// parameter) its value. Otherwise, returns the given default value. +// This function handles one level of nesting. That is, if the desired value +// is actually in a direct child of the given registry key (where the child +// and/or the value being sought may not actually be present), this function +// will handle that. In the normal case, though, optionalChildName will be +// null. +static nsresult ReadRegKeyValueWithDefault(nsCOMPtr regKey, + uint32_t flags, + const wchar_t* optionalChildName, + const wchar_t* valueName, + uint32_t defaultValue, + uint32_t& valueOut) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("ReadRegKeyValueWithDefault")); + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("attempting to read '%S%s%S' with default '%u'", + optionalChildName ? optionalChildName : L"", + optionalChildName ? "\\" : "", valueName, defaultValue)); + if (optionalChildName) { + nsDependentString childNameString(optionalChildName); + bool hasChild; + nsresult rv = regKey->HasChild(childNameString, &hasChild); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("failed to determine if child key is present")); + return rv; + } + if (!hasChild) { + valueOut = defaultValue; + return NS_OK; + } + nsCOMPtr childRegKey; + rv = regKey->OpenChild(childNameString, flags, getter_AddRefs(childRegKey)); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't open child key")); + return rv; + } + return ReadRegKeyValueWithDefault(childRegKey, flags, nullptr, valueName, + defaultValue, valueOut); + } + nsDependentString valueNameString(valueName); + bool hasValue; + nsresult rv = regKey->HasValue(valueNameString, &hasValue); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("failed to determine if value is present")); + return rv; + } + if (!hasValue) { + valueOut = defaultValue; + return NS_OK; + } + rv = regKey->ReadIntValue(valueNameString, &valueOut); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("failed to read value")); + return rv; + } + return NS_OK; +} + +static nsresult AccountHasFamilySafetyEnabled(bool& enabled) { + enabled = false; + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("AccountHasFamilySafetyEnabled?")); + nsCOMPtr parentalControlsKey( + do_CreateInstance("@mozilla.org/windows-registry-key;1")); + if (!parentalControlsKey) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't create nsIWindowsRegKey")); + return NS_ERROR_FAILURE; + } + uint32_t flags = nsIWindowsRegKey::ACCESS_READ | nsIWindowsRegKey::WOW64_64; + constexpr auto familySafetyPath = + u"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Parental Controls"_ns; + nsresult rv = parentalControlsKey->Open( + nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, familySafetyPath, flags); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't open parentalControlsKey")); + return rv; + } + constexpr auto usersString = u"Users"_ns; + bool hasUsers; + rv = parentalControlsKey->HasChild(usersString, &hasUsers); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("HasChild(Users) failed")); + return rv; + } + if (!hasUsers) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("Users subkey not present - Parental Controls not enabled")); + return NS_OK; + } + nsCOMPtr usersKey; + rv = parentalControlsKey->OpenChild(usersString, flags, + getter_AddRefs(usersKey)); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("failed to open Users subkey")); + return rv; + } + nsAutoString sid; + if (!GetUserSid(sid)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't get sid")); + return NS_ERROR_FAILURE; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("our sid is '%S'", sid.get())); + bool hasSid; + rv = usersKey->HasChild(sid, &hasSid); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("HasChild(sid) failed")); + return rv; + } + if (!hasSid) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("sid not present in Family Safety Users")); + return NS_OK; + } + nsCOMPtr sidKey; + rv = usersKey->OpenChild(sid, flags, getter_AddRefs(sidKey)); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't open sid key")); + return rv; + } + // There are three keys we're interested in: "Parental Controls On", + // "Logging Required", and "Web\\Filter On". These keys will have value 0 + // or 1, indicating a particular feature is disabled or enabled, + // respectively. So, if "Parental Controls On" is not 1, Family Safety is + // disabled and we don't care about anything else. If both "Logging + // Required" and "Web\\Filter On" are 0, the proxy will not be running, + // so for our purposes we can consider Family Safety disabled in that + // case. + // By default, "Logging Required" is 1 and "Web\\Filter On" is 0, + // reflecting the initial settings when Family Safety is enabled for an + // account for the first time, However, these sub-keys are not created + // unless they are switched away from the default value. + uint32_t parentalControlsOn; + rv = sidKey->ReadIntValue(u"Parental Controls On"_ns, &parentalControlsOn); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("couldn't read Parental Controls On")); + return rv; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("Parental Controls On: %u", parentalControlsOn)); + if (parentalControlsOn != 1) { + return NS_OK; + } + uint32_t loggingRequired; + rv = ReadRegKeyValueWithDefault(sidKey, flags, nullptr, L"Logging Required", + 1, loggingRequired); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("failed to read value of Logging Required")); + return rv; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("Logging Required: %u", loggingRequired)); + uint32_t webFilterOn; + rv = ReadRegKeyValueWithDefault(sidKey, flags, L"Web", L"Filter On", 0, + webFilterOn); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("failed to read value of Web\\Filter On")); + return rv; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Web\\Filter On: %u", webFilterOn)); + enabled = loggingRequired == 1 || webFilterOn == 1; + return NS_OK; +} +#endif // XP_WIN + +// On Windows 8.1, if the following preference is 2, we will attempt to detect +// if the Family Safety TLS interception feature has been enabled. If so, we +// will behave as if the enterprise roots feature has been enabled (i.e. import +// and trust third party root certificates from the OS). +// With any other value of the pref or on any other platform, this does nothing. +// This preference takes precedence over "security.enterprise_roots.enabled". +const char* kFamilySafetyModePref = "security.family_safety.mode"; +const uint32_t kFamilySafetyModeDefault = 0; + +bool nsNSSComponent::ShouldEnableEnterpriseRootsForFamilySafety( + uint32_t familySafetyMode) { +#ifdef XP_WIN + if (!(IsWin8Point1OrLater() && !IsWin10OrLater())) { + return false; + } + if (familySafetyMode != 2) { + return false; + } + bool familySafetyEnabled; + nsresult rv = AccountHasFamilySafetyEnabled(familySafetyEnabled); + if (NS_FAILED(rv)) { + return false; + } + return familySafetyEnabled; +#else + return false; +#endif // XP_WIN +} + +void nsNSSComponent::UnloadEnterpriseRoots() { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("UnloadEnterpriseRoots")); + MutexAutoLock lock(mMutex); + mEnterpriseCerts.clear(); + setValidationOptions(false, lock); +} + +static const char* kEnterpriseRootModePref = + "security.enterprise_roots.enabled"; +static const char* kOSClientCertsModulePref = "security.osclientcerts.autoload"; + +class BackgroundImportEnterpriseCertsTask final : public CryptoTask { + public: + explicit BackgroundImportEnterpriseCertsTask(nsNSSComponent* nssComponent) + : mNSSComponent(nssComponent) {} + + private: + virtual nsresult CalculateResult() override { + mNSSComponent->ImportEnterpriseRoots(); + mNSSComponent->UpdateCertVerifierWithEnterpriseRoots(); + return NS_OK; + } + + virtual void CallCallback(nsresult rv) override { + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (observerService) { + observerService->NotifyObservers(nullptr, "psm:enterprise-certs-imported", + nullptr); + } + } + + RefPtr mNSSComponent; +}; + +void nsNSSComponent::MaybeImportEnterpriseRoots() { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return; + } + bool importEnterpriseRoots = + Preferences::GetBool(kEnterpriseRootModePref, false); + uint32_t familySafetyMode = + Preferences::GetUint(kFamilySafetyModePref, kFamilySafetyModeDefault); + // If we've been configured to detect the Family Safety TLS interception + // feature, see if it's enabled. If so, we want to import enterprise roots. + if (ShouldEnableEnterpriseRootsForFamilySafety(familySafetyMode)) { + importEnterpriseRoots = true; + } + if (importEnterpriseRoots) { + RefPtr task = + new BackgroundImportEnterpriseCertsTask(this); + Unused << task->Dispatch(); + } +} + +void nsNSSComponent::ImportEnterpriseRoots() { + MOZ_ASSERT(!NS_IsMainThread()); + if (NS_IsMainThread()) { + return; + } + + Vector enterpriseCerts; + nsresult rv = GatherEnterpriseCerts(enterpriseCerts); + if (NS_SUCCEEDED(rv)) { + MutexAutoLock lock(mMutex); + mEnterpriseCerts = std::move(enterpriseCerts); + } else { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("failed gathering enterprise roots")); + } +} + +nsresult nsNSSComponent::CommonGetEnterpriseCerts( + nsTArray>& enterpriseCerts, bool getRoots) { + nsresult rv = BlockUntilLoadableCertsLoaded(); + if (NS_FAILED(rv)) { + return rv; + } + + MutexAutoLock nsNSSComponentLock(mMutex); + enterpriseCerts.Clear(); + for (const auto& cert : mEnterpriseCerts) { + nsTArray certCopy; + // mEnterpriseCerts includes both roots and intermediates. + if (cert.GetIsRoot() == getRoots) { + nsresult rv = cert.CopyBytes(certCopy); + if (NS_FAILED(rv)) { + return rv; + } + // XXX(Bug 1631371) Check if this should use a fallible operation as it + // pretended earlier. + enterpriseCerts.AppendElement(std::move(certCopy)); + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSComponent::GetEnterpriseRoots( + nsTArray>& enterpriseRoots) { + return CommonGetEnterpriseCerts(enterpriseRoots, true); +} + +NS_IMETHODIMP +nsNSSComponent::GetEnterpriseIntermediates( + nsTArray>& enterpriseIntermediates) { + return CommonGetEnterpriseCerts(enterpriseIntermediates, false); +} + +NS_IMETHODIMP +nsNSSComponent::AddEnterpriseIntermediate( + const nsTArray& intermediateBytes) { + nsresult rv = BlockUntilLoadableCertsLoaded(); + if (NS_FAILED(rv)) { + return rv; + } + EnterpriseCert intermediate; + rv = intermediate.Init(intermediateBytes.Elements(), + intermediateBytes.Length(), false); + if (NS_FAILED(rv)) { + return rv; + } + + { + MutexAutoLock nsNSSComponentLock(mMutex); + if (!mEnterpriseCerts.append(std::move(intermediate))) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + + UpdateCertVerifierWithEnterpriseRoots(); + return NS_OK; +} + +class LoadLoadableCertsTask final : public Runnable { + public: + LoadLoadableCertsTask(nsNSSComponent* nssComponent, + bool importEnterpriseRoots, uint32_t familySafetyMode, + Vector&& possibleLoadableRootsLocations, + Maybe&& osClientCertsModuleLocation) + : Runnable("LoadLoadableCertsTask"), + mNSSComponent(nssComponent), + mImportEnterpriseRoots(importEnterpriseRoots), + mFamilySafetyMode(familySafetyMode), + mPossibleLoadableRootsLocations( + std::move(possibleLoadableRootsLocations)), + mOSClientCertsModuleLocation(std::move(osClientCertsModuleLocation)) { + MOZ_ASSERT(nssComponent); + } + + ~LoadLoadableCertsTask() = default; + + nsresult Dispatch(); + + private: + NS_IMETHOD Run() override; + nsresult LoadLoadableRoots(); + RefPtr mNSSComponent; + bool mImportEnterpriseRoots; + uint32_t mFamilySafetyMode; + Vector mPossibleLoadableRootsLocations; + Maybe mOSClientCertsModuleLocation; +}; + +nsresult LoadLoadableCertsTask::Dispatch() { + // The stream transport service (note: not the socket transport service) can + // be used to perform background tasks or I/O that would otherwise block the + // main thread. + nsCOMPtr target( + do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID)); + if (!target) { + return NS_ERROR_FAILURE; + } + return target->Dispatch(this, NS_DISPATCH_NORMAL); +} + +NS_IMETHODIMP +LoadLoadableCertsTask::Run() { + Telemetry::AutoScalarTimer + timer; + + nsresult loadLoadableRootsResult = LoadLoadableRoots(); + if (NS_WARN_IF(NS_FAILED(loadLoadableRootsResult))) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("LoadLoadableRoots failed")); + // We don't return loadLoadableRootsResult here because then + // BlockUntilLoadableCertsLoaded will just wait forever. Instead we'll save + // its value (below) so we can inform code that relies on the roots module + // being present that loading it failed. + } + + // Loading EV information will only succeed if we've successfully loaded the + // loadable roots module. + if (NS_SUCCEEDED(loadLoadableRootsResult)) { + if (NS_FAILED(LoadExtendedValidationInfo())) { + // This isn't a show-stopper in the same way that failing to load the + // roots module is. + MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("failed to load EV info")); + } + } + + // If we've been configured to detect the Family Safety TLS interception + // feature, see if it's enabled. If so, we want to import enterprise roots. + if (mNSSComponent->ShouldEnableEnterpriseRootsForFamilySafety( + mFamilySafetyMode)) { + mImportEnterpriseRoots = true; + } + if (mImportEnterpriseRoots) { + mNSSComponent->ImportEnterpriseRoots(); + mNSSComponent->UpdateCertVerifierWithEnterpriseRoots(); + } + if (mOSClientCertsModuleLocation.isSome()) { + bool success = LoadOSClientCertsModule(*mOSClientCertsModuleLocation); + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("loading OS client certs module %s", + success ? "succeeded" : "failed")); + } + { + MonitorAutoLock rootsLoadedLock(mNSSComponent->mLoadableCertsLoadedMonitor); + mNSSComponent->mLoadableCertsLoaded = true; + // Cache the result of LoadLoadableRoots so BlockUntilLoadableCertsLoaded + // can return it to all callers later (we use that particular result because + // if that operation fails, it's unlikely that any TLS connection will + // succeed whereas the browser may still be able to operate if the other + // tasks fail). + mNSSComponent->mLoadableCertsLoadedResult = loadLoadableRootsResult; + mNSSComponent->mLoadableCertsLoadedMonitor.NotifyAll(); + } + return NS_OK; +} + +// Returns by reference the path to the desired directory, based on the current +// settings in the directory service. +static nsresult GetDirectoryPath(const char* directoryKey, nsCString& result) { + MOZ_ASSERT(NS_IsMainThread()); + + nsCOMPtr directoryService( + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID)); + if (!directoryService) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("could not get directory service")); + return NS_ERROR_FAILURE; + } + nsCOMPtr directory; + nsresult rv = directoryService->Get(directoryKey, NS_GET_IID(nsIFile), + getter_AddRefs(directory)); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("could not get '%s' from directory service", directoryKey)); + return rv; + } +#ifdef XP_WIN + // Native path will drop Unicode characters that cannot be mapped to system's + // codepage, using short (canonical) path as workaround. + nsCOMPtr directoryWin = do_QueryInterface(directory); + if (!directoryWin) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't get nsILocalFileWin")); + return NS_ERROR_FAILURE; + } + return directoryWin->GetNativeCanonicalPath(result); +#else + return directory->GetNativePath(result); +#endif +} + +class BackgroundLoadOSClientCertsModuleTask final : public CryptoTask { + public: + explicit BackgroundLoadOSClientCertsModuleTask(const nsCString&& libraryDir) + : mLibraryDir(std::move(libraryDir)) {} + + private: + virtual nsresult CalculateResult() override { + bool success = LoadOSClientCertsModule(mLibraryDir); + return success ? NS_OK : NS_ERROR_FAILURE; + } + + virtual void CallCallback(nsresult rv) override { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("loading OS client certs module %s", + NS_SUCCEEDED(rv) ? "succeeded" : "failed")); + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (observerService) { + observerService->NotifyObservers( + nullptr, "psm:load-os-client-certs-module-task-ran", nullptr); + } + } + + nsCString mLibraryDir; +}; + +void AsyncLoadOrUnloadOSClientCertsModule(bool load) { + if (load) { + nsCString libraryDir; + nsresult rv = GetDirectoryPath(NS_GRE_BIN_DIR, libraryDir); + if (NS_FAILED(rv)) { + return; + } + RefPtr task = + new BackgroundLoadOSClientCertsModuleTask(std::move(libraryDir)); + Unused << task->Dispatch(); + } else { + UniqueSECMODModule osClientCertsModule( + SECMOD_FindModule(kOSClientCertsModuleName)); + if (osClientCertsModule) { + SECMOD_UnloadUserModule(osClientCertsModule.get()); + } + } +} + +NS_IMETHODIMP +nsNSSComponent::HasActiveSmartCards(bool* result) { + NS_ENSURE_ARG_POINTER(result); + + BlockUntilLoadableCertsLoaded(); + +#ifndef MOZ_NO_SMART_CARDS + AutoSECMODListReadLock secmodLock; + SECMODModuleList* list = SECMOD_GetDefaultModuleList(); + while (list) { + SECMODModule* module = list->module; + if (SECMOD_HasRemovableSlots(module)) { + *result = true; + return NS_OK; + } + for (int i = 0; i < module->slotCount; i++) { + if (!PK11_IsFriendly(module->slots[i])) { + *result = true; + return NS_OK; + } + } + list = list->next; + } +#endif + *result = false; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSComponent::HasUserCertsInstalled(bool* result) { + NS_ENSURE_ARG_POINTER(result); + + BlockUntilLoadableCertsLoaded(); + + // FindClientCertificatesWithPrivateKeys won't ever return an empty list, so + // all we need to do is check if this is null or not. + UniqueCERTCertList certList(FindClientCertificatesWithPrivateKeys()); + *result = !!certList; + + return NS_OK; +} + +nsresult nsNSSComponent::BlockUntilLoadableCertsLoaded() { + MonitorAutoLock rootsLoadedLock(mLoadableCertsLoadedMonitor); + while (!mLoadableCertsLoaded) { + rootsLoadedLock.Wait(); + } + MOZ_ASSERT(mLoadableCertsLoaded); + + return mLoadableCertsLoadedResult; +} + +#ifndef MOZ_NO_SMART_CARDS +static StaticMutex sCheckForSmartCardChangesMutex; +static TimeStamp sLastCheckedForSmartCardChanges = TimeStamp::Now(); +#endif + +nsresult nsNSSComponent::CheckForSmartCardChanges() { +#ifndef MOZ_NO_SMART_CARDS + { + StaticMutexAutoLock lock(sCheckForSmartCardChangesMutex); + // Do this at most once every 3 seconds. + TimeStamp now = TimeStamp::Now(); + if (now - sLastCheckedForSmartCardChanges < + TimeDuration::FromSeconds(3.0)) { + return NS_OK; + } + sLastCheckedForSmartCardChanges = now; + } + + // SECMOD_UpdateSlotList attempts to acquire the list lock as well, + // so we have to do this in two steps. The lock protects the list itself, so + // if we get our own owned references to the modules we're interested in, + // there's no thread safety concern here. + Vector modulesWithRemovableSlots; + { + AutoSECMODListReadLock secmodLock; + SECMODModuleList* list = SECMOD_GetDefaultModuleList(); + while (list) { + if (SECMOD_HasRemovableSlots(list->module)) { + UniqueSECMODModule module(SECMOD_ReferenceModule(list->module)); + if (!modulesWithRemovableSlots.append(std::move(module))) { + return NS_ERROR_OUT_OF_MEMORY; + } + } + list = list->next; + } + } + for (auto& module : modulesWithRemovableSlots) { + // Best-effort. + Unused << SECMOD_UpdateSlotList(module.get()); + for (int i = 0; i < module->slotCount; i++) { + // We actually don't care about the return value here - we just need to + // call this to get NSS to update its view of this slot. + Unused << PK11_IsPresent(module->slots[i]); + } + } +#endif + + return NS_OK; +} + +// Returns by reference the path to the directory containing the file that has +// been loaded as MOZ_DLL_PREFIX nss3 MOZ_DLL_SUFFIX. +static nsresult GetNSS3Directory(nsCString& result) { + MOZ_ASSERT(NS_IsMainThread()); + + UniquePRString nss3Path( + PR_GetLibraryFilePathname(MOZ_DLL_PREFIX "nss3" MOZ_DLL_SUFFIX, + reinterpret_cast(NSS_Initialize))); + if (!nss3Path) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nss not loaded?")); + return NS_ERROR_FAILURE; + } + nsCOMPtr nss3File(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID)); + if (!nss3File) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't create a file?")); + return NS_ERROR_FAILURE; + } + nsAutoCString nss3PathAsString(nss3Path.get()); + nsresult rv = nss3File->InitWithNativePath(nss3PathAsString); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("couldn't initialize file with path '%s'", nss3Path.get())); + return rv; + } + nsCOMPtr nss3Directory; + rv = nss3File->GetParent(getter_AddRefs(nss3Directory)); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't get parent directory?")); + return rv; + } +#ifdef XP_WIN + // Native path will drop Unicode characters that cannot be mapped to system's + // codepage, using short (canonical) path as workaround. + nsCOMPtr nss3DirectoryWin = do_QueryInterface(nss3Directory); + if (!nss3DirectoryWin) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't get nsILocalFileWin")); + return NS_ERROR_FAILURE; + } + return nss3DirectoryWin->GetNativeCanonicalPath(result); +#else + return nss3Directory->GetNativePath(result); +#endif +} + +// The loadable roots library is probably in the same directory we loaded the +// NSS shared library from, but in some cases it may be elsewhere. This function +// enumerates and returns the possible locations as nsCStrings. +static nsresult ListPossibleLoadableRootsLocations( + Vector& possibleLoadableRootsLocations) { + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + // First try in the directory where we've already loaded + // MOZ_DLL_PREFIX nss3 MOZ_DLL_SUFFIX, since that's likely to be correct. + nsAutoCString nss3Dir; + nsresult rv = GetNSS3Directory(nss3Dir); + if (NS_SUCCEEDED(rv)) { + if (!possibleLoadableRootsLocations.append(std::move(nss3Dir))) { + return NS_ERROR_OUT_OF_MEMORY; + } + } else { + // For some reason this fails on android. In any case, we should try with + // the other potential locations we have. + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("could not determine where nss was loaded from")); + } + nsAutoCString currentProcessDir; + rv = GetDirectoryPath(NS_XPCOM_CURRENT_PROCESS_DIR, currentProcessDir); + if (NS_SUCCEEDED(rv)) { + if (!possibleLoadableRootsLocations.append(std::move(currentProcessDir))) { + return NS_ERROR_OUT_OF_MEMORY; + } + } else { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("could not get current process directory")); + } + nsAutoCString greDir; + rv = GetDirectoryPath(NS_GRE_DIR, greDir); + if (NS_SUCCEEDED(rv)) { + if (!possibleLoadableRootsLocations.append(std::move(greDir))) { + return NS_ERROR_OUT_OF_MEMORY; + } + } else { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("could not get gre directory")); + } + // As a last resort, this will cause the library loading code to use the OS' + // default library search path. + nsAutoCString emptyString; + if (!possibleLoadableRootsLocations.append(std::move(emptyString))) { + return NS_ERROR_OUT_OF_MEMORY; + } + + return NS_OK; +} + +nsresult LoadLoadableCertsTask::LoadLoadableRoots() { + for (const auto& possibleLocation : mPossibleLoadableRootsLocations) { + if (mozilla::psm::LoadLoadableRoots(possibleLocation)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("loaded CKBI from %s", possibleLocation.get())); + return NS_OK; + } + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("could not load loadable roots")); + return NS_ERROR_FAILURE; +} + +// Table of pref names and SSL cipher ID +typedef struct { + const char* pref; + long id; + bool enabledByDefault; +} CipherPref; + +// Update the switch statement in AccumulateCipherSuite in nsNSSCallbacks.cpp +// when you add/remove cipher suites here. +static const CipherPref sCipherPrefs[] = { + {"security.ssl3.ecdhe_rsa_aes_128_gcm_sha256", + TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, true}, + {"security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256", + TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, true}, + + {"security.ssl3.ecdhe_ecdsa_chacha20_poly1305_sha256", + TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, true}, + {"security.ssl3.ecdhe_rsa_chacha20_poly1305_sha256", + TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, true}, + + {"security.ssl3.ecdhe_ecdsa_aes_256_gcm_sha384", + TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, true}, + {"security.ssl3.ecdhe_rsa_aes_256_gcm_sha384", + TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, true}, + + {"security.ssl3.ecdhe_rsa_aes_128_sha", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + true}, + {"security.ssl3.ecdhe_ecdsa_aes_128_sha", + TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, true}, + + {"security.ssl3.ecdhe_rsa_aes_256_sha", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + true}, + {"security.ssl3.ecdhe_ecdsa_aes_256_sha", + TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, true}, + + {"security.ssl3.dhe_rsa_aes_128_sha", TLS_DHE_RSA_WITH_AES_128_CBC_SHA, + false}, + + {"security.ssl3.dhe_rsa_aes_256_sha", TLS_DHE_RSA_WITH_AES_256_CBC_SHA, + false}, + + {"security.tls13.aes_128_gcm_sha256", TLS_AES_128_GCM_SHA256, true}, + {"security.tls13.chacha20_poly1305_sha256", TLS_CHACHA20_POLY1305_SHA256, + true}, + {"security.tls13.aes_256_gcm_sha384", TLS_AES_256_GCM_SHA384, true}, + + {"security.ssl3.rsa_aes_128_gcm_sha256", TLS_RSA_WITH_AES_128_GCM_SHA256, + true}, // deprecated (RSA key exchange) + {"security.ssl3.rsa_aes_256_gcm_sha384", TLS_RSA_WITH_AES_256_GCM_SHA384, + true}, // deprecated (RSA key exchange) + {"security.ssl3.rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA, + true}, // deprecated (RSA key exchange) + {"security.ssl3.rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA, + true}, // deprecated (RSA key exchange) + {"security.ssl3.rsa_des_ede3_sha", TLS_RSA_WITH_3DES_EDE_CBC_SHA, + true}, // deprecated (RSA key exchange, 3DES) + + // All the rest are disabled + + {nullptr, 0} // end marker +}; + +// This function will convert from pref values like 1, 2, ... +// to the internal values of SSL_LIBRARY_VERSION_TLS_1_0, +// SSL_LIBRARY_VERSION_TLS_1_1, ... +/*static*/ +void nsNSSComponent::FillTLSVersionRange(SSLVersionRange& rangeOut, + uint32_t minFromPrefs, + uint32_t maxFromPrefs, + SSLVersionRange defaults) { + rangeOut = defaults; + // determine what versions are supported + SSLVersionRange supported; + if (SSL_VersionRangeGetSupported(ssl_variant_stream, &supported) != + SECSuccess) { + return; + } + + // Clip the defaults by what NSS actually supports to enable + // working with a system NSS with different ranges. + rangeOut.min = std::max(rangeOut.min, supported.min); + rangeOut.max = std::min(rangeOut.max, supported.max); + + // convert min/maxFromPrefs to the internal representation + minFromPrefs += SSL_LIBRARY_VERSION_3_0; + maxFromPrefs += SSL_LIBRARY_VERSION_3_0; + // if min/maxFromPrefs are invalid, use defaults + if (minFromPrefs > maxFromPrefs || minFromPrefs < supported.min || + maxFromPrefs > supported.max || + minFromPrefs < SSL_LIBRARY_VERSION_TLS_1_0) { + return; + } + + // fill out rangeOut + rangeOut.min = (uint16_t)minFromPrefs; + rangeOut.max = (uint16_t)maxFromPrefs; +} + +static const int32_t OCSP_ENABLED_DEFAULT = 1; +static const bool REQUIRE_SAFE_NEGOTIATION_DEFAULT = false; +static const bool FALSE_START_ENABLED_DEFAULT = true; +static const bool ALPN_ENABLED_DEFAULT = false; +static const bool ENABLED_0RTT_DATA_DEFAULT = false; +static const bool HELLO_DOWNGRADE_CHECK_DEFAULT = true; +static const bool ENABLED_POST_HANDSHAKE_AUTH_DEFAULT = false; +static const bool DELEGATED_CREDENTIALS_ENABLED_DEFAULT = false; + +static void ConfigureTLSSessionIdentifiers() { + bool disableSessionIdentifiers = + Preferences::GetBool("security.ssl.disable_session_identifiers", false); + SSL_OptionSetDefault(SSL_ENABLE_SESSION_TICKETS, !disableSessionIdentifiers); + SSL_OptionSetDefault(SSL_NO_CACHE, disableSessionIdentifiers); +} + +nsresult CommonInit() { + SSL_OptionSetDefault(SSL_ENABLE_SSL2, false); + SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, false); + + nsresult rv = nsNSSComponent::SetEnabledTLSVersions(); + if (NS_FAILED(rv)) { + return rv; + } + + ConfigureTLSSessionIdentifiers(); + + bool requireSafeNegotiation = + Preferences::GetBool("security.ssl.require_safe_negotiation", + REQUIRE_SAFE_NEGOTIATION_DEFAULT); + SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, requireSafeNegotiation); + + SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_REQUIRES_XTN); + + SSL_OptionSetDefault(SSL_ENABLE_EXTENDED_MASTER_SECRET, true); + + bool enableDowngradeCheck = Preferences::GetBool( + "security.tls.hello_downgrade_check", HELLO_DOWNGRADE_CHECK_DEFAULT); + SSL_OptionSetDefault(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, enableDowngradeCheck); + + SSL_OptionSetDefault(SSL_ENABLE_FALSE_START, + Preferences::GetBool("security.ssl.enable_false_start", + FALSE_START_ENABLED_DEFAULT)); + + // SSL_ENABLE_ALPN also requires calling SSL_SetNextProtoNego in order for + // the extensions to be negotiated. + // WebRTC does not do that so it will not use ALPN even when this preference + // is true. + SSL_OptionSetDefault( + SSL_ENABLE_ALPN, + Preferences::GetBool("security.ssl.enable_alpn", ALPN_ENABLED_DEFAULT)); + + SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA, + Preferences::GetBool("security.tls.enable_0rtt_data", + ENABLED_0RTT_DATA_DEFAULT)); + + SSL_OptionSetDefault( + SSL_ENABLE_POST_HANDSHAKE_AUTH, + Preferences::GetBool("security.tls.enable_post_handshake_auth", + ENABLED_POST_HANDSHAKE_AUTH_DEFAULT)); + + SSL_OptionSetDefault( + SSL_ENABLE_DELEGATED_CREDENTIALS, + Preferences::GetBool("security.tls.enable_delegated_credentials", + DELEGATED_CREDENTIALS_ENABLED_DEFAULT)); + + rv = InitializeCipherSuite(); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("Unable to initialize cipher suite settings\n")); + return rv; + } + + DisableMD5(); + + mozilla::pkix::RegisterErrorTable(); + + SharedSSLState::GlobalInit(); + RememberCertErrorsTable::Init(); + + SetValidationOptionsCommon(); + + return NS_OK; +} + +void NSSShutdownForSocketProcess() { + MOZ_ASSERT(XRE_IsSocketProcess()); + SharedSSLState::GlobalCleanup(); + RememberCertErrorsTable::Cleanup(); +} + +bool HandleTLSPrefChange(const nsCString& prefName) { + // Note that the code in this function should be kept in sync with + // gCallbackSecurityPrefs in nsIOService.cpp. + bool prefFound = true; + if (prefName.EqualsLiteral("security.tls.version.min") || + prefName.EqualsLiteral("security.tls.version.max") || + prefName.EqualsLiteral("security.tls.version.enable-deprecated")) { + (void)nsNSSComponent::SetEnabledTLSVersions(); + } else if (prefName.EqualsLiteral("security.tls.hello_downgrade_check")) { + bool enableDowngradeCheck = Preferences::GetBool( + "security.tls.hello_downgrade_check", HELLO_DOWNGRADE_CHECK_DEFAULT); + SSL_OptionSetDefault(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, + enableDowngradeCheck); + } else if (prefName.EqualsLiteral("security.ssl.require_safe_negotiation")) { + bool requireSafeNegotiation = + Preferences::GetBool("security.ssl.require_safe_negotiation", + REQUIRE_SAFE_NEGOTIATION_DEFAULT); + SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, requireSafeNegotiation); + } else if (prefName.EqualsLiteral("security.ssl.enable_false_start")) { + SSL_OptionSetDefault(SSL_ENABLE_FALSE_START, + Preferences::GetBool("security.ssl.enable_false_start", + FALSE_START_ENABLED_DEFAULT)); + } else if (prefName.EqualsLiteral("security.ssl.enable_alpn")) { + SSL_OptionSetDefault( + SSL_ENABLE_ALPN, + Preferences::GetBool("security.ssl.enable_alpn", ALPN_ENABLED_DEFAULT)); + } else if (prefName.EqualsLiteral("security.tls.enable_0rtt_data")) { + SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA, + Preferences::GetBool("security.tls.enable_0rtt_data", + ENABLED_0RTT_DATA_DEFAULT)); + } else if (prefName.EqualsLiteral( + "security.tls.enable_post_handshake_auth")) { + SSL_OptionSetDefault( + SSL_ENABLE_POST_HANDSHAKE_AUTH, + Preferences::GetBool("security.tls.enable_post_handshake_auth", + ENABLED_POST_HANDSHAKE_AUTH_DEFAULT)); + } else if (prefName.EqualsLiteral( + "security.tls.enable_delegated_credentials")) { + SSL_OptionSetDefault( + SSL_ENABLE_DELEGATED_CREDENTIALS, + Preferences::GetBool("security.tls.enable_delegated_credentials", + DELEGATED_CREDENTIALS_ENABLED_DEFAULT)); + } else if (prefName.EqualsLiteral( + "security.ssl.disable_session_identifiers")) { + ConfigureTLSSessionIdentifiers(); + } else { + prefFound = false; + } + return prefFound; +} + +void SetValidationOptionsCommon() { + // Note that the code in this function should be kept in sync with + // gCallbackSecurityPrefs in nsIOService.cpp. + bool ocspStaplingEnabled = + Preferences::GetBool("security.ssl.enable_ocsp_stapling", true); + PublicSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled); + PrivateSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled); + + bool ocspMustStapleEnabled = + Preferences::GetBool("security.ssl.enable_ocsp_must_staple", true); + PublicSSLState()->SetOCSPMustStapleEnabled(ocspMustStapleEnabled); + PrivateSSLState()->SetOCSPMustStapleEnabled(ocspMustStapleEnabled); + + const CertVerifier::CertificateTransparencyMode defaultCTMode = + CertVerifier::CertificateTransparencyMode::TelemetryOnly; + CertVerifier::CertificateTransparencyMode ctMode = + static_cast( + Preferences::GetInt("security.pki.certificate_transparency.mode", + static_cast(defaultCTMode))); + switch (ctMode) { + case CertVerifier::CertificateTransparencyMode::Disabled: + case CertVerifier::CertificateTransparencyMode::TelemetryOnly: + break; + default: + ctMode = defaultCTMode; + break; + } + bool sctsEnabled = + ctMode != CertVerifier::CertificateTransparencyMode::Disabled; + PublicSSLState()->SetSignedCertTimestampsEnabled(sctsEnabled); + PrivateSSLState()->SetSignedCertTimestampsEnabled(sctsEnabled); + + CertVerifier::PinningMode pinningMode = + static_cast( + Preferences::GetInt("security.cert_pinning.enforcement_level", + CertVerifier::pinningDisabled)); + if (pinningMode > CertVerifier::pinningEnforceTestMode) { + pinningMode = CertVerifier::pinningDisabled; + } + PublicSSLState()->SetPinningMode(pinningMode); + PrivateSSLState()->SetPinningMode(pinningMode); + + BRNameMatchingPolicy::Mode nameMatchingMode = + static_cast(Preferences::GetInt( + "security.pki.name_matching_mode", + static_cast(BRNameMatchingPolicy::Mode::DoNotEnforce))); + switch (nameMatchingMode) { + case BRNameMatchingPolicy::Mode::Enforce: + case BRNameMatchingPolicy::Mode::EnforceAfter23August2015: + case BRNameMatchingPolicy::Mode::EnforceAfter23August2016: + case BRNameMatchingPolicy::Mode::DoNotEnforce: + break; + default: + nameMatchingMode = BRNameMatchingPolicy::Mode::DoNotEnforce; + break; + } + PublicSSLState()->SetNameMatchingMode(nameMatchingMode); + PrivateSSLState()->SetNameMatchingMode(nameMatchingMode); +} + +namespace { + +class CipherSuiteChangeObserver : public nsIObserver { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIOBSERVER + + static nsresult StartObserve(); + + protected: + virtual ~CipherSuiteChangeObserver() = default; + + private: + static StaticRefPtr sObserver; + CipherSuiteChangeObserver() = default; +}; + +NS_IMPL_ISUPPORTS(CipherSuiteChangeObserver, nsIObserver) + +// static +StaticRefPtr CipherSuiteChangeObserver::sObserver; + +// static +nsresult CipherSuiteChangeObserver::StartObserve() { + MOZ_ASSERT(NS_IsMainThread(), + "CipherSuiteChangeObserver::StartObserve() can only be accessed " + "on the main thread"); + if (!sObserver) { + RefPtr observer = + new CipherSuiteChangeObserver(); + nsresult rv = Preferences::AddStrongObserver(observer.get(), "security."); + if (NS_FAILED(rv)) { + sObserver = nullptr; + return rv; + } + + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + observerService->AddObserver(observer, NS_XPCOM_SHUTDOWN_OBSERVER_ID, + false); + + sObserver = observer; + } + return NS_OK; +} + +nsresult CipherSuiteChangeObserver::Observe(nsISupports* /*aSubject*/, + const char* aTopic, + const char16_t* someData) { + MOZ_ASSERT(NS_IsMainThread(), + "CipherSuiteChangeObserver::Observe can only be accessed on main " + "thread"); + if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { + NS_ConvertUTF16toUTF8 prefName(someData); + // Look through the cipher table and set according to pref setting + const CipherPref* const cp = sCipherPrefs; + for (size_t i = 0; cp[i].pref; ++i) { + if (prefName.Equals(cp[i].pref)) { + bool cipherEnabled = + Preferences::GetBool(cp[i].pref, cp[i].enabledByDefault); + SSL_CipherPrefSetDefault(cp[i].id, cipherEnabled); + nsNSSComponent::DoClearSSLExternalAndInternalSessionCache(); + break; + } + } + } else if (nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { + Preferences::RemoveObserver(this, "security."); + MOZ_ASSERT(sObserver.get() == this); + sObserver = nullptr; + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID); + } + return NS_OK; +} + +} // namespace + +void nsNSSComponent::setValidationOptions( + bool isInitialSetting, const mozilla::MutexAutoLock& proofOfLock) { + // We access prefs so this must be done on the main thread. + MOZ_ASSERT(NS_IsMainThread()); + if (NS_WARN_IF(!NS_IsMainThread())) { + return; + } + + SetValidationOptionsCommon(); + + const CertVerifier::CertificateTransparencyMode defaultCTMode = + CertVerifier::CertificateTransparencyMode::TelemetryOnly; + CertVerifier::CertificateTransparencyMode ctMode = + static_cast( + Preferences::GetInt("security.pki.certificate_transparency.mode", + static_cast(defaultCTMode))); + switch (ctMode) { + case CertVerifier::CertificateTransparencyMode::Disabled: + case CertVerifier::CertificateTransparencyMode::TelemetryOnly: + break; + default: + ctMode = defaultCTMode; + break; + } + + // This preference controls whether we do OCSP fetching and does not affect + // OCSP stapling. + // 0 = disabled, 1 = enabled + int32_t ocspEnabled = + Preferences::GetInt("security.OCSP.enabled", OCSP_ENABLED_DEFAULT); + + bool ocspRequired = + ocspEnabled && Preferences::GetBool("security.OCSP.require", false); + + // We measure the setting of the pref at startup only to minimize noise by + // addons that may muck with the settings, though it probably doesn't matter. + if (isInitialSetting) { + Telemetry::Accumulate(Telemetry::CERT_OCSP_ENABLED, ocspEnabled); + Telemetry::Accumulate(Telemetry::CERT_OCSP_REQUIRED, ocspRequired); + } + + CertVerifier::SHA1Mode sha1Mode = + static_cast(Preferences::GetInt( + "security.pki.sha1_enforcement_level", + static_cast(CertVerifier::SHA1Mode::Allowed))); + switch (sha1Mode) { + case CertVerifier::SHA1Mode::Allowed: + case CertVerifier::SHA1Mode::Forbidden: + case CertVerifier::SHA1Mode::UsedToBeBefore2016ButNowIsForbidden: + case CertVerifier::SHA1Mode::ImportedRoot: + case CertVerifier::SHA1Mode::ImportedRootOrBefore2016: + break; + default: + sha1Mode = CertVerifier::SHA1Mode::Allowed; + break; + } + + // Convert a previously-available setting to a safe one. + if (sha1Mode == CertVerifier::SHA1Mode::UsedToBeBefore2016ButNowIsForbidden) { + sha1Mode = CertVerifier::SHA1Mode::Forbidden; + } + + NetscapeStepUpPolicy netscapeStepUpPolicy = + static_cast(Preferences::GetUint( + "security.pki.netscape_step_up_policy", + static_cast(NetscapeStepUpPolicy::AlwaysMatch))); + switch (netscapeStepUpPolicy) { + case NetscapeStepUpPolicy::AlwaysMatch: + case NetscapeStepUpPolicy::MatchBefore23August2016: + case NetscapeStepUpPolicy::MatchBefore23August2015: + case NetscapeStepUpPolicy::NeverMatch: + break; + default: + netscapeStepUpPolicy = NetscapeStepUpPolicy::AlwaysMatch; + break; + } + + CRLiteMode defaultCRLiteMode = CRLiteMode::Disabled; + CRLiteMode crliteMode = static_cast(Preferences::GetUint( + "security.pki.crlite_mode", static_cast(defaultCRLiteMode))); + switch (crliteMode) { + case CRLiteMode::Disabled: + case CRLiteMode::TelemetryOnly: + case CRLiteMode::Enforce: + break; + default: + crliteMode = defaultCRLiteMode; + break; + } + + uint32_t defaultCRLiteCTMergeDelaySeconds = + 60 * 60 * 28; // 28 hours in seconds + uint64_t maxCRLiteCTMergeDelaySeconds = 60 * 60 * 24 * 365; + uint64_t crliteCTMergeDelaySeconds = + Preferences::GetUint("security.pki.crlite_ct_merge_delay_seconds", + defaultCRLiteCTMergeDelaySeconds); + if (crliteCTMergeDelaySeconds > maxCRLiteCTMergeDelaySeconds) { + crliteCTMergeDelaySeconds = maxCRLiteCTMergeDelaySeconds; + } + + CertVerifier::OcspDownloadConfig odc; + CertVerifier::OcspStrictConfig osc; + uint32_t certShortLifetimeInDays; + TimeDuration softTimeout; + TimeDuration hardTimeout; + + GetRevocationBehaviorFromPrefs(&odc, &osc, &certShortLifetimeInDays, + softTimeout, hardTimeout, proofOfLock); + + mDefaultCertVerifier = new SharedCertVerifier( + odc, osc, softTimeout, hardTimeout, certShortLifetimeInDays, + PublicSSLState()->PinningMode(), sha1Mode, + PublicSSLState()->NameMatchingMode(), netscapeStepUpPolicy, ctMode, + crliteMode, crliteCTMergeDelaySeconds, mEnterpriseCerts); +} + +void nsNSSComponent::UpdateCertVerifierWithEnterpriseRoots() { + MutexAutoLock lock(mMutex); + MOZ_ASSERT(mDefaultCertVerifier); + if (NS_WARN_IF(!mDefaultCertVerifier)) { + return; + } + + RefPtr oldCertVerifier = mDefaultCertVerifier; + mDefaultCertVerifier = new SharedCertVerifier( + oldCertVerifier->mOCSPDownloadConfig, + oldCertVerifier->mOCSPStrict ? CertVerifier::ocspStrict + : CertVerifier::ocspRelaxed, + oldCertVerifier->mOCSPTimeoutSoft, oldCertVerifier->mOCSPTimeoutHard, + oldCertVerifier->mCertShortLifetimeInDays, oldCertVerifier->mPinningMode, + oldCertVerifier->mSHA1Mode, oldCertVerifier->mNameMatchingMode, + oldCertVerifier->mNetscapeStepUpPolicy, oldCertVerifier->mCTMode, + oldCertVerifier->mCRLiteMode, oldCertVerifier->mCRLiteCTMergeDelaySeconds, + mEnterpriseCerts); +} + +// Enable the TLS versions given in the prefs, defaulting to TLS 1.0 (min) and +// TLS 1.2 (max) when the prefs aren't set or set to invalid values. +nsresult nsNSSComponent::SetEnabledTLSVersions() { + // Keep these values in sync with all.js. + // 1 means TLS 1.0, 2 means TLS 1.1, etc. + static const uint32_t PSM_DEFAULT_MIN_TLS_VERSION = 3; + static const uint32_t PSM_DEFAULT_MAX_TLS_VERSION = 4; + static const uint32_t PSM_DEPRECATED_TLS_VERSION = 1; + + uint32_t minFromPrefs = Preferences::GetUint("security.tls.version.min", + PSM_DEFAULT_MIN_TLS_VERSION); + uint32_t maxFromPrefs = Preferences::GetUint("security.tls.version.max", + PSM_DEFAULT_MAX_TLS_VERSION); + + // This override should be removed some time after + // PSM_DEFAULT_MIN_TLS_VERSION is increased to 3. + bool enableDeprecated = + Preferences::GetBool("security.tls.version.enable-deprecated", false); + if (enableDeprecated) { + minFromPrefs = std::min(minFromPrefs, PSM_DEPRECATED_TLS_VERSION); + } + + SSLVersionRange defaults = { + SSL_LIBRARY_VERSION_3_0 + PSM_DEFAULT_MIN_TLS_VERSION, + SSL_LIBRARY_VERSION_3_0 + PSM_DEFAULT_MAX_TLS_VERSION}; + SSLVersionRange filledInRange; + FillTLSVersionRange(filledInRange, minFromPrefs, maxFromPrefs, defaults); + + SECStatus srv = + SSL_VersionRangeSetDefault(ssl_variant_stream, &filledInRange); + if (srv != SECSuccess) { + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +#if defined(XP_WIN) || (defined(XP_LINUX) && !defined(ANDROID)) +// If the profile directory is on a networked drive, we want to set the +// environment variable NSS_SDB_USE_CACHE to yes (as long as it hasn't been set +// before). +static void SetNSSDatabaseCacheModeAsAppropriate() { + MOZ_ASSERT(NS_IsMainThread()); + + nsCOMPtr profileFile; + nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, + getter_AddRefs(profileFile)); + if (NS_FAILED(rv)) { + // We're probably running without a profile directory, so this is + // irrelevant. + return; + } + + static const char sNSS_SDB_USE_CACHE[] = "NSS_SDB_USE_CACHE"; + static const char sNSS_SDB_USE_CACHE_WITH_VALUE[] = "NSS_SDB_USE_CACHE=yes"; + auto profilePath = profileFile->NativePath(); + +# if defined(XP_LINUX) && !defined(ANDROID) + struct statfs statfs_s; + if (statfs(profilePath.get(), &statfs_s) == 0 && + statfs_s.f_type == NFS_SUPER_MAGIC && !PR_GetEnv(sNSS_SDB_USE_CACHE)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("profile is remote (and NSS_SDB_USE_CACHE wasn't set): " + "setting NSS_SDB_USE_CACHE")); + PR_SetEnv(sNSS_SDB_USE_CACHE_WITH_VALUE); + } else { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("not setting NSS_SDB_USE_CACHE")); + } +# endif // defined(XP_LINUX) && !defined(ANDROID) + +# ifdef XP_WIN + wchar_t volPath[MAX_PATH]; + if (::GetVolumePathNameW(profilePath.get(), volPath, MAX_PATH) && + ::GetDriveTypeW(volPath) == DRIVE_REMOTE && + !PR_GetEnv(sNSS_SDB_USE_CACHE)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("profile is remote (and NSS_SDB_USE_CACHE wasn't set): " + "setting NSS_SDB_USE_CACHE")); + PR_SetEnv(sNSS_SDB_USE_CACHE_WITH_VALUE); + } else { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("not setting NSS_SDB_USE_CACHE")); + } +# endif // XP_WIN +} +#endif // defined(XP_WIN) || (defined(XP_LINUX) && !defined(ANDROID)) + +static nsresult GetNSSProfilePath(nsAutoCString& aProfilePath) { + aProfilePath.Truncate(); + nsCOMPtr profileFile; + nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, + getter_AddRefs(profileFile)); + if (NS_FAILED(rv)) { + NS_WARNING( + "NSS will be initialized without a profile directory. " + "Some things may not work as expected."); + return NS_OK; + } + +#if defined(XP_WIN) + // SQLite always takes UTF-8 file paths regardless of the current system + // code page. + nsCOMPtr profileFileWin(do_QueryInterface(profileFile)); + if (!profileFileWin) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("Could not get nsILocalFileWin for profile directory.\n")); + return NS_ERROR_FAILURE; + } + nsAutoString u16ProfilePath; + rv = profileFileWin->GetCanonicalPath(u16ProfilePath); + CopyUTF16toUTF8(u16ProfilePath, aProfilePath); +#else + rv = profileFile->GetNativePath(aProfilePath); +#endif + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("Could not get native path for profile directory.\n")); + return rv; + } + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("NSS profile at '%s'\n", aProfilePath.get())); + return NS_OK; +} + +#ifndef ANDROID +// Given a profile path, attempt to rename the PKCS#11 module DB to +// "pkcs11.txt.fips". In the case of a catastrophic failure (e.g. out of +// memory), returns a failing nsresult. If execution could conceivably proceed, +// returns NS_OK even if renaming the file didn't work. This simplifies the +// logic of the calling code. +// |profilePath| is encoded in UTF-8. +static nsresult AttemptToRenamePKCS11ModuleDB(const nsACString& profilePath) { + nsCOMPtr profileDir = do_CreateInstance("@mozilla.org/file/local;1"); + if (!profileDir) { + return NS_ERROR_FAILURE; + } +# ifdef XP_WIN + // |profilePath| is encoded in UTF-8 because SQLite always takes UTF-8 file + // paths regardless of the current system code page. + nsresult rv = profileDir->InitWithPath(NS_ConvertUTF8toUTF16(profilePath)); +# else + nsresult rv = profileDir->InitWithNativePath(profilePath); +# endif + if (NS_FAILED(rv)) { + return rv; + } + const char* moduleDBFilename = "pkcs11.txt"; + nsAutoCString destModuleDBFilename(moduleDBFilename); + destModuleDBFilename.Append(".fips"); + nsCOMPtr dbFile; + rv = profileDir->Clone(getter_AddRefs(dbFile)); + if (NS_FAILED(rv) || !dbFile) { + return NS_ERROR_FAILURE; + } + rv = dbFile->AppendNative(nsAutoCString(moduleDBFilename)); + if (NS_FAILED(rv)) { + return rv; + } + // If the PKCS#11 module DB doesn't exist, renaming it won't help. + bool exists; + rv = dbFile->Exists(&exists); + if (NS_FAILED(rv)) { + return rv; + } + // This is strange, but not a catastrophic failure. + if (!exists) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("%s doesn't exist?", moduleDBFilename)); + return NS_OK; + } + nsCOMPtr destDBFile; + rv = profileDir->Clone(getter_AddRefs(destDBFile)); + if (NS_FAILED(rv) || !destDBFile) { + return NS_ERROR_FAILURE; + } + rv = destDBFile->AppendNative(destModuleDBFilename); + if (NS_FAILED(rv)) { + return rv; + } + // If the destination exists, presumably we've already tried this. Doing it + // again won't help. + rv = destDBFile->Exists(&exists); + if (NS_FAILED(rv)) { + return rv; + } + // Unfortunate, but not a catastrophic failure. + if (exists) { + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("%s already exists - not overwriting", destModuleDBFilename.get())); + return NS_OK; + } + // Now do the actual move. + // This may fail on, e.g., a read-only file system. This would be unfortunate, + // but again it isn't catastropic and we would want to fall back to + // initializing NSS in no-DB mode. + Unused << dbFile->MoveToNative(profileDir, destModuleDBFilename); + return NS_OK; +} +#endif // ifndef ANDROID + +// Given a profile directory, attempt to initialize NSS. If nocertdb is true, +// (or if we don't have a profile directory) simply initialize NSS in no DB mode +// and return. Otherwise, first attempt to initialize in read/write mode, and +// then read-only mode if that fails. If both attempts fail, we may be failing +// to initialize an NSS DB collection that has FIPS mode enabled. Attempt to +// ascertain if this is the case, and if so, rename the offending PKCS#11 module +// DB so we can (hopefully) initialize NSS in read-write mode. Again attempt +// read-only mode if that fails. Finally, fall back to no DB mode. On Android +// we can skip the FIPS workaround since it was never possible to enable FIPS +// there anyway. +// |profilePath| is encoded in UTF-8. +static nsresult InitializeNSSWithFallbacks(const nsACString& profilePath, + bool nocertdb, bool safeMode) { + if (nocertdb || profilePath.IsEmpty()) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("nocertdb mode or empty profile path -> NSS_NoDB_Init")); + SECStatus srv = NSS_NoDB_Init(nullptr); +#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + if (srv != SECSuccess) { + MOZ_CRASH_UNSAFE_PRINTF("InitializeNSSWithFallbacks failed: %d", + PR_GetError()); + } +#endif + return srv == SECSuccess ? NS_OK : NS_ERROR_FAILURE; + } + + // Try read/write mode. If we're in safeMode, we won't load PKCS#11 modules. +#ifndef ANDROID + PRErrorCode savedPRErrorCode1; +#endif // ifndef ANDROID + PKCS11DBConfig safeModeDBConfig = + safeMode ? PKCS11DBConfig::DoNotLoadModules : PKCS11DBConfig::LoadModules; + SECStatus srv = ::mozilla::psm::InitializeNSS( + profilePath, NSSDBConfig::ReadWrite, safeModeDBConfig); + if (srv == SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized NSS in r/w mode")); + return NS_OK; + } +#ifndef ANDROID + savedPRErrorCode1 = PR_GetError(); + PRErrorCode savedPRErrorCode2; +#endif // ifndef ANDROID + // That failed. Try read-only mode. + srv = ::mozilla::psm::InitializeNSS(profilePath, NSSDBConfig::ReadOnly, + safeModeDBConfig); + if (srv == SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized NSS in r-o mode")); + return NS_OK; + } +#ifndef ANDROID + savedPRErrorCode2 = PR_GetError(); + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("failed to initialize NSS with codes %d %d", savedPRErrorCode1, + savedPRErrorCode2)); +#endif // ifndef ANDROID + +#ifndef ANDROID + // That failed as well. Maybe we're trying to load a PKCS#11 module DB that is + // in FIPS mode, but we don't support FIPS? Test load NSS without PKCS#11 + // modules. If that succeeds, that's probably what's going on. + if (!safeMode && (savedPRErrorCode1 == SEC_ERROR_LEGACY_DATABASE || + savedPRErrorCode2 == SEC_ERROR_LEGACY_DATABASE || + savedPRErrorCode1 == SEC_ERROR_PKCS11_DEVICE_ERROR || + savedPRErrorCode2 == SEC_ERROR_PKCS11_DEVICE_ERROR)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("attempting no-module db init")); + // It would make sense to initialize NSS in read-only mode here since this + // is just a test to see if the PKCS#11 module DB being in FIPS mode is the + // problem, but for some reason the combination of read-only and no-moddb + // flags causes NSS initialization to fail, so unfortunately we have to use + // read-write mode. + srv = ::mozilla::psm::InitializeNSS(profilePath, NSSDBConfig::ReadWrite, + PKCS11DBConfig::DoNotLoadModules); + if (srv == SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("FIPS may be the problem")); + // Unload NSS so we can attempt to fix this situation for the user. + srv = NSS_Shutdown(); + if (srv != SECSuccess) { +# ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + MOZ_CRASH_UNSAFE_PRINTF("InitializeNSSWithFallbacks failed: %d", + PR_GetError()); +# endif + return NS_ERROR_FAILURE; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("trying to rename module db")); + // If this fails non-catastrophically, we'll attempt to initialize NSS + // again in r/w then r-o mode (both of which will fail), and then we'll + // fall back to NSS_NoDB_Init, which is the behavior we want. + nsresult rv = AttemptToRenamePKCS11ModuleDB(profilePath); + if (NS_FAILED(rv)) { +# ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + // An nsresult is a uint32_t, but at least one of our compilers doesn't + // like this format string unless we include the cast. + MOZ_CRASH_UNSAFE_PRINTF("InitializeNSSWithFallbacks failed: %u", + (uint32_t)rv); +# endif + return rv; + } + srv = ::mozilla::psm::InitializeNSS(profilePath, NSSDBConfig::ReadWrite, + PKCS11DBConfig::LoadModules); + if (srv == SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized in r/w mode")); + return NS_OK; + } + srv = ::mozilla::psm::InitializeNSS(profilePath, NSSDBConfig::ReadOnly, + PKCS11DBConfig::LoadModules); + if (srv == SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized in r-o mode")); + return NS_OK; + } + } + } +#endif + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("last-resort NSS_NoDB_Init")); + srv = NSS_NoDB_Init(nullptr); +#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED + if (srv != SECSuccess) { + MOZ_CRASH_UNSAFE_PRINTF("InitializeNSSWithFallbacks failed: %d", + PR_GetError()); + } +#endif + return srv == SECSuccess ? NS_OK : NS_ERROR_FAILURE; +} + +nsresult nsNSSComponent::InitializeNSS() { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::InitializeNSS\n")); + AUTO_PROFILER_LABEL("nsNSSComponent::InitializeNSS", OTHER); + AUTO_PROFILER_TRACING_MARKER("NSS", "nsNSSComponent::InitializeNSS", OTHER); + + static_assert( + nsINSSErrorsService::NSS_SEC_ERROR_BASE == SEC_ERROR_BASE && + nsINSSErrorsService::NSS_SEC_ERROR_LIMIT == SEC_ERROR_LIMIT && + nsINSSErrorsService::NSS_SSL_ERROR_BASE == SSL_ERROR_BASE && + nsINSSErrorsService::NSS_SSL_ERROR_LIMIT == SSL_ERROR_LIMIT, + "You must update the values in nsINSSErrorsService.idl"); + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("NSS Initialization beginning\n")); + + nsAutoCString profileStr; + nsresult rv = GetNSSProfilePath(profileStr); + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); + if (NS_FAILED(rv)) { + return NS_ERROR_NOT_AVAILABLE; + } + +#if defined(XP_WIN) || (defined(XP_LINUX) && !defined(ANDROID)) + SetNSSDatabaseCacheModeAsAppropriate(); +#endif + + bool nocertdb = Preferences::GetBool("security.nocertdb", false); + bool inSafeMode = true; + nsCOMPtr runtime(do_GetService("@mozilla.org/xre/runtime;1")); + // There might not be an nsIXULRuntime in embedded situations. This will + // default to assuming we are in safe mode (as a result, no external PKCS11 + // modules will be loaded). + if (runtime) { + rv = runtime->GetInSafeMode(&inSafeMode); + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); + if (NS_FAILED(rv)) { + return rv; + } + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("inSafeMode: %u\n", inSafeMode)); + + rv = InitializeNSSWithFallbacks(profileStr, nocertdb, inSafeMode); + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("failed to initialize NSS")); + return rv; + } + + PK11_SetPasswordFunc(PK11PasswordPrompt); + + // Register an observer so we can inform NSS when these prefs change + Preferences::AddStrongObserver(this, "security."); + + rv = CommonInit(); + + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); + if (NS_FAILED(rv)) { + return NS_ERROR_UNEXPECTED; + } + + nsCOMPtr certOverrideService( + do_GetService(NS_CERTOVERRIDE_CONTRACTID)); + nsCOMPtr clientAuthRememberService( + do_GetService(NS_CLIENTAUTHREMEMBERSERVICE_CONTRACTID)); + nsCOMPtr siteSecurityService( + do_GetService(NS_SSSERVICE_CONTRACTID)); + nsCOMPtr certStorage(do_GetService(NS_CERT_STORAGE_CID)); + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("NSS Initialization done\n")); + + { + MutexAutoLock lock(mMutex); + + // ensure we have initial values for various root hashes +#ifdef DEBUG + mTestBuiltInRootHash.Truncate(); + Preferences::GetString("security.test.built_in_root_hash", + mTestBuiltInRootHash); +#endif + mContentSigningRootHash.Truncate(); + Preferences::GetCString("security.content.signature.root_hash", + mContentSigningRootHash); + + mMitmCanaryIssuer.Truncate(); + Preferences::GetString("security.pki.mitm_canary_issuer", + mMitmCanaryIssuer); + mMitmDetecionEnabled = + Preferences::GetBool("security.pki.mitm_canary_issuer.enabled", true); + + // Set dynamic options from prefs. + setValidationOptions(true, lock); + + bool importEnterpriseRoots = + Preferences::GetBool(kEnterpriseRootModePref, false); + uint32_t familySafetyMode = + Preferences::GetUint(kFamilySafetyModePref, kFamilySafetyModeDefault); + Vector possibleLoadableRootsLocations; + rv = ListPossibleLoadableRootsLocations(possibleLoadableRootsLocations); + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); + if (NS_FAILED(rv)) { + return rv; + } + + bool loadOSClientCertsModule = + Preferences::GetBool(kOSClientCertsModulePref, false); + Maybe maybeOSClientCertsModuleLocation; + if (loadOSClientCertsModule) { + nsAutoCString libraryDir; + if (NS_SUCCEEDED(GetDirectoryPath(NS_GRE_BIN_DIR, libraryDir))) { + maybeOSClientCertsModuleLocation.emplace(libraryDir); + } + } + RefPtr loadLoadableCertsTask( + new LoadLoadableCertsTask(this, importEnterpriseRoots, familySafetyMode, + std::move(possibleLoadableRootsLocations), + std::move(maybeOSClientCertsModuleLocation))); + rv = loadLoadableCertsTask->Dispatch(); + MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); + if (NS_FAILED(rv)) { + return rv; + } + + mLoadLoadableCertsTaskDispatched = true; + return NS_OK; + } +} + +void nsNSSComponent::ShutdownNSS() { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::ShutdownNSS\n")); + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + + bool loadLoadableCertsTaskDispatched; + { + MutexAutoLock lock(mMutex); + loadLoadableCertsTaskDispatched = mLoadLoadableCertsTaskDispatched; + } + // We have to block until the load loadable certs task has completed, because + // otherwise we might try to unload the loaded modules while the loadable + // certs loading thread is setting up EV information, which can cause + // it to fail to find the roots it is expecting. However, if initialization + // failed, we won't have dispatched the load loadable certs background task. + // In that case, we don't want to block on an event that will never happen. + if (loadLoadableCertsTaskDispatched) { + Unused << BlockUntilLoadableCertsLoaded(); + } + + ::mozilla::psm::UnloadUserModules(); + + PK11_SetPasswordFunc((PK11PasswordFunc) nullptr); + + Preferences::RemoveObserver(this, "security."); + + if (mIntermediatePreloadingHealerTimer) { + mIntermediatePreloadingHealerTimer->Cancel(); + mIntermediatePreloadingHealerTimer = nullptr; + } + + // Release the default CertVerifier. This will cause any held NSS resources + // to be released. + MutexAutoLock lock(mMutex); + mDefaultCertVerifier = nullptr; + // We don't actually shut down NSS - XPCOM does, after all threads have been + // joined and the component manager has been shut down (and so there shouldn't + // be any XPCOM objects holding NSS resources). +} + +// The aim of the intermediate preloading healer is to remove intermediates +// that were previously cached by PSM in the NSS certdb that are now preloaded +// in cert_storage. When cached by PSM, these certificates will have no +// particular trust set - they are intended to inherit their trust. If, upon +// examination, these certificates do have trust bits set that affect +// certificate validation, they must have been modified by the user, so we want +// to leave them alone. +bool CertHasDefaultTrust(CERTCertificate* cert) { + CERTCertTrust trust; + if (CERT_GetCertTrust(cert, &trust) != SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CERT_GetCertTrust failed")); + return false; + } + // This is the active distrust test for CA certificates (this is expected to + // be an intermediate). + if ((trust.sslFlags & (CERTDB_TRUSTED_CA | CERTDB_TERMINAL_RECORD)) == + CERTDB_TERMINAL_RECORD) { + return false; + } + // This is the trust anchor test. + if (trust.sslFlags & CERTDB_TRUSTED_CA) { + return false; + } + // This is the active distrust test for CA certificates (this is expected to + // be an intermediate). + if ((trust.emailFlags & (CERTDB_TRUSTED_CA | CERTDB_TERMINAL_RECORD)) == + CERTDB_TERMINAL_RECORD) { + return false; + } + // This is the trust anchor test. + if (trust.emailFlags & CERTDB_TRUSTED_CA) { + return false; + } + return true; +} + +void IntermediatePreloadingHealerCallback(nsITimer*, void*) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("IntermediatePreloadingHealerCallback")); + + if (AppShutdown::IsShuttingDown()) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("Exiting healer due to app shutdown")); + return; + } + + // Get the slot corresponding to the NSS certdb. + UniquePK11SlotInfo softokenSlot(PK11_GetInternalKeySlot()); + if (!softokenSlot) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("PK11_GetInternalKeySlot failed")); + return; + } + // List the certificates in the NSS certdb. + UniqueCERTCertList softokenCertificates( + PK11_ListCertsInSlot(softokenSlot.get())); + if (!softokenCertificates) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("PK11_ListCertsInSlot failed")); + return; + } + nsCOMPtr certStorage(do_GetService(NS_CERT_STORAGE_CID)); + if (!certStorage) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't get cert_storage")); + return; + } + Vector certsToDelete; + // For each certificate, look it up in cert_storage. If there's a match, this + // is a preloaded intermediate. + for (CERTCertListNode* n = CERT_LIST_HEAD(softokenCertificates); + !CERT_LIST_END(n, softokenCertificates); n = CERT_LIST_NEXT(n)) { + if (AppShutdown::IsShuttingDown()) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("Exiting healer due to app shutdown")); + return; + } + + nsTArray subject; + subject.AppendElements(n->cert->derSubject.data, n->cert->derSubject.len); + nsTArray> certs; + nsresult rv = certStorage->FindCertsBySubject(subject, certs); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("FindCertsBySubject failed")); + break; + } + for (const auto& encodedCert : certs) { + if (encodedCert.Length() != n->cert->derCert.len) { + continue; + } + if (memcmp(encodedCert.Elements(), n->cert->derCert.data, + encodedCert.Length()) != 0) { + continue; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("found preloaded intermediate in certdb")); + if (!CertHasDefaultTrust(n->cert)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("certificate doesn't have default trust - skipping")); + continue; + } + UniqueCERTCertificate certCopy(CERT_DupCertificate(n->cert)); + if (!certCopy) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CERT_DupCertificate failed")); + continue; + } + // Note that we want to remove this certificate from the NSS certdb + // because it also exists in preloaded intermediate storage and is thus + // superfluous. + if (!certsToDelete.append(std::move(certCopy))) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("append failed - out of memory?")); + return; + } + break; + } + // Only delete 20 at a time. + if (certsToDelete.length() >= 20) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("found limit of 20 preloaded intermediates in certdb")); + break; + } + } + for (const auto& certToDelete : certsToDelete) { + if (AppShutdown::IsShuttingDown()) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("Exiting healer due to app shutdown")); + return; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("attempting to delete preloaded intermediate '%s'", + certToDelete->subjectName)); + if (SEC_DeletePermCertificate(certToDelete.get()) != SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("SEC_DeletePermCertificate failed")); + } + } + + // This is for tests - notify that this ran. + nsCOMPtr runnable(NS_NewRunnableFunction( + "IntermediatePreloadingHealerCallbackDone", []() -> void { + nsCOMPtr observerService = + mozilla::services::GetObserverService(); + if (observerService) { + observerService->NotifyObservers( + nullptr, "psm:intermediate-preloading-healer-ran", nullptr); + } + })); + Unused << NS_DispatchToMainThread(runnable.forget()); +} + +nsresult nsNSSComponent::Init() { + MOZ_RELEASE_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + MOZ_ASSERT(XRE_IsParentProcess()); + if (!XRE_IsParentProcess()) { + return NS_ERROR_NOT_AVAILABLE; + } + + Telemetry::AutoScalarTimer + timer; + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Beginning NSS initialization\n")); + + nsresult rv = InitializeNSS(); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("nsNSSComponent::InitializeNSS() failed\n")); + return rv; + } + + rv = RegisterObservers(); + if (NS_FAILED(rv)) { + return rv; + } + + rv = MaybeEnableIntermediatePreloadingHealer(); + if (NS_FAILED(rv)) { + return rv; + } + + return NS_OK; +} + +nsresult nsNSSComponent::MaybeEnableIntermediatePreloadingHealer() { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("nsNSSComponent::MaybeEnableIntermediatePreloadingHealer")); + MOZ_ASSERT(NS_IsMainThread()); + if (!NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + if (mIntermediatePreloadingHealerTimer) { + mIntermediatePreloadingHealerTimer->Cancel(); + mIntermediatePreloadingHealerTimer = nullptr; + } + + if (!Preferences::GetBool("security.intermediate_preloading_healer.enabled", + false)) { + return NS_OK; + } + + if (!mIntermediatePreloadingHealerTaskQueue) { + nsresult rv = NS_CreateBackgroundTaskQueue( + "IntermediatePreloadingHealer", + getter_AddRefs(mIntermediatePreloadingHealerTaskQueue)); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("NS_CreateBackgroundTaskQueue failed")); + return rv; + } + } + uint32_t timerDelayMS = Preferences::GetUint( + "security.intermediate_preloading_healer.timer_interval_ms", + 5 * 60 * 1000); + nsresult rv = NS_NewTimerWithFuncCallback( + getter_AddRefs(mIntermediatePreloadingHealerTimer), + IntermediatePreloadingHealerCallback, nullptr, timerDelayMS, + nsITimer::TYPE_REPEATING_SLACK_LOW_PRIORITY, + "IntermediatePreloadingHealer", mIntermediatePreloadingHealerTaskQueue); + if (NS_FAILED(rv)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("NS_NewTimerWithFuncCallback failed")); + return rv; + } + return NS_OK; +} + +// nsISupports Implementation for the class +NS_IMPL_ISUPPORTS(nsNSSComponent, nsINSSComponent, nsIObserver) + +static const char* const PROFILE_BEFORE_CHANGE_TOPIC = "profile-before-change"; + +NS_IMETHODIMP +nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* someData) { + // In some tests, we don't receive a "profile-before-change" topic. However, + // we still have to shut down before the storage service shuts down, because + // closing the sql-backed softoken requires sqlite still be available. Thus, + // we observe "xpcom-shutdown" just in case. + if (nsCRT::strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC) == 0 || + nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("receiving profile change or XPCOM shutdown notification")); + ShutdownNSS(); + } else if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { + bool clearSessionCache = true; + NS_ConvertUTF16toUTF8 prefName(someData); + + if (HandleTLSPrefChange(prefName)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("HandleTLSPrefChange done")); + } else if (prefName.EqualsLiteral("security.OCSP.enabled") || + prefName.EqualsLiteral("security.OCSP.require") || + prefName.EqualsLiteral( + "security.pki.cert_short_lifetime_in_days") || + prefName.EqualsLiteral("security.ssl.enable_ocsp_stapling") || + prefName.EqualsLiteral("security.ssl.enable_ocsp_must_staple") || + prefName.EqualsLiteral( + "security.pki.certificate_transparency.mode") || + prefName.EqualsLiteral( + "security.cert_pinning.enforcement_level") || + prefName.EqualsLiteral("security.pki.sha1_enforcement_level") || + prefName.EqualsLiteral("security.pki.name_matching_mode") || + prefName.EqualsLiteral("security.pki.netscape_step_up_policy") || + prefName.EqualsLiteral( + "security.OCSP.timeoutMilliseconds.soft") || + prefName.EqualsLiteral( + "security.OCSP.timeoutMilliseconds.hard") || + prefName.EqualsLiteral("security.pki.crlite_mode") || + prefName.EqualsLiteral( + "security.pki.crlite_ct_merge_delay_seconds")) { + MutexAutoLock lock(mMutex); + setValidationOptions(false, lock); +#ifdef DEBUG + } else if (prefName.EqualsLiteral("security.test.built_in_root_hash")) { + MutexAutoLock lock(mMutex); + mTestBuiltInRootHash.Truncate(); + Preferences::GetString("security.test.built_in_root_hash", + mTestBuiltInRootHash); +#endif // DEBUG + } else if (prefName.EqualsLiteral("security.content.signature.root_hash")) { + MutexAutoLock lock(mMutex); + mContentSigningRootHash.Truncate(); + Preferences::GetCString("security.content.signature.root_hash", + mContentSigningRootHash); + } else if (prefName.Equals(kEnterpriseRootModePref) || + prefName.Equals(kFamilySafetyModePref)) { + UnloadEnterpriseRoots(); + MaybeImportEnterpriseRoots(); + } else if (prefName.Equals(kOSClientCertsModulePref)) { + bool loadOSClientCertsModule = + Preferences::GetBool(kOSClientCertsModulePref, false); + AsyncLoadOrUnloadOSClientCertsModule(loadOSClientCertsModule); + } else if (prefName.EqualsLiteral("security.pki.mitm_canary_issuer")) { + MutexAutoLock lock(mMutex); + mMitmCanaryIssuer.Truncate(); + Preferences::GetString("security.pki.mitm_canary_issuer", + mMitmCanaryIssuer); + } else if (prefName.EqualsLiteral( + "security.pki.mitm_canary_issuer.enabled")) { + MutexAutoLock lock(mMutex); + mMitmDetecionEnabled = + Preferences::GetBool("security.pki.mitm_canary_issuer.enabled", true); + } else { + clearSessionCache = false; + } + if (clearSessionCache) { + ClearSSLExternalAndInternalSessionCache(); + } + + // Preferences that don't affect certificate verification. + if (prefName.Equals("security.intermediate_preloading_healer.enabled") || + prefName.Equals( + "security.intermediate_preloading_healer.timer_interval_ms")) { + MaybeEnableIntermediatePreloadingHealer(); + } + } + + return NS_OK; +} + +/*static*/ +nsresult nsNSSComponent::GetNewPrompter(nsIPrompt** result) { + NS_ENSURE_ARG_POINTER(result); + *result = nullptr; + + if (!NS_IsMainThread()) { + NS_ERROR("nsSDRContext::GetNewPrompter called off the main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + + nsresult rv; + nsCOMPtr wwatch( + do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = wwatch->GetNewPrompter(0, result); + NS_ENSURE_SUCCESS(rv, rv); + + return rv; +} + +nsresult nsNSSComponent::LogoutAuthenticatedPK11() { + nsCOMPtr icos = + do_GetService("@mozilla.org/security/certoverride;1"); + if (icos) { + icos->ClearValidityOverride("all:temporary-certificates"_ns, 0); + } + + ClearSSLExternalAndInternalSessionCache(); + + nsCOMPtr os = mozilla::services::GetObserverService(); + if (os) { + os->NotifyObservers(nullptr, "net:cancel-all-connections", nullptr); + } + + return NS_OK; +} + +nsresult nsNSSComponent::RegisterObservers() { + nsCOMPtr observerService( + do_GetService("@mozilla.org/observer-service;1")); + if (!observerService) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("nsNSSComponent: couldn't get observer service\n")); + return NS_ERROR_FAILURE; + } + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent: adding observers\n")); + // Using false for the ownsweak parameter means the observer service will + // keep a strong reference to this component. As a result, this will live at + // least as long as the observer service. + observerService->AddObserver(this, PROFILE_BEFORE_CHANGE_TOPIC, false); + observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSComponent::IsCertTestBuiltInRoot(CERTCertificate* cert, bool* result) { + NS_ENSURE_ARG_POINTER(cert); + NS_ENSURE_ARG_POINTER(result); + *result = false; + +#ifdef DEBUG + RefPtr nsc = nsNSSCertificate::Create(cert); + if (!nsc) { + return NS_ERROR_FAILURE; + } + nsAutoString certHash; + nsresult rv = nsc->GetSha256Fingerprint(certHash); + if (NS_FAILED(rv)) { + return rv; + } + + MutexAutoLock lock(mMutex); + if (mTestBuiltInRootHash.IsEmpty()) { + return NS_OK; + } + + *result = mTestBuiltInRootHash.Equals(certHash); +#endif // DEBUG + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSComponent::IsCertContentSigningRoot(const nsTArray& cert, + bool* result) { + NS_ENSURE_ARG_POINTER(result); + *result = false; + if (cert.Length() > std::numeric_limits::max()) { + return NS_ERROR_INVALID_ARG; + } + nsTArray digestArray; + nsresult rv = Digest::DigestBuf(SEC_OID_SHA256, cert.Elements(), + cert.Length(), digestArray); + if (NS_FAILED(rv)) { + return rv; + } + SECItem digestItem = {siBuffer, digestArray.Elements(), + static_cast(digestArray.Length())}; + + UniquePORTString fingerprintCString( + CERT_Hexify(&digestItem, true /* use colon delimiters */)); + if (!fingerprintCString) { + return NS_ERROR_FAILURE; + } + + MutexAutoLock lock(mMutex); + *result = mContentSigningRootHash.Equals(fingerprintCString.get()); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSComponent::IssuerMatchesMitmCanary(const char* aCertIssuer) { + MutexAutoLock lock(mMutex); + if (mMitmDetecionEnabled && !mMitmCanaryIssuer.IsEmpty()) { + nsString certIssuer = NS_ConvertUTF8toUTF16(aCertIssuer); + if (mMitmCanaryIssuer.Equals(certIssuer)) { + return NS_OK; + } + } + + return NS_ERROR_FAILURE; +} + +SharedCertVerifier::~SharedCertVerifier() = default; + +NS_IMETHODIMP +nsNSSComponent::GetDefaultCertVerifier(SharedCertVerifier** result) { + MutexAutoLock lock(mMutex); + NS_ENSURE_ARG_POINTER(result); + RefPtr certVerifier(mDefaultCertVerifier); + certVerifier.forget(result); + return NS_OK; +} + +// static +void nsNSSComponent::DoClearSSLExternalAndInternalSessionCache() { + SSL_ClearSessionCache(); + mozilla::net::SSLTokensCache::Clear(); +} + +NS_IMETHODIMP +nsNSSComponent::ClearSSLExternalAndInternalSessionCache() { + MOZ_ASSERT(XRE_IsParentProcess()); + if (!XRE_IsParentProcess()) { + return NS_ERROR_NOT_AVAILABLE; + } + + if (mozilla::net::nsIOService::UseSocketProcess()) { + if (mozilla::net::gIOService) { + mozilla::net::gIOService->CallOrWaitForSocketProcess([]() { + Unused << mozilla::net::SocketProcessParent::GetSingleton() + ->SendClearSessionCache(); + }); + } + } + DoClearSSLExternalAndInternalSessionCache(); + return NS_OK; +} + +namespace mozilla { +namespace psm { + +already_AddRefed GetDefaultCertVerifier() { + static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); + + nsCOMPtr nssComponent(do_GetService(kNSSComponentCID)); + if (!nssComponent) { + return nullptr; + } + nsresult rv = nssComponent->BlockUntilLoadableCertsLoaded(); + if (NS_FAILED(rv)) { + return nullptr; + } + RefPtr result; + rv = nssComponent->GetDefaultCertVerifier(getter_AddRefs(result)); + if (NS_FAILED(rv)) { + return nullptr; + } + return result.forget(); +} + +// Lists all private keys on all modules and returns a list of any corresponding +// client certificates. Returns null if no such certificates can be found. Also +// returns null if an error is encountered, because this is called as part of +// the client auth data callback, and NSS ignores any errors returned by the +// callback. +UniqueCERTCertList FindClientCertificatesWithPrivateKeys() { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("FindClientCertificatesWithPrivateKeys")); + UniqueCERTCertList certsWithPrivateKeys(CERT_NewCertList()); + if (!certsWithPrivateKeys) { + return nullptr; + } + + AutoSECMODListReadLock secmodLock; + SECMODModuleList* list = SECMOD_GetDefaultModuleList(); + while (list) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + (" module '%s'", list->module->commonName)); + for (int i = 0; i < list->module->slotCount; i++) { + PK11SlotInfo* slot = list->module->slots[i]; + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + (" slot '%s'", PK11_GetSlotName(slot))); + if (!PK11_IsPresent(slot)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" (not present)")); + continue; + } + // We may need to log in to be able to find private keys. + if (PK11_Authenticate(slot, true, nullptr) != SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" (couldn't authenticate)")); + continue; + } + UniqueSECKEYPrivateKeyList privateKeys( + PK11_ListPrivKeysInSlot(slot, nullptr, nullptr)); + if (!privateKeys) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" (no private keys)")); + continue; + } + for (SECKEYPrivateKeyListNode* node = PRIVKEY_LIST_HEAD(privateKeys); + !PRIVKEY_LIST_END(node, privateKeys); + node = PRIVKEY_LIST_NEXT(node)) { + UniqueCERTCertList certs(PK11_GetCertsMatchingPrivateKey(node->key)); + if (!certs) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + (" PK11_GetCertsMatchingPrivateKey encountered an error " + "- returning")); + return nullptr; + } + if (CERT_LIST_EMPTY(certs)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" (no certs for key)")); + continue; + } + for (CERTCertListNode* n = CERT_LIST_HEAD(certs); + !CERT_LIST_END(n, certs); n = CERT_LIST_NEXT(n)) { + UniqueCERTCertificate cert(CERT_DupCertificate(n->cert)); + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + (" provisionally adding '%s'", n->cert->subjectName)); + if (CERT_AddCertToListTail(certsWithPrivateKeys.get(), cert.get()) == + SECSuccess) { + Unused << cert.release(); + } + } + } + } + list = list->next; + } + + if (CERT_FilterCertListByUsage(certsWithPrivateKeys.get(), certUsageSSLClient, + false) != SECSuccess) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + (" CERT_FilterCertListByUsage encountered an error - returning")); + return nullptr; + } + + if (MOZ_UNLIKELY(MOZ_LOG_TEST(gPIPNSSLog, LogLevel::Debug))) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" returning:")); + for (CERTCertListNode* n = CERT_LIST_HEAD(certsWithPrivateKeys); + !CERT_LIST_END(n, certsWithPrivateKeys); n = CERT_LIST_NEXT(n)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" %s", n->cert->subjectName)); + } + } + + if (CERT_LIST_EMPTY(certsWithPrivateKeys)) { + return nullptr; + } + + return certsWithPrivateKeys; +} + +} // namespace psm +} // namespace mozilla + +NS_IMPL_ISUPPORTS(PipUIContext, nsIInterfaceRequestor) + +PipUIContext::PipUIContext() = default; + +PipUIContext::~PipUIContext() = default; + +NS_IMETHODIMP +PipUIContext::GetInterface(const nsIID& uuid, void** result) { + NS_ENSURE_ARG_POINTER(result); + *result = nullptr; + + if (!NS_IsMainThread()) { + NS_ERROR("PipUIContext::GetInterface called off the main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + + if (!uuid.Equals(NS_GET_IID(nsIPrompt))) return NS_ERROR_NO_INTERFACE; + + nsIPrompt* prompt = nullptr; + nsresult rv = nsNSSComponent::GetNewPrompter(&prompt); + *result = prompt; + return rv; +} + +nsresult getNSSDialogs(void** _result, REFNSIID aIID, const char* contract) { + if (!NS_IsMainThread()) { + NS_ERROR("getNSSDialogs called off the main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + + nsresult rv; + + nsCOMPtr svc = do_GetService(contract, &rv); + if (NS_FAILED(rv)) { + return rv; + } + + rv = svc->QueryInterface(aIID, _result); + + return rv; +} + +nsresult setPassword(PK11SlotInfo* slot, nsIInterfaceRequestor* ctx) { + MOZ_ASSERT(slot); + MOZ_ASSERT(ctx); + NS_ENSURE_ARG_POINTER(slot); + NS_ENSURE_ARG_POINTER(ctx); + + if (PK11_NeedUserInit(slot)) { + nsCOMPtr dialogs; + nsresult rv = getNSSDialogs(getter_AddRefs(dialogs), + NS_GET_IID(nsITokenPasswordDialogs), + NS_TOKENPASSWORDSDIALOG_CONTRACTID); + if (NS_FAILED(rv)) { + return rv; + } + + bool canceled; + nsCOMPtr token = new nsPK11Token(slot); + rv = dialogs->SetPassword(ctx, token, &canceled); + if (NS_FAILED(rv)) { + return rv; + } + + if (canceled) { + return NS_ERROR_NOT_AVAILABLE; + } + } + + return NS_OK; +} + +// NSS will call this during PKCS12 export to potentially switch the endianness +// of the characters of `inBuf` to big (network) endian. Since we already did +// that in nsPKCS12Blob::stringToBigEndianBytes, we just perform a memcpy here. +extern "C" { +PRBool pkcs12StringEndiannessConversion(PRBool, unsigned char* inBuf, + unsigned int inBufLen, + unsigned char* outBuf, unsigned int, + unsigned int* outBufLen, PRBool) { + *outBufLen = inBufLen; + memcpy(outBuf, inBuf, inBufLen); + return true; +} +} + +namespace mozilla { +namespace psm { + +nsresult InitializeCipherSuite() { + MOZ_ASSERT(NS_IsMainThread(), + "InitializeCipherSuite() can only be accessed on the main thread"); + + if (NSS_SetDomesticPolicy() != SECSuccess) { + return NS_ERROR_FAILURE; + } + + // Disable any ciphers that NSS might have enabled by default + for (uint16_t i = 0; i < SSL_NumImplementedCiphers; ++i) { + uint16_t cipher_id = SSL_ImplementedCiphers[i]; + SSL_CipherPrefSetDefault(cipher_id, false); + } + + // Now only set SSL/TLS ciphers we knew about at compile time + const CipherPref* const cp = sCipherPrefs; + for (size_t i = 0; cp[i].pref; ++i) { + bool cipherEnabled = + Preferences::GetBool(cp[i].pref, cp[i].enabledByDefault); + SSL_CipherPrefSetDefault(cp[i].id, cipherEnabled); + } + + // Enable ciphers for PKCS#12 + SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1); + SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1); + SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1); + SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1); + SEC_PKCS12EnableCipher(PKCS12_DES_56, 1); + SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1); + SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1); + PORT_SetUCS2_ASCIIConversionFunction(pkcs12StringEndiannessConversion); + + // PSM enforces a minimum RSA key size of 1024 bits, which is overridable. + // NSS has its own minimum, which is not overridable (the default is 1023 + // bits). This sets the NSS minimum to 512 bits so users can still connect to + // devices like wifi routers with woefully small keys (they would have to add + // an override to do so, but they already do for such devices). + NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, 512); + + // Observe preference change around cipher suite setting. + return CipherSuiteChangeObserver::StartObserve(); +} + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/nsNSSComponent.h b/security/manager/ssl/nsNSSComponent.h new file mode 100644 index 0000000000..64afa6a312 --- /dev/null +++ b/security/manager/ssl/nsNSSComponent.h @@ -0,0 +1,176 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef _nsNSSComponent_h_ +#define _nsNSSComponent_h_ + +#include "nsINSSComponent.h" + +#include "EnterpriseRoots.h" +#include "ScopedNSSTypes.h" +#include "SharedCertVerifier.h" +#include "mozilla/Monitor.h" +#include "mozilla/Mutex.h" +#include "mozilla/RefPtr.h" +#include "nsCOMPtr.h" +#include "nsIObserver.h" +#include "nsNSSCallbacks.h" +#include "nsServiceManagerUtils.h" +#include "prerror.h" +#include "sslt.h" + +#ifdef XP_WIN +# include "windows.h" // this needs to be before the following includes +# include "wincrypt.h" +#endif // XP_WIN + +class nsIDOMWindow; +class nsIPrompt; +class nsISerialEventTarget; +class nsITimer; + +namespace mozilla { +namespace psm { + +[[nodiscard]] ::already_AddRefed +GetDefaultCertVerifier(); +UniqueCERTCertList FindClientCertificatesWithPrivateKeys(); + +} // namespace psm +} // namespace mozilla + +#define NS_NSSCOMPONENT_CID \ + { \ + 0x4cb64dfd, 0xca98, 0x4e24, { \ + 0xbe, 0xfd, 0x0d, 0x92, 0x85, 0xa3, 0x3b, 0xcb \ + } \ + } + +extern bool EnsureNSSInitializedChromeOrContent(); +extern bool HandleTLSPrefChange(const nsCString& aPref); +extern void SetValidationOptionsCommon(); +extern void NSSShutdownForSocketProcess(); + +// Implementation of the PSM component interface. +class nsNSSComponent final : public nsINSSComponent, public nsIObserver { + public: + // LoadLoadableCertsTask updates mLoadableCertsLoaded and + // mLoadableCertsLoadedResult and then signals mLoadableCertsLoadedMonitor. + friend class LoadLoadableCertsTask; + // BackgroundImportEnterpriseCertsTask calls ImportEnterpriseRoots and + // UpdateCertVerifierWithEnterpriseRoots. + friend class BackgroundImportEnterpriseCertsTask; + + nsNSSComponent(); + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSINSSCOMPONENT + NS_DECL_NSIOBSERVER + + nsresult Init(); + + static nsresult GetNewPrompter(nsIPrompt** result); + + static void FillTLSVersionRange(SSLVersionRange& rangeOut, + uint32_t minFromPrefs, uint32_t maxFromPrefs, + SSLVersionRange defaults); + + static nsresult SetEnabledTLSVersions(); + + // This function does the actual work of clearing the session cache. It is to + // be used by the socket process (where there is no nsINSSComponent) and + // internally by nsNSSComponent. + // NB: NSS must have already been initialized before this is called. + static void DoClearSSLExternalAndInternalSessionCache(); + + protected: + virtual ~nsNSSComponent(); + + private: + nsresult InitializeNSS(); + void ShutdownNSS(); + + void setValidationOptions(bool isInitialSetting, + const mozilla::MutexAutoLock& proofOfLock); + void GetRevocationBehaviorFromPrefs( + /*out*/ mozilla::psm::CertVerifier::OcspDownloadConfig* odc, + /*out*/ mozilla::psm::CertVerifier::OcspStrictConfig* osc, + /*out*/ uint32_t* certShortLifetimeInDays, + /*out*/ TimeDuration& softTimeout, + /*out*/ TimeDuration& hardTimeout, + const mozilla::MutexAutoLock& proofOfLock); + void UpdateCertVerifierWithEnterpriseRoots(); + nsresult RegisterObservers(); + + void MaybeImportEnterpriseRoots(); + void ImportEnterpriseRoots(); + void UnloadEnterpriseRoots(); + nsresult CommonGetEnterpriseCerts( + nsTArray>& enterpriseCerts, bool getRoots); + + bool ShouldEnableEnterpriseRootsForFamilySafety(uint32_t familySafetyMode); + + nsresult MaybeEnableIntermediatePreloadingHealer(); + + // mLoadableCertsLoadedMonitor protects mLoadableCertsLoaded. + mozilla::Monitor mLoadableCertsLoadedMonitor; + bool mLoadableCertsLoaded; + nsresult mLoadableCertsLoadedResult; + + // mMutex protects all members that are accessed from more than one thread. + mozilla::Mutex mMutex; + + // The following members are accessed from more than one thread: + +#ifdef DEBUG + nsString mTestBuiltInRootHash; +#endif + nsCString mContentSigningRootHash; + RefPtr mDefaultCertVerifier; + nsString mMitmCanaryIssuer; + bool mMitmDetecionEnabled; + mozilla::Vector mEnterpriseCerts; + + // The following members are accessed only on the main thread: + static int mInstanceCount; + // If InitializeNSS succeeds, then we have dispatched an event to load the + // loadable roots module, enterprise certificates (if enabled), and the os + // client certs module (if enabled) on a background thread. We must wait for + // it to complete before attempting to unload the modules again in + // ShutdownNSS. If we never dispatched the event, then we can't wait for it + // to complete (because it will never complete) so we use this boolean to keep + // track of if we should wait. + bool mLoadLoadableCertsTaskDispatched; + // If the intermediate preloading healer is enabled, the following timer + // periodically dispatches events to the background task queue. Each of these + // events scans the NSS certdb for preloaded intermediates that are in + // cert_storage and thus can be removed. By default, the interval is 5 + // minutes. + nsCOMPtr mIntermediatePreloadingHealerTaskQueue; + nsCOMPtr mIntermediatePreloadingHealerTimer; +}; + +inline nsresult BlockUntilLoadableCertsLoaded() { + nsCOMPtr component(do_GetService(PSM_COMPONENT_CONTRACTID)); + if (!component) { + return NS_ERROR_FAILURE; + } + return component->BlockUntilLoadableCertsLoaded(); +} + +inline nsresult CheckForSmartCardChanges() { +#ifndef MOZ_NO_SMART_CARDS + nsCOMPtr component(do_GetService(PSM_COMPONENT_CONTRACTID)); + if (!component) { + return NS_ERROR_FAILURE; + } + return component->CheckForSmartCardChanges(); +#else + return NS_OK; +#endif +} + +#endif // _nsNSSComponent_h_ diff --git a/security/manager/ssl/nsNSSHelper.h b/security/manager/ssl/nsNSSHelper.h new file mode 100644 index 0000000000..5f3f5ea9b4 --- /dev/null +++ b/security/manager/ssl/nsNSSHelper.h @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef nsNSSHelper_h +#define nsNSSHelper_h + +#include "nsIInterfaceRequestor.h" +#include "nsIInterfaceRequestorUtils.h" +#include "pk11func.h" + +// Implementation of an nsIInterfaceRequestor for use as context for NSS calls. +class PipUIContext : public nsIInterfaceRequestor { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIINTERFACEREQUESTOR + + PipUIContext(); + + protected: + virtual ~PipUIContext(); +}; + +// Function to get the implementor for a certain set of NSS specific dialogs. +nsresult getNSSDialogs(void** _result, REFNSIID aIID, const char* contract); + +// A function that sets the password on an unitialized slot. +nsresult setPassword(PK11SlotInfo* slot, nsIInterfaceRequestor* ctx); + +#endif // nsNSSHelper_h diff --git a/security/manager/ssl/nsNSSIOLayer.cpp b/security/manager/ssl/nsNSSIOLayer.cpp new file mode 100644 index 0000000000..b95506eabc --- /dev/null +++ b/security/manager/ssl/nsNSSIOLayer.cpp @@ -0,0 +1,2916 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsNSSIOLayer.h" + +#include +#include +#include + +#include "NSSCertDBTrustDomain.h" +#include "NSSErrorsService.h" +#include "PSMIPCCommon.h" +#include "PSMRunnable.h" +#include "SSLServerCertVerification.h" +#include "ScopedNSSTypes.h" +#include "SharedSSLState.h" +#include "cert_storage/src/cert_storage.h" +#include "keyhi.h" +#include "mozilla/Base64.h" +#include "mozilla/Casting.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/Logging.h" +#include "mozilla/Preferences.h" +#include "mozilla/Telemetry.h" +#include "mozilla/net/SSLTokensCache.h" +#include "mozilla/net/SocketProcessChild.h" +#include "mozpkix/pkixnss.h" +#include "mozpkix/pkixtypes.h" +#include "mozpkix/pkixutil.h" +#include "nsArray.h" +#include "nsArrayUtils.h" +#include "nsCRT.h" +#include "nsCharSeparatedTokenizer.h" +#include "nsClientAuthRemember.h" +#include "nsContentUtils.h" +#include "nsIClientAuthDialogs.h" +#include "nsISocketProvider.h" +#include "nsIWebProgressListener.h" +#include "nsNSSCertHelper.h" +#include "nsNSSComponent.h" +#include "nsNSSHelper.h" +#include "nsPrintfCString.h" +#include "nsServiceManagerUtils.h" +#include "prmem.h" +#include "prnetdb.h" +#include "secder.h" +#include "secerr.h" +#include "ssl.h" +#include "sslerr.h" +#include "sslexp.h" +#include "sslproto.h" + +using namespace mozilla::psm; + +//#define DEBUG_SSL_VERBOSE //Enable this define to get minimal +// reports when doing SSL read/write + +//#define DUMP_BUFFER //Enable this define along with +// DEBUG_SSL_VERBOSE to dump SSL +// read/write buffer to a log. +// Uses PR_LOG except on Mac where +// we always write out to our own +// file. + +namespace { + +// The NSSSocketInfo tls flags are meant to be opaque to most calling +// applications but provide a mechanism for direct TLS manipulation when +// experimenting with new features in the scope of a single socket. They do not +// create a persistent ABI. +// +// Use of these flags creates a new 'sharedSSLState' so existing states for +// intolerance are not carried to sockets that use these flags (and intolerance +// they discover does not impact other normal sockets not using the flags.) +// +// Their current definitions are: +// +// bits 0-2 (mask 0x07) specify the max tls version +// 0 means no override 1->4 are 1.0, 1.1, 1.2, 1.3, 4->7 unused +// bits 3-5 (mask 0x38) specify the tls fallback limit +// 0 means no override, values 1->4 match prefs +// bit 6 (mask 0x40) was used to specify compat mode. Temporarily reserved. + +enum { + kTLSProviderFlagMaxVersion10 = 0x01, + kTLSProviderFlagMaxVersion11 = 0x02, + kTLSProviderFlagMaxVersion12 = 0x03, + kTLSProviderFlagMaxVersion13 = 0x04, +}; + +static uint32_t getTLSProviderFlagMaxVersion(uint32_t flags) { + return (flags & 0x07); +} + +static uint32_t getTLSProviderFlagFallbackLimit(uint32_t flags) { + return (flags & 0x38) >> 3; +} + +#define MAX_ALPN_LENGTH 255 + +void getSiteKey(const nsACString& hostName, uint16_t port, + /*out*/ nsACString& key) { + key = hostName; + key.AppendLiteral(":"); + key.AppendInt(port); +} + +} // unnamed namespace + +extern LazyLogModule gPIPNSSLog; + +nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags, + uint32_t providerTlsFlags) + : CommonSocketControl(providerFlags), + mFd(nullptr), + mCertVerificationState(before_cert_verification), + mSharedState(aState), + mForSTARTTLS(false), + mHandshakePending(true), + mPreliminaryHandshakeDone(false), + mEarlyDataAccepted(false), + mDenyClientCert(false), + mFalseStartCallbackCalled(false), + mFalseStarted(false), + mIsFullHandshake(false), + mNotedTimeUntilReady(false), + mIsShortWritePending(false), + mShortWritePendingByte(0), + mShortWriteOriginalAmount(-1), + mKEAUsed(nsISSLSocketControl::KEY_EXCHANGE_UNKNOWN), + mKEAKeyBits(0), + mMACAlgorithmUsed(nsISSLSocketControl::SSL_MAC_UNKNOWN), + mProviderTlsFlags(providerTlsFlags), + mSocketCreationTimestamp(TimeStamp::Now()), + mPlaintextBytesRead(0), + mClientCert(nullptr) { + mTLSVersionRange.min = 0; + mTLSVersionRange.max = 0; +} + +nsNSSSocketInfo::~nsNSSSocketInfo() = default; + +NS_IMPL_ISUPPORTS_INHERITED(nsNSSSocketInfo, TransportSecurityInfo, + nsISSLSocketControl) + +NS_IMETHODIMP +nsNSSSocketInfo::GetProviderTlsFlags(uint32_t* aProviderTlsFlags) { + *aProviderTlsFlags = mProviderTlsFlags; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetKEAUsed(int16_t* aKea) { + *aKea = mKEAUsed; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetKEAKeyBits(uint32_t* aKeyBits) { + *aKeyBits = mKEAKeyBits; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetSSLVersionOffered(int16_t* aSSLVersionOffered) { + *aSSLVersionOffered = mTLSVersionRange.max; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetMACAlgorithmUsed(int16_t* aMac) { + *aMac = mMACAlgorithmUsed; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetClientCert(nsIX509Cert** aClientCert) { + NS_ENSURE_ARG_POINTER(aClientCert); + *aClientCert = mClientCert; + NS_IF_ADDREF(*aClientCert); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::SetClientCert(nsIX509Cert* aClientCert) { + mClientCert = aClientCert; + return NS_OK; +} + +void nsNSSSocketInfo::NoteTimeUntilReady() { + MutexAutoLock lock(mMutex); + if (mNotedTimeUntilReady) return; + + mNotedTimeUntilReady = true; + + // This will include TCP and proxy tunnel wait time + Telemetry::AccumulateTimeDelta(Telemetry::SSL_TIME_UNTIL_READY, + mSocketCreationTimestamp, TimeStamp::Now()); + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] nsNSSSocketInfo::NoteTimeUntilReady\n", mFd)); +} + +void nsNSSSocketInfo::SetHandshakeCompleted() { + if (!mHandshakeCompleted) { + enum HandshakeType { + Resumption = 1, + FalseStarted = 2, + ChoseNotToFalseStart = 3, + NotAllowedToFalseStart = 4, + }; + + HandshakeType handshakeType = !IsFullHandshake() ? Resumption + : mFalseStarted ? FalseStarted + : mFalseStartCallbackCalled + ? ChoseNotToFalseStart + : NotAllowedToFalseStart; + MutexAutoLock lock(mMutex); + // This will include TCP and proxy tunnel wait time + Telemetry::AccumulateTimeDelta( + Telemetry::SSL_TIME_UNTIL_HANDSHAKE_FINISHED_KEYED_BY_KA, mKeaGroup, + mSocketCreationTimestamp, TimeStamp::Now()); + + // If the handshake is completed for the first time from just 1 callback + // that means that TLS session resumption must have been used. + Telemetry::Accumulate(Telemetry::SSL_RESUMED_SESSION, + handshakeType == Resumption); + Telemetry::Accumulate(Telemetry::SSL_HANDSHAKE_TYPE, handshakeType); + } + + // Remove the plaintext layer as it is not needed anymore. + // The plaintext layer is not always present - so it's not a fatal error if it + // cannot be removed. + // Note that PR_PopIOLayer may modify its stack, so a pointer returned by + // PR_GetIdentitiesLayer may not point to what we think it points to after + // calling PR_PopIOLayer. We must operate on the pointer returned by + // PR_PopIOLayer. + if (PR_GetIdentitiesLayer(mFd, + nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity)) { + PRFileDesc* poppedPlaintext = + PR_PopIOLayer(mFd, nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity); + poppedPlaintext->dtor(poppedPlaintext); + } + + mHandshakeCompleted = true; + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] nsNSSSocketInfo::SetHandshakeCompleted\n", (void*)mFd)); + + mIsFullHandshake = false; // reset for next handshake on this connection +} + +void nsNSSSocketInfo::SetNegotiatedNPN(const char* value, uint32_t length) { + MutexAutoLock lock(mMutex); + if (!value) { + mNegotiatedNPN.Truncate(); + } else { + mNegotiatedNPN.Assign(value, length); + } + mNPNCompleted = true; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetAlpnEarlySelection(nsACString& aAlpnSelected) { + aAlpnSelected.Truncate(); + + SSLPreliminaryChannelInfo info; + SECStatus rv = SSL_GetPreliminaryChannelInfo(mFd, &info, sizeof(info)); + if (rv != SECSuccess || !info.canSendEarlyData) { + return NS_ERROR_NOT_AVAILABLE; + } + + SSLNextProtoState alpnState; + unsigned char chosenAlpn[MAX_ALPN_LENGTH]; + unsigned int chosenAlpnLen; + rv = SSL_GetNextProto(mFd, &alpnState, chosenAlpn, &chosenAlpnLen, + AssertedCast(ArrayLength(chosenAlpn))); + + if (rv != SECSuccess) { + return NS_ERROR_NOT_AVAILABLE; + } + + if (alpnState == SSL_NEXT_PROTO_EARLY_VALUE) { + aAlpnSelected.Assign(BitwiseCast(chosenAlpn), + chosenAlpnLen); + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetEarlyDataAccepted(bool* aAccepted) { + *aAccepted = mEarlyDataAccepted; + return NS_OK; +} + +void nsNSSSocketInfo::SetEarlyDataAccepted(bool aAccepted) { + mEarlyDataAccepted = aAccepted; +} + +bool nsNSSSocketInfo::GetDenyClientCert() { return mDenyClientCert; } + +void nsNSSSocketInfo::SetDenyClientCert(bool aDenyClientCert) { + mDenyClientCert = aDenyClientCert; +} + +NS_IMETHODIMP +nsNSSSocketInfo::DriveHandshake() { + if (!mFd) { + return NS_ERROR_FAILURE; + } + if (IsCanceled()) { + PRErrorCode errorCode = GetErrorCode(); + MOZ_DIAGNOSTIC_ASSERT(errorCode, "handshake cancelled without error code"); + return GetXPCOMFromNSSError(errorCode); + } + + SECStatus rv = SSL_ForceHandshake(mFd); + + if (rv != SECSuccess) { + PRErrorCode errorCode = PR_GetError(); + MOZ_DIAGNOSTIC_ASSERT(errorCode, "handshake failed without error code"); + if (errorCode == PR_WOULD_BLOCK_ERROR) { + return NS_BASE_STREAM_WOULD_BLOCK; + } + + SetCanceled(errorCode); + return GetXPCOMFromNSSError(errorCode); + } + return NS_OK; +} + +bool nsNSSSocketInfo::GetForSTARTTLS() { return mForSTARTTLS; } + +void nsNSSSocketInfo::SetForSTARTTLS(bool aForSTARTTLS) { + mForSTARTTLS = aForSTARTTLS; +} + +NS_IMETHODIMP +nsNSSSocketInfo::ProxyStartSSL() { return ActivateSSL(); } + +NS_IMETHODIMP +nsNSSSocketInfo::StartTLS() { return ActivateSSL(); } + +NS_IMETHODIMP +nsNSSSocketInfo::SetNPNList(nsTArray& protocolArray) { + if (!mFd) return NS_ERROR_FAILURE; + + // the npn list is a concatenated list of 8 bit byte strings. + nsCString npnList; + + for (uint32_t index = 0; index < protocolArray.Length(); ++index) { + if (protocolArray[index].IsEmpty() || protocolArray[index].Length() > 255) + return NS_ERROR_ILLEGAL_VALUE; + + npnList.Append(protocolArray[index].Length()); + npnList.Append(protocolArray[index]); + } + + if (SSL_SetNextProtoNego( + mFd, BitwiseCast(npnList.get()), + npnList.Length()) != SECSuccess) + return NS_ERROR_FAILURE; + + return NS_OK; +} + +nsresult nsNSSSocketInfo::ActivateSSL() { + if (SECSuccess != SSL_OptionSet(mFd, SSL_SECURITY, true)) + return NS_ERROR_FAILURE; + if (SECSuccess != SSL_ResetHandshake(mFd, false)) return NS_ERROR_FAILURE; + + mHandshakePending = true; + + return SetResumptionTokenFromExternalCache(); +} + +nsresult nsNSSSocketInfo::GetFileDescPtr(PRFileDesc** aFilePtr) { + *aFilePtr = mFd; + return NS_OK; +} + +nsresult nsNSSSocketInfo::SetFileDescPtr(PRFileDesc* aFilePtr) { + mFd = aFilePtr; + return NS_OK; +} + +void nsNSSSocketInfo::SetCertVerificationWaiting() { + // mCertVerificationState may be before_cert_verification for the first + // handshake on the connection, or after_cert_verification for subsequent + // renegotiation handshakes. + MOZ_ASSERT(mCertVerificationState != waiting_for_cert_verification, + "Invalid state transition to waiting_for_cert_verification"); + mCertVerificationState = waiting_for_cert_verification; +} + +// Be careful that SetCertVerificationResult does NOT get called while we are +// processing a SSL callback function, because SSL_AuthCertificateComplete will +// attempt to acquire locks that are already held by libssl when it calls +// callbacks. +void nsNSSSocketInfo::SetCertVerificationResult(PRErrorCode errorCode) { + MOZ_ASSERT(mCertVerificationState == waiting_for_cert_verification, + "Invalid state transition to cert_verification_finished"); + + if (mFd) { + SECStatus rv = SSL_AuthCertificateComplete(mFd, errorCode); + // Only replace errorCode if there was originally no error + if (rv != SECSuccess && errorCode == 0) { + errorCode = PR_GetError(); + if (errorCode == 0) { + NS_ERROR("SSL_AuthCertificateComplete didn't set error code"); + errorCode = PR_INVALID_STATE_ERROR; + } + } + } + + if (errorCode) { + mFailedVerification = true; + SetCanceled(errorCode); + } + + if (mPlaintextBytesRead && !errorCode) { + Telemetry::Accumulate(Telemetry::SSL_BYTES_BEFORE_CERT_CALLBACK, + AssertedCast(mPlaintextBytesRead)); + } + + mCertVerificationState = after_cert_verification; +} + +SharedSSLState& nsNSSSocketInfo::SharedState() { return mSharedState; } + +void nsNSSSocketInfo::SetSharedOwningReference(SharedSSLState* aRef) { + mOwningSharedRef = aRef; +} + +void nsSSLIOLayerHelpers::Cleanup() { + MutexAutoLock lock(mutex); + mTLSIntoleranceInfo.Clear(); + mInsecureFallbackSites.Clear(); +} + +namespace { + +enum Operation { reading, writing, not_reading_or_writing }; + +int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, + PRFileDesc* ssl_layer_fd, nsNSSSocketInfo* socketInfo); + +nsNSSSocketInfo* getSocketInfoIfRunning(PRFileDesc* fd, Operation op) { + if (!fd || !fd->lower || !fd->secret || + fd->identity != nsSSLIOLayerHelpers::nsSSLIOLayerIdentity) { + NS_ERROR("bad file descriptor passed to getSocketInfoIfRunning"); + PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0); + return nullptr; + } + + nsNSSSocketInfo* socketInfo = (nsNSSSocketInfo*)fd->secret; + + if (socketInfo->IsCanceled()) { + PRErrorCode err = socketInfo->GetErrorCode(); + PR_SetError(err, 0); + if (op == reading || op == writing) { + // We must do TLS intolerance checks for reads and writes, for timeouts + // in particular. + (void)checkHandshake(-1, op == reading, fd, socketInfo); + } + + // If we get here, it is probably because cert verification failed and this + // is the first I/O attempt since that failure. + return nullptr; + } + + return socketInfo; +} + +} // namespace + +static PRStatus nsSSLIOLayerConnect(PRFileDesc* fd, const PRNetAddr* addr, + PRIntervalTime timeout) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] connecting SSL socket\n", (void*)fd)); + if (!getSocketInfoIfRunning(fd, not_reading_or_writing)) return PR_FAILURE; + + PRStatus status = fd->lower->methods->connect(fd->lower, addr, timeout); + if (status != PR_SUCCESS) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("[%p] Lower layer connect error: %d\n", (void*)fd, PR_GetError())); + return status; + } + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("[%p] Connect\n", (void*)fd)); + return status; +} + +void nsSSLIOLayerHelpers::rememberTolerantAtVersion(const nsACString& hostName, + int16_t port, + uint16_t tolerant) { + nsCString key; + getSiteKey(hostName, port, key); + + MutexAutoLock lock(mutex); + + IntoleranceEntry entry; + if (mTLSIntoleranceInfo.Get(key, &entry)) { + entry.AssertInvariant(); + entry.tolerant = std::max(entry.tolerant, tolerant); + if (entry.intolerant != 0 && entry.intolerant <= entry.tolerant) { + entry.intolerant = entry.tolerant + 1; + entry.intoleranceReason = 0; // lose the reason + } + } else { + entry.tolerant = tolerant; + entry.intolerant = 0; + entry.intoleranceReason = 0; + } + + entry.AssertInvariant(); + + mTLSIntoleranceInfo.Put(key, entry); +} + +void nsSSLIOLayerHelpers::forgetIntolerance(const nsACString& hostName, + int16_t port) { + nsCString key; + getSiteKey(hostName, port, key); + + MutexAutoLock lock(mutex); + + IntoleranceEntry entry; + if (mTLSIntoleranceInfo.Get(key, &entry)) { + entry.AssertInvariant(); + + entry.intolerant = 0; + entry.intoleranceReason = 0; + + entry.AssertInvariant(); + mTLSIntoleranceInfo.Put(key, entry); + } +} + +bool nsSSLIOLayerHelpers::fallbackLimitReached(const nsACString& hostName, + uint16_t intolerant) { + if (isInsecureFallbackSite(hostName)) { + return intolerant <= SSL_LIBRARY_VERSION_TLS_1_0; + } + return intolerant <= mVersionFallbackLimit; +} + +// returns true if we should retry the handshake +bool nsSSLIOLayerHelpers::rememberIntolerantAtVersion( + const nsACString& hostName, int16_t port, uint16_t minVersion, + uint16_t intolerant, PRErrorCode intoleranceReason) { + if (intolerant <= minVersion || fallbackLimitReached(hostName, intolerant)) { + // We can't fall back any further. Assume that intolerance isn't the issue. + forgetIntolerance(hostName, port); + return false; + } + + nsCString key; + getSiteKey(hostName, port, key); + + MutexAutoLock lock(mutex); + + IntoleranceEntry entry; + if (mTLSIntoleranceInfo.Get(key, &entry)) { + entry.AssertInvariant(); + if (intolerant <= entry.tolerant) { + // We already know the server is tolerant at an equal or higher version. + return false; + } + if ((entry.intolerant != 0 && intolerant >= entry.intolerant)) { + // We already know that the server is intolerant at a lower version. + return true; + } + } else { + entry.tolerant = 0; + } + + entry.intolerant = intolerant; + entry.intoleranceReason = intoleranceReason; + entry.AssertInvariant(); + mTLSIntoleranceInfo.Put(key, entry); + + return true; +} + +void nsSSLIOLayerHelpers::adjustForTLSIntolerance( + const nsACString& hostName, int16_t port, + /*in/out*/ SSLVersionRange& range) { + IntoleranceEntry entry; + + { + nsCString key; + getSiteKey(hostName, port, key); + + MutexAutoLock lock(mutex); + if (!mTLSIntoleranceInfo.Get(key, &entry)) { + return; + } + } + + entry.AssertInvariant(); + + if (entry.intolerant != 0) { + // We've tried connecting at a higher range but failed, so try at the + // version we haven't tried yet, unless we have reached the minimum. + if (range.min < entry.intolerant) { + range.max = entry.intolerant - 1; + } + } +} + +PRErrorCode nsSSLIOLayerHelpers::getIntoleranceReason( + const nsACString& hostName, int16_t port) { + IntoleranceEntry entry; + + { + nsCString key; + getSiteKey(hostName, port, key); + + MutexAutoLock lock(mutex); + if (!mTLSIntoleranceInfo.Get(key, &entry)) { + return 0; + } + } + + entry.AssertInvariant(); + return entry.intoleranceReason; +} + +bool nsSSLIOLayerHelpers::nsSSLIOLayerInitialized = false; +PRDescIdentity nsSSLIOLayerHelpers::nsSSLIOLayerIdentity; +PRDescIdentity nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity; +PRIOMethods nsSSLIOLayerHelpers::nsSSLIOLayerMethods; +PRIOMethods nsSSLIOLayerHelpers::nsSSLPlaintextLayerMethods; + +static PRStatus nsSSLIOLayerClose(PRFileDesc* fd) { + if (!fd) return PR_FAILURE; + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] Shutting down socket\n", (void*)fd)); + + nsNSSSocketInfo* socketInfo = (nsNSSSocketInfo*)fd->secret; + MOZ_ASSERT(socketInfo, "nsNSSSocketInfo was null for an fd"); + + return socketInfo->CloseSocketAndDestroy(); +} + +PRStatus nsNSSSocketInfo::CloseSocketAndDestroy() { + PRFileDesc* popped = PR_PopIOLayer(mFd, PR_TOP_IO_LAYER); + MOZ_ASSERT( + popped && popped->identity == nsSSLIOLayerHelpers::nsSSLIOLayerIdentity, + "SSL Layer not on top of stack"); + + // The plaintext layer is not always present - so it's not a fatal error if it + // cannot be removed. + // Note that PR_PopIOLayer may modify its stack, so a pointer returned by + // PR_GetIdentitiesLayer may not point to what we think it points to after + // calling PR_PopIOLayer. We must operate on the pointer returned by + // PR_PopIOLayer. + if (PR_GetIdentitiesLayer(mFd, + nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity)) { + PRFileDesc* poppedPlaintext = + PR_PopIOLayer(mFd, nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity); + poppedPlaintext->dtor(poppedPlaintext); + } + + // We need to clear the callback to make sure the ssl layer cannot call the + // callback after mFD is nulled. + if (StaticPrefs::network_ssl_tokens_cache_enabled()) { + SSL_SetResumptionTokenCallback(mFd, nullptr, nullptr); + } + + PRStatus status = mFd->methods->close(mFd); + + // the nsNSSSocketInfo instance can out-live the connection, so we need some + // indication that the connection has been closed. mFd == nullptr is that + // indication. This is needed, for example, when the connection is closed + // before we have finished validating the server's certificate. + mFd = nullptr; + + if (status != PR_SUCCESS) return status; + + popped->identity = PR_INVALID_IO_LAYER; + NS_RELEASE_THIS(); + popped->dtor(popped); + + return PR_SUCCESS; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetEsniTxt(nsACString& aEsniTxt) { + aEsniTxt = mEsniTxt; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::SetEsniTxt(const nsACString& aEsniTxt) { + mEsniTxt = aEsniTxt; + + if (mEsniTxt.Length()) { + nsAutoCString esniBin; + if (NS_OK != Base64Decode(mEsniTxt, esniBin)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("[%p] Invalid ESNIKeys record. Couldn't base64 decode\n", + (void*)mFd)); + return NS_OK; + } + + if (SECSuccess != + SSL_EnableESNI(mFd, reinterpret_cast(esniBin.get()), + esniBin.Length(), nullptr)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("[%p] Invalid ESNIKeys record %s\n", (void*)mFd, + PR_ErrorToName(PR_GetError()))); + return NS_OK; + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetEchConfig(nsACString& aEchConfig) { + aEchConfig = mEchConfig; + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::SetEchConfig(const nsACString& aEchConfig) { + mEchConfig = aEchConfig; + + if (mEchConfig.Length()) { + if (SECSuccess != + SSL_SetClientEchConfigs( + mFd, reinterpret_cast(aEchConfig.BeginReading()), + aEchConfig.Length())) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("[%p] Invalid EchConfig record %s\n", (void*)mFd, + PR_ErrorToName(PR_GetError()))); + return NS_OK; + } + } + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetRetryEchConfig(nsACString& aEchConfig) { + if (!mFd) { + return NS_ERROR_FAILURE; + } + + ScopedAutoSECItem retryConfigItem; + SECStatus rv = SSL_GetEchRetryConfigs(mFd, &retryConfigItem); + if (rv != SECSuccess) { + return NS_ERROR_FAILURE; + } + aEchConfig = nsCString(reinterpret_cast(retryConfigItem.data), + retryConfigItem.len); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSSocketInfo::GetPeerId(nsACString& aResult) { + if (!mPeerId.IsEmpty()) { + aResult.Assign(mPeerId); + return NS_OK; + } + + if (mProviderFlags & + nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080 + mPeerId.AppendLiteral("anon:"); + } + if (mProviderFlags & nsISocketProvider::NO_PERMANENT_STORAGE) { + mPeerId.AppendLiteral("private:"); + } + if (mProviderFlags & nsISocketProvider::BE_CONSERVATIVE) { + mPeerId.AppendLiteral("beConservative:"); + } + + mPeerId.AppendPrintf("tlsflags0x%08x:", mProviderTlsFlags); + + mPeerId.Append(GetHostName()); + mPeerId.Append(':'); + mPeerId.AppendInt(GetPort()); + nsAutoCString suffix; + GetOriginAttributes().CreateSuffix(suffix); + mPeerId.Append(suffix); + + aResult.Assign(mPeerId); + return NS_OK; +} + +nsresult nsNSSSocketInfo::SetResumptionTokenFromExternalCache() { + if (!StaticPrefs::network_ssl_tokens_cache_enabled()) { + return NS_OK; + } + + if (!mFd) { + return NS_ERROR_FAILURE; + } + + // If SSL_NO_CACHE option was set, we must not use the cache + PRIntn val; + if (SSL_OptionGet(mFd, SSL_NO_CACHE, &val) != SECSuccess) { + return NS_ERROR_FAILURE; + } + + if (val != 0) { + return NS_OK; + } + + nsTArray token; + nsAutoCString peerId; + nsresult rv = GetPeerId(peerId); + if (NS_FAILED(rv)) { + return rv; + } + + rv = mozilla::net::SSLTokensCache::Get(peerId, token); + if (NS_FAILED(rv)) { + if (rv == NS_ERROR_NOT_AVAILABLE) { + // It's ok if we can't find the token. + return NS_OK; + } + + return rv; + } + + SECStatus srv = SSL_SetResumptionToken(mFd, token.Elements(), token.Length()); + if (srv == SECFailure) { + PRErrorCode error = PR_GetError(); + mozilla::net::SSLTokensCache::Remove(peerId); + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("Setting token failed with NSS error %d [id=%s]", error, + PromiseFlatCString(peerId).get())); + // We don't consider SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR as a hard error, + // since this error means this token is just expired or can't be decoded + // correctly. + if (error == SSL_ERROR_BAD_RESUMPTION_TOKEN_ERROR) { + return NS_OK; + } + + return NS_ERROR_FAILURE; + } + + return NS_OK; +} + +#if defined(DEBUG_SSL_VERBOSE) && defined(DUMP_BUFFER) +// Dumps a (potentially binary) buffer using SSM_DEBUG. (We could have used +// the version in ssltrace.c, but that's specifically tailored to SSLTRACE.) +# define DUMPBUF_LINESIZE 24 +static void nsDumpBuffer(unsigned char* buf, int len) { + char hexbuf[DUMPBUF_LINESIZE * 3 + 1]; + char chrbuf[DUMPBUF_LINESIZE + 1]; + static const char* hex = "0123456789abcdef"; + int i = 0; + int l = 0; + char ch; + char* c; + char* h; + if (len == 0) return; + hexbuf[DUMPBUF_LINESIZE * 3] = '\0'; + chrbuf[DUMPBUF_LINESIZE] = '\0'; + (void)memset(hexbuf, 0x20, DUMPBUF_LINESIZE * 3); + (void)memset(chrbuf, 0x20, DUMPBUF_LINESIZE); + h = hexbuf; + c = chrbuf; + + while (i < len) { + ch = buf[i]; + + if (l == DUMPBUF_LINESIZE) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("%s%s\n", hexbuf, chrbuf)); + (void)memset(hexbuf, 0x20, DUMPBUF_LINESIZE * 3); + (void)memset(chrbuf, 0x20, DUMPBUF_LINESIZE); + h = hexbuf; + c = chrbuf; + l = 0; + } + + // Convert a character to hex. + *h++ = hex[(ch >> 4) & 0xf]; + *h++ = hex[ch & 0xf]; + h++; + + // Put the character (if it's printable) into the character buffer. + if ((ch >= 0x20) && (ch <= 0x7e)) { + *c++ = ch; + } else { + *c++ = '.'; + } + i++; + l++; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("%s%s\n", hexbuf, chrbuf)); +} + +# define DEBUG_DUMP_BUFFER(buf, len) nsDumpBuffer(buf, len) +#else +# define DEBUG_DUMP_BUFFER(buf, len) +#endif + +namespace { + +uint32_t tlsIntoleranceTelemetryBucket(PRErrorCode err) { + // returns a numeric code for where we track various errors in telemetry + // only errors that cause version fallback are tracked, + // so this is also used to determine which errors can cause version fallback + switch (err) { + case SSL_ERROR_BAD_MAC_ALERT: + return 1; + case SSL_ERROR_BAD_MAC_READ: + return 2; + case SSL_ERROR_HANDSHAKE_FAILURE_ALERT: + return 3; + case SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT: + return 4; + case SSL_ERROR_ILLEGAL_PARAMETER_ALERT: + return 6; + case SSL_ERROR_NO_CYPHER_OVERLAP: + return 7; + case SSL_ERROR_UNSUPPORTED_VERSION: + return 10; + case SSL_ERROR_PROTOCOL_VERSION_ALERT: + return 11; + case SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE: + return 13; + case SSL_ERROR_DECODE_ERROR_ALERT: + return 14; + case PR_CONNECT_RESET_ERROR: + return 16; + case PR_END_OF_FILE_ERROR: + return 17; + case SSL_ERROR_INTERNAL_ERROR_ALERT: + return 18; + default: + return 0; + } +} + +bool retryDueToTLSIntolerance(PRErrorCode err, nsNSSSocketInfo* socketInfo) { + // This function is supposed to decide which error codes should + // be used to conclude server is TLS intolerant. + // Note this only happens during the initial SSL handshake. + + SSLVersionRange range = socketInfo->GetTLSVersionRange(); + nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers(); + + if (err == SSL_ERROR_UNSUPPORTED_VERSION && + range.min == SSL_LIBRARY_VERSION_TLS_1_0) { + socketInfo->SetSecurityState(nsIWebProgressListener::STATE_IS_INSECURE | + nsIWebProgressListener::STATE_USES_SSL_3); + } + + // NSS will return SSL_ERROR_RX_MALFORMED_SERVER_HELLO if anti-downgrade + // detected the downgrade. + if (err == SSL_ERROR_INAPPROPRIATE_FALLBACK_ALERT || + err == SSL_ERROR_RX_MALFORMED_SERVER_HELLO) { + // This is a clear signal that we've fallen back too many versions. Treat + // this as a hard failure, but forget any intolerance so that later attempts + // don't use this version (i.e., range.max) and trigger the error again. + + // First, track the original cause of the version fallback. This uses the + // same buckets as the telemetry below, except that bucket 0 will include + // all cases where there wasn't an original reason. + PRErrorCode originalReason = helpers.getIntoleranceReason( + socketInfo->GetHostName(), socketInfo->GetPort()); + Telemetry::Accumulate(Telemetry::SSL_VERSION_FALLBACK_INAPPROPRIATE, + tlsIntoleranceTelemetryBucket(originalReason)); + + helpers.forgetIntolerance(socketInfo->GetHostName(), socketInfo->GetPort()); + + return false; + } + + // When not using a proxy we'll see a connection reset error. + // When using a proxy, we'll see an end of file error. + + // Don't allow STARTTLS connections to fall back on connection resets or + // EOF. + if ((err == PR_CONNECT_RESET_ERROR || err == PR_END_OF_FILE_ERROR) && + socketInfo->GetForSTARTTLS()) { + return false; + } + + uint32_t reason = tlsIntoleranceTelemetryBucket(err); + if (reason == 0) { + return false; + } + + Telemetry::HistogramID pre; + Telemetry::HistogramID post; + switch (range.max) { + case SSL_LIBRARY_VERSION_TLS_1_3: + pre = Telemetry::SSL_TLS13_INTOLERANCE_REASON_PRE; + post = Telemetry::SSL_TLS13_INTOLERANCE_REASON_POST; + break; + case SSL_LIBRARY_VERSION_TLS_1_2: + pre = Telemetry::SSL_TLS12_INTOLERANCE_REASON_PRE; + post = Telemetry::SSL_TLS12_INTOLERANCE_REASON_POST; + break; + case SSL_LIBRARY_VERSION_TLS_1_1: + pre = Telemetry::SSL_TLS11_INTOLERANCE_REASON_PRE; + post = Telemetry::SSL_TLS11_INTOLERANCE_REASON_POST; + break; + case SSL_LIBRARY_VERSION_TLS_1_0: + pre = Telemetry::SSL_TLS10_INTOLERANCE_REASON_PRE; + post = Telemetry::SSL_TLS10_INTOLERANCE_REASON_POST; + break; + default: + MOZ_CRASH("impossible TLS version"); + return false; + } + + // The difference between _PRE and _POST represents how often we avoided + // TLS intolerance fallback due to remembered tolerance. + Telemetry::Accumulate(pre, reason); + + if (!helpers.rememberIntolerantAtVersion(socketInfo->GetHostName(), + socketInfo->GetPort(), range.min, + range.max, err)) { + return false; + } + + Telemetry::Accumulate(post, reason); + + return true; +} + +// Ensure that we haven't added too many errors to fit. +static_assert((SSL_ERROR_END_OF_LIST - SSL_ERROR_BASE) <= 256, + "too many SSL errors"); +static_assert((SEC_ERROR_END_OF_LIST - SEC_ERROR_BASE) <= 256, + "too many SEC errors"); +static_assert((PR_MAX_ERROR - PR_NSPR_ERROR_BASE) <= 128, + "too many NSPR errors"); +static_assert((mozilla::pkix::ERROR_BASE - mozilla::pkix::END_OF_LIST) < 31, + "too many moz::pkix errors"); + +static void reportHandshakeResult(int32_t bytesTransferred, bool wasReading, + PRErrorCode err) { + uint32_t bucket; + + // A negative bytesTransferred or a 0 read are errors. + if (bytesTransferred > 0) { + bucket = 0; + } else if ((bytesTransferred == 0) && !wasReading) { + // PR_Write() is defined to never return 0, but let's make sure. + // https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSPR/Reference/PR_Write. + MOZ_ASSERT(false); + bucket = 671; + } else if (IS_SSL_ERROR(err)) { + bucket = err - SSL_ERROR_BASE; + MOZ_ASSERT(bucket > 0); // SSL_ERROR_EXPORT_ONLY_SERVER isn't used. + } else if (IS_SEC_ERROR(err)) { + bucket = (err - SEC_ERROR_BASE) + 256; + } else if ((err >= PR_NSPR_ERROR_BASE) && (err < PR_MAX_ERROR)) { + bucket = (err - PR_NSPR_ERROR_BASE) + 512; + } else if ((err >= mozilla::pkix::ERROR_BASE) && + (err < mozilla::pkix::ERROR_LIMIT)) { + bucket = (err - mozilla::pkix::ERROR_BASE) + 640; + } else { + bucket = 671; + } + + Telemetry::Accumulate(Telemetry::SSL_HANDSHAKE_RESULT, bucket); +} + +int32_t checkHandshake(int32_t bytesTransfered, bool wasReading, + PRFileDesc* ssl_layer_fd, nsNSSSocketInfo* socketInfo) { + const PRErrorCode originalError = PR_GetError(); + PRErrorCode err = originalError; + + // This is where we work around all of those SSL servers that don't + // conform to the SSL spec and shutdown a connection when we request + // SSL v3.1 (aka TLS). The spec says the client says what version + // of the protocol we're willing to perform, in our case SSL v3.1 + // In its response, the server says which version it wants to perform. + // Many servers out there only know how to do v3.0. Next, we're supposed + // to send back the version of the protocol we requested (ie v3.1). At + // this point many servers's implementations are broken and they shut + // down the connection when they don't see the version they sent back. + // This is supposed to prevent a man in the middle from forcing one + // side to dumb down to a lower level of the protocol. Unfortunately, + // there are enough broken servers out there that such a gross work-around + // is necessary. :( + + // Do NOT assume TLS intolerance on a closed connection after bad cert ui was + // shown. Simply retry. This depends on the fact that Cert UI will not be + // shown again, should the user override the bad cert. + + bool handleHandshakeResultNow = socketInfo->IsHandshakePending(); + + bool wantRetry = false; + + if (0 > bytesTransfered) { + if (handleHandshakeResultNow) { + if (PR_WOULD_BLOCK_ERROR == err) { + PR_SetError(err, 0); + return bytesTransfered; + } + + wantRetry = retryDueToTLSIntolerance(err, socketInfo); + } + + // This is the common place where we trigger non-cert-errors on a SSL + // socket. This might be reached at any time of the connection. + // + // IsCanceled() is backed by an atomic boolean. It will only ever go from + // false to true, so we will never erroneously not call SetCanceled here. We + // could in theory overwrite a previously-set error code, but we'll always + // have some sort of error. + if (!wantRetry && mozilla::psm::IsNSSErrorCode(err) && + !socketInfo->IsCanceled()) { + socketInfo->SetCanceled(err); + } + } else if (wasReading && 0 == bytesTransfered) { + // zero bytes on reading, socket closed + if (handleHandshakeResultNow) { + wantRetry = retryDueToTLSIntolerance(PR_END_OF_FILE_ERROR, socketInfo); + } + } + + if (wantRetry) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] checkHandshake: will retry with lower max TLS version\n", + ssl_layer_fd)); + // We want to cause the network layer to retry the connection. + err = PR_CONNECT_RESET_ERROR; + if (wasReading) bytesTransfered = -1; + } + + // TLS intolerant servers only cause the first transfer to fail, so let's + // set the HandshakePending attribute to false so that we don't try the logic + // above again in a subsequent transfer. + if (handleHandshakeResultNow) { + // Report the result once for each handshake. Note that this does not + // get handshakes which are cancelled before any reads or writes + // happen. + reportHandshakeResult(bytesTransfered, wasReading, originalError); + socketInfo->SetHandshakeNotPending(); + } + + if (bytesTransfered < 0) { + // Remember that we encountered an error so that getSocketInfoIfRunning + // will correctly cause us to fail if another part of Gecko + // (erroneously) calls an I/O function (PR_Send/PR_Recv/etc.) again on + // this socket. Note that we use the original error because if we use + // PR_CONNECT_RESET_ERROR, we'll repeated try to reconnect. + if (originalError != PR_WOULD_BLOCK_ERROR && !socketInfo->IsCanceled()) { + socketInfo->SetCanceled(originalError); + } + PR_SetError(err, 0); + } + + return bytesTransfered; +} + +} // namespace + +static int16_t nsSSLIOLayerPoll(PRFileDesc* fd, int16_t in_flags, + int16_t* out_flags) { + if (!out_flags) { + NS_WARNING("nsSSLIOLayerPoll called with null out_flags"); + return 0; + } + + *out_flags = 0; + + nsNSSSocketInfo* socketInfo = + getSocketInfoIfRunning(fd, not_reading_or_writing); + + if (!socketInfo) { + // If we get here, it is probably because certificate validation failed + // and this is the first I/O operation after the failure. + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("[%p] polling SSL socket right after certificate verification failed " + "or NSS shutdown or SDR logout %d\n", + fd, (int)in_flags)); + + MOZ_ASSERT(in_flags & PR_POLL_EXCEPT, + "Caller did not poll for EXCEPT (canceled)"); + // Since this poll method cannot return errors, we want the caller to call + // PR_Send/PR_Recv right away to get the error, so we tell that we are + // ready for whatever I/O they are asking for. (See getSocketInfoIfRunning). + *out_flags = in_flags | PR_POLL_EXCEPT; // see also bug 480619 + return in_flags; + } + + MOZ_LOG(gPIPNSSLog, LogLevel::Verbose, + (socketInfo->IsWaitingForCertVerification() + ? "[%p] polling SSL socket during certificate verification " + "using lower %d\n" + : "[%p] poll SSL socket using lower %d\n", + fd, (int)in_flags)); + + // We want the handshake to continue during certificate validation, so we + // don't need to do anything special here. libssl automatically blocks when + // it reaches any point that would be unsafe to send/receive something before + // cert validation is complete. + int16_t result = fd->lower->methods->poll(fd->lower, in_flags, out_flags); + MOZ_LOG(gPIPNSSLog, LogLevel::Verbose, + ("[%p] poll SSL socket returned %d\n", (void*)fd, (int)result)); + return result; +} + +nsSSLIOLayerHelpers::nsSSLIOLayerHelpers(uint32_t aTlsFlags) + : mTreatUnsafeNegotiationAsBroken(false), + mTLSIntoleranceInfo(), + mVersionFallbackLimit(SSL_LIBRARY_VERSION_TLS_1_0), + mutex("nsSSLIOLayerHelpers.mutex"), + mTlsFlags(aTlsFlags) {} + +// PSMAvailable and PSMAvailable64 are reachable, but they're unimplemented in +// PSM, so we set an error and return -1. +static int32_t PSMAvailable(PRFileDesc*) { + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return -1; +} + +static int64_t PSMAvailable64(PRFileDesc*) { + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return -1; +} + +static PRStatus PSMGetsockname(PRFileDesc* fd, PRNetAddr* addr) { + if (!getSocketInfoIfRunning(fd, not_reading_or_writing)) return PR_FAILURE; + + return fd->lower->methods->getsockname(fd->lower, addr); +} + +static PRStatus PSMGetpeername(PRFileDesc* fd, PRNetAddr* addr) { + if (!getSocketInfoIfRunning(fd, not_reading_or_writing)) return PR_FAILURE; + + return fd->lower->methods->getpeername(fd->lower, addr); +} + +static PRStatus PSMGetsocketoption(PRFileDesc* fd, PRSocketOptionData* data) { + if (!getSocketInfoIfRunning(fd, not_reading_or_writing)) return PR_FAILURE; + + return fd->lower->methods->getsocketoption(fd, data); +} + +static PRStatus PSMSetsocketoption(PRFileDesc* fd, + const PRSocketOptionData* data) { + if (!getSocketInfoIfRunning(fd, not_reading_or_writing)) return PR_FAILURE; + + return fd->lower->methods->setsocketoption(fd, data); +} + +static int32_t PSMRecv(PRFileDesc* fd, void* buf, int32_t amount, int flags, + PRIntervalTime timeout) { + nsNSSSocketInfo* socketInfo = getSocketInfoIfRunning(fd, reading); + if (!socketInfo) return -1; + + if (flags != PR_MSG_PEEK && flags != 0) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + + int32_t bytesRead = + fd->lower->methods->recv(fd->lower, buf, amount, flags, timeout); + + MOZ_LOG(gPIPNSSLog, LogLevel::Verbose, + ("[%p] read %d bytes\n", (void*)fd, bytesRead)); + +#ifdef DEBUG_SSL_VERBOSE + DEBUG_DUMP_BUFFER((unsigned char*)buf, bytesRead); +#endif + + return checkHandshake(bytesRead, true, fd, socketInfo); +} + +static int32_t PSMSend(PRFileDesc* fd, const void* buf, int32_t amount, + int flags, PRIntervalTime timeout) { + nsNSSSocketInfo* socketInfo = getSocketInfoIfRunning(fd, writing); + if (!socketInfo) return -1; + + if (flags != 0) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return -1; + } + +#ifdef DEBUG_SSL_VERBOSE + DEBUG_DUMP_BUFFER((unsigned char*)buf, amount); +#endif + + if (socketInfo->IsShortWritePending() && amount > 0) { + // We got "SSL short write" last time, try to flush the pending byte. +#ifdef DEBUG + socketInfo->CheckShortWrittenBuffer(static_cast(buf), + amount); +#endif + + buf = socketInfo->GetShortWritePendingByteRef(); + amount = 1; + + MOZ_LOG(gPIPNSSLog, LogLevel::Verbose, + ("[%p] pushing 1 byte after SSL short write", fd)); + } + + int32_t bytesWritten = + fd->lower->methods->send(fd->lower, buf, amount, flags, timeout); + + // NSS indicates that it can't write all requested data (due to network + // congestion, for example) by returning either one less than the amount + // of data requested or 16383, if the requested amount is greater than + // 16384. We refer to this as a "short write". If we simply returned + // the amount that NSS did write, the layer above us would then call + // PSMSend with a very small amount of data (often 1). This is inefficient + // and can lead to alternating between sending large packets and very small + // packets. To prevent this, we alert the layer calling us that the operation + // would block and that it should be retried later, with the same data. + // When it does, we tell NSS to write the remaining byte it didn't write + // in the previous call. We then return the total number of bytes written, + // which is the number that caused the short write plus the additional byte + // we just wrote out. + + // The 16384 value is based on libssl's maximum buffer size: + // MAX_FRAGMENT_LENGTH - 1 + // + // It's in a private header, though, filed bug 1394822 to expose it. + static const int32_t kShortWrite16k = 16383; + + if ((amount > 1 && bytesWritten == (amount - 1)) || + (amount > kShortWrite16k && bytesWritten == kShortWrite16k)) { + // This is indication of an "SSL short write", block to force retry. + socketInfo->SetShortWritePending( + bytesWritten + 1, // The amount to return after the flush + *(static_cast(buf) + bytesWritten)); + + MOZ_LOG( + gPIPNSSLog, LogLevel::Verbose, + ("[%p] indicated SSL short write for %d bytes (written just %d bytes)", + fd, amount, bytesWritten)); + + bytesWritten = -1; + PR_SetError(PR_WOULD_BLOCK_ERROR, 0); + +#ifdef DEBUG + socketInfo->RememberShortWrittenBuffer( + static_cast(buf)); +#endif + + } else if (socketInfo->IsShortWritePending() && bytesWritten == 1) { + // We have now flushed all pending data in the SSL socket + // after the indicated short write. Tell the upper layer + // it has sent all its data now. + MOZ_LOG(gPIPNSSLog, LogLevel::Verbose, + ("[%p] finished SSL short write", fd)); + + bytesWritten = socketInfo->ResetShortWritePending(); + } + + MOZ_LOG(gPIPNSSLog, LogLevel::Verbose, + ("[%p] wrote %d bytes\n", fd, bytesWritten)); + + return checkHandshake(bytesWritten, false, fd, socketInfo); +} + +static PRStatus PSMBind(PRFileDesc* fd, const PRNetAddr* addr) { + if (!getSocketInfoIfRunning(fd, not_reading_or_writing)) return PR_FAILURE; + + return fd->lower->methods->bind(fd->lower, addr); +} + +static int32_t nsSSLIOLayerRead(PRFileDesc* fd, void* buf, int32_t amount) { + return PSMRecv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT); +} + +static int32_t nsSSLIOLayerWrite(PRFileDesc* fd, const void* buf, + int32_t amount) { + return PSMSend(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT); +} + +static PRStatus PSMConnectcontinue(PRFileDesc* fd, int16_t out_flags) { + if (!getSocketInfoIfRunning(fd, not_reading_or_writing)) { + return PR_FAILURE; + } + + return fd->lower->methods->connectcontinue(fd, out_flags); +} + +namespace { + +class PrefObserver : public nsIObserver { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOBSERVER + explicit PrefObserver(nsSSLIOLayerHelpers* aOwner) : mOwner(aOwner) {} + + protected: + virtual ~PrefObserver() = default; + + private: + nsSSLIOLayerHelpers* mOwner; +}; + +} // unnamed namespace + +NS_IMPL_ISUPPORTS(PrefObserver, nsIObserver) + +NS_IMETHODIMP +PrefObserver::Observe(nsISupports* aSubject, const char* aTopic, + const char16_t* someData) { + if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { + NS_ConvertUTF16toUTF8 prefName(someData); + + if (prefName.EqualsLiteral( + "security.ssl.treat_unsafe_negotiation_as_broken")) { + bool enabled; + Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", + &enabled); + mOwner->setTreatUnsafeNegotiationAsBroken(enabled); + } else if (prefName.EqualsLiteral("security.tls.version.fallback-limit")) { + mOwner->loadVersionFallbackLimit(); + } else if (prefName.EqualsLiteral("security.tls.insecure_fallback_hosts")) { + // Changes to the allowlist on the public side will update the pref. + // Don't propagate the changes to the private side. + if (mOwner->isPublic()) { + mOwner->initInsecureFallbackSites(); + } + } + } + return NS_OK; +} + +static int32_t PlaintextRecv(PRFileDesc* fd, void* buf, int32_t amount, + int flags, PRIntervalTime timeout) { + // The shutdownlocker is not needed here because it will already be + // held higher in the stack + nsNSSSocketInfo* socketInfo = nullptr; + + int32_t bytesRead = + fd->lower->methods->recv(fd->lower, buf, amount, flags, timeout); + if (fd->identity == nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity) + socketInfo = (nsNSSSocketInfo*)fd->secret; + + if ((bytesRead > 0) && socketInfo) + socketInfo->AddPlaintextBytesRead(bytesRead); + return bytesRead; +} + +nsSSLIOLayerHelpers::~nsSSLIOLayerHelpers() { + // mPrefObserver will only be set if this->Init was called. The GTest tests + // do not call Init. + if (mPrefObserver) { + Preferences::RemoveObserver( + mPrefObserver, "security.ssl.treat_unsafe_negotiation_as_broken"); + Preferences::RemoveObserver(mPrefObserver, + "security.tls.version.fallback-limit"); + Preferences::RemoveObserver(mPrefObserver, + "security.tls.insecure_fallback_hosts"); + } +} + +template +static R InvalidPRIOMethod(Args...) { + MOZ_ASSERT_UNREACHABLE("I/O method is invalid"); + PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); + return return_value; +} + +nsresult nsSSLIOLayerHelpers::Init() { + if (!nsSSLIOLayerInitialized) { + MOZ_ASSERT(NS_IsMainThread()); + nsSSLIOLayerInitialized = true; + nsSSLIOLayerIdentity = PR_GetUniqueIdentity("NSS layer"); + nsSSLIOLayerMethods = *PR_GetDefaultIOMethods(); + + nsSSLIOLayerMethods.fsync = + InvalidPRIOMethod; + nsSSLIOLayerMethods.seek = + InvalidPRIOMethod; + nsSSLIOLayerMethods.seek64 = + InvalidPRIOMethod; + nsSSLIOLayerMethods.fileInfo = + InvalidPRIOMethod; + nsSSLIOLayerMethods.fileInfo64 = + InvalidPRIOMethod; + nsSSLIOLayerMethods.writev = + InvalidPRIOMethod; + nsSSLIOLayerMethods.accept = + InvalidPRIOMethod; + nsSSLIOLayerMethods.listen = + InvalidPRIOMethod; + nsSSLIOLayerMethods.shutdown = + InvalidPRIOMethod; + nsSSLIOLayerMethods.recvfrom = + InvalidPRIOMethod; + nsSSLIOLayerMethods.sendto = + InvalidPRIOMethod; + nsSSLIOLayerMethods.acceptread = + InvalidPRIOMethod; + nsSSLIOLayerMethods.transmitfile = + InvalidPRIOMethod; + nsSSLIOLayerMethods.sendfile = + InvalidPRIOMethod; + + nsSSLIOLayerMethods.available = PSMAvailable; + nsSSLIOLayerMethods.available64 = PSMAvailable64; + nsSSLIOLayerMethods.getsockname = PSMGetsockname; + nsSSLIOLayerMethods.getpeername = PSMGetpeername; + nsSSLIOLayerMethods.getsocketoption = PSMGetsocketoption; + nsSSLIOLayerMethods.setsocketoption = PSMSetsocketoption; + nsSSLIOLayerMethods.recv = PSMRecv; + nsSSLIOLayerMethods.send = PSMSend; + nsSSLIOLayerMethods.connectcontinue = PSMConnectcontinue; + nsSSLIOLayerMethods.bind = PSMBind; + + nsSSLIOLayerMethods.connect = nsSSLIOLayerConnect; + nsSSLIOLayerMethods.close = nsSSLIOLayerClose; + nsSSLIOLayerMethods.write = nsSSLIOLayerWrite; + nsSSLIOLayerMethods.read = nsSSLIOLayerRead; + nsSSLIOLayerMethods.poll = nsSSLIOLayerPoll; + + nsSSLPlaintextLayerIdentity = PR_GetUniqueIdentity("Plaintxext PSM layer"); + nsSSLPlaintextLayerMethods = *PR_GetDefaultIOMethods(); + nsSSLPlaintextLayerMethods.recv = PlaintextRecv; + } + + loadVersionFallbackLimit(); + + // non main thread helpers will need to use defaults + if (NS_IsMainThread()) { + bool enabled = false; + Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", + &enabled); + setTreatUnsafeNegotiationAsBroken(enabled); + + initInsecureFallbackSites(); + + mPrefObserver = new PrefObserver(this); + Preferences::AddStrongObserver( + mPrefObserver, "security.ssl.treat_unsafe_negotiation_as_broken"); + Preferences::AddStrongObserver(mPrefObserver, + "security.tls.version.fallback-limit"); + Preferences::AddStrongObserver(mPrefObserver, + "security.tls.insecure_fallback_hosts"); + } else { + MOZ_ASSERT(mTlsFlags, "Only per socket version can ignore prefs"); + } + + return NS_OK; +} + +void nsSSLIOLayerHelpers::loadVersionFallbackLimit() { + // see nsNSSComponent::SetEnabledTLSVersions for pref handling rules + uint32_t limit = 3; // TLS 1.2 + + if (NS_IsMainThread()) { + limit = Preferences::GetUint("security.tls.version.fallback-limit", + 3); // 3 = TLS 1.2 + } + + // set fallback limit if it is set in the tls flags + uint32_t tlsFlagsFallbackLimit = getTLSProviderFlagFallbackLimit(mTlsFlags); + + if (tlsFlagsFallbackLimit) { + limit = tlsFlagsFallbackLimit; + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("loadVersionFallbackLimit overriden by tlsFlags %d\n", limit)); + } + + SSLVersionRange defaults = {SSL_LIBRARY_VERSION_TLS_1_2, + SSL_LIBRARY_VERSION_TLS_1_2}; + SSLVersionRange filledInRange; + nsNSSComponent::FillTLSVersionRange(filledInRange, limit, limit, defaults); + if (filledInRange.max < SSL_LIBRARY_VERSION_TLS_1_2) { + filledInRange.max = SSL_LIBRARY_VERSION_TLS_1_2; + } + + mVersionFallbackLimit = filledInRange.max; +} + +void nsSSLIOLayerHelpers::clearStoredData() { + MOZ_ASSERT(NS_IsMainThread()); + initInsecureFallbackSites(); + + MutexAutoLock lock(mutex); + mTLSIntoleranceInfo.Clear(); +} + +void nsSSLIOLayerHelpers::setInsecureFallbackSites(const nsCString& str) { + MutexAutoLock lock(mutex); + + mInsecureFallbackSites.Clear(); + + for (const nsACString& host : nsCCharSeparatedTokenizer(str, ',').ToRange()) { + if (!host.IsEmpty()) { + mInsecureFallbackSites.PutEntry(host); + } + } +} + +void nsSSLIOLayerHelpers::initInsecureFallbackSites() { + MOZ_ASSERT(NS_IsMainThread()); + nsAutoCString insecureFallbackHosts; + Preferences::GetCString("security.tls.insecure_fallback_hosts", + insecureFallbackHosts); + setInsecureFallbackSites(insecureFallbackHosts); +} + +bool nsSSLIOLayerHelpers::isPublic() const { + return this == &PublicSSLState()->IOLayerHelpers(); +} + +class FallbackPrefRemover final : public Runnable { + public: + explicit FallbackPrefRemover(const nsACString& aHost) + : mozilla::Runnable("FallbackPrefRemover"), mHost(aHost) {} + NS_IMETHOD Run() override; + + private: + nsCString mHost; +}; + +NS_IMETHODIMP +FallbackPrefRemover::Run() { + MOZ_ASSERT(NS_IsMainThread()); + nsAutoCString oldValue; + Preferences::GetCString("security.tls.insecure_fallback_hosts", oldValue); + nsCString newValue; + for (const nsACString& host : + nsCCharSeparatedTokenizer(oldValue, ',').ToRange()) { + if (host.Equals(mHost)) { + continue; + } + if (!newValue.IsEmpty()) { + newValue.Append(','); + } + newValue.Append(host); + } + Preferences::SetCString("security.tls.insecure_fallback_hosts", newValue); + return NS_OK; +} + +void nsSSLIOLayerHelpers::removeInsecureFallbackSite(const nsACString& hostname, + uint16_t port) { + forgetIntolerance(hostname, port); + { + MutexAutoLock lock(mutex); + if (!mInsecureFallbackSites.Contains(hostname)) { + return; + } + mInsecureFallbackSites.RemoveEntry(hostname); + } + if (!isPublic()) { + return; + } + RefPtr runnable = new FallbackPrefRemover(hostname); + if (NS_IsMainThread()) { + runnable->Run(); + } else { + NS_DispatchToMainThread(runnable); + } +} + +bool nsSSLIOLayerHelpers::isInsecureFallbackSite(const nsACString& hostname) { + MutexAutoLock lock(mutex); + return mInsecureFallbackSites.Contains(hostname); +} + +void nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(bool broken) { + MutexAutoLock lock(mutex); + mTreatUnsafeNegotiationAsBroken = broken; +} + +bool nsSSLIOLayerHelpers::treatUnsafeNegotiationAsBroken() { + MutexAutoLock lock(mutex); + return mTreatUnsafeNegotiationAsBroken; +} + +nsresult nsSSLIOLayerNewSocket(int32_t family, const char* host, int32_t port, + nsIProxyInfo* proxy, + const OriginAttributes& originAttributes, + PRFileDesc** fd, nsISupports** info, + bool forSTARTTLS, uint32_t flags, + uint32_t tlsFlags) { + PRFileDesc* sock = PR_OpenTCPSocket(family); + if (!sock) return NS_ERROR_OUT_OF_MEMORY; + + nsresult rv = + nsSSLIOLayerAddToSocket(family, host, port, proxy, originAttributes, sock, + info, forSTARTTLS, flags, tlsFlags); + if (NS_FAILED(rv)) { + PR_Close(sock); + return rv; + } + + *fd = sock; + return NS_OK; +} + +// Possible behaviors for choosing a cert for client auth. +enum class UserCertChoice { + // Ask the user to choose a cert. + Ask = 0, + // Automatically choose a cert. + Auto = 1, +}; + +// Returns the most appropriate user cert choice based on the value of the +// security.default_personal_cert preference. +UserCertChoice nsGetUserCertChoice() { + nsAutoCString value; + nsresult rv = + Preferences::GetCString("security.default_personal_cert", value); + if (NS_FAILED(rv)) { + return UserCertChoice::Ask; + } + + // There are three cases for what the preference could be set to: + // 1. "Select Automatically" -> Auto. + // 2. "Ask Every Time" -> Ask. + // 3. Something else -> Ask. This might be a nickname from a migrated cert, + // but we no longer support this case. + return value.EqualsLiteral("Select Automatically") ? UserCertChoice::Auto + : UserCertChoice::Ask; +} + +static bool hasExplicitKeyUsageNonRepudiation(CERTCertificate* cert) { + // There is no extension, v1 or v2 certificate + if (!cert->extensions) return false; + + SECStatus srv; + SECItem keyUsageItem; + keyUsageItem.data = nullptr; + + srv = CERT_FindKeyUsageExtension(cert, &keyUsageItem); + if (srv == SECFailure) return false; + + unsigned char keyUsage = keyUsageItem.data[0]; + PORT_Free(keyUsageItem.data); + + return !!(keyUsage & KU_NON_REPUDIATION); +} + +ClientAuthInfo::ClientAuthInfo(const nsACString& hostName, + const OriginAttributes& originAttributes, + int32_t port, uint32_t providerFlags, + uint32_t providerTlsFlags, + nsIX509Cert* clientCert) + : mHostName(hostName), + mOriginAttributes(originAttributes), + mPort(port), + mProviderFlags(providerFlags), + mProviderTlsFlags(providerTlsFlags), + mClientCert(clientCert) {} + +ClientAuthInfo::ClientAuthInfo(ClientAuthInfo&& aOther) noexcept + : mHostName(std::move(aOther.mHostName)), + mOriginAttributes(std::move(aOther.mOriginAttributes)), + mPort(aOther.mPort), + mProviderFlags(aOther.mProviderFlags), + mProviderTlsFlags(aOther.mProviderTlsFlags), + mClientCert(std::move(aOther.mClientCert)) {} + +const nsACString& ClientAuthInfo::HostName() const { return mHostName; } + +const OriginAttributes& ClientAuthInfo::OriginAttributesRef() const { + return mOriginAttributes; +} + +int32_t ClientAuthInfo::Port() const { return mPort; } + +uint32_t ClientAuthInfo::ProviderFlags() const { return mProviderFlags; } + +uint32_t ClientAuthInfo::ProviderTlsFlags() const { return mProviderTlsFlags; } + +already_AddRefed ClientAuthInfo::GetClientCert() const { + nsCOMPtr cert = mClientCert; + return cert.forget(); +} + +class ClientAuthDataRunnable : public SyncRunnableBase { + public: + ClientAuthDataRunnable(ClientAuthInfo&& info, + const UniqueCERTCertificate& serverCert, + nsTArray>&& collectedCANames) + : mInfo(std::move(info)), + mServerCert(serverCert.get()), + mCollectedCANames(std::move(collectedCANames)), + mSelectedCertificate(nullptr), + mSelectedKey(nullptr) {} + + virtual mozilla::pkix::Result BuildChainForCertificate( + CERTCertificate* cert, UniqueCERTCertList& builtChain); + + // Take the selected certificate. Will be null if none was selected or if an + // error prevented selecting one. + UniqueCERTCertificate TakeSelectedCertificate() { + return std::move(mSelectedCertificate); + } + // Take the private key for the selected certificate. Will be null if no + // certificate was selected or an error prevented selecting one or getting + // the corresponding key. + UniqueSECKEYPrivateKey TakeSelectedKey() { return std::move(mSelectedKey); } + + protected: + virtual void RunOnTargetThread() override; + + ClientAuthInfo mInfo; + CERTCertificate* const mServerCert; + nsTArray> mCollectedCANames; + nsTArray> mEnterpriseCertificates; + UniqueCERTCertificate mSelectedCertificate; + UniqueSECKEYPrivateKey mSelectedKey; +}; + +class RemoteClientAuthDataRunnable : public ClientAuthDataRunnable { + public: + RemoteClientAuthDataRunnable(ClientAuthInfo&& info, + const UniqueCERTCertificate& serverCert, + nsTArray>&& collectedCANames) + : ClientAuthDataRunnable(std::move(info), serverCert, + std::move(collectedCANames)) {} + + virtual mozilla::pkix::Result BuildChainForCertificate( + CERTCertificate* cert, UniqueCERTCertList& builtChain) override; + + protected: + virtual void RunOnTargetThread() override; + + CopyableTArray mBuiltChain; +}; + +nsTArray> CollectCANames(CERTDistNames* caNames) { + MOZ_ASSERT(caNames); + + nsTArray> collectedCANames; + if (!caNames) { + return collectedCANames; + } + + for (int i = 0; i < caNames->nnames; i++) { + nsTArray caName; + caName.AppendElements(caNames->names[i].data, caNames->names[i].len); + collectedCANames.AppendElement(std::move(caName)); + } + return collectedCANames; +} + +// This callback function is used to pull client certificate +// information upon server request +// +// - arg: SSL data connection +// - socket: SSL socket we're dealing with +// - caNames: list of CA names to use as a hint for selecting potential client +// certificates (may be empty) +// - pRetCert: returns a pointer to a pointer to a valid certificate if +// successful; otherwise nullptr +// - pRetKey: returns a pointer to a pointer to the corresponding key if +// successful; otherwise nullptr +SECStatus nsNSS_SSLGetClientAuthData(void* arg, PRFileDesc* socket, + CERTDistNames* caNames, + CERTCertificate** pRetCert, + SECKEYPrivateKey** pRetKey) { + if (!socket || !caNames || !pRetCert || !pRetKey) { + PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0); + return SECFailure; + } + + *pRetCert = nullptr; + *pRetKey = nullptr; + + Telemetry::ScalarAdd(Telemetry::ScalarID::SECURITY_CLIENT_CERT, + u"requested"_ns, 1); + + RefPtr info( + BitwiseCast(socket->higher->secret)); + + UniqueCERTCertificate serverCert(SSL_PeerCertificate(socket)); + if (!serverCert) { + MOZ_ASSERT_UNREACHABLE( + "Missing server cert should have been detected during server cert " + "auth."); + PR_SetError(SSL_ERROR_NO_CERTIFICATE, 0); + return SECFailure; + } + + if (info->GetDenyClientCert()) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] Not returning client cert due to denyClientCert attribute\n", + socket)); + return SECSuccess; + } + + if (info->GetJoined()) { + // We refuse to send a client certificate when there are multiple hostnames + // joined on this connection, because we only show the user one hostname + // (mHostName) in the client certificate UI. + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] Not returning client cert due to previous join\n", socket)); + return SECSuccess; + } + + nsCOMPtr socketClientCert; + info->GetClientCert(getter_AddRefs(socketClientCert)); + ClientAuthInfo authInfo(info->GetHostName(), info->GetOriginAttributes(), + info->GetPort(), info->GetProviderFlags(), + info->GetProviderTlsFlags(), socketClientCert); + nsTArray> collectedCANames(CollectCANames(caNames)); + + UniqueCERTCertificate selectedCertificate; + UniqueSECKEYPrivateKey selectedKey; + UniqueCERTCertList builtChain; + SECStatus status = DoGetClientAuthData( + std::move(authInfo), serverCert, std::move(collectedCANames), + selectedCertificate, selectedKey, builtChain); + if (status != SECSuccess) { + return status; + } + + if (selectedCertificate && selectedKey) { + if (builtChain) { + info->SetClientCertChain(std::move(builtChain)); + } else { + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("[%p] couldn't determine chain for selected client cert", socket)); + } + *pRetCert = selectedCertificate.release(); + *pRetKey = selectedKey.release(); + // Make joinConnection prohibit joining after we've sent a client cert + info->SetSentClientCert(); + Telemetry::ScalarAdd(Telemetry::ScalarID::SECURITY_CLIENT_CERT, u"sent"_ns, + 1); + if (info->GetSSLVersionUsed() == nsISSLSocketControl::TLS_VERSION_1_3) { + Telemetry::Accumulate(Telemetry::TLS_1_3_CLIENT_AUTH_USES_PHA, + info->IsHandshakeCompleted()); + } + } + + return SECSuccess; +} + +SECStatus DoGetClientAuthData(ClientAuthInfo&& info, + const UniqueCERTCertificate& serverCert, + nsTArray>&& collectedCANames, + UniqueCERTCertificate& outCert, + UniqueSECKEYPrivateKey& outKey, + UniqueCERTCertList& outBuiltChain) { + // XXX: This should be done asynchronously; see bug 696976 + RefPtr runnable = + XRE_IsSocketProcess() + ? new RemoteClientAuthDataRunnable(std::move(info), serverCert, + std::move(collectedCANames)) + : new ClientAuthDataRunnable(std::move(info), serverCert, + std::move(collectedCANames)); + + nsresult rv = runnable->DispatchToMainThreadAndWait(); + if (NS_FAILED(rv)) { + PR_SetError(SEC_ERROR_NO_MEMORY, 0); + return SECFailure; + } + + outCert = runnable->TakeSelectedCertificate(); + outKey = runnable->TakeSelectedKey(); + if (outCert && outKey) { + mozilla::pkix::Result result = + runnable->BuildChainForCertificate(outCert.get(), outBuiltChain); + if (result != Success) { + outBuiltChain.reset(nullptr); + } + } + + return SECSuccess; +} + +// This TrustDomain only exists to facilitate the mozilla::pkix path building +// algorithm. It considers any certificate with an issuer distinguished name in +// the set of given CA names to be a trust anchor. It does essentially no +// validation or verification (in particular, the signature checking function +// always returns "Success"). +class ClientAuthCertNonverifyingTrustDomain final : public TrustDomain { + public: + ClientAuthCertNonverifyingTrustDomain( + nsTArray>& collectedCANames, + nsTArray>& thirdPartyCertificates) + : mCollectedCANames(collectedCANames), + mCertStorage(do_GetService(NS_CERT_STORAGE_CID)), + mThirdPartyCertificates(thirdPartyCertificates) {} + + virtual mozilla::pkix::Result GetCertTrust( + EndEntityOrCA endEntityOrCA, const CertPolicyId& policy, + Input candidateCertDER, + /*out*/ TrustLevel& trustLevel) override; + virtual mozilla::pkix::Result FindIssuer(Input encodedIssuerName, + IssuerChecker& checker, + Time time) override; + + virtual mozilla::pkix::Result CheckRevocation( + EndEntityOrCA endEntityOrCA, const CertID& certID, Time time, + Duration validityDuration, + /*optional*/ const Input* stapledOCSPresponse, + /*optional*/ const Input* aiaExtension, + /*optional*/ const Input* sctExtension) override { + return Success; + } + + virtual mozilla::pkix::Result IsChainValid( + const DERArray& certChain, Time time, + const CertPolicyId& requiredPolicy) override; + + virtual mozilla::pkix::Result CheckSignatureDigestAlgorithm( + DigestAlgorithm digestAlg, EndEntityOrCA endEntityOrCA, + Time notBefore) override { + return Success; + } + virtual mozilla::pkix::Result CheckRSAPublicKeyModulusSizeInBits( + EndEntityOrCA endEntityOrCA, unsigned int modulusSizeInBits) override { + return Success; + } + virtual mozilla::pkix::Result VerifyRSAPKCS1SignedDigest( + const SignedDigest& signedDigest, Input subjectPublicKeyInfo) override { + return Success; + } + virtual mozilla::pkix::Result CheckECDSACurveIsAcceptable( + EndEntityOrCA endEntityOrCA, NamedCurve curve) override { + return Success; + } + virtual mozilla::pkix::Result VerifyECDSASignedDigest( + const SignedDigest& signedDigest, Input subjectPublicKeyInfo) override { + return Success; + } + virtual mozilla::pkix::Result CheckValidityIsAcceptable( + Time notBefore, Time notAfter, EndEntityOrCA endEntityOrCA, + KeyPurposeId keyPurpose) override { + return Success; + } + virtual mozilla::pkix::Result NetscapeStepUpMatchesServerAuth( + Time notBefore, + /*out*/ bool& matches) override { + matches = true; + return Success; + } + virtual void NoteAuxiliaryExtension(AuxiliaryExtension extension, + Input extensionData) override {} + virtual mozilla::pkix::Result DigestBuf(Input item, DigestAlgorithm digestAlg, + /*out*/ uint8_t* digestBuf, + size_t digestBufLen) override { + return DigestBufNSS(item, digestAlg, digestBuf, digestBufLen); + } + + UniqueCERTCertList TakeBuiltChain() { return std::move(mBuiltChain); } + + private: + nsTArray>& mCollectedCANames; // non-owning + nsCOMPtr mCertStorage; + nsTArray>& mThirdPartyCertificates; // non-owning + UniqueCERTCertList mBuiltChain; +}; + +mozilla::pkix::Result ClientAuthCertNonverifyingTrustDomain::GetCertTrust( + EndEntityOrCA endEntityOrCA, const CertPolicyId& policy, + Input candidateCertDER, + /*out*/ TrustLevel& trustLevel) { + // If the server did not specify any CA names, all client certificates are + // acceptable. + if (mCollectedCANames.Length() == 0) { + trustLevel = TrustLevel::TrustAnchor; + return Success; + } + BackCert cert(candidateCertDER, endEntityOrCA, nullptr); + mozilla::pkix::Result rv = cert.Init(); + if (rv != Success) { + return rv; + } + // If this certificate's issuer distinguished name is in the set of acceptable + // CA names, we say this is a trust anchor so that the client certificate + // issued from this certificate will be presented as an option for the user. + // We also check the certificate's subject distinguished name to account for + // the case where client certificates that have the id-kp-OCSPSigning EKU + // can't be trust anchors according to mozilla::pkix, and thus we may be + // looking directly at the issuer. + Input issuer(cert.GetIssuer()); + Input subject(cert.GetSubject()); + for (const auto& caName : mCollectedCANames) { + Input caNameInput; + rv = caNameInput.Init(caName.Elements(), caName.Length()); + if (rv != Success) { + continue; // probably too big + } + if (InputsAreEqual(issuer, caNameInput) || + InputsAreEqual(subject, caNameInput)) { + trustLevel = TrustLevel::TrustAnchor; + return Success; + } + } + trustLevel = TrustLevel::InheritsTrust; + return Success; +} + +// In theory this implementation should only need to consider intermediate +// certificates, since in theory it should only need to look at the issuer +// distinguished name of each certificate to determine if the client +// certificate is considered acceptable to the server. +// However, because we need to account for client certificates with the +// id-kp-OCSPSigning EKU, and because mozilla::pkix doesn't allow such +// certificates to be trust anchors, we need to consider the issuers of such +// certificates directly. These issuers could be roots, so we have to consider +// roots here. +mozilla::pkix::Result ClientAuthCertNonverifyingTrustDomain::FindIssuer( + Input encodedIssuerName, IssuerChecker& checker, Time time) { + // First try all relevant certificates known to Gecko, which avoids calling + // CERT_CreateSubjectCertList, because that can be expensive. + Vector geckoCandidates; + if (!mCertStorage) { + return mozilla::pkix::Result::FATAL_ERROR_LIBRARY_FAILURE; + } + nsTArray subject; + subject.AppendElements(encodedIssuerName.UnsafeGetData(), + encodedIssuerName.GetLength()); + nsTArray> certs; + nsresult rv = mCertStorage->FindCertsBySubject(subject, certs); + if (NS_FAILED(rv)) { + return mozilla::pkix::Result::FATAL_ERROR_LIBRARY_FAILURE; + } + for (auto& cert : certs) { + Input certDER; + mozilla::pkix::Result rv = certDER.Init(cert.Elements(), cert.Length()); + if (rv != Success) { + continue; // probably too big + } + if (!geckoCandidates.append(certDER)) { + return mozilla::pkix::Result::FATAL_ERROR_NO_MEMORY; + } + } + + for (const auto& thirdPartyCertificate : mThirdPartyCertificates) { + Input thirdPartyCertificateInput; + mozilla::pkix::Result rv = thirdPartyCertificateInput.Init( + thirdPartyCertificate.Elements(), thirdPartyCertificate.Length()); + if (rv != Success) { + continue; // probably too big + } + if (!geckoCandidates.append(thirdPartyCertificateInput)) { + return mozilla::pkix::Result::FATAL_ERROR_NO_MEMORY; + } + } + + bool keepGoing = true; + for (Input candidate : geckoCandidates) { + mozilla::pkix::Result rv = checker.Check(candidate, nullptr, keepGoing); + if (rv != Success) { + return rv; + } + if (!keepGoing) { + return Success; + } + } + + SECItem encodedIssuerNameItem = UnsafeMapInputToSECItem(encodedIssuerName); + // NSS seems not to differentiate between "no potential issuers found" and + // "there was an error trying to retrieve the potential issuers." We assume + // there was no error if CERT_CreateSubjectCertList returns nullptr. + UniqueCERTCertList candidates(CERT_CreateSubjectCertList( + nullptr, CERT_GetDefaultCertDB(), &encodedIssuerNameItem, 0, false)); + Vector nssCandidates; + if (candidates) { + for (CERTCertListNode* n = CERT_LIST_HEAD(candidates); + !CERT_LIST_END(n, candidates); n = CERT_LIST_NEXT(n)) { + Input certDER; + mozilla::pkix::Result rv = + certDER.Init(n->cert->derCert.data, n->cert->derCert.len); + if (rv != Success) { + continue; // probably too big + } + if (!nssCandidates.append(certDER)) { + return mozilla::pkix::Result::FATAL_ERROR_NO_MEMORY; + } + } + } + + for (Input candidate : nssCandidates) { + mozilla::pkix::Result rv = checker.Check(candidate, nullptr, keepGoing); + if (rv != Success) { + return rv; + } + if (!keepGoing) { + return Success; + } + } + return Success; +} + +mozilla::pkix::Result ClientAuthCertNonverifyingTrustDomain::IsChainValid( + const DERArray& certChain, Time, const CertPolicyId&) { + if (ConstructCERTCertListFromReversedDERArray(certChain, mBuiltChain) != + SECSuccess) { + return MapPRErrorCodeToResult(PR_GetError()); + } + return Success; +} + +mozilla::pkix::Result ClientAuthDataRunnable::BuildChainForCertificate( + CERTCertificate* cert, UniqueCERTCertList& builtChain) { + ClientAuthCertNonverifyingTrustDomain trustDomain(mCollectedCANames, + mEnterpriseCertificates); + Input certDER; + mozilla::pkix::Result result = + certDER.Init(cert->derCert.data, cert->derCert.len); + if (result != Success) { + return result; + } + // Client certificates shouldn't be CAs, but for interoperability reasons we + // attempt to build a path with each certificate as an end entity and then as + // a CA if that fails. + const EndEntityOrCA kEndEntityOrCAParams[] = {EndEntityOrCA::MustBeEndEntity, + EndEntityOrCA::MustBeCA}; + // mozilla::pkix rejects certificates with id-kp-OCSPSigning unless it is + // specifically required. A client certificate should never have this EKU. + // Unfortunately, there are some client certificates in private PKIs that + // have this EKU. For interoperability, we attempt to work around this + // restriction in mozilla::pkix by first building the certificate chain with + // no particular EKU required and then again with id-kp-OCSPSigning required + // if that fails. + const KeyPurposeId kKeyPurposeIdParams[] = {KeyPurposeId::anyExtendedKeyUsage, + KeyPurposeId::id_kp_OCSPSigning}; + for (const auto& endEntityOrCAParam : kEndEntityOrCAParams) { + for (const auto& keyPurposeIdParam : kKeyPurposeIdParams) { + mozilla::pkix::Result result = + BuildCertChain(trustDomain, certDER, Now(), endEntityOrCAParam, + KeyUsage::noParticularKeyUsageRequired, + keyPurposeIdParam, CertPolicyId::anyPolicy, nullptr); + if (result == Success) { + builtChain = trustDomain.TakeBuiltChain(); + return Success; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("client cert non-validation returned %d for '%s'", + static_cast(result), cert->subjectName)); + } + } + return mozilla::pkix::Result::ERROR_UNKNOWN_ISSUER; +} + +void ClientAuthDataRunnable::RunOnTargetThread() { + // We check the value of a pref in this runnable, so this runnable should only + // be run on the main thread. + MOZ_ASSERT(NS_IsMainThread()); + + nsCOMPtr component(do_GetService(PSM_COMPONENT_CONTRACTID)); + if (NS_WARN_IF(!component)) { + return; + } + nsresult rv = component->GetEnterpriseIntermediates(mEnterpriseCertificates); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + nsTArray> enterpriseRoots; + rv = component->GetEnterpriseRoots(enterpriseRoots); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + mEnterpriseCertificates.AppendElements(std::move(enterpriseRoots)); + + if (NS_WARN_IF(NS_FAILED(CheckForSmartCardChanges()))) { + return; + } + + // If a client cert preference was set on the socket info, use that and skip + // the client cert UI and/or search of the user's past cert decisions. + nsCOMPtr socketClientCert = mInfo.GetClientCert(); + if (socketClientCert) { + mSelectedCertificate.reset(socketClientCert->GetCert()); + if (NS_WARN_IF(!mSelectedCertificate)) { + return; + } + mSelectedKey.reset( + PK11_FindKeyByAnyCert(mSelectedCertificate.get(), nullptr)); + return; + } + + UniqueCERTCertList certList(FindClientCertificatesWithPrivateKeys()); + if (!certList) { + return; + } + + CERTCertListNode* n = CERT_LIST_HEAD(certList); + while (!CERT_LIST_END(n, certList)) { + UniqueCERTCertList unusedBuiltChain; + mozilla::pkix::Result result = + BuildChainForCertificate(n->cert, unusedBuiltChain); + if (result != Success) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("removing cert '%s'", n->cert->subjectName)); + CERTCertListNode* toRemove = n; + n = CERT_LIST_NEXT(n); + CERT_RemoveCertListNode(toRemove); + continue; + } + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("keeping cert '%s'\n", n->cert->subjectName)); + n = CERT_LIST_NEXT(n); + } + + if (CERT_LIST_EMPTY(certList)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("no client certificates available after filtering by CA")); + return; + } + + // find valid user cert and key pair + if (nsGetUserCertChoice() == UserCertChoice::Auto) { + // automatically find the right cert + UniqueCERTCertificate lowPrioNonrepCert; + // loop through the list until we find a cert with a key + for (CERTCertListNode* node = CERT_LIST_HEAD(certList); + !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)) { + UniqueSECKEYPrivateKey tmpKey(PK11_FindKeyByAnyCert(node->cert, nullptr)); + if (tmpKey) { + if (hasExplicitKeyUsageNonRepudiation(node->cert)) { + // Not a preferred cert + if (!lowPrioNonrepCert) { // did not yet find a low prio cert + lowPrioNonrepCert.reset(CERT_DupCertificate(node->cert)); + } + } else { + // this is a good cert to present + mSelectedCertificate.reset(CERT_DupCertificate(node->cert)); + mSelectedKey = std::move(tmpKey); + return; + } + } + if (PR_GetError() == SEC_ERROR_BAD_PASSWORD) { + // problem with password: bail + break; + } + } + + if (lowPrioNonrepCert) { + mSelectedCertificate = std::move(lowPrioNonrepCert); + mSelectedKey.reset( + PK11_FindKeyByAnyCert(mSelectedCertificate.get(), nullptr)); + } + return; + } + + // Not Auto => ask + // Get the SSL Certificate + const nsACString& hostname = mInfo.HostName(); + nsCOMPtr cars = nullptr; + + if (mInfo.ProviderTlsFlags() == 0) { + cars = do_GetService(NS_CLIENTAUTHREMEMBERSERVICE_CONTRACTID); + } + + if (cars) { + nsCString rememberedDBKey; + bool found; + nsresult rv = + cars->HasRememberedDecision(hostname, mInfo.OriginAttributesRef(), + mServerCert, rememberedDBKey, &found); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + if (found) { + // An empty dbKey indicates that the user chose not to use a certificate + // and chose to remember this decision + if (rememberedDBKey.IsEmpty()) { + return; + } + nsCOMPtr certdb = do_GetService(NS_X509CERTDB_CONTRACTID); + if (NS_WARN_IF(!certdb)) { + return; + } + nsCOMPtr foundCert; + nsresult rv = + certdb->FindCertByDBKey(rememberedDBKey, getter_AddRefs(foundCert)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + if (foundCert) { + nsNSSCertificate* objCert = + BitwiseCast(foundCert.get()); + if (NS_WARN_IF(!objCert)) { + return; + } + mSelectedCertificate.reset(objCert->GetCert()); + if (NS_WARN_IF(!mSelectedCertificate)) { + return; + } + mSelectedKey.reset( + PK11_FindKeyByAnyCert(mSelectedCertificate.get(), nullptr)); + return; + } + } + } + + // ask the user to select a certificate + nsCOMPtr dialogs; + UniquePORTString corg(CERT_GetOrgName(&mServerCert->subject)); + nsAutoCString org(corg.get()); + + UniquePORTString cissuer(CERT_GetOrgName(&mServerCert->issuer)); + nsAutoCString issuer(cissuer.get()); + + nsCOMPtr certArray = nsArrayBase::Create(); + if (NS_WARN_IF(!certArray)) { + return; + } + + for (CERTCertListNode* node = CERT_LIST_HEAD(certList); + !CERT_LIST_END(node, certList); node = CERT_LIST_NEXT(node)) { + nsCOMPtr tempCert = nsNSSCertificate::Create(node->cert); + if (NS_WARN_IF(!tempCert)) { + return; + } + nsresult rv = certArray->AppendElement(tempCert); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + } + + // Throw up the client auth dialog and get back the index of the selected + // cert + rv = getNSSDialogs(getter_AddRefs(dialogs), NS_GET_IID(nsIClientAuthDialogs), + NS_CLIENTAUTHDIALOGS_CONTRACTID); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + uint32_t selectedIndex = 0; + bool certChosen = false; + + // even if the user has canceled, we want to remember that, to avoid + // repeating prompts + bool wantRemember = false; + rv = + dialogs->ChooseCertificate(hostname, mInfo.Port(), org, issuer, certArray, + &selectedIndex, &wantRemember, &certChosen); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + if (certChosen) { + nsCOMPtr selectedCert = + do_QueryElementAt(certArray, selectedIndex); + if (NS_WARN_IF(!selectedCert)) { + return; + } + mSelectedCertificate.reset(selectedCert->GetCert()); + if (NS_WARN_IF(!mSelectedCertificate)) { + return; + } + mSelectedKey.reset( + PK11_FindKeyByAnyCert(mSelectedCertificate.get(), nullptr)); + } + + if (cars && wantRemember) { + rv = cars->RememberDecision( + hostname, mInfo.OriginAttributesRef(), mServerCert, + certChosen ? mSelectedCertificate.get() : nullptr); + Unused << NS_WARN_IF(NS_FAILED(rv)); + } +} + +mozilla::pkix::Result RemoteClientAuthDataRunnable::BuildChainForCertificate( + CERTCertificate*, UniqueCERTCertList& builtChain) { + builtChain.reset(CERT_NewCertList()); + if (!builtChain) { + return mozilla::pkix::Result::FATAL_ERROR_NO_MEMORY; + } + + for (auto& certBytes : mBuiltChain) { + SECItem certDER = {siBuffer, certBytes.data().Elements(), + static_cast(certBytes.data().Length())}; + UniqueCERTCertificate cert(CERT_NewTempCertificate( + CERT_GetDefaultCertDB(), &certDER, nullptr, false, true)); + if (!cert) { + return mozilla::pkix::Result::ERROR_BAD_DER; + } + + if (CERT_AddCertToListTail(builtChain.get(), cert.get()) != SECSuccess) { + return mozilla::pkix::Result::FATAL_ERROR_NO_MEMORY; + } + Unused << cert.release(); + } + + return Success; +} + +void RemoteClientAuthDataRunnable::RunOnTargetThread() { + MOZ_ASSERT(NS_IsMainThread()); + + const ByteArray serverCertSerialized = CopyableTArray{ + mServerCert->derCert.data, mServerCert->derCert.len}; + + // Note that client cert is NULL in socket process until bug 1632809 is done. + Maybe clientCertSerialized; + nsCOMPtr socketClientCert = mInfo.GetClientCert(); + if (socketClientCert) { + nsTArray certBytes; + if (NS_FAILED(socketClientCert->GetRawDER(certBytes))) { + return; + } + clientCertSerialized.emplace(std::move(certBytes)); + } + + nsTArray collectedCANames; + for (auto& name : mCollectedCANames) { + collectedCANames.AppendElement(std::move(name)); + } + + bool succeeded = false; + ByteArray cert; + ByteArray key; + mozilla::net::SocketProcessChild::GetSingleton()->SendGetTLSClientCert( + nsCString(mInfo.HostName()), mInfo.OriginAttributesRef(), mInfo.Port(), + mInfo.ProviderFlags(), mInfo.ProviderTlsFlags(), serverCertSerialized, + clientCertSerialized, collectedCANames, &succeeded, &cert, &key, + &mBuiltChain); + + if (!succeeded) { + return; + } + + DeserializeClientCertAndKey(cert, key, mSelectedCertificate, mSelectedKey); +} + +static PRFileDesc* nsSSLIOLayerImportFD(PRFileDesc* fd, + nsNSSSocketInfo* infoObject, + const char* host, bool haveHTTPSProxy) { + PRFileDesc* sslSock = SSL_ImportFD(nullptr, fd); + if (!sslSock) { + MOZ_ASSERT_UNREACHABLE("NSS: Error importing socket"); + return nullptr; + } + SSL_SetPKCS11PinArg(sslSock, (nsIInterfaceRequestor*)infoObject); + SSL_HandshakeCallback(sslSock, HandshakeCallback, infoObject); + SSL_SetCanFalseStartCallback(sslSock, CanFalseStartCallback, infoObject); + + // Disable this hook if we connect anonymously. See bug 466080. + uint32_t flags = 0; + infoObject->GetProviderFlags(&flags); + // Provide the client cert to HTTPS proxy no matter if it is anonymous. + if (flags & nsISocketProvider::ANONYMOUS_CONNECT && !haveHTTPSProxy) { + SSL_GetClientAuthDataHook(sslSock, nullptr, infoObject); + } else { + SSL_GetClientAuthDataHook( + sslSock, (SSLGetClientAuthData)nsNSS_SSLGetClientAuthData, infoObject); + } + + if (SECSuccess != + SSL_AuthCertificateHook(sslSock, AuthCertificateHook, infoObject)) { + MOZ_ASSERT_UNREACHABLE("Failed to configure AuthCertificateHook"); + goto loser; + } + + if (SECSuccess != SSL_SetURL(sslSock, host)) { + MOZ_ASSERT_UNREACHABLE("SSL_SetURL failed"); + goto loser; + } + + return sslSock; +loser: + if (sslSock) { + PR_Close(sslSock); + } + return nullptr; +} + +// Please change getSignatureName in nsNSSCallbacks.cpp when changing the list +// here. See NOTE at SSL_SignatureSchemePrefSet call site. +static const SSLSignatureScheme sEnabledSignatureSchemes[] = { + ssl_sig_ecdsa_secp256r1_sha256, ssl_sig_ecdsa_secp384r1_sha384, + ssl_sig_ecdsa_secp521r1_sha512, ssl_sig_rsa_pss_sha256, + ssl_sig_rsa_pss_sha384, ssl_sig_rsa_pss_sha512, + ssl_sig_rsa_pkcs1_sha256, ssl_sig_rsa_pkcs1_sha384, + ssl_sig_rsa_pkcs1_sha512, ssl_sig_ecdsa_sha1, + ssl_sig_rsa_pkcs1_sha1, +}; + +static nsresult nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS, + bool haveProxy, const char* host, + int32_t port, + nsNSSSocketInfo* infoObject) { + if (forSTARTTLS || haveProxy) { + if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) { + return NS_ERROR_FAILURE; + } + } + + SSLVersionRange range; + if (SSL_VersionRangeGet(fd, &range) != SECSuccess) { + return NS_ERROR_FAILURE; + } + + // Set TLS 1.3 compat mode. + if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("[%p] nsSSLIOLayerSetOptions: Setting compat mode failed\n", fd)); + } + + // setting TLS max version + uint32_t versionFlags = + getTLSProviderFlagMaxVersion(infoObject->GetProviderTlsFlags()); + if (versionFlags) { + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("[%p] nsSSLIOLayerSetOptions: version flags %d\n", fd, versionFlags)); + if (versionFlags == kTLSProviderFlagMaxVersion10) { + range.max = SSL_LIBRARY_VERSION_TLS_1_0; + } else if (versionFlags == kTLSProviderFlagMaxVersion11) { + range.max = SSL_LIBRARY_VERSION_TLS_1_1; + } else if (versionFlags == kTLSProviderFlagMaxVersion12) { + range.max = SSL_LIBRARY_VERSION_TLS_1_2; + } else if (versionFlags == kTLSProviderFlagMaxVersion13) { + range.max = SSL_LIBRARY_VERSION_TLS_1_3; + } else { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("[%p] nsSSLIOLayerSetOptions: unknown version flags %d\n", fd, + versionFlags)); + } + } + + if ((infoObject->GetProviderFlags() & nsISocketProvider::BE_CONSERVATIVE) && + (range.max > SSL_LIBRARY_VERSION_TLS_1_2)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] nsSSLIOLayerSetOptions: range.max limited to 1.2 due to " + "BE_CONSERVATIVE flag\n", + fd)); + range.max = SSL_LIBRARY_VERSION_TLS_1_2; + } + + uint16_t maxEnabledVersion = range.max; + infoObject->SharedState().IOLayerHelpers().adjustForTLSIntolerance( + infoObject->GetHostName(), infoObject->GetPort(), range); + MOZ_LOG( + gPIPNSSLog, LogLevel::Debug, + ("[%p] nsSSLIOLayerSetOptions: using TLS version range (0x%04x,0x%04x)\n", + fd, static_cast(range.min), + static_cast(range.max))); + + // If the user has set their minimum version to something higher than what + // we've now set the maximum to, this will result in an inconsistent version + // range unless we fix it up. This will override their preference, but we only + // do this for sites critical to the operation of the browser (e.g. update + // servers) and telemetry experiments. + if (range.min > range.max) { + range.min = range.max; + } + + if (SSL_VersionRangeSet(fd, &range) != SECSuccess) { + return NS_ERROR_FAILURE; + } + infoObject->SetTLSVersionRange(range); + + // when adjustForTLSIntolerance tweaks the maximum version downward, + // we tell the server using this SCSV so they can detect a downgrade attack + if (range.max < maxEnabledVersion) { + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] nsSSLIOLayerSetOptions: enabling TLS_FALLBACK_SCSV\n", fd)); + // Some servers will choke if we send the fallback SCSV with TLS 1.2. + if (range.max < SSL_LIBRARY_VERSION_TLS_1_2) { + if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_FALLBACK_SCSV, true)) { + return NS_ERROR_FAILURE; + } + } + // tell NSS the max enabled version to make anti-downgrade effective + if (SECSuccess != SSL_SetDowngradeCheckVersion(fd, maxEnabledVersion)) { + return NS_ERROR_FAILURE; + } + } + + // Include a modest set of named groups. + // Please change getKeaGroupName in nsNSSCallbacks.cpp when changing the list + // here. + const SSLNamedGroup namedGroups[] = { + ssl_grp_ec_curve25519, ssl_grp_ec_secp256r1, ssl_grp_ec_secp384r1, + ssl_grp_ec_secp521r1, ssl_grp_ffdhe_2048, ssl_grp_ffdhe_3072}; + if (SECSuccess != SSL_NamedGroupConfig(fd, namedGroups, + mozilla::ArrayLength(namedGroups))) { + return NS_ERROR_FAILURE; + } + // This ensures that we send key shares for X25519 and P-256 in TLS 1.3, so + // that servers are less likely to use HelloRetryRequest. + if (SECSuccess != SSL_SendAdditionalKeyShares(fd, 1)) { + return NS_ERROR_FAILURE; + } + + // NOTE: Should this list ever include ssl_sig_rsa_pss_pss_sha* (or should + // it become possible to enable this scheme via a pref), it is required + // to test that a Delegated Credential containing a small-modulus RSA-PSS SPKI + // is properly rejected. NSS will not advertise PKCS1 or RSAE schemes (which + // the |ssl_sig_rsa_pss_*| defines alias, meaning we will not currently accept + // any RSA DC. + if (SECSuccess != SSL_SignatureSchemePrefSet( + fd, sEnabledSignatureSchemes, + mozilla::ArrayLength(sEnabledSignatureSchemes))) { + return NS_ERROR_FAILURE; + } + + bool enabled = infoObject->SharedState().IsOCSPStaplingEnabled(); + if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_OCSP_STAPLING, enabled)) { + return NS_ERROR_FAILURE; + } + + bool sctsEnabled = infoObject->SharedState().IsSignedCertTimestampsEnabled(); + if (SECSuccess != + SSL_OptionSet(fd, SSL_ENABLE_SIGNED_CERT_TIMESTAMPS, sctsEnabled)) { + return NS_ERROR_FAILURE; + } + + if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) { + return NS_ERROR_FAILURE; + } + +#ifdef __arm__ + unsigned int enabledCiphers = 0; + std::vector ciphers(SSL_GetNumImplementedCiphers()); + + // Returns only the enabled (reflecting prefs) ciphers, ordered + // by their occurence in + // https://hg.mozilla.org/projects/nss/file/a75ea4cdacd95282c6c245ebb849c25e84ccd908/lib/ssl/ssl3con.c#l87 + if (SSL_CipherSuiteOrderGet(fd, ciphers.data(), &enabledCiphers) != + SECSuccess) { + return NS_ERROR_FAILURE; + } + + // On ARM, prefer (TLS_CHACHA20_POLY1305_SHA256) over AES. However, + // it may be disabled. If enabled, it will either be element [0] or [1]*. + // If [0], we're done. If [1], swap it with [0] (TLS_AES_128_GCM_SHA256). + // * (assuming the compile-time order remains unchanged) + if (enabledCiphers > 1) { + if (ciphers[0] != TLS_CHACHA20_POLY1305_SHA256 && + ciphers[1] == TLS_CHACHA20_POLY1305_SHA256) { + std::swap(ciphers[0], ciphers[1]); + + if (SSL_CipherSuiteOrderSet(fd, ciphers.data(), enabledCiphers) != + SECSuccess) { + return NS_ERROR_FAILURE; + } + } + } +#endif + + // Set the Peer ID so that SSL proxy connections work properly and to + // separate anonymous and/or private browsing connections. + nsAutoCString peerId; + infoObject->GetPeerId(peerId); + if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) { + return NS_ERROR_FAILURE; + } + + uint32_t flags = infoObject->GetProviderFlags(); + if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) { + if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_SESSION_TICKETS, false) || + SECSuccess != SSL_OptionSet(fd, SSL_NO_CACHE, true)) { + return NS_ERROR_FAILURE; + } + } + + return NS_OK; +} + +SECStatus StoreResumptionToken(PRFileDesc* fd, const PRUint8* resumptionToken, + unsigned int len, void* ctx) { + PRIntn val; + if (SSL_OptionGet(fd, SSL_ENABLE_SESSION_TICKETS, &val) != SECSuccess || + val == 0) { + return SECFailure; + } + + nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*)ctx; + if (!infoObject) { + return SECFailure; + } + + nsAutoCString peerId; + infoObject->GetPeerId(peerId); + if (NS_FAILED( + net::SSLTokensCache::Put(peerId, resumptionToken, len, infoObject))) { + return SECFailure; + } + + return SECSuccess; +} + +nsresult nsSSLIOLayerAddToSocket(int32_t family, const char* host, int32_t port, + nsIProxyInfo* proxy, + const OriginAttributes& originAttributes, + PRFileDesc* fd, nsISupports** info, + bool forSTARTTLS, uint32_t providerFlags, + uint32_t providerTlsFlags) { + PRFileDesc* layer = nullptr; + PRFileDesc* plaintextLayer = nullptr; + nsresult rv; + PRStatus stat; + + SharedSSLState* sharedState = nullptr; + RefPtr allocatedState; + if (providerTlsFlags) { + allocatedState = new SharedSSLState(providerTlsFlags); + sharedState = allocatedState.get(); + } else { + bool isPrivate = providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE || + originAttributes.mPrivateBrowsingId != + OriginAttributes().mPrivateBrowsingId; + sharedState = isPrivate ? PrivateSSLState() : PublicSSLState(); + } + + nsNSSSocketInfo* infoObject = + new nsNSSSocketInfo(*sharedState, providerFlags, providerTlsFlags); + if (!infoObject) return NS_ERROR_FAILURE; + + NS_ADDREF(infoObject); + infoObject->SetForSTARTTLS(forSTARTTLS); + infoObject->SetHostName(host); + infoObject->SetPort(port); + infoObject->SetOriginAttributes(originAttributes); + if (allocatedState) { + infoObject->SetSharedOwningReference(allocatedState); + } + + bool haveProxy = false; + bool haveHTTPSProxy = false; + if (proxy) { + nsAutoCString proxyHost; + proxy->GetHost(proxyHost); + haveProxy = !proxyHost.IsEmpty(); + nsAutoCString type; + haveHTTPSProxy = haveProxy && NS_SUCCEEDED(proxy->GetType(type)) && + type.EqualsLiteral("https"); + } + + // A plaintext observer shim is inserted so we can observe some protocol + // details without modifying nss + plaintextLayer = + PR_CreateIOLayerStub(nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity, + &nsSSLIOLayerHelpers::nsSSLPlaintextLayerMethods); + if (plaintextLayer) { + plaintextLayer->secret = (PRFilePrivate*)infoObject; + stat = PR_PushIOLayer(fd, PR_TOP_IO_LAYER, plaintextLayer); + if (stat == PR_FAILURE) { + plaintextLayer->dtor(plaintextLayer); + plaintextLayer = nullptr; + } + } + + PRFileDesc* sslSock = + nsSSLIOLayerImportFD(fd, infoObject, host, haveHTTPSProxy); + if (!sslSock) { + MOZ_ASSERT_UNREACHABLE("NSS: Error importing socket"); + goto loser; + } + + infoObject->SetFileDescPtr(sslSock); + + rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, haveProxy, host, port, + infoObject); + + if (NS_FAILED(rv)) goto loser; + + // Now, layer ourselves on top of the SSL socket... + layer = PR_CreateIOLayerStub(nsSSLIOLayerHelpers::nsSSLIOLayerIdentity, + &nsSSLIOLayerHelpers::nsSSLIOLayerMethods); + if (!layer) goto loser; + + layer->secret = (PRFilePrivate*)infoObject; + stat = PR_PushIOLayer(sslSock, PR_GetLayersIdentity(sslSock), layer); + + if (stat == PR_FAILURE) { + goto loser; + } + + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("[%p] Socket set up\n", (void*)sslSock)); + infoObject->QueryInterface(NS_GET_IID(nsISupports), (void**)(info)); + + // We are going use a clear connection first // + if (forSTARTTLS || haveProxy) { + infoObject->SetHandshakeNotPending(); + } + + infoObject->SharedState().NoteSocketCreated(); + + if (StaticPrefs::network_ssl_tokens_cache_enabled()) { + rv = infoObject->SetResumptionTokenFromExternalCache(); + if (NS_FAILED(rv)) { + return rv; + } + SSL_SetResumptionTokenCallback(sslSock, &StoreResumptionToken, infoObject); + } + + return NS_OK; +loser: + NS_IF_RELEASE(infoObject); + if (layer) { + layer->dtor(layer); + } + if (plaintextLayer) { + // Note that PR_*IOLayer operations may modify the stack of fds, so a + // previously-valid pointer may no longer point to what we think it points + // to after calling PR_PopIOLayer. We must operate on the pointer returned + // by PR_PopIOLayer. + plaintextLayer = + PR_PopIOLayer(fd, nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity); + plaintextLayer->dtor(plaintextLayer); + } + return NS_ERROR_FAILURE; +} diff --git a/security/manager/ssl/nsNSSIOLayer.h b/security/manager/ssl/nsNSSIOLayer.h new file mode 100644 index 0000000000..beb0a67340 --- /dev/null +++ b/security/manager/ssl/nsNSSIOLayer.h @@ -0,0 +1,359 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef nsNSSIOLayer_h +#define nsNSSIOLayer_h + +#include "CommonSocketControl.h" +#include "mozilla/Assertions.h" +#include "mozilla/TimeStamp.h" +#include "mozilla/UniquePtr.h" +#include "nsCOMPtr.h" +#include "nsDataHashtable.h" +#include "nsIProxyInfo.h" +#include "nsISSLSocketControl.h" +#include "nsNSSCertificate.h" +#include "nsTHashtable.h" +#include "sslt.h" + +namespace mozilla { +class OriginAttributes; +namespace psm { +class SharedSSLState; +} // namespace psm +} // namespace mozilla + +using mozilla::OriginAttributes; + +class nsIObserver; + +class nsNSSSocketInfo final : public CommonSocketControl { + public: + nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags, + uint32_t providerTlsFlags); + + NS_DECL_ISUPPORTS_INHERITED + + void SetForSTARTTLS(bool aForSTARTTLS); + bool GetForSTARTTLS(); + + nsresult GetFileDescPtr(PRFileDesc** aFilePtr); + nsresult SetFileDescPtr(PRFileDesc* aFilePtr); + + bool IsHandshakePending() const { return mHandshakePending; } + void SetHandshakeNotPending() { mHandshakePending = false; } + + void SetTLSVersionRange(SSLVersionRange range) { mTLSVersionRange = range; } + SSLVersionRange GetTLSVersionRange() const { return mTLSVersionRange; }; + + // From nsISSLSocketControl. + NS_IMETHOD ProxyStartSSL(void) override; + NS_IMETHOD StartTLS(void) override; + NS_IMETHOD SetNPNList(nsTArray& aNPNList) override; + NS_IMETHOD GetAlpnEarlySelection(nsACString& _retval) override; + NS_IMETHOD GetEarlyDataAccepted(bool* aEarlyDataAccepted) override; + NS_IMETHOD DriveHandshake(void) override; + using nsISSLSocketControl::GetKEAUsed; + NS_IMETHOD GetKEAUsed(int16_t* aKEAUsed) override; + NS_IMETHOD GetKEAKeyBits(uint32_t* aKEAKeyBits) override; + NS_IMETHOD GetProviderTlsFlags(uint32_t* aProviderTlsFlags) override; + NS_IMETHOD GetSSLVersionOffered(int16_t* aSSLVersionOffered) override; + NS_IMETHOD GetMACAlgorithmUsed(int16_t* aMACAlgorithmUsed) override; + bool GetDenyClientCert() override; + void SetDenyClientCert(bool aDenyClientCert) override; + NS_IMETHOD GetClientCert(nsIX509Cert** aClientCert) override; + NS_IMETHOD SetClientCert(nsIX509Cert* aClientCert) override; + NS_IMETHOD GetEsniTxt(nsACString& aEsniTxt) override; + NS_IMETHOD SetEsniTxt(const nsACString& aEsniTxt) override; + NS_IMETHOD GetEchConfig(nsACString& aEchConfig) override; + NS_IMETHOD SetEchConfig(const nsACString& aEchConfig) override; + NS_IMETHOD GetPeerId(nsACString& aResult) override; + NS_IMETHOD GetRetryEchConfig(nsACString& aEchConfig) override; + + PRStatus CloseSocketAndDestroy(); + + void SetNegotiatedNPN(const char* value, uint32_t length); + void SetEarlyDataAccepted(bool aAccepted); + + void SetHandshakeCompleted(); + bool IsHandshakeCompleted() const { return mHandshakeCompleted; } + void NoteTimeUntilReady(); + + void SetFalseStartCallbackCalled() { mFalseStartCallbackCalled = true; } + void SetFalseStarted() { mFalseStarted = true; } + + // Note that this is only valid *during* a handshake; at the end of the + // handshake, it gets reset back to false. + void SetFullHandshake() { mIsFullHandshake = true; } + bool IsFullHandshake() const { return mIsFullHandshake; } + + bool GetJoined() { return mJoined; } + void SetSentClientCert() { mSentClientCert = true; } + + uint32_t GetProviderTlsFlags() const { return mProviderTlsFlags; } + + mozilla::psm::SharedSSLState& SharedState(); + + // XXX: These are only used on for diagnostic purposes + enum CertVerificationState { + before_cert_verification, + waiting_for_cert_verification, + after_cert_verification + }; + void SetCertVerificationWaiting(); + // Use errorCode == 0 to indicate success; + void SetCertVerificationResult(PRErrorCode errorCode) override; + + // for logging only + PRBool IsWaitingForCertVerification() const { + return mCertVerificationState == waiting_for_cert_verification; + } + void AddPlaintextBytesRead(uint64_t val) { mPlaintextBytesRead += val; } + + bool IsPreliminaryHandshakeDone() const { return mPreliminaryHandshakeDone; } + void SetPreliminaryHandshakeDone() { mPreliminaryHandshakeDone = true; } + + void SetKEAUsed(uint16_t kea) { mKEAUsed = kea; } + + void SetKEAKeyBits(uint32_t keaBits) { mKEAKeyBits = keaBits; } + + void SetMACAlgorithmUsed(int16_t mac) { mMACAlgorithmUsed = mac; } + + void SetShortWritePending(int32_t amount, unsigned char data) { + mIsShortWritePending = true; + mShortWriteOriginalAmount = amount; + mShortWritePendingByte = data; + } + + bool IsShortWritePending() { return mIsShortWritePending; } + + unsigned char const* GetShortWritePendingByteRef() { + return &mShortWritePendingByte; + } + + int32_t ResetShortWritePending() { + mIsShortWritePending = false; + return mShortWriteOriginalAmount; + } + +#ifdef DEBUG + // These helpers assert that the caller does try to send the same data + // as it was previously when we hit the short-write. This is a measure + // to make sure we communicate correctly to the consumer. + void RememberShortWrittenBuffer(const unsigned char* data) { + mShortWriteBufferCheck = + mozilla::MakeUnique(mShortWriteOriginalAmount); + memcpy(mShortWriteBufferCheck.get(), data, mShortWriteOriginalAmount); + } + void CheckShortWrittenBuffer(const unsigned char* data, int32_t amount) { + if (!mShortWriteBufferCheck) return; + MOZ_ASSERT(amount >= mShortWriteOriginalAmount, + "unexpected amount length after short write"); + MOZ_ASSERT( + !memcmp(mShortWriteBufferCheck.get(), data, mShortWriteOriginalAmount), + "unexpected buffer content after short write"); + mShortWriteBufferCheck = nullptr; + } +#endif + + void SetSharedOwningReference(mozilla::psm::SharedSSLState* ref); + + nsresult SetResumptionTokenFromExternalCache(); + + void SetClientCertChain(mozilla::UniqueCERTCertList&& clientCertChain) { + mClientCertChain = std::move(clientCertChain); + } + + protected: + virtual ~nsNSSSocketInfo(); + + private: + PRFileDesc* mFd; + + CertVerificationState mCertVerificationState; + + mozilla::psm::SharedSSLState& mSharedState; + bool mForSTARTTLS; + SSLVersionRange mTLSVersionRange; + bool mHandshakePending; + bool mPreliminaryHandshakeDone; // after false start items are complete + + nsresult ActivateSSL(); + + nsCString mEsniTxt; + nsCString mEchConfig; + nsCString mPeerId; + bool mEarlyDataAccepted; + bool mDenyClientCert; + bool mFalseStartCallbackCalled; + bool mFalseStarted; + bool mIsFullHandshake; + bool mNotedTimeUntilReady; + + // True when SSL layer has indicated an "SSL short write", i.e. need + // to call on send one or more times to push all pending data to write. + bool mIsShortWritePending; + + // These are only valid if mIsShortWritePending is true. + // + // Value of the last byte pending from the SSL short write that needs + // to be passed to subsequent calls to send to perform the flush. + unsigned char mShortWritePendingByte; + + // Original amount of data the upper layer has requested to write to + // return after the successful flush. + int32_t mShortWriteOriginalAmount; + +#ifdef DEBUG + mozilla::UniquePtr mShortWriteBufferCheck; +#endif + + // mKEA* are used in false start and http/2 detetermination + // Values are from nsISSLSocketControl + int16_t mKEAUsed; + uint32_t mKEAKeyBits; + int16_t mMACAlgorithmUsed; + + uint32_t mProviderTlsFlags; + mozilla::TimeStamp mSocketCreationTimestamp; + uint64_t mPlaintextBytesRead; + + nsCOMPtr mClientCert; + // Regarding the client certificate message in the TLS handshake, RFC 5246 + // (TLS 1.2) says: + // If the certificate_authorities list in the certificate request + // message was non-empty, one of the certificates in the certificate + // chain SHOULD be issued by one of the listed CAs. + // (RFC 8446 (TLS 1.3) has a similar provision) + // These certificates may be known to gecko but not NSS (e.g. enterprise + // intermediates). In order to make these certificates discoverable to NSS + // so it can include them in the message, we cache them here as temporary + // certificates. + mozilla::UniqueCERTCertList mClientCertChain; + + // if non-null this is a reference to the mSharedState (which is + // not an owning reference). If this is used, the info has a private + // state that does not share things like intolerance lists with the + // rest of the session. This is normally used when you have per + // socket tls flags overriding session wide defaults. + RefPtr mOwningSharedRef; +}; + +// This class is used to store the needed information for invoking the client +// cert selection UI. +class ClientAuthInfo final { + public: + explicit ClientAuthInfo(const nsACString& hostName, + const OriginAttributes& originAttributes, + int32_t port, uint32_t providerFlags, + uint32_t providerTlsFlags, nsIX509Cert* clientCert); + ~ClientAuthInfo() = default; + ClientAuthInfo(ClientAuthInfo&& aOther) noexcept; + + const nsACString& HostName() const; + const OriginAttributes& OriginAttributesRef() const; + int32_t Port() const; + already_AddRefed GetClientCert() const; + uint32_t ProviderFlags() const; + uint32_t ProviderTlsFlags() const; + + private: + ClientAuthInfo(const ClientAuthInfo&) = delete; + void operator=(const ClientAuthInfo&) = delete; + + nsCString mHostName; + OriginAttributes mOriginAttributes; + int32_t mPort; + uint32_t mProviderFlags; + uint32_t mProviderTlsFlags; + nsCOMPtr mClientCert; +}; + +class nsSSLIOLayerHelpers { + public: + explicit nsSSLIOLayerHelpers(uint32_t aTlsFlags = 0); + ~nsSSLIOLayerHelpers(); + + nsresult Init(); + void Cleanup(); + + static bool nsSSLIOLayerInitialized; + static PRDescIdentity nsSSLIOLayerIdentity; + static PRDescIdentity nsSSLPlaintextLayerIdentity; + static PRIOMethods nsSSLIOLayerMethods; + static PRIOMethods nsSSLPlaintextLayerMethods; + + bool mTreatUnsafeNegotiationAsBroken; + + void setTreatUnsafeNegotiationAsBroken(bool broken); + bool treatUnsafeNegotiationAsBroken(); + + private: + struct IntoleranceEntry { + uint16_t tolerant; + uint16_t intolerant; + PRErrorCode intoleranceReason; + + void AssertInvariant() const { + MOZ_ASSERT(intolerant == 0 || tolerant < intolerant); + } + }; + nsDataHashtable mTLSIntoleranceInfo; + // Sites that require insecure fallback to TLS 1.0, set by the pref + // security.tls.insecure_fallback_hosts, which is a comma-delimited + // list of domain names. + nsTHashtable mInsecureFallbackSites; + + public: + void rememberTolerantAtVersion(const nsACString& hostname, int16_t port, + uint16_t tolerant); + bool fallbackLimitReached(const nsACString& hostname, uint16_t intolerant); + bool rememberIntolerantAtVersion(const nsACString& hostname, int16_t port, + uint16_t intolerant, uint16_t minVersion, + PRErrorCode intoleranceReason); + void forgetIntolerance(const nsACString& hostname, int16_t port); + void adjustForTLSIntolerance(const nsACString& hostname, int16_t port, + /*in/out*/ SSLVersionRange& range); + PRErrorCode getIntoleranceReason(const nsACString& hostname, int16_t port); + + void clearStoredData(); + void loadVersionFallbackLimit(); + void setInsecureFallbackSites(const nsCString& str); + void initInsecureFallbackSites(); + bool isPublic() const; + void removeInsecureFallbackSite(const nsACString& hostname, uint16_t port); + bool isInsecureFallbackSite(const nsACString& hostname); + + uint16_t mVersionFallbackLimit; + + private: + mozilla::Mutex mutex; + nsCOMPtr mPrefObserver; + uint32_t mTlsFlags; +}; + +nsresult nsSSLIOLayerNewSocket(int32_t family, const char* host, int32_t port, + nsIProxyInfo* proxy, + const OriginAttributes& originAttributes, + PRFileDesc** fd, nsISupports** securityInfo, + bool forSTARTTLS, uint32_t flags, + uint32_t tlsFlags); + +nsresult nsSSLIOLayerAddToSocket(int32_t family, const char* host, int32_t port, + nsIProxyInfo* proxy, + const OriginAttributes& originAttributes, + PRFileDesc* fd, nsISupports** securityInfo, + bool forSTARTTLS, uint32_t flags, + uint32_t tlsFlags); + +SECStatus DoGetClientAuthData(ClientAuthInfo&& info, + const mozilla::UniqueCERTCertificate& serverCert, + nsTArray>&& collectedCANames, + mozilla::UniqueCERTCertificate& outCert, + mozilla::UniqueSECKEYPrivateKey& outKey, + mozilla::UniqueCERTCertList& outBuiltChain); + +#endif // nsNSSIOLayer_h diff --git a/security/manager/ssl/nsNSSModule.cpp b/security/manager/ssl/nsNSSModule.cpp new file mode 100644 index 0000000000..2fa628ad58 --- /dev/null +++ b/security/manager/ssl/nsNSSModule.cpp @@ -0,0 +1,134 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "nsNSSModule.h" + +#include "ContentSignatureVerifier.h" +#include "NSSErrorsService.h" +#include "OSKeyStore.h" +#include "OSReauthenticator.h" +#include "PKCS11ModuleDB.h" +#include "SecretDecoderRing.h" +#include "TransportSecurityInfo.h" +#include "mozilla/MacroArgs.h" +#include "mozilla/ModuleUtils.h" +#include "mozilla/SyncRunnable.h" +#include "nsCURILoader.h" +#include "nsCryptoHash.h" +#include "nsKeyModule.h" +#include "nsNSSCertificate.h" +#include "nsNSSCertificateDB.h" +#include "nsNSSComponent.h" +#include "nsNSSVersion.h" +#include "nsNetCID.h" +#include "nsPK11TokenDB.h" +#include "nsPKCS11Slot.h" +#include "nsRandomGenerator.h" +#include "nsSecureBrowserUI.h" +#include "nsXULAppAPI.h" + +#ifdef MOZ_XUL +# include "nsCertTree.h" +#endif + +namespace mozilla { +namespace psm { + +// Many of the implementations in this module call NSS functions and as a result +// require that PSM has successfully initialized NSS before being used. +// Additionally, some of the implementations have various restrictions on which +// process and threads they can be used on (e.g. some can only be used in the +// parent process and some must be initialized only on the main thread). +// The following initialization framework allows these requirements to be +// succinctly expressed and implemented. + +template +MOZ_ALWAYS_INLINE static nsresult Instantiate(REFNSIID aIID, void** aResult) { + InstanceClass* inst = new InstanceClass(); + NS_ADDREF(inst); + nsresult rv = InitMethod != nullptr ? (inst->*InitMethod)() : NS_OK; + if (NS_SUCCEEDED(rv)) { + rv = inst->QueryInterface(aIID, aResult); + } + NS_RELEASE(inst); + return rv; +} + +enum class ThreadRestriction { + // must be initialized on the main thread (but can be used on any thread) + MainThreadOnly, + // can be initialized and used on any thread + AnyThread, +}; + +enum class ProcessRestriction { + ParentProcessOnly, + AnyProcess, +}; + +template +static nsresult Constructor(nsISupports* aOuter, REFNSIID aIID, + void** aResult) { + *aResult = nullptr; + if (aOuter != nullptr) { + return NS_ERROR_NO_AGGREGATION; + } + + if (processRestriction == ProcessRestriction::ParentProcessOnly && + !XRE_IsParentProcess()) { + return NS_ERROR_NOT_AVAILABLE; + } + + if (!EnsureNSSInitializedChromeOrContent()) { + return NS_ERROR_FAILURE; + } + + if (threadRestriction == ThreadRestriction::MainThreadOnly && + !NS_IsMainThread()) { + return NS_ERROR_NOT_SAME_THREAD; + } + + return Instantiate(aIID, aResult); +} + +#define IMPL(type, ...) \ + template <> \ + nsresult NSSConstructor(nsISupports * aOuter, const nsIID& aIID, \ + void** aResult) { \ + return Constructor(aOuter, aIID, aResult); \ + } + +// Components that require main thread initialization could cause a deadlock +// in necko code (bug 1418752). To prevent it we initialize all such components +// on main thread in advance in net_EnsurePSMInit(). Update that function when +// new component with ThreadRestriction::MainThreadOnly is added. +IMPL(SecretDecoderRing, nullptr) +IMPL(nsPK11TokenDB, nullptr) +IMPL(PKCS11ModuleDB, nullptr) +IMPL(nsNSSCertificate, nullptr, ProcessRestriction::AnyProcess) +IMPL(nsNSSCertificateDB, nullptr) +#ifdef MOZ_XUL +IMPL(nsCertTree, nullptr) +#endif +IMPL(nsCryptoHash, nullptr, ProcessRestriction::AnyProcess) +IMPL(nsCryptoHMAC, nullptr, ProcessRestriction::AnyProcess) +IMPL(nsKeyObject, nullptr, ProcessRestriction::AnyProcess) +IMPL(nsKeyObjectFactory, nullptr, ProcessRestriction::AnyProcess) +IMPL(ContentSignatureVerifier, nullptr) +IMPL(nsRandomGenerator, nullptr, ProcessRestriction::AnyProcess) +IMPL(TransportSecurityInfo, nullptr, ProcessRestriction::AnyProcess) +IMPL(OSKeyStore, nullptr, ProcessRestriction::ParentProcessOnly, + ThreadRestriction::MainThreadOnly) +IMPL(OSReauthenticator, nullptr, ProcessRestriction::ParentProcessOnly, + ThreadRestriction::MainThreadOnly) +#undef IMPL + +} // namespace psm +} // namespace mozilla diff --git a/security/manager/ssl/nsNSSModule.h b/security/manager/ssl/nsNSSModule.h new file mode 100644 index 0000000000..1f2024f573 --- /dev/null +++ b/security/manager/ssl/nsNSSModule.h @@ -0,0 +1,23 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef nsNSSModule_h +#define nsNSSModule_h + +#include "nsID.h" + +class nsISupports; + +namespace mozilla { +namespace psm { +template +nsresult NSSConstructor(nsISupports* aOuter, const nsIID& aIID, + void** aInstancePtr); + +} +} // namespace mozilla + +#endif // nsNSSModule_h diff --git a/security/manager/ssl/nsNSSVersion.cpp b/security/manager/ssl/nsNSSVersion.cpp new file mode 100644 index 0000000000..4ad5046a96 --- /dev/null +++ b/security/manager/ssl/nsNSSVersion.cpp @@ -0,0 +1,78 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "nsNSSVersion.h" +#include "nsString.h" +#include "prinit.h" +#include "nss.h" +#include "nssutil.h" +#include "ssl.h" +#include "smime.h" + +NS_IMPL_ISUPPORTS(nsNSSVersion, nsINSSVersion) + +nsNSSVersion::nsNSSVersion() = default; + +nsNSSVersion::~nsNSSVersion() = default; + +NS_IMETHODIMP +nsNSSVersion::GetNSPR_Version(nsAString& v) { + v.AssignASCII(PR_GetVersion()); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSVersion::GetNSS_Version(nsAString& v) { + v.AssignASCII(NSS_GetVersion()); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSVersion::GetNSSUTIL_Version(nsAString& v) { + v.AssignASCII(NSSUTIL_GetVersion()); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSVersion::GetNSSSSL_Version(nsAString& v) { + v.AssignASCII(NSSSSL_GetVersion()); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSVersion::GetNSSSMIME_Version(nsAString& v) { + v.AssignASCII(NSSSMIME_GetVersion()); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSVersion::GetNSPR_MinVersion(nsAString& v) { + v.AssignLiteral(PR_VERSION); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSVersion::GetNSS_MinVersion(nsAString& v) { + v.AssignLiteral(NSS_VERSION); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSVersion::GetNSSUTIL_MinVersion(nsAString& v) { + v.AssignLiteral(NSSUTIL_VERSION); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSVersion::GetNSSSSL_MinVersion(nsAString& v) { + v.AssignLiteral(NSS_VERSION); + return NS_OK; +} + +NS_IMETHODIMP +nsNSSVersion::GetNSSSMIME_MinVersion(nsAString& v) { + v.AssignLiteral(NSS_VERSION); + return NS_OK; +} diff --git a/security/manager/ssl/nsNSSVersion.h b/security/manager/ssl/nsNSSVersion.h new file mode 100644 index 0000000000..de8dc15dd3 --- /dev/null +++ b/security/manager/ssl/nsNSSVersion.h @@ -0,0 +1,30 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef _NS_NSSVERSION_H_ +#define _NS_NSSVERSION_H_ + +#include "nsINSSVersion.h" +#include "mozilla/Attributes.h" + +class nsNSSVersion final : public nsINSSVersion { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSINSSVERSION + + nsNSSVersion(); + + private: + ~nsNSSVersion(); +}; + +#define NS_NSSVERSION_CID \ + { \ + 0x23ad3531, 0x11d2, 0x4e8e, { \ + 0x80, 0x5a, 0x6a, 0x75, 0x2e, 0x91, 0x68, 0x1a \ + } \ + } + +#endif diff --git a/security/manager/ssl/nsNTLMAuthModule.cpp b/security/manager/ssl/nsNTLMAuthModule.cpp new file mode 100644 index 0000000000..d3901c524b --- /dev/null +++ b/security/manager/ssl/nsNTLMAuthModule.cpp @@ -0,0 +1,1077 @@ +/* vim:set ts=2 sw=2 et cindent: */ +/* 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/. */ + +#include "nsNTLMAuthModule.h" + +#include + +#include "ScopedNSSTypes.h" +#include "md4.h" +#include "mozilla/Assertions.h" +#include "mozilla/Base64.h" +#include "mozilla/Casting.h" +#include "mozilla/CheckedInt.h" +#include "mozilla/EndianUtils.h" +#include "mozilla/Likely.h" +#include "mozilla/Logging.h" +#include "mozilla/Preferences.h" +#include "mozilla/Sprintf.h" +#include "mozilla/StaticPrefs_network.h" +#include "mozilla/Telemetry.h" +#include "nsCOMPtr.h" +#include "nsComponentManagerUtils.h" +#include "nsICryptoHMAC.h" +#include "nsICryptoHash.h" +#include "nsIKeyModule.h" +#include "nsKeyModule.h" +#include "nsNativeCharsetUtils.h" +#include "nsNetCID.h" +#include "nsUnicharUtils.h" +#include "pk11pub.h" +#include "prsystem.h" + +static mozilla::LazyLogModule sNTLMLog("NTLM"); + +#define LOG(x) MOZ_LOG(sNTLMLog, mozilla::LogLevel::Debug, x) +#define LOG_ENABLED() MOZ_LOG_TEST(sNTLMLog, mozilla::LogLevel::Debug) + +static void des_makekey(const uint8_t* raw, uint8_t* key); +static void des_encrypt(const uint8_t* key, const uint8_t* src, uint8_t* hash); + +//----------------------------------------------------------------------------- +// this file contains a cross-platform NTLM authentication implementation. it +// is based on documentation from: http://davenport.sourceforge.net/ntlm.html +//----------------------------------------------------------------------------- + +#define NTLM_NegotiateUnicode 0x00000001 +#define NTLM_NegotiateOEM 0x00000002 +#define NTLM_RequestTarget 0x00000004 +#define NTLM_Unknown1 0x00000008 +#define NTLM_NegotiateSign 0x00000010 +#define NTLM_NegotiateSeal 0x00000020 +#define NTLM_NegotiateDatagramStyle 0x00000040 +#define NTLM_NegotiateLanManagerKey 0x00000080 +#define NTLM_NegotiateNetware 0x00000100 +#define NTLM_NegotiateNTLMKey 0x00000200 +#define NTLM_Unknown2 0x00000400 +#define NTLM_Unknown3 0x00000800 +#define NTLM_NegotiateDomainSupplied 0x00001000 +#define NTLM_NegotiateWorkstationSupplied 0x00002000 +#define NTLM_NegotiateLocalCall 0x00004000 +#define NTLM_NegotiateAlwaysSign 0x00008000 +#define NTLM_TargetTypeDomain 0x00010000 +#define NTLM_TargetTypeServer 0x00020000 +#define NTLM_TargetTypeShare 0x00040000 +#define NTLM_NegotiateNTLM2Key 0x00080000 +#define NTLM_RequestInitResponse 0x00100000 +#define NTLM_RequestAcceptResponse 0x00200000 +#define NTLM_RequestNonNTSessionKey 0x00400000 +#define NTLM_NegotiateTargetInfo 0x00800000 +#define NTLM_Unknown4 0x01000000 +#define NTLM_Unknown5 0x02000000 +#define NTLM_Unknown6 0x04000000 +#define NTLM_Unknown7 0x08000000 +#define NTLM_Unknown8 0x10000000 +#define NTLM_Negotiate128 0x20000000 +#define NTLM_NegotiateKeyExchange 0x40000000 +#define NTLM_Negotiate56 0x80000000 + +// we send these flags with our type 1 message +#define NTLM_TYPE1_FLAGS \ + (NTLM_NegotiateUnicode | NTLM_NegotiateOEM | NTLM_RequestTarget | \ + NTLM_NegotiateNTLMKey | NTLM_NegotiateAlwaysSign | NTLM_NegotiateNTLM2Key) + +static const char NTLM_SIGNATURE[] = "NTLMSSP"; +static const char NTLM_TYPE1_MARKER[] = {0x01, 0x00, 0x00, 0x00}; +static const char NTLM_TYPE2_MARKER[] = {0x02, 0x00, 0x00, 0x00}; +static const char NTLM_TYPE3_MARKER[] = {0x03, 0x00, 0x00, 0x00}; + +#define NTLM_TYPE1_HEADER_LEN 32 +#define NTLM_TYPE2_HEADER_LEN 48 +#define NTLM_TYPE3_HEADER_LEN 64 + +/** + * We don't actually send a LM response, but we still have to send something in + * this spot + */ +#define LM_RESP_LEN 24 + +#define NTLM_CHAL_LEN 8 + +#define NTLM_HASH_LEN 16 +#define NTLMv2_HASH_LEN 16 +#define NTLM_RESP_LEN 24 +#define NTLMv2_RESP_LEN 16 +#define NTLMv2_BLOB1_LEN 28 + +//----------------------------------------------------------------------------- + +/** + * Prints a description of flags to the NSPR Log, if enabled. + */ +static void LogFlags(uint32_t flags) { + if (!LOG_ENABLED()) return; +#define TEST(_flag) \ + if (flags & NTLM_##_flag) \ + PR_LogPrint(" 0x%08x (" #_flag ")\n", NTLM_##_flag) + + TEST(NegotiateUnicode); + TEST(NegotiateOEM); + TEST(RequestTarget); + TEST(Unknown1); + TEST(NegotiateSign); + TEST(NegotiateSeal); + TEST(NegotiateDatagramStyle); + TEST(NegotiateLanManagerKey); + TEST(NegotiateNetware); + TEST(NegotiateNTLMKey); + TEST(Unknown2); + TEST(Unknown3); + TEST(NegotiateDomainSupplied); + TEST(NegotiateWorkstationSupplied); + TEST(NegotiateLocalCall); + TEST(NegotiateAlwaysSign); + TEST(TargetTypeDomain); + TEST(TargetTypeServer); + TEST(TargetTypeShare); + TEST(NegotiateNTLM2Key); + TEST(RequestInitResponse); + TEST(RequestAcceptResponse); + TEST(RequestNonNTSessionKey); + TEST(NegotiateTargetInfo); + TEST(Unknown4); + TEST(Unknown5); + TEST(Unknown6); + TEST(Unknown7); + TEST(Unknown8); + TEST(Negotiate128); + TEST(NegotiateKeyExchange); + TEST(Negotiate56); + +#undef TEST +} + +/** + * Prints a hexdump of buf to the NSPR Log, if enabled. + * @param tag Description of the data, will be printed in front of the data + * @param buf the data to print + * @param bufLen length of the data + */ +static void LogBuf(const char* tag, const uint8_t* buf, uint32_t bufLen) { + int i; + + if (!LOG_ENABLED()) return; + + PR_LogPrint("%s =\n", tag); + char line[80]; + while (bufLen > 0) { + int count = bufLen; + if (count > 8) count = 8; + + strcpy(line, " "); + for (i = 0; i < count; ++i) { + int len = strlen(line); + snprintf(line + len, sizeof(line) - len, "0x%02x ", int(buf[i])); + } + for (; i < 8; ++i) { + int len = strlen(line); + snprintf(line + len, sizeof(line) - len, " "); + } + + int len = strlen(line); + snprintf(line + len, sizeof(line) - len, " "); + for (i = 0; i < count; ++i) { + len = strlen(line); + if (isprint(buf[i])) + snprintf(line + len, sizeof(line) - len, "%c", buf[i]); + else + snprintf(line + len, sizeof(line) - len, "."); + } + PR_LogPrint("%s\n", line); + + bufLen -= count; + buf += count; + } +} + +/** + * Print base64-encoded token to the NSPR Log. + * @param name Description of the token, will be printed in front + * @param token The token to print + * @param tokenLen length of the data in token + */ +static void LogToken(const char* name, const void* token, uint32_t tokenLen) { + if (!LOG_ENABLED()) { + return; + } + + nsDependentCSubstring tokenString(static_cast(token), tokenLen); + nsAutoCString base64Token; + nsresult rv = mozilla::Base64Encode(tokenString, base64Token); + if (NS_FAILED(rv)) { + return; + } + + PR_LogPrint("%s: %s\n", name, base64Token.get()); +} + +//----------------------------------------------------------------------------- + +// byte order swapping +#define SWAP16(x) ((((x)&0xff) << 8) | (((x) >> 8) & 0xff)) +#define SWAP32(x) ((SWAP16((x)&0xffff) << 16) | (SWAP16((x) >> 16))) + +static void* WriteBytes(void* buf, const void* data, uint32_t dataLen) { + memcpy(buf, data, dataLen); + return (uint8_t*)buf + dataLen; +} + +static void* WriteDWORD(void* buf, uint32_t dword) { +#ifdef IS_BIG_ENDIAN + // NTLM uses little endian on the wire + dword = SWAP32(dword); +#endif + return WriteBytes(buf, &dword, sizeof(dword)); +} + +static void* WriteSecBuf(void* buf, uint16_t length, uint32_t offset) { +#ifdef IS_BIG_ENDIAN + length = SWAP16(length); + offset = SWAP32(offset); +#endif + buf = WriteBytes(buf, &length, sizeof(length)); + buf = WriteBytes(buf, &length, sizeof(length)); + buf = WriteBytes(buf, &offset, sizeof(offset)); + return buf; +} + +#ifdef IS_BIG_ENDIAN +/** + * WriteUnicodeLE copies a unicode string from one buffer to another. The + * resulting unicode string is in little-endian format. The input string is + * assumed to be in the native endianness of the local machine. It is safe + * to pass the same buffer as both input and output, which is a handy way to + * convert the unicode buffer to little-endian on big-endian platforms. + */ +static void* WriteUnicodeLE(void* buf, const char16_t* str, uint32_t strLen) { + // convert input string from BE to LE + uint8_t *cursor = (uint8_t*)buf, *input = (uint8_t*)str; + for (uint32_t i = 0; i < strLen; ++i, input += 2, cursor += 2) { + // allow for the case where |buf == str| + uint8_t temp = input[0]; + cursor[0] = input[1]; + cursor[1] = temp; + } + return buf; +} +#endif + +static uint16_t ReadUint16(const uint8_t*& buf) { + uint16_t x = ((uint16_t)buf[0]) | ((uint16_t)buf[1] << 8); + buf += sizeof(x); + return x; +} + +static uint32_t ReadUint32(const uint8_t*& buf) { + uint32_t x = ((uint32_t)buf[0]) | (((uint32_t)buf[1]) << 8) | + (((uint32_t)buf[2]) << 16) | (((uint32_t)buf[3]) << 24); + buf += sizeof(x); + return x; +} + +//----------------------------------------------------------------------------- + +static void ZapBuf(void* buf, size_t bufLen) { memset(buf, 0, bufLen); } + +static void ZapString(nsString& s) { ZapBuf(s.BeginWriting(), s.Length() * 2); } + +/** + * NTLM_Hash computes the NTLM hash of the given password. + * + * @param password + * null-terminated unicode password. + * @param hash + * 16-byte result buffer + */ +static void NTLM_Hash(const nsString& password, unsigned char* hash) { + uint32_t len = password.Length(); + uint8_t* passbuf; + +#ifdef IS_BIG_ENDIAN + passbuf = (uint8_t*)malloc(len * 2); + WriteUnicodeLE(passbuf, password.get(), len); +#else + passbuf = (uint8_t*)password.get(); +#endif + + md4sum(passbuf, len * 2, hash); + +#ifdef IS_BIG_ENDIAN + ZapBuf(passbuf, len * 2); + free(passbuf); +#endif +} + +//----------------------------------------------------------------------------- + +/** + * LM_Response generates the LM response given a 16-byte password hash and the + * challenge from the Type-2 message. + * + * @param hash + * 16-byte password hash + * @param challenge + * 8-byte challenge from Type-2 message + * @param response + * 24-byte buffer to contain the LM response upon return + */ +static void LM_Response(const uint8_t* hash, const uint8_t* challenge, + uint8_t* response) { + uint8_t keybytes[21], k1[8], k2[8], k3[8]; + + memcpy(keybytes, hash, 16); + ZapBuf(keybytes + 16, 5); + + des_makekey(keybytes, k1); + des_makekey(keybytes + 7, k2); + des_makekey(keybytes + 14, k3); + + des_encrypt(k1, challenge, response); + des_encrypt(k2, challenge, response + 8); + des_encrypt(k3, challenge, response + 16); +} + +//----------------------------------------------------------------------------- + +static nsresult GenerateType1Msg(void** outBuf, uint32_t* outLen) { + // + // verify that bufLen is sufficient + // + *outLen = NTLM_TYPE1_HEADER_LEN; + *outBuf = moz_xmalloc(*outLen); + + // + // write out type 1 msg + // + void* cursor = *outBuf; + + // 0 : signature + cursor = WriteBytes(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)); + + // 8 : marker + cursor = WriteBytes(cursor, NTLM_TYPE1_MARKER, sizeof(NTLM_TYPE1_MARKER)); + + // 12 : flags + cursor = WriteDWORD(cursor, NTLM_TYPE1_FLAGS); + + // + // NOTE: it is common for the domain and workstation fields to be empty. + // this is true of Win2k clients, and my guess is that there is + // little utility to sending these strings before the charset has + // been negotiated. we follow suite -- anyways, it doesn't hurt + // to save some bytes on the wire ;-) + // + + // 16 : supplied domain security buffer (empty) + cursor = WriteSecBuf(cursor, 0, 0); + + // 24 : supplied workstation security buffer (empty) + cursor = WriteSecBuf(cursor, 0, 0); + + return NS_OK; +} + +struct Type2Msg { + uint32_t flags; // NTLM_Xxx bitwise combination + uint8_t challenge[NTLM_CHAL_LEN]; // 8 byte challenge + const uint8_t* target; // target string (type depends on flags) + uint32_t targetLen; // target length in bytes + const uint8_t* + targetInfo; // target Attribute-Value pairs (DNS domain, et al) + uint32_t targetInfoLen; // target AV pairs length in bytes +}; + +static nsresult ParseType2Msg(const void* inBuf, uint32_t inLen, + Type2Msg* msg) { + // make sure inBuf is long enough to contain a meaningful type2 msg. + // + // 0 NTLMSSP Signature + // 8 NTLM Message Type + // 12 Target Name + // 20 Flags + // 24 Challenge + // 32 targetInfo + // 48 start of optional data blocks + // + if (inLen < NTLM_TYPE2_HEADER_LEN) return NS_ERROR_UNEXPECTED; + + auto cursor = static_cast(inBuf); + + // verify NTLMSSP signature + if (memcmp(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)) != 0) + return NS_ERROR_UNEXPECTED; + + cursor += sizeof(NTLM_SIGNATURE); + + // verify Type-2 marker + if (memcmp(cursor, NTLM_TYPE2_MARKER, sizeof(NTLM_TYPE2_MARKER)) != 0) + return NS_ERROR_UNEXPECTED; + + cursor += sizeof(NTLM_TYPE2_MARKER); + + // Read target name security buffer: ... + // ... read target length. + uint32_t targetLen = ReadUint16(cursor); + // ... skip next 16-bit "allocated space" value. + ReadUint16(cursor); + // ... read offset from inBuf. + uint32_t offset = ReadUint32(cursor); + mozilla::CheckedInt targetEnd = offset; + targetEnd += targetLen; + // Check the offset / length combo is in range of the input buffer, including + // integer overflow checking. + if (MOZ_LIKELY(targetEnd.isValid() && targetEnd.value() <= inLen)) { + msg->targetLen = targetLen; + msg->target = static_cast(inBuf) + offset; + } else { + // Do not error out, for (conservative) backward compatibility. + msg->targetLen = 0; + msg->target = nullptr; + } + + // read flags + msg->flags = ReadUint32(cursor); + + // read challenge + memcpy(msg->challenge, cursor, sizeof(msg->challenge)); + cursor += sizeof(msg->challenge); + + LOG(("NTLM type 2 message:\n")); + LogBuf("target", msg->target, msg->targetLen); + LogBuf("flags", + mozilla::BitwiseCast(&msg->flags), 4); + LogFlags(msg->flags); + LogBuf("challenge", msg->challenge, sizeof(msg->challenge)); + + // Read (and skip) the reserved field + ReadUint32(cursor); + ReadUint32(cursor); + // Read target name security buffer: ... + // ... read target length. + uint32_t targetInfoLen = ReadUint16(cursor); + // ... skip next 16-bit "allocated space" value. + ReadUint16(cursor); + // ... read offset from inBuf. + offset = ReadUint32(cursor); + mozilla::CheckedInt targetInfoEnd = offset; + targetInfoEnd += targetInfoLen; + // Check the offset / length combo is in range of the input buffer, including + // integer overflow checking. + if (MOZ_LIKELY(targetInfoEnd.isValid() && targetInfoEnd.value() <= inLen)) { + msg->targetInfoLen = targetInfoLen; + msg->targetInfo = static_cast(inBuf) + offset; + } else { + NS_ERROR("failed to get NTLMv2 target info"); + return NS_ERROR_UNEXPECTED; + } + + return NS_OK; +} + +static nsresult GenerateType3Msg(const nsString& domain, + const nsString& username, + const nsString& password, const void* inBuf, + uint32_t inLen, void** outBuf, + uint32_t* outLen) { + // inBuf contains Type-2 msg (the challenge) from server + MOZ_ASSERT(NS_IsMainThread()); + nsresult rv; + Type2Msg msg; + + rv = ParseType2Msg(inBuf, inLen, &msg); + if (NS_FAILED(rv)) return rv; + + bool unicode = (msg.flags & NTLM_NegotiateUnicode); + + // There is no negotiation for NTLMv2, so we just do it unless we are forced + // by explict user configuration to use the older DES-based cryptography. + bool ntlmv2 = + mozilla::StaticPrefs::network_auth_force_generic_ntlm_v1() == false; + + // temporary buffers for unicode strings +#ifdef IS_BIG_ENDIAN + nsAutoString ucsDomainBuf, ucsUserBuf; +#endif + nsAutoCString hostBuf; + nsAutoString ucsHostBuf; + // temporary buffers for oem strings + nsAutoCString oemDomainBuf, oemUserBuf, oemHostBuf; + // pointers and lengths for the string buffers; encoding is unicode if + // the "negotiate unicode" flag was set in the Type-2 message. + const void *domainPtr, *userPtr, *hostPtr; + uint32_t domainLen, userLen, hostLen; + + // This is for NTLM, for NTLMv2 we set the new full length once we know it + mozilla::CheckedInt ntlmRespLen = NTLM_RESP_LEN; + + // + // get domain name + // + if (unicode) { +#ifdef IS_BIG_ENDIAN + ucsDomainBuf = domain; + domainPtr = ucsDomainBuf.get(); + domainLen = ucsDomainBuf.Length() * 2; + WriteUnicodeLE(const_cast(domainPtr), + static_cast(domainPtr), + ucsDomainBuf.Length()); +#else + domainPtr = domain.get(); + domainLen = domain.Length() * 2; +#endif + } else { + NS_CopyUnicodeToNative(domain, oemDomainBuf); + domainPtr = oemDomainBuf.get(); + domainLen = oemDomainBuf.Length(); + } + + // + // get user name + // + if (unicode) { +#ifdef IS_BIG_ENDIAN + ucsUserBuf = username; + userPtr = ucsUserBuf.get(); + userLen = ucsUserBuf.Length() * 2; + WriteUnicodeLE(const_cast(userPtr), + static_cast(userPtr), ucsUserBuf.Length()); +#else + userPtr = username.get(); + userLen = username.Length() * 2; +#endif + } else { + NS_CopyUnicodeToNative(username, oemUserBuf); + userPtr = oemUserBuf.get(); + userLen = oemUserBuf.Length(); + } + + // + // get workstation name + // (do not use local machine's hostname after bug 1046421) + // + rv = mozilla::Preferences::GetCString("network.generic-ntlm-auth.workstation", + hostBuf); + if (NS_FAILED(rv)) { + return rv; + } + + if (unicode) { + CopyUTF8toUTF16(hostBuf, ucsHostBuf); + hostPtr = ucsHostBuf.get(); + hostLen = ucsHostBuf.Length() * 2; +#ifdef IS_BIG_ENDIAN + WriteUnicodeLE(const_cast(hostPtr), + static_cast(hostPtr), ucsHostBuf.Length()); +#endif + } else { + hostPtr = hostBuf.get(); + hostLen = hostBuf.Length(); + } + + // + // now that we have generated all of the strings, we can allocate outBuf. + // + // + // next, we compute the NTLM or NTLM2 responses. + // + uint8_t lmResp[LM_RESP_LEN]; + uint8_t ntlmResp[NTLM_RESP_LEN]; + uint8_t ntlmv2Resp[NTLMv2_RESP_LEN]; + uint8_t ntlmHash[NTLM_HASH_LEN]; + uint8_t ntlmv2_blob1[NTLMv2_BLOB1_LEN]; + if (ntlmv2) { + // NTLMv2 mode, the default + nsString userUpper, domainUpper; + nsAutoCString ntlmHashStr; + nsAutoCString ntlmv2HashStr; + nsAutoCString lmv2ResponseStr; + nsAutoCString ntlmv2ResponseStr; + + // temporary buffers for unicode strings + nsAutoString ucsDomainUpperBuf; + nsAutoString ucsUserUpperBuf; + const void* domainUpperPtr; + const void* userUpperPtr; + uint32_t domainUpperLen; + uint32_t userUpperLen; + + if (msg.targetInfoLen == 0) { + NS_ERROR("failed to get NTLMv2 target info, can not do NTLMv2"); + return NS_ERROR_UNEXPECTED; + } + + ToUpperCase(username, ucsUserUpperBuf); + userUpperPtr = ucsUserUpperBuf.get(); + userUpperLen = ucsUserUpperBuf.Length() * 2; +#ifdef IS_BIG_ENDIAN + WriteUnicodeLE(const_cast(userUpperPtr), + static_cast(userUpperPtr), + ucsUserUpperBuf.Length()); +#endif + ToUpperCase(domain, ucsDomainUpperBuf); + domainUpperPtr = ucsDomainUpperBuf.get(); + domainUpperLen = ucsDomainUpperBuf.Length() * 2; +#ifdef IS_BIG_ENDIAN + WriteUnicodeLE(const_cast(domainUpperPtr), + static_cast(domainUpperPtr), + ucsDomainUpperBuf.Length()); +#endif + + NTLM_Hash(password, ntlmHash); + ntlmHashStr = nsAutoCString( + mozilla::BitwiseCast(ntlmHash), + NTLM_HASH_LEN); + + nsCOMPtr keyFactory = + do_CreateInstance(NS_KEYMODULEOBJECTFACTORY_CONTRACTID, &rv); + + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr ntlmKey = + do_CreateInstance(NS_KEYMODULEOBJECT_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return rv; + } + + rv = keyFactory->KeyFromString(nsIKeyObject::HMAC, ntlmHashStr, + getter_AddRefs(ntlmKey)); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr hasher = + do_CreateInstance(NS_CRYPTO_HMAC_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Init(nsICryptoHMAC::MD5, ntlmKey); + if (NS_FAILED(rv)) { + return rv; + } + rv = + hasher->Update(static_cast(userUpperPtr), userUpperLen); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Update(static_cast(domainUpperPtr), + domainUpperLen); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Finish(false, ntlmv2HashStr); + if (NS_FAILED(rv)) { + return rv; + } + + uint8_t client_random[NTLM_CHAL_LEN]; + PK11_GenerateRandom(client_random, NTLM_CHAL_LEN); + + nsCOMPtr ntlmv2Key = + do_CreateInstance(NS_KEYMODULEOBJECT_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return rv; + } + + // Prepare the LMv2 response + rv = keyFactory->KeyFromString(nsIKeyObject::HMAC, ntlmv2HashStr, + getter_AddRefs(ntlmv2Key)); + if (NS_FAILED(rv)) { + return rv; + } + + rv = hasher->Init(nsICryptoHMAC::MD5, ntlmv2Key); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Update(msg.challenge, NTLM_CHAL_LEN); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Update(client_random, NTLM_CHAL_LEN); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Finish(false, lmv2ResponseStr); + if (NS_FAILED(rv)) { + return rv; + } + + if (lmv2ResponseStr.Length() != NTLMv2_HASH_LEN) { + return NS_ERROR_UNEXPECTED; + } + + memcpy(lmResp, lmv2ResponseStr.get(), NTLMv2_HASH_LEN); + memcpy(lmResp + NTLMv2_HASH_LEN, client_random, NTLM_CHAL_LEN); + + memset(ntlmv2_blob1, 0, NTLMv2_BLOB1_LEN); + + time_t unix_time; + uint64_t nt_time = time(&unix_time); + nt_time += 11644473600LL; // Number of seconds betwen 1601 and 1970 + nt_time *= 1000 * 1000 * 10; // Convert seconds to 100 ns units + + ntlmv2_blob1[0] = 1; + ntlmv2_blob1[1] = 1; + mozilla::LittleEndian::writeUint64(&ntlmv2_blob1[8], nt_time); + PK11_GenerateRandom(&ntlmv2_blob1[16], NTLM_CHAL_LEN); + + rv = hasher->Init(nsICryptoHMAC::MD5, ntlmv2Key); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Update(msg.challenge, NTLM_CHAL_LEN); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Update(ntlmv2_blob1, NTLMv2_BLOB1_LEN); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Update(msg.targetInfo, msg.targetInfoLen); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Finish(false, ntlmv2ResponseStr); + if (NS_FAILED(rv)) { + return rv; + } + + if (ntlmv2ResponseStr.Length() != NTLMv2_RESP_LEN) { + return NS_ERROR_UNEXPECTED; + } + + memcpy(ntlmv2Resp, ntlmv2ResponseStr.get(), NTLMv2_RESP_LEN); + ntlmRespLen = NTLMv2_RESP_LEN + NTLMv2_BLOB1_LEN; + ntlmRespLen += msg.targetInfoLen; + if (!ntlmRespLen.isValid()) { + NS_ERROR("failed to do NTLMv2: integer overflow?!?"); + return NS_ERROR_UNEXPECTED; + } + } else if (msg.flags & NTLM_NegotiateNTLM2Key) { + // compute NTLM2 session response + nsCString sessionHashString; + + PK11_GenerateRandom(lmResp, NTLM_CHAL_LEN); + memset(lmResp + NTLM_CHAL_LEN, 0, LM_RESP_LEN - NTLM_CHAL_LEN); + + nsCOMPtr hasher = + do_CreateInstance(NS_CRYPTO_HASH_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Init(nsICryptoHash::MD5); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Update(msg.challenge, NTLM_CHAL_LEN); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Update(lmResp, NTLM_CHAL_LEN); + if (NS_FAILED(rv)) { + return rv; + } + rv = hasher->Finish(false, sessionHashString); + if (NS_FAILED(rv)) { + return rv; + } + + auto sessionHash = mozilla::BitwiseCast( + sessionHashString.get()); + + LogBuf("NTLM2 effective key: ", sessionHash, 8); + + NTLM_Hash(password, ntlmHash); + LM_Response(ntlmHash, sessionHash, ntlmResp); + } else { + NTLM_Hash(password, ntlmHash); + LM_Response(ntlmHash, msg.challenge, ntlmResp); + + // According to http://davenport.sourceforge.net/ntlm.html#ntlmVersion2, + // the correct way to not send the LM hash is to send the NTLM hash twice + // in both the LM and NTLM response fields. + LM_Response(ntlmHash, msg.challenge, lmResp); + } + + mozilla::CheckedInt totalLen = NTLM_TYPE3_HEADER_LEN + LM_RESP_LEN; + totalLen += hostLen; + totalLen += domainLen; + totalLen += userLen; + totalLen += ntlmRespLen.value(); + + if (!totalLen.isValid()) { + NS_ERROR("failed preparing to allocate NTLM response: integer overflow?!?"); + return NS_ERROR_FAILURE; + } + *outBuf = moz_xmalloc(totalLen.value()); + *outLen = totalLen.value(); + + // + // finally, we assemble the Type-3 msg :-) + // + void* cursor = *outBuf; + mozilla::CheckedInt offset; + + // 0 : signature + cursor = WriteBytes(cursor, NTLM_SIGNATURE, sizeof(NTLM_SIGNATURE)); + + // 8 : marker + cursor = WriteBytes(cursor, NTLM_TYPE3_MARKER, sizeof(NTLM_TYPE3_MARKER)); + + // 12 : LM response sec buf + offset = NTLM_TYPE3_HEADER_LEN; + offset += domainLen; + offset += userLen; + offset += hostLen; + if (!offset.isValid()) { + NS_ERROR("failed preparing to write NTLM response: integer overflow?!?"); + return NS_ERROR_UNEXPECTED; + } + cursor = WriteSecBuf(cursor, LM_RESP_LEN, offset.value()); + memcpy(static_cast(*outBuf) + offset.value(), lmResp, LM_RESP_LEN); + + // 20 : NTLM or NTLMv2 response sec buf + offset += LM_RESP_LEN; + if (!offset.isValid()) { + NS_ERROR("failed preparing to write NTLM response: integer overflow?!?"); + return NS_ERROR_UNEXPECTED; + } + cursor = WriteSecBuf(cursor, ntlmRespLen.value(), offset.value()); + if (ntlmv2) { + memcpy(static_cast(*outBuf) + offset.value(), ntlmv2Resp, + NTLMv2_RESP_LEN); + offset += NTLMv2_RESP_LEN; + if (!offset.isValid()) { + NS_ERROR("failed preparing to write NTLM response: integer overflow?!?"); + return NS_ERROR_UNEXPECTED; + } + memcpy(static_cast(*outBuf) + offset.value(), ntlmv2_blob1, + NTLMv2_BLOB1_LEN); + offset += NTLMv2_BLOB1_LEN; + if (!offset.isValid()) { + NS_ERROR("failed preparing to write NTLM response: integer overflow?!?"); + return NS_ERROR_UNEXPECTED; + } + memcpy(static_cast(*outBuf) + offset.value(), msg.targetInfo, + msg.targetInfoLen); + } else { + memcpy(static_cast(*outBuf) + offset.value(), ntlmResp, + NTLM_RESP_LEN); + } + // 28 : domain name sec buf + offset = NTLM_TYPE3_HEADER_LEN; + cursor = WriteSecBuf(cursor, domainLen, offset.value()); + memcpy(static_cast(*outBuf) + offset.value(), domainPtr, domainLen); + + // 36 : user name sec buf + offset += domainLen; + if (!offset.isValid()) { + NS_ERROR("failed preparing to write NTLM response: integer overflow?!?"); + return NS_ERROR_UNEXPECTED; + } + cursor = WriteSecBuf(cursor, userLen, offset.value()); + memcpy(static_cast(*outBuf) + offset.value(), userPtr, userLen); + + // 44 : workstation (host) name sec buf + offset += userLen; + if (!offset.isValid()) { + NS_ERROR("failed preparing to write NTLM response: integer overflow?!?"); + return NS_ERROR_UNEXPECTED; + } + cursor = WriteSecBuf(cursor, hostLen, offset.value()); + memcpy(static_cast(*outBuf) + offset.value(), hostPtr, hostLen); + + // 52 : session key sec buf (not used) + cursor = WriteSecBuf(cursor, 0, 0); + + // 60 : negotiated flags + cursor = WriteDWORD(cursor, msg.flags & NTLM_TYPE1_FLAGS); + + return NS_OK; +} + +//----------------------------------------------------------------------------- + +NS_IMPL_ISUPPORTS(nsNTLMAuthModule, nsIAuthModule) + +nsNTLMAuthModule::~nsNTLMAuthModule() { ZapString(mPassword); } + +nsresult nsNTLMAuthModule::InitTest() { + // disable NTLM authentication when FIPS mode is enabled. + return PK11_IsFIPS() ? NS_ERROR_NOT_AVAILABLE : NS_OK; +} + +NS_IMETHODIMP +nsNTLMAuthModule::Init(const char* /*serviceName*/, uint32_t serviceFlags, + const char16_t* domain, const char16_t* username, + const char16_t* password) { + MOZ_ASSERT((serviceFlags & ~nsIAuthModule::REQ_PROXY_AUTH) == + nsIAuthModule::REQ_DEFAULT, + "Unexpected service flags"); + + mDomain = domain; + mUsername = username; + mPassword = password; + mNTLMNegotiateSent = false; + + static bool sTelemetrySent = false; + if (!sTelemetrySent) { + mozilla::Telemetry::Accumulate(mozilla::Telemetry::NTLM_MODULE_USED_2, + serviceFlags & nsIAuthModule::REQ_PROXY_AUTH + ? NTLM_MODULE_GENERIC_PROXY + : NTLM_MODULE_GENERIC_DIRECT); + sTelemetrySent = true; + } + + return NS_OK; +} + +NS_IMETHODIMP +nsNTLMAuthModule::GetNextToken(const void* inToken, uint32_t inTokenLen, + void** outToken, uint32_t* outTokenLen) { + nsresult rv; + + // disable NTLM authentication when FIPS mode is enabled. + if (PK11_IsFIPS()) { + return NS_ERROR_NOT_AVAILABLE; + } + + if (mNTLMNegotiateSent) { + // if inToken is non-null, and we have sent the NTLMSSP_NEGOTIATE (type 1), + // then the NTLMSSP_CHALLENGE (type 2) is expected + if (inToken) { + LogToken("in-token", inToken, inTokenLen); + // Now generate the NTLMSSP_AUTH (type 3) + rv = GenerateType3Msg(mDomain, mUsername, mPassword, inToken, inTokenLen, + outToken, outTokenLen); + } else { + LOG( + ("NTLMSSP_NEGOTIATE already sent and presumably " + "rejected by the server, refusing to send another")); + rv = NS_ERROR_UNEXPECTED; + } + } else { + if (inToken) { + LOG(("NTLMSSP_NEGOTIATE not sent but NTLM reply already received?!?")); + rv = NS_ERROR_UNEXPECTED; + } else { + rv = GenerateType1Msg(outToken, outTokenLen); + if (NS_SUCCEEDED(rv)) { + mNTLMNegotiateSent = true; + } + } + } + + if (NS_SUCCEEDED(rv)) LogToken("out-token", *outToken, *outTokenLen); + + return rv; +} + +NS_IMETHODIMP +nsNTLMAuthModule::Unwrap(const void* inToken, uint32_t inTokenLen, + void** outToken, uint32_t* outTokenLen) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +NS_IMETHODIMP +nsNTLMAuthModule::Wrap(const void* inToken, uint32_t inTokenLen, + bool confidential, void** outToken, + uint32_t* outTokenLen) { + return NS_ERROR_NOT_IMPLEMENTED; +} + +//----------------------------------------------------------------------------- +// DES support code + +// set odd parity bit (in least significant bit position) +static uint8_t des_setkeyparity(uint8_t x) { + if ((((x >> 7) ^ (x >> 6) ^ (x >> 5) ^ (x >> 4) ^ (x >> 3) ^ (x >> 2) ^ + (x >> 1)) & + 0x01) == 0) + x |= 0x01; + else + x &= 0xfe; + return x; +} + +// build 64-bit des key from 56-bit raw key +static void des_makekey(const uint8_t* raw, uint8_t* key) { + key[0] = des_setkeyparity(raw[0]); + key[1] = des_setkeyparity((raw[0] << 7) | (raw[1] >> 1)); + key[2] = des_setkeyparity((raw[1] << 6) | (raw[2] >> 2)); + key[3] = des_setkeyparity((raw[2] << 5) | (raw[3] >> 3)); + key[4] = des_setkeyparity((raw[3] << 4) | (raw[4] >> 4)); + key[5] = des_setkeyparity((raw[4] << 3) | (raw[5] >> 5)); + key[6] = des_setkeyparity((raw[5] << 2) | (raw[6] >> 6)); + key[7] = des_setkeyparity((raw[6] << 1)); +} + +// run des encryption algorithm (using NSS) +static void des_encrypt(const uint8_t* key, const uint8_t* src, uint8_t* hash) { + CK_MECHANISM_TYPE cipherMech = CKM_DES_ECB; + PK11SymKey* symkey = nullptr; + PK11Context* ctxt = nullptr; + SECItem keyItem; + mozilla::UniqueSECItem param; + SECStatus rv; + unsigned int n; + + mozilla::UniquePK11SlotInfo slot(PK11_GetBestSlot(cipherMech, nullptr)); + if (!slot) { + NS_ERROR("no slot"); + goto done; + } + + keyItem.data = const_cast(key); + keyItem.len = 8; + symkey = PK11_ImportSymKey(slot.get(), cipherMech, PK11_OriginUnwrap, + CKA_ENCRYPT, &keyItem, nullptr); + if (!symkey) { + NS_ERROR("no symkey"); + goto done; + } + + // no initialization vector required + param = mozilla::UniqueSECItem(PK11_ParamFromIV(cipherMech, nullptr)); + if (!param) { + NS_ERROR("no param"); + goto done; + } + + ctxt = + PK11_CreateContextBySymKey(cipherMech, CKA_ENCRYPT, symkey, param.get()); + if (!ctxt) { + NS_ERROR("no context"); + goto done; + } + + rv = PK11_CipherOp(ctxt, hash, (int*)&n, 8, (uint8_t*)src, 8); + if (rv != SECSuccess) { + NS_ERROR("des failure"); + goto done; + } + + rv = PK11_DigestFinal(ctxt, hash + 8, &n, 0); + if (rv != SECSuccess) { + NS_ERROR("des failure"); + goto done; + } + +done: + if (ctxt) PK11_DestroyContext(ctxt, true); + if (symkey) PK11_FreeSymKey(symkey); +} diff --git a/security/manager/ssl/nsNTLMAuthModule.h b/security/manager/ssl/nsNTLMAuthModule.h new file mode 100644 index 0000000000..25a96a09d8 --- /dev/null +++ b/security/manager/ssl/nsNTLMAuthModule.h @@ -0,0 +1,33 @@ +/* vim:set ts=2 sw=2 et cindent: */ +/* 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/. */ + +#ifndef nsNTLMAuthModule_h__ +#define nsNTLMAuthModule_h__ + +#include "nsIAuthModule.h" +#include "nsString.h" + +class nsNTLMAuthModule : public nsIAuthModule { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIAUTHMODULE + + nsNTLMAuthModule() : mNTLMNegotiateSent(false) {} + + nsresult InitTest(); + + static void SetSendLM(bool sendLM); + + protected: + virtual ~nsNTLMAuthModule(); + + private: + nsString mDomain; + nsString mUsername; + nsString mPassword; + bool mNTLMNegotiateSent; +}; + +#endif // nsNTLMAuthModule_h__ diff --git a/security/manager/ssl/nsPK11TokenDB.cpp b/security/manager/ssl/nsPK11TokenDB.cpp new file mode 100644 index 0000000000..58788140d1 --- /dev/null +++ b/security/manager/ssl/nsPK11TokenDB.cpp @@ -0,0 +1,286 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ +#include "nsPK11TokenDB.h" + +#include + +#include "ScopedNSSTypes.h" +#include "mozilla/Casting.h" +#include "mozilla/Unused.h" +#include "nsISupports.h" +#include "nsNSSCertHelper.h" +#include "nsNSSComponent.h" +#include "nsPromiseFlatString.h" +#include "nsReadableUtils.h" +#include "nsServiceManagerUtils.h" +#include "prerror.h" +#include "secerr.h" + +extern mozilla::LazyLogModule gPIPNSSLog; + +NS_IMPL_ISUPPORTS(nsPK11Token, nsIPK11Token) + +nsPK11Token::nsPK11Token(PK11SlotInfo* slot) : mUIContext(new PipUIContext()) { + MOZ_ASSERT(slot); + mSlot.reset(PK11_ReferenceSlot(slot)); + mIsInternalCryptoToken = + PK11_IsInternal(mSlot.get()) && !PK11_IsInternalKeySlot(mSlot.get()); + mIsInternalKeyToken = PK11_IsInternalKeySlot(mSlot.get()); + mSeries = PK11_GetSlotSeries(slot); + mozilla::Unused << refreshTokenInfo(); +} + +nsresult nsPK11Token::refreshTokenInfo() { + if (mIsInternalCryptoToken) { + nsresult rv; + if (PK11_IsFIPS()) { + rv = GetPIPNSSBundleString("Fips140TokenDescription", mTokenName); + } else { + rv = GetPIPNSSBundleString("TokenDescription", mTokenName); + } + if (NS_FAILED(rv)) { + return rv; + } + } else if (mIsInternalKeyToken) { + nsresult rv = GetPIPNSSBundleString("PrivateTokenDescription", mTokenName); + if (NS_FAILED(rv)) { + return rv; + } + } else { + mTokenName.Assign(PK11_GetTokenName(mSlot.get())); + } + + CK_TOKEN_INFO tokInfo; + nsresult rv = mozilla::MapSECStatus(PK11_GetTokenInfo(mSlot.get(), &tokInfo)); + if (NS_FAILED(rv)) { + return rv; + } + + // Set the Manufacturer field + if (mIsInternalCryptoToken || mIsInternalKeyToken) { + rv = GetPIPNSSBundleString("ManufacturerID", mTokenManufacturerID); + if (NS_FAILED(rv)) { + return rv; + } + } else { + const char* ccManID = + mozilla::BitwiseCast(tokInfo.manufacturerID); + mTokenManufacturerID.Assign( + ccManID, strnlen(ccManID, sizeof(tokInfo.manufacturerID))); + mTokenManufacturerID.Trim(" ", false, true); + } + + // Set the Hardware Version field + mTokenHWVersion.Truncate(); + mTokenHWVersion.AppendInt(tokInfo.hardwareVersion.major); + mTokenHWVersion.Append('.'); + mTokenHWVersion.AppendInt(tokInfo.hardwareVersion.minor); + + // Set the Firmware Version field + mTokenFWVersion.Truncate(); + mTokenFWVersion.AppendInt(tokInfo.firmwareVersion.major); + mTokenFWVersion.Append('.'); + mTokenFWVersion.AppendInt(tokInfo.firmwareVersion.minor); + + // Set the Serial Number field + const char* ccSerial = + mozilla::BitwiseCast(tokInfo.serialNumber); + mTokenSerialNum.Assign(ccSerial, + strnlen(ccSerial, sizeof(tokInfo.serialNumber))); + mTokenSerialNum.Trim(" ", false, true); + + return NS_OK; +} + +nsresult nsPK11Token::GetAttributeHelper(const nsACString& attribute, + /*out*/ nsACString& xpcomOutParam) { + // Handle removals/insertions. + if (PK11_GetSlotSeries(mSlot.get()) != mSeries) { + nsresult rv = refreshTokenInfo(); + if (NS_FAILED(rv)) { + return rv; + } + } + + xpcomOutParam = attribute; + return NS_OK; +} + +NS_IMETHODIMP +nsPK11Token::GetTokenName(/*out*/ nsACString& tokenName) { + return GetAttributeHelper(mTokenName, tokenName); +} + +NS_IMETHODIMP +nsPK11Token::GetIsInternalKeyToken(/*out*/ bool* _retval) { + NS_ENSURE_ARG_POINTER(_retval); + *_retval = mIsInternalKeyToken; + return NS_OK; +} + +NS_IMETHODIMP +nsPK11Token::GetTokenManID(/*out*/ nsACString& tokenManufacturerID) { + return GetAttributeHelper(mTokenManufacturerID, tokenManufacturerID); +} + +NS_IMETHODIMP +nsPK11Token::GetTokenHWVersion(/*out*/ nsACString& tokenHWVersion) { + return GetAttributeHelper(mTokenHWVersion, tokenHWVersion); +} + +NS_IMETHODIMP +nsPK11Token::GetTokenFWVersion(/*out*/ nsACString& tokenFWVersion) { + return GetAttributeHelper(mTokenFWVersion, tokenFWVersion); +} + +NS_IMETHODIMP +nsPK11Token::GetTokenSerialNumber(/*out*/ nsACString& tokenSerialNum) { + return GetAttributeHelper(mTokenSerialNum, tokenSerialNum); +} + +NS_IMETHODIMP +nsPK11Token::IsLoggedIn(bool* _retval) { + NS_ENSURE_ARG_POINTER(_retval); + *_retval = PK11_IsLoggedIn(mSlot.get(), 0); + return NS_OK; +} + +NS_IMETHODIMP +nsPK11Token::Login(bool force) { + nsresult rv; + bool test; + rv = this->NeedsLogin(&test); + if (NS_FAILED(rv)) return rv; + if (test && force) { + rv = this->LogoutSimple(); + if (NS_FAILED(rv)) return rv; + } + rv = setPassword(mSlot.get(), mUIContext); + if (NS_FAILED(rv)) return rv; + + return mozilla::MapSECStatus( + PK11_Authenticate(mSlot.get(), true, mUIContext)); +} + +NS_IMETHODIMP +nsPK11Token::LogoutSimple() { + // PK11_Logout() can fail if the user wasn't logged in beforehand. We want + // this method to succeed even in this case, so we ignore the return value. + mozilla::Unused << PK11_Logout(mSlot.get()); + return NS_OK; +} + +NS_IMETHODIMP +nsPK11Token::LogoutAndDropAuthenticatedResources() { + static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); + + nsresult rv = LogoutSimple(); + + if (NS_FAILED(rv)) return rv; + + nsCOMPtr nssComponent(do_GetService(kNSSComponentCID, &rv)); + if (NS_FAILED(rv)) return rv; + + return nssComponent->LogoutAuthenticatedPK11(); +} + +NS_IMETHODIMP +nsPK11Token::Reset() { + return mozilla::MapSECStatus(PK11_ResetToken(mSlot.get(), nullptr)); +} + +NS_IMETHODIMP +nsPK11Token::GetNeedsUserInit(bool* aNeedsUserInit) { + NS_ENSURE_ARG_POINTER(aNeedsUserInit); + *aNeedsUserInit = PK11_NeedUserInit(mSlot.get()); + return NS_OK; +} + +NS_IMETHODIMP +nsPK11Token::CheckPassword(const nsACString& password, bool* _retval) { + NS_ENSURE_ARG_POINTER(_retval); + SECStatus srv = + PK11_CheckUserPassword(mSlot.get(), PromiseFlatCString(password).get()); + if (srv != SECSuccess) { + *_retval = false; + PRErrorCode error = PR_GetError(); + if (error != SEC_ERROR_BAD_PASSWORD) { + /* something really bad happened - throw an exception */ + return mozilla::psm::GetXPCOMFromNSSError(error); + } + } else { + *_retval = true; + } + return NS_OK; +} + +NS_IMETHODIMP +nsPK11Token::InitPassword(const nsACString& initialPassword) { + const nsCString& passwordCStr = PromiseFlatCString(initialPassword); + // PSM initializes the sqlite-backed softoken with an empty password. The + // implementation considers this not to be a password (GetHasPassword returns + // false), but we can't actually call PK11_InitPin again. Instead, we call + // PK11_ChangePW with the empty password. + bool hasPassword; + nsresult rv = GetHasPassword(&hasPassword); + if (NS_FAILED(rv)) { + return rv; + } + if (!PK11_NeedUserInit(mSlot.get()) && !hasPassword) { + return mozilla::MapSECStatus( + PK11_ChangePW(mSlot.get(), "", passwordCStr.get())); + } + return mozilla::MapSECStatus( + PK11_InitPin(mSlot.get(), "", passwordCStr.get())); +} + +NS_IMETHODIMP +nsPK11Token::ChangePassword(const nsACString& oldPassword, + const nsACString& newPassword) { + // PK11_ChangePW() has different semantics for the empty string and for + // nullptr. In order to support this difference, we need to check IsVoid() to + // find out if our caller supplied null/undefined args or just empty strings. + // See Bug 447589. + return mozilla::MapSECStatus(PK11_ChangePW( + mSlot.get(), + oldPassword.IsVoid() ? nullptr : PromiseFlatCString(oldPassword).get(), + newPassword.IsVoid() ? nullptr : PromiseFlatCString(newPassword).get())); +} + +NS_IMETHODIMP +nsPK11Token::GetHasPassword(bool* hasPassword) { + NS_ENSURE_ARG_POINTER(hasPassword); + // PK11_NeedLogin returns true if the token is currently configured to require + // the user to log in (whether or not the user is actually logged in makes no + // difference). + *hasPassword = PK11_NeedLogin(mSlot.get()) && !PK11_NeedUserInit(mSlot.get()); + return NS_OK; +} + +NS_IMETHODIMP +nsPK11Token::NeedsLogin(bool* _retval) { + NS_ENSURE_ARG_POINTER(_retval); + *_retval = PK11_NeedLogin(mSlot.get()); + return NS_OK; +} + +/*=========================================================*/ + +NS_IMPL_ISUPPORTS(nsPK11TokenDB, nsIPK11TokenDB) + +NS_IMETHODIMP +nsPK11TokenDB::GetInternalKeyToken(nsIPK11Token** _retval) { + NS_ENSURE_ARG_POINTER(_retval); + mozilla::UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr token = new nsPK11Token(slot.get()); + token.forget(_retval); + + return NS_OK; +} diff --git a/security/manager/ssl/nsPK11TokenDB.h b/security/manager/ssl/nsPK11TokenDB.h new file mode 100644 index 0000000000..36f54354ad --- /dev/null +++ b/security/manager/ssl/nsPK11TokenDB.h @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef nsPK11TokenDB_h +#define nsPK11TokenDB_h + +#include "nsCOMPtr.h" +#include "nsIPK11Token.h" +#include "nsIPK11TokenDB.h" +#include "nsISupports.h" +#include "nsNSSHelper.h" +#include "nsString.h" +#include "pk11func.h" +#include "ScopedNSSTypes.h" + +class nsPK11Token : public nsIPK11Token { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPK11TOKEN + + explicit nsPK11Token(PK11SlotInfo* slot); + + protected: + virtual ~nsPK11Token() = default; + + private: + friend class nsPK11TokenDB; + nsresult refreshTokenInfo(); + + nsCString mTokenName; + nsCString mTokenManufacturerID; + nsCString mTokenHWVersion; + nsCString mTokenFWVersion; + nsCString mTokenSerialNum; + mozilla::UniquePK11SlotInfo mSlot; + // True if this is the "PKCS#11 token" that provides cryptographic functions. + bool mIsInternalCryptoToken; + // True if this is the "PKCS#11 token" where private keys are stored. + bool mIsInternalKeyToken; + int mSeries; + nsCOMPtr mUIContext; + nsresult GetAttributeHelper(const nsACString& attribute, + /*out*/ nsACString& xpcomOutParam); +}; + +class nsPK11TokenDB : public nsIPK11TokenDB { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPK11TOKENDB + + nsPK11TokenDB() = default; + + protected: + virtual ~nsPK11TokenDB() = default; +}; + +#define NS_PK11TOKENDB_CID \ + { \ + 0xb084a2ce, 0x1dd1, 0x11b2, { \ + 0xbf, 0x10, 0x83, 0x24, 0xf8, 0xe0, 0x65, 0xcc \ + } \ + } + +#endif // nsPK11TokenDB_h diff --git a/security/manager/ssl/nsPKCS11Slot.cpp b/security/manager/ssl/nsPKCS11Slot.cpp new file mode 100644 index 0000000000..a39b8e424e --- /dev/null +++ b/security/manager/ssl/nsPKCS11Slot.cpp @@ -0,0 +1,276 @@ +/* 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/. */ + +#include "nsPKCS11Slot.h" + +#include + +#include "mozilla/Casting.h" +#include "mozilla/Logging.h" +#include "mozilla/Telemetry.h" +#include "mozilla/Unused.h" +#include "nsCOMPtr.h" +#include "nsIMutableArray.h" +#include "nsNSSCertHelper.h" +#include "nsNSSComponent.h" +#include "nsPK11TokenDB.h" +#include "nsPromiseFlatString.h" +#include "secmod.h" + +using mozilla::LogLevel; + +extern mozilla::LazyLogModule gPIPNSSLog; + +NS_IMPL_ISUPPORTS(nsPKCS11Slot, nsIPKCS11Slot) + +nsPKCS11Slot::nsPKCS11Slot(PK11SlotInfo* slot) { + MOZ_ASSERT(slot); + mSlot.reset(PK11_ReferenceSlot(slot)); + mIsInternalCryptoSlot = + PK11_IsInternal(mSlot.get()) && !PK11_IsInternalKeySlot(mSlot.get()); + mIsInternalKeySlot = PK11_IsInternalKeySlot(mSlot.get()); + mSeries = PK11_GetSlotSeries(slot); + mozilla::Unused << refreshSlotInfo(); +} + +nsresult nsPKCS11Slot::refreshSlotInfo() { + CK_SLOT_INFO slotInfo; + nsresult rv = mozilla::MapSECStatus(PK11_GetSlotInfo(mSlot.get(), &slotInfo)); + if (NS_FAILED(rv)) { + return rv; + } + + // Set the Description field + if (mIsInternalCryptoSlot) { + nsresult rv; + if (PK11_IsFIPS()) { + rv = GetPIPNSSBundleString("Fips140SlotDescription", mSlotDesc); + } else { + rv = GetPIPNSSBundleString("SlotDescription", mSlotDesc); + } + if (NS_FAILED(rv)) { + return rv; + } + } else if (mIsInternalKeySlot) { + rv = GetPIPNSSBundleString("PrivateSlotDescription", mSlotDesc); + if (NS_FAILED(rv)) { + return rv; + } + } else { + const char* ccDesc = + mozilla::BitwiseCast(slotInfo.slotDescription); + mSlotDesc.Assign(ccDesc, strnlen(ccDesc, sizeof(slotInfo.slotDescription))); + mSlotDesc.Trim(" ", false, true); + } + + // Set the Manufacturer field + if (mIsInternalCryptoSlot || mIsInternalKeySlot) { + rv = GetPIPNSSBundleString("ManufacturerID", mSlotManufacturerID); + if (NS_FAILED(rv)) { + return rv; + } + } else { + const char* ccManID = + mozilla::BitwiseCast(slotInfo.manufacturerID); + mSlotManufacturerID.Assign( + ccManID, strnlen(ccManID, sizeof(slotInfo.manufacturerID))); + mSlotManufacturerID.Trim(" ", false, true); + } + + // Set the Hardware Version field + mSlotHWVersion.Truncate(); + mSlotHWVersion.AppendInt(slotInfo.hardwareVersion.major); + mSlotHWVersion.Append('.'); + mSlotHWVersion.AppendInt(slotInfo.hardwareVersion.minor); + + // Set the Firmware Version field + mSlotFWVersion.Truncate(); + mSlotFWVersion.AppendInt(slotInfo.firmwareVersion.major); + mSlotFWVersion.Append('.'); + mSlotFWVersion.AppendInt(slotInfo.firmwareVersion.minor); + + return NS_OK; +} + +nsresult nsPKCS11Slot::GetAttributeHelper(const nsACString& attribute, + /*out*/ nsACString& xpcomOutParam) { + if (PK11_GetSlotSeries(mSlot.get()) != mSeries) { + nsresult rv = refreshSlotInfo(); + if (NS_FAILED(rv)) { + return rv; + } + } + + xpcomOutParam = attribute; + return NS_OK; +} + +NS_IMETHODIMP +nsPKCS11Slot::GetName(/*out*/ nsACString& name) { + if (mIsInternalCryptoSlot) { + if (PK11_IsFIPS()) { + return GetPIPNSSBundleString("Fips140TokenDescription", name); + } + return GetPIPNSSBundleString("TokenDescription", name); + } + if (mIsInternalKeySlot) { + return GetPIPNSSBundleString("PrivateTokenDescription", name); + } + name.Assign(PK11_GetSlotName(mSlot.get())); + + return NS_OK; +} + +NS_IMETHODIMP +nsPKCS11Slot::GetDesc(/*out*/ nsACString& desc) { + return GetAttributeHelper(mSlotDesc, desc); +} + +NS_IMETHODIMP +nsPKCS11Slot::GetManID(/*out*/ nsACString& manufacturerID) { + return GetAttributeHelper(mSlotManufacturerID, manufacturerID); +} + +NS_IMETHODIMP +nsPKCS11Slot::GetHWVersion(/*out*/ nsACString& hwVersion) { + return GetAttributeHelper(mSlotHWVersion, hwVersion); +} + +NS_IMETHODIMP +nsPKCS11Slot::GetFWVersion(/*out*/ nsACString& fwVersion) { + return GetAttributeHelper(mSlotFWVersion, fwVersion); +} + +NS_IMETHODIMP +nsPKCS11Slot::GetToken(nsIPK11Token** _retval) { + NS_ENSURE_ARG_POINTER(_retval); + nsCOMPtr token = new nsPK11Token(mSlot.get()); + token.forget(_retval); + return NS_OK; +} + +NS_IMETHODIMP +nsPKCS11Slot::GetTokenName(/*out*/ nsACString& tokenName) { + if (!PK11_IsPresent(mSlot.get())) { + tokenName.SetIsVoid(true); + return NS_OK; + } + + if (PK11_GetSlotSeries(mSlot.get()) != mSeries) { + nsresult rv = refreshSlotInfo(); + if (NS_FAILED(rv)) { + return rv; + } + } + + if (mIsInternalCryptoSlot) { + if (PK11_IsFIPS()) { + return GetPIPNSSBundleString("Fips140TokenDescription", tokenName); + } + return GetPIPNSSBundleString("TokenDescription", tokenName); + } + if (mIsInternalKeySlot) { + return GetPIPNSSBundleString("PrivateTokenDescription", tokenName); + } + + tokenName.Assign(PK11_GetTokenName(mSlot.get())); + return NS_OK; +} + +NS_IMETHODIMP +nsPKCS11Slot::GetStatus(uint32_t* _retval) { + NS_ENSURE_ARG_POINTER(_retval); + if (PK11_IsDisabled(mSlot.get())) { + *_retval = SLOT_DISABLED; + } else if (!PK11_IsPresent(mSlot.get())) { + *_retval = SLOT_NOT_PRESENT; + } else if (PK11_NeedLogin(mSlot.get()) && PK11_NeedUserInit(mSlot.get())) { + *_retval = SLOT_UNINITIALIZED; + } else if (PK11_NeedLogin(mSlot.get()) && + !PK11_IsLoggedIn(mSlot.get(), nullptr)) { + *_retval = SLOT_NOT_LOGGED_IN; + } else if (PK11_NeedLogin(mSlot.get())) { + *_retval = SLOT_LOGGED_IN; + } else { + *_retval = SLOT_READY; + } + return NS_OK; +} + +NS_IMPL_ISUPPORTS(nsPKCS11Module, nsIPKCS11Module) + +nsPKCS11Module::nsPKCS11Module(SECMODModule* module) { + MOZ_ASSERT(module); + mModule.reset(SECMOD_ReferenceModule(module)); +} + +// Convert the UTF8 internal name of the module to how it should appear to the +// user. In most cases this involves simply passing back the module's name. +// However, the builtin roots module has a non-localized name internally that we +// must map to the localized version when we display it to the user. +static nsresult NormalizeModuleNameOut(const char* moduleNameIn, + nsACString& moduleNameOut) { + // Easy case: this isn't the builtin roots module. + if (strnlen(moduleNameIn, kRootModuleNameLen + 1) != kRootModuleNameLen || + strncmp(kRootModuleName, moduleNameIn, kRootModuleNameLen) != 0) { + moduleNameOut.Assign(moduleNameIn); + return NS_OK; + } + + nsAutoString localizedRootModuleName; + nsresult rv = + GetPIPNSSBundleString("RootCertModuleName", localizedRootModuleName); + if (NS_FAILED(rv)) { + return rv; + } + moduleNameOut.Assign(NS_ConvertUTF16toUTF8(localizedRootModuleName)); + return NS_OK; +} + +NS_IMETHODIMP +nsPKCS11Module::GetName(/*out*/ nsACString& name) { + return NormalizeModuleNameOut(mModule->commonName, name); +} + +NS_IMETHODIMP +nsPKCS11Module::GetLibName(/*out*/ nsACString& libName) { + if (mModule->dllName) { + libName = mModule->dllName; + } else { + libName.SetIsVoid(true); + } + return NS_OK; +} + +NS_IMETHODIMP +nsPKCS11Module::ListSlots(nsISimpleEnumerator** _retval) { + NS_ENSURE_ARG_POINTER(_retval); + + nsresult rv = CheckForSmartCardChanges(); + if (NS_FAILED(rv)) { + return rv; + } + + nsCOMPtr array = do_CreateInstance(NS_ARRAY_CONTRACTID); + if (!array) { + return NS_ERROR_FAILURE; + } + + /* applications which allow new slot creation (which Firefox now does + * since it uses the WaitForSlotEvent call) need to hold the + * ModuleList Read lock to prevent the slot array from changing out + * from under it. */ + mozilla::AutoSECMODListReadLock lock; + for (int i = 0; i < mModule->slotCount; i++) { + if (mModule->slots[i]) { + nsCOMPtr slot = new nsPKCS11Slot(mModule->slots[i]); + rv = array->AppendElement(slot); + if (NS_FAILED(rv)) { + return rv; + } + } + } + + return array->Enumerate(_retval, NS_GET_IID(nsIPKCS11Slot)); +} diff --git a/security/manager/ssl/nsPKCS11Slot.h b/security/manager/ssl/nsPKCS11Slot.h new file mode 100644 index 0000000000..3f532d7064 --- /dev/null +++ b/security/manager/ssl/nsPKCS11Slot.h @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef nsPKCS11Slot_h +#define nsPKCS11Slot_h + +#include "ScopedNSSTypes.h" +#include "nsIPKCS11Module.h" +#include "nsIPKCS11Slot.h" +#include "nsISupports.h" +#include "nsString.h" +#include "pk11func.h" + +class nsPKCS11Slot : public nsIPKCS11Slot { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPKCS11SLOT + + explicit nsPKCS11Slot(PK11SlotInfo* slot); + + protected: + virtual ~nsPKCS11Slot() = default; + + private: + mozilla::UniquePK11SlotInfo mSlot; + // True if this is the "PKCS#11 slot" that provides cryptographic functions. + bool mIsInternalCryptoSlot; + // True if this is the "PKCS#11 slot" where private keys are stored. + bool mIsInternalKeySlot; + nsCString mSlotDesc; + nsCString mSlotManufacturerID; + nsCString mSlotHWVersion; + nsCString mSlotFWVersion; + int mSeries; + + nsresult refreshSlotInfo(); + nsresult GetAttributeHelper(const nsACString& attribute, + /*out*/ nsACString& xpcomOutParam); +}; + +class nsPKCS11Module : public nsIPKCS11Module { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSIPKCS11MODULE + + explicit nsPKCS11Module(SECMODModule* module); + + protected: + virtual ~nsPKCS11Module() = default; + + private: + mozilla::UniqueSECMODModule mModule; +}; + +#endif // nsPKCS11Slot_h diff --git a/security/manager/ssl/nsPKCS12Blob.cpp b/security/manager/ssl/nsPKCS12Blob.cpp new file mode 100644 index 0000000000..471acfc3c4 --- /dev/null +++ b/security/manager/ssl/nsPKCS12Blob.cpp @@ -0,0 +1,343 @@ +/* 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/. */ + +#include "nsPKCS12Blob.h" + +#include "ScopedNSSTypes.h" +#include "mozilla/Assertions.h" +#include "mozilla/Casting.h" +#include "mozilla/Unused.h" +#include "nsIFile.h" +#include "nsIInputStream.h" +#include "nsIX509CertDB.h" +#include "nsNSSCertHelper.h" +#include "nsNSSCertificate.h" +#include "nsNSSHelper.h" +#include "nsNetUtil.h" +#include "nsReadableUtils.h" +#include "nsTArray.h" +#include "nsThreadUtils.h" +#include "p12plcy.h" +#include "mozpkix/pkixtypes.h" +#include "secerr.h" +#include "p12plcy.h" + +using namespace mozilla; +extern LazyLogModule gPIPNSSLog; + +#define PIP_PKCS12_BUFFER_SIZE 2048 +#define PIP_PKCS12_NOSMARTCARD_EXPORT 4 +#define PIP_PKCS12_RESTORE_FAILED 5 +#define PIP_PKCS12_BACKUP_FAILED 6 +#define PIP_PKCS12_NSS_ERROR 7 + +nsPKCS12Blob::nsPKCS12Blob() : mUIContext(new PipUIContext()) {} + +// Given a file handle, read a PKCS#12 blob from that file, decode it, and +// import the results into the internal database. +nsresult nsPKCS12Blob::ImportFromFile(nsIFile* aFile, + const nsAString& aPassword, + uint32_t& aError) { + uint32_t passwordBufferLength; + UniquePtr passwordBuffer; + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + return NS_ERROR_FAILURE; + } + + passwordBuffer = stringToBigEndianBytes(aPassword, passwordBufferLength); + + // initialize the decoder + SECItem unicodePw = {siBuffer, passwordBuffer.get(), passwordBufferLength}; + UniqueSEC_PKCS12DecoderContext dcx( + SEC_PKCS12DecoderStart(&unicodePw, slot.get(), nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr)); + if (!dcx) { + return NS_ERROR_FAILURE; + } + // read input aFile and feed it to the decoder + PRErrorCode nssError; + nsresult rv = inputToDecoder(dcx, aFile, nssError); + if (NS_FAILED(rv)) { + return rv; + } + if (nssError != 0) { + aError = handlePRErrorCode(nssError); + return NS_OK; + } + // verify the blob + SECStatus srv = SEC_PKCS12DecoderVerify(dcx.get()); + if (srv != SECSuccess) { + aError = handlePRErrorCode(PR_GetError()); + return NS_OK; + } + // validate bags + srv = SEC_PKCS12DecoderValidateBags(dcx.get(), nicknameCollision); + if (srv != SECSuccess) { + aError = handlePRErrorCode(PR_GetError()); + return NS_OK; + } + // import cert and key + srv = SEC_PKCS12DecoderImportBags(dcx.get()); + if (srv != SECSuccess) { + aError = handlePRErrorCode(PR_GetError()); + return NS_OK; + } + aError = nsIX509CertDB::Success; + return NS_OK; +} + +static bool isExtractable(UniqueSECKEYPrivateKey& privKey) { + ScopedAutoSECItem value; + SECStatus rv = PK11_ReadRawAttribute(PK11_TypePrivKey, privKey.get(), + CKA_EXTRACTABLE, &value); + if (rv != SECSuccess) { + return false; + } + + bool isExtractable = false; + if ((value.len == 1) && value.data) { + isExtractable = !!(*(CK_BBOOL*)value.data); + } + return isExtractable; +} + +// Having already loaded the certs, form them into a blob (loading the keys +// also), encode the blob, and stuff it into the file. +nsresult nsPKCS12Blob::ExportToFile(nsIFile* aFile, + const nsTArray>& aCerts, + const nsAString& aPassword, + uint32_t& aError) { + // get file password (unicode) + uint32_t passwordBufferLength; + UniquePtr passwordBuffer; + passwordBuffer = stringToBigEndianBytes(aPassword, passwordBufferLength); + aError = nsIX509CertDB::Success; + if (!passwordBuffer) { + return NS_OK; + } + UniqueSEC_PKCS12ExportContext ecx( + SEC_PKCS12CreateExportContext(nullptr, nullptr, nullptr, nullptr)); + if (!ecx) { + aError = nsIX509CertDB::ERROR_PKCS12_BACKUP_FAILED; + return NS_OK; + } + // add password integrity + SECItem unicodePw = {siBuffer, passwordBuffer.get(), passwordBufferLength}; + SECStatus srv = + SEC_PKCS12AddPasswordIntegrity(ecx.get(), &unicodePw, SEC_OID_SHA1); + if (srv != SECSuccess) { + aError = nsIX509CertDB::ERROR_PKCS12_BACKUP_FAILED; + return NS_OK; + } + for (auto& cert : aCerts) { + UniqueCERTCertificate nssCert(cert->GetCert()); + if (!nssCert) { + aError = nsIX509CertDB::ERROR_PKCS12_BACKUP_FAILED; + return NS_OK; + } + // We can probably only successfully export certs that are on the internal + // token. Most, if not all, smart card vendors won't let you extract the + // private key (in any way shape or form) from the card. So let's punt if + // the cert is not in the internal db. + if (nssCert->slot && !PK11_IsInternal(nssCert->slot)) { + // We aren't the internal token, see if the key is extractable. + UniqueSECKEYPrivateKey privKey( + PK11_FindKeyByDERCert(nssCert->slot, nssCert.get(), mUIContext)); + if (privKey && !isExtractable(privKey)) { + // This is informative. If a serious error occurs later it will + // override it later and return. + aError = nsIX509CertDB::ERROR_PKCS12_NOSMARTCARD_EXPORT; + continue; + } + } + + // certSafe and keySafe are owned by ecx. + SEC_PKCS12SafeInfo* certSafe; + SEC_PKCS12SafeInfo* keySafe = SEC_PKCS12CreateUnencryptedSafe(ecx.get()); + if (!SEC_PKCS12IsEncryptionAllowed() || PK11_IsFIPS()) { + certSafe = keySafe; + } else { + certSafe = SEC_PKCS12CreatePasswordPrivSafe( + ecx.get(), &unicodePw, + SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC); + } + if (!certSafe || !keySafe) { + aError = nsIX509CertDB::ERROR_PKCS12_BACKUP_FAILED; + return NS_OK; + } + // add the cert and key to the blob + srv = SEC_PKCS12AddCertAndKey( + ecx.get(), certSafe, nullptr, nssCert.get(), CERT_GetDefaultCertDB(), + keySafe, nullptr, true, &unicodePw, + SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC); + if (srv != SECSuccess) { + aError = nsIX509CertDB::ERROR_PKCS12_BACKUP_FAILED; + return NS_OK; + } + } + + UniquePRFileDesc prFile; + PRFileDesc* rawPRFile; + nsresult rv = aFile->OpenNSPRFileDesc(PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, + 0664, &rawPRFile); + if (NS_FAILED(rv) || !rawPRFile) { + aError = nsIX509CertDB::ERROR_PKCS12_BACKUP_FAILED; + return NS_OK; + } + prFile.reset(rawPRFile); + // encode and write + srv = SEC_PKCS12Encode(ecx.get(), writeExportFile, prFile.get()); + if (srv != SECSuccess) { + aError = nsIX509CertDB::ERROR_PKCS12_BACKUP_FAILED; + } + return NS_OK; +} + +// For the NSS PKCS#12 library, must convert PRUnichars (shorts) to a buffer of +// octets. Must handle byte order correctly. +UniquePtr nsPKCS12Blob::stringToBigEndianBytes( + const nsAString& uni, uint32_t& bytesLength) { + if (uni.IsVoid()) { + bytesLength = 0; + return nullptr; + } + + uint32_t wideLength = uni.Length() + 1; // +1 for the null terminator. + bytesLength = wideLength * 2; + auto buffer = MakeUnique(bytesLength); + + // We have to use a cast here because on Windows, uni.get() returns + // char16ptr_t instead of char16_t*. + mozilla::NativeEndian::copyAndSwapToBigEndian( + buffer.get(), static_cast(uni.BeginReading()), + wideLength); + + return buffer; +} + +// Given a decoder, read bytes from file and input them to the decoder. +nsresult nsPKCS12Blob::inputToDecoder(UniqueSEC_PKCS12DecoderContext& dcx, + nsIFile* file, PRErrorCode& nssError) { + nssError = 0; + + nsCOMPtr fileStream; + nsresult rv = NS_NewLocalFileInputStream(getter_AddRefs(fileStream), file); + if (NS_FAILED(rv)) { + return rv; + } + + char buf[PIP_PKCS12_BUFFER_SIZE]; + uint32_t amount; + while (true) { + rv = fileStream->Read(buf, PIP_PKCS12_BUFFER_SIZE, &amount); + if (NS_FAILED(rv)) { + return rv; + } + // feed the file data into the decoder + SECStatus srv = + SEC_PKCS12DecoderUpdate(dcx.get(), (unsigned char*)buf, amount); + if (srv != SECSuccess) { + nssError = PR_GetError(); + return NS_OK; + } + if (amount < PIP_PKCS12_BUFFER_SIZE) { + break; + } + } + return NS_OK; +} + +// What to do when the nickname collides with one already in the db. +SECItem* nsPKCS12Blob::nicknameCollision(SECItem* oldNick, PRBool* cancel, + void* wincx) { + *cancel = false; + int count = 1; + nsCString nickname; + nsAutoString nickFromProp; + nsresult rv = GetPIPNSSBundleString("P12DefaultNickname", nickFromProp); + if (NS_FAILED(rv)) { + return nullptr; + } + NS_ConvertUTF16toUTF8 nickFromPropC(nickFromProp); + // The user is trying to import a PKCS#12 file that doesn't have the + // attribute we use to set the nickname. So in order to reduce the + // number of interactions we require with the user, we'll build a nickname + // for the user. The nickname isn't prominently displayed in the UI, + // so it's OK if we generate one on our own here. + // XXX If the NSS API were smarter and actually passed a pointer to + // the CERTCertificate* we're importing we could actually just + // call default_nickname (which is what the issuance code path + // does) and come up with a reasonable nickname. Alas, the NSS + // API limits our ability to produce a useful nickname without + // bugging the user. :( + while (1) { + // If we've gotten this far, that means there isn't a certificate + // in the database that has the same subject name as the cert we're + // trying to import. So we need to come up with a "nickname" to + // satisfy the NSS requirement or fail in trying to import. + // Basically we use a default nickname from a properties file and + // see if a certificate exists with that nickname. If there isn't, then + // create update the count by one and append the string '#1' Or + // whatever the count currently is, and look for a cert with + // that nickname. Keep updating the count until we find a nickname + // without a corresponding cert. + // XXX If a user imports *many* certs without the 'friendly name' + // attribute, then this may take a long time. :( + nickname = nickFromPropC; + if (count > 1) { + nickname.AppendPrintf(" #%d", count); + } + UniqueCERTCertificate cert( + CERT_FindCertByNickname(CERT_GetDefaultCertDB(), nickname.get())); + if (!cert) { + break; + } + count++; + } + UniqueSECItem newNick( + SECITEM_AllocItem(nullptr, nullptr, nickname.Length() + 1)); + if (!newNick) { + return nullptr; + } + memcpy(newNick->data, nickname.get(), nickname.Length()); + newNick->data[nickname.Length()] = 0; + + return newNick.release(); +} + +// write bytes to the exported PKCS#12 file +void nsPKCS12Blob::writeExportFile(void* arg, const char* buf, + unsigned long len) { + PRFileDesc* file = static_cast(arg); + MOZ_RELEASE_ASSERT(file); + PR_Write(file, buf, len); +} + +// Translate PRErrorCode to nsIX509CertDB error +uint32_t nsPKCS12Blob::handlePRErrorCode(PRErrorCode aPrerr) { + MOZ_ASSERT(aPrerr != 0); + uint32_t error = nsIX509CertDB::ERROR_UNKNOWN; + switch (aPrerr) { + case SEC_ERROR_PKCS12_CERT_COLLISION: + error = nsIX509CertDB::ERROR_PKCS12_DUPLICATE_DATA; + break; + // INVALID_ARGS is returned on bad password when importing cert + // exported from firefox or generated by openssl + case SEC_ERROR_INVALID_ARGS: + case SEC_ERROR_BAD_PASSWORD: + error = nsIX509CertDB::ERROR_BAD_PASSWORD; + break; + case SEC_ERROR_BAD_DER: + case SEC_ERROR_PKCS12_CORRUPT_PFX_STRUCTURE: + case SEC_ERROR_PKCS12_INVALID_MAC: + error = nsIX509CertDB::ERROR_DECODE_ERROR; + break; + case SEC_ERROR_PKCS12_DUPLICATE_DATA: + error = nsIX509CertDB::ERROR_PKCS12_DUPLICATE_DATA; + break; + } + return error; +} diff --git a/security/manager/ssl/nsPKCS12Blob.h b/security/manager/ssl/nsPKCS12Blob.h new file mode 100644 index 0000000000..e764481999 --- /dev/null +++ b/security/manager/ssl/nsPKCS12Blob.h @@ -0,0 +1,54 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#ifndef nsPKCS12Blob_h +#define nsPKCS12Blob_h + +#include "mozilla/RefPtr.h" +#include "mozilla/UniquePtr.h" +#include "nsCOMPtr.h" +#include "nsIInterfaceRequestor.h" +#include "nsString.h" +#include "nsTArray.h" +#include "p12.h" +#include "prerror.h" +#include "ScopedNSSTypes.h" +#include "seccomon.h" + +class nsIFile; +class nsIX509Cert; + +// Class for importing/exporting PKCS#12 blobs +class nsPKCS12Blob { + public: + nsPKCS12Blob(); + ~nsPKCS12Blob() = default; + + // PKCS#12 Import + nsresult ImportFromFile(nsIFile* file, const nsAString& password, + uint32_t& error); + + // PKCS#12 Export + nsresult ExportToFile(nsIFile* file, + const nsTArray>& certs, + const nsAString& password, uint32_t& error); + + private: + nsCOMPtr mUIContext; + + // local helper functions + nsresult inputToDecoder(mozilla::UniqueSEC_PKCS12DecoderContext& dcx, + nsIFile* file, PRErrorCode& nssError); + mozilla::UniquePtr stringToBigEndianBytes(const nsAString& uni, + uint32_t& bytesLength); + uint32_t handlePRErrorCode(PRErrorCode prerr); + + static SECItem* nicknameCollision(SECItem* oldNick, PRBool* cancel, + void* wincx); + static void writeExportFile(void* arg, const char* buf, unsigned long len); +}; + +#endif // nsPKCS12Blob_h diff --git a/security/manager/ssl/nsProtectedAuthThread.cpp b/security/manager/ssl/nsProtectedAuthThread.cpp new file mode 100644 index 0000000000..939ad2fed9 --- /dev/null +++ b/security/manager/ssl/nsProtectedAuthThread.cpp @@ -0,0 +1,135 @@ +/* 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/. */ + +#include "PSMRunnable.h" +#include "mozilla/Assertions.h" +#include "mozilla/DebugOnly.h" +#include "mozilla/RefPtr.h" +#include "nsCOMPtr.h" +#include "GeckoProfiler.h" +#include "nsPKCS11Slot.h" +#include "nsProtectedAuthThread.h" +#include "nsReadableUtils.h" +#include "nsString.h" +#include "nsThreadUtils.h" +#include "pk11func.h" + +using namespace mozilla; +using namespace mozilla::psm; + +NS_IMPL_ISUPPORTS(nsProtectedAuthThread, nsIProtectedAuthThread) + +static void nsProtectedAuthThreadRunner(void* arg) { + AUTO_PROFILER_REGISTER_THREAD("Protected Auth"); + NS_SetCurrentThreadName("Protected Auth"); + + nsProtectedAuthThread* self = static_cast(arg); + self->Run(); +} + +nsProtectedAuthThread::nsProtectedAuthThread() + : mMutex("nsProtectedAuthThread.mMutex"), + mIAmRunning(false), + mLoginReady(false), + mThreadHandle(nullptr), + mSlot(0), + mLoginResult(SECFailure) {} + +nsProtectedAuthThread::~nsProtectedAuthThread() = default; + +NS_IMETHODIMP nsProtectedAuthThread::Login(nsIObserver* aObserver) { + NS_ENSURE_ARG(aObserver); + + if (!mSlot) + // We need pointer to the slot + return NS_ERROR_FAILURE; + + MutexAutoLock lock(mMutex); + + if (mIAmRunning || mLoginReady) { + return NS_OK; + } + + if (aObserver) { + // We must AddRef aObserver here on the main thread, because it probably + // does not implement a thread-safe AddRef. + mNotifyObserver = + new NotifyObserverRunnable(aObserver, "operation-completed"); + } + + mIAmRunning = true; + + mThreadHandle = PR_CreateThread(PR_USER_THREAD, nsProtectedAuthThreadRunner, + static_cast(this), PR_PRIORITY_NORMAL, + PR_GLOBAL_THREAD, PR_JOINABLE_THREAD, 0); + + // bool thread_started_ok = (threadHandle != nullptr); + // we might want to return "thread started ok" to caller in the future + MOZ_ASSERT(mThreadHandle, + "Could not create nsProtectedAuthThreadRunner thread"); + return NS_OK; +} + +NS_IMETHODIMP nsProtectedAuthThread::GetTokenName(nsAString& _retval) { + MutexAutoLock lock(mMutex); + + // Get token name + CopyUTF8toUTF16(nsDependentCString(PK11_GetTokenName(mSlot)), _retval); + + return NS_OK; +} + +NS_IMETHODIMP nsProtectedAuthThread::GetSlot(nsIPKCS11Slot** _retval) { + RefPtr slot; + { + MutexAutoLock lock(mMutex); + slot = new nsPKCS11Slot(mSlot); + } + + slot.forget(_retval); + return NS_OK; +} + +void nsProtectedAuthThread::SetParams(PK11SlotInfo* aSlot) { + MutexAutoLock lock(mMutex); + + mSlot = (aSlot) ? PK11_ReferenceSlot(aSlot) : 0; +} + +SECStatus nsProtectedAuthThread::GetResult() { return mLoginResult; } + +void nsProtectedAuthThread::Run(void) { + // Login with null password. This call will also do C_Logout() but + // it is harmless here + mLoginResult = PK11_CheckUserPassword(mSlot, 0); + + nsCOMPtr notifyObserver; + { + MutexAutoLock lock(mMutex); + + mLoginReady = true; + mIAmRunning = false; + + // Forget the slot + if (mSlot) { + PK11_FreeSlot(mSlot); + mSlot = 0; + } + + notifyObserver.swap(mNotifyObserver); + } + + if (notifyObserver) { + DebugOnly rv = NS_DispatchToMainThread(notifyObserver); + MOZ_ASSERT(NS_SUCCEEDED(rv), + "Failed to dispatch protected auth observer to main thread"); + } +} + +void nsProtectedAuthThread::Join() { + if (!mThreadHandle) return; + + PR_JoinThread(mThreadHandle); + mThreadHandle = nullptr; +} diff --git a/security/manager/ssl/nsProtectedAuthThread.h b/security/manager/ssl/nsProtectedAuthThread.h new file mode 100644 index 0000000000..83554658f9 --- /dev/null +++ b/security/manager/ssl/nsProtectedAuthThread.h @@ -0,0 +1,54 @@ +/* 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/. */ + +#ifndef NSPROTECTEDAUTHTHREAD_H_ +#define NSPROTECTEDAUTHTHREAD_H_ + +#include +#include "keyhi.h" +#include "nspr.h" + +#include "mozilla/Mutex.h" +#include "nsIProtectedAuthThread.h" + +class nsIRunnable; + +class nsProtectedAuthThread : public nsIProtectedAuthThread { + private: + mozilla::Mutex mMutex; + + nsCOMPtr mNotifyObserver; + + bool mIAmRunning; + bool mLoginReady; + + PRThread* mThreadHandle; + + // Slot to do authentication on + PK11SlotInfo* mSlot; + + // Result of the authentication + SECStatus mLoginResult; + + public: + nsProtectedAuthThread(); + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIPROTECTEDAUTHTHREAD + + // Sets parameters for the thread + void SetParams(PK11SlotInfo* slot); + + // Gets result of the protected authentication operation + SECStatus GetResult(); + + void Join(void); + + void Run(void); + + protected: + virtual ~nsProtectedAuthThread(); +}; + +#endif // NSPROTECTEDAUTHTHREAD_H_ diff --git a/security/manager/ssl/nsRandomGenerator.cpp b/security/manager/ssl/nsRandomGenerator.cpp new file mode 100644 index 0000000000..aee99e2536 --- /dev/null +++ b/security/manager/ssl/nsRandomGenerator.cpp @@ -0,0 +1,36 @@ +/* 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/. */ + +#include "nsRandomGenerator.h" + +#include "ScopedNSSTypes.h" +#include "nsNSSComponent.h" +#include "pk11pub.h" +#include "prerror.h" +#include "secerr.h" + +NS_IMPL_ISUPPORTS(nsRandomGenerator, nsIRandomGenerator) + +NS_IMETHODIMP +nsRandomGenerator::GenerateRandomBytes(uint32_t aLength, uint8_t** aBuffer) { + NS_ENSURE_ARG_POINTER(aBuffer); + *aBuffer = nullptr; + + mozilla::UniquePK11SlotInfo slot(PK11_GetInternalSlot()); + if (!slot) { + return NS_ERROR_FAILURE; + } + + auto buf = static_cast(moz_xmalloc(aLength)); + + SECStatus srv = PK11_GenerateRandomOnSlot(slot.get(), buf, aLength); + if (srv != SECSuccess) { + free(buf); + return NS_ERROR_FAILURE; + } + + *aBuffer = buf; + + return NS_OK; +} diff --git a/security/manager/ssl/nsRandomGenerator.h b/security/manager/ssl/nsRandomGenerator.h new file mode 100644 index 0000000000..4ae3fc82f4 --- /dev/null +++ b/security/manager/ssl/nsRandomGenerator.h @@ -0,0 +1,29 @@ +/* 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/. */ + +#ifndef nsRandomGenerator_h +#define nsRandomGenerator_h + +#include "mozilla/Attributes.h" +#include "nsIRandomGenerator.h" + +#define NS_RANDOMGENERATOR_CID \ + { \ + 0xbe65e2b7, 0xfe46, 0x4e0f, { \ + 0x88, 0xe0, 0x4b, 0x38, 0x5d, 0xb4, 0xd6, 0x8a \ + } \ + } + +#define NS_RANDOMGENERATOR_CONTRACTID "@mozilla.org/security/random-generator;1" + +class nsRandomGenerator final : public nsIRandomGenerator { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIRANDOMGENERATOR + + private: + ~nsRandomGenerator() = default; +}; + +#endif // nsRandomGenerator_h diff --git a/security/manager/ssl/nsSSLSocketProvider.cpp b/security/manager/ssl/nsSSLSocketProvider.cpp new file mode 100644 index 0000000000..6de78517e4 --- /dev/null +++ b/security/manager/ssl/nsSSLSocketProvider.cpp @@ -0,0 +1,46 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "mozilla/BasePrincipal.h" +#include "nsSSLSocketProvider.h" +#include "nsNSSIOLayer.h" +#include "nsError.h" + +using mozilla::OriginAttributes; + +nsSSLSocketProvider::nsSSLSocketProvider() = default; + +nsSSLSocketProvider::~nsSSLSocketProvider() = default; + +NS_IMPL_ISUPPORTS(nsSSLSocketProvider, nsISocketProvider) + +NS_IMETHODIMP +nsSSLSocketProvider::NewSocket(int32_t family, const char* host, int32_t port, + nsIProxyInfo* proxy, + const OriginAttributes& originAttributes, + uint32_t flags, uint32_t tlsFlags, + PRFileDesc** _result, + nsISupports** securityInfo) { + nsresult rv = + nsSSLIOLayerNewSocket(family, host, port, proxy, originAttributes, + _result, securityInfo, false, flags, tlsFlags); + return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK; +} + +// Add the SSL IO layer to an existing socket +NS_IMETHODIMP +nsSSLSocketProvider::AddToSocket(int32_t family, const char* host, int32_t port, + nsIProxyInfo* proxy, + const OriginAttributes& originAttributes, + uint32_t flags, uint32_t tlsFlags, + PRFileDesc* aSocket, + nsISupports** securityInfo) { + nsresult rv = + nsSSLIOLayerAddToSocket(family, host, port, proxy, originAttributes, + aSocket, securityInfo, false, flags, tlsFlags); + + return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK; +} diff --git a/security/manager/ssl/nsSSLSocketProvider.h b/security/manager/ssl/nsSSLSocketProvider.h new file mode 100644 index 0000000000..690c911bd5 --- /dev/null +++ b/security/manager/ssl/nsSSLSocketProvider.h @@ -0,0 +1,32 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef _NSSSLSOCKETPROVIDER_H_ +#define _NSSSLSOCKETPROVIDER_H_ + +#include "nsISocketProvider.h" + +/* 217d014a-1dd2-11b2-999c-b0c4df79b324 */ +#define NS_SSLSOCKETPROVIDER_CID \ + { \ + 0x217d014a, 0x1dd2, 0x11b2, { \ + 0x99, 0x9c, 0xb0, 0xc4, 0xdf, 0x79, 0xb3, 0x24 \ + } \ + } + +class nsSSLSocketProvider : public nsISocketProvider { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSISOCKETPROVIDER + + // nsSSLSocketProvider methods: + nsSSLSocketProvider(); + + protected: + virtual ~nsSSLSocketProvider(); +}; + +#endif /* _NSSSLSOCKETPROVIDER_H_ */ diff --git a/security/manager/ssl/nsSTSPreloadList.inc b/security/manager/ssl/nsSTSPreloadList.inc new file mode 100644 index 0000000000..b01428654f --- /dev/null +++ b/security/manager/ssl/nsSTSPreloadList.inc @@ -0,0 +1,109307 @@ +/* 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/. */ + +/*****************************************************************************/ +/* This is an automatically generated file. If you're not */ +/* nsSiteSecurityService.cpp, you shouldn't be #including it. */ +/*****************************************************************************/ + +#include +const PRTime gPreloadListExpirationTime = INT64_C(1623940876762000); +%% +0--1.de, 1 +0-1.party, 1 +0-24.com, 1 +0-24.net, 1 +00000000-0000-0000-0000-000000000000.xyz, 1 +00010.xyz, 0 +0007552.com, 1 +000a1.com, 1 +000a2.com, 1 +000a3.com, 1 +000a5.com, 1 +000a6.com, 1 +000a7.com, 1 +000a8.com, 1 +000a9.com, 1 +000b58.com, 1 +000g.ru, 1 +000x2.com, 1 +000x3.com, 1 +0010100.net, 1 +0011011.xyz, 1 +00120012.net, 1 +00140014.net, 1 +00168365.com, 1 +0017552.com, 1 +0017d88.com, 1 +0018d88.com, 1 +001yapan.com, 1 +002.ro, 1 +00220022.net, 1 +00228.am, 1 +00228.org, 1 +00228555.com, 1 +00228999.com, 1 +00228vip5.com, 1 +00228vip6.com, 1 +00228vip8.com, 1 +00228vv.com, 1 +00228w.com, 1 +00228ww.com, 1 +00228x.com, 1 +00228xx.com, 1 +00228y.com, 1 +00228yy.com, 1 +00228z.com, 1 +00228zz.com, 1 +002k8.com, 1 +00321365.com, 1 +00365t.com, 1 +0037552.com, 1 +003d88.com, 1 +0047552.com, 1 +004d88.com, 1 +0057552.com, 1 +00660066.net, 1 +0067552.com, 1 +006d88.com, 1 +00770077.net, 1 +0077552.com, 1 +007d88.com, 1 +007kf.com, 1 +0087552.com, 1 +00880088.net, 1 +008yingshi.com, 1 +009597.com, 1 +0097552.com, 1 +00990099.net, 0 +009d88.com, 1 +009zl.com, 1 +00b31.com, 1 +00b58.com, 1 +00bet86.com, 1 +00d88.com, 1 +00dani.me, 1 +00f.net, 1 +00s.io, 1 +00wbf.com, 1 +01.org, 1 +01011970.xyz, 1 +010203.ru, 1 +010kb.com, 1 +010ks.com, 1 +010ks.net, 1 +01100010011001010111001101110100.com, 1 +01110000011100110111001001100111.com, 1 +011101.xyz, 1 +0116288.com, 1 +0117552.com, 1 +011ks.com, 1 +012345678365.com, 1 +0123456789365.com, 1 +0123movies.sx, 1 +0127552.com, 1 +01337.tech, 1 +01365t.com, 1 +0137552.com, 1 +0138365.com, 0 +0139365.com, 0 +013zl.com, 1 +015kb.com, 1 +016028.com, 1 +016098.com, 1 +016298.com, 1 +016328.com, 1 +0175365.com, 0 +018663.com, 1 +018zl.com, 1 +01918.net, 1 +019328.com, 1 +019398.com, 1 +019ks.com, 1 +019zl.com, 1 +01bargainhunter.com, 1 +01btc.com, 0 +01electronica.com.ar, 1 +01media.fr, 1 +01seguridad.com.ar, 1 +01smh.com, 1 +01tools.com, 1 +01up.co.za, 1 +020ks.com, 1 +021002.com, 1 +0222z6.com, 1 +022367.com, 1 +022379.com, 1 +022391.com, 1 +022501.com, 1 +022503.com, 1 +022507.com, 1 +022561.com, 1 +022571.com, 1 +022601.com, 1 +022609.com, 1 +022610.com, 1 +022kb.com, 1 +02327.net, 1 +02365t.com, 1 +02375.net, 1 +023sec.com, 1 +025k8.com, 1 +025ks.com, 1 +02607.com, 1 +026122.com, 1 +02638.net, 1 +026ks.com, 1 +028718.com, 1 +029978.com, 1 +02d88.net, 1 +02smh.com, 1 +03-09-2016.wedding, 1 +03012.net, 1 +03018.net, 1 +0311z6.com, 1 +031373.com, 1 +0315z6.com, 1 +03170317.com, 1 +032ks.com, 1 +0335z6.com, 1 +033ks.com, 1 +035711630.xyz, 1 +035ks.com, 1 +03637.com, 0 +036ks.com, 1 +0376z6.com, 1 +0377z6.com, 1 +038663.com, 1 +038899.com, 1 +0391315.com, 1 +03d88.com, 1 +03d88.net, 1 +03region.ga, 1 +0404.co.il, 1 +040552.com, 0 +041552.com, 0 +042552.com, 0 +04365t.com, 1 +046552.com, 0 +046569.com, 1 +04911701.cn, 1 +049552.com, 0 +04d.co, 1 +04d88.com, 1 +04d88.net, 1 +04dco.tk, 1 +04sun.com, 1 +050.ca, 1 +050a1.com, 1 +050a2.com, 1 +050a3.com, 1 +050a4.com, 1 +050a5.com, 1 +050a6.com, 1 +050ks.com, 1 +0511315.net, 1 +0513z6.com, 1 +0514.chat, 1 +051552.com, 0 +0517z6.com, 1 +0518z6.com, 1 +051ks.com, 1 +052ks.com, 1 +05365t.com, 1 +053ks.com, 1 +054552.com, 0 +055268.com, 1 +0553z6.com, 1 +0555z6.com, 1 +0573wk.com, 1 +0575z6.com, 1 +058kb.com, 1 +0597z6.com, 1 +05am8.com, 1 +060258.com, 1 +060579.com, 1 +060757.com, 1 +060796.com, 1 +060798.com, 1 +06091994.xyz, 1 +06365t.com, 1 +065l.com, 1 +066318.com, 1 +066538.com, 1 +066718.com, 1 +066928.com, 1 +066938.com, 1 +06804.com, 1 +0681a.com, 1 +0681h.com, 1 +068552.com, 0 +06918.net, 1 +06d88.com, 1 +06d88.net, 1 +0707.agency, 1 +070709.net, 1 +0712z6.com, 1 +071552.com, 0 +0717z6.com, 1 +071k8.com, 1 +07365t.com, 1 +0737399.com, 1 +075k8.com, 1 +0760ks.com, 1 +076k8.com, 1 +0771z6.com, 1 +077768.net, 1 +077969.com, 1 +077k8.com, 1 +078663.com, 1 +0788yh.com, 1 +0792112.com, 1 +0797.tv, 1 +0798rcw.com, 1 +07d88.com, 1 +07d88.net, 1 +08000113.nl, 1 +0809yh.com, 1 +081115.com, 1 +081638.com, 1 +081752.com, 1 +081763.com, 1 +081769.com, 1 +081783.com, 1 +081925.com, 1 +081927.com, 1 +081957.com, 1 +081967.com, 1 +082157.com, 1 +082159.com, 1 +082167.com, 1 +082173.com, 1 +082175.com, 1 +082179.com, 1 +082187.com, 1 +082192.com, 1 +082193.com, 1 +082195.com, 1 +082359.com, 1 +08365t.com, 1 +083903.com, 1 +083905.com, 1 +083907.com, 1 +083912.com, 1 +083957.com, 1 +083960.com, 1 +083962.com, 1 +083965.com, 1 +083967.com, 1 +084552.com, 1 +085851.com, 1 +086628.com, 1 +087010.com, 1 +08845.cc, 1 +08918.net, 1 +089818.com, 1 +08detaxe.fr, 1 +08lc.net, 1 +09000113.nl, 1 +0906-clan.tk, 1 +09115.com, 0 +091k8.com, 1 +092k8.com, 1 +09365t.com, 1 +095598.cc, 1 +09892.net, 1 +098k8.com, 1 +0998z6.com, 1 +0999z6.com, 1 +09btt.com, 1 +09d88.com, 1 +09elektrik.com, 1 +0akarma.me, 1 +0au.de, 0 +0c3.de, 1 +0cdn.ga, 1 +0cdn.net, 1 +0chan.club, 1 +0chan.pl, 1 +0chanru.net, 1 +0cp8778.com, 1 +0culus.tk, 1 +0d111.com, 1 +0day.agency, 1 +0dayexploits.gq, 1 +0des.com, 1 +0dev.cc, 1 +0i0.nl, 1 +0ii0.cf, 1 +0ik.de, 1 +0iz.net, 1 +0knowledge.de, 0 +0kun.net, 1 +0o0.edu.pl, 1 +0okmnbvcxzx.tk, 1 +0paste.com, 1 +0q0.eu, 1 +0vi.org, 1 +0vo.moe, 1 +0wx.cat, 1 +0wx.es, 1 +0wx.eu, 1 +0wx.org, 1 +0x.cx, 1 +0x.sk, 1 +0x0.cloud, 1 +0x0.li, 1 +0x00c.de, 1 +0x00ff00ff.com, 1 +0x1.ink, 1 +0x12.de, 1 +0x15.ca, 1 +0x17.de, 1 +0x21.consulting, 1 +0x22.de, 1 +0x2a.ninja, 1 +0x378.net, 1 +0x3a.net, 1 +0x41.us, 1 +0x52.net, 1 +0x52.org, 1 +0x53.de, 1 +0x5d.de, 1 +0x5f3759df.net, 1 +0x6470.xyz, 1 +0x7.io, 1 +0x76.de, 1 +0x7d.com, 1 +0x7fffffff.net, 1 +0x80.org, 1 +0x90.io, 1 +0xaa55.me, 1 +0xabe.io, 1 +0xacab.org, 1 +0xaf.tk, 1 +0xda.de, 1 +0xdefaced.de, 1 +0xedward.io, 1 +0xee.eu, 1 +0xf00.ch, 1 +0xfc.de, 1 +0xff.se, 1 +0xn.de, 1 +0xreki.de, 1 +0xword.com, 1 +0yen.org, 1 +1-2-3bounce.co.uk, 1 +1-pujcky-uvery.tk, 1 +1-weightloss.com, 1 +100-downloads.com, 1 +10000hits.tk, 1 +10000lab.net, 1 +10000rub.gq, 1 +10000spoons.tk, 1 +10000v.ru, 1 +1000cp4.cc, 1 +1000cp5.cc, 1 +1000cp6.cc, 1 +1000inf.ru, 1 +1000minds.com, 1 +1000rubley.ml, 1 +1000serien.com, 1 +1000wordsevents.com, 1 +1001firms.com, 1 +1001kartini.com, 1 +1001kerstpakketten.com, 0 +1001mv.com, 1 +1001reasonstolearnspanish.com, 1 +1007337.com, 1 +10086.ru, 1 +100baksov.tk, 1 +100ballov.tk, 1 +100cccc.com, 1 +100dddd.com, 1 +100eeee.com, 1 +100ffff.com, 1 +100gggg.com, 1 +100hhhh.com, 1 +100jjjj.com, 1 +100k.eu, 1 +100kkkk.com, 1 +100kredite.de, 1 +100lat.pl, 1 +100mani.it, 1 +100onrainkajino.com, 1 +100pounds.co.uk, 1 +100pourcentlocale.be, 1 +100procentlokaal.be, 1 +100pudov.tk, 1 +100qqqq.com, 1 +100rrrr.com, 1 +100sapog.tk, 1 +100skidok.ga, 1 +100up.de, 1 +100up.org, 1 +100uuuu.com, 1 +100visits.tk, 1 +100vvvv.com, 1 +100words.ca, 1 +100yyyy.com, 1 +100zakladok.tk, 1 +100zzzz.com, 1 +101.qa, 1 +10101.io, 1 +101010.pl, 1 +1011100.com, 1 +101st-airborne.tk, 1 +101st.tk, 1 +1020310.com, 1 +1020311.com, 1 +1020312.com, 1 +1020313.com, 1 +1020314.com, 1 +1020316.com, 1 +1020318.com, 1 +1020319.com, 1 +1020320.com, 1 +10365e.com, 1 +10365f.com, 1 +10365g.com, 1 +10365h.com, 1 +104.ua, 1 +1041263497.rsc.cdn77.org, 1 +10414.org, 1 +10430.net, 1 +10435.net, 1 +10436.net, 1 +10438.net, 1 +10439.net, 1 +10453.net, 1 +10495.net, 1 +105318.com, 1 +1068511.com, 1 +10774.net, 1 +107996.com, 1 +10840.net, 1 +1088.fun, 1 +1091.jp, 1 +109k8.com, 1 +10gbit.ovh, 1 +10hz.de, 1 +10ktotalent.com, 1 +10media.ru, 1 +10mijlvanijmuiden.tk, 1 +10milliondollarpage.com, 1 +10og.de, 1 +10ppm.com, 1 +10site.ru, 1 +10x.ooo, 1 +10x.to, 1 +10xnation.com, 1 +1100.so, 1 +1100110.xyz, 1 +11018vip.com, 1 +11018xpj.com, 1 +11046.com, 1 +110692.com, 1 +110ae.com, 1 +110al.com, 1 +110ap.com, 1 +110au.com, 1 +110bg.com, 1 +110bu.com, 1 +110bv.com, 1 +110ce.com, 1 +110cl.com, 1 +110eh.com, 1 +110ej.com, 1 +110ek.com, 1 +110en.com, 1 +110ep.com, 1 +110es.com, 1 +110et.com, 1 +110fn.com, 1 +110fr.com, 1 +110gf.com, 1 +110gh.com, 1 +110hq.com, 1 +110jf.com, 1 +110ju.com, 1 +110jx.com, 1 +110kh.com, 1 +110kn.com, 1 +110kp.com, 1 +110lh.com, 1 +110lj.com, 1 +110na.com, 1 +110ne.com, 1 +110nf.com, 1 +110ng.com, 1 +110nl.com, 1 +110nr.com, 1 +110nz.com, 1 +110pe.com, 1 +110qa.com, 1 +110qc.com, 1 +110qu.com, 1 +110rd.com, 1 +110rl.com, 1 +110sk.com, 1 +110uh.com, 1 +110ut.com, 1 +110wc.com, 1 +110wd.com, 1 +110we.com, 1 +110wf.com, 1 +110wq.com, 1 +110wy.com, 1 +110xp.com, 1 +110xz.com, 1 +110yj.com, 1 +110yl.com, 1 +110yn.com, 1 +110yt.com, 1 +110yu.com, 1 +110ze.com, 1 +110zg.com, 1 +111111.plus, 1 +1111365t.com, 1 +1111k8.com, 1 +111365t.com, 1 +11168365.com, 1 +111b58.com, 1 +111bet86.com, 1 +111novosti.tk, 1 +111ttt.com, 1 +1120301.com, 1 +1120302.com, 1 +1120303.com, 1 +1120305.com, 1 +1120306.com, 1 +1120307.com, 1 +1120308.com, 1 +1120309.com, 1 +1120311.com, 1 +1120312.com, 1 +1120313.com, 1 +1120314.com, 1 +1120315.com, 1 +1120316.com, 1 +1120317.com, 1 +1120320.com, 1 +1120321.com, 1 +1120322.com, 1 +1120323.com, 1 +1120324.com, 1 +1120325.com, 1 +1120326.com, 1 +1120327.com, 1 +1120328.com, 1 +1120330.com, 1 +1120331.com, 1 +1120332.com, 1 +1120334.com, 1 +1120335.com, 1 +1120336.com, 1 +1120337.com, 1 +1120338.com, 1 +1120339.com, 1 +1120340.com, 1 +1120341.com, 1 +1120342.com, 1 +1120343.com, 1 +1120344.com, 1 +1120345.com, 1 +1120346.com, 1 +1120347.com, 1 +1120348.com, 1 +1120349.com, 1 +1120350.com, 1 +11221jz.com, 1 +11223837.com, 1 +112app.nl, 1 +112fryslan.nl, 1 +112hz.com, 1 +112it.ro, 0 +11321365.com, 1 +11333837.com, 1 +11335835.com, 1 +11365t.com, 1 +113k8.com, 1 +113ks.com, 1 +113z6.com, 1 +11443837.com, 1 +11445835.com, 1 +114514ss.com, 1 +11553837.com, 1 +115z6.com, 1 +11665835.com, 1 +116ks.com, 1 +11773837.com, 1 +11775835.com, 1 +1177z6.com, 1 +11883837.com, 1 +11885835.com, 1 +118btt.com, 1 +118vip.net, 1 +1190america.tk, 1 +11993837.com, 1 +1199bet.vip, 1 +11aaee.com, 1 +11aagg.com, 1 +11aajj.com, 1 +11aaqq.com, 1 +11aass.com, 1 +11aazz.com, 1 +11ag8.com, 1 +11assets.com, 1 +11b31.com, 1 +11b58.com, 1 +11bbee.com, 1 +11bbjj.com, 1 +11bbpp.com, 1 +11bbqq.com, 1 +11bbrr.com, 1 +11bbss.com, 1 +11bbtt.com, 1 +11bbzz.com, 1 +11bet86.com, 1 +11ccee.com, 1 +11ccgg.com, 1 +11cchh.com, 1 +11ccjj.com, 1 +11cckk.com, 1 +11ccpp.com, 1 +11ccqq.com, 1 +11cctt.com, 1 +11ccxx.com, 1 +11ccyy.com, 1 +11cczz.com, 1 +11cloud.ch, 1 +11ddbb.com, 1 +11ddcc.com, 1 +11ddee.com, 1 +11ddjj.com, 1 +11ddkk.com, 1 +11ddpp.com, 1 +11ddqq.com, 1 +11ddrr.com, 1 +11ddtt.com, 1 +11ddzz.com, 1 +11dzon.com, 1 +11eebb.com, 1 +11eeff.com, 1 +11eegg.com, 1 +11eehh.com, 1 +11eejj.com, 1 +11eeqq.com, 1 +11eess.com, 1 +11eett.com, 1 +11eexx.com, 1 +11eeyy.com, 1 +11eezz.com, 1 +11ffcc.com, 1 +11ffee.com, 1 +11ffhh.com, 1 +11ffjj.com, 1 +11ffkk.com, 1 +11ffrr.com, 1 +11fftt.com, 1 +11ffxx.com, 1 +11ffyy.com, 1 +11ffzz.com, 1 +11ggaa.com, 1 +11ggbb.com, 1 +11ggcc.com, 1 +11ggdd.com, 1 +11ggee.com, 1 +11ggff.com, 1 +11ggjj.com, 1 +11ggkk.com, 1 +11ggpp.com, 1 +11ggqq.com, 1 +11ggrr.com, 1 +11ggss.com, 1 +11ggtt.com, 1 +11ggyy.com, 1 +11ggzz.com, 1 +11hhee.com, 1 +11hhff.com, 1 +11hhgg.com, 1 +11hhpp.com, 1 +11hhqq.com, 1 +11hhrr.com, 1 +11hhtt.com, 1 +11hhzz.com, 1 +11jjaa.com, 1 +11jjcc.com, 1 +11jjee.com, 1 +11jjpp.com, 1 +11jjqq.com, 1 +11jjrr.com, 1 +11jjtt.com, 1 +11jjyy.com, 1 +11jjzz.com, 1 +11kkee.com, 1 +11kkff.com, 1 +11kkss.com, 1 +11loc.de, 1 +11men.tk, 1 +11ppbb.com, 1 +11ppcc.com, 1 +11ppdd.com, 1 +11ppee.com, 1 +11ppgg.com, 1 +11pphh.com, 1 +11ppjj.com, 1 +11ppqq.com, 1 +11ppss.com, 1 +11pptt.com, 1 +11ppyy.com, 1 +11ppzz.com, 1 +11qqbb.com, 1 +11qqdd.com, 1 +11qqff.com, 1 +11qqgg.com, 1 +11qqhh.com, 1 +11qqkk.com, 1 +11qqpp.com, 1 +11qqrr.com, 1 +11qqss.com, 1 +11qqyy.com, 1 +11rrcc.com, 1 +11rrdd.com, 1 +11rree.com, 1 +11rrff.com, 1 +11rrgg.com, 1 +11rrhh.com, 1 +11rrjj.com, 1 +11rrkk.com, 1 +11rrpp.com, 1 +11rrqq.com, 1 +11rrss.com, 1 +11rryy.com, 1 +11rrzz.com, 1 +11sshh.com, 1 +11ssjj.com, 1 +11sskk.com, 1 +11sspp.com, 1 +11ssqq.com, 1 +11ssrr.com, 1 +11sstt.com, 1 +11thstreetcoffee.com, 1 +11traders.com, 1 +11ttbb.com, 1 +11ttdd.com, 1 +11ttee.com, 1 +11ttff.com, 1 +11tthh.com, 1 +11ttkk.com, 1 +11ttpp.com, 1 +11ttqq.com, 1 +11ttrr.com, 1 +11ttxx.com, 1 +11ttzz.com, 1 +11urss.com, 1 +11yybb.com, 1 +11yycc.com, 1 +11yydd.com, 1 +11yyee.com, 1 +11yygg.com, 1 +11yyjj.com, 1 +11yykk.com, 1 +11yypp.com, 1 +11yyqq.com, 1 +11yyrr.com, 1 +11yytt.com, 1 +11yyxx.com, 1 +11zzbb.com, 1 +11zzdd.com, 1 +11zzgg.com, 1 +11zzhh.com, 1 +11zzjj.com, 1 +11zzkk.com, 1 +11zztt.com, 1 +11zzyy.com, 1 +120323.com, 1 +120percent-inc.com, 1 +1211bet.com, 1 +1212873467.rsc.cdn77.org, 1 +1218641649.rsc.cdn77.org, 1 +1220310.com, 1 +1220321.com, 1 +1220322.com, 1 +1220323.com, 1 +1220324.com, 1 +1220325.com, 1 +1220326.com, 1 +1220327.com, 1 +1220328.com, 1 +1220329.com, 1 +1220330.com, 1 +1220331.com, 1 +1220332.com, 1 +1220334.com, 1 +1220335.com, 1 +1220336.com, 1 +1220337.com, 1 +1220338.com, 1 +1220339.com, 1 +1220340.com, 1 +1220342.com, 1 +1220343.com, 1 +1220344.com, 1 +1220345.com, 1 +1220346.com, 1 +1220347.com, 1 +1220348.com, 1 +1220349.com, 1 +1220350.com, 1 +1222z6.com, 1 +1223.tk, 1 +123-d.com, 1 +123-printer-setup.net, 1 +123.gg, 1 +123110.com, 1 +123365t.com, 1 +1234.link, 1 +1234365.vip, 1 +1234365a.com, 1 +1234365b.com, 1 +1234365c.com, 1 +1234365d.com, 1 +1234365e.com, 1 +1234365f.com, 1 +1234365g.com, 1 +1234365h.com, 1 +1234365i.com, 1 +1234365j.com, 1 +1234365k.com, 1 +1234365l.com, 1 +1234365m.com, 1 +1234365n.com, 1 +1234365o.com, 1 +1234365p.com, 1 +1234365q.com, 1 +1234365s.com, 1 +1234365t.com, 1 +1234365u.com, 1 +1234365v.com, 1 +1234365vip.com, 1 +1234365w.com, 1 +1234365x.com, 1 +1234365y.com, 1 +12345.lv, 1 +12345678365.com, 1 +123456789365.com, 1 +12345porn.com, 1 +1234666365.com, 1 +1236.be, 1 +12365t.com, 1 +123666365.com, 1 +123ali.ir, 1 +123apps.net, 1 +123bearing.co.uk, 1 +123bearing.com, 1 +123bearing.eu, 1 +123birthdaygreetings.com, 1 +123derivatives.com, 1 +123djdrop.com, 1 +123freebrushes.com, 1 +123freevectors.com, 1 +123hpcom.co.uk, 1 +123midterm.com, 1 +123nutricion.es, 1 +123opstalverzekeringen.nl, 1 +123pay.ir, 1 +123roulement.be, 1 +123roulement.com, 1 +123seo.ml, 1 +123start.pl, 1 +123termpapers.com, 1 +123viajando.com, 1 +123writings.com, 1 +123z6.com, 1 +124133.com, 1 +1244.tk, 1 +1244546066.rsc.cdn77.org, 1 +124633.com, 1 +1248.ink, 1 +125m125.de, 1 +1266bet.com, 1 +127661.com, 1 +1277bet.com, 1 +1288366.com, 1 +129.co, 1 +1299bet.com, 1 +12ag8.com, 1 +12cp.me.uk, 1 +12gramu.cz, 1 +12grid.co.jp, 1 +12l.nl, 1 +12nomos.tk, 1 +12socialsmansa.tk, 1 +12thmanrising.com, 1 +12train.com, 1 +130.ua, 1 +130978.com, 1 +130kb.com, 1 +130ks.com, 1 +130ks.net, 1 +131365a.com, 0 +131365qq.com, 1 +1313z6.com, 1 +13214.cc, 1 +132ks.com, 1 +132kv.ch, 1 +13318522.com, 1 +1333z6.com, 1 +133492.com, 1 +1337.vg, 1 +133769.xyz, 1 +1337ersprime.com, 1 +133846.xyz, 1 +133ks.com, 1 +133ks.net, 1 +133z6.com, 1 +134ks.net, 1 +1359826938.rsc.cdn77.org, 1 +135vv.com, 1 +135z6.com, 1 +136824.com, 1 +136book.com, 1 +136ks.com, 1 +136z6.com, 1 +137724.com, 1 +137kb.com, 1 +137z6.com, 1 +138.hk, 1 +13826145000.com, 1 +138z6.com, 1 +1391kj.com, 1 +1395kj.com, 1 +1396.net, 1 +139z6.com, 1 +13ag8.com, 1 +13th-dover.uk, 1 +14159.gb.net, 1 +142552.com, 0 +143533.com, 1 +143633.com, 1 +143733.com, 1 +143933.com, 1 +1453914078.rsc.cdn77.org, 1 +145433.com, 1 +145733.com, 1 +145ks.net, 1 +146233.com, 1 +146433.com, 1 +1464424382.rsc.cdn77.org, 1 +146533.com, 1 +146552.com, 1 +146733.com, 1 +1481486.net, 1 +148663.com, 1 +149433.com, 1 +149733.com, 1 +14er.games, 1 +14er.jp, 1 +14er.net, 1 +14erc.com, 1 +14ercooper.com, 1 +14flags.de, 1 +14it.de, 1 +14technology.com, 1 +14x3.de, 1 +15-10.com, 1 +1511774230.rsc.cdn77.org, 1 +1517598.com, 1 +1517668.com, 1 +1517669.com, 1 +1517883.com, 1 +1517886.com, 1 +1517889.com, 1 +1520301.com, 1 +1520302.com, 1 +1520303.com, 1 +1520304.com, 1 +1520305.com, 1 +1520306.com, 1 +1520310.com, 1 +1520316.com, 1 +1520318.com, 1 +1520319.com, 1 +1520320.com, 1 +1520322.com, 1 +1520323.com, 1 +1520324.com, 1 +1520325.com, 1 +1520326.com, 1 +1520327.com, 1 +1520328.com, 1 +1520329.com, 1 +1520330.com, 1 +1520331.com, 1 +1520332.com, 1 +1520333.com, 1 +1520334.com, 1 +1520335.com, 1 +1520336.com, 1 +1520337.com, 1 +1520338.com, 1 +1520339.com, 1 +1520340.com, 1 +1520341.com, 1 +1520342.com, 1 +1520343.com, 1 +1520344.com, 1 +1520345.com, 1 +1520346.com, 1 +1520347.com, 1 +1520348.com, 1 +1520349.com, 1 +1520350.com, 1 +152433.com, 1 +1527web.com, 1 +152z6.com, 1 +153z6.com, 1 +154233.com, 1 +154552.com, 0 +154633.com, 1 +154922.com, 0 +154933.com, 1 +155175.com, 0 +155ks.net, 1 +155z6.com, 1 +156433.com, 1 +156k66.com, 1 +156z6.com, 1 +157z6.com, 1 +158bg.com, 1 +158fb.com, 1 +158ia.com, 1 +158in.com, 1 +158iw.com, 1 +158yt.com, 1 +158yv.com, 1 +158za.com, 1 +1590284872.rsc.cdn77.org, 1 +15918.net, 1 +159ks.com, 1 +159ks.net, 1 +159z6.com, 1 +16-qw.tk, 1 +1600esplanade.com, 1 +160887.com, 1 +161233.com, 1 +161263.com, 1 +16164f.com, 1 +1620301.com, 1 +1620302.com, 1 +1620303.com, 1 +1620304.com, 1 +1620305.com, 1 +1620306.com, 1 +1620307.com, 1 +1620308.com, 1 +1620309.com, 1 +1620310.com, 1 +1620311.com, 1 +1620312.com, 1 +1620313.com, 1 +1620314.com, 1 +1620315.com, 1 +1620316.com, 1 +1620317.com, 1 +1620318.com, 1 +1620319.com, 1 +1620320.com, 1 +1620321.com, 1 +1620323.com, 1 +1620324.com, 1 +1620325.com, 1 +1620326.com, 1 +1620328.com, 1 +1620329.com, 1 +1620330.com, 1 +1620331.com, 1 +1620332.com, 1 +1620333.com, 1 +1620334.com, 1 +1620335.com, 1 +1620336.com, 1 +1620337.com, 1 +1620338.com, 1 +1620339.com, 1 +1620340.com, 1 +1620341.com, 1 +1620342.com, 1 +1620343.com, 1 +1620349.com, 1 +1620350.com, 1 +162223.com, 1 +162229.com, 1 +162361.com, 1 +162632.com, 1 +162bf.com, 1 +162bg.com, 1 +162ca.com, 1 +162cb.com, 1 +162cf.com, 1 +162cr.com, 1 +162ea.com, 1 +162ee.com, 1 +162ff.com, 1 +162jj.com, 1 +162jonesrd.ca, 1 +162rt.com, 1 +16321.tk, 1 +16345.net, 1 +1644091933.rsc.cdn77.org, 1 +1661237.com, 1 +1661618.com, 1 +1661618.net, 1 +166166.com, 1 +1666ks.com, 1 +166jk.cc, 1 +166killearn.com, 1 +166zzz.com, 1 +16836500.com, 1 +1683651.com, 1 +16836511.com, 1 +1683652.com, 1 +16836522.com, 1 +1683653.com, 1 +16836533.com, 1 +1683654.com, 1 +16836544.com, 1 +1683655.com, 1 +16836555.com, 1 +16836577.com, 1 +16836588.com, 1 +1683659.com, 1 +16836599.com, 1 +168365t.com, 1 +168bet9.com, 1 +168esb.com, 1 +168fff.cc, 1 +168z6.com, 1 +168zz.cc, 1 +169xpj.com, 1 +16ag6.com, 1 +16packets.com, 1 +16qw.tk, 1 +16region.tk, 1 +16te.com, 1 +16valerienicolas.tk, 1 +171365a.com, 1 +171365b.com, 1 +171365c.com, 1 +171365d.com, 1 +171365e.com, 1 +171365f.com, 1 +171365g.com, 1 +171365h.com, 1 +171365i.com, 1 +171365j.com, 1 +171365k.com, 1 +171365m.com, 1 +171365n.com, 1 +171365p.com, 1 +171365q.com, 1 +171365r.com, 1 +171365s.com, 1 +171365t.com, 1 +171365u.com, 1 +171365v.com, 1 +171365w.com, 1 +171365x.com, 1 +171365y.com, 1 +171365z.com, 1 +17187q.com, 1 +1720301.com, 1 +1720302.com, 1 +1720303.com, 1 +1720304.com, 1 +1720305.com, 1 +1720306.com, 1 +1720307.com, 1 +1720308.com, 1 +1720309.com, 1 +1720312.com, 1 +1720313.com, 1 +1720314.com, 1 +1720315.com, 1 +1720316.com, 1 +1720317.com, 1 +1720318.com, 1 +1720319.com, 1 +1720320.com, 1 +1720321.com, 1 +1720322.com, 1 +1720323.com, 1 +1720324.com, 1 +1720325.com, 1 +1720326.com, 1 +1720327.com, 1 +1720328.com, 1 +1720329.com, 1 +1720330.com, 1 +1720331.com, 1 +1720332.com, 1 +1720333.com, 1 +1720334.com, 1 +1720335.com, 1 +1720336.com, 1 +1720337.com, 1 +1720338.com, 1 +1720339.com, 1 +1720340.com, 1 +1720341.com, 1 +1720342.com, 1 +1720343.com, 1 +1720344.com, 1 +1720345.com, 1 +1720346.com, 1 +1720347.com, 1 +1720348.com, 1 +1720349.com, 1 +1720350.com, 1 +174.net.nz, 1 +174343.com, 1 +1750studios.com, 0 +175dt.com, 1 +175k8.com, 1 +175ks.com, 1 +1768calc.com.au, 1 +176f88.com, 1 +178ks.net, 1 +178spb.com, 1 +17avolemsaberlaveritat.cat, 1 +17hats.com, 1 +17kpw.cc, 1 +17kpw.com, 1 +17th-airborne.tk, 1 +17xile.com, 1 +1800shutters.com, 1 +180btt.com, 1 +180k8.com, 1 +1811559.com, 1 +181k8.com, 1 +181ks.net, 1 +181z6.com, 1 +1820301.com, 1 +1820302.com, 1 +1820303.com, 1 +1820304.com, 1 +1820305.com, 1 +1820306.com, 1 +1820307.com, 1 +1820308.com, 1 +1820309.com, 1 +1820310.com, 1 +1820311.com, 1 +1820313.com, 1 +1820314.com, 1 +1820315.com, 1 +1820316.com, 1 +1820317.com, 1 +1820318.com, 1 +1820319.com, 1 +1820320.com, 1 +1820321.com, 1 +1820322.com, 1 +1820323.com, 1 +1820324.com, 1 +1820325.com, 1 +1820326.com, 1 +1820327.com, 1 +1820328.com, 1 +1820329.com, 1 +1820330.com, 1 +1820331.com, 1 +1820332.com, 1 +1820333.com, 1 +1820334.com, 1 +1820335.com, 1 +1820336.com, 1 +1820337.com, 1 +1820338.com, 1 +1820340.com, 1 +1820341.com, 1 +1820342.com, 1 +1820343.com, 1 +1820344.com, 1 +1820345.com, 1 +1820346.com, 1 +1820347.com, 1 +1820348.com, 1 +1820349.com, 1 +1820350.com, 1 +182162.com, 1 +182k8.com, 1 +182wh.com, 1 +182zlong.com, 1 +1831365.com, 1 +1832365.com, 1 +1834365.com, 1 +1837365.com, 1 +183cm.tk, 1 +183zlong.com, 1 +1844329061.rsc.cdn77.org, 1 +185k8.com, 1 +186526.club, 1 +186526.top, 1 +186526.xyz, 1 +1869365.com, 1 +186kb.com, 1 +186ks.com, 1 +1876365.com, 1 +1876996.com, 1 +188cn-sb.com, 1 +188da.com, 1 +188wei.com, 1 +189dv.com, 1 +189fc.com, 1 +18celebration.com, 1 +18f.gov, 1 +18f.gsa.gov, 0 +18onlypixel.com, 1 +18onlypixels.com, 1 +18pee.com, 1 +18upchat.com, 1 +191090.com, 1 +1911trust.com, 1 +1912x.com, 1 +192.io, 0 +1920301.com, 1 +1920302.com, 1 +1920303.com, 1 +1920304.com, 1 +1920305.com, 1 +192080.com, 1 +192168ll.repair, 1 +1921958389.rsc.cdn77.org, 1 +192433.com, 1 +1939365.com, 1 +1941-45.ru, 1 +1965.ml, 1 +1972969867.rsc.cdn77.org, 1 +197k8.com, 1 +1981365.com, 1 +1981612088.rsc.cdn77.org, 1 +1989-bmw-e30-forsale-in-norcal.com, 1 +1989studio.tk, 1 +198ks.net, 1 +198wei.com, 1 +1994.io, 1 +19990bb.com, 1 +19990c.com, 1 +19990cc.com, 1 +19990d.com, 1 +19990dd.com, 1 +19990e.com, 1 +19990ee.com, 1 +19990ff.com, 1 +19990g.com, 1 +19990gg.com, 1 +19990h.com, 1 +19990hh.com, 1 +19990i.com, 1 +19990ii.com, 1 +19990j.com, 1 +19990jj.com, 1 +19990kk.com, 1 +19990ll.com, 1 +19990m.com, 1 +19990mm.com, 1 +19990o.com, 1 +19990oo.com, 1 +19990p.com, 1 +19990q.com, 1 +19990r.com, 1 +19990rr.com, 1 +19990s.com, 1 +19990ss.com, 1 +19990tt.com, 1 +19990u.com, 1 +19990uu.com, 1 +19990v.com, 1 +19990vv.com, 1 +19990ww.com, 1 +19990x.com, 1 +19990xx.com, 1 +19990y.com, 1 +19990yy.com, 0 +19990zz.com, 1 +199ks.com, 1 +19area.cn, 1 +19btt.com, 1 +19qq.vip, 1 +1a-diamantscheiben.de, 1 +1a-werkstattgeraete.de, 1 +1ab-machinery.com, 1 +1abcicka.ru, 1 +1ag777.com, 1 +1ag88.com, 1 +1allhosting.com, 1 +1android.de, 1 +1baks.tk, 1 +1bis.ru, 1 +1bitcoinprice.com, 1 +1blazing.cf, 1 +1breadcrumb.com, 1 +1breadcrumb.com.au, 1 +1c-power.ru, 1 +1chan.pl, 1 +1codex.online, 1 +1cover.co.nz, 1 +1cover.com.au, 1 +1cplsd.store, 1 +1cprosto.tk, 1 +1csgo.org, 1 +1cswd.com, 1 +1datatec.com, 1 +1day1ac.red, 1 +1dollar.ml, 1 +1dollarwebsite.gq, 1 +1e9.nl, 1 +1eanda.com, 1 +1er-secours.ch, 0 +1europlan.nl, 1 +1f123.net, 1 +1fach-digital.de, 1 +1fastcourse.com, 1 +1fax.com, 1 +1fc0.org, 1 +1gp.us, 1 +1hc.be, 1 +1hfree.tk, 1 +1huiszoeken.nl, 1 +1ii.im, 1 +1in9.net, 1 +1it.click, 1 +1js.de, 1 +1kando.com, 0 +1kdui.com, 1 +1ki174.com, 1 +1kmi.co, 1 +1lc1.com, 1 +1ll.uk, 1 +1lord1faith.com, 1 +1m.duckdns.org, 1 +1malaysian.tk, 1 +1mall.shop, 1 +1masquepourtous.com, 1 +1me.cz, 1 +1minutoomenos.com, 1 +1montre.fr, 1 +1morebounce.co.uk, 1 +1nian.vip, 1 +1oaklasvegas.com, 1 +1of16.de, 0 +1on1on1.de, 1 +1on1on1.tv, 1 +1onehouse.com, 1 +1p.ro, 0 +1panorama.ru, 1 +1para.net, 1 +1password.ca, 1 +1password.com, 1 +1password.eu, 1 +1picture.hu, 1 +1pieces.com, 1 +1plus.red, 1 +1pluss.ee, 1 +1pw.ca, 1 +1px.tv, 1 +1q2w.nl, 1 +1q365a.com, 1 +1r.is, 1 +1rs.nl, 1 +1salland.nl, 1 +1sand0s.nl, 1 +1scope.com, 1 +1se.co, 1 +1se2or3.com, 1 +1st-bounce.co.uk, 1 +1st-community.de, 1 +1st-online-academy.com, 1 +1st2bounce.com, 1 +1stav.dk, 1 +1stchoicelandscapingwa.com, 1 +1stchoicemoney.com, 1 +1stclassbouncycastles.co.uk, 1 +1stforfun.co.uk, 1 +1stpeninsulabouncers.co.uk, 1 +1ststop.co.uk, 1 +1ticks.com, 1 +1u0m.com, 1 +1up.it, 1 +1v1.xyz, 1 +1v9.im, 1 +1v9.io, 1 +1volcano.ru, 1 +1voz.org, 1 +1vpns.com, 1 +1way.faith, 1 +1whw.co.uk, 1 +1whw.uk, 1 +1wirelog.de, 1 +1wl.uk, 1 +1x2magazine.com, 1 +1x2magazine.eu, 1 +1xbet.by, 1 +1xbet.com, 1 +1xbet.com.mx, 1 +1xbet.in, 1 +1xbet.ke, 1 +1xbet.kz, 1 +1xbet.ng, 1 +1xbetapk.com, 1 +1xstavka.ru, 1 +1xtranslate.com, 1 +1zavse.si, 1 +1zombie.team, 1 +2-euromuenzen.de, 1 +2.ag, 1 +2.wtf, 1 +200.ee, 1 +200.network, 1 +2000.is, 1 +2000feet.tk, 1 +2000meter.no, 1 +2001y.me, 1 +2002000.xyz, 1 +200201.xyz, 1 +20071019780415.com, 1 +2007gp.com, 1 +200aaaa.com, 1 +200bbbb.com, 1 +200cccc.com, 1 +200fcw.com, 1 +200ffff.com, 1 +200gggg.com, 1 +200hhhh.com, 1 +200iiii.com, 1 +200jjjj.com, 1 +200kkkk.com, 1 +200llll.com, 1 +200mmmm.com, 1 +200oooo.com, 1 +200pppp.com, 1 +200qqqq.com, 1 +200rrrr.com, 1 +200uuuu.com, 1 +200vvvv.com, 1 +200wwww.com, 1 +200yyyy.com, 1 +200zzzz.com, 1 +2012.ovh, 1 +2012review.tk, 1 +2013review.tk, 1 +20150412.xyz, 1 +2015review.tk, 1 +2016.ga, 1 +2016.tk, 1 +2017c.com, 1 +2018-frisuren.tk, 1 +2018.wales, 1 +2018fifaworldcup.tk, 1 +2018j95.com, 1 +2019j95.com, 1 +2020j95.com, 1 +2021j95.com, 1 +2022class1.ga, 1 +2022j95.com, 1 +2023j95.com, 1 +2024j95.com, 1 +2025j95.com, 1 +2026j95.com, 1 +202jj.com, 1 +2030404.com, 1 +2030411.com, 1 +2033002.com, 1 +2033003.com, 1 +2033004.com, 1 +2033005.com, 1 +2033006.com, 1 +2033007.com, 1 +2033008.com, 1 +2033009.com, 1 +2033010.com, 1 +2033011.com, 1 +2033a.com, 1 +2033b.com, 1 +2033c.com, 1 +2033z.com, 1 +204504byse.info, 1 +2048-spiel.de, 1 +2048game.co.uk, 1 +205jj.com, 1 +207ss.com, 1 +207vv.com, 1 +2083236893.com, 1 +208garfield.com, 1 +208wns.com, 1 +209vv.com, 1 +20at.com, 1 +20denier.com, 1 +2113.ch, 1 +211hh.com, 1 +2122bet.com, 1 +2132hb.com, 0 +213k8.com, 1 +21566365.com, 0 +215dy.net, 1 +216vv.com, 1 +219k8.com, 1 +21stcenturycarpentry.com.au, 1 +21x9.org, 1 +22.ag, 1 +220220.de, 1 +220control.ru, 1 +22168365.com, 1 +222001.com, 1 +222111.cc, 1 +2222365t.com, 1 +2222k8.com, 1 +2222k8.net, 1 +222321365.com, 1 +2226321.com, 1 +2227552.com, 1 +222b58.com, 1 +222bet86.com, 1 +222digits.pl, 1 +222k8.com, 1 +222k8.net, 1 +222tips.com, 1 +22321365.com, 1 +224918.com, 1 +225485.com, 1 +2255motion.com, 1 +2277bet.com, 1 +228668.com, 1 +22884.org, 1 +2288422.com, 1 +2288499.com, 1 +22884a.com, 1 +22884b.com, 1 +22884c.com, 1 +22884d.com, 1 +22884e.com, 1 +22884f.com, 1 +22884g.com, 1 +22884h.com, 1 +22918.net, 1 +22994.org, 1 +2299411.com, 1 +2299422.com, 1 +2299433.com, 1 +2299455.com, 1 +2299466.com, 1 +2299477.com, 1 +2299488.com, 1 +22aaee.com, 1 +22aagg.com, 1 +22aahh.com, 1 +22aaii.com, 1 +22aajj.com, 1 +22aarr.com, 1 +22aaxx.com, 1 +22aayy.com, 1 +22ag6.com, 1 +22atat.com, 1 +22b31.com, 1 +22b58.com, 1 +22bbgg.com, 1 +22bbhh.com, 1 +22bbii.com, 1 +22bbjj.com, 1 +22bbtt.com, 1 +22bet.com, 1 +22bet.ng, 1 +22bet86.com, 1 +22ccaa.com, 1 +22ccbb.com, 1 +22ccpp.com, 1 +22ccxx.com, 1 +22cncn.com, 1 +22d.io, 1 +22ddhh.com, 1 +22ddii.com, 1 +22ddkk.com, 1 +22ddpp.com, 1 +22ddqq.com, 1 +22ddrr.com, 1 +22delta.com, 1 +22digital.agency, 1 +22eebb.com, 1 +22eedd.com, 1 +22eeff.com, 1 +22eegg.com, 1 +22eekk.com, 1 +22eess.com, 1 +22ffee.com, 1 +22ffpp.com, 1 +22ffxx.com, 1 +22ggaa.com, 1 +22ggdd.com, 1 +22haose.com, 1 +22hehe.com, 1 +22hhcc.com, 1 +22hhii.com, 1 +22hhqq.com, 1 +22i.co.uk, 1 +22iigg.com, 1 +22iirr.com, 1 +22iiyy.com, 1 +22jjbb.com, 1 +22jjdd.com, 1 +22jjyy.com, 1 +22kkdd.com, 1 +22kkpp.com, 1 +22kkyy.com, 1 +22momo.com, 1 +22ppdd.com, 1 +22ppgg.com, 1 +22ppss.com, 1 +22pptt.com, 1 +22qqbb.com, 1 +22qqgg.com, 1 +22qqii.com, 1 +22qqrr.com, 1 +22qqtt.com, 1 +22rree.com, 1 +22rrff.com, 1 +22rrss.com, 1 +22ssbb.com, 1 +22ssjj.com, 1 +22sskk.com, 1 +22sstt.com, 1 +22tete.com, 1 +22times.com, 1 +22ttgg.com, 1 +22vetter.st, 1 +22xxhh.com, 1 +22xxjj.com, 1 +22xxyy.com, 1 +22yybb.com, 1 +22yydd.com, 1 +22yyii.com, 1 +22yyjj.com, 1 +22yykk.com, 1 +22yypp.com, 1 +22yyqq.com, 1 +22yyrr.com, 1 +22yyss.com, 1 +22yytt.com, 1 +22yyxx.com, 1 +230beats.com, 1 +232192.com, 1 +2322bet.com, 1 +233.be, 1 +233.land, 1 +233.services, 1 +2333.press, 1 +233333.ga, 1 +2333666.xyz, 1 +2333blog.com, 1 +2333z6.com, 1 +23365t.com, 1 +2337365.com, 1 +233abc.com, 0 +233blog.com, 1 +233boy.com, 1 +233hub.com, 1 +233hub.net, 1 +233hub.org, 1 +233hugo.com, 1 +233image.land, 1 +233now.com, 1 +233ss.net, 1 +233try.com, 1 +233v2.com, 1 +233vps.com, 1 +233yes.com, 1 +2340365.com, 0 +23436565.com, 1 +2345666365.com, 1 +234567365.com, 1 +2345678365.com, 1 +23456789365.com, 1 +2346321.com, 1 +234666365.com, 1 +235551.com, 1 +235u.net, 1 +236530.com, 1 +236560.com, 1 +236570.com, 1 +2366bet.com, 1 +23732.com, 1 +2377bet.com, 1 +238212.com, 1 +2399bet.com, 1 +23ks.app, 1 +24-7.jp, 1 +24.ie, 1 +240vv.com, 1 +241552.com, 1 +242552.com, 1 +245990.xyz, 1 +245meadowvistaway.com, 0 +246060.ru, 1 +246773.com, 1 +247a.co.uk, 1 +247able.com, 1 +247courierservices.co.in, 1 +247healthshop.com, 1 +247medplan.com, 1 +247megamart.com.au, 1 +247naijabuzz.com, 1 +247xchanger.com, 1 +2484811.com, 1 +24848168.com, 1 +24848188.com, 1 +2484822.com, 1 +2484833.com, 1 +2484855.com, 1 +24848588.com, 1 +24848678.com, 1 +24848918.com, 1 +24848966.com, 1 +24848988.com, 1 +24848a.vip, 1 +24848b.vip, 1 +24848c.vip, 1 +24848d.vip, 1 +24848e.vip, 1 +24848h.vip, 1 +24848jj.com, 1 +24848kk.com, 1 +24848ll.com, 1 +24848mm.com, 1 +24848nn.com, 1 +24848oo.com, 1 +24848pp.com, 1 +24848qq.com, 1 +24848rr.com, 1 +24848ss.com, 1 +24848tt.com, 1 +24848uu.com, 1 +24848v.vip, 1 +24848vv.com, 1 +24848w.vip, 1 +24848ww.com, 1 +24848x.vip, 1 +24848xx.com, 1 +24848y.vip, 1 +24848yy.com, 1 +24848z.vip, 1 +24848zz.com, 1 +248663.com, 1 +2495dentalimplants.com, 1 +249722.com, 1 +249cq.com, 1 +24bel.ru, 1 +24buffalo.com, 1 +24dian30.com, 1 +24gazette.ga, 1 +24hour-locksmithsanantonio.com, 1 +24hourcyclist.co.uk, 1 +24hourelectricalservices.co.uk, 1 +24hourlocksmithbaltimore.com, 1 +24hourlocksmithdallastx.com, 1 +24hourlocksmithdetroit.com, 1 +24hourlocksmithhoustontx.com, 1 +24hourlocksmithshouston.com, 1 +24hourlocksmithspring.com, 1 +24hoursanantoniolocksmiths.com, 1 +24hourscienceprojects.com, 1 +24ip.com, 1 +24ip.de, 1 +24ip.fr, 1 +24kbet.com, 1 +24ohrana.com, 1 +24onlain.tk, 1 +24onlinereview.com, 1 +24seven.com.np, 1 +24seven.pk, 0 +24webservice.nl, 1 +24zpravy.cz, 1 +2502.net, 1 +250708.com, 1 +2525admin.nl, 1 +2555z6.com, 1 +255k8.com, 1 +256ac.com, 1 +256be.com, 1 +256bf.com, 1 +256bl.com, 1 +256bp.com, 1 +256bq.com, 1 +256br.com, 1 +256bt.com, 1 +256bx.com, 1 +256hh.com, 1 +256k.me, 1 +256pb.com, 1 +256pf.com, 1 +256rr.com, 1 +256tq.com, 1 +258877.com, 1 +259885.com, 1 +25may.tk, 1 +25percent.me, 1 +25reinyan25.net, 1 +26004.cc, 1 +2600edinburgh.org, 1 +2600hq.com, 1 +260887.com, 1 +262569.com, 1 +263.info, 1 +269196.com, 1 +26bbc.com, 1 +26ce.com, 1 +26ck.com, 1 +26gt.com, 1 +26ja.com, 1 +26nc.com, 1 +26nd.com, 1 +26pg.com, 1 +26pn.com, 1 +26sn.com, 1 +26sr.com, 1 +26ssb.com, 1 +26uuu.info, 1 +26uuu.mobi, 1 +26uuu.us, 1 +27000.best, 1 +2718282.net, 1 +272live.com, 1 +276771.com, 1 +27728522.com, 1 +277z6.com, 1 +28-industries.com, 1 +281116.com, 1 +281180.de, 1 +281ks.com, 1 +282ks.com, 1 +28365cn-365.com, 1 +28428.com, 0 +284365.com, 1 +285551.com, 1 +2858958.com, 1 +2881dh.com, 1 +288cn-563.com, 1 +288game.net, 1 +288k8.com, 1 +2890.ltd, 1 +28peaks.com, 1 +28spots.net, 1 +291167.xyz, 1 +2912.nl, 1 +29227.com, 1 +2948.ca, 1 +297computers.com, 1 +2991236.com, 1 +299ks.com, 1 +299ks.net, 1 +299zzz.com, 1 +2ag88.com, 1 +2au.ru, 1 +2b2b.pro, 1 +2b3b.com, 1 +2bas.nl, 1 +2bcompany.ch, 0 +2bet86.com, 1 +2bis10.de, 1 +2bitout.com, 1 +2blazing.cf, 1 +2bougie.com, 1 +2business.ml, 1 +2c-b.com, 1 +2c-d.com, 1 +2c-e.com, 1 +2c-t-2.com, 1 +2c-t-7.com, 1 +2c-t-8.com, 1 +2cash.ru, 1 +2cat.cc, 1 +2cb.rocks, 1 +2chan.eu, 1 +2chan.jp, 1 +2cv-fahrer.de, 1 +2cx.net, 1 +2dk.info, 1 +2driver-ok.ml, 1 +2earn-online.com, 0 +2fm.ie, 1 +2fm.radio, 1 +2fr3.com, 1 +2fraud.pro, 1 +2g1s.net, 1 +2gen.com, 1 +2gether.fr, 1 +2gisparser.tk, 1 +2h-nagoya.org, 1 +2habc.com, 1 +2heartsbookings.co.uk, 1 +2hypeenterprises.com, 1 +2img.net, 1 +2isk.in, 1 +2jhb.com, 1 +2kgwf.fi, 1 +2krueger.de, 1 +2learncomputing.ga, 1 +2li.ch, 1 +2link.ga, 1 +2lovebirdsblog.com, 1 +2manydots.nl, 1 +2mb.solutions, 1 +2me.cl, 0 +2melo.fr, 1 +2mfitnessduo.com, 1 +2mileservice.com, 1 +2mir.com, 1 +2monkeysandme.com, 1 +2nains.ch, 1 +2ndmileservice.com, 1 +2nerds1bit.com, 1 +2nics.net, 1 +2nimpresores.es, 1 +2of.me, 1 +2pay.fr, 1 +2q.ru, 1 +2rsc.com, 1 +2rsc.net, 1 +2sendai.net, 1 +2stv.net, 0 +2th.me, 1 +2travel8.world, 1 +2tt1.org, 1 +2tuu.com, 1 +2ulcceria.nl, 1 +2url.link, 1 +2vp-an.online, 1 +2wheel.com, 0 +2x.nu, 1 +2y.fi, 1 +2y3x.com, 1 +2yy.nl, 1 +3-dot-careapp1-146314.appspot.com, 1 +3000peaks.com, 1 +30019cc.com, 1 +3007337.com, 1 +300aaaa.com, 1 +300bbbb.com, 1 +300cccc.com, 1 +300dddd.com, 1 +300hhhh.com, 1 +300jjjj.com, 1 +300kkkk.com, 1 +300llll.com, 1 +300mmmm.com, 1 +300oooo.com, 1 +300qqqq.com, 1 +300rrrr.com, 1 +300uuuu.com, 1 +300xxxx.com, 1 +301.moe, 1 +301.technology, 1 +302422.com, 1 +3033888.com, 1 +303422.com, 1 +30375500.com, 1 +30375511.com, 0 +30375533.com, 1 +30375544.com, 0 +30375555.com, 0 +30375566.com, 0 +30375577.com, 0 +3040519.com, 1 +304122.com, 1 +304322.com, 1 +304622.com, 1 +3056999.com, 1 +308xpj.com, 0 +309422.com, 1 +30bet365.com, 1 +30for30podcasts.com, 1 +30hzcollective.com, 1 +310422.com, 1 +311186.com, 1 +311191.com, 1 +3133bet.com, 1 +313422.com, 1 +313xpj.com, 0 +314022.com, 1 +314122.com, 1 +314322.com, 1 +314522.com, 1 +314553.com, 1 +314622.com, 1 +314633.com, 1 +314922.com, 1 +315422.com, 1 +315xpj.com, 0 +316433.com, 1 +3165365.com, 1 +3175365.com, 1 +317811111.com, 1 +31782222.com, 1 +317822222.com, 1 +31783333.com, 1 +317833333.com, 1 +31784444.com, 1 +317844444.com, 1 +317855555.com, 1 +31786666.com, 1 +317866666.com, 1 +3178666666.com, 1 +317877777.com, 1 +3178888888.com, 1 +31789999.com, 1 +317899999.com, 1 +3178aaa.com, 1 +3178b.com, 1 +3178bbb.com, 0 +3178c.com, 1 +3178ccc.com, 1 +3178dd.com, 1 +3178ddd.com, 1 +3178e.com, 1 +3178eee.com, 1 +3178f.com, 1 +3178fff.com, 1 +3178g.com, 1 +3178h.com, 1 +3178i.com, 1 +3178iii.com, 1 +3178j.com, 1 +3178jjj.com, 1 +3178l.com, 1 +3178m.com, 1 +3178n.com, 1 +3178o.com, 1 +3178p.com, 1 +3178ppp.com, 1 +3178qqq.com, 1 +3178rrr.com, 1 +3178tt.com, 1 +3178ttt.com, 1 +3178uuu.com, 1 +3178vvv.com, 1 +3178ww.com, 1 +3178www.com, 1 +3178xx.com, 1 +3178xxx.com, 1 +3178yy.com, 1 +3178yyy.com, 1 +3178zzz.com, 1 +319422.com, 1 +319k3.com, 1 +319xpj.com, 1 +31du.cn, 1 +320281.net, 1 +321132.com, 1 +321666365.com, 1 +321live.nl, 1 +3233bet.com, 1 +323kkk.com, 1 +324022.com, 1 +324122.com, 1 +324133.com, 1 +324522.com, 1 +324533.com, 1 +324922.com, 1 +325422.com, 1 +325552.com, 1 +326422.com, 1 +326433.com, 1 +3265623.com, 1 +329422.com, 1 +32bet365.com, 1 +32h.de, 1 +33-km.ru, 1 +33168365.com, 1 +33321365.com, 1 +333321365.com, 1 +3333365t.com, 1 +333365t.com, 1 +3333k8.com, 1 +3333k8.net, 1 +3333ylc.cc, 1 +3336321.com, 1 +33365t.com, 1 +333bet86.com, 1 +33445111.com, 1 +33445222.com, 1 +33445444.com, 1 +3345.com, 1 +3351p.com, 1 +335a.cc, 1 +3369p.com, 1 +336yh.com, 1 +338393.com, 1 +3389p.com, 1 +338da.com, 1 +338sa.com, 1 +33acac.com, 1 +33b58.com, 1 +33btt.net, 1 +33devici.ml, 1 +33knkn.com, 1 +33weishang.com, 1 +33zv.com, 1 +33zxzx.com, 1 +34-restaurant.co.uk, 1 +340422.com, 1 +340622.com, 1 +340922.com, 1 +341422.com, 1 +341433.com, 1 +341533.com, 1 +341633.com, 1 +341733.com, 1 +341922.com, 1 +342022.com, 1 +342033.com, 1 +342133.com, 1 +342633.com, 1 +342733.com, 1 +342922.com, 1 +342933.com, 1 +343022.com, 1 +3433bet.com, 1 +343622.com, 1 +34365t.com, 1 +343722.com, 1 +343922.com, 1 +34536565.com, 1 +3455bet.com, 1 +345666365.com, 1 +3456666365.com, 1 +345678365.com, 1 +3456789365.com, 1 +346022.com, 1 +346033.com, 1 +346122.com, 1 +346233.com, 1 +346322.com, 1 +346422.com, 1 +346522.com, 1 +346533.com, 1 +3466bet.com, 1 +346722.com, 1 +346922.com, 1 +3473-wiki.de, 1 +347552.com, 1 +3477bet.com, 1 +348233.com, 1 +348433.com, 1 +348533.com, 1 +348663.com, 1 +349022.com, 1 +349033.com, 1 +349233.com, 1 +349433.com, 1 +349533.com, 1 +34ac.com, 1 +34ax.com, 1 +34bg.com, 1 +34bk.com, 1 +34da.com, 1 +34fc.com, 1 +34fy.com, 1 +34gr.com, 1 +34gv.com, 1 +34hc.com, 1 +34if.com, 1 +34il.com, 1 +34iu.com, 1 +34iv.com, 1 +34ix.com, 1 +34ja.com, 1 +34jb.com, 1 +34jg.com, 1 +34ji.com, 1 +34jm.com, 1 +34jn.com, 1 +34jw.com, 1 +34kr.com, 1 +34lb.com, 1 +34ld.com, 1 +34lp.com, 1 +34lq.com, 1 +34lr.com, 1 +34nd.com, 1 +34nh.com, 1 +34nj.com, 1 +34nv.com, 1 +34nw.com, 1 +34oa.com, 1 +34oh.com, 1 +34om.com, 1 +34oy.com, 1 +34pv.com, 1 +34py.com, 1 +34qa.com, 1 +34qf.com, 1 +34qx.com, 1 +34sh.com, 1 +34sk.com, 1 +34uf.com, 1 +34va.com, 1 +34vd.com, 1 +34vh.com, 1 +34vi.com, 1 +34vt.com, 1 +34vu.com, 1 +34vz.com, 1 +34xc.com, 1 +34xt.com, 1 +34xu.com, 1 +34yt.com, 1 +34zi.com, 1 +34zq.com, 1 +350.org, 1 +350422.com, 1 +35089y.com, 1 +350vv.com, 1 +351079.com, 1 +351113.com, 1 +351365.com, 1 +3539783.com, 1 +354022.com, 1 +354133.com, 1 +354233.com, 1 +354622.com, 1 +354633.com, 1 +354922.com, 1 +354933.com, 1 +3559365.com, 1 +356433.com, 1 +357601.com, 1 +35898a.com, 1 +35898b.com, 1 +35898c.com, 1 +35898d.com, 1 +35898e.com, 1 +35898f.com, 1 +35898g.com, 1 +35898h.com, 1 +35898j.com, 1 +35898k.com, 1 +35898m.com, 1 +35898s.com, 1 +35898w.com, 1 +35898x.com, 1 +35898y.com, 1 +35898z.com, 1 +35dr.com, 1 +35if.com, 1 +35jq.com, 1 +35ud.com, 1 +35ue.com, 1 +35uj.com, 1 +35vn.com, 1 +360-ot.de, 1 +360365.com, 1 +360bcty.com, 1 +360cycling.com.br, 1 +360gradus.com, 0 +360hosting.com.au, 1 +360kuvia.fi, 1 +360live.fr, 1 +360prokuvat.fi, 1 +360rail.nl, 1 +360videoshare.com, 1 +360vrs.com, 1 +361116.com, 1 +3615jacky.fr, 1 +362590.com, 1 +363331.com, 1 +364553.com, 1 +365.asia, 1 +365.systems, 1 +36506088.com, 1 +36506099.com, 1 +3651145.com, 1 +3651146.com, 1 +3651147.com, 1 +3651149.com, 1 +3651201.com, 1 +3651202.com, 1 +3651203.com, 1 +3651204.com, 1 +3651205.com, 1 +3651267.com, 0 +3652367.com, 0 +3652389.com, 0 +36525.hk, 1 +36533c.com, 1 +36533d.com, 1 +36533e.com, 1 +36533f.com, 1 +36533g.com, 1 +36533h.com, 1 +36533i.com, 1 +36533j.com, 1 +36533k.com, 1 +36533l.com, 1 +36533m.com, 1 +36533n.com, 1 +36533o.com, 1 +36533r.com, 1 +36533s.com, 1 +36533t.com, 1 +36533u.com, 1 +365365.com, 1 +3653650000.com, 1 +3653651111.com, 1 +36536533.vip, 0 +3653654444.com, 1 +36536555.vip, 0 +36536566.vip, 0 +36536588.vip, 0 +36536599.vip, 0 +3654.vip, 1 +3655053.com, 1 +36554ll.com, 1 +36554mm.com, 1 +3655612.com, 0 +3655623.com, 0 +3655634.com, 0 +3655645.com, 0 +365600dl.com, 1 +36565123.com, 1 +36565234.com, 1 +36565345.com, 1 +365654321.com, 1 +36565456.com, 1 +36565567.com, 1 +36565678.com, 1 +36565789.com, 1 +36565b.com, 1 +36565f.com, 1 +3656701.com, 0 +3656712.com, 0 +3656723.com, 0 +3656734.com, 0 +3656745.com, 0 +3656778.com, 0 +3658200.com, 1 +36587654321.com, 1 +36594a.com, 1 +36594b.com, 1 +36594c.com, 1 +3659868.com, 1 +3659869.com, 1 +3659980.com, 1 +365a1.com, 1 +365beautyworld.com, 1 +365cn-288.com, 1 +365d88.com, 1 +365daysreview.com, 1 +365eib.com, 1 +365eif.com, 1 +365eil.com, 1 +365eiq.com, 1 +365eis.com, 1 +365eiv.com, 1 +365eiw.com, 1 +365electricalvn.com, 1 +365healthworld.com, 1 +365iosapp.com, 1 +365nnnn.com, 0 +365propertybuyer.co.uk, 0 +365q01.com, 1 +365r.co, 0 +365sb-cn.com, 1 +365securitymg.com, 1 +365skulls.com, 1 +365y0.com, 1 +365y00.com, 1 +365y11.com, 1 +365y2.com, 1 +365y22.com, 1 +365y3.com, 1 +365y33.com, 1 +365y5.com, 1 +365y55.com, 1 +365y6.com, 1 +365y66.com, 1 +365y7.com, 1 +365y77.com, 1 +365y9.com, 1 +365y99.com, 1 +365yapan.com, 1 +365ypw.com, 1 +365yuwen.com, 1 +365zg.org, 1 +3666ks.com, 1 +369az.com, 1 +369bk.com, 1 +369bn.com, 1 +369bu.com, 1 +369bw.com, 1 +369cd.com, 1 +369ck.com, 1 +369cr.com, 1 +369cu.com, 1 +369dp.com, 1 +369dr.com, 1 +369ec.com, 1 +369eh.com, 1 +369em.com, 1 +369ep.com, 1 +369eq.com, 1 +369ex.com, 1 +369fj.com, 1 +369fn.com, 1 +369ft.com, 1 +369fy.com, 1 +369gh.com, 1 +369gp.com, 1 +369ja.com, 1 +369mr.com, 1 +369nk.com, 1 +369pb.com, 1 +369qb.com, 1 +369ra.com, 1 +369rr.com, 1 +369ve.com, 1 +369wt.com, 1 +36ag8.com, 1 +36ga.com, 1 +36gx.com, 1 +36ja.com, 1 +36jn.com, 1 +36kn.com, 1 +36ky.com, 1 +36pd.com, 1 +36pg.com, 1 +36xk.com, 1 +36xn.com, 1 +36yf.com, 1 +36yj.com, 1 +370422.com, 1 +371422.com, 1 +371cloud.com, 0 +372bbb.com, 1 +373.moe, 1 +3733366.xyz, 1 +373422.com, 1 +374933.com, 1 +375422.com, 1 +375ks.com, 1 +377625.com, 1 +377632.com, 1 +377817.com, 1 +3778vip.com, 0 +377ks.com, 1 +377zzz.com, 1 +37879.com, 0 +37889658.com, 0 +378901.com, 1 +378902.com, 1 +378bbb.com, 1 +379700.com, 1 +37987.com, 1 +37987a.com, 1 +37987c.com, 1 +37987d.com, 1 +37987e.com, 1 +37987f.com, 1 +37zk.com, 1 +37zw.com, 1 +380111000.com, 1 +380111111.com, 0 +380111222.com, 0 +380111333.com, 0 +380111444.com, 0 +380111555.com, 0 +380111666.com, 0 +380111777.com, 1 +380111888.com, 0 +380222000.com, 0 +380222111.com, 0 +380222222.com, 0 +380222333.com, 0 +380222444.com, 0 +380222555.com, 0 +380222666.com, 0 +380222777.com, 0 +380222888.com, 0 +380222999.com, 0 +3803300.com, 0 +380422.com, 1 +3806600.com, 0 +3807722.com, 0 +380805.com, 1 +3808833.com, 0 +3809955.com, 0 +381115.com, 1 +38138938.com, 1 +382225.com, 1 +3837a.com, 1 +3837app.com, 1 +3837app3837app.com, 1 +3837app3837app3837app.com, 1 +3837b.com, 1 +3837c.com, 1 +3837d.com, 1 +3837e.com, 1 +3837g.com, 1 +3837h.com, 1 +3837i.com, 1 +3837j.com, 1 +3837k.com, 1 +3837l.com, 1 +3837m.com, 1 +3837n.com, 1 +3837o.com, 1 +3837p.com, 1 +3837q.com, 1 +3837r.com, 1 +3837s.com, 1 +3837t.com, 1 +3837u.com, 1 +3837v.com, 1 +3837w.com, 1 +3837x.com, 1 +3837y.com, 1 +3837z.com, 1 +383838.plus, 1 +3838onndo.tk, 1 +3839.ca, 1 +383aaa.com, 1 +3880p.com, 1 +38888msc.com, 1 +388da.com, 1 +38irkutsk.tk, 1 +390422.com, 1 +391119.com, 1 +391231.com, 1 +392365.com, 0 +392422.com, 1 +393335.ml, 0 +393422.com, 1 +394022.com, 1 +394122.com, 1 +394322.com, 1 +394522.com, 1 +394553.com, 1 +394622.com, 1 +394922.com, 1 +3957b.com, 1 +3957d.com, 1 +3957f.com, 1 +3957g.com, 1 +396228.com, 1 +396301.com, 1 +396302.com, 1 +396303.com, 1 +396304.com, 1 +396305.com, 1 +3963aa.com, 1 +3963bb.com, 1 +3963cc.com, 1 +3963dd.com, 1 +3963ee.com, 1 +396422.com, 1 +3970a.com, 1 +3970aa.com, 1 +3970abc.com, 1 +3970b.com, 1 +3970bb.com, 1 +3970bc.com, 1 +3970c.com, 1 +3970cc.com, 1 +3970ccc.com, 1 +3970d.com, 1 +3970dd.com, 1 +3970ee.com, 1 +3970f.com, 1 +3970fa.com, 1 +3970ff.com, 1 +3970g.com, 1 +3970gg.com, 1 +3970go.com, 1 +3970h.com, 1 +3970hh.com, 1 +3970i.com, 1 +3970ii.com, 1 +3970j.com, 1 +3970jj.com, 1 +3970k.com, 1 +3970kk.com, 1 +3970ku.com, 1 +3970l.com, 1 +3970ll.com, 1 +3970mm.com, 1 +3970n.com, 1 +3970o.com, 1 +3970ok.com, 1 +3970oo.com, 1 +3970p.com, 1 +3970pp.com, 1 +3970q.com, 1 +3970qq.com, 1 +3970r.com, 1 +3970rr.com, 1 +3970s.com, 1 +3970ss.com, 1 +3970t.com, 1 +3970tt.com, 1 +3970u.com, 1 +3970uu.com, 1 +3970v.com, 1 +3970vv.com, 1 +3970w.com, 1 +3970win.com, 1 +3970ww.com, 1 +3970x.com, 1 +3970xx.com, 1 +3970y.com, 1 +3970yes.com, 1 +3970ylc.com, 1 +3970yy.com, 1 +3970z.com, 1 +3970zz.com, 1 +398.info, 1 +3987.com, 1 +399z6.com, 1 +39news.tk, 1 +39sihu.com, 0 +39w66.com, 1 +3aa365.com, 1 +3accounts.ml, 1 +3aexpert.com.ua, 1 +3ags.de, 1 +3amtoolbox.se, 1 +3ank.in, 0 +3b.pm, 1 +3bb365.com, 1 +3bet86.com, 1 +3bigking.com, 1 +3blazing.cf, 1 +3c-d.de, 1 +3candy.com, 1 +3cbalance.pl, 1 +3cc365.com, 1 +3commas.io, 1 +3countiescastlehire.co.uk, 1 +3cs.ch, 1 +3d-animator.net, 1 +3d-fotoservice.de, 1 +3d-glow.de, 1 +3d-station.fr, 1 +3dagentur.com, 1 +3danimation.tk, 1 +3dapartment.com, 1 +3dcollective.es, 1 +3dd365.com, 1 +3de5.nl, 1 +3deeplearner.com, 1 +3degreedesign.co.uk, 1 +3deni.com, 1 +3dexpose.tk, 1 +3dflat.tk, 1 +3dgep.com, 1 +3dissue.com, 1 +3djuegos.com, 1 +3dlab.team, 1 +3dm.audio, 1 +3dmedium.de, 1 +3dmetalprinting.tk, 1 +3dmusiclab.nl, 1 +3dn-modell.hu, 1 +3dnchu.com, 1 +3do3dont.com, 1 +3dprintsondemand.eu, 1 +3dranger.com, 1 +3dreal.tk, 1 +3dsmarket.com, 1 +3dstore.dk, 1 +3dsupplies.be, 1 +3dtech.pt, 1 +3ecpa.com.hk, 1 +3ecpa.com.my, 1 +3ecpa.com.sg, 1 +3ee365.com, 1 +3elife.vn, 0 +3em1.pt, 1 +3ff365.com, 1 +3gdu.tk, 1 +3gg365.com, 1 +3haeuserprojekt.org, 1 +3haueserprojekt.org, 1 +3hh365.com, 1 +3hl0.net, 1 +3i-infotech.com, 1 +3ii365.com, 1 +3james.com, 1 +3jj365.com, 1 +3logic.ru, 1 +3lot.ru, 1 +3mediaweb.com, 1 +3n5b.com, 1 +3niu10.com, 1 +3niu12.com, 1 +3niu13.com, 1 +3niu15.com, 1 +3niu168.com, 1 +3niu178.com, 1 +3niu19.com, 1 +3niu2.com, 1 +3niu3.com, 1 +3niu4.com, 1 +3niu5.com, 1 +3niu6.com, 1 +3niu66.com, 1 +3niu666.com, 1 +3niu668.com, 1 +3niu7.com, 1 +3niu8.com, 1 +3niu88.com, 1 +3niu888.com, 1 +3niu9.com, 1 +3niu99.com, 1 +3niusurl.com, 1 +3niuurl.com, 1 +3orod.ml, 1 +3os.ooo, 1 +3os.org, 1 +3pestki.org, 1 +3phase.pw, 1 +3pif.de, 1 +3plusdesign.gr, 1 +3pm.tw, 1 +3prn.com, 1 +3proxy.org, 1 +3proxy.ru, 1 +3queens.cz, 1 +3queens.io, 1 +3r.org.uk, 1 +3ringenieria.com, 1 +3rr0r.com, 1 +3rr0r.net, 1 +3rr0r.org, 1 +3rsee.com, 1 +3s-datasolution.de, 1 +3s-datasolutions.de, 1 +3s-ddns.de, 1 +3s-dns.de, 1 +3s-hosting.de, 1 +3s-mail.de, 1 +3sdatasolution.de, 1 +3sdatasolutions.de, 1 +3sddns.de, 1 +3sdns.de, 1 +3shosting.de, 1 +3sixtydutyfree.com, 1 +3smail.de, 1 +3speak.co, 1 +3techjournal.cf, 1 +3v4l.org, 1 +3varta.com.ua, 1 +3vlnaeet.cz, 1 +3w-solutions.fr, 1 +3xbit.com.br, 1 +3xx.link, 1 +3xy.insure, 1 +3zzbet.com, 1 +4-0-4.ga, 1 +4-1-where.com, 1 +4-it.de, 1 +4000milestare.com, 1 +4000ok.com, 1 +4000sf.com, 1 +4005365.com, 1 +400bbbb.com, 1 +400cccc.com, 1 +400eeee.com, 1 +400gggg.com, 1 +400iiii.com, 1 +400jjjj.com, 1 +400llll.com, 1 +400nnnn.com, 1 +400pppp.com, 1 +400tttt.com, 1 +400uuuu.com, 1 +400vvvv.com, 1 +400yyyy.com, 1 +4025360.com, 1 +4025361.com, 1 +4025362.com, 1 +4025363.com, 1 +4025364.com, 1 +4025365.com, 1 +4025366.com, 1 +4025367.com, 1 +4025368.com, 1 +4025369.com, 1 +403.ch, 1 +403page.com, 1 +404.guide, 1 +4048kkk.com, 1 +4048v.com, 1 +404group.tk, 1 +404notfound.com.br, 1 +406811.com, 1 +406833.com, 1 +408663.com, 1 +4096b.com, 1 +4096bit.de, 0 +40acts.org.uk, 1 +40daysnutrition.com, 1 +40percentpapermache.com, 1 +41-where.com, 1 +41199.com, 1 +411movie.com, 1 +411quest.com, 1 +4144bet.com, 1 +414553.com, 1 +4151365.com, 1 +416365.com, 1 +418663.com, 1 +41where.com, 1 +420.nerdpol.ovh, 1 +420java.com, 1 +420screen.com, 1 +420weedcenter.com, 1 +4233065.com, 1 +4233068.com, 1 +4233069.com, 1 +4233070.com, 1 +4233330.com, 1 +4233331.com, 1 +4233332.com, 1 +4233334.com, 1 +4233335.com, 1 +4233336.com, 1 +4233337.com, 1 +4233338.com, 1 +4233339.com, 1 +4245pay.com, 1 +4251365.com, 1 +426773.com, 1 +427552.com, 1 +428northampton.com, 1 +42browning.com, 1 +42day.info, 1 +42entrepreneurs.fr, 0 +42l.fr, 1 +42t.ru, 1 +4305design.com.au, 1 +432666365.com, 1 +432web.net, 1 +434365.com, 1 +4344bet.com, 1 +4345.me, 0 +4351365.com, 1 +436773.com, 1 +437844.com, 1 +438663.com, 1 +439050.com, 1 +43klive.com, 0 +44-k.com, 1 +440887.com, 1 +44168365.com, 1 +442887.com, 1 +44321365.com, 1 +443658.com, 1 +44365t.com, 1 +443887.com, 1 +444321365.com, 1 +4447552.com, 1 +444887.com, 1 +444b58.com, 1 +444bet86.com, 1 +445887.com, 1 +44bet86.com, 1 +44feelings.com, 1 +44sec.com, 0 +451.ooo, 1 +451365.com, 1 +45365t.com, 1 +4544bet.com, 1 +4551365.com, 1 +4553.com, 1 +455327.com, 1 +455328.com, 1 +4553s.com, 1 +4553vip.com, 1 +4562030.com, 1 +4562040.com, 1 +4562050.com, 1 +45636565.com, 1 +456365t.com, 1 +4566321.com, 1 +456666365.com, 1 +4567.plus, 1 +4567666365.com, 1 +457552.com, 1 +458663.com, 1 +459022.com, 1 +45b.org, 1 +45min.ga, 1 +45secondes.fr, 1 +463855.com, 1 +4661049.com, 1 +46ae.com, 1 +46ah.com, 1 +46aj.com, 1 +46ak.com, 1 +46ap.com, 1 +46ay.com, 1 +46az.com, 1 +46bf.com, 1 +46bg.com, 1 +46bh.com, 1 +46bl.com, 1 +46bn.com, 1 +46bp.com, 1 +46bq.com, 1 +46br.com, 1 +46bx.com, 1 +46cg.com, 1 +46cu.com, 1 +46d88.com, 1 +46da.com, 1 +46db.com, 1 +46df.com, 1 +46dk.com, 1 +46dn.com, 1 +46dr.com, 1 +46ds.com, 1 +46eb.com, 1 +46ed.com, 1 +46eg.com, 1 +46ep.com, 1 +46eq.com, 1 +46et.com, 1 +46ey.com, 1 +46fn.com, 1 +46fp.com, 1 +46fq.com, 1 +46gc.com, 1 +46gi.com, 1 +46gj.com, 1 +46gk.com, 1 +46gl.com, 1 +46gx.com, 1 +46gy.com, 1 +46gz.com, 1 +46ha.com, 1 +46he.com, 1 +46hi.com, 1 +46hl.com, 1 +46ia.com, 1 +46if.com, 1 +46ig.com, 1 +46ij.com, 1 +46ik.com, 1 +46iq.com, 1 +46ir.com, 1 +46iy.com, 1 +46iz.com, 1 +46ja.com, 1 +46jc.com, 1 +46jd.com, 1 +46jr.com, 1 +46kh.com, 1 +46ki.com, 1 +46kn.com, 1 +46kp.com, 1 +46kq.com, 1 +46kt.com, 1 +46ky.com, 1 +46kz.com, 1 +46lf.com, 1 +46lk.com, 1 +46lq.com, 1 +46lt.com, 1 +46na.com, 1 +46ng.com, 1 +46ni.com, 1 +46nk.com, 1 +46nu.com, 1 +46pg.com, 1 +46pj.com, 1 +46pn.com, 1 +46pq.com, 1 +46pz.com, 1 +46ql.com, 1 +46qt.com, 1 +46ra.com, 1 +46rb.com, 1 +46rf.com, 1 +46rj.com, 1 +46rl.com, 1 +46rn.com, 1 +46rx.com, 1 +46rz.com, 1 +46sd.com, 1 +46sg.com, 1 +46sp.com, 1 +46sr.com, 1 +46sx.com, 1 +46td.com, 1 +46te.com, 1 +46tf.com, 1 +46ti.com, 1 +46tj.com, 1 +46tn.com, 1 +46tr.com, 1 +46ty.com, 1 +46tz.com, 1 +46ua.com, 1 +46ub.com, 1 +46ud.com, 1 +46ue.com, 1 +46uk.com, 1 +46uq.com, 1 +46ut.com, 1 +46ux.com, 1 +46uz.com, 1 +46xa.com, 1 +46xe.com, 1 +46xj.com, 1 +46yf.com, 1 +46yj.com, 1 +46yk.com, 1 +46yl.com, 1 +46yq.com, 1 +46yt.com, 1 +46yu.com, 1 +46yz.com, 1 +46zb.com, 1 +46ze.com, 1 +46zf.com, 1 +46zh.com, 1 +46zi.com, 1 +46zk.com, 1 +46zl.com, 1 +46zn.com, 1 +47.rs, 1 +4706666.com, 1 +4716666.com, 1 +4726666.com, 1 +4736666.com, 1 +4756666.com, 1 +4761.cc, 0 +4762.cc, 0 +476773.com, 1 +4776070.com, 1 +4786666.com, 1 +47af.com, 1 +47d88.com, 1 +47dp.com, 1 +47essays.com, 1 +47fd.com, 1 +47fl.com, 1 +47gq.com, 1 +47gr.com, 1 +47hc.com, 1 +47hf.com, 1 +47ho.com, 1 +47hv.com, 1 +47ic.com, 1 +47ix.com, 1 +47iz.com, 1 +47jc.com, 1 +47kl.com, 1 +47lo.com, 1 +47nf.com, 1 +47nt.com, 1 +47ph.com, 1 +47qe.com, 1 +47rd.com, 1 +47rv.com, 1 +47tech.com, 1 +47tf.com, 1 +47tw.com, 1 +47ty.com, 1 +47uy.com, 1 +47vg.com, 1 +47vk.com, 1 +47vy.com, 1 +47wv.com, 1 +47xc.com, 1 +47xt.com, 1 +47yi.com, 1 +47yp.com, 1 +47yr.com, 1 +47yv.com, 1 +47yw.com, 1 +47yz.com, 1 +47ze.com, 1 +47zg.com, 1 +47zv.com, 1 +48365365cn.com, 1 +48365cn-365.com, 1 +486773.com, 1 +487511.com, 1 +487522.com, 1 +487552.com, 1 +487866.com, 1 +48d88.com, 1 +48lipetsk.tk, 1 +491mhz.net, 1 +4927a.com, 1 +492977.com, 1 +492y.com, 1 +494k.com, 0 +497552.com, 0 +497773.com, 1 +498663.com, 1 +49889.com, 1 +49948522.com, 1 +499ks.net, 1 +49dollaridahoregisteredagent.com, 1 +4am.click, 1 +4baby.com.br, 1 +4best.tk, 1 +4bet86.com, 1 +4budget.ga, 1 +4c-haircare.com, 1 +4car.site, 1 +4cavaleiros.com.br, 1 +4cdesigners.com, 1 +4cut.tk, 1 +4d2.xyz, 1 +4dbygg.se, 1 +4dillusion.tk, 1 +4dlatest.com, 1 +4dpredict.com, 1 +4driver.eu, 1 +4everproxy.com, 1 +4eyes.ch, 1 +4fit.ro, 1 +4flex.info, 1 +4freepress.com, 1 +4g-server.eu, 0 +4garage.com.br, 1 +4gnews.pt, 1 +4hmediaproductions.com, 1 +4host.ch, 1 +4hourcourse.com, 1 +4huawei.ru, 1 +4hw.ru, 1 +4hypo.cz, 1 +4iners.com, 1 +4investors.de, 1 +4k3dyptt.com, 1 +4kpi.eu, 1 +4kprojektory.cz, 1 +4kvids.com, 1 +4lephants.tk, 1 +4list.ml, 1 +4loc.us, 1 +4lock.com.br, 1 +4mama.ua, 1 +4maniacos.tk, 1 +4meizu.ru, 1 +4mm.org, 1 +4nikola.de, 1 +4o5.xyz, 1 +4obgyne.com, 1 +4peace.gent, 1 +4pillarsit.com, 1 +4played.de, 1 +4played.vip, 1 +4plebs.moe, 1 +4project.co.il, 1 +4ree.tk, 1 +4screens.net, 1 +4seo.ml, 1 +4share.tv, 1 +4sics.se, 1 +4smart.cz, 1 +4smart.house, 1 +4tgw34.tk, 1 +4th-ave-studio.com, 1 +4thdc.com, 1 +4u.services, 0 +4u2ore.net, 1 +4vector.com, 1 +4vf.de, 1 +4vio.com, 1 +4voip.ru, 1 +4web-hosting.com, 1 +4web.online, 1 +4wrd.cc, 1 +4x.fi, 1 +4x4-27mc.nl, 1 +4x4.lk, 1 +4x4coatingen.nl, 1 +4x4tt.com, 1 +4xiaomi.ru, 1 +4xlabs.co, 1 +4y4a-arts.space, 1 +4yuz.net, 1 +50-ottenkov.tk, 1 +50.gy, 1 +50.pe, 1 +50.tf, 1 +5000164.com, 1 +5000164.jp, 1 +5000yz.com, 1 +5002888.com, 1 +5007999.com, 1 +500bbbb.com, 1 +500dddd.com, 1 +500eeee.com, 1 +500fcw.com, 1 +500foods.com, 1 +500iiii.com, 1 +500jjjj.com, 1 +500k.nl, 1 +500k8.com, 1 +500mmmm.com, 1 +500nnnn.com, 1 +500p.xyz, 1 +500promocodes.com, 1 +500promokodov.ru, 1 +500qqqq.com, 1 +500rrrr.com, 1 +500tttt.com, 1 +500uuuu.com, 1 +500vvvv.com, 1 +500wordessay.gq, 1 +500zzzz.com, 1 +5017501.com, 1 +5017502.com, 1 +5017503.com, 1 +5017504.com, 1 +5017505.com, 1 +5017601.com, 0 +5017602.com, 0 +5017603.com, 0 +5017604.com, 0 +5017701.com, 1 +5017702.com, 1 +5017703.com, 1 +5017704.com, 1 +5017705.com, 1 +5017801.com, 1 +5017802.com, 1 +5017803.com, 1 +5017804.com, 1 +5017805.com, 1 +502312.com, 1 +504122.com, 1 +504322.com, 1 +504622.com, 1 +504922.com, 1 +505343.com, 1 +5060711.com, 1 +5060715.com, 1 +506422.com, 1 +508kb.com, 1 +50lakeshore.com, 1 +50ma.xyz, 1 +50milli.com, 1 +50plusmusikfestival.ch, 1 +50plusnet.nl, 1 +50ten40.com, 1 +5132hb.com, 0 +513651.com, 1 +51365a.com, 1 +51365aa.com, 1 +51365b.com, 1 +51365bb.com, 1 +51365c.com, 1 +51365cc.com, 1 +51365d.com, 1 +51365dd.com, 1 +51365ee.com, 1 +513maximus.site, 1 +513x.cc, 1 +514122.com, 1 +514522.com, 1 +514622.com, 1 +514922.com, 1 +515422.com, 1 +5155bet.com, 1 +516422.com, 1 +516btt.com, 1 +516btt.net, 1 +517vpn.cn, 1 +518.com.tw, 1 +51877.net, 1 +518k8.com, 1 +519422.com, 1 +5197aa.co, 1 +5197bb.co, 1 +5197cc.co, 1 +5197dd.co, 1 +5197dh.co, 0 +5197dns.com, 1 +5197ee.co, 1 +5197ff.co, 1 +5197gg.co, 1 +5197hd.co, 1 +5197hh.co, 1 +5197ii.co, 1 +5197jj.co, 1 +5197kk.co, 1 +5197ll.co, 1 +5197m.co, 1 +5197mm.co, 1 +5197n.co, 1 +5197nn.co, 1 +5197o.co, 1 +5197oo.co, 1 +5197p.co, 1 +5197pp.co, 1 +5197q.co, 1 +5197qq.co, 1 +5197r.co, 1 +5197rr.co, 1 +5197s.co, 1 +5197ss.co, 1 +5197t.co, 1 +5197tt.co, 1 +5197u.co, 1 +5197uu.co, 1 +5197v.co, 1 +5197vv.co, 1 +5197w.co, 1 +5197ww.co, 1 +5197x.co, 1 +5197xx.co, 1 +5197y.co, 1 +5197yy.co, 1 +5197z.co, 1 +5197zz.co, 1 +51acg.eu.org, 1 +51aifuli.com, 1 +51cls.tw, 1 +51club8.com, 1 +51guaq.com, 1 +51kly.net, 1 +51tiaojiu.com, 1 +52002a.com, 1 +52002b.com, 1 +52002c.com, 1 +52002d.com, 1 +52002e.com, 1 +52002f.com, 1 +52002g.com, 1 +52002h.com, 1 +52002i.com, 1 +52002j.com, 1 +52002k.com, 1 +52002l.com, 1 +52002m.com, 1 +52002n.com, 1 +52002o.com, 1 +52002p.com, 1 +52002q.com, 1 +52002r.com, 1 +52002s.com, 1 +52002t.com, 1 +52002u.com, 1 +52002v.com, 1 +52002w.com, 1 +52002x.com, 1 +52002y.com, 1 +5201365.com, 0 +52051.com, 1 +52051a.com, 1 +5205365.com, 0 +5206365.com, 0 +5209365.com, 0 +520xpjxpj.com, 1 +5219.ml, 1 +521keyvista.com, 1 +5225sf.com, 1 +524022.com, 1 +524622.com, 1 +524922.com, 1 +525.info, 1 +5287.com, 1 +528sss.com, 1 +529kb.com, 1 +529sss.com, 1 +52b9.com, 1 +52b9.net, 1 +52danji.cc, 1 +52dashboard.com, 1 +52hentai.ml, 1 +52hentai.us, 0 +52kb1.com, 1 +52kb365.com, 0 +52ncp.net, 1 +52sykb.com, 0 +52weekspodcast.com, 1 +531422.com, 1 +531k8.com, 1 +533sss.com, 1 +534122.com, 1 +534365.com, 1 +534622.com, 1 +534922.com, 1 +535kb.com, 1 +536422.com, 1 +5364b.com, 1 +5364c.com, 1 +5364d.com, 1 +5364jc.com, 1 +538vv.com, 1 +53ningen.com, 1 +53pluk.cz, 1 +53ty.com, 1 +54.sb, 0 +540922.com, 1 +540interactive.com, 1 +541022.com, 1 +541622.com, 1 +541651.com, 1 +541722.com, 1 +541922.com, 1 +5454app.com, 1 +5455bet.com, 1 +545755.com, 1 +545922.com, 1 +546802.com, 1 +54below.com, 1 +54cuatro.com, 1 +54lsj.cc, 1 +5518k3.com, 1 +552z6.com, 1 +55321365.com, 1 +5533445.com, 1 +55365t.com, 1 +5536z.com, 1 +555321365.com, 1 +5557552.com, 1 +555b58.com, 1 +555bet86.com, 1 +555btt.com, 1 +555kb.com, 1 +555w.org, 1 +555wfcp.com, 1 +555xl.com, 1 +555zlong.com, 1 +556021.com, 1 +556185.com, 1 +5566bet.vip, 1 +556777.cc, 1 +557bbb.com, 1 +557z6.com, 1 +558btt.net, 1 +55bet86.com, 1 +55d88.com, 1 +55k66.vip, 1 +55ks.app, 1 +55opt.org, 1 +5611bet.com, 1 +5622bet.com, 1 +5633bet.com, 1 +56365t.com, 1 +5663.cc, 1 +5663.co, 1 +566380.com, 1 +56695.com, 1 +56736565.com, 1 +5676321.com, 1 +567666365.com, 1 +567667.cc, 1 +5678666365.com, 1 +56877.com, 1 +572kb.com, 1 +573sss.com, 1 +575380.com, 1 +575kb.com, 1 +5763.org, 1 +576422.com, 1 +5765.io, 1 +5781.org, 1 +578380.com, 1 +5792.org, 1 +579422.com, 1 +5795444.com, 1 +5795887.com, 1 +5796.org, 1 +5797.org, 1 +583422.com, 1 +585380.com, 1 +585422.com, 1 +586422.com, 1 +588e.com, 1 +588k8.com, 1 +5898657.com, 1 +589ks.com, 1 +58d88.com, 1 +58w66.com, 1 +591380.com, 1 +591422.com, 1 +592227.com, 1 +592422.com, 1 +5930593.com, 1 +593380.com, 1 +594022.com, 1 +594622.com, 1 +595380.com, 1 +595422.com, 1 +596422.com, 1 +59759vip.com, 1 +59759z.com, 1 +5981168.com, 1 +5981611.com, 1 +5981622.com, 1 +5981644.com, 1 +5981655.com, 1 +5981667.com, 1 +5981668.com, 1 +5981669.com, 1 +5981677.com, 1 +5981688.com, 1 +5981699.com, 1 +5981800.com, 1 +5981811.com, 1 +5981822.com, 1 +5981833.com, 1 +5981844.com, 1 +5981855.com, 1 +5981866.com, 1 +5981877.com, 1 +5981899.com, 1 +5981918.com, 1 +5981a.com, 1 +5981b.com, 1 +5981c.com, 1 +5981d.com, 1 +5981e.com, 1 +5981f.com, 1 +5981g.com, 1 +5981h.com, 1 +5981i.com, 1 +5981j.com, 1 +5981k.com, 1 +5981l.com, 1 +5981m.com, 1 +5981n.com, 1 +5981o.com, 1 +5981p.com, 1 +5981q.com, 1 +5981r.com, 1 +5981s.com, 1 +5981t.com, 1 +5981u.com, 1 +5981v.com, 1 +5981w.com, 1 +5981x.com, 1 +5981y.com, 0 +5981z.com, 1 +59859h.vip, 1 +59859j.vip, 1 +59859k.vip, 1 +59859l.vip, 1 +59859y.vip, 1 +59859z.vip, 1 +5986fc.com, 1 +59937.com, 1 +5997891.com, 1 +599980.com, 1 +59rus.tk, 1 +5a6j.com, 1 +5agks.com, 1 +5apps.com, 1 +5bet86.com, 1 +5c1fd0f31022cbc40af9f785847baaf9.space, 1 +5ccapitalinvestments.com, 1 +5chat.it, 1 +5dm.tv, 1 +5e.tools, 1 +5ece.de, 1 +5francs.com, 1 +5gb.space, 1 +5goglobal.com, 1 +5h0r7.com, 1 +5i.gs, 1 +5icsb.com, 1 +5ilg.com, 1 +5kraceforals.com, 1 +5long88.com, 1 +5net.ga, 1 +5ososea.com, 1 +5peciali5t.tk, 1 +5percentperweek.com, 1 +5sporn.com, 1 +5starcruises.com.au, 1 +5stars.tv, 1 +5thchichesterscouts.org.uk, 1 +5y.fi, 1 +5yeb.com, 0 +60062b.cc, 1 +60062h.cc, 1 +60062i.cc, 1 +600aaaa.com, 1 +600bbbb.com, 1 +600cao.com, 1 +600dddd.com, 1 +600iiii.com, 1 +600k8.com, 1 +600kkkk.com, 1 +600llll.com, 1 +600mmmm.com, 1 +600pppp.com, 1 +600ssss.com, 1 +600tttt.com, 1 +600vvvv.com, 1 +600wwww.com, 1 +600xxxx.com, 1 +602422.com, 1 +602yb.com, 1 +603yb.com, 1 +604122.com, 1 +604322.com, 1 +604522.com, 1 +604622.com, 1 +604windswell.ca, 1 +605422.com, 1 +605vv.com, 1 +606422.com, 1 +608vets.com, 1 +609422.com, 1 +60n13.com, 1 +611121.com, 1 +611125.com, 1 +611135.com, 1 +611165.com, 1 +611195.com, 1 +6132hb.com, 0 +614022.com, 1 +614322.com, 1 +614922.com, 1 +616578.com, 1 +616675.com, 1 +616728.com, 1 +616758.com, 1 +616798.com, 1 +616btt.net, 1 +616f88.com, 1 +61730123.com, 1 +618034.xyz, 1 +619kb.com, 1 +61ag8.com, 1 +61d88.com, 1 +620207.com, 1 +620881.com, 1 +621162.com, 1 +621422.com, 1 +621kb.com, 1 +621nn.com, 1 +622283.com, 1 +622812.com, 1 +622bbb.com, 1 +62314.cc, 1 +624022.com, 1 +624122.com, 1 +624322.com, 1 +624522.com, 1 +624922.com, 1 +625kb.com, 1 +626422.com, 1 +630422.com, 1 +631422.com, 1 +632017.com, 1 +632025.com, 1 +632026.com, 1 +632027.com, 1 +632035.com, 1 +632040.com, 1 +632045.com, 1 +632046.com, 1 +632047.com, 1 +6321000.com, 0 +6321007.com, 0 +6321008.com, 0 +6321009.com, 0 +6321222.com, 0 +6321333.com, 0 +632140.com, 1 +632143.com, 1 +632144.com, 1 +632147.com, 1 +632148.com, 0 +632174.com, 0 +632365.com, 1 +633362.com, 1 +633663.cc, 1 +633663.net, 1 +633663.vip, 1 +634022.com, 1 +634322.com, 1 +634365.com, 1 +634622.com, 1 +634922.com, 1 +635-488.com, 1 +635-588.com, 1 +635-788.com, 1 +635-888.com, 1 +635-988.com, 1 +635422.com, 1 +636422.com, 1 +6365ah.com, 0 +6365am.com, 0 +6365bj.com, 0 +6365cq.com, 0 +6365dx.com, 0 +6365fj.com, 0 +6365gd.com, 0 +6365gs.com, 0 +6365gx.com, 0 +6365gz.com, 0 +6365hb.com, 0 +6365hh.com, 0 +6365hk.com, 0 +6365hlj.com, 0 +6365hn.com, 0 +6365jl.com, 0 +6365js.com, 0 +6365jx.com, 0 +6365ln.com, 0 +6365lt.com, 0 +6365nmg.com, 0 +6365nn.com, 0 +6365nx.com, 0 +6365qh.com, 0 +6365sc.com, 0 +6365sd.com, 0 +6365sh.com, 0 +6365ss.com, 0 +6365sx.com, 0 +6365tj.com, 0 +6365tw.com, 0 +6365xj.com, 0 +6365xz.com, 0 +6365yd.com, 0 +6365yn.com, 0 +6365zj.com, 0 +638566.com, 1 +639422.com, 1 +6396000.com, 1 +63960000.com, 1 +63961111.com, 1 +6396222.com, 1 +63962222.com, 1 +6396333.com, 1 +63963333.com, 1 +6396444.com, 1 +63964444.com, 1 +63965555.com, 1 +63967777.com, 1 +63968888.com, 1 +639688888.com, 1 +63969999.com, 1 +6396aaa.com, 1 +6396bbb.com, 1 +6396ccc.com, 1 +6396fff.com, 1 +6396ggg.com, 1 +6396hhh.com, 1 +6396iii.com, 1 +6396jjj.com, 1 +6396ooo.com, 1 +6396qqq.com, 1 +6396rrr.com, 1 +6396ttt.com, 1 +6396vvv.com, 1 +6396www.com, 1 +6396xxx.com, 1 +6396yyy.com, 1 +6396zzz.com, 1 +63aj.com, 1 +63at.com, 1 +63bg.com, 1 +63bh.com, 1 +63cb.com, 1 +63co.com, 1 +63dt.com, 1 +63eb.com, 1 +63eh.com, 1 +63ej.com, 1 +63en.com, 1 +63ep.com, 1 +63et.com, 1 +63fb.com, 1 +63fd.com, 1 +63fg.com, 1 +63fk.com, 1 +63fn.com, 1 +63fp.com, 1 +63ga.com, 1 +63gaming.com, 1 +63gc.com, 1 +63gf.com, 1 +63gh.com, 1 +63gj.com, 1 +63gn.com, 1 +63gq.com, 1 +63gu.com, 1 +63ha.com, 1 +63he.com, 1 +63hq.com, 1 +63hv.com, 1 +63hx.com, 1 +63ia.com, 1 +63if.com, 1 +63ik.com, 1 +63im.com, 1 +63iw.com, 1 +63jl.com, 1 +63jr.com, 1 +63kd.com, 1 +63ki.com, 1 +63kl.com, 1 +63kn.com, 1 +63kv.com, 1 +63kz.com, 1 +63lb.com, 1 +63lc.com, 1 +63ld.com, 1 +63lo.com, 1 +63lr.com, 1 +63md.com, 1 +63mf.com, 1 +63mq.com, 1 +63nd.com, 1 +63ng.com, 1 +63ni.com, 1 +63nk.com, 1 +63nl.com, 1 +63nx.com, 1 +63of.com, 1 +63ox.com, 1 +63pd.com, 1 +63pl.com, 1 +63qb.com, 1 +63qz.com, 1 +63re.com, 1 +63rh.com, 1 +63rj.com, 1 +63rk.com, 1 +63rn.com, 1 +63rz.com, 1 +63ta.com, 1 +63tf.com, 1 +63tx.com, 1 +63ud.com, 1 +63uf.com, 1 +63um.com, 1 +63ut.com, 1 +63uz.com, 1 +63vg.com, 1 +63vo.com, 1 +63wq.com, 1 +640622.com, 1 +640722.com, 1 +640922.com, 1 +641022.com, 1 +641322.com, 1 +641422.com, 1 +641522.com, 1 +641622.com, 1 +641722.com, 1 +641822.com, 1 +641922.com, 1 +642022.com, 1 +642322.com, 1 +642422.com, 1 +642722.com, 1 +642822.com, 1 +642922.com, 1 +643022.com, 1 +643122.com, 1 +643722.com, 1 +643922.com, 1 +645022.com, 1 +645122.com, 1 +645322.com, 1 +645722.com, 1 +645822.com, 1 +645922.com, 1 +645ds.cn, 0 +645ds.com, 0 +646.io, 0 +646022.com, 1 +646322.com, 1 +646722.com, 1 +647630.xyz, 1 +649022.com, 1 +649622.com, 1 +64970.com, 1 +649722.com, 1 +649822.com, 1 +64bitgaming.de, 1 +64d88.com, 1 +64i.de, 1 +64stacks.com, 1 +65131a.com, 1 +65131b.com, 1 +65131c.com, 1 +65131d.com, 1 +65131g.com, 1 +65131h.com, 1 +65131i.com, 1 +65131j.com, 1 +65131t.com, 1 +65131u.com, 1 +65131v.com, 1 +65131w.com, 1 +65131x.com, 1 +65131y.com, 1 +65131z.com, 1 +651422.com, 1 +652422.com, 1 +6541166.com, 1 +6542277.com, 1 +6543399.com, 1 +65477.com, 1 +6547700.com, 1 +6547711.com, 1 +6547722.com, 1 +6547733.com, 1 +6547744.com, 1 +6547755.com, 1 +6547766.com, 1 +6548855.com, 1 +6548877.com, 1 +655591.com, 1 +655ks.com, 1 +655z6.com, 1 +657660.com, 1 +659422.com, 1 +65book.net, 1 +65d88.com, 1 +6602p.com, 1 +661326.com, 1 +66168365.com, 1 +6616fc.com, 1 +6617365.com, 0 +661z6.com, 1 +662607.xyz, 1 +6627365.com, 0 +6629365.com, 0 +66321365.com, 1 +6633445.com, 1 +663365666.com, 1 +663365777.com, 1 +663365888.com, 1 +663365a.vip, 1 +663365b.vip, 1 +663365c.vip, 1 +663365d.vip, 1 +663365e.vip, 1 +663365f.vip, 1 +663365g.vip, 1 +663365h.vip, 1 +663365i.com, 1 +663365i.vip, 1 +663365j.com, 1 +663365j.vip, 1 +663365k.com, 1 +663365k.vip, 1 +663365l.com, 1 +663365m.com, 1 +663365n.com, 1 +663365o.com, 1 +663365p.com, 1 +663365q.com, 1 +663365r.com, 1 +663365s.com, 1 +663365t.com, 1 +663365u.com, 1 +663365v.com, 1 +663365w.com, 1 +663365x.com, 1 +663365y.com, 1 +663365z.com, 1 +663651.com, 1 +664048.com, 1 +6652566.com, 1 +6660111.ru, 1 +666111bet.com, 1 +666222bet.com, 1 +666321365.com, 1 +666333bet.com, 1 +666365app.com, 1 +666365ios.com, 1 +666365iosapp.com, 1 +666365t.com, 1 +6664553.com, 1 +666555bet.com, 1 +666668722.com, 1 +666689999.xyz, 1 +6666sb.com, 1 +666777bet.com, 1 +666888bet.com, 1 +66689j.com, 1 +666999bet.com, 1 +666b58.com, 1 +666bet86.com, 1 +666btt.net, 1 +666k8.com, 1 +666k8.net, 1 +6671365.com, 0 +6672365.com, 0 +6673365.com, 0 +6677.us, 1 +667z6.com, 1 +668825.vip, 1 +668k8.com, 1 +668k8.net, 1 +668z6.com, 1 +66b.com, 1 +66b58.com, 1 +66bet86.com, 1 +66bwf.com, 1 +66d88.net, 1 +66k66.vip, 1 +670102.com, 1 +670422.com, 1 +671422.com, 1 +671660.com, 1 +671990.com, 1 +672422.com, 1 +6728365.com, 1 +6729.co, 0 +672990.com, 0 +6729a.co, 1 +6729aa.co, 1 +6729aa.com, 1 +6729apk.com, 1 +6729app.com, 1 +6729b.co, 1 +6729bb.co, 1 +6729bb.com, 1 +6729c.co, 1 +6729c.com, 1 +6729cc.co, 1 +6729cc.com, 1 +6729d.co, 1 +6729d.com, 1 +6729dd.co, 1 +6729dd.com, 1 +6729dh.co, 1 +6729dns.com, 1 +6729e.co, 1 +6729e.com, 1 +6729ee.co, 1 +6729ee.com, 1 +6729f.co, 1 +6729f.com, 1 +6729ff.co, 1 +6729ff.com, 1 +6729g.co, 1 +6729g.com, 1 +6729gg.co, 1 +6729gg.com, 1 +6729h.co, 1 +6729h.com, 1 +6729hb.com, 0 +6729hd.com, 1 +6729hh.co, 1 +6729hh.com, 1 +6729i.co, 1 +6729i.com, 1 +6729ii.co, 1 +6729ii.com, 1 +6729ipa.com, 1 +6729j.co, 1 +6729j.com, 1 +6729jj.co, 1 +6729jj.com, 1 +6729k.co, 1 +6729k.com, 1 +6729kk.co, 1 +6729kk.com, 1 +6729l.co, 1 +6729l.com, 1 +6729ll.co, 1 +6729ll.com, 1 +6729m.co, 1 +6729m.com, 1 +6729mm.co, 1 +6729mm.com, 1 +6729n.co, 1 +6729n.com, 1 +6729nn.co, 1 +6729nn.com, 1 +6729o.co, 1 +6729o.com, 1 +6729oo.co, 1 +6729oo.com, 1 +6729p.co, 1 +6729p.com, 1 +6729pp.co, 1 +6729pp.com, 1 +6729q.co, 1 +6729q.com, 1 +6729qq.co, 1 +6729qq.com, 1 +6729r.co, 1 +6729r.com, 1 +6729rr.co, 1 +6729rr.com, 1 +6729s.co, 1 +6729s.com, 1 +6729ss.co, 1 +6729ss.com, 1 +6729sx.com, 1 +6729t.co, 1 +6729t.com, 1 +6729tt.co, 1 +6729tt.com, 1 +6729u.co, 1 +6729u.com, 1 +6729uu.co, 1 +6729uu.com, 1 +6729v.co, 1 +6729v.com, 1 +6729vv.co, 1 +6729vv.com, 1 +6729w.co, 1 +6729w.com, 1 +6729ww.co, 1 +6729ww.com, 1 +6729x.co, 1 +6729x.com, 1 +6729xx.co, 1 +6729xx.com, 1 +6729xy.com, 0 +6729y.co, 1 +6729y.com, 1 +6729yy.co, 1 +6729yy.com, 1 +6729z.co, 1 +6729z.com, 1 +6729zz.co, 1 +6729zz.com, 1 +672bbb.com, 1 +673422.com, 1 +673569.com, 1 +673660.com, 1 +673990.com, 1 +673bbb.com, 1 +676422.com, 1 +677314.com, 1 +677340.com, 1 +677341.com, 1 +677346.com, 1 +677347.com, 1 +677354.com, 1 +677364.com, 1 +677384.com, 1 +67836565.com, 1 +678365app.com, 1 +678365cc.com, 1 +678365t.com, 1 +678678365.com, 1 +67877777.com, 1 +6789666365.com, 1 +679422.com, 1 +679660.com, 0 +67y7.com, 1 +680422.com, 1 +681vv.com, 1 +68277.me, 1 +68522.com, 1 +68522c.com, 1 +68522k.com, 1 +68522m.com, 1 +68522s.com, 1 +68622.com, 1 +68622a.com, 1 +68622b.com, 1 +686848.com, 1 +68722.com, 1 +688z6.com, 1 +68hvip.com, 1 +68reg.tk, 1 +690422.com, 1 +691422.com, 1 +692422.com, 1 +692660.com, 1 +692b8c32.de, 1 +693422.com, 1 +694322.com, 1 +694622.com, 1 +694922.com, 1 +695660.com, 1 +6957.co, 1 +6957a.co, 1 +6957aa.co, 1 +6957apk.com, 1 +6957app.com, 1 +6957b.co, 1 +6957bb.co, 1 +6957c.co, 1 +6957cc.co, 1 +6957d.co, 1 +6957dd.co, 1 +6957dh.co, 1 +6957e.co, 1 +6957ee.co, 1 +6957f.co, 1 +6957ff.co, 1 +6957g.co, 1 +6957gg.co, 1 +6957h.co, 1 +6957hh.co, 1 +6957i.co, 1 +6957ii.co, 1 +6957j.co, 1 +6957jj.co, 1 +6957k.co, 1 +6957kk.co, 1 +6957l.co, 1 +6957ll.co, 1 +6957m.co, 1 +6957mm.co, 1 +6957n.co, 1 +6957nn.co, 1 +6957o.co, 1 +6957oo.co, 1 +6957p.co, 1 +6957pp.co, 1 +6957q.co, 1 +6957qq.co, 1 +6957r.co, 1 +6957rr.co, 1 +6957rr.com, 1 +6957s.co, 1 +6957ss.co, 1 +6957t.co, 1 +6957tt.co, 1 +6957u.co, 1 +6957uu.co, 1 +6957v.co, 1 +6957vv.co, 1 +6957vv.com, 0 +6957w.co, 1 +6957ww.co, 1 +6957x.co, 1 +6957xx.co, 1 +6957xy.com, 0 +6957y.co, 1 +6957yy.co, 1 +6957z.co, 1 +6957z.com, 1 +6957zz.co, 1 +695990.com, 1 +6997896.com, 1 +69butterfly.com, 1 +69games.xxx, 1 +69level.com, 1 +69mentor.com, 1 +69shu.com, 1 +69wasted.net, 1 +69yd.com, 1 +6bet86.com, 1 +6bwcp.com, 1 +6dec.gc.ca, 1 +6ird.com, 0 +6lo.zgora.pl, 1 +6meter.tk, 1 +6play.fr, 1 +6qubedirectory.com, 1 +6t-montjoye.org, 1 +6thmarch.com, 1 +6upagent.com, 1 +6wbz.com, 1 +6yue.org, 1 +7-it.ml, 1 +700.az, 1 +700bbbb.com, 1 +700cccc.com, 1 +700dddd.com, 1 +700gggg.com, 1 +700hhhh.com, 1 +700iiii.com, 1 +700mmmm.com, 1 +700uuuu.com, 1 +700wns.com, 1 +700yyyy.com, 1 +700zzzz.com, 1 +701135.com, 1 +701605.com, 1 +701squad.tk, 1 +70365365.com, 1 +704233.com, 1 +704533.com, 1 +704633.com, 1 +705994.com, 1 +708090.ru, 1 +70872.com, 0 +709129.com, 1 +70mpg.org, 1 +712433.com, 1 +712kb.com, 1 +713433.com, 1 +71365365.com, 1 +7139365.com, 1 +713kb.com, 1 +714133.com, 1 +714533.com, 1 +714633.com, 1 +715433.com, 1 +7177bet.com, 1 +71787m.com, 1 +71787n.com, 1 +71787o.com, 1 +71787p.com, 1 +71787q.com, 1 +71787r.com, 1 +71787s.com, 1 +71787t.com, 1 +71787u.com, 1 +71787v.com, 1 +71787w.com, 1 +71787x.com, 1 +71787y.com, 1 +71787z.com, 1 +7183.org, 0 +718433.com, 1 +719433.com, 1 +71tuiguang.com, 1 +7214.cc, 1 +721aa.com, 1 +722sss.com, 1 +722z6.com, 1 +724233.com, 1 +724go.com, 1 +7261696e626f77.net, 1 +726433.com, 1 +727sss.com, 1 +728433.com, 1 +729433.com, 1 +729solutions.com, 1 +72hours2sold.com, 1 +72ty.com, 1 +72ty.net, 1 +730433.com, 1 +731433.com, 1 +732365.com, 1 +732433.com, 1 +733575.com, 1 +73365365.com, 1 +7337app.com, 1 +734365.com, 1 +735433.com, 1 +736433.com, 1 +738433.com, 1 +739433.com, 1 +73af.com, 1 +73aj.com, 1 +73ap.com, 1 +73ar.com, 1 +73ax.com, 1 +73az.com, 1 +73ea.com, 1 +73eb.com, 1 +73ef.com, 1 +73eg.com, 1 +73eh.com, 1 +73ei.com, 1 +73ej.com, 1 +73ek.com, 1 +73en.com, 1 +73eq.com, 1 +73es.com, 1 +73ex.com, 1 +73ez.com, 1 +73fd.com, 1 +73fg.com, 1 +73fl.com, 1 +73fp.com, 1 +73fq.com, 1 +73fw.com, 1 +73fy.com, 1 +73fz.com, 1 +73ga.com, 1 +73gb.com, 1 +73gc.com, 1 +73gf.com, 1 +73gj.com, 1 +73gl.com, 1 +73gn.com, 1 +73gp.com, 1 +73gr.com, 1 +73gs.com, 1 +73gx.com, 1 +73hb.com, 1 +73hc.com, 1 +73hn.com, 1 +73hw.com, 1 +73ia.com, 1 +73if.com, 1 +73ig.com, 1 +73ih.com, 1 +73iw.com, 1 +73ix.com, 1 +73iy.com, 1 +73ja.com, 1 +73je.com, 1 +73jn.com, 1 +73kc.com, 1 +73kn.com, 1 +73kp.com, 1 +73ky.com, 1 +73ld.com, 1 +73lg.com, 1 +73ln.com, 1 +73nk.com, 1 +73nm.com, 1 +73np.com, 1 +73nq.com, 1 +73nw.com, 1 +73nz.com, 1 +73pb.com, 1 +73pe.com, 1 +73pl.com, 1 +73px.com, 1 +73qa.com, 1 +73qd.com, 1 +73qe.com, 1 +73ql.com, 1 +73qx.com, 1 +73rh.com, 1 +73rq.com, 1 +73rt.com, 1 +73ru.com, 1 +73si.com, 1 +73sk.com, 1 +73te.com, 1 +73tf.com, 1 +73tg.com, 1 +73ti.com, 1 +73tq.com, 1 +73tx.com, 1 +73ub.com, 1 +73ud.com, 1 +73uh.com, 1 +73ui.com, 1 +73uk.com, 1 +73un.com, 1 +73uq.com, 1 +73uy.com, 1 +73vt.com, 1 +73vz.com, 1 +73wb.com, 1 +73wj.com, 1 +73wt.com, 1 +73xh.com, 1 +73xi.com, 1 +73xm.com, 1 +73xv.com, 1 +73yj.com, 1 +73yp.com, 1 +73yr.com, 1 +73yu.com, 1 +73za.com, 1 +73zd.com, 1 +740833.com, 1 +741833.com, 1 +742833.com, 1 +743365.com, 1 +74365365.com, 1 +743833.com, 1 +74d88.com, 1 +74dy.org, 1 +74th.jp, 1 +753365.com, 1 +7552001.com, 1 +7552002.com, 1 +7552005.com, 1 +7552006.com, 1 +7552008.com, 1 +7552009.com, 1 +7552010.com, 1 +7552011.com, 1 +7552012.com, 1 +7552013.com, 1 +755204.com, 1 +755243.com, 1 +755245.com, 1 +755246.com, 1 +755249.com, 1 +755274.com, 1 +755284.com, 0 +755294.com, 0 +755k3.com, 1 +75codes.com, 1 +761.com, 1 +762.ch, 0 +763365.com, 1 +76365365.com, 1 +765666365.com, 1 +7666321.com, 1 +76668.com, 1 +7666898.com, 1 +76669.com, 1 +76956.com, 1 +769k.com, 1 +76networks.tk, 1 +77018bb.com, 1 +77018cc.com, 1 +77018dd.com, 1 +77018ee.com, 1 +77018vip.com, 1 +77168365.com, 1 +77177.de, 1 +77321365.com, 1 +7733445.com, 1 +7748229.xyz, 1 +775018.com, 1 +776z6.com, 1 +777365t.com, 1 +7776321.com, 0 +7776365.com, 1 +7777k8.com, 1 +777bet86.com, 1 +777coin.com, 1 +7788bet.vip, 1 +778z6.com, 1 +779z6.com, 1 +77b58.com, 1 +77bet86.com, 1 +77dd.com, 0 +77zxdy.com, 1 +780aa.com, 1 +78365b.com, 0 +78365cc.com, 1 +783lab.com, 1 +787637.com, 1 +7877bet.com, 1 +7878365.com, 0 +787k3.com, 1 +787kb.com, 1 +7885765.com, 1 +7888813.com, 1 +7888815.com, 1 +7888821.com, 1 +788zzz.com, 1 +7891553.com, 1 +7891997.com, 1 +7893.net, 1 +78936565.com, 1 +789365t.com, 1 +7894.net, 1 +795sss.com, 1 +797715.com, 1 +797sss.com, 1 +798sss.com, 1 +799ks.com, 1 +799z6.com, 1 +7azarfazar.com, 1 +7bet86.com, 1 +7careconnect.com, 1 +7delights.com, 1 +7delights.in, 1 +7emka.tk, 1 +7f.is, 1 +7geese.com, 1 +7graus.pt, 1 +7in0.me, 1 +7ki.photography, 1 +7kicks.com, 1 +7kovrikov.ru, 1 +7l00p.com, 1 +7lb.de, 1 +7milesglobal.com, 1 +7pets.net, 1 +7plus.com.au, 1 +7proxies.com, 1 +7qly.com, 1 +7sdre.am, 1 +7starhealth.ga, 1 +7th-heaven.me, 1 +7thcircledesigns.com, 1 +7url.ml, 1 +7x24servis.com, 1 +7zet.ml, 1 +8001d.com, 1 +8001d88.com, 1 +8003pay.com, 1 +8006d.com, 1 +8006d88.com, 1 +8007d88.com, 1 +800bbbb.com, 1 +800cccc.com, 1 +800dddd.com, 1 +800eeee.com, 1 +800hhhh.com, 1 +800iiii.com, 1 +800kkkk.com, 1 +800llll.com, 1 +800nnnn.com, 1 +800qqqq.com, 1 +800rrrr.com, 1 +800vvvv.com, 1 +800wwww.com, 1 +800xxxx.com, 1 +800zzzz.com, 1 +8010d88.com, 1 +8012d88.com, 1 +8017d.com, 1 +8017d88.com, 1 +8019d88.com, 1 +801hao.com, 1 +8020d88.com, 1 +8021d.com, 1 +8022d.com, 1 +8026d88.com, 1 +8027d.com, 1 +8028d.com, 1 +8028d88.com, 1 +8029d.com, 1 +8029d88.com, 1 +803001.com, 1 +8032d88.com, 1 +8033d88.com, 1 +8035d88.com, 1 +80365365.com, 1 +8036d88.com, 1 +8038d88.com, 1 +8039d.com, 1 +804322.com, 1 +8050d.com, 1 +8059d88.com, 1 +805lifeguard.com, 1 +805vv.com, 1 +8060d88.com, 1 +80630.com, 1 +8069d88.com, 1 +8071d.com, 1 +8077d.com, 1 +80780780.com, 1 +8078d.com, 1 +8081d.com, 1 +8086.cf, 1 +808arts.com, 1 +808cleanups.org, 1 +808phone.net, 1 +809088.cc, 1 +8092d88.com, 1 +8093d.com, 1 +809422.com, 1 +8097d.com, 1 +80993.net, 1 +809kb.com, 1 +80bin.com, 1 +8100d.com, 1 +8102d.com, 1 +8102d88.com, 1 +8105d.com, 1 +8106365.com, 1 +8109d88.com, 1 +811121.com, 1 +8113d.com, 1 +8115d88.com, 1 +8116d88.com, 1 +811z6.com, 1 +8121d.com, 1 +8121d88.com, 1 +812221.com, 1 +8128d.com, 1 +8129d.com, 1 +8130d88.com, 1 +8132365.com, 1 +8133d.com, 1 +8135d88.com, 1 +81365365.com, 1 +81365b.com, 1 +81365c.com, 1 +81365d.com, 1 +81365e.com, 1 +81365f.com, 1 +81365g.com, 1 +81365h.com, 1 +81365i.com, 1 +81365j.com, 1 +81365k.com, 1 +81365l.com, 1 +81365m.com, 1 +81365n.com, 1 +81365o.com, 1 +81365p.com, 1 +81365q.com, 1 +81365r.com, 1 +81365s.com, 1 +81365t.com, 1 +81365u.com, 1 +81365v.com, 1 +81365w.com, 1 +81365x.com, 1 +81365y.com, 1 +81365z.com, 0 +8139d.com, 1 +814022.com, 1 +8151d.com, 1 +8153365.com, 1 +8153d.com, 1 +8156d.com, 1 +8159d88.com, 1 +815jz.com, 1 +8160d.com, 1 +8160d88.com, 1 +8161d.com, 1 +8161d88.com, 1 +8162d.com, 1 +8163d.com, 1 +8167365.com, 1 +816jz.com, 1 +8170d.com, 1 +8171d.com, 1 +817209.com, 1 +8173d.com, 1 +8176d.com, 1 +8178d.com, 1 +81818app.com, 1 +81818d.com, 1 +81818z.com, 1 +8181d88.com, 1 +8182d.com, 1 +8182d88.com, 1 +8183d.com, 1 +8183d88.com, 1 +8186d.com, 1 +8187d.com, 1 +8189196.com, 1 +8189d.com, 1 +818bwf.com, 1 +818z6.com, 1 +8190d.com, 1 +8190d88.com, 1 +8192d.com, 1 +8193d.com, 1 +8193d88.com, 1 +8196d.com, 1 +8197d.com, 1 +8197d88.com, 1 +8198d.com, 1 +8198d88.com, 1 +81d88.com, 1 +81uc.com, 1 +8200d.com, 1 +8202d.com, 1 +8203d88.com, 1 +8206688.com, 1 +8206d.com, 1 +8207d88.com, 1 +8208d.com, 1 +8208d88.com, 1 +8210d88.com, 1 +8211d88.com, 1 +8216d.com, 1 +8216d88.com, 1 +8217d.com, 1 +8217d88.com, 1 +8218d88.com, 1 +8219d.com, 1 +8219d88.com, 1 +8221d88.com, 1 +8222d88.com, 1 +8225.com, 1 +8225d.com, 1 +8226d.com, 1 +8228d.com, 1 +8229d88.com, 1 +822z6.com, 1 +82365a.com, 1 +82365b.com, 1 +82365c.com, 1 +82365d.com, 1 +82365e.com, 1 +82365f.com, 1 +82365g.com, 1 +82365h.com, 1 +82365i.com, 1 +82365j.com, 1 +82365k.com, 1 +82365l.com, 1 +82365m.com, 1 +82365n.com, 1 +82365o.com, 1 +82365p.com, 1 +82365q.com, 1 +82365r.com, 1 +82365s.com, 1 +82365t.com, 1 +82365u.com, 1 +82365v.com, 1 +82365w.com, 1 +82365x.com, 1 +82365y.com, 1 +82365z.com, 1 +8236d.com, 1 +8238d.com, 1 +8239d.com, 1 +827774.com, 1 +82781111.com, 0 +82783333.com, 0 +82784444.com, 0 +82785555.com, 0 +82786666.com, 0 +82789999.com, 0 +8278a.com, 0 +8278b.com, 0 +8278bb.com, 0 +8278ee.com, 0 +8278eee.com, 1 +8278ff.com, 0 +8278jj.com, 0 +8278jjj.com, 1 +8278kk.com, 0 +8278rr.com, 0 +8278tt.com, 0 +8278yy.com, 0 +82ag88.com, 1 +82kb88.com, 1 +832365.com, 1 +83365365.com, 1 +833z6.com, 1 +834365.com, 1 +8349822.com, 1 +83kb88.com, 1 +84036.ml, 1 +842365.com, 1 +842844.com, 1 +846773.com, 1 +847773.com, 1 +848jz.com, 1 +848sf.com, 1 +84ag.com, 1 +84aj.com, 1 +84al.com, 1 +84an.com, 1 +84aq.com, 1 +84ar.com, 1 +84az.com, 1 +84bd.com, 1 +84bf.com, 1 +84bi.com, 1 +84bn.com, 1 +84bp.com, 1 +84bq.com, 1 +84bx.com, 1 +84ce.com, 1 +84cl.com, 1 +84cr.com, 1 +84cw.com, 1 +84cx.com, 1 +84dp.com, 1 +84dt.com, 1 +84eg.com, 1 +84ei.com, 1 +84ek.com, 1 +84et.com, 1 +84ev.com, 1 +84ew.com, 1 +84ez.com, 1 +84fb.com, 1 +84fd.com, 1 +84fe.com, 1 +84fg.com, 1 +84fh.com, 1 +84fi.com, 1 +84fq.com, 1 +84fs.com, 1 +84ft.com, 1 +84fz.com, 1 +84ga.com, 1 +84gc.com, 1 +84gf.com, 1 +84gi.com, 1 +84gk.com, 1 +84gt.com, 1 +84hb.com, 1 +84he.com, 1 +84hp.com, 1 +84hs.com, 1 +84hv.com, 1 +84hx.com, 1 +84ia.com, 1 +84if.com, 1 +84im.com, 1 +84jg.com, 1 +84jh.com, 1 +84ji.com, 1 +84jl.com, 1 +84jt.com, 1 +84kc.com, 1 +84ki.com, 1 +84kl.com, 1 +84kn.com, 1 +84kp.com, 1 +84kq.com, 1 +84kt.com, 1 +84kv.com, 1 +84lb.com, 1 +84lh.com, 1 +84pe.com, 1 +84pg.com, 1 +84pq.com, 1 +84qb.com, 1 +84qf.com, 1 +84qj.com, 1 +84qx.com, 1 +84rb.com, 1 +84rd.com, 1 +84rf.com, 1 +84rn.com, 1 +84sg.com, 1 +84sr.com, 1 +84sv.com, 1 +84td.com, 1 +84tn.com, 1 +84tp.com, 1 +84tw.com, 1 +84tx.com, 1 +84ua.com, 1 +84xa.com, 1 +84xe.com, 1 +84xl.com, 1 +84xm.com, 1 +84xp.com, 1 +84yd.com, 1 +84yj.com, 1 +84yp.com, 1 +84yq.com, 1 +84yv.com, 1 +84yw.com, 1 +84zb.com, 1 +84zc.com, 1 +84zr.com, 1 +84zu.com, 1 +84zv.com, 1 +850226.com, 1 +8521.co, 1 +8521.me, 1 +8522hk.com, 1 +8522ph.com, 1 +8522top.com, 1 +8522tw.com, 1 +8522usa.com, 1 +8560.be, 1 +8602010.com, 1 +8602012.com, 1 +8602013.com, 1 +8602014.com, 1 +8602015.com, 1 +8602016.com, 1 +8602017.com, 1 +8602018.com, 1 +8602019.com, 1 +8602020.com, 1 +86086011.com, 1 +86086022.com, 1 +86086033.com, 1 +86086044.com, 1 +86086055.com, 1 +86086066.com, 1 +86086077.com, 1 +86086099.com, 1 +860vv.com, 1 +861365.vip, 1 +861365a.com, 1 +861365b.com, 1 +861365c.com, 1 +861365d.com, 1 +861365e.com, 1 +861365f.com, 1 +861365g.com, 1 +861365h.com, 1 +861365i.com, 1 +861365j.com, 1 +861365k.com, 1 +861365l.com, 1 +861365m.com, 1 +861365o.com, 1 +861365q.com, 1 +861365r.com, 1 +861365s.com, 1 +861365t.com, 1 +861365u.com, 1 +861365v.com, 1 +861365vip.com, 1 +861365w.com, 1 +861365x.com, 1 +861365y.com, 1 +861365z.com, 1 +861kb.com, 1 +86499.com, 1 +8649955.com, 1 +8649966.com, 1 +8649977.com, 1 +866300.vip, 1 +866304.com, 0 +866305.vip, 1 +866308.vip, 1 +866314.com, 0 +866341.com, 1 +866346.com, 0 +866349.com, 0 +866374.com, 0 +866394.com, 0 +8666321.com, 1 +8666ks.com, 1 +866z6.com, 1 +8688fc.com, 1 +868z6.com, 1 +8699bet.com, 1 +869kb.com, 1 +86btt.com, 1 +86kb88.com, 1 +86metro.ru, 1 +870.cc, 1 +8722am.com, 1 +8722cn.com, 1 +8722hk.com, 1 +8722ph.com, 1 +8722tw.com, 1 +8722usa.com, 1 +87365365.com, 1 +87577.com, 1 +877027.com, 1 +877791.com, 1 +878365bb.com, 1 +878365c.com, 1 +878365cn.com, 1 +878365ii.com, 1 +878365jj.com, 1 +878365ll.com, 1 +878365nn.com, 1 +878989.com, 1 +8796.jp, 1 +8799bet.com, 1 +87kb88.com, 1 +88-line.com, 1 +88-line.net, 1 +8800.ru, 1 +8806d.com, 1 +8809d.com, 1 +8809d88.com, 1 +8809ks.com, 1 +881-line.com, 1 +881-line.net, 1 +8812ks.com, 1 +8815d.com, 1 +88168365.com, 1 +8816d.com, 1 +8816d88.com, 1 +8817d88.com, 1 +8818k3.com, 1 +8818ks.com, 1 +8819ks.com, 1 +881z6.com, 1 +8821ks.com, 1 +8822d88.com, 1 +8826d.com, 1 +8826d88.com, 1 +8826ks.com, 1 +8830ks.com, 1 +88321365.com, 1 +8832ks.com, 1 +8833445.com, 1 +8835365.com, 1 +88365.net, 1 +88365t.com, 1 +88518.com, 1 +88522am.com, 1 +885287.com, 1 +8852ks.com, 1 +8855d88.com, 1 +8857d88.com, 1 +8858ks.com, 1 +885kb.com, 1 +885z6.com, 1 +8860d.com, 1 +8861ks.com, 1 +886666f.com, 1 +886666h.com, 1 +886666l.com, 1 +886666n.com, 1 +886666p.com, 1 +886666q.com, 1 +886666r.com, 1 +886666s.com, 1 +886666t.com, 1 +886666u.com, 1 +886666v.com, 1 +886666y.com, 1 +8866d88.com, 1 +8868ty8.com, 1 +8869ks.com, 1 +886k8.com, 1 +886k8.net, 1 +886z6.com, 1 +8871d.com, 1 +8872d.com, 1 +88740b.com, 1 +88740d.com, 1 +88740e.com, 1 +88740f.com, 1 +88740i.com, 1 +88740j.com, 1 +88740k.com, 1 +88740l.com, 1 +88740m.com, 1 +88740n.com, 1 +88740o.com, 1 +88740p.com, 1 +88740q.com, 1 +88740r.com, 1 +88740s.com, 1 +88740t.com, 1 +88740u.com, 1 +88740v.com, 1 +88740w.com, 1 +88740x.com, 1 +88740z.com, 1 +8876d.com, 1 +887d.com, 1 +8881234j.com, 1 +8881ks.com, 1 +888234j.com, 1 +888321365.com, 1 +8883456j.com, 1 +888345j.com, 1 +8884553.com, 1 +8884567j.com, 1 +888456j.com, 1 +888567j.com, 0 +8885asknick.com, 1 +8885ks.com, 1 +888666pj.com, 1 +8886789j.com, 1 +888789j.com, 1 +888888722.com, 1 +88889822.com, 1 +8888yule8888.com, 1 +8889ks.com, 1 +888am8.com, 1 +888b58.com, 1 +888bet86.com, 1 +888bwf.com, 1 +888funcity.com, 1 +888funcity.net, 1 +888xpjxpj.com, 1 +8890d.com, 1 +8890ks.com, 1 +8891d.com, 1 +8891ks.com, 1 +8892d.com, 1 +8892ks.com, 1 +8895d.com, 1 +8897d.com, 1 +8898ks.com, 1 +889999vip.com, 1 +889vip1.com, 1 +889vip10.com, 1 +889vip2.com, 1 +889vip3.com, 1 +889vip4.com, 1 +889vip5.com, 1 +889vip6.com, 1 +889vip7.com, 1 +889vip8.com, 1 +889vip9.com, 1 +889w889.com, 1 +889w889.net, 1 +88bet86.com, 1 +88cakescorner.com, 1 +88creative.ca, 1 +88d.com, 1 +88djl.cc, 1 +88home9.com, 1 +88kb88.com, 1 +88laohu.cc, 1 +88laohu.com, 1 +88lc88.com, 1 +88wewin.com, 1 +88yabo.com, 1 +88yule11.com, 1 +88yule112.com, 1 +88yule113.com, 1 +88yule12.com, 1 +88yule13.com, 1 +88yule15.com, 1 +88yule16.com, 1 +88yule3.com, 1 +88yule5.com, 1 +88yule6.com, 1 +88yule7.com, 1 +88yule9.com, 1 +8900d.com, 1 +890238.com, 1 +8906d.com, 1 +8907d.com, 1 +8908d.com, 1 +8919d.com, 1 +8920d.com, 1 +8921d.com, 1 +8925d.com, 1 +8925d88.com, 1 +8926d88.com, 1 +8927d.com, 1 +8927d88.com, 1 +8929d88.com, 1 +893067.com, 1 +89365t.com, 1 +89386.com, 1 +89386a.com, 1 +89386b.com, 1 +89386c.com, 1 +89386d.com, 1 +89386e.com, 1 +89386l.com, 1 +8938885.com, 1 +8966bet.com, 1 +897774.com, 1 +8977bet.com, 1 +8989k3.com, 1 +899ks.com, 1 +89btt.com, 1 +89ca.com, 1 +89he.com, 1 +8ack.de, 1 +8ag8.org, 1 +8ag88.com, 1 +8agks.com, 1 +8b8888.com, 1 +8ballbombom.uk, 1 +8balls.nl, 1 +8bet86.com, 1 +8bitsafe.com, 1 +8dabet.com, 1 +8duhu.com, 1 +8e8z.com, 1 +8freeporn.com, 1 +8hrs.net, 1 +8maerz.at, 1 +8me.nl, 1 +8o8wave.com, 1 +8pecxstudios.com, 1 +8shequapp.com, 1 +8t8.eu, 1 +8t88.biz, 1 +8tech.com.hk, 1 +8thportsmouth.org.uk, 1 +8tuffbeers.com, 1 +8ung.online, 1 +8xx.bet, 1 +8xx.io, 1 +8xx888.com, 1 +8xxxxxxx.com, 1 +8y.network, 1 +8yun.cf, 1 +8yun.ga, 0 +9-11commission.gov, 1 +9005424.com, 1 +9009019.com, 1 +900aaaa.com, 1 +900bbbb.com, 1 +900cccc.com, 1 +900dddd.com, 1 +900eeee.com, 1 +900gggg.com, 1 +900iiii.com, 1 +900jjjj.com, 1 +900k8.com, 1 +900nnnn.com, 1 +900qqqq.com, 1 +900tttt.com, 1 +900uuuu.com, 1 +900wwww.com, 1 +900yyyy.com, 1 +900zzzz.com, 1 +901543.com, 1 +903422.com, 1 +905422.com, 1 +906vv.com, 1 +908vv.com, 1 +90920.cn, 1 +90r.jp, 1 +90splease.com, 1 +91-freedom.com, 1 +9108.fun, 1 +910kj.com, 1 +911.gov, 1 +9111s.ru, 1 +911216.xyz, 1 +9118.com, 1 +911commission.gov, 1 +912422.com, 1 +9132365.com, 1 +913422.com, 1 +9137365.com, 1 +914122.com, 1 +915ers.com, 0 +918-siteinfo.com, 1 +9180nn.com, 1 +9180tt.com, 1 +9180vv.com, 1 +9180xx.com, 1 +9180yy.com, 1 +9180zz.com, 1 +918116.com, 1 +9181181.com, 1 +9181182.com, 1 +9181183.com, 1 +9181184.com, 1 +9181185.com, 1 +9181186.com, 1 +9181187.com, 1 +9181189.com, 1 +91816.net, 1 +9182289.com, 1 +9186.fun, 1 +9186119.com, 1 +91891849.com, 1 +91891854.com, 1 +91891856.com, 1 +91891878.com, 1 +918aac.com, 1 +918aah.com, 1 +918aait.co, 1 +918aaj.com, 1 +918aak.com, 1 +918aav.com, 1 +918ac.com, 1 +918aff.com, 1 +918agr.co, 1 +918ahh.com, 1 +918ajj.com, 1 +918amj.co, 1 +918att.com, 1 +918awx.co, 1 +918axx.com, 1 +918ayy.com, 1 +918baa.com, 1 +918bba.com, 1 +918bbd.com, 1 +918bbg.com, 1 +918bbm.co, 1 +918bby.co, 1 +918bby.com, 1 +918bcf.co, 1 +918bcw.co, 1 +918bdd.com, 1 +918bhh.com, 1 +918bio.co, 1 +918bip.co, 1 +918bis.co, 1 +918bjj.com, 1 +918bkk.com, 1 +918bs.com, 1 +918btty.com, 1 +918bttz.com, 1 +918byy.com, 1 +918bzz.com, 1 +918ca.com, 1 +918caa.com, 1 +918ccb.com, 1 +918cch.com, 1 +918ccq.com, 1 +918ccs.com, 1 +918cct.com, 1 +918ccu.com, 1 +918ccv.com, 1 +918ccw.com, 1 +918ccy.com, 1 +918cdd.com, 1 +918cff.com, 1 +918cgg.com, 1 +918ch.com, 1 +918cjj.com, 1 +918cmm.com, 1 +918cqq.com, 1 +918cr.com, 1 +918crr.com, 1 +918css.com, 1 +918ctt.com, 1 +918cvv.com, 1 +918cww.com, 1 +918cx.com, 1 +918cxx.com, 1 +918db.com, 1 +918dbb.com, 1 +918dc04.com, 1 +918dc16.com, 1 +918dc19.com, 1 +918dcc.com, 1 +918dda.com, 1 +918dde.com, 1 +918ddf.com, 1 +918ddj.com, 1 +918ddk.com, 1 +918ddo.com, 1 +918ddp.com, 1 +918ddq.com, 1 +918ddr.com, 1 +918ddw.com, 1 +918ddx.com, 1 +918ddy.com, 1 +918dgg.com, 1 +918dkk.com, 1 +918dp.com, 1 +918dpp.com, 1 +918dxx.com, 1 +918dzz.com, 1 +918eaa.com, 1 +918ebb.com, 1 +918ecc.com, 1 +918edd.com, 1 +918ee.com, 1 +918eea.com, 1 +918eec.com, 1 +918eed.com, 1 +918eef.com, 1 +918eej.com, 1 +918eek.com, 1 +918eem.com, 1 +918een.com, 1 +918eeq.com, 1 +918eer.com, 1 +918ees.com, 1 +918eex.com, 1 +918eey.com, 1 +918eez.com, 1 +918ej.com, 1 +918ejj.com, 1 +918emm.com, 1 +918epp.com, 1 +918ess.com, 1 +918euu.com, 1 +918ev.com, 1 +918fdd.com, 1 +918ffa.com, 1 +918ffb.com, 1 +918ffc.com, 1 +918ffe.com, 1 +918ffh.com, 1 +918ffk.com, 1 +918fq.com, 1 +918fr.com, 1 +918fv.com, 1 +918gd.com, 1 +918hi.com, 1 +918hr.com, 1 +918hs.com, 1 +918hu.com, 1 +918hw.com, 1 +918ia.com, 1 +918iz.com, 1 +918ji.com, 1 +918jt.co, 1 +918kissinw.com, 1 +918kx.com, 1 +918mc.com, 1 +918mf.com, 1 +918mh.com, 1 +918mo.com, 1 +918mz.com, 1 +918mzoz.com, 1 +918nc.com, 1 +918nd.com, 1 +918nn.com, 1 +918nu.com, 1 +918ny.com, 1 +918og.com, 1 +918pn.com, 1 +918pt.com, 1 +918qa.com, 1 +918qg.com, 1 +918qi.com, 1 +918qs.com, 1 +918rh.com, 1 +918sa.com, 1 +918sj.com, 1 +918sn.com, 1 +918ta.com, 1 +918tj.com, 1 +918tr.com, 1 +918tw.com, 1 +918uh.com, 1 +918ui.com, 1 +918um.com, 1 +918vb.com, 1 +918ve.com, 1 +918vi.com, 1 +918vk.com, 1 +918vs.com, 1 +918vz.com, 1 +918wa.com, 1 +918we.com, 1 +918wo.com, 1 +918wq.com, 1 +918wv.com, 1 +918ww.com, 1 +918xe.com, 1 +918xn.com, 1 +918ze.com, 1 +918zm.com, 1 +918zv.com, 1 +918zw.com, 1 +919422.com, 1 +919898.com, 1 +91d03.com, 1 +91d27.com, 1 +91d52.com, 1 +91d58.com, 1 +91d72.com, 1 +91d81.com, 1 +91d82.com, 1 +91d83.com, 1 +91d85.com, 1 +91d87.com, 1 +91d89.com, 1 +91dh.cc, 1 +91fldz.com, 1 +91idy.com, 1 +91imh.com, 1 +91news.tk, 1 +91tianmi.com, 0 +924122.com, 1 +924322.com, 1 +924622.com, 1 +926422.com, 1 +927774.com, 1 +929349.com, 1 +9297.co, 1 +9297a.co, 1 +9297aa.co, 1 +9297b.co, 1 +9297bb.co, 1 +9297c.co, 1 +9297cc.co, 1 +9297d.co, 1 +9297dd.co, 1 +9297dh.co, 1 +9297dns.com, 1 +9297e.co, 1 +9297ee.co, 1 +9297f.co, 1 +9297ff.co, 1 +9297g.co, 1 +9297gg.co, 1 +9297h.co, 1 +9297hb.com, 0 +9297hd.co, 1 +9297hd.com, 1 +9297hh.co, 1 +9297i.co, 1 +9297ii.co, 1 +9297j.co, 1 +9297jj.co, 1 +9297k.co, 1 +9297kk.co, 1 +9297l.co, 1 +9297ll.co, 1 +9297m.co, 1 +9297mm.co, 1 +9297n.co, 1 +9297nn.co, 1 +9297o.co, 1 +9297oo.co, 1 +9297p.co, 1 +9297pp.co, 1 +9297q.co, 1 +9297qq.co, 1 +9297r.co, 1 +9297rr.co, 1 +9297s.co, 1 +9297ss.co, 1 +9297t.co, 1 +9297tt.co, 1 +9297u.co, 1 +9297uu.co, 1 +9297v.co, 1 +9297vv.co, 1 +9297w.co, 1 +9297ww.co, 1 +9297x.co, 1 +9297xx.co, 1 +9297y.co, 1 +9297yy.co, 1 +9297z.co, 1 +9297zz.co, 1 +92url.com, 1 +931422.com, 1 +932422.com, 1 +933325.com, 1 +934122.com, 1 +934365.com, 1 +93644.com, 0 +93644a.com, 1 +93644b.com, 1 +93644c.com, 1 +93644d.com, 1 +93644x.com, 1 +93644y.com, 1 +93644z.com, 1 +937774.com, 1 +939394.org, 1 +9397.com, 1 +9397a.com, 1 +9397b.com, 1 +9397bb.com, 1 +9397c.com, 1 +9397cc.com, 1 +9397dd.com, 1 +9397dh.com, 1 +9397e.com, 1 +9397ee.com, 1 +9397f.com, 1 +9397ff.com, 1 +9397g.com, 1 +9397gg.com, 1 +9397h.com, 1 +9397hb.com, 1 +9397hd.com, 1 +9397hh.com, 1 +9397i.com, 1 +9397ii.com, 1 +9397jj.com, 1 +9397kk.com, 1 +9397ll.com, 1 +9397m.com, 1 +9397n.com, 1 +9397nn.com, 1 +9397o.com, 1 +9397oo.com, 1 +9397p.com, 1 +9397pp.com, 1 +9397q.com, 1 +9397qq.com, 1 +9397r.com, 1 +9397rr.com, 1 +9397s.com, 1 +9397ss.com, 1 +9397t.com, 1 +9397tt.com, 1 +9397u.com, 1 +9397uu.com, 1 +9397v.com, 1 +9397vv.com, 1 +9397w.com, 1 +9397ww.com, 1 +9397x.com, 1 +9397xx.com, 1 +9397yy.com, 1 +9397z.com, 1 +9397zz.com, 1 +939wns.com, 1 +93ag8.com, 1 +93cq.com, 1 +93jc.cn, 1 +940365.com, 1 +941988.cn, 1 +943022.com, 1 +9449-27a1-22a1-e0d9-4237-dd99-e75e-ac85-2f47-9d34.de, 1 +944cq.com, 1 +946022.com, 1 +946321.com, 1 +946422.com, 1 +946773.com, 1 +947cq.com, 1 +949022.com, 1 +949122.com, 1 +949622.com, 1 +949722.com, 1 +9499060.com, 1 +9499113.com, 1 +9499115.com, 1 +9499125.com, 1 +9499137.com, 1 +9499151.com, 1 +9499232.com, 1 +9499292.com, 1 +9499293.com, 1 +9499369.com, 1 +9499399.com, 1 +9499403.com, 1 +9499459.com, 1 +9499518.com, 1 +9499558.com, 1 +9499565.com, 1 +9499568.com, 1 +9499575.com, 1 +9499668.com, 1 +9499676.com, 1 +9499737.com, 1 +9499757.com, 1 +9499835.com, 1 +9499869.com, 1 +9499958.com, 1 +9499jjj.com, 1 +9499l.com, 1 +9499mmmm.com, 1 +9499ttt.com, 1 +9499xxx.com, 1 +9499yl.com, 1 +94imk.com, 1 +9528365.com, 1 +956jj.com, 1 +96002.com, 1 +96002e.com, 1 +9617818.com, 1 +9617818.net, 1 +963cq.com, 1 +96658.com, 1 +96658.la, 1 +9666ks.com, 1 +96678.com, 1 +96685.com, 1 +966kb.com, 1 +966ty.com, 1 +967606.com, 1 +9679693.com, 1 +967you.com, 1 +9681909.com, 1 +9721.com, 1 +9721a.com, 1 +9721aa.com, 1 +9721b.com, 1 +9721bb.com, 1 +9721c.com, 1 +9721cc.com, 1 +9721d.com, 1 +9721dd.com, 1 +9721dh.com, 1 +9721e.com, 1 +9721ee.com, 1 +9721ff.com, 1 +9721g.com, 1 +9721gg.com, 1 +9721h.com, 1 +9721hd.com, 1 +9721hh.com, 1 +9721i.com, 1 +9721j.com, 1 +9721jj.com, 1 +9721k.com, 1 +9721l.com, 1 +9721ll.com, 1 +9721m.com, 1 +9721nn.com, 1 +9721o.com, 1 +9721oo.com, 1 +9721p.com, 1 +9721pp.com, 1 +9721q.com, 1 +9721qq.com, 1 +9721r.com, 1 +9721rr.com, 1 +9721s.com, 1 +9721ss.com, 1 +9721t.com, 1 +9721tt.com, 1 +9721u.com, 1 +9721uu.com, 1 +9721v.com, 1 +9721vv.com, 1 +9721w.com, 1 +9721ww.com, 1 +9721x.com, 1 +9721xx.com, 1 +9721z.com, 1 +9721zz.com, 1 +972422.com, 1 +9728.com, 1 +9728a.co, 1 +9728aa.co, 1 +9728b.co, 1 +9728bb.co, 0 +9728c.co, 1 +9728cc.co, 1 +9728d.co, 1 +9728dd.co, 1 +9728dh.com, 1 +9728dns.com, 1 +9728dz.com, 1 +9728e.co, 1 +9728ee.co, 1 +9728f.co, 1 +9728ff.co, 1 +9728g.co, 1 +9728gg.co, 1 +9728h.co, 1 +9728hb.com, 0 +9728hd.com, 1 +9728hh.co, 1 +9728i.co, 1 +9728ii.co, 1 +9728j.co, 1 +9728jj.co, 1 +9728k.co, 1 +9728kk.co, 1 +9728l.co, 1 +9728ll.co, 1 +9728m.co, 1 +9728mm.co, 1 +9728n.co, 1 +9728nn.co, 1 +9728o.co, 1 +9728oo.co, 1 +9728p.co, 1 +9728pp.co, 1 +9728q.co, 1 +9728qq.co, 1 +9728r.co, 1 +9728rr.co, 1 +9728s.co, 1 +9728ss.co, 1 +9728sx.com, 1 +9728t.co, 1 +9728tt.co, 1 +9728u.co, 1 +9728uu.co, 1 +9728v.co, 1 +9728vv.co, 1 +9728w.co, 1 +9728ww.co, 1 +9728x.co, 1 +9728xx.co, 1 +9728y.co, 1 +9728yy.co, 1 +9728z.co, 1 +9728zz.co, 1 +97736.com, 1 +97737.com, 1 +97738.com, 1 +97739.com, 1 +977hghg.com, 1 +977kb.com, 1 +9788876.com, 1 +97bros.com, 1 +9800.cc, 1 +9822.am, 1 +9822am.com, 1 +9822cn.com, 1 +9822hk.com, 1 +9822ph.com, 1 +9822tw.com, 1 +9822usa.com, 1 +982zzz.com, 1 +9836952.com, 1 +984.ch, 1 +9859365.com, 1 +985ccc.com, 1 +986ccc.com, 1 +9877bet.com, 1 +987987.com, 1 +988316.com, 1 +988am8.com, 1 +988am8.net, 1 +98d88.com, 1 +98e.site, 1 +98laba.com, 0 +98laba.net, 0 +9906753.net, 1 +99123j.com, 1 +9918883.com, 1 +991ccc.com, 1 +992ccc.com, 1 +992zzz.com, 1 +99321365.com, 1 +9933445.com, 1 +99365t.com, 1 +99456j.com, 0 +99511.fi, 1 +99599.fi, 1 +99599.net, 1 +995ccc.com, 1 +9968101.com, 1 +9968110.com, 1 +9968121.com, 1 +9968159.com, 1 +9968161.com, 1 +9968202.com, 1 +9968232.com, 1 +9968235.com, 1 +9968285.com, 1 +9968303.com, 1 +9968321.com, 1 +9968343.com, 1 +9968359.com, 1 +9968368.com, 1 +9968383.com, 1 +9968454.com, 1 +9968565.com, 1 +9968595.com, 0 +9968606.com, 1 +9968676.com, 1 +9968678.com, 1 +9968787.com, 1 +9968808.com, 1 +9968838.com, 0 +9968909.com, 1 +9968959.com, 0 +9968989.com, 1 +9968aaa.com, 1 +9968good.com, 1 +9968live.com, 1 +9968love.com, 1 +9968xl.com, 1 +9968xpj.com, 1 +9977432.com, 1 +99789j.com, 1 +997z6.com, 1 +998081.com, 1 +9988ty.com, 1 +998sa.com, 1 +998wei.com, 1 +998wns.com, 1 +998z6.com, 1 +999321365.com, 1 +999365t.com, 1 +9994553.com, 1 +9998722.com, 1 +99989796.com, 1 +99989796.net, 1 +9998k8.com, 1 +99998522.com, 1 +99999822.com, 1 +999998722.com, 1 +99999999977.rocks, 1 +9999k8.net, 1 +999b58.com, 1 +999bet86.com, 1 +999btt.net, 1 +999salon.co, 1 +999salon.com, 1 +999zlong.com, 1 +99billionaire.com, 1 +99buffets.com, 1 +99casinos.com, 1 +99d88.com, 1 +99furnitureideasandtips.gq, 1 +99furnitureideasexamples.ga, 1 +99laptops.com, 1 +99lib.net, 1 +99naturalfoods.de, 1 +99qp.org, 1 +99rst.org, 1 +99spokes.com, 0 +99wxt.com, 1 +9ag88.com, 1 +9articles.org, 1 +9bet86.com, 1 +9box.jp, 1 +9dragonstea.com, 1 +9elements.com, 1 +9fvip.net, 1 +9gag.com, 1 +9hosts.net, 1 +9i0.com, 1 +9iwan.net, 1 +9jajuice.com, 1 +9jajuice.net, 1 +9k226.com, 1 +9k228.com, 1 +9k229.com, 1 +9k233.com, 1 +9k235.com, 1 +9k236.com, 1 +9k237.com, 1 +9k239.com, 1 +9k255.com, 1 +9k256.com, 1 +9k257.com, 1 +9k258.com, 1 +9k259.com, 1 +9k262.com, 1 +9k266.com, 1 +9k267.com, 1 +9k268.com, 1 +9k269.com, 1 +9k282.com, 1 +9k285.com, 1 +9k299.com, 1 +9k323.com, 1 +9k329.com, 1 +9k337.com, 1 +9k339.com, 1 +9k363.com, 1 +9k366.com, 1 +9k373.com, 1 +9k375.com, 1 +9k376.com, 1 +9k378.com, 1 +9k379.com, 1 +9k383.com, 1 +9k385.com, 1 +9k387.com, 1 +9k388.com, 1 +9k389.com, 1 +9k392.com, 1 +9k393.com, 1 +9k397.com, 1 +9k398.com, 1 +9k562.com, 1 +9k566.com, 1 +9k568.com, 1 +9k569.com, 1 +9k572.com, 1 +9k573.com, 1 +9k577.com, 1 +9k585.com, 1 +9k586.com, 1 +9k587.com, 1 +9k589.com, 1 +9k625.com, 1 +9k626.com, 1 +9k632.com, 1 +9k635.com, 1 +9k636.com, 1 +9k637.com, 1 +9k638.com, 1 +9k639.com, 1 +9k653.com, 1 +9k655.com, 1 +9k656.com, 1 +9k657.com, 1 +9k658.com, 1 +9k659.com, 1 +9k662.com, 1 +9k663.com, 1 +9k665.com, 1 +9k667.com, 1 +9k668.com, 1 +9k669.com, 1 +9k675.com, 1 +9k679.com, 1 +9k682.com, 1 +9k686.com, 1 +9k689.com, 1 +9k693.com, 1 +9k695.com, 1 +9k696.com, 1 +9k698.com, 1 +9k699.com, 1 +9k822.com, 1 +9k823.com, 1 +9k825.com, 1 +9k826.com, 1 +9k828.com, 1 +9k829.com, 1 +9k832.com, 1 +9k833.com, 1 +9k835.com, 1 +9k836.com, 1 +9k837.com, 1 +9k852.com, 1 +9k855.com, 1 +9k857.com, 1 +9k858.com, 1 +9k859.com, 1 +9k862.com, 1 +9k865.com, 1 +9k866.com, 1 +9k867.com, 1 +9k869.com, 1 +9k872.com, 1 +9k873.com, 1 +9k875.com, 1 +9k877.com, 1 +9k879.com, 1 +9k882.com, 1 +9k883.com, 1 +9k885.com, 1 +9k886.com, 1 +9k889.com, 1 +9k892.com, 1 +9k893.com, 1 +9k895.com, 1 +9k896.com, 1 +9k897.com, 1 +9k898.com, 1 +9k899.com, 1 +9kb.xyz, 1 +9kopb.ru, 1 +9pkfz.com, 1 +9point6.com, 1 +9riddles.com, 1 +9saves.com, 1 +9to5linux.com, 1 +9to5notes.in, 1 +9u.no, 1 +9uelle.jp, 1 +9ungnir.xyz, 1 +9vx.org, 1 +9yw.me, 1 +a-1indianawaterproofing.com, 1 +a-1waterproofing.com, 1 +a-actor.com, 1 +a-allard.be, 1 +a-bicycleshop.com, 1 +a-busty.com, 1 +a-care.net, 1 +a-colorful-life.com, 1 +a-fx.ru, 0 +a-gokan.com, 1 +a-h-p.de, 1 +a-hitoduma.com, 1 +a-invest.de, 1 +a-ix.net, 1 +a-little-linux-box.at, 1 +a-moe.com, 1 +a-msystems.com, 1 +a-oben.org, 1 +a-players.team, 1 +a-pradana.net, 1 +a-r-t-house.jp, 1 +a-shirouto.com, 1 +a-sparks.com, 1 +a-starbouncycastles.co.uk, 1 +a-up.info, 1 +a-wife.net, 1 +a-ztransmission.com, 1 +a00228.com, 1 +a04gameapp.com, 1 +a04webapp.com, 1 +a05webapp.com, 1 +a06gameapp.com, 1 +a06webapp.com, 1 +a0print.nl, 1 +a122.cc, 1 +a163.top, 1 +a1bouncycastlehire.com, 1 +a1demolitionhauling.com, 1 +a1expresscarremoval.com.au, 1 +a1jumpandbounce.co.uk, 1 +a1moldsolutions.com, 1 +a1post.bg, 1 +a1scrapmetalrecyclers.com.au, 1 +a1scuba.com, 1 +a1spareparts.com.au, 1 +a210.online, 1 +a22z.xyz, 1 +a291.cc, 1 +a2a.me, 1 +a2c-co.net, 1 +a2censo.com, 1 +a2ch.ru, 1 +a2ssrl.duckdns.org, 1 +a30.tokyo, 0 +a356.top, 1 +a36533.com, 1 +a365vip2.com, 1 +a365vip3.com, 0 +a365vip5.com, 1 +a365vip9.com, 0 +a3m.gmbh, 1 +a3mobile.com, 1 +a3sys-elodie.fr, 1 +a4sound.com, 1 +a5197.co, 1 +a567.top, 1 +a632079.me, 1 +a66.la, 1 +a6619.com, 1 +a6621.com, 1 +a6623.com, 1 +a6627.com, 1 +a6631.com, 1 +a6651.com, 1 +a6652.com, 1 +a6657.com, 1 +a6659.com, 1 +a6671.com, 1 +a6672.com, 1 +a6673.com, 1 +a6675.com, 1 +a6682.com, 1 +a6683.com, 1 +a6687.com, 1 +a6691.com, 1 +a6692.com, 1 +a6695.com, 1 +a6729.co, 1 +a6729.com, 1 +a6957.co, 1 +a77018.com, 1 +a789.top, 1 +a7m2.me, 1 +a7sa2eat.com, 1 +a81365.com, 1 +a82365.com, 1 +a88fc.com, 1 +a899365.com, 1 +a9297.co, 1 +a9297.com, 1 +a9721.com, 1 +a9728.co, 1 +aa-tour.ru, 1 +aa00228.com, 1 +aa43d.cn, 1 +aa4888.com, 1 +aa5197.co, 1 +aa6688.net, 0 +aa6729.co, 1 +aa6729.com, 1 +aa6957.co, 1 +aa793.com, 1 +aa9297.co, 1 +aa9397.com, 1 +aa9721.com, 1 +aa9728.co, 1 +aaa-racing.com, 1 +aaa-racing.net, 1 +aaa-racing.uk, 1 +aaa.my, 1 +aaablindfactory.com, 1 +aaacomms.com, 1 +aaainfosystems.com, 1 +aaapl.com, 1 +aaapo.com.br, 1 +aaaportaserve.com, 1 +aabanet.com.br, 1 +aabeltech.com, 1 +aaben-bank.dk, 1 +aabenbank.dk, 1 +aabenjaminjewelry.com, 1 +aacc.ac, 1 +aacs-design.com, 1 +aadv.com.br, 1 +aaex.uk, 1 +aaflalo.me, 1 +aagetransport.no, 1 +aajkakavi.in, 1 +aakf.org.pk, 1 +aalalbayt.com, 1 +aalalbayt.net, 1 +aaliyahclothing.com, 1 +aalstmotors-usedcars.be, 0 +aaltocapital.com, 1 +aalvarezs.cl, 1 +aalvarezs.com, 1 +aamt.es, 1 +aan-shop.co.il, 1 +aanbieders.ga, 1 +aandachtsmeditatie.nl, 1 +aandkevents.co.uk, 1 +aandocontracting.com, 0 +aanhuisgebakken.tk, 1 +aanlynskool.co.za, 1 +aanmeldensecundairescholen.gent, 1 +aanmpc.com, 1 +aanwp.com, 1 +aanyasri.com, 1 +aaomidi.com, 1 +aapar.nl, 1 +aappe.fr, 1 +aardvarksoep.nl, 1 +aariefhaafiz.com, 1 +aarklendoia.com, 1 +aarkue.eu, 1 +aaron-russell.co.uk, 1 +aaron-schaal.de, 1 +aaron-smith-cpa.com, 1 +aaronburrows.com, 1 +aaronfurtado.com, 1 +aaronhorler.com, 1 +aaronkimmig.de, 1 +aaronmaar.de, 1 +aaronosmani.com, 1 +aaronqueen.com, 1 +aaronroyle.com, 1 +aarons.law, 1 +aaronsilber.me, 1 +aaronspain.tk, 1 +aarontechnology.net, 1 +aarquiteta.com.br, 1 +aarsunwoods.com, 1 +aarvinproperties.com, 1 +aarwer.com, 1 +aarwer.jp, 1 +aasvets.co.uk, 1 +aatf.us, 1 +aati.be, 1 +aati.info, 1 +aattrans.com, 1 +aautoline.tk, 1 +aavienna.com, 1 +aavstudio.com, 1 +aawt.net.au, 1 +ab-mfbnigeria.com, 1 +ab-pflege.de, 1 +ab-photography.nl, 1 +ab288.com, 1 +ab2888.cn, 1 +ab28s.com, 1 +ab2web.com, 1 +ab91corp.com, 1 +abaapplianceservice.com, 1 +abaaustin.com, 1 +abaca.bar, 1 +abaclean.com, 1 +abaco.cr, 1 +abacross.com, 1 +abacus-essen.de, 1 +abacusfi.com, 1 +abacuslouisville.com, 1 +abacustech.co.jp, 1 +abaev.uk, 1 +abalsa.tk, 1 +abandoned.photo, 1 +abandoned.tk, 1 +abandonedmines.gov, 1 +abanilla.tk, 1 +abaranov.gq, 1 +abarquinha.tk, 1 +abasalehngo.com, 1 +abashevo.ml, 1 +abasky.net, 1 +abateroad66.it, 1 +abattepeluqueriacitas.com, 1 +abay-today.tk, 1 +abayakaram.org.au, 1 +abazola.cl, 1 +abbadabbabouncycastles.co.uk, 1 +abbas.ch, 1 +abbeyok.com, 1 +abbeyvetspets.co.uk, 1 +abborsjo.fi, 1 +abbottscastles.co.uk, 1 +abbreviated-adult-course.com, 1 +abbruch-star.de, 1 +abbtw.com, 1 +abbyairsoft.tk, 1 +abbyvangrinsven.co.nz, 1 +abc-kinderbetreuung.at, 1 +abc-people.tk, 1 +abc-rz.de, 1 +abc-solutions.cf, 1 +abc-sport-klin.nl, 1 +abc.li, 1 +abc001.ga, 1 +abcbouncycastlessurrey.co.uk, 1 +abcbouncyfactory.co.uk, 1 +abcbusinesspark.com.br, 1 +abcc.dk, 1 +abcdreamusa.com, 1 +abcdthesis.net, 1 +abceducationacademy.com, 1 +abcempreendimentos.com.br, 1 +abcensax.tk, 1 +abcheck.se, 1 +abckam.com, 1 +abclyrics.tk, 1 +abcode.ml, 1 +abcorporate-aviation.com, 1 +abcorporate-aviation.fr, 1 +abcpartyhire.com, 1 +abcrcm.com, 1 +abcstudio.com.au, 1 +abcsystem.ml, 1 +abdel.me, 1 +abdelali.tk, 1 +abdelaliezzyn.tk, 1 +abdl.link, 1 +abdulawal.tk, 1 +abdulkarimm.tk, 1 +abdullaeff.info, 1 +abdullaeff.net, 1 +abdullahavci.com, 1 +abdullahavci.com.tr, 1 +abdullahavci.net.tr, 1 +abdullahzubayerofficial.ml, 1 +abdulrahman.eu, 1 +abdulwahaab.ca, 1 +abdurrahmangazidis.tk, 1 +abdurrehman.tk, 1 +abe-elektro.de, 1 +abe-medical.jp, 1 +abecodes.net, 1 +abeilles-idapi.fr, 0 +abelbarretto.tk, 1 +abellagranitecountertops.com, 1 +abellanillos.com, 1 +abelles.cf, 1 +abelles.gq, 1 +abelles.ml, 1 +abelles.tk, 1 +abelordbalagtas.com, 1 +abelrubio.me, 1 +abelsflooringandtile.com, 1 +abemarx.hu, 1 +abenteuer-ahnenforschung.de, 1 +aberdeenalmeras.com, 1 +aberdeencastles.co.uk, 1 +aberdeencriticalmass.tk, 1 +aberdeenjudo.co.uk, 1 +abetterdeath.com, 1 +abetterwichita.com, 1 +abetterwichita.org, 1 +abeus.com, 1 +abg.ninja, 1 +abhaldus.ee, 1 +abhayaranya.com, 1 +abhijitvalluri.com, 1 +abhisharma.me, 1 +abhishekkabdijain.tk, 1 +abi-fvs.de, 1 +abi95oha.de, 1 +abiapp.net, 1 +abibliasagrada.tk, 1 +abibruce.co.uk, 1 +abidinginhesed.com, 1 +abierta.cr, 1 +abiertoempleos.com, 1 +abigailstark.com, 1 +abigisp.com, 1 +abilenemachine.com, 1 +abilitycaresoftware.com, 1 +abilitymatters.co.uk, 1 +abilityone.gov, 1 +abilix.tk, 1 +abilma.com, 1 +abilymp06.net, 1 +abilympics.org.au, 1 +abimelec.com, 0 +abinferis.com, 1 +abinyah.com, 1 +abitaspringsla.gov, 1 +abitech.tk, 1 +abitidalavoro.roma.it, 1 +abitidasposa.roma.it, 1 +abiturma.de, 1 +abjay.com, 1 +abkbank.de, 1 +abkhazianews.tk, 1 +ablecha.tk, 1 +ableofficeadmin.com, 1 +ableprop.net, 1 +abloomnova.net, 1 +abloop.com, 1 +abmackenzie.com, 1 +abminiplex.in, 1 +abmledger.ca, 1 +abmtax.ca, 1 +abn-consultants.ie, 1 +abnamropensioenen.nl, 1 +abnehmen.com, 1 +abnobapetstore.co.uk, 1 +abnradiofm.tk, 1 +aboces.org, 1 +aboderenovation.co.uk, 0 +abogadamediadora.es, 1 +abogadocriminalorlando.com, 1 +abogadoperu.com, 1 +abogadophd.com, 1 +abogadoscav.com, 1 +abolicionistas.com, 1 +abolition.net, 1 +abolitionism.ca, 1 +abolitionism.co.uk, 1 +abolitionism.com, 1 +abolitionism.in, 1 +abolitionism.net, 1 +abolitionism.us, 1 +abolitionist-project.com, 1 +abolitionist-society.com, 1 +abolitionist.ca, 1 +abolitionist.co.uk, 1 +abolitionist.com, 1 +abolitionist.in, 1 +abolitionist.net, 1 +abolitionist.us, 1 +abolitionistparty.com, 1 +abolitionistproject.com, 1 +abolitionistsociety.com, 1 +abolitionniste.com, 1 +abolitionofspeciesism.tk, 1 +abolizionista.com, 1 +abona24.de, 1 +abonentka.tk, 1 +abonilla.com, 1 +aborla.net, 1 +abos.eu, 0 +aboticaprodutosnaturais.com, 1 +abouncycastleman.co.uk, 1 +about-bangladesh.tk, 1 +about-jewelry.tk, 1 +about-sects-and-cults.tk, 1 +about-ti.me, 1 +aboutamit.com, 1 +aboutassistedliving.org, 0 +aboutconstruction.gq, 1 +aboutconstruction.ml, 1 +aboutdelphi.tk, 1 +aboutdiabetesinfo.gq, 1 +aboutgrills.tk, 1 +abouthistory.tk, 1 +abouthrm.nl, 1 +aboutict.nl, 1 +aboutlegal.nl, 1 +aboutmedia.nl, 1 +aboutmoney.tk, 1 +aboutmusicals.tk, 1 +aboutmyip.info, 1 +aboutmyproperty.ca, 1 +aboutpakistan.com, 1 +aboutpublishers.nl, 1 +aboutrom.tk, 1 +aboutshakil.cf, 1 +aboutshakil.tk, 1 +aboutsleep.com.ua, 1 +aboutspice.com, 1 +abouttime.gq, 1 +abouttravel.gq, 1 +aboutwealthcreation.tk, 1 +aboutyou.at, 1 +aboutyou.be, 1 +aboutyou.ch, 1 +aboutyou.cz, 1 +aboutyou.de, 1 +aboutyou.nl, 1 +aboutyou.si, 1 +aboveaverageplumbing.com, 1 +abox-kb.com, 1 +aboyle.ca, 1 +abpis.hr, 1 +abplive.com, 1 +abpoolsub.com, 1 +abracadabra.co.jp, 0 +abracadabra.com, 1 +abrah.am, 1 +abrahametalero.tk, 1 +abram-lab.ir, 1 +abramovich.tk, 1 +abramowskimi.tk, 1 +abraxan.pro, 1 +abrec.ga, 1 +abrightsolution.co.uk, 1 +abrightspark.gq, 1 +abrikos.group, 1 +abrilect.com, 1 +abristolgeek.co.uk, 1 +abrition.com, 1 +abroferlendo.tk, 1 +absat.tk, 1 +absb.ca, 1 +abschleppdienst-hilfe.de, 1 +abseits.org, 0 +absolem.cc, 1 +absoluav.com, 1 +absoluconseils.com, 1 +absolucopine.com, 1 +absolugroupe.com, 1 +absoluphoto.com, 1 +absolutcruceros.com, 1 +absolute.com, 1 +absoluteautobody.com, 1 +absolutebritney.com, 1 +absolutedouble.co.uk, 1 +absoluterush.net, 1 +absolutezero.tk, 1 +absolutperm.tk, 1 +absolutviajes.com, 1 +absolutweb.tk, 1 +abstechs.ae, 1 +abstimmen.online, 1 +abstractbarista.com, 1 +abstractbarista.net, 1 +absturztau.be, 1 +absturztaube.ch, 1 +absurdia.tk, 1 +absurdopedia.wiki, 1 +absynthe-inquisition.fr, 1 +absyscyborg.com, 1 +abth.tk, 1 +abthorpe.org, 1 +abtinheydari.tk, 1 +abtinsh.com, 1 +abu-auftrag.ch, 1 +abu-nour.tk, 1 +abuahmed.ga, 1 +abulanov.com, 1 +abundanteconomy.com, 1 +abundent.com, 1 +abusamraphotography.tk, 1 +abuse.ch, 1 +abuse.fi, 1 +abuse.io, 1 +abusinessinabox.ca, 1 +abusive-host.tk, 1 +abvent.net, 0 +abvlbasketviganello.ch, 0 +abwatches.net, 1 +abysra.com, 1 +abyssinian.ga, 1 +abyssiniankitty.com, 1 +abyssproject.net, 1 +abyzebyzek.tk, 1 +abzarweb.com, 1 +ac-admin.pl, 1 +ac-booster.net, 1 +ac-cosmetics.nl, 1 +ac-town.com, 1 +ac.id.au, 1 +ac.milan.it, 1 +ac0g.dyndns.org, 1 +aca-creative.co.uk, 1 +acacia-gardens.co.uk, 1 +academiaba.com, 1 +academiacivilbalonmano.tk, 1 +academiadebomberosonline.com, 1 +academiadetecnologia.com, 1 +academiaelizart.ro, 1 +academiaeureka.tk, 1 +academiaoposicionescorreos.com, 1 +academiasdemodelos.com, 1 +academica.nl, 1 +academichealthscience.net, 1 +academichelp.gq, 1 +academie-de-police.ch, 0 +academie-essentiel.ch, 1 +academie-musique-nice.com, 0 +academkin.com, 1 +academus.io, 1 +academy-awards.ml, 1 +academytv.com.au, 1 +acadiate.com, 1 +acahaymarket.com.ec, 1 +acampar.com.br, 1 +acandroid.top, 1 +acaonegocios.com.br, 1 +acapadena.co, 1 +acapellalanguage.tk, 1 +acapetahua.tk, 1 +acaptureservices.com, 1 +acara-yoga.de, 1 +acareer.in, 1 +acaseta.com, 1 +acat.io, 1 +acatec.de, 1 +acbrussels-used.be, 0 +accademia24.it, 1 +accademiaditruccoblog.it, 1 +accademiaprati.tk, 1 +accademiapugilistica.it, 1 +accadia.academy, 1 +acccnyc.org, 0 +accelaway.com, 1 +acceldigital.com.au, 1 +acceleranda.com, 1 +acceleratedpayments.com, 1 +acceleratedreading.cf, 1 +accelerateyourworld.org, 1 +accelerator.tk, 1 +accelsnow.com, 1 +accentthailand.com, 1 +acceptancerecoverycenter.com, 1 +acces-elevation.fr, 1 +accesloges.com, 1 +access-board.gov, 1 +access-odata.com, 1 +accessacab.co.uk, 1 +accessauto-occasions.be, 0 +accessgaragedoors.com, 1 +accesshq.com, 1 +accessibility.gov, 1 +accessibilityguidelines.com, 1 +accessibletravelclub.com, 1 +accessiware.com, 1 +accesskeycloning.com, 1 +accesslogisticgroup.com, 1 +accessmania.com, 1 +accessnetworks.com, 1 +accessoirescheveuxchic.com, 1 +accessories-for-women.tk, 1 +accessoriesautoparts.tk, 1 +accessoripersmartphone.it, 1 +acchan-fun.com, 1 +accioninmobiliaria.tk, 1 +accionistaprincipiante.com, 1 +acclivity.pro, 1 +accme.co, 1 +accniitmash.ru, 1 +accolade.com.br, 1 +accoladescreens.com.au, 1 +accord-application.com, 1 +accordable.gq, 1 +accordiondoor.com, 1 +accordproject.tk, 1 +account.bbc.com, 1 +accountmover.io, 1 +accounts.firefox.com, 1 +accounts.google.com, 1 +accpl.co, 1 +accpressurewashing.com, 1 +accreditamento.net, 1 +accrosoft.com, 1 +accs.org.au, 1 +accurateautobodywa.com, 1 +accurateinfosolutions.in, 1 +accuritconsulting.com, 1 +accustomedicals.ga, 1 +accutint.com, 1 +accutone.com.mx, 1 +accwing.com, 1 +acdcbrasil.net, 1 +acdk2.de, 1 +ace-aegon.cloud, 1 +ace-clan.tk, 1 +ace-familydental.com, 1 +ace.one, 1 +ace360.org, 1 +acealters.com, 0 +aceanswering.com, 1 +acebovirtual.tk, 1 +acecerts.co.uk, 1 +acecolleges.edu.au, 1 +acedstudy.com, 1 +acefishing.tk, 1 +acefreightco.com, 1 +aceinflatables.com, 1 +aceinstituteonline.com, 1 +aceitedelcampo.com, 1 +aceleraguria.com.br, 1 +aceleratuweb.com, 1 +acelpb.com, 1 +acem.org.au, 1 +acemadeira.pt, 1 +acemobileforce.com, 1 +acemsa.ga, 1 +acemypaper.com, 1 +acendealuz.com.br, 1 +aceofdiamondspainting.com, 1 +aceparking.com, 1 +acephalafashion.com, 1 +acercapartners.com, 1 +acerentalandsales.com, 1 +acerislaw.com, 1 +acerosfortuna.com.mx, 1 +aceshop702.com, 1 +acessoeducacao.com, 1 +acetudy.com, 1 +acftienda.tk, 1 +acfun.eu.org, 1 +acg.mn, 1 +acgaudio.com, 1 +acgc.nl, 1 +acgmoon.com, 1 +acgmoon.org, 1 +acgpiano.club, 1 +acgqwq.gq, 1 +acgtalktw.com, 1 +achalay.org, 0 +acharin.org, 1 +achat-de-lead.com, 1 +achat-volets-roulants.fr, 1 +acheconcursos.com.br, 1 +acheter-ethylotest.fr, 1 +achieveinternet.com, 1 +achievenewsfrance.tk, 1 +achiever.ga, 1 +achievingheightsacademy.com, 1 +achiksongs.tk, 1 +achill.org, 1 +achinsk.tk, 1 +achkandiro.ml, 1 +achmadfamily.com, 1 +achmazstore.ir, 1 +achromatisch.de, 1 +achterblog.de, 1 +achterhoekseveiligheidsbeurs.nl, 1 +achterstieg.dedyn.io, 1 +achtzehn.de, 1 +achtzehn.eu, 1 +achtzig20.de, 1 +achwo.de, 1 +aciclinical.com, 1 +aciclovir.ga, 1 +acidchrist.tk, 1 +acidoascorbico.com, 1 +acihotel.vn, 1 +aciksite.com, 1 +acilicraft.cn, 1 +acina.fr, 1 +acinq.co, 1 +ackadia.com, 1 +ackermann.ch, 1 +acl.gov, 1 +aclandia.fr, 1 +aclasskids.ru, 1 +aclipt.com, 1 +aclu.org, 0 +acluva.org, 0 +acmegamer.com, 1 +acmi.fr, 1 +acmilan.gq, 1 +acnh.info, 1 +acodess.com, 1 +acolicy.com, 1 +acolle.co.jp, 1 +acomerygozar.cam, 1 +acomplia20mg.cf, 1 +aconnor.xyz, 1 +acordes.online, 1 +acorncastles.co.uk, 1 +acorncredentialing.com, 1 +acourse.io, 0 +acousti-tech.com, 1 +acousticalsolutions.com, 1 +acousticbiotech.com, 1 +acoustics.network, 1 +acoustics.tech, 1 +acousticsoundrecords.com, 1 +acoustique-tardy.com, 0 +acp-integrative.fr, 1 +acpa-ancenis.fr, 1 +acperu.ch, 0 +acpica.org, 1 +acpinformatique.fr, 1 +acquadiparma.kr, 1 +acquaparrucchieri.it, 1 +acquire.co.nz, 1 +acquireit.com.au, 1 +acquisition.gov, 1 +acredperu.org, 1 +acrepairgeorgetown.com, 1 +acrepairhutto.com, 1 +acrepairroundrocktx.com, 1 +acrhnc2020.dedyn.io, 1 +acriticismlab.org, 1 +acrobatic.tk, 1 +acronaline.com, 1 +acronis.com, 1 +acronis.org, 1 +acronis.work, 1 +acronym24.com, 1 +acropolis.edu.mx, 1 +across-community.tk, 1 +across.ml, 1 +acrossgw.com, 1 +acrosstheblvd.com, 1 +acrowebs.com, 1 +acroyoga-nuernberg.de, 1 +acrylbilder-acrylmalerei.de, 1 +acrylicwifi.com, 1 +acs-nettoyage-entretien-immeuble.com, 1 +acsbbs.org, 1 +acsc.gov.au, 1 +acscbasket.com, 1 +acsemb.org, 1 +acsihostingsolutions.com, 0 +acsports.ca, 1 +actc.org.uk, 1 +actdigital.agency, 1 +actexpo.com, 1 +actforrights.com, 1 +actgruppe.de, 0 +actheater.com, 1 +acticu.com, 1 +actiefgeld.nl, 0 +actilove.ch, 1 +actimap.ga, 1 +acting.by, 1 +actingcxo.com, 1 +action-biosphere.org, 1 +action-intell.com, 1 +action-verite.fr, 1 +actioncameraaccessories.ga, 1 +actioncleaningnd.com, 1 +actioncoachignite.co.za, 1 +actioncutprint.com, 1 +actionfinancialservices.net, 1 +actionlabs.net, 1 +actionmadagascar.ch, 0 +actionminecraft.tk, 1 +actionsack.com, 1 +activatemyiphone.com, 1 +activateudid.com, 1 +active-english.tk, 1 +active.hu, 0 +active247.info, 1 +activeaerogels.com, 1 +activecare-monitor.com, 0 +activeclearweb.com, 1 +activeexcavator.com, 1 +activefootandankle.com, 1 +activehire.co.uk, 1 +activeleisure.ie, 1 +activelife.travel, 0 +activephoto.se, 1 +activeplatesystem.ga, 1 +activespaceautomation.com, 1 +activespacetech.com, 1 +activism.cf, 1 +activiteithardenberg.nl, 1 +activitesaintnicaise.org, 1 +activiteschiens.be, 1 +activiti.alfresco.com, 1 +activityhub.cloud, 1 +activityhub.xyz, 1 +activohotels.com, 1 +activs.ru, 1 +actom.cc, 1 +actom.org, 1 +actonwoodworks.com, 1 +actoralcareprofessional.com, 1 +actors-cafe.net, 1 +actorsanthosh.tk, 1 +actorshop.co.uk, 1 +actorsroom.com, 1 +actrices.tk, 1 +actris.ac.cy, 1 +actro.ga, 1 +actserv.co.ke, 1 +actualadmins.com, 1 +actualidadblog.com, 1 +actualidadecommerce.com, 1 +actualidadgadget.com, 1 +actualidadiphone.com, 1 +actualidadkd.com, 1 +actualidadliteratura.com, 1 +actualidadmotor.com, 1 +actualidadviajes.com, 1 +actualite-videos.com, 1 +actualizarapp.com, 1 +actualpost.com, 1 +actualsolutions.am, 1 +actuatemedia.com, 1 +actuse.tk, 1 +acuarismo-iquique.tk, 1 +acuarius.tk, 1 +acudire.es, 1 +acuica.co.uk, 0 +acuityfinishing.com, 1 +acul.me, 1 +aculocity.com, 1 +acunetix.com, 1 +acupofsalt.tv, 1 +acupuncture.ml, 1 +acupuntura.coach, 1 +acupuntura.doctor, 1 +acupuntura.institute, 1 +acupunturamadrid.xyz, 1 +acupunturavalencia.xyz, 1 +acus.gov, 1 +acusticocoffeehouse.com, 1 +acutane.ga, 1 +acutehoest.nl, 1 +acutewealthadvisors.com, 1 +acuvate.com, 1 +acvan.net, 1 +acwcerts.co.uk, 1 +acwi.gov, 1 +acy.com, 1 +acyclovir-cream.cf, 1 +acyclovir400mg.ml, 1 +acytec.cl, 1 +ad-disruptio.fr, 0 +ad-notam.asia, 1 +ad-notam.ch, 1 +ad-notam.co.uk, 1 +ad-notam.com, 1 +ad-notam.de, 1 +ad-notam.fr, 1 +ad-notam.it, 1 +ad-notam.pt, 1 +ad-notam.uk, 1 +ad-notam.us, 1 +ad-s.cn, 1 +ad13.in, 1 +ada.eco, 1 +ada.gov, 1 +adaera.com, 1 +adagia.eu, 1 +adaiacorporation.com, 1 +adaio.es, 1 +adaio.eu, 1 +adaio.net, 1 +adala.com.kw, 1 +adalis.org, 1 +adalite-staging-testnet.herokuapp.com, 1 +adalite.io, 1 +adam-ant.co.uk, 1 +adam-kostecki.de, 1 +adam.id.au, 1 +adam.lgbt, 1 +adamabernathy.com, 1 +adamadr.com, 1 +adamas-magicus.ru, 1 +adamaveray.com.au, 1 +adambalogh.net, 1 +adambryant.ca, 0 +adamcoffee.net, 1 +adamdixon.co.uk, 1 +adamdorman.com, 1 +adamfontenot.com, 1 +adamgibbins.com, 1 +adamh.us, 1 +adamh.website, 1 +adamjoycegames.co.uk, 1 +adamkostecki.de, 1 +adamlee.com, 0 +adamlevine.ga, 1 +adamliu.net, 0 +adamoutler.com, 1 +adamov.tk, 1 +adamradocz.com, 1 +adamraoof.tk, 1 +adamricheimer.com, 1 +adams.dk, 1 +adams.es, 1 +adamsasphaltpaving.com, 1 +adamscampcolorado.org, 1 +adamstas.com, 1 +adamwallington.co.uk, 1 +adamyuan.xyz, 1 +adappt.co.uk, 1 +adapptlabs.com, 1 +adapt-elektronik.com, 1 +adaptationplatform.ca, 1 +adapti.de, 1 +adaptiv.ltd, 1 +adaptivecenter.net, 1 +adaptiveequipment.com.au, 1 +adaptivehedge.com, 1 +adaptiveicons.com, 1 +adaptivemechanics.edu.au, 1 +adaptivesite.cf, 1 +adaptiveu.io, 1 +adaptsolvents.com, 1 +adarixconsultores.com, 1 +adarshcloud.in, 1 +adarshthapa.in, 1 +adarshthapa.net, 1 +adarsvidler.me, 1 +adasbench.com, 1 +adata.kz, 1 +adativos.com.br, 1 +adauge.com, 1 +adawolfa.cz, 1 +adayinthelifeof.nl, 1 +adblock.ovh, 1 +adblockextreme.com, 1 +adblockextreme.net, 1 +adblockextreme.org, 1 +adboard.info, 1 +adbpub.com, 1 +adc64.com, 1 +adceuta.tk, 1 +adcnvs.com, 1 +addag.de, 1 +addbonus.ml, 1 +addcrazy.com, 1 +adder.ml, 1 +adderall.ml, 1 +adderall.space, 1 +addictedtolength.co.uk, 1 +addictedtotravel.pl, 1 +addictionresource.com, 1 +addictionsolutionsllc.com, 1 +addictively.com, 1 +addictlaw.com, 1 +addiko.net, 1 +addiko.rs, 1 +addisoncrump.info, 1 +addlink.ga, 1 +addmefast.tk, 1 +addnewsite.tk, 1 +addnine.com, 1 +addo-addo.com, 1 +addon.watch, 1 +addones.org, 1 +addr.space, 1 +addresstobe.com, 1 +addscoop.ml, 1 +addstar.jp, 0 +addtoany.com, 1 +adduono.com, 1 +addurls.tk, 1 +addydari.us, 1 +addyourlink.tk, 1 +adec-emsa.ae, 1 +adelaidecc.com.au, 0 +adelaidecoldlaser.com.au, 1 +adelebeals.com, 1 +adelgace.top, 1 +adelicious.co, 1 +adelightfulglow.com, 1 +adelina.com.br, 0 +adeline.mobi, 1 +adelonline.tk, 1 +ademaulana.tk, 1 +ademy.ml, 1 +adenoma.tk, 1 +adenopatia.com, 1 +adenos.in, 1 +adenplus1.com, 1 +adentalsolution.com, 1 +adeon.ml, 1 +adept-elearning.com, 1 +adept.org.pl, 1 +adesa-asesoria.com, 1 +adesachatbottecnicowab01.azurewebsites.net, 1 +adescb.ga, 1 +adesex.in, 1 +adevel.eu, 1 +adevo.be, 1 +adex.network, 1 +adextremadurafs.tk, 1 +adf-safetytools.com, 1 +adf.gov, 1 +adfisicateca.org, 1 +adftrasporti.it, 1 +adfxllc.com, 1 +adgift.ro, 1 +adh.org.au, 1 +adhd-explained.com, 1 +adhd-inattentive.com, 1 +adhdyogi.ca, 1 +adhgroup.ug, 1 +adhigamindia.com, 1 +adhockery.ga, 1 +adhocracy.plus, 1 +adhyayanclasses.com, 1 +adi.com.au, 1 +adi.company, 1 +adi.net.au, 1 +adib.family, 1 +adidas-2020-spring.com, 1 +adiehard.party, 0 +adiesyndrome.tk, 1 +adilgraphics.com, 1 +adilsoybali.com.tr, 1 +adimplere.com.br, 1 +adinfinitum.gq, 1 +adingenierie.fr, 1 +adinternational.com.au, 1 +adiprospero.it, 1 +adiraku.co.id, 1 +adiscorduser.com, 1 +aditro.com, 1 +adje-fansite.tk, 1 +adlerneves.com, 1 +adlerneves.com.br, 1 +adlerosn.com, 1 +adlerosn.com.br, 1 +adlershop.ch, 1 +adlignum.se, 1 +adm-sarov.ru, 1 +adme.co.il, 1 +admicos.cf, 1 +admin-gator.com, 1 +admin-gator.net, 1 +admin-serv.net, 1 +admin.fedoraproject.org, 1 +admin.google.com, 1 +admin.place, 1 +admin.stg.fedoraproject.org, 1 +admind.at, 1 +admindaily.com, 1 +adminforge.de, 1 +admingator.com, 1 +admingator.net, 1 +administracionessaez.es, 1 +administratie-smits.nl, 1 +administratiekantoorblom.nl, 1 +administrator.de, 1 +administratorhandal.cf, 1 +administratorserwera.pl, 0 +adminless.ovh, 1 +adminlinux.pl, 1 +adminmare.4lima.de, 1 +admino.cz, 1 +adminova.tk, 1 +adminresurs.tk, 1 +adminrezo.fr, 1 +adminton.eu, 1 +admiralshipsupplier.com, 0 +admody.com, 1 +admongo.gov, 1 +adn-recrutement.fr, 1 +adnanotoyedekparca.com, 1 +adnexa.it, 1 +adnmb1.com, 1 +adnolesh.com, 1 +adnotam.ch, 1 +adnseguros.es, 1 +adoll.ml, 1 +adomani-italia.com, 1 +adomicilio.com.gt, 1 +adomicilio.gt, 1 +adon.is, 1 +adonai.eti.br, 1 +adondevamosmundo.com, 1 +adonis.media, 1 +adonisgrup.ro, 1 +adonizer.science, 1 +adonnante.com, 0 +adontenchambers.com, 1 +adopt.tk, 1 +adoptabeehive.co.uk, 1 +adoptabeehive.com, 1 +adoptabeehive.org, 1 +adoptabeehive.org.uk, 1 +adoptionpregnancycenter.com, 1 +adoptionpregnancycenter.net, 1 +adorade.ro, 1 +adorai.tk, 1 +adoran.ga, 1 +adorecricket.com, 1 +adores.gq, 1 +adorewe.co.uk, 1 +adorewe.com, 1 +adorez.tk, 1 +adoric.com, 1 +adorned.ga, 1 +adorno-gymnasium.de, 1 +adotta.me, 1 +adoucisseur.shop, 1 +adpost.com, 1 +adquisitio.co.uk, 1 +adquisitio.es, 1 +adr.gov, 1 +adra.com, 1 +adrafinil.wiki, 1 +adrans.com, 1 +adregain.com, 1 +adregain.ru, 1 +adrenalin.od.ua, 1 +adrenaline-gaming.ru, 1 +adrenalinhunters.tk, 1 +adresults.com, 1 +adresults.nl, 1 +adrian-riemer.tk, 1 +adrian.web.id, 1 +adrian2023.com, 1 +adrianadelrossi.com, 1 +adrianajewelry.my, 1 +adrianasantos.me, 1 +adrianbechtold.de, 1 +adriancitu.com, 1 +adriancostin.ro, 1 +adrianfeliciano.com, 1 +adrianhardy.com, 1 +adrianjensen.com, 1 +adriankeenan.co.uk, 1 +adrianmejias.com, 1 +adrianobarbosa.xyz, 1 +adrianpetcu.tk, 1 +adrianpole.tk, 1 +adrianseo.ro, 0 +adrianwalls.tk, 1 +adrianweb.ml, 1 +adriarae.xyz, 1 +adriatic.hr, 1 +adriatika.tk, 1 +adriatrans.ga, 1 +adrienjacquierbret.com, 1 +adrienkohlbecker.com, 1 +adriennesmiles.com, 1 +adrinet.tk, 1 +adrino.ml, 1 +adrup.com, 1 +adsbouncycastles.co.uk, 1 +adscambodia.com, 1 +adsense-arbitrage.com, 1 +adserve.works, 1 +adsforcash.ga, 1 +adsib.gob.bo, 1 +adsl2meg.fr, 1 +adsmobilefor.win, 1 +adsnn.com, 1 +adson.at, 1 +adson.cz, 1 +adson.de, 1 +adson.ee, 1 +adson.eu, 1 +adson.fi, 1 +adson.fr, 1 +adson.hu, 1 +adson.ie, 1 +adson.li, 1 +adson.lt, 1 +adson.lv, 1 +adson.nl, 1 +adson.no, 1 +adson.pt, 1 +adspire.tk, 1 +adspu.org, 1 +adstop.ml, 1 +adstrafficsales.com, 0 +adstune.com, 1 +adsviews.gq, 1 +adswoo.com, 1 +adtelligent.com, 1 +adtgroup.com, 1 +adti.pt, 0 +adultbizz.eu, 1 +adultforum.gr, 1 +adultshop.com.au, 1 +adultwebcams1.com, 1 +adurra.com, 1 +adutoras.com.br, 1 +adv.cr, 1 +advair-generic.ga, 1 +advairgeneric.ga, 1 +advairprice.ga, 1 +advaith.fun, 1 +advaith.io, 1 +advaithbot.xyz, 1 +advance.hr, 1 +advanced-fleet-services.com, 1 +advanced-online.eu, 1 +advanced-scribes.com, 1 +advanced.info, 0 +advancedbotoxclinic.com, 1 +advanceddieselspokane.com, 1 +advancedelectricalservicesqld.com.au, 1 +advancedendoscopycenter.net, 1 +advancedheatinginc.com, 1 +advancednetflowtraining.com, 1 +advancedob-gyn.com, 1 +advancedoneroofing.com, 1 +advancedprotectionkey.com, 1 +advancedprotectionsecuritykey.com, 1 +advancedroofingmuskoka.com, 1 +advancedseotool.it, 1 +advancedsepticandpumping.com, 0 +advancedsurgicalconsultantsllc.com, 1 +advancedturf.tk, 1 +advancedurologyca.com, 1 +advancedurologyswla.com, 1 +advancedwriters.com, 1 +advanceworx.com, 1 +advancis.net, 1 +advania.info, 1 +advantagehomeexteriors.com, 1 +advantagehomeinteriors.com, 1 +advantagemechanicalinc.com, 1 +advantageroofer.com, 1 +advantis.tk, 1 +advara.com, 1 +advasa.jp, 1 +advasa.net, 1 +advbizintel.com, 1 +advenacs.com, 1 +advenacs.com.au, 1 +advenapay.com, 1 +advenirewealth.com, 1 +advens.com, 1 +advens.fr, 1 +adventaholdings.com, 1 +adventistai.lt, 1 +advento.bg, 1 +adventry.tk, 1 +adventure-inn.com, 1 +adventureally.com, 1 +adventurealpinetreks.com, 1 +adventureboundlife.com, 1 +adventurecorps.gq, 1 +adventurecreators.com, 1 +adventuredrives.com, 0 +adventureforest.co.nz, 1 +adventureforest.de, 0 +adventureforest.nz, 1 +adventuregamers.com, 1 +adventurenow.nl, 1 +adventures.com, 1 +adventuresinparanoia.com, 1 +adventureswithlillie.ca, 1 +adventureworldtour.com, 1 +adventuringup.com, 1 +adventurousway.com, 1 +adventus.space, 1 +advercarte.com, 1 +adversus-test.tk, 0 +adversus-web-staging.tk, 0 +advertis.biz, 1 +advertising-design.tk, 1 +advertisingcompany.tk, 1 +adveszker.hu, 1 +advice24.tk, 1 +advirk.tk, 1 +advisercentre.com.au, 1 +adviserplus.com, 1 +advmaster.cf, 1 +advocatae.com, 1 +advocaten-avocats.be, 1 +advocatize.com, 1 +advocator.ca, 1 +advoervice.ga, 1 +advogatech.com.br, 1 +advokat-dtp.cf, 1 +advokat-dtp.ga, 1 +advokat-dtp.gq, 1 +advokat-dtp.ml, 1 +advokat-dtp.tk, 1 +advokat-malinovskii.ml, 1 +advokat-romanov.com, 1 +advokat-vvp.com.ua, 1 +advokat73.gq, 1 +advokatfrolov.com, 1 +advokati-ceva.cz, 1 +advokatkonsult.cf, 1 +advokatonline.ml, 1 +advokatskoe-byuro.ml, 1 +advokaty-onlajn.cf, 1 +advokaty-onlajn.ga, 1 +advokaty-onlajn.gq, 1 +advokaty-onlajn.ml, 1 +advokaty-onlajn.tk, 1 +advokaty-yuristy.ga, 1 +advokaty-yuristy.ml, 1 +advokaty-yuristy.tk, 1 +advokaty.cf, 1 +advokaty.gq, 1 +advst.uk, 1 +advtran.com, 0 +adware.pl, 0 +adwokatzdunek.pl, 1 +adws.io, 1 +adxperience.com, 1 +adygeya.cf, 1 +adzie.xyz, 1 +adzuna.at, 1 +adzuna.ca, 1 +adzuna.co.nz, 1 +adzuna.co.za, 1 +adzuna.com, 1 +adzuna.com.au, 1 +adzuna.com.br, 1 +adzuna.de, 1 +adzuna.fr, 1 +adzuna.in, 1 +adzuna.it, 1 +adzuna.nl, 1 +adzuna.pl, 1 +adzuna.ru, 1 +adzuna.sg, 1 +ae-construction.co.uk, 1 +ae-dir.com, 1 +ae-dir.org, 1 +ae86.de, 1 +ae86.dog, 1 +ae86.im, 1 +ae86.in, 1 +ae86.pro, 1 +ae86.pw, 1 +ae86.run, 1 +ae86.tv, 1 +ae86c.com, 1 +ae86dj.com, 1 +ae86dy.com, 1 +ae86f.com, 1 +ae86k.com, 1 +ae86m.com, 1 +ae86nb.com, 1 +ae86t.com, 1 +ae86tt.com, 1 +ae86u.com, 1 +ae86uu.com, 1 +ae86v.com, 1 +ae86w.com, 1 +ae86x.com, 0 +ae86y.com, 1 +ae86yy.com, 1 +ae86zx.net, 1 +ae86zy.com, 1 +aeb.io, 1 +aebba.org, 1 +aebian.org, 1 +aebleskoven.dk, 1 +aecexpert.fr, 1 +aechelon.net, 1 +aecis.org, 1 +aecom.digital, 1 +aecom.io, 1 +aedollon.com, 1 +aefcleaning.com, 1 +aegee-utrecht.nl, 1 +aegis.moe, 1 +aegisaccounting.co.uk, 1 +aegisalarm.co.uk, 1 +aegisalarm.com, 1 +aegisalarms.co.uk, 1 +aegisalarms.com, 1 +aegrel.ee, 1 +aeh5134.cc, 1 +aeksistem.com, 1 +aelena.games, 1 +aelieve.com, 1 +aelisya.net, 0 +aenterprise.info, 1 +aeolservice.es, 1 +aeon.co, 1 +aeonc.com, 1 +aeonct.org, 1 +aepx.org, 1 +aeradesign.com, 1 +aerandir.fr, 1 +aeravo.co, 1 +aeravo.org, 1 +aerelon.de, 1 +aergia.eu, 1 +aerisnetwork.com, 1 +aerlux.md, 1 +aero-pioneer.com, 1 +aero.parts, 1 +aeroacademia.com.mx, 1 +aeroalbrook.com, 1 +aerobasegroup.com, 1 +aerobatt.com, 1 +aerobotz.com, 1 +aeroexpress.tk, 1 +aeroflot.gq, 1 +aeroframe.tk, 1 +aeroglass.ml, 1 +aerolineasvenezolanas.net, 1 +aeronautix.com, 1 +aeronote.net, 1 +aeroplan.tk, 1 +aeropole.de, 1 +aeropole.eu, 1 +aeroport.gq, 1 +aerorecords.net, 1 +aerosoul.tk, 1 +aerospace-schools.com, 1 +aerospacearchives.tk, 1 +aerospacescience.ml, 1 +aerotechcoatings.com, 1 +aerowillys.tk, 1 +aertel.ie, 1 +aes-freundeskreis.de, 1 +aessencia.com.br, 1 +aestheticsplus.xyz, 1 +aesthetikpiercing.de, 1 +aesthetx.com, 1 +aestore.by, 1 +aesvalanalys.com, 1 +aesym.de, 1 +aeternus-darkermonument.tk, 1 +aeternus.tech, 1 +aetherc0r3.eu, 1 +aethereahealth.com, 1 +aetherlink.de, 1 +aethonan.pro, 1 +aethopy.ga, 1 +aevar.io, 1 +aevpn.org, 1 +aextron.com, 1 +aextron.de, 1 +aextron.org, 1 +af.link, 1 +afadvantage.gov, 1 +afanasev.tk, 1 +afas-apps.nl, 1 +afavre.io, 1 +afbrlf.com, 1 +afbrtn.com, 1 +afbrtnjobs.com, 1 +afbrtv.com, 1 +afbrunswick.com, 1 +afbryt.com, 1 +afbtoto.com, 1 +afc-capital.mx, 1 +afcmrs.org, 1 +afcmrsfeedback.org, 1 +afcmrstest.org, 1 +afdah.se, 1 +affaire.com, 1 +affairefacile.net, 1 +affairemateriaux.fr, 1 +affarsnatverk.nu, 1 +affcoupon.com, 1 +affektblog.de, 1 +affilia.tk, 1 +affiliateprogram.ga, 1 +affiliatetest.azurewebsites.net, 1 +affilowinners.com, 1 +affily.io, 1 +affinity.co, 1 +affinity.vc, 1 +affissioni.roma.it, 1 +affittacamere.roma.it, 1 +affittialmare.it, 1 +affittibreviliguria.it, 1 +affittisalento.it, 1 +afflictedquarter.tk, 1 +affordableazdivorce.com, 1 +affordablecameras.tk, 1 +affordableelectronics.tk, 1 +affordableenvironmental.net, 1 +affordablehealthquotesforyou.com, 1 +affordableinsurancenow.com, 1 +affordablemudjacking.com, 1 +affordablepapers.com, 1 +affordableracingparts.com.au, 1 +affpass.com, 1 +affping.com, 1 +affproduct.com, 1 +affsquare.com, 1 +affumico.it, 1 +affvps.net, 1 +afg-team.tk, 1 +afganistan.cf, 1 +afghan.dating, 1 +afghan.gq, 1 +afghandonia.tk, 1 +afgn.com.ua, 1 +afgphotographers.com, 1 +afgraphic.tk, 1 +afi-business-consulting.com, 1 +afiador.com.br, 1 +aficards.com, 1 +aficionados.com.br, 1 +afiliadosganadores.com, 1 +afilio.de, 1 +afinadoronline.com.br, 1 +afinaudio.com, 1 +afishablogs.tk, 1 +afive.us, 1 +aflam-online.tk, 1 +aflamtorrent.com, 0 +aflattr.com, 1 +aflebedevo.tk, 1 +afoch.cl, 1 +afonso.io, 1 +aforism.tk, 1 +afp548.com, 1 +afrakib.com, 1 +afree.ir, 1 +afri.cc, 1 +africa.dating, 1 +africaindemander.tk, 1 +africalebanon.tk, 1 +africanchildrenschoir.com, 1 +africanewstest0.ml, 1 +africangreyparrotscare.com, 1 +africanhosting.ml, 1 +africankitchen.gallery, 1 +africanmangoforum.ga, 1 +africansafaris.co.nz, 1 +africantourer.com, 1 +africaone-publishing.com, 1 +africaricecenter.org, 1 +afrikmag.com, 1 +afrique.buzz, 1 +afrodigital.uk, 1 +afrodisiac.tk, 1 +afrodita.tk, 1 +afroditafirm.tk, 1 +afrohub.se, 1 +afroto.com, 1 +afslankspecialist.nl, 1 +aftab-alam.de, 0 +after-whoru.tk, 1 +after.digital, 1 +afterblokrock.tk, 1 +afterdwi.info, 1 +afterfostercare.tk, 1 +afterhate.fr, 1 +afterhaven.com, 1 +afternoonhereyes.tk, 1 +afterpay.com, 1 +afterschoolprogramsoflancaster.org, 1 +afterskool.eu, 1 +afterstack.net, 1 +afto-chor.de, 1 +aftodioikisi.gr, 1 +afva.net, 1 +afwd.international, 1 +afxsoft.ml, 1 +ag-33.net, 1 +ag-55.net, 1 +ag-777.com, 1 +ag000.com, 1 +ag01.la, 1 +ag018.cc, 1 +ag06.la, 1 +ag066.vip, 1 +ag08.la, 1 +ag09.la, 1 +ag11.net, 1 +ag123.la, 1 +ag138.com, 1 +ag13842.com, 1 +ag1386.com, 1 +ag158.cc, 1 +ag1601.com, 1 +ag1603.com, 1 +ag1604.com, 1 +ag1607.com, 1 +ag166.com, 1 +ag173168.com, 1 +ag2.app, 1 +ag2017.cc, 1 +ag288.vip, 1 +ag2911.com, 1 +ag2983.com, 1 +ag3.la, 1 +ag3115.com, 1 +ag3232g.com, 1 +ag33.la, 1 +ag388.vip, 1 +ag3916.com, 1 +ag3917.com, 1 +ag393.com, 1 +ag3953.com, 1 +ag4.app, 1 +ag5152.com, 1 +ag5159.com, 1 +ag518518.net, 1 +ag5326.com, 1 +ag5358.com, 1 +ag5392.com, 1 +ag5519.com, 1 +ag556.com, 1 +ag5623.com, 1 +ag5657.com, 1 +ag5662.com, 1 +ag5758.com, 1 +ag5761.com, 1 +ag5852.com, 1 +ag5856.com, 1 +ag5862.com, 1 +ag5876.com, 1 +ag58ks.com, 1 +ag5917.com, 1 +ag5933.com, 1 +ag5936.com, 1 +ag5939.com, 1 +ag5951.com, 1 +ag5952.com, 1 +ag5967.com, 1 +ag6.im, 1 +ag6.pub, 1 +ag6.us, 1 +ag6.vc, 1 +ag6.vip, 1 +ag600.la, 1 +ag6005.com, 1 +ag6016.com, 1 +ag6037.com, 1 +ag618.la, 1 +ag6215.com, 1 +ag6225.com, 1 +ag6262g.com, 1 +ag6272.com, 1 +ag6283.com, 1 +ag6291.com, 1 +ag6298.com, 1 +ag660.com, 1 +ag66321.com, 1 +ag66567.com, 1 +ag666.vip, 1 +ag66668.com, 1 +ag6819.com, 1 +ag6825.com, 1 +ag686.com, 1 +ag68ks.com, 1 +ag69000.com, 1 +ag7.la, 1 +ag700.com, 1 +ag72.vip, 1 +ag7273.com, 1 +ag77.la, 1 +ag77.win, 1 +ag775.com, 1 +ag77655.com, 1 +ag7811.com, 1 +ag7822.com, 1 +ag8-game.com, 1 +ag8.email, 1 +ag8.im, 1 +ag8.live, 1 +ag8.us, 1 +ag8.vip, 1 +ag806.tv, 1 +ag80808.com, 1 +ag80880.com, 1 +ag81117.com, 1 +ag81122.com, 1 +ag81125.com, 1 +ag81191.com, 1 +ag812.com, 1 +ag812.tv, 1 +ag81211.com, 1 +ag81213.com, 1 +ag81268.com, 1 +ag81275.com, 1 +ag81277.com, 1 +ag81325.com, 1 +ag81362.com, 1 +ag81393.com, 1 +ag81399.com, 1 +ag816.com, 1 +ag81613.com, 1 +ag818.cc, 1 +ag818.net, 1 +ag8181g.com, 1 +ag81826.com, 1 +ag81867.com, 1 +ag81881.com, 1 +ag818818.com, 1 +ag81886.com, 1 +ag819.tv, 1 +ag81912.com, 1 +ag81917.com, 1 +ag82006.com, 1 +ag82007.com, 1 +ag82011.vip, 1 +ag82015.com, 1 +ag82018.cc, 1 +ag82018.com, 1 +ag82022.cc, 1 +ag821.com, 1 +ag82135.com, 1 +ag8218.com, 1 +ag822.com, 1 +ag82225.com, 1 +ag82226.com, 1 +ag82287.com, 1 +ag8400.com, 1 +ag8500.com, 1 +ag860.com, 1 +ag8600.com, 1 +ag865.com, 1 +ag8778.net, 1 +ag88-guide.com, 1 +ag88.com, 1 +ag880.com, 1 +ag880.win, 1 +ag88001.com, 1 +ag88008.com, 1 +ag88028.com, 1 +ag88058.com, 1 +ag88068.com, 1 +ag8808.com, 1 +ag88080.com, 1 +ag88081.com, 1 +ag88086.com, 1 +ag88089.com, 1 +ag88090.com, 1 +ag88094.com, 1 +ag88098.com, 1 +ag88110.com, 1 +ag88158.com, 1 +ag8819-livechat.com, 1 +ag88220.com, 1 +ag8829.com, 1 +ag8850.com, 1 +ag88518.com, 1 +ag8856.com, 1 +ag8859.com, 1 +ag88618.com, 1 +ag8876.com, 1 +ag88777.com, 1 +ag8879.com, 1 +ag88799.com, 1 +ag88801.com, 1 +ag88818.com, 1 +ag888818.com, 1 +ag889.com, 1 +ag8890.com, 1 +ag88905.com, 1 +ag8891.com, 1 +ag88910.com, 1 +ag88988.com, 1 +ag88dc22.com, 1 +ag88ks.com, 1 +ag89000.com, 1 +ag891.com, 1 +ag898.cc, 1 +ag899.com, 1 +ag89951.com, 1 +ag8vip.com, 1 +ag9.im, 1 +ag9.vip, 1 +ag905.com, 1 +ag908.com, 1 +ag9100.com, 1 +ag918.cc, 1 +ag918.co, 1 +ag918.top, 1 +ag92018.com, 1 +ag9532.com, 1 +ag96.win, 1 +ag961.com, 1 +ag9623.com, 1 +ag9792.com, 1 +ag9793.com, 1 +ag98.tv, 1 +ag9800.com, 1 +ag9815.com, 1 +ag983.com, 1 +ag98ks.com, 1 +ag992.com, 1 +ag995.com, 1 +ag9999.co, 1 +ag9ks.com, 1 +ag9vip.com, 1 +aga-eiken.tk, 1 +agaclinicaltrials.com, 1 +agagent.vip, 1 +agalloch.tk, 1 +agambarta.com, 0 +agambition.eu, 1 +agamsecurity.ch, 0 +agape24-7.com, 1 +agapelove.tk, 1 +agar.kr, 1 +agargiulo.com, 1 +agari-mj.com, 1 +agarioforum.ga, 1 +agasaya.com, 1 +agasport.nl, 1 +agatajanik.de, 1 +agate.pw, 1 +agateh.com.au, 1 +agaveandpine.com, 1 +agcpapp.com, 1 +agdalieso.com.ba, 1 +agds.pw, 1 +age-encryption.org, 1 +ageasagentessummit.pt, 1 +agechecker.net, 1 +agedgamer.com, 1 +agefriendlyri.org, 1 +agehotel.com, 1 +agelesscitizen.com, 1 +agelesscitizens.com, 1 +agellonia.com, 1 +agemfis.com, 1 +agence-initiale.fr, 1 +agence-sightcom.com, 1 +agence-wazacom.fr, 1 +agences-cegee.fr, 1 +agencesaintpierre.fr, 1 +agencetourismemali.ml, 1 +agencia.barcelona, 1 +agencia.cat, 1 +agencia.pro, 1 +agenciacorujadesign.com.br, 1 +agenciadeempregosdourados.com.br, 1 +agenciadigitalbolivia.com, 1 +agenciaempleo.tk, 1 +agenciafiscal.pe, 1 +agenciaingenium.cl, 1 +agenciarubik.com, 1 +agencxy.ga, 1 +agencyalacarte.com, 1 +agencybeam.com, 1 +agencyinmotion.com, 1 +agencymanager.be, 1 +agenda-loto.net, 0 +agenda21senden.de, 1 +agendadelvolo.info, 1 +agendas.tk, 1 +agendaspectacles.fr, 1 +agent-007.tk, 1 +agent-grow.com, 1 +agent-ubezpieczeniowy.com.pl, 1 +agent47.tk, 1 +agentedebienes.com, 1 +agenteit.com, 1 +agentfirewall.com, 1 +agentpoint.website, 1 +agentprocessing.com, 1 +agentrisk.com, 0 +agentum.ga, 1 +agentur-circumplex.de, 1 +agentur-pottkinder.de, 1 +agentz.ga, 1 +agenux.org, 1 +agenziaimmobiliarezeta.it, 1 +agenziapubblicitaria.milano.it, 1 +agenziapubblicitaria.roma.it, 1 +agespisa.com.br, 1 +agfmedia.com, 1 +agg097.com, 1 +agg66.com, 1 +agg77.com, 1 +agg88.com, 1 +aggielandtutoring.com, 1 +agglo-sion.ch, 1 +aggression.tk, 1 +aggressivecarwraps.com, 1 +agh6p.com, 1 +aghayeva-edler.de, 1 +aghospital.on.ca, 1 +agiacleaning.co.za, 1 +agiairini.cz, 1 +agibank.com.br, 1 +agic-geneve.ch, 1 +agilealliance.org, 1 +agilebits.com, 1 +agilebits.net, 0 +agilecraft.com, 1 +agilecyber.com, 1 +agilee.io, 1 +agileui.com, 1 +agiley.se, 1 +agilicus.ca, 1 +agilicus.com, 1 +agility-westvlaanderen.tk, 1 +aging.gov, 1 +agingstats.gov, 1 +agingstop.net, 1 +aginion.net, 1 +agiosthomas.tk, 1 +agiserv.fr, 1 +agitmedia.ru, 1 +agk.co.com, 1 +agks02.com, 1 +agks1.com, 1 +agks11.com, 1 +agks116.com, 1 +agks13.com, 1 +agks131.com, 1 +agks136.com, 1 +agks138.com, 1 +agks158.com, 1 +agks16.com, 1 +agks168.com, 1 +agks18.com, 1 +agks188.com, 1 +agks19.com, 1 +agks21.com, 1 +agks23.com, 1 +agks27.com, 1 +agks3.com, 1 +agks35.com, 1 +agks38.com, 1 +agks4.com, 1 +agks45.com, 1 +agks53.com, 1 +agks57.com, 1 +agks59.com, 1 +agks60.com, 1 +agks63.com, 1 +agks67.com, 1 +agks68.com, 1 +agks69.com, 1 +agks7.com, 1 +agks70.com, 1 +agks71.com, 1 +agks72.com, 1 +agks75.com, 1 +agks78.com, 1 +agks79.com, 1 +agks8.com, 1 +agks82.com, 1 +agks83.com, 1 +agks85.com, 1 +agks86.com, 1 +agks87.com, 1 +agks88.com, 1 +agks888.com, 1 +agks89.com, 1 +agks9.com, 1 +agks90.com, 1 +agks92.com, 1 +agks96.com, 1 +agktest1.ga, 1 +aglc8.com, 1 +agleventis.com, 1 +aglh.com, 1 +aglilai001.com, 1 +aglow.nl, 1 +aglucky.com, 1 +agm4545.com, 1 +agnesk.blog, 1 +agnesmatilda.tk, 1 +agnestakeaway.be, 1 +agneta.tk, 1 +agnosia.tk, 1 +agnosticism.tk, 1 +agonpro.ch, 1 +agonswim.com, 1 +agonworks.com, 1 +agora-soft.cf, 1 +agora.ru, 1 +agoradanza.tk, 1 +agoradesk.com, 1 +agoravox.fr, 1 +agoravox.it, 1 +agoravox.tv, 1 +agotnes.com, 1 +agouraelectrical.com, 1 +agouraelectrician.com, 1 +agouraexteriorlighting.com, 1 +agourahillselectric.com, 1 +agourahillselectrical.com, 1 +agourahillselectrician.com, 1 +agourahillsexteriorlighting.com, 1 +agourahillslandscapelighting.com, 1 +agourahillslighting.com, 1 +agourahillsoutdoorlighting.com, 1 +agouralandscapelighting.com, 1 +agouralighting.com, 1 +agouraoutdoorlighting.com, 1 +agowa338.de, 1 +agpideas.com, 1 +agpnepal.com, 1 +agproducts.co.uk, 1 +agpsn.com, 1 +agptco.com, 1 +agr.asia, 1 +agralines.tk, 1 +agrargruppe.tk, 1 +agregator.tk, 1 +agrekov.ru, 1 +agremo.com, 0 +agreor.com, 1 +agri-meet.com, 1 +agrichamber.com.ua, 1 +agricult.tk, 1 +agricultural-technology.tk, 1 +agriculture-schools.com, 1 +agrikulturchic.com, 1 +agripartner.fr, 1 +agrippa.tk, 1 +agriprofocus.com, 1 +agrish.tk, 1 +agrisicilia.it, 1 +agro-dom.solutions, 1 +agro-ferma.tk, 1 +agro-forestry.net, 1 +agrocare.tk, 1 +agroclefic.com, 1 +agroclimat.tk, 1 +agroconsultoraplus.com, 1 +agrodoki.hu, 1 +agrodronechile.cl, 1 +agroexp.com.ua, 0 +agrofetch.co.ke, 1 +agrokredit.ga, 1 +agrolab.dk, 1 +agrolife.tk, 1 +agromotorsburzaco.com, 1 +agron.tk, 1 +agronomi.tk, 1 +agronomict.tk, 1 +agropark.tk, 1 +agroplas.cf, 1 +agropool.tk, 1 +agropotter.com.ua, 1 +agrospan.ga, 1 +agroteam.tk, 1 +agrotek.lt, 1 +agrotender.com.ua, 1 +agroxxi.ru, 0 +agroyard.com.ua, 1 +agrus-wow.tk, 1 +agscapeslandscaping.com, 1 +agscinemas.com, 1 +agscinemasapp.com, 1 +agslot.com, 1 +agslot777.com, 1 +agsogou.com, 1 +agsun6.com, 1 +aguantepimpinero.tk, 1 +aguarani.com.br, 1 +aguaviva.tk, 1 +aguiascarecas.org, 1 +aguidetolovelossanddesperation.com, 1 +aguilarsoluciones.com, 1 +agujetas.tk, 1 +agung-furniture.com, 1 +agustin.cf, 1 +agustinperalt.es, 0 +agviet88.com, 1 +agvip1000.com, 1 +agvip168.com, 1 +agvip1888.com, 1 +agvip2001.com, 1 +agvip2008.com, 1 +agvip2013.com, 1 +agvip88.com, 1 +agvip8800.com, 1 +agvip986.com, 1 +agwa.name, 1 +agweili.com, 0 +agwin1.com, 1 +agwin2.com, 1 +agwin7.com, 1 +agwin777.com, 1 +agwin8.com, 1 +agwin9.com, 1 +agworkers.com, 1 +agy.cl, 1 +agzlapp.com, 1 +ahawkesrealtors.com, 1 +ahbap.org, 1 +ahc.fyi, 1 +ahccorleone.tk, 1 +ahcpr.gov, 1 +ahd.com, 0 +ahegao.ca, 1 +ahelos.tk, 1 +ahenkerp.com, 1 +ahero4all.org, 1 +ahhcomfortshoes.com, 1 +ahidta.gov, 1 +ahj.no, 1 +ahl.gov.au, 1 +ahlac.tk, 1 +ahlaejaba.com, 1 +ahliqqpoker.online, 1 +ahlz.sk, 1 +ahmad.works, 1 +ahmed-alasadi.tk, 1 +ahmedabadflowermall.com, 1 +ahmedcharles.com, 1 +ahmerjamilkhan.org, 1 +ahmetakgul.com.tr, 1 +ahmetozer.org, 1 +ahmud.net, 1 +ahoj.hu, 1 +ahollamby.com, 1 +ahornblatt.org, 1 +ahosi.com, 1 +ahoy.travel, 1 +ahrq.gov, 1 +ahsinsaleem.tk, 1 +ahstrem.com, 1 +ahstremweb.com, 1 +ahsyg.com, 1 +ahtuxpk.ru, 1 +ahughes03.com, 1 +ahvassociates.com, 1 +ahwah.net, 1 +ahxxm.com, 0 +ai-english.jp, 1 +ai-practitioners.com, 1 +ai-soft.co.jp, 1 +ai.design, 0 +ai.gov, 1 +ai.ls, 1 +ai.mr, 1 +ai00.vip, 1 +ai1989.com, 1 +ai2-jp.com, 1 +aiasesoriainmobiliaria.com, 1 +aiat.net, 1 +aibaoyou.com, 1 +aibenzi.com, 1 +aibiying.com, 1 +aibolit-apteka.tk, 1 +aibolit.ga, 1 +aibolit.ml, 1 +aibolitik.tk, 1 +aibsoftware.mx, 1 +aicamilwaukee.com, 1 +aicevote.com, 1 +aicfb.in, 1 +aicial.co.uk, 1 +aicv.club, 1 +aid-web.ch, 1 +aidablanco.tk, 1 +aidaccess.org, 1 +aidanamavi.com, 1 +aidanapple.com, 1 +aidanmitchell.co.uk, 1 +aidanmitchell.uk, 1 +aidanmontare.net, 1 +aidanpr.com, 1 +aidanpr.net, 1 +aidarikako.com, 1 +aide-valais.ch, 1 +aiden.cool, 0 +aiden.link, 0 +aidenlx.top, 1 +aidez-moi.ca, 1 +aidhan.net, 1 +aidi-ahmi.com, 1 +aidmycomputer.com, 1 +aidoru.net, 1 +aids.gov, 1 +aie.de, 1 +aiesecarad.ro, 1 +aievaluare.ro, 1 +aiforsocialmedia.com, 1 +aifriccampbell.com, 1 +aifx.ml, 1 +aigcev.org, 1 +aigenpul.se, 1 +aigner-club.com, 1 +aigner-club.de, 1 +aignerimage.de, 1 +aignermunich.com, 1 +aignermunich.de, 1 +aignermunich.jp, 1 +aigua.it, 1 +aihschgo.org, 1 +aihub.codes, 1 +aiinsurance.io, 1 +aiinsurance.xyz, 1 +aiken.golf, 1 +aikenorganics.com, 1 +aikenpromotions.com, 1 +aiki.de, 1 +aiki.do, 1 +aiki.tk, 0 +aikido-club-limburg.de, 1 +aikido-kiel.de, 1 +aikido-linz.at, 1 +aikido-wels.at, 1 +aikidoaalst.tk, 1 +aikidoboskovice.cz, 1 +ailamarket.ir, 0 +ailitonia.com, 1 +ailitonia.xyz, 1 +aim-port.com, 1 +aim.org.pt, 1 +aimanance.com, 1 +aimare-web.tk, 1 +aimax.com, 1 +aimd.tech, 1 +aimdigital.tk, 1 +aimeeandalec.com, 1 +aimgroup.co.tz, 1 +aimi-salon.com, 1 +aimless.tk, 1 +aimlessempire.tk, 1 +aimmail.info, 1 +aimotive.com, 1 +aimrom.org, 1 +ainamoroms.com, 1 +ainfographie.com, 1 +aini99.club, 1 +ainutrition.co.uk, 1 +ainvest.de, 1 +ainzu.net, 1 +aioboot.com, 1 +aiois.com, 1 +aip.ai, 1 +aipbarcelona.com, 1 +aiphyron.com, 1 +aipi.de, 1 +aipi.tel, 1 +aiplabs.ai, 1 +aiplabs.io, 1 +aipor.pt, 0 +aiprecipecollection.com, 1 +air-business.tk, 1 +air-craftglass.com, 1 +air-flot.tk, 1 +air-planning.co.jp, 1 +air-rishon.tk, 1 +air-shots.ch, 0 +air-techniques.fr, 1 +air-we-go.co.uk, 1 +airalamo.com, 1 +airbender.tk, 1 +airbnb.ae, 1 +airbnb.at, 1 +airbnb.be, 1 +airbnb.biz, 1 +airbnb.ca, 1 +airbnb.cat, 1 +airbnb.ch, 1 +airbnb.cl, 1 +airbnb.cn, 1 +airbnb.co.cr, 1 +airbnb.co.id, 1 +airbnb.co.il, 1 +airbnb.co.in, 1 +airbnb.co.kr, 1 +airbnb.co.nz, 1 +airbnb.co.uk, 1 +airbnb.co.ve, 1 +airbnb.com, 1 +airbnb.com.ar, 1 +airbnb.com.au, 1 +airbnb.com.bo, 1 +airbnb.com.br, 1 +airbnb.com.bz, 1 +airbnb.com.cn, 1 +airbnb.com.co, 1 +airbnb.com.ec, 1 +airbnb.com.gt, 1 +airbnb.com.hk, 1 +airbnb.com.hn, 1 +airbnb.com.hr, 1 +airbnb.com.kh, 1 +airbnb.com.mt, 1 +airbnb.com.my, 1 +airbnb.com.ni, 1 +airbnb.com.pa, 1 +airbnb.com.pe, 1 +airbnb.com.ph, 1 +airbnb.com.py, 1 +airbnb.com.sg, 1 +airbnb.com.sv, 1 +airbnb.com.tr, 1 +airbnb.com.tw, 1 +airbnb.com.ua, 1 +airbnb.com.vn, 1 +airbnb.cz, 1 +airbnb.de, 1 +airbnb.dk, 1 +airbnb.es, 1 +airbnb.fi, 1 +airbnb.fr, 1 +airbnb.gr, 1 +airbnb.gy, 1 +airbnb.hu, 1 +airbnb.ie, 1 +airbnb.is, 1 +airbnb.it, 1 +airbnb.jp, 1 +airbnb.la, 1 +airbnb.lu, 1 +airbnb.mx, 1 +airbnb.nl, 1 +airbnb.no, 1 +airbnb.pl, 1 +airbnb.pt, 1 +airbnb.ru, 1 +airbnb.se, 1 +airbnb.tools, 1 +airbnbchina.cn, 1 +airbnbcupom.com, 1 +airborne-clan.tk, 1 +airborne-inflatables.co.uk, 1 +airbossofamerica.com, 1 +aircheapfare.com, 1 +aircheapfares.com, 1 +aircomet.tk, 1 +airconditioning.tk, 1 +airconrandburg.co.za, 1 +airconsalberton.co.za, 1 +airconsandton.co.za, 1 +airconsboksburg.co.za, 1 +airconsmidrand.co.za, 1 +airconsrandburg.co.za, 1 +airconssandton.co.za, 1 +aircraftnoisemodel.org, 1 +airday.tk, 1 +airdropkings.com, 1 +airductcleaninggrandprairie.com, 1 +airductcleaningirving.com, 1 +airdur.eu, 1 +aireaseleaks.org, 1 +airedaleterrier.com.br, 1 +airethilien.tk, 1 +airetvie.com, 1 +aireuropeflights.com, 1 +airfan.cf, 1 +airfareandcheap.com, 1 +airfarecheapdeal.com, 1 +airfarecheapeurope.com, 1 +airfarecompareprices.com, 1 +airfaredealstoindia.com, 1 +airfarefrom.com, 1 +airfarehonolulu.com, 1 +airfarehoteldeals.com, 1 +airfareinindia.com, 1 +airfaremexicocity.com, 1 +airfareorlando.com, 1 +airfaresdomestic.com, 1 +airfareseconomy.com, 1 +airfaresfrom.com, 1 +airfareshotels.com, 1 +airfield.gq, 1 +airfocused.com, 1 +airfoto.tk, 1 +airhart.me, 1 +airhelp.com, 1 +airhorn.de, 1 +airi-tabei.com, 1 +airi.ga, 1 +airicy.com, 1 +airikai.com, 1 +airit.de, 1 +airjet.cf, 1 +airjordanpascher.tk, 1 +airkiss.ga, 1 +airlibre-parachutisme.com, 1 +airline-rabota.tk, 1 +airlinefarescompare.com, 1 +airlinenews.tk, 1 +airlinesettlement.com, 1 +airloge.com, 1 +airmag.tk, 1 +airmail.cc, 0 +airman.cf, 1 +airmash.online, 0 +airmaxinflatables.com, 1 +airnode.ga, 1 +airnow.gov, 1 +airpark-roissy.fr, 1 +airpbx.com, 1 +airplanet.tk, 1 +airplay-inflatable-hire.co.uk, 1 +airplayradio.nl, 1 +airport-car-rental.tk, 1 +airport-charlotte.com, 1 +airportal.cn, 1 +airportstuttgart.com, 1 +airpost.pw, 1 +airpurifierproductsonline.com, 1 +airrestoration.ch, 1 +airseatac.net, 1 +airship.com, 1 +airskystore.com, 1 +airslate.com, 1 +airsnore.com, 1 +airsoft.ch, 1 +airsoftpinoso.tk, 1 +airstrike.tk, 1 +airswap.io, 1 +airtable.com, 1 +airtec-france.fr, 1 +airtel.com.ng, 1 +airtimerewards.co.uk, 0 +airtoolaccessoryo.com, 1 +airtrain.gq, 1 +airtrolinc.com, 1 +airventilation.ca, 1 +airvpn.org, 1 +airvuz.com, 1 +airwaystorage.net, 1 +airwolf.tk, 1 +airwolfthemes.com, 1 +airwrenchei.com, 1 +airy.host, 0 +airzone.tk, 1 +ais.fashion, 1 +aisanity.com, 1 +aisedomains.ga, 1 +aisi316l.net, 1 +aissel.com, 1 +aisteru.ch, 1 +aisthesthai.tk, 1 +aistockcharts.com, 1 +aistrope.com, 1 +ait.com.ar, 1 +aiticon.com, 1 +aitosoftware.com, 1 +aitrading.uk, 1 +aitrust.ro, 1 +aiui10.cn, 1 +aiutodomestico.ch, 0 +aiva.ai, 1 +aivan.ai, 1 +aivd.lol, 1 +aiwosq.cn, 1 +aixamfinancialservices.nl, 1 +aja.de, 1 +ajarope.com, 1 +ajaxed.net, 1 +ajaxforever.tk, 1 +ajaxtime.tk, 1 +ajces.com, 1 +ajel.sa, 1 +ajetaci.cz, 1 +ajeventhire.co.uk, 1 +ajfite.com, 0 +ajforum.tk, 1 +ajhstamps.co.uk, 1 +ajiboye.com, 1 +ajitp.com, 1 +ajl.io, 1 +ajman-realty.ga, 1 +ajmara.pl, 1 +ajnah.net, 1 +ajnasz.hu, 1 +ajramos.tk, 1 +ajsb85.com, 1 +ajt.io, 1 +ajtatum.com, 1 +ajvco.com.hk, 1 +ajvocab.com, 1 +ajwebsolutions.com, 0 +ak-design.tk, 1 +ak-online.tk, 1 +ak-varazdin.hr, 1 +ak47-miyamoto.spdns.org, 1 +ak96.tk, 1 +aka.ms, 1 +akaal.pw, 1 +akachanikuji.com, 1 +akachanwebsite.tk, 1 +akademiaantykorupcyjna.pl, 1 +akademiawawer.pl, 1 +akademie-frankfurt.de, 1 +akagiauto.net, 1 +akalashnikov.ru, 1 +akalpremkaur.de, 1 +akamon.ac.jp, 1 +akaoma.com, 1 +akapumkin.com, 1 +akasha.world, 1 +akashdsouza.now.sh, 1 +akawuifan.com, 1 +akay.me, 1 +akbam.co.uk, 1 +akbarsempoi.tk, 1 +akbas.tk, 1 +akbtv.ru, 1 +akdenizim.tk, 1 +akdigitalegesellschaft.de, 0 +akepayu.com, 1 +akerboom.family, 1 +akerboom.me, 1 +akerboom.org, 1 +aketzasantacoloma.tk, 1 +akf-plastics.com, 1 +akfoundationindia.com, 1 +akhabar.tk, 1 +akhealthconnection.com, 0 +akhepcat.com, 1 +akhilindurti.com, 0 +akhomesforyou.com, 1 +akiba-server.info, 1 +akiba-souken.com, 1 +akiekintveld.com, 1 +akihito.com, 1 +akijo.de, 1 +akilli-devre.com, 1 +akinavn.vn, 1 +akinix.com, 1 +akinlau.com, 1 +akinokae.de, 1 +akiranet.tk, 1 +akita-boutique.com, 1 +akita-stream.com, 1 +akitoy.mx, 1 +akiym.com, 1 +akj.io, 1 +akkbouncycastles.co.uk, 1 +akkordy-skachat.ga, 1 +aklagare.se, 1 +akmatrix.org, 1 +aknastore.co, 1 +akoch.net, 1 +akoofs.com, 1 +akostecki.de, 1 +akouryy.net, 1 +akoww.de, 0 +akoya.com, 1 +akoya.fi, 1 +akp.photos, 1 +akplates.org, 1 +akpwebdesign.com, 1 +akr.io, 1 +akr.services, 1 +akracing.se, 0 +akrep.com, 1 +akrilikhavuz.com, 1 +akritikos.info, 1 +akrobat.cf, 1 +akropolis-ravensburg.de, 1 +aksaramedia.com, 1 +aksehir.bel.tr, 1 +aksenov.tk, 1 +aksenovalexey.tk, 1 +aksert.com, 1 +akses.co, 1 +akshay.in.eu.org, 1 +akshi.in, 1 +akshit.me, 1 +aksot.com, 1 +akssma.com, 1 +akszita.com, 1 +aktarma.fr, 1 +aktfotozas.eu, 1 +aktin.cz, 1 +aktin.sk, 1 +aktion-vielfalt.ch, 1 +aktiv-naturheilmittel.at, 1 +aktiv-naturheilmittel.ch, 1 +aktiv-naturheilmittel.de, 1 +aktivace.eu, 1 +aktive-arbeitslose.at, 1 +aktivierungscenter.de, 1 +aktivitetatil.com, 1 +aktivterapi.dk, 1 +aktuelleprospekte.at, 1 +aktuellsakerhet.se, 1 +akubadaura.org, 1 +akuislam.com, 1 +akukas.com, 0 +akul.co.in, 1 +akumat.com.pl, 1 +akumat.eu, 1 +akumat.pl, 1 +akuntansilengkap.com, 1 +akupunktur-akupunktoer.dk, 1 +akupunktura.tk, 1 +akura.cf, 1 +akuseorangtraveler.com, 1 +akuston.eu, 1 +akutun.cl, 1 +akvaristika.cf, 1 +akvilon.tk, 1 +akvorrat.at, 1 +al-capone.ga, 1 +al-capone.tk, 1 +al-f.net, 1 +al3xpro.com, 1 +alab.space, 1 +alabalaporto.tk, 1 +alabamaag.gov, 1 +alabamacoastalradiology.com, 1 +alabamadebtrelief.org, 1 +alabn.com, 1 +alaboard.com, 1 +alabordage.fr, 1 +alabuena.com, 1 +alacriti.com, 1 +alacritylaw.com, 1 +aladdin.ie, 1 +aladdinschools.appspot.com, 1 +aladintechnologies.tk, 1 +alainbaechlerphotography.ch, 0 +alainfrancois.eu, 1 +alainfrancois.nl, 0 +alainmargot.ch, 0 +alainodea.com, 1 +alainwolf.ch, 1 +alainwolf.net, 1 +alair.cn, 0 +alalivre.cf, 1 +alamad.cf, 1 +alamalsahara.co, 1 +alamanceconstruction.com, 1 +alamani.tk, 1 +alamitosbaytraders.com, 1 +alamo-analytics.com, 1 +alamowellnessalliance.com, 1 +alana.com.ua, 1 +alanberger.me.uk, 1 +alanbleiweiss.com, 1 +alancabrera.com, 1 +alandoyle.com, 1 +alanhua.ng, 1 +alanhuang.name, 1 +alanina.com, 1 +alaninkenya.org, 1 +alaniz-law.com, 1 +alankardresswalla.tk, 1 +alanonsantabarbara.info, 1 +alansilson.tk, 1 +alantica.ga, 1 +alapetite.fr, 1 +alarbnet.tk, 1 +alarelleimpresiones.com, 1 +alargarlavida.com, 1 +alaricfavier.eu, 0 +alarko-carrier.com.tr, 1 +alarmat.pl, 1 +alarmcast.ca, 1 +alarmcomplete.co.uk, 1 +alarna.de, 1 +alas-negras.tk, 1 +alasdelalma.com.co, 1 +alaskabuylocal.org, 1 +alaskacruises.com, 1 +alaskafishinglodges.net, 1 +alaskajewelry.com, 1 +alasta.info, 1 +alastairs-place.net, 1 +alatkesehatan.tk, 1 +alaturkaonline.com, 1 +alaundeil.xyz, 1 +alaunus.com, 1 +alb-flirt.de, 1 +albagold.tk, 1 +albagora.nl, 1 +albakham.eu.org, 1 +albakos.tk, 1 +albaladejodelcuende.tk, 1 +albalatedelarzobispo.tk, 1 +albalew.is, 1 +albalinks.tk, 1 +albamusic.tk, 1 +albanesi.it, 1 +albaniachat.tk, 1 +albaniaonline.tk, 1 +albanildedios.tk, 1 +albanyca.gov, 1 +albanycountydems.com, 1 +albarius.ga, 1 +albarugby.tk, 1 +albatrosboat.it, 1 +albayan.ae, 1 +albbounce.co.uk, 1 +albendazole.ga, 1 +albendazole.ml, 1 +albergolafiorita.com, 1 +albersdruck.de, 1 +albertathome.org, 1 +albertcuyp-markt.amsterdam, 1 +alberteinsteinbiography.tk, 1 +albertforfuture.de, 1 +albertgibb.tk, 1 +albertify.xyz, 1 +albertohurtado.fyi, 1 +albertovr.com, 1 +alberts-blatt.de, 1 +albhof-wasserfall.de, 1 +albilaga.id, 1 +albinma.com, 1 +albinvega.tk, 1 +albion2.org, 1 +albionfaeries.org.uk, 1 +albourne.com, 1 +alboweb.nl, 1 +albrocar.com, 1 +albstaedter-kids-cup.de, 1 +albuic.tk, 1 +albuterol.ga, 1 +albuterolonline.ga, 1 +albwith.ru, 1 +alca31.com, 0 +alcaldia.info, 1 +alcamilo.cloudns.cc, 1 +alcantara.cf, 1 +alcapalis.tk, 1 +alcar.tk, 1 +alcaralifusi.tk, 1 +alcasan.de, 1 +alcatelonetouch.us, 1 +alchakov.tk, 1 +alchemisten.tk, 1 +alchemiya.ru, 1 +alchemy-media-marketing.com, 1 +alchemy.gr, 1 +alchemyvfx.com, 1 +alchimic.ch, 0 +alcionesakugawa.com, 1 +alcites.com, 1 +alcnutrition.com, 1 +alcobendas.tk, 1 +alcoholapi.com, 1 +alcoholia.tk, 1 +alcoholicbeverages.tk, 1 +alcoholismtreatment.tk, 1 +alcoleadetajo.tk, 1 +alcolecapital.com, 1 +alcouponest.com, 1 +alcove.cf, 1 +alcubillas.tk, 1 +aldeal.gq, 1 +aldealices.tk, 1 +aldersgate.cf, 1 +aldersgate.ga, 1 +aldersgate.gq, 1 +aldersgate.ml, 1 +aldersgate.tk, 1 +aldersgateumc.cf, 1 +aldersgateumc.ga, 1 +aldersgateumc.gq, 1 +aldersgateumc.ml, 1 +aldersgateumc.tk, 1 +aldiabcs.com, 1 +aldien.com.br, 1 +aldipresscentre.co.uk, 1 +aldiwan-mobile.com, 1 +aldo-saputra.ga, 1 +aldomedia.com, 1 +aldorr.net, 0 +aldous-huxley.com, 1 +aldridge-ringers.tk, 1 +aldyputra.net, 1 +alea.xyz, 1 +aleax.me, 1 +alecel.de, 1 +alecpap.com, 1 +alecpapierniak.com, 1 +alecrimacessorios.com.br, 1 +alecrust.com, 1 +aleftinka.tk, 1 +alegromania.tk, 1 +alejandrophones.com.mx, 1 +alek.in, 1 +aleks.com, 1 +aleksandar-vukmirovic.tk, 1 +aleksanders.tk, 1 +alekseevski.tk, 1 +aleksejjocic.tk, 1 +aleksib.fi, 1 +alela.fr, 1 +alemangranada.tk, 1 +alenaserezhina.cf, 1 +alenbadel.com, 1 +alendronate.gq, 1 +alentadoras.com, 1 +alenwich.com, 1 +aleph.land, 1 +alerbon.net, 1 +alertboxx.com, 1 +alertonline.nl, 1 +alerts.sg, 1 +alertwire.com, 1 +alesha.tk, 1 +aless.io, 1 +alessandrobasi.it, 1 +alessandroonline.com.br, 1 +alessandrotravel.com, 1 +alessandroz.ddns.net, 1 +aletm.it, 1 +alevi.tk, 1 +alex-n.net, 1 +alex-ross.co.uk, 1 +alex-weigle.shop, 1 +alex97000.de, 1 +alexalist.tk, 1 +alexandbonnie.com, 1 +alexander-beck.eu, 1 +alexander-cameron.com, 1 +alexander-van-nieuwenhoven.tk, 1 +alexanderb.info, 1 +alexanderg.tk, 1 +alexanderjshapiro.com, 1 +alexanderkhen.tk, 1 +alexanderlau.ga, 1 +alexanderneng.de, 1 +alexandernorth.ch, 1 +alexanderpiatigorsky.tk, 1 +alexanderpopov.tk, 1 +alexanderschimpf.de, 1 +alexandertutoring.com, 1 +alexandra-schulze.de, 1 +alexandraandnicolay.com, 1 +alexandraschmidt.coach, 1 +alexandrastrauss.fr, 1 +alexandre-barret.fr, 1 +alexandreguarita.com.br, 1 +alexandremottier.tk, 1 +alexandrevicente.net, 1 +alexandrite.cf, 1 +alexandros.io, 1 +alexbaker.org, 1 +alexberts.ch, 1 +alexbresnahan.com, 1 +alexcoman.com, 1 +alexcpp.tk, 1 +alexdaniel.org, 1 +alexdaulby.com, 1 +alexdesigner.tk, 1 +alexey-shamara.ru, 0 +alexeykamalov.tk, 1 +alexeykopytko.com, 1 +alexeyweb.ru, 1 +alexfabian.myftp.org, 1 +alexgaynor.net, 1 +alexgebhard.com, 1 +alexglover.co.uk, 1 +alexgonzalez-online.tk, 1 +alexgsites.co.il, 1 +alexguti.com, 1 +alexhd.de, 1 +alexio.ml, 1 +alexisabarca.com, 1 +alexisathlani.com, 0 +alexischaussy.xyz, 1 +alexiskoustoulidis.com, 1 +alexismeza.com, 1 +alexismeza.com.mx, 1 +alexismeza.dk, 1 +alexismeza.es, 1 +alexismeza.nl, 1 +alexispoficial.tk, 1 +alexitor.com, 1 +alexjett.com, 1 +alexkushner.com, 1 +alexlambertz.de, 1 +alexlombardo.tk, 1 +alexlouden.com, 1 +alexmainz.com, 1 +alexmerkel.com, 1 +alexmerkel.me, 1 +alexmerkel.xyz, 1 +alexmol.tk, 1 +alexmroberts.net, 1 +alexn.org, 1 +alexpavel.com, 1 +alexpetrik.com, 1 +alexpnixon.com, 1 +alexpotter.net, 1 +alexs.de, 1 +alexsandrasverden.cf, 1 +alexsantos.tk, 1 +alexschroeder.ch, 1 +alexsergeyev.com, 1 +alexsexton.com, 1 +alexstudio.tk, 1 +alextaffe.com, 1 +alexthayne.co.uk, 1 +alextjam.es, 1 +alextsang.net, 1 +alextweewielers.tk, 1 +alexustinoff.cf, 1 +alexvdveen.nl, 1 +alexvetter.de, 0 +alexwardweb.com, 1 +alexweber.tk, 1 +alexyang.me, 1 +aleynamasajsalonu.gq, 1 +alfa-books.ga, 1 +alfa-host.ml, 1 +alfa-music.tk, 1 +alfa-tech.su, 1 +alfaair.aero, 1 +alfabank-info.ru, 1 +alfacharlie.co, 1 +alfadecor.ml, 1 +alfadefiant.tk, 1 +alfadlmedical.com, 1 +alfadlmedical.net, 1 +alfalasteenyia.cf, 1 +alfamask.de, 1 +alfambra.tk, 1 +alfamx.com, 1 +alfaperfumes.com.br, 1 +alfaproweb.fr, 1 +alfarisnet.com, 0 +alfastone.com.ua, 1 +alfavideocirurgica.com.br, 1 +alfavit.cf, 1 +alfawedding.com, 1 +alfiebarker.com, 1 +alfonso-baya.tk, 1 +alforto.nl, 0 +alfransiacademy.com, 0 +alfratehotelcampiglio.it, 1 +alfred-figge.de, 1 +alfredapp.com, 1 +alfredlin015.com, 1 +alfst.com, 1 +alftrain.com, 1 +algarize.com, 1 +algarmatic-automatismos.pt, 1 +algbee.com, 1 +algebra-quiz.com, 1 +algercounty.gov, 1 +algerianportal.tk, 1 +algeriaweb.tk, 1 +algerie-music.tk, 1 +alghadpowersolutions.com, 1 +alghanimcatering.com, 1 +alginformatica.es, 1 +algoarmada.com, 1 +algodoncotton.com, 1 +algoentremanos.com, 1 +algofactory.de, 1 +algolia.com, 1 +algopix.com, 1 +algorista.tk, 1 +algorithmic.ml, 1 +algorithmofsuccess.com, 1 +algoritm.gq, 1 +algoritmus-uspechu.cz, 1 +algoritmususpechu.cz, 1 +algorytm.tk, 1 +algustionesa.com, 1 +alhomaidani.com, 1 +alhost.ml, 1 +alhs-archives.com, 1 +aliamex.com, 1 +alianet.org, 1 +aliantsoft.pl, 1 +aliasinfoforums.tk, 1 +aliaswp.com, 1 +alibabau.tk, 1 +alibip.de, 1 +alicante-spain.tk, 1 +alice-memorial.de, 1 +alice-noutore.com, 1 +alice.tw, 1 +alicebaldenegro.tk, 1 +alicedepret.com, 1 +alicemag.ng, 1 +alicemaywebdesign.com.au, 1 +alicestudio.it, 1 +alicetone.net, 1 +alicialab.org, 1 +aliefirfany.com, 1 +alieke.design, 1 +alienation.biz, 0 +alienflight.com, 1 +alieninvasion.fun, 1 +alienslab.net, 1 +alienstat.com, 1 +aliexfantaisies.com, 1 +alifeadjacent.com, 1 +alighierirescaldina.it, 1 +alignedchiro.org, 1 +alignminds.com, 1 +alignrs.com, 1 +alignthoughts.com, 1 +alihashemrasheed.com, 1 +aliim.gdn, 1 +alikulov.me, 1 +alilialili.ga, 1 +alimak.com, 1 +aliment-covid19.com, 1 +alimentosmcf.com, 1 +alimentsduquebecaumenu.com, 1 +alimenty.tk, 1 +alimeta.it, 1 +alinasmusicstudio.com, 1 +alinbu.net, 1 +alineasatu.com, 1 +alineonline.tk, 1 +alinmaacademy.com, 0 +alinode.com, 1 +alinol.com, 1 +aliorange.com, 1 +alireza2love.tk, 1 +alirezahesari.com, 1 +alis-test.tk, 1 +alishanova.tk, 1 +alisoft.gq, 1 +alisondavenport.ga, 1 +alisondemarco.com, 1 +alisonlitchfield.com, 1 +alisonmcalpine.com, 1 +alisonpaloma.com, 1 +alisstyle.tk, 1 +alistairstowing.com, 1 +alistaku.tk, 1 +alisync.com, 1 +alitec.it, 1 +alitpedia.ga, 1 +aliv.biz, 1 +alivecast.co.jp, 1 +alivelimo.com, 1 +alix-board.de, 1 +alize-theatre.ch, 0 +aliziolaw.com, 1 +aljaspod.ch, 1 +aljaspod.com, 1 +aljaspod.hu, 1 +aljaspod.net, 1 +aljaspod.org, 1 +aljullusims.tk, 1 +aljweb.com, 1 +alkacoin.net, 1 +alkami.com, 1 +alkamitech.com, 1 +alkel.info, 1 +alkemi-si.fr, 1 +alko-centr.ru, 1 +alko-stop.cf, 1 +alko-stop.ml, 1 +alkogol.ga, 1 +alkopedia.tk, 1 +alkor.tk, 1 +alkozeroks-wiki.ru, 1 +alkusin.net, 1 +all-bronza.ru, 1 +all-connect.net, 0 +all-credits.cf, 1 +all-ebooks.gq, 1 +all-fashion-schools.com, 1 +all-for-u.tk, 1 +all-gsm-solutions.tk, 1 +all-markup-news.com, 1 +all-seo.tk, 1 +all-things.tk, 1 +all-top.tk, 1 +all4hardware4u.de, 1 +all4web.tk, 1 +all878.com, 1 +allaboutfunuk.com, 1 +allaboutgreg.net, 1 +allabouthome.ml, 1 +allaboutmadonna.tk, 1 +allaboutreligions.tk, 1 +allaboutswing.co.uk, 1 +allaboutswing.com, 1 +allaboutthekink.org, 1 +allaccessglobal.tech, 1 +allactioneventhire.co.uk, 1 +allamakee.k12.ia.us, 1 +allamericanmuslim.com, 1 +allamericanprotection.net, 1 +allamericatrans.com, 1 +allangirvan.net, 1 +allanta.be, 1 +allarmi.roma.it, 1 +allarticles.tk, 1 +allbenjoy.de, 1 +allbestcbdoil.com, 1 +allbetgame.cn, 1 +allbetgaming.com, 1 +allbetter.com, 1 +allbigdicks.com, 1 +allbookmark.cf, 1 +allbouncesurrey.co.uk, 1 +allbrestby.tk, 1 +allbrestorg.tk, 1 +allbridges.tk, 1 +allbusiness.com, 1 +allcapa.org, 1 +allcarecorrectionalpharmacy.com, 1 +allcarepharmacy.com, 1 +allcarespecialty.pharmacy, 1 +allcelebs.tk, 1 +allcinema.net, 1 +allcleanservices.ca, 1 +allcloud.com, 1 +allcooking.tk, 1 +allcoveredbyac.com, 1 +allcrimea.tk, 1 +alldewall.de, 1 +alldm.ru, 1 +alldogs.tk, 1 +alle-zonvakanties.nl, 1 +alle.bg, 1 +allegorymetal.tk, 1 +allegra.ga, 1 +allegra180.ga, 1 +allegra180mg.ga, 1 +allegrapark.ga, 1 +allemoz.com, 1 +allemoz.fr, 1 +allenacampbell.tk, 1 +allenarchive.com, 1 +allensun.org, 1 +allenturley.com, 1 +allenwillis.ga, 1 +allergento.shop, 1 +allergento.store, 1 +allergictoidiots.tk, 1 +allergyweb.ga, 1 +allerlei-havelte.nl, 1 +allerstorfer.at, 1 +alles-kan.be, 1 +alles-nur-ge.cloud, 1 +alles.cx, 0 +alleskan.gent, 1 +alleskomtgoed.org, 1 +allesley.com, 1 +allesuitdekast.be, 1 +allevamentoticinella.tk, 1 +allfashionews.tk, 1 +allfaucet.ml, 1 +allfoodrecipes.ga, 1 +allforex.ml, 1 +allforhon.tk, 1 +allformsweden.com, 1 +allfortips.com, 1 +allfundsconnect.com, 1 +allgadgetsfree.tk, 1 +allgaragefloors.com, 1 +allgemeinarzt-wenta-bralla.de, 1 +allgolfreviews.com, 1 +allgooddeedshomes.com, 1 +allgosts.ru, 1 +allgrass.net, 1 +allgreek.tk, 1 +allgreenturf.com.au, 1 +allhallows.tk, 1 +allhard.org, 1 +allhits.ml, 1 +allhomemueble.com, 1 +allhsa.com, 1 +alli-diet-pill.cf, 1 +alli-pills.cf, 1 +alliaancebiotech.com, 1 +alliance-clan.tk, 1 +alliance-immobilier-service-neuf.fr, 1 +alliance-psychiatry.com, 1 +allianceforafreesociety.com, 1 +allianceforafreesociety.net, 1 +allianceforafreesociety.org, 1 +alliances-globalsolutions.com, 0 +allianskyrkan.se, 1 +alliedfrozenstorage.com, 1 +alliedpavers.com, 1 +allinagency.com, 1 +allinbit.ir, 1 +allincoin.shop, 1 +allindiacityguide.com, 1 +allindiajobs.ga, 1 +allinform.ga, 1 +allinone-ranking150.com, 1 +allinsuranceinformation.com, 1 +allis.studio, 1 +allitcrm.sytes.net, 1 +allius.de, 1 +alljamin.com, 1 +alljokesaside.tk, 1 +alllaboutchickens.tk, 1 +allladyboys.com, 1 +allline.shop, 1 +allmagic.tk, 1 +allmajestic.com, 1 +allmandlaw.com, 1 +allmaps.tk, 1 +allmaster.ga, 1 +allmba.cf, 1 +allmemy.com, 0 +allmessedup.tk, 1 +allmodern.com, 1 +allmousepads.com, 1 +allnoticebd.com, 1 +allnovosibirsk.tk, 1 +allns.fr, 1 +allo-credit.ch, 0 +allo-luxembourg.tk, 1 +allofthestops.com, 1 +allontanamentovolatili.it, 1 +allontanamentovolatili.milano.it, 1 +allopurinol.gq, 1 +allopurinol100mg.tk, 1 +allopurinol300mg.ml, 1 +alloutofgum.com, 1 +alloutsec.com, 1 +alloverthehill.com, 1 +allpedia.tk, 1 +allphaseclean.com, 1 +allplayer.tk, 1 +allpointsblog.com, 1 +allpointsheating.com, 1 +allpornvids.com, 1 +allprices.world, 1 +allprints.tk, 1 +allproapplianceservice.com, 1 +allproptonline.com, 1 +allpussynow.com, 1 +allrad-buck.de, 1 +allram.info, 1 +allrepair.gr, 1 +allresorts.tk, 1 +allright.tk, 1 +allroundtechnology.com, 1 +allroundtechnology.nl, 1 +allsaints.church, 1 +allsarms.com, 1 +allscammers.exposed, 1 +allsearch.io, 1 +allseasons-cleaning.co.uk, 1 +allseasonswaterproofing.com, 1 +allsoftfree.com, 1 +allsoulinc.com, 1 +allsoulmobile.com, 1 +allsoultech.com, 1 +allspinecare.com, 1 +allstakesupply.com.au, 1 +allstarautokiaparts.com, 1 +allstarcashforcars.com, 1 +allstarcustompools.com, 1 +allstarpartyinflatables.co.uk, 1 +allstarquilts.com, 1 +allsun.online, 1 +allsurpl.us, 1 +allsync.com, 1 +allsync.nl, 0 +alltape.eu, 1 +allterrainfence.com, 1 +allthebots.com, 1 +alltheplaces2go.com, 1 +alltherapies.tk, 1 +alltherooms.com, 1 +alltherooms.es, 1 +allthestuff.com, 1 +allthethings.co.nz, 1 +allthetopnews.com, 1 +allthewaynorth.xyz, 1 +allthings.me, 1 +allthingsfpl.com, 1 +allthingshealthy.org, 1 +allthingssquared.com, 1 +allthingswild.co.uk, 1 +alltimeonline.com, 1 +alltrade.ga, 1 +alltubedownload.net, 1 +allucinati.tk, 1 +allur-club.cf, 1 +allurebikerental.com, 1 +allurechiro.com, 1 +alluremedicalaesthetic.com, 1 +allurescarves.com, 1 +alluvion.studio, 1 +allvideofoot.tk, 1 +allvips.ru, 0 +allvitalconstruction.com, 1 +allways.tk, 1 +allweatherlandscaping.net, 1 +allwebtuts.com, 1 +allwiki.tk, 1 +allwordpress.tk, 1 +allworld.ga, 1 +allwrestling.ga, 1 +alma365.it, 1 +almaarkansas.gov, 1 +almadeviajante.com, 1 +almagalla.com, 1 +almanassa.com, 1 +almanassa.net, 1 +almanassa.run, 1 +almanea.email, 1 +almanea.org, 1 +almanssur.com, 1 +almarail.tk, 1 +almargen.ga, 1 +almasoft.ga, 1 +almastabriz.com, 1 +almasteb.com, 1 +almatinki.com, 1 +almavios.com, 0 +almayadeen.education, 1 +almaz-host.ml, 1 +almaz-host.tk, 1 +almeeraloyalty.com, 1 +almenrausch-pirkhof.de, 1 +almi.cz, 1 +almiriatechstore.co.ke, 1 +almlab.tk, 1 +almorafestival.com, 1 +almosis.tk, 1 +almost.fit, 1 +almostobjective.com, 1 +almstrom.org, 1 +almukhtar.se, 0 +almusbahperfume.com, 1 +almut-zielonka.de, 1 +almx.net, 1 +alng.me, 1 +alnitech.com, 0 +alocato.com, 1 +alodokita.com, 1 +aloe-vera-info.tk, 1 +aloemeda.de, 1 +aloesoluciones.com.ar, 1 +alofone.vn, 1 +alohapartyevents.co.uk, 1 +alojamientos-cuba.com, 1 +alolabor.org, 1 +alomch.gq, 1 +alonely.place, 1 +alonetone.com, 1 +along.org, 1 +alonsoluzgas.es, 1 +aloo.ga, 1 +alotso.com, 1 +alov.blog, 1 +alp.od.ua, 1 +alpca.org, 1 +alpe-d-or.dyn-o-saur.com, 1 +alpencam.com, 1 +alpencams.at, 1 +alpencams.com, 1 +alpencams.de, 1 +alpencams.net, 1 +alpencams.nl, 1 +alpengreis.ch, 1 +alpenjuice.com, 1 +alperozmen.kim, 1 +alpertron.com.ar, 1 +alpes-deis-tools.com, 1 +alpha-ag.ru, 1 +alpha-assistant.com, 1 +alpha-bet.com.ua, 1 +alpha-centauri.tk, 1 +alpha-force.net, 0 +alpha-protein.de, 1 +alpha-shop.gr, 1 +alpha-showcase.com, 1 +alpha.ch, 1 +alpha88uat.com, 1 +alphaantileak.net, 1 +alphabet-z.xyz, 1 +alphabeta.com, 1 +alphabetsigns.com, 1 +alphabouncycastles.co.uk, 1 +alphabytes.uk, 0 +alphachat.net, 1 +alphacity.tk, 1 +alphacomputersllc.com, 1 +alphaconsult.sk, 0 +alphaconvites.com.br, 1 +alphadance.tk, 1 +alphadefense.co.za, 1 +alphadote.com, 1 +alphadronten.tk, 1 +alphaetomega3d.fr, 1 +alphagames.tk, 1 +alphahosting.hu, 1 +alphahunks.com, 1 +alphainflatablehire.com, 1 +alphalibraries.com, 1 +alphalight.id, 1 +alphalightgear.com, 1 +alphamedphysicians.com, 1 +alphanodes.com, 1 +alphapengu.in, 1 +alphaperfumes.com.br, 1 +alphapoker.ru, 1 +alpharail.se, 1 +alpharoofga.com, 1 +alpharotary.com, 1 +alphasall.com, 1 +alphasib.ru, 1 +alphasoft-i.net, 1 +alphasoko.com, 1 +alphassl.de, 1 +alphatrading.tk, 1 +alphatrash.de, 1 +alphatv.cf, 1 +alphatv.ga, 1 +alphazure.co.uk, 1 +alphera.nl, 1 +alphipneux.fr, 1 +alpine-holiday.de, 1 +alpine-tuning.de, 1 +alpinechaletrental.com, 1 +alpinedentalhealth.com, 1 +alpinehighlandrealty.com, 1 +alpineitltd.co.uk, 0 +alpineplanet.com, 1 +alpinepubliclibrary.org, 1 +alpinestarmassage.com, 1 +alplogopedia.it, 1 +alquds.edu, 1 +alquila-tu-casa.com, 1 +alquilerps5.com, 1 +alquran-online.tk, 1 +alrait.com, 1 +alre-outillage.fr, 1 +alrobotics.net, 1 +alroniks.com, 1 +alsaagency.tk, 1 +alsace-boutique.fr, 1 +alsaceboutique-peluches-bukowski.fr, 1 +alsops.cf, 1 +alstertouch.com, 1 +alstertouch.de, 1 +alt-three.com, 1 +alt.org, 1 +alta-ict.nl, 1 +altabash.tk, 1 +altabib.me, 1 +altabooks.ga, 1 +altacomunicazione.tk, 1 +altaekwondo.club, 1 +altahrim.net, 1 +altai-info.ga, 1 +altai-voyage.tk, 1 +altai-zemlya.cf, 1 +altai-zemlya.ga, 1 +altai-zemlya.ml, 1 +altai-zemlya.tk, 1 +altai22.tk, 1 +altairlyh.com, 1 +altaizemlya.cf, 1 +altaizemlya.ga, 1 +altaizemlya.ml, 1 +altaizemlya.tk, 1 +altapina.com, 0 +altaplana.be, 1 +altdforyou.tk, 1 +alteah.com, 1 +altecgmbh.de, 1 +altedirect.com, 1 +alteiria.fr, 1 +alter-news.fr, 1 +alteralife.eu, 1 +alteraro.org, 1 +alterbaum.net, 1 +altered.network, 1 +altered.si, 1 +alterego.tk, 1 +alterengine.tk, 1 +altergalaxy.tk, 1 +alterlinks.com, 1 +alterlinks.fr, 1 +alterlinks.it, 1 +alterlinks.nl, 1 +alternador.com.br, 1 +alternativagospel.tk, 1 +alternative-e-energy.tk, 1 +alternative-reussite.org, 1 +alternative.bike, 1 +alternative.hosting, 1 +alternativedev.ca, 1 +alternativeenergy.tk, 1 +alternativefacts.cf, 1 +alternativehosting.ca, 1 +alternativehosting.com, 1 +alternativeinternet.ca, 1 +alternativet.party, 1 +alternativetomeds.com, 1 +alternatiwa.tk, 1 +alternatyv.ch, 1 +alterspalter.de, 1 +altertek.org, 1 +altes-sportamt.de, 1 +altesses.eu, 1 +altestore.com, 1 +altezza-autore.ru, 1 +althistory.ga, 1 +altidrabat.dk, 1 +altieresgomes.com.br, 1 +altijdleroy.nl, 1 +altijdleroy.online, 1 +altimari.net, 1 +altinea.fr, 1 +altinopoliscervejaria.com.br, 1 +altisdev.com, 1 +altisnet.ga, 1 +altiup.com, 0 +altiusconsulting.net, 1 +altiusmortgage.com, 1 +altkremsmuensterer.at, 1 +altmaestrat.es, 1 +altmann-systems.de, 1 +altmedicine.tk, 1 +altoa.cz, 1 +altonkey.com, 1 +altopartners.com, 1 +altopia.com, 1 +altorise.com, 1 +altos.tk, 1 +altospam.com, 1 +altovoltaggio.tk, 1 +altoweb.tk, 1 +altphotos.com, 1 +altralamezia.tk, 1 +altramarsala.tk, 1 +altrasoluzione.com, 1 +altratella.tk, 1 +altrei.ch, 1 +altrui.st, 1 +altsdigital.com, 1 +altspacex.com, 1 +altterapevt.com, 1 +alttrackr.com, 1 +altunbas.info, 1 +altweb.ro, 1 +aluchta.tk, 1 +aluguer-rodagigante.pt, 0 +alulasails.com, 1 +aluminiosluanda.com, 1 +aluminium-express.ru, 1 +aluminium-giesserei.de, 1 +aluminumfencestlouis.com, 1 +alumni-kusa.jp, 1 +alumni-skensa.tk, 1 +alunara.eu, 1 +alunyc.gq, 1 +alupferd.de, 1 +aluroof.eu, 1 +alushta-vostorg.ml, 1 +alushta-vostorg.tk, 1 +alushta.tk, 1 +alusib.ga, 1 +alusim.ga, 1 +alusta.co, 0 +alvaiazere.net, 1 +alvarezmorales.tk, 1 +alvarojacome.com, 1 +alvarovega.tk, 1 +alvastonauto.fi, 1 +alvcs.com, 1 +alviano.com, 0 +alvicom.hu, 1 +alvimedika.com.ua, 1 +alvirzy.tk, 1 +alvn.ga, 1 +alvoconsult.com, 0 +alvosec.com, 1 +always.com, 1 +always.com.mx, 1 +alwayshowher.tk, 1 +alwayslookingyourbest.com, 1 +alwaysmine.fi, 1 +alwaysonssl.com, 1 +alwayswanderlust.com, 1 +alxclub.tk, 1 +alxlegal.com, 1 +alxu.ca, 1 +alykkelife.com, 1 +alyoung.com, 1 +alyssamilano.tk, 1 +alza.at, 1 +alza.co.uk, 1 +alza.cz, 1 +alza.de, 1 +alza.hu, 1 +alza.sk, 1 +alzashop.com, 1 +alziamoiltetto.it, 1 +alzon.cf, 1 +alzulej.pt, 1 +am-39.com, 1 +am-dd.com, 1 +am-executive-consulting.com, 1 +am-i-on-am-i-on-drugs-dot-com.com, 1 +am-i-on-drugs.com, 1 +am-liaotian.com, 0 +am-schlossgarten.haus, 1 +am-sonnenblick.de, 1 +am-sonnengarten.de, 1 +am156.com, 1 +am22i6xaf1m2a5m9k.xyz, 1 +am2digital.com, 1 +am3.se, 1 +am5.pl, 1 +am5039.com, 1 +am5188.com, 1 +am5199.com, 1 +am6118.com, 1 +am8.com, 1 +am8009.com, 1 +am8028.com, 1 +am8136.com, 1 +am8213.com, 1 +am85168.com, 1 +am8811.net, 1 +am8833.net, 1 +am8898.net, 1 +am8info.com, 1 +am9588.com, 1 +ama-agency.ma, 1 +ama.ne.jp, 1 +amaabjj.com, 1 +amabiligranilhas.com, 1 +amadeusproject.cf, 1 +amadin.tk, 1 +amadoraslindas.com, 1 +amadvice.com, 1 +amadvocates.com, 1 +amaforro.com, 1 +amagdic.com, 1 +amagical.net, 0 +amaiz.com, 1 +amal2019.com, 1 +amalfi5stars.com, 1 +amalficoastransfers.it, 1 +amalfilapiazzetta.it, 1 +amalfipositanoboatrental.com, 1 +amalfirock.it, 1 +amalfitabula.it, 1 +amalgaamvrij.tk, 1 +amalgamma.ml, 1 +amanandalens.com, 1 +amandadamsphotography.com, 1 +amandahamilton.tk, 1 +amandasage.ca, 1 +amandaworldstudies.com, 1 +amanduscommunication.com, 1 +amani-kinderdorf.de, 1 +amaranthinewanderlust.com, 1 +amaranthus.com.ph, 1 +amardham.org, 1 +amaresq.com, 1 +amarreconbrujeria.com, 1 +amarresconvudu.com, 1 +amarresdeamorconelbrujoguillermo.com, 1 +amarresimposibles.com, 1 +amarresperuanos.com, 1 +amarresydominio.com, 1 +amartaramitramandal.tk, 1 +amaruddinmufid.com, 1 +amasea.yachts, 1 +amasing.tk, 1 +amateri.com, 1 +amateur-ham-rad.io, 1 +amateur.cf, 1 +amateurplayerstour.com, 1 +amateurpornhours.com, 1 +amateurradionotes.com, 1 +amateurs.ga, 1 +amateurvoicetalent.com, 1 +amati.solutions, 1 +amato.tk, 1 +amatsuka.com, 1 +amatya.co.uk, 1 +amatzen.dk, 1 +amauf.de, 1 +amautorepairwa.com, 1 +amavis.org, 1 +amazcode.ooo, 1 +amazefabrics.com, 1 +amazetimberfurniture.com.au, 1 +amazili-communication.com, 1 +amazinations.com, 1 +amazing-castles.co.uk, 1 +amazinginflatables.co.uk, 1 +amazingmalang.id, 1 +amazingpetshere.com, 1 +amazingraymond.com, 1 +amazingraymond.com.au, 1 +amazonemotions.com, 1 +amazoniacoffees.com, 1 +amb.tf, 1 +amb8.net, 1 +ambacoin.io, 1 +ambassify.com, 1 +ambassify.eu, 1 +amberalert.gov, 1 +amberglowleisure.co.uk, 1 +amberhouse.ga, 1 +amberoad.tk, 1 +amberonline.tk, 1 +ambersoftware.co.uk, 1 +amberwiz.com, 1 +ambholding-usedcars.be, 0 +ambicorpenergy.com, 1 +ambicorprealestate.com, 1 +ambiente.one, 1 +ambigramasdecarmela.tk, 1 +ambion.am, 1 +ambiq.nl, 1 +ambivalence.tk, 1 +ambouncyhire.com, 1 +ambra.net.au, 1 +ambra.net.nz, 1 +ambrosiamosaicos.co, 1 +ambrosio.tk, 1 +ambrosius.io, 1 +ambulanceplus.cz, 1 +ambulanza.roma.it, 1 +ambulari.cz, 1 +amcchemical.com, 0 +amcfirst.com, 1 +amchainitiative.org, 1 +amcs.website, 1 +amdm.ru, 1 +amdouglas.uk, 1 +amdrumors.com, 1 +amdukis-bordercollies.tk, 1 +amechancez.work, 1 +amedtest.org, 1 +ameego.com, 1 +ameego.it, 1 +ameego.net, 1 +ameego.nl, 1 +ameego.org, 1 +ameeradubai.com, 1 +amees.me, 0 +ameeventos.pt, 1 +ameho.me, 0 +ameliemarieintokyo.com, 1 +amello.de, 1 +amendine.fr, 1 +ameninalaceira.com.br, 1 +ameri-drain.com, 1 +ameri.capital, 1 +america.gov, 1 +america250.gov, 1 +americafamilylawcenter.org, 1 +americafc.tk, 1 +americagambles.com, 1 +americahealthcare.tk, 1 +americamilitar.com, 1 +american-school-search.com, 1 +american.dating, 1 +americanartwarehouse.com, 1 +americanbooks.cf, 1 +americanbuzz.tk, 1 +americancomfortexperts.com, 1 +americandisinfectingassociation.com, 1 +americandisinfectingassociation.org, 1 +americanenergysystemswa.com, 1 +americanflooring.co, 1 +americanflooringservicesinc.com, 1 +americanfootball.ml, 1 +americanfootball.tk, 1 +americangods.tk, 1 +americanhoneyproducers.org, 1 +americanindiancoc.org, 0 +americanindiannursing.com, 1 +americanitpartners.com, 1 +americankickoff.ga, 1 +americanmediainstitute.com, 1 +americanpop.be, 1 +americanpregnancy.org, 1 +americanreservations.us, 1 +americans.cam, 1 +americanstrategic.com, 1 +americanunicornparty.tk, 1 +americanwater.lk, 1 +americapitalfunding.com, 1 +americasbasementcontractor.com, 1 +americasdirector.com, 1 +americasgottalentauditions.com, 1 +americathebeautifulquarters.gov, 1 +americkykongres.cz, 1 +americoadvogados.com.br, 1 +americolorcorp.com, 1 +ameriikanpoijat.org, 1 +amerika-forum.de, 1 +amerikanloto.tk, 1 +amerimex.cc, 1 +amerimex.org, 1 +amerion.nl, 1 +ameriondental.nl, 1 +amesgen.de, 1 +amesvacuumrepair.com, 1 +amethystbodyart.co.za, 1 +amethystcards.co.uk, 1 +amethystdevelopment.co.uk, 1 +amethystwebsitedesign.com, 1 +amevoice.com, 1 +ameza.co.uk, 1 +ameza.com.mx, 1 +ameza.io, 1 +ameza.me, 1 +ameza.net, 1 +amf.to, 1 +amfiteatr.tk, 1 +amfora.gq, 1 +amforst.ddns.net, 1 +amg-microwave.com, 1 +amgreatness.com, 1 +amh-entertainments.co.uk, 1 +ami-de-bastanes.fr, 1 +amianto.roma.it, 1 +amica-travel.com, 1 +amicalecanyon.ch, 0 +amiciperlatesta.it, 1 +amielle.com, 1 +amifoundation.net, 1 +amigodeltoro.tk, 1 +amigosdelvalenciadeastorga.tk, 1 +amigosdivecenter.com, 1 +amigosencanada.com, 1 +amigucrochet.com, 1 +amikootours.com, 1 +amilaresort.com, 1 +amilcalcados.com.br, 1 +amilesportes.com.br, 1 +amilum.org, 1 +amin.one, 1 +aminafrance.com, 1 +amindset.hk, 1 +amineamellouk.com, 1 +amineptine.com, 1 +aminfarhoodi.tk, 1 +aminko.ga, 1 +aminoro.de, 1 +aminorth.com, 1 +aminovega.com, 1 +aminsabeti.com, 1 +aminullrouted.com, 1 +amion.com.ua, 1 +amionamiondrugsdotcom.com, 1 +amiondrugs.com, 1 +amionvpn.com, 1 +amirasyraf.com, 1 +amirautos.com, 0 +amirmahdy.com, 1 +amiserver.de, 1 +amisharingstuff.com, 1 +amisoft.co.jp, 1 +amisoft.tk, 1 +amissing.link, 1 +amithvijayan.in, 1 +amitpatra.com, 0 +amitriptyline-hydrochloride.ga, 1 +amitriptyline25mg.cf, 1 +amitt.ga, 1 +amj74-informatique.fr, 1 +amjaadabdullah.com, 1 +amjinc.ca, 1 +amlakresan.ir, 1 +amlakzibakenar.com, 1 +amlameiras.pt, 0 +amleather.pl, 1 +amliorefemme.tk, 1 +amm6e.com, 1 +ammachiyudeadukkala.net, 1 +ammanagingdirectors.com, 1 +ammboi.my, 1 +amministratore.biz, 1 +amministratore.roma.it, 1 +amministratorecondominiale.it, 1 +amministratorecondominio.roma.it, 1 +amnesty.org.au, 1 +amnesy.fr, 1 +amniowell.com, 1 +amnistiya.tk, 1 +amobileway.co.uk, 1 +amodeocarlo.com, 1 +amok8.am, 1 +amokinio.com, 1 +amolaccum.tk, 1 +amolador.com.br, 1 +amolare.com.br, 1 +amollare.com.br, 1 +amongtheflora.com, 1 +amongus-guru.ru, 1 +amongus.coffee, 1 +amoozesh98.ir, 1 +amoraparavoce.com.br, 1 +amordetelas.com, 1 +amorgos-aegialis.com, 1 +amorgosrentandgo.gr, 1 +amorim.ca, 1 +amorphis.tk, 1 +amortyzator.tk, 1 +amorxyoga.com, 1 +amorymerced.tk, 1 +amoryurgentcare.com, 1 +amoursucre.com, 1 +amoxicillin-500mg.ga, 1 +amoxicillin.cf, 1 +amoxicillin.ga, 1 +amoxicillincapsules.tk, 1 +amoxicillinonline.tk, 1 +amoxil.cf, 1 +amoxil.ga, 1 +amoxil875.ga, 1 +amoxilonline.gq, 1 +amp-logistics.com, 1 +ampdes.com.au, 1 +amper.kharkov.ua, 1 +amperaa.net, 1 +ampersandnbspsemicolon.com, 1 +ampetronic.com, 1 +ampgroep.nl, 1 +amphetamines.org, 1 +amphibo.ly, 1 +amphora.tk, 1 +amphost.tk, 1 +ampicillin.ga, 1 +ampicillin.ml, 1 +ampicilliniv.tk, 1 +ampicillinonline.gq, 1 +amplead.com, 1 +ampledesigners.com, 1 +ampleinfographics.com, 1 +ampleitsolutions.com.au, 1 +ampleroads.com, 1 +amplifier-technics.tk, 1 +ampproject.com, 1 +ampproject.org, 1 +ampullen.tk, 1 +amputated.tk, 1 +amputatedgenitals.tk, 1 +amrcaustin.com, 1 +amrcla.com, 1 +amrff.com, 1 +amritps.com, 1 +amroofingelpaso.com, 1 +amruta.org, 1 +ams-web-qa.azurewebsites.net, 1 +ams.co.rs, 1 +amsconnectapp.com, 1 +amsel305nc.ddnss.de, 1 +amsfoodhk.com, 1 +amstelland.com, 1 +amstelradio.tk, 1 +amstelveentje.nl, 1 +amsterdamian.com, 1 +amsuisse.com, 1 +amt-taxfrance.com, 1 +amtcplays.com, 1 +amtentertainments.co.uk, 1 +amule.cf, 1 +amunoz.org, 1 +amuq.net, 1 +amur-photo.ml, 1 +amur.tk, 1 +amuraimpianti.it, 1 +amusa.cl, 1 +amvip9.com, 1 +amvisualgraphics.com, 1 +amxpj888.com, 0 +amy-nichols.ga, 1 +amyapets.tk, 1 +amyfoundhermann.com, 1 +amymabel.com, 1 +amyria.jp, 1 +amyrussellhair.com, 1 +amytuarez.ml, 1 +amyyeung.com, 1 +amzik.tk, 1 +amzlive.com, 1 +amzmall.com, 1 +amzn.rocks, 1 +an-alles-gedacht.de, 1 +an0ns.ru, 0 +an0ns.tk, 1 +an2ic3.de, 1 +an7hrax.se, 1 +anaal-nathrakh.tk, 1 +anaalnathrakh.tk, 1 +anabecoaj.org, 1 +anabelpagra.com, 1 +anabolic-stresser.ga, 1 +anabolic.co, 1 +anabolickdieta.ga, 1 +anabolics.tk, 1 +anabolika.ga, 1 +anabolika.gq, 1 +anabolika.ml, 1 +anachristinarodriguez.com, 1 +anachronis.gq, 1 +anacom.pt, 1 +anacreon.de, 1 +anacruz.es, 1 +anadiyogacentre.com, 1 +anaethelion.fr, 1 +anafranil.cf, 1 +anageorgia.com, 1 +anagir.tk, 1 +anagramma.tk, 1 +anahwaftah.ga, 1 +anaiscoachpersonal.es, 1 +anaisfae.art, 1 +anakeles.com, 0 +anakin.ca, 1 +analgesia.ga, 1 +analgesia.net, 1 +analinsting.tk, 1 +analisi-grammaticale.biz, 1 +analisi-logica.it, 1 +analisi-periodo.it, 1 +analisilaica.it, 1 +analitik.ml, 1 +analizator.tk, 1 +analogical.ga, 1 +analogist.net, 1 +analpantyhose.org, 1 +analteengirls.net, 1 +analytics-shop.com, 1 +analyticsinmotion.com, 1 +analyticum.at, 1 +analyticum.com, 1 +analyticum.de, 1 +analyticum.eu, 1 +analyticum.net, 1 +analytik.news, 1 +analyze-ed.com, 1 +analyzemyfriends.com, 1 +anamelikian.com, 1 +anamterminal.tk, 1 +ananas.gq, 1 +anandchowdhary.com, 1 +anangeix.tk, 1 +ananiev.ml, 1 +anankecosmetics.com, 1 +anantshri.info, 1 +ananyagupta.tk, 1 +anapsi.tk, 1 +anarajaoui.ma, 1 +anarcasmetalicos.tk, 1 +anarchista.top, 1 +anarchistischegroepnijmegen.nl, 0 +anarchistos.tk, 1 +anarchyrp.life, 1 +anarchyweb.tk, 1 +anarhia.tk, 1 +anarhija.tk, 1 +anarka.org, 1 +anarkhe.net, 1 +anarshist.tk, 1 +anarticle.gq, 1 +anasaci.com, 1 +anasahr.be, 1 +anasibrahim.com, 1 +anassiriphotography.com, 0 +anastasia-shamara.ru, 0 +anastasiaweb.tk, 1 +anastasis.studio, 1 +anatoly.tk, 1 +anatomized.tk, 1 +anatoray.com, 1 +anaxios.ga, 1 +anayarealm.com, 1 +anblife.com, 1 +ancarda.net, 1 +ance.lv, 0 +ancel.io, 1 +ancentury.com, 1 +ancestramil.fr, 1 +anchev.net, 1 +anchorit.gov, 1 +anchoritsg.com, 1 +anchovy.nz, 0 +anchr.io, 1 +anciennes-automobiles.fr, 1 +anciens.org, 1 +ancient-gates.de, 1 +ancientnorth.com, 1 +ancolies-andre.com, 0 +anconaswine.com, 1 +ancroma.ro, 1 +and-stuff.nl, 1 +and.com, 0 +andaluciaboard.tk, 1 +andalusierondreizen.nl, 1 +andcable.com, 1 +andel.info, 0 +anders.hamburg, 1 +anderskp.dk, 0 +andersonpowerservices.com, 1 +andersonshatch.com, 1 +anderstornkvist.se, 1 +andesnevadotours.com, 1 +andhaniawan.my.id, 1 +andibo.net, 1 +andiland.pl, 1 +andiplusben.com, 1 +andisadhdspot.com, 1 +andiscyber.space, 1 +anditi.com, 1 +andnet.tk, 1 +andoms.fi, 1 +andorraimperial.tk, 1 +andorrainsiders.com, 1 +andos.tk, 1 +andr-mobile.tk, 1 +andradealbuquerque.pt, 1 +andre-ballensiefen.de, 1 +andre-otto.com, 1 +andre-schlichting.de, 1 +andrea-kiaora.de, 1 +andrea-m.me, 1 +andrea-wirthensohn.at, 0 +andreaalloway.com, 1 +andreaassenti.it, 1 +andreaboero.it, 1 +andreadraghetti.it, 1 +andreae.nl, 1 +andreagobetti.com, 1 +andreagourmet.it, 1 +andreahruby.it, 1 +andreamcnett.com, 1 +andreamonicahug.com, 1 +andreapalermo.tk, 1 +andreapavone.com, 1 +andreariccitraduzioni.it, 1 +andreasfeusi.ch, 1 +andreasjanker.de, 0 +andreaskluge.eu, 1 +andreaskrasa.com, 1 +andreaslicht.nl, 1 +andreasolsson.se, 1 +andreasr.com, 1 +andrecanuto.com.br, 1 +andree.cloud, 1 +andrehansen.de, 1 +andrehazeswinactie.nl, 1 +andrei-nakov.org, 1 +andreina-atencio.com, 1 +andrejbenz.com, 1 +andrejstefanovski.com, 1 +andrelauzier.com, 1 +andremaciel.pt, 1 +andreoliveira.io, 1 +andrepicard.de, 1 +andrescuartas.tk, 1 +andresgarzon.net, 1 +andrespaz.com, 1 +andresrios.nl, 1 +andresrosa.es, 1 +andressaflores.com.br, 1 +andreundnina.de, 1 +andrew.fi, 1 +andrewbennett.ltd, 1 +andrewbroekman.com, 1 +andrewdaws.info, 1 +andrewdaws.io, 1 +andrewdaws.me, 1 +andrewdaws.tv, 1 +andrewensley.com, 1 +andrewhowden.com, 0 +andrewimeson.com, 1 +andrewin.ru, 1 +andrewisidoro.co.uk, 1 +andrewlarson.org, 1 +andrewletson.com, 1 +andrewmcfarlane.tk, 1 +andrewmichaelsmith.com, 1 +andrewmichaud.com, 1 +andrewmichaud.me, 1 +andrewpeng.net, 1 +andrewprokos.com, 1 +andrewpucci.com, 0 +andrewrdaws.com, 1 +andrewrgoss.com, 1 +andrewryno.com, 1 +andrewsandford.com, 1 +andrewsoutar.com, 1 +andrewsun.com, 1 +andrewtasso.com, 1 +andrewtaylor.eu, 1 +andrewtchin.com, 1 +andrewtran.xyz, 1 +andrewwiggins.ca, 1 +andrewx.net, 1 +andrey.red, 1 +andrey1p.ru, 1 +andreyborisov.cf, 1 +andreyjuravlev.ga, 1 +andreypopp.com, 1 +andreysmirnov.tk, 1 +andrian.tk, 1 +andrianova.ml, 1 +andrienko.tk, 1 +andriraharjo.com, 1 +andrisilberschmidt.ch, 1 +andro4all.com, 1 +android, 1 +android-10-inch-tablets.tk, 1 +android-center.tk, 1 +android-club.cf, 1 +android-gamers.tk, 1 +android-hit.ml, 1 +android-it.cf, 1 +android-tv.3utilities.com, 1 +android-tv.ml, 1 +android.re, 1 +android1.co.id, 1 +android1pro.com, 1 +androide.com, 1 +androidgadgematic.com, 1 +androidgaming.tk, 1 +androidhry.cz, 1 +androidhub.ru, 1 +androidkatalog.cz, 1 +androidmarketturkiye.tk, 1 +androidmax.tk, 1 +androidmovile.com, 1 +androidnovinky.cz, 1 +androidphones.ga, 1 +androidru.ml, 1 +androidservicetool.com, 1 +androidsis.com, 1 +androidtamer.com, 1 +androidtcpdump.com, 1 +androidtelefony.cz, 1 +androidtools.gq, 1 +androidwale.ga, 1 +androidzone.me, 1 +androlab.tk, 1 +andromeda.se, 1 +andromedacenter.com, 1 +andropia-online.fr, 1 +androtix.com, 1 +androtiyas.com, 1 +andrush.eu, 1 +andruvision.cz, 1 +andsat.org, 1 +andschwa.com, 0 +andsecure.ch, 0 +anduril.de, 1 +anduril.eu, 1 +andy-hagans.tk, 1 +andybrett.com, 1 +andyc.cc, 1 +andycatteceur.tk, 1 +andycraftz.eu, 1 +andycrockett.io, 1 +andys-place.co.uk, 1 +andyscubepage.tk, 1 +andyson.at, 1 +andysroom.dynu.net, 1 +andyt.eu, 1 +andythomasonline.tk, 1 +andywalkeronline.tk, 1 +andywilliamsonline.tk, 1 +andzia.art.pl, 1 +anecuni-club.com, 1 +anecuni-rec.com, 1 +anedot-sandbox.com, 1 +anedot.com, 1 +anedot.space, 1 +anedot.xyz, 1 +aneducationuto.tk, 1 +anekdot-pr.tk, 1 +anekdotik.tk, 1 +anekdotiki.tk, 1 +anelik.tk, 1 +aneslix.com, 0 +anetaben.nl, 1 +anetteolzon.tk, 1 +aneutrallife.com, 1 +anex.us, 1 +anextraordinaryday.net, 1 +ange-de-bonheur444.com, 1 +angel-body.com, 1 +angelalombardo.it, 1 +angelarellano.tk, 1 +angelbulldog.tk, 1 +angelcorpus.tk, 1 +angelefloramendy.org, 1 +angelesverdes.org, 1 +angelesydemonios.es, 1 +angeletakis.net, 1 +angelic47.com, 1 +angelicare.co.uk, 1 +angelicsphynx.tk, 1 +angelikaclothing.com, 1 +angelinafilipski.tk, 1 +angelishansen.se, 1 +angeljmadrid.com, 1 +angelo4ek.tk, 1 +angeloanan.xyz, 0 +angelok.ru, 1 +angeloreyes.com, 1 +angelremigene.com, 0 +angelsanctum.tk, 1 +angelsandairwaves.tk, 1 +angelschlesser.tk, 1 +angelsgirl.eu.org, 1 +angelsmile.tk, 1 +angelsmithphotography.com, 1 +angelsoft.com, 1 +angelspabeauty.co.uk, 1 +angelswar.ga, 1 +angeltorri.tk, 1 +angelzapien.com, 1 +angepsychedelices.tk, 1 +angermanalvorna.tk, 1 +angiejones.com, 1 +angievancise.com, 1 +angiewickes.com, 1 +anginf.de, 1 +angiolinikids.it, 1 +angione.ca, 1 +angione.se, 1 +angkasa.net.id, 1 +anglersconservation.net, 1 +anglertanke.de, 1 +anglesgirl.eu.org, 1 +anglesya.win, 1 +anglictina-sojcak.cz, 1 +anglictinasojcak.cz, 1 +anglingactive.co.uk, 1 +anglirl.eu.org, 1 +angolo.ga, 1 +angora.me, 1 +angorarabbitsaspets.com, 1 +angrido.com, 1 +angristan.fr, 1 +angristan.xyz, 1 +angry-monk.com, 1 +angry.im, 1 +angrybear.tk, 1 +angrybug.com, 1 +angrydragonproductions.com, 1 +angrygolfer.com, 1 +angrysnarl.com, 1 +angryteeth.net, 1 +angular-js.ga, 1 +angular-software.at, 1 +angularjs.org, 0 +angusandperthpgl.tk, 1 +anh-dv.com, 1 +anhaffen.lu, 1 +anhcuti.com, 1 +anhdvboot.com, 1 +anhdvshop.com, 1 +anhqv.es, 1 +ani-man.de, 1 +aniaimichal.eu, 1 +aniblizzard.tk, 1 +anicam.fr, 1 +aniforprez.net, 1 +anihilated.tk, 1 +anihonetwallpaper.com, 1 +anilasansor.com, 1 +anillosdecompromiso.co, 1 +anim.ee, 1 +anima.digital, 1 +animaalternative.it, 1 +animaemundi.be, 0 +animal-liberation.com, 1 +animal-rights.com, 1 +animalarkvets.co.uk, 1 +animalcenterunomas.tk, 1 +animalcrossing.pro, 1 +animalcrossingwiki.de, 1 +animaletnous.be, 1 +animalliberation.tk, 1 +animalshelter.tk, 1 +animalstropic.com, 1 +animaltesting.fr, 1 +animalworld.club, 1 +animalworld.gq, 1 +animalz.tk, 1 +animamega.tk, 1 +animan.ca, 1 +animanganetwork.tk, 1 +animashka.tk, 1 +anime-best.tk, 1 +anime-cafe.tk, 1 +anime-culture.com, 1 +anime-dragoon.tk, 1 +anime-drift.tk, 1 +anime-tip.com, 1 +anime.my, 0 +anime1.me, 1 +anime1.moe, 1 +anime1.pw, 1 +anime1.top, 1 +animeai.com, 1 +animebase.me, 1 +animebits.moe, 1 +animeclub.in.ua, 1 +animecracks.com, 1 +animecreed.ga, 1 +animeday.ml, 1 +animedescarga.ml, 1 +animedon.tk, 1 +animeelite.tk, 1 +animefire.net, 0 +animefluxxx.com, 1 +animefun.cf, 1 +animeheaven.ml, 1 +animehf.com, 1 +animeinsights.net, 1 +animekun.tk, 1 +animelandia.tk, 1 +animelody.net, 1 +animemotivation.com, 1 +animepahe.com, 1 +animeplus1.tk, 1 +animeronews.tk, 1 +animes-portal.info, 1 +animesbrasil.tk, 1 +animesconsteemplee.tk, 1 +animesharp.com, 1 +animeshka.tk, 1 +animestreamingfr.fr, 1 +animetosho.org, 1 +animetriad.com, 1 +animorphsfanforum.com, 1 +animoxavilorza.tk, 1 +aninews.tk, 1 +anip.icu, 1 +anipassion.com, 0 +aniplus.cf, 1 +aniplus.gq, 1 +anirvalle.com, 1 +anisimov.ml, 1 +anitaalbersen.nl, 1 +anitahebe.com, 1 +anitalk.dk, 1 +anitaxcph.dk, 1 +anitube-nocookie.ch, 1 +anitube.ch, 1 +anivar.net, 1 +aniviasport.store, 1 +anivision.tk, 1 +aniwhen.com, 1 +anja-vastgoed.nl, 1 +anjaamelia.com, 1 +anjaliandthekid.com, 1 +anjara.eu, 1 +anjocerdena.com, 1 +anjoola.com, 1 +ankane.org, 1 +ankaradaozelders.tk, 1 +ankaraevdenevenakliyat.name.tr, 1 +ankarakurumsalwebtasarim.com, 1 +ankaraotokiralama.tk, 1 +ankaraprofesyonelwebtasarim.com, 1 +ankaraseo.name.tr, 1 +ankarauzmanlarnakliyat.com, 1 +anker-wladyslawowo.pl, 1 +ankitha.in, 1 +ankitpati.in, 1 +ankiuser.net, 1 +ankiweb.net, 1 +ankureurope.co.uk, 1 +ankwanoma.com, 1 +ankya9.com, 1 +anleitung-deutsch-lernen.de, 1 +anleitung-zum-flechten.de, 1 +anleitung-zum-haekeln.de, 1 +anleitung-zum-schreiben.de, 1 +anleitung-zum-schweissen.de, 1 +anleitung-zum-toepfern.de, 1 +anlene.com, 1 +anlikhaber.tk, 1 +anliting.com, 1 +anmelden.io, 1 +anmolnayyar.com, 1 +anna-beauty.ga, 1 +anna-beauty.gq, 1 +anna-center.tk, 1 +anna-dance.ru, 1 +anna-mai.net, 1 +anna.info, 1 +annabelcinemas.com, 1 +annadebrux.cf, 1 +annaenemma.nl, 1 +annafiore.com.br, 1 +annalaudel.gallery, 1 +annaleon.tk, 1 +annalisefashion.ga, 1 +annalitvinova.pro, 1 +annalouise.tk, 1 +annangela.moe, 1 +annarborplasticsurgery.com, 1 +annarokina.com, 1 +annasadzik.art, 1 +annavissi.tk, 1 +annawagner.pl, 1 +annaweb.tk, 1 +annazweglinska.pl, 1 +anne-marie.tk, 1 +annebacarat.fr, 1 +annedaniels.co.uk, 1 +anneeden.com, 1 +annejan.com, 1 +anneliesonline.nl, 1 +annema.biz, 1 +annemakeslovelycandles.co.uk, 1 +annemation.de, 1 +annetta.com, 1 +annetta.net, 1 +annettewindlin.ch, 1 +annevankesteren.nl, 1 +annevankesteren.org, 1 +anney-life.com, 1 +anniangel-porn.com, 1 +annicascakes.nl, 1 +annitrinity.com, 1 +anniversary-cruise.com, 1 +annonasoftware.com, 1 +annoncer.ga, 1 +annonces34.tk, 1 +annotate.software, 1 +annoyingasfuk.com, 1 +annrusnak.com, 1 +anns.eu, 1 +annu.tk, 1 +annuaire-auto-ecole.com, 1 +annuaire-express.tk, 1 +annuaire-photographe.fr, 0 +annual.ga, 1 +annuitycommunity.com, 1 +annulleret.tk, 1 +annunciationbvmchurch.org, 1 +annynantasiri.com, 1 +anodas.lt, 1 +anohana.org, 1 +anojan.com, 1 +anomalous.eu, 1 +anomaly.tk, 1 +anon-gap.tk, 1 +anon-next.de, 1 +anonaddy.com, 1 +anonaddy.me, 1 +anoncrypto.org, 1 +anoneko.com, 1 +anongoth.pl, 0 +anonicloud.ch, 1 +anonimizers.tk, 1 +anonish.com, 1 +anonrea.ch, 1 +anons.fr, 0 +anonser.tk, 1 +anonym-surfen.de, 1 +anonym-surfen.online, 1 +anonyme-spieler.at, 1 +anonymousbitcoinexchange.org, 1 +anonymster.com, 1 +anopan.tk, 1 +anora.ai, 1 +anoracdn.net, 1 +anorak.tech, 1 +anoretics.com, 1 +anorexia-nervosa.tk, 1 +another.ch, 1 +anotherfatgeek.net, 1 +anothermilan.net, 1 +anothermusic.tk, 1 +anothervps.com, 1 +anoujaa.com, 1 +anouncer.ga, 1 +anowicki.pl, 1 +anpaju.gq, 1 +anpigabon.ga, 1 +anquankongjian.com, 1 +anradienstverlening.nl, 1 +ans-ge.ch, 0 +ans-solutions.com, 1 +ansas.eu, 1 +ansas.net, 1 +ansdell.net, 1 +ansellchallenge.azurewebsites.net, 1 +anseo.ninja, 1 +ansermet.net, 0 +ansgar-sonntag.de, 0 +ansgar.tk, 1 +ansgarscheffold.com, 1 +ansgarsonntag.de, 0 +anshar.eu, 1 +ansibeast.net, 1 +ansichtssache.at, 1 +ansogning-sg.dk, 1 +anstaskforce.gov, 1 +answerconnect.com, 1 +answerforce.com, 1 +answering365.com, 1 +answernow.cf, 1 +answers-online.ru, 1 +answersreviews.com, 1 +ant.lgbt, 1 +antabuse.ga, 1 +antabuse500mg.ga, 1 +antabuskaufen1.gq, 1 +antalya-taxi.cf, 1 +antalya-turkey.tk, 1 +antalya-yesim.cf, 1 +antalyaescortyaren.tk, 1 +antalyamasajsalonu.gq, 1 +antama.eu, 1 +antama.nl, 1 +antanavagefarbiarz.com, 1 +antani.cloud, 1 +antarcti.co, 1 +antarctida.tk, 1 +antaresmedia.com.py, 1 +antarktida.tk, 1 +antcas.com, 0 +antechrista.tk, 1 +antecim.fr, 1 +antelope.ai, 1 +antena.ga, 1 +antenadorada.com, 1 +antenasmundosat.com.br, 1 +antenna-lyubertsy.cf, 1 +antennajunkies.com, 1 +antennista.bari.it, 1 +antennista.catania.it, 1 +antennista.it, 1 +antennista.milano.it, 1 +antennista.pavia.it, 1 +antennista.roma.it, 1 +antennista.tv, 1 +antennistaroma.it, 1 +antennisti.milano.it, 1 +antennisti.roma.it, 1 +anteprima.info, 1 +anteroleppanen.fi, 1 +antfarm.cf, 1 +antha.com, 1 +anthisis.tv, 1 +anthony-bardon.eu, 1 +anthony.games, 1 +anthonycarbonaro.com, 0 +anthonychampagne.fr, 1 +anthonychampagne.me, 1 +anthonyellis.com, 1 +anthonyfontanez.com, 1 +anthonygaidot.fr, 1 +anthonylaberge.tk, 1 +anthonyloop.com, 1 +anthonymineo.com, 0 +anthonys-landscaping.com, 1 +anthonyvadala.me, 1 +anthro.icu, 1 +anthropoid.ca, 1 +anti-bible.com, 1 +anti-civilisation.tk, 1 +anti-depressants.tk, 1 +anti-doping.tk, 1 +anti-eniologiya.ml, 1 +anti-gololed.ga, 1 +anti-iupac.tk, 1 +anti-lohotron.tk, 1 +anti-nsa.tk, 1 +anti-radar.org, 1 +anti-spy.net, 0 +anti-stop.cf, 1 +antiage.ml, 1 +antianti.nl, 1 +antiaz.com, 1 +antibanner.tk, 1 +antibioticaugmentin.cf, 1 +antibioticsadvice.cf, 1 +anticapitalist.party, 0 +anticensorship-russia.tk, 1 +antichat.tk, 1 +antichatresources.ga, 1 +anticopyright.com, 1 +anticorruption.tk, 1 +antiddoss.online, 1 +antidepressants.tk, 1 +antidopamine.com, 1 +antidope.tk, 1 +antidoping.tk, 1 +antidott.fr, 1 +antiekboerderijgraafland.nl, 1 +antifa.sh, 0 +antifake-funko.fr, 1 +antifaschistisch-reisen.tk, 1 +antifaschistische-linke.tk, 1 +antifaschistischeaktioncelle.tk, 1 +antifilter.network, 1 +antifraud.cf, 1 +antigender.tk, 1 +antigravity.cf, 1 +antihelp-tomsk.tk, 1 +antihistaminico.com, 1 +antihistory.cf, 1 +antihype.space, 1 +antijob.tk, 1 +antik-trodelmarkt.de, 1 +antikeo.com, 1 +antikfloors.ga, 1 +antikfloors.gq, 1 +antikfloors.ml, 1 +antikvar-i-ya.tk, 1 +antikvar-net.tk, 1 +antikvarius.ro, 1 +antikvarshop.tk, 1 +antilaserpriority.com, 1 +antiled.by, 1 +antimateri.com, 1 +antimaterie.tk, 1 +antimine.me, 1 +antincendio.it, 1 +antincendio.roma.it, 1 +antipa.ch, 1 +antipodi.ga, 1 +antipolygraph.org, 1 +antique-pedalcars.ch, 1 +antiquecenter.gq, 1 +antirepressionbayarea.com, 1 +antiseptik.me, 1 +antisocialist.tk, 1 +antispamcloud.dk, 1 +antispeciesism.com, 1 +antispeciesist.com, 1 +antistarenie.tk, 1 +antistate.ch, 1 +antistatik.tk, 1 +antisystem.tk, 1 +antitabak.tk, 1 +antiuser.tk, 1 +antivandal.tk, 1 +antivirus.directory, 1 +antivirusnet.tk, 1 +antivirusnik.tk, 1 +antivirusprotection.reviews, 1 +antizon.net, 1 +antocom.com, 1 +antoga.eu, 1 +antoinedeschenes.com, 1 +antoineelizabe.com, 1 +antoineschaller.ch, 0 +anton-media.tk, 1 +antonchen.com, 1 +antonellabb.eu, 1 +antoni.xyz, 1 +antonianolocura.tk, 1 +antonimos.com.br, 1 +antonin.one, 1 +antoninocardillo.com, 1 +antonio-gartenbau.de, 0 +antoniojr.adv.br, 1 +antonioordonez.es, 1 +antonjuulnaber.dk, 1 +antonoff.tk, 1 +antonok.com, 1 +antonovka.ga, 1 +antonygeorge.tk, 1 +antonyraz.de, 1 +antopie.org, 1 +antoshka-net.tk, 1 +antota.lt, 1 +antragsgruen.de, 1 +antraxx.ee, 1 +antroposboutique.it, 1 +antroposofica.com.br, 1 +ants-carte-grise.fr, 1 +antstoolbox.com, 1 +anttitenhunen.com, 1 +antvklik.com, 1 +antwire.net, 1 +antyblokada.pl, 1 +antyfake.pl, 1 +antykilion.pl, 1 +anubislinux.tk, 1 +anubisz.tk, 1 +anukaweb.com, 1 +anulowano.pl, 1 +anunciosbolivia.com, 1 +anunturitv.ro, 1 +anvagro.com, 1 +anvilmetal.tk, 1 +anvilsales.tk, 1 +anvish.in, 1 +anwalt.us, 1 +anwarverdict.ml, 1 +anxietydisorderexplained.com, 1 +anxietyspace.com, 1 +anxiolytics.com, 1 +any-download.cf, 1 +any-download.ga, 1 +any-download.gq, 1 +any-download.ml, 1 +any-download.tk, 1 +any.pm, 0 +anyad.at, 1 +anydaytour.cf, 1 +anyduchildren.tk, 1 +anyebooks.gq, 1 +anyfood.fi, 1 +anyhobby.ga, 1 +anyi.in, 1 +anyilin.cn, 1 +anypeer.net, 1 +anyplant.ga, 1 +anyprime.net, 1 +anyquestions.govt.nz, 1 +anyradio.ga, 1 +anyrose.ga, 1 +anysale.ga, 1 +anyshapemusic.com, 1 +anyshow.ga, 1 +anystack.xyz, 1 +anytimeoffices.ga, 1 +anytimesewerrepair.com, 1 +anyuta-mebel.tk, 1 +anyways.at, 1 +anywhereworks.com, 1 +anzacparkeast.com, 1 +anzahcraft.de, 1 +anzalikala.com, 1 +anzeiger.ag, 1 +anzimatech.com, 1 +ao-dev.com, 1 +ao2.it, 1 +ao27.net, 1 +ao3-cn.top, 1 +ao3unlock.xyz, 1 +ao6.me, 1 +aoadatacommunity.us, 1 +aoaprograms.net, 1 +aobeauty.com.au, 1 +aobogo.com, 1 +aodnovel.com, 1 +aoe9.com, 1 +aoeuaoeu.com, 1 +aofusa.net, 1 +aoicollege.edu, 1 +aoicprobationil.gov, 1 +aoil.gr, 1 +aojf.fr, 1 +aojiao.org, 1 +aokae.com, 1 +aoku3d.com, 1 +aomar-mohammedi.tk, 1 +aonepick.com, 1 +aooobo.com, 1 +aopedeure.nl, 1 +aopsy.de, 1 +aori.com, 1 +aorosora.com, 0 +aosc.io, 0 +aosclan.tk, 1 +aostacarnavals.it, 1 +aotearoa.maori.nz, 1 +aotearoafreepress.com, 1 +aotearoaleaks.org, 1 +aothuntees.com, 1 +aoyamacc.co.jp, 1 +aozora.moe, 1 +ap-swiss.ch, 0 +apache-portal.com, 1 +apachecountyaz.gov, 1 +apachehaus.de, 0 +apachelounge.com, 1 +apadmi.com, 1 +apadrinaunolivo.org, 1 +apadvantage.com, 1 +apalachicolaboatslips.com, 1 +apalancamiento.trade, 1 +aparistravel.com, 1 +apart-hotel-weimar.de, 1 +apartamentscalpatoi.cat, 1 +apartbook.co.uk, 1 +apartema.eu, 1 +apartema.se, 1 +apartmanicg.me, 1 +apartment-in-rijeka.com, 1 +apartment-market.ml, 1 +apartmentdecoratingblog.com, 1 +apartmentforus.vn, 1 +apartmentkroatien.at, 1 +apartmentregister.com.au, 1 +apartments-promajna.tk, 1 +apartrentrotterdam.nl, 1 +apasaja.tech, 1 +apbforum.tk, 1 +apbox.de, 1 +apcemporium.co.uk, 1 +apcpky.com, 1 +apcube.com, 1 +apdfawl.com, 1 +apdx.com, 1 +apeelectrics.com, 1 +apef.ch, 0 +apeiri.de, 1 +apelsin.ml, 1 +aperioadvice.ga, 1 +apertis.org, 0 +aperto-nota.eu, 1 +aperto.de, 1 +apertura.tk, 1 +aperture-science.net, 1 +aperture.gr, 1 +apertureimaging.com, 1 +aperturelabs.tk, 1 +aperturescience.cf, 1 +aperturesciencelabs.de, 1 +apertvre.tk, 1 +apervita.net, 1 +apex-parts.com, 1 +apex-promotion.com, 1 +apex.ac, 1 +apex.to, 1 +apexconsulting.io, 1 +apexfacades.com.au, 1 +apexitsolutions.ca, 1 +apexperformancegym.com, 1 +apfhaiti.org, 1 +apfm.fr, 1 +apfnxg.com, 1 +apgw.jp, 1 +aphelion-design.jp, 1 +aphelionband.ga, 1 +aphelionentertainment.com, 1 +aphelis.net, 1 +api-bitrefill.com, 1 +api-connect.com, 0 +api-geek.com, 0 +api.biz.tr, 1 +api.lookout.com, 1 +api.recurly.com, 1 +api.xero.com, 0 +apiary.blog, 1 +apiary.clothing, 1 +apiary.shop, 1 +apiary.store, 1 +apiary.supplies, 1 +apiary.supply, 1 +apicep.com, 1 +apiida.com, 1 +apila.care, 1 +apila.us, 1 +apiled.io, 1 +apimon.de, 1 +apimoveisorocaba.com.br, 1 +apinat.de, 1 +apination.com, 1 +apinsa.com, 1 +apio.systems, 1 +apiora.ru, 1 +apiplus.fr, 1 +apipsandiego.ml, 1 +apirest.top, 1 +apis.blue, 1 +apis.google.com, 1 +apisvida.com.br, 1 +apisyouwonthate.com, 1 +apitodemestre.com.br, 1 +apiu.me, 1 +apix.uz, 1 +apk.li, 1 +apk4fun.com, 1 +apkclash.com, 1 +apkdv.com, 0 +apkfame.com, 1 +apkfuse.com, 1 +apkmaze.com, 1 +apkmody.io, 1 +apknut.com, 1 +apkoc.com, 1 +apkoyunlar.club, 1 +apkpokemongo.ga, 1 +apkpokemongo.gq, 1 +apkpokemongo.tk, 1 +apktechy.com, 1 +apkteen.com, 1 +aplazame.com, 1 +aplibrary.org, 1 +aplikaceproandroid.cz, 1 +aplis-online.de, 0 +aplpackaging.co.uk, 1 +aplteam.tk, 1 +aplu.fr, 1 +aplusdownload.com, 1 +apluswaterservices.com, 1 +apm.com.tw, 1 +apmg-certified.com, 1 +apn-dz.org, 1 +apn-einstellungen.de, 1 +apo-deutschland.biz, 0 +apobot.de, 1 +apocalipsisdot.tk, 1 +apocalypseboard.tk, 1 +apocalypseclan.tk, 1 +apod.com.au, 1 +apod.ml, 1 +apogaea.com, 1 +apogeephoto.com, 1 +apokalipsis.tk, 1 +apollochiropractor.com, 1 +apollodiet.com, 1 +apolloheatingandair.com, 1 +apollonas.tk, 1 +apollonia.tk, 1 +apollowallet.org, 1 +apollyon.work, 1 +apoly.de, 1 +apometria.site, 1 +aponkral.com, 1 +aponkral.com.tr, 1 +aponkral.net, 1 +aponkral.org, 1 +aponte-systems.com, 1 +apopov.tk, 1 +aporia.io, 1 +aposke.com, 1 +aposke.net, 1 +aposke.org, 1 +apostalegal.com, 1 +apostalegal.pt, 1 +apostascomvalor.com, 1 +apostasolida.com, 1 +apostasolida.eu, 1 +apostilasaprovacao.com, 1 +apothecarydouglasville.com, 1 +apotheek-ict.nl, 1 +apotheke.market, 1 +apotheke55.de, 1 +apothekeonline.tk, 1 +apotom.tk, 1 +apozitivenergiasport.hu, 1 +app, 1 +app-at.work, 1 +app-cinveninfostream-qa.azurewebsites.net, 1 +app-online.cloud, 1 +app-scantech.com, 1 +app-scope.com, 1 +app.do, 1 +app.gp, 1 +app.lookout.com, 1 +app.ps, 1 +app.recurly.com, 1 +app.yinxiang.com, 0 +app00228.com, 1 +app11018.com, 1 +app2get.de, 1 +app3w.nl, 1 +app666365.com, 1 +app77018.com, 1 +appagility.co.nz, 1 +appapi.link, 1 +apparatrechose.tk, 1 +apparatus.ga, 1 +apparelfashionwiki.com, 1 +appartamento.tk, 1 +appartement-andrea.at, 1 +appartement-evolene.net, 0 +appartementhaus-badria.de, 1 +appartementmarsum.nl, 1 +appassionata.ru, 1 +appbet43.com, 1 +appbot.co, 1 +appbydl.com, 1 +appcitor.com, 1 +appcoins.io, 1 +appcuarium.com, 1 +appdrinks.com, 1 +appel-aide.ch, 1 +appelaprojets.fr, 1 +appelboomdefilm.nl, 1 +appelerintrt.tk, 1 +appengine.google.com, 1 +appers.co, 1 +appetiser.com.au, 1 +appetitesanonymous.com, 1 +appfarm.io, 1 +appgeek.com.br, 1 +appharbor.com, 1 +appify.org, 1 +appimlab.it, 1 +appizia.com, 1 +applaudit.com, 1 +apple-laptops.com, 1 +apple-watch-zubehoer.de, 1 +apple.ax, 1 +applebee1558.com, 1 +applegun.com, 1 +applejacks-bouncy-castles.co.uk, 1 +applemon.com, 1 +applemon.net, 1 +applemon.org, 1 +appleoosa.com, 1 +applesencia.com, 1 +applet.cyou, 1 +appletree.is, 1 +applevalleyca.gov, 1 +applewatch.co.nz, 1 +applian.jp, 1 +appliancepronwi.com, 1 +appliances-for-home.tk, 1 +appliancesrepairservice.ca, 1 +applic8.com, 0 +application-travel.us.com, 1 +applicationmanager.gov, 1 +applied-privacy.net, 1 +appliedenglish.jp, 1 +apply-esta.us.com, 1 +apply-eta.org, 1 +apply-visa.us.com, 1 +apply.eu, 1 +apply55gx.com, 1 +applydirect.org, 1 +applytofaceblog.com, 1 +appmania.cf, 1 +appmania.gq, 1 +appmeas.co.uk, 1 +appmeucredito.com.br, 1 +appmobile.io, 1 +appninjas.com, 1 +appointment.ga, 1 +apponic.com, 1 +apponline.com, 1 +appraf.com, 1 +apprank.in, 1 +apprendre-le-russe-avec-ania.fr, 1 +apprenticeship.gov, 1 +apprenticeships.gov, 1 +apprentimillionnaire.com, 1 +approbo.com, 1 +approval-workflow.com, 1 +approvedtreecare.com, 1 +apps-cart.com, 1 +apps.facebook.com, 0 +apps.fedoraproject.org, 1 +apps.stg.fedoraproject.org, 1 +apps4all.sytes.net, 1 +apps4inter.net, 0 +appsaraby.com, 1 +appsbud.com, 1 +appscloudplus.com, 1 +appshuttle.com, 1 +appsimplex.pt, 1 +appson.co.uk, 1 +appsren.com, 1 +appt.ch, 0 +apptesters.com, 1 +apptomics.com, 1 +apptoutou.com, 1 +appuals.com, 1 +appub.co.jp, 1 +appugo.tk, 1 +appui-de-fenetre.fr, 1 +appuntidallarete.com, 1 +appveyor.com, 1 +appworld.ga, 1 +appy.la, 1 +appzoojoo.be, 1 +aprazivel.com.br, 1 +aprendafotografia.org, 1 +aprendaingles123.com, 1 +aprende.org, 1 +aprendejainternet.tk, 1 +aprendendoengalego.gal, 1 +aprenderjuntos.cl, 1 +aprendiendoforexhoy.com, 1 +apresski-pictures.tk, 1 +apretatuercas.es, 1 +aprilagentur.de, 1 +aprofunda.art.br, 1 +aprsdroid.org, 1 +apruebaexamenes.com, 1 +aprz.de, 1 +apsa.paris, 1 +apsb.cz, 1 +apse.ga, 1 +apsnewcastle.com, 1 +apsrustandtint.com, 1 +apstats.tk, 1 +apstudynotes.org, 1 +apsua.tk, 1 +apt-one.com, 1 +aptcaust.com.au, 1 +aptechka.ga, 1 +apteka38.com, 1 +aptekakolska.pl, 1 +aptekas.tk, 1 +aptitudetests.org, 1 +aptive.co.uk, 1 +aptumseguros.mx, 1 +apu-board.de, 1 +apuestalegal.com, 1 +apuestalegal.pe, 1 +apunkt.dk, 1 +apur.org, 1 +apuraytravel.com, 1 +apuyou.io, 1 +apv-ollon.ch, 1 +apviz.io, 1 +apyha.com, 1 +aqalat.com.sa, 1 +aqarategypt.com, 1 +aqarbab.com, 1 +aqcbv.com, 1 +aqdun.com, 1 +aqiqahpremium.com, 1 +aqlami.net, 1 +aqlivia.com, 1 +aqqrate.com, 1 +aqsiq.net, 1 +aqua-ferra.co.uk, 1 +aqua-fm.tk, 1 +aqua-fotowelt.de, 1 +aqua-print.com.ua, 1 +aquabio.ch, 0 +aquabiodesign.tk, 1 +aquablue.tk, 1 +aquabotanic.tk, 1 +aquacapsule.cf, 1 +aquacitylands.com, 1 +aquadarts.tk, 1 +aquadecor.cf, 1 +aquadonis.ch, 0 +aquadrom.cz, 1 +aquafc.com, 1 +aquafilm.cf, 1 +aquagarden.com.pl, 1 +aquagino.nl, 1 +aquaholic.tk, 1 +aquahomo.com, 1 +aquaist.com, 1 +aqualife.com.gr, 1 +aqualifeprojects.com, 1 +aqualysis.nl, 0 +aquamarin.icu, 1 +aquamarinavillas.com, 1 +aquamart.tk, 1 +aquamixing.com, 1 +aquapets.tk, 1 +aquapoint.kiev.ua, 1 +aquarden.com, 1 +aquariawise.com, 1 +aquariu.ms, 1 +aquarium-supplement.net, 1 +aquariumhome.tk, 1 +aquariymist.tk, 1 +aquaselect.eu, 1 +aquastech.in, 1 +aquasun.pl, 1 +aquatherm72.ru, 1 +aquaviaspa.es, 1 +aquavisor.eu, 1 +aquavitaedayspa.com.au, 1 +aquila.co.uk, 1 +aquilaguild.com, 0 +aquiparoxetina.gq, 1 +aquitainebrasserie.com.au, 1 +aquivardenafilo.gq, 1 +aqwire.io, 1 +aqworlds.cf, 1 +ar-android.com, 1 +ar-informatique.ch, 0 +ar-oma.tk, 1 +ar-vernet.fr, 1 +ar.al, 1 +araadvocats.net, 1 +arab.dating, 1 +arab1info.cf, 1 +arabakiralama.name.tr, 1 +arabapps.org, 1 +arabarba7.com, 1 +arabearthcommunity.ml, 1 +arabhardware.net, 1 +arabi-news.ml, 1 +arabi-online.net, 1 +arabia-news.gq, 1 +arabic-shirts.com, 1 +arabicclass.tk, 1 +arabictranslation.tk, 1 +arabicxz.com, 1 +arabmusic.tk, 1 +arabska.tk, 1 +arabskills.tk, 1 +arabwomen.ml, 1 +arachina.com, 1 +arachnida.ml, 1 +arackiralama.name.tr, 1 +aradiantlife.org, 1 +aradiantlyhealthylife.com, 1 +arados.de, 1 +arai21.net, 1 +arakanis.tk, 1 +aral.ml, 1 +araleeniken.com, 1 +araluenvalleyhotel.ga, 1 +aralys.com, 1 +aramido.de, 1 +aramloebmd.com, 1 +aranchhomes.com, 1 +arandomsite.tk, 1 +aranel.me, 1 +aranycsillag.net, 1 +aranym.com, 1 +araqnid.org, 1 +araratour.com, 1 +arargo.cf, 1 +araro.ch, 0 +ararrl.com, 1 +ararrl.net, 1 +ararrl.org, 1 +araseifudousan.com, 1 +aravitor.com, 1 +aravo.com, 1 +arawaza.info, 1 +araxis.com, 1 +araya.ga, 1 +arbaiten.tk, 1 +arbavere.ee, 1 +arbeiten.ga, 1 +arbeitsch.eu, 1 +arbeitskraft.de, 1 +arbeitskreis-asyl-eningen.de, 1 +arbeitslosenverwaltung.de, 1 +arbejdsdag.dk, 1 +arbitrarion.com, 1 +arbitrary.ch, 1 +arbitrazh.tk, 1 +arbobille.es, 1 +arboleda-hurtado.com, 1 +arbolesdenavidad.site, 1 +arborpress.cf, 1 +arboworks.com, 1 +arbu.eu, 0 +arc-relight.com, 1 +arc.run, 1 +arca.info.ro, 1 +arca.live, 1 +arcadeencasa.com, 1 +arcadegame.ga, 1 +arcadegames.com, 1 +arcadia.com.ph, 1 +arcadiaca.gov, 1 +arcaik.net, 1 +arcandadults.org, 1 +arcanefrost.de, 1 +arcanehardware.com, 1 +arcanetides.com, 1 +arcbouncycastles.co.uk, 1 +arcenergy.co.uk, 1 +archaeoadventures.com, 1 +archaeology.lk, 1 +archambault.paris, 1 +archangelbio.com, 1 +archauthority.com, 1 +archbishop.ga, 1 +archeologicatoscana.it, 1 +archeologiegorinchem.com, 1 +archerconsulting.llc, 1 +archerlong.com, 1 +archerlongx.com, 1 +archerxlong.com, 1 +archframe.net, 1 +archi.net.tw, 1 +archief-ocmwgent.be, 1 +archim.org.uk, 1 +archimedicx.com, 1 +archina.ir, 1 +archined.nl, 1 +archipaedia.org, 1 +archispace.com.cn, 1 +archit.in, 1 +architectryan.com, 1 +architectsecurity.org, 1 +architecturaldesignschool.com, 1 +architecture-colleges.com, 1 +architectureblog.ml, 1 +architectus.ga, 1 +architekten.tk, 1 +architektur.ga, 1 +architektur.tk, 1 +architekturwiki.tk, 1 +archival-services.gov.ge, 1 +archive.gov.ge, 1 +archivero.es, 1 +archives.cf, 1 +archives.gov, 1 +archivesdelavieordinaire.ch, 1 +archivestesting.tk, 1 +archivium.biz, 1 +archivosstl.com, 1 +archiweb.pl, 0 +archlinux.de, 1 +archlinux.org, 1 +archlinuxcn.org, 1 +archmacro.ga, 1 +archmediamarketing.com, 1 +archmirror.it, 1 +archoit.org, 0 +archsec.info, 1 +archwaypromotions.com, 1 +archwomen.org, 1 +arcinapoli.it, 1 +arcj.es, 1 +arckr.com, 1 +arclookup.com, 1 +arco.lu, 1 +arcobalabs.ca, 1 +arcogb.co, 1 +arcoiriscastellon.tk, 1 +arcopay.io, 1 +arcosdelallana.tk, 1 +arcosdequejana.com, 1 +arcovix.com, 1 +arcsar.eu, 1 +arcskoru.com, 1 +arcthelad.com, 1 +arctic.ca, 1 +arctica.io, 0 +arcticwolf.com, 1 +arctus-security.com, 1 +arcueil-cachan.fr, 0 +arcza.com, 1 +arcza.net, 1 +ardabil.tk, 1 +ardakannews.tk, 1 +ardania.de, 1 +arditech.ml, 1 +ardor.noip.me, 1 +ardtrade.ru, 1 +are-you-experienced.tk, 1 +area.ge, 1 +area21.ga, 1 +area3.org, 1 +area4pro.com, 1 +areacinquentaeum.tk, 1 +areaclienti.net, 0 +areafiftylan.nl, 1 +areallyneatwebsite.com, 1 +areata.tk, 1 +areatrend.com, 1 +arefidgetspinnersgay.com, 1 +areis.pt, 1 +arekatieandchrisgettingmarried.com, 1 +arekatieandchrisgettingmarried.today, 1 +arekatieandchrismarriedyet.com, 1 +areminder.co, 1 +arena-lemgo.de, 1 +arena-news.tk, 1 +arenadagon.tk, 1 +arenas-architecte.com, 1 +arenatennis.ga, 1 +arenda-bez-agenta.ml, 1 +arenda247.by, 0 +arendabotov.tk, 1 +arendadoma.tk, 1 +arendaskuterov.cf, 1 +arendburgers.nl, 1 +arenlor.com, 1 +arenlor.info, 1 +arenns.com, 1 +arenzanaphotography.com, 1 +areqgaming.com, 1 +ares-trading.de, 1 +aresproject.org, 1 +arest.web.id, 1 +arete.net, 1 +arex-corp.com, 1 +areyoubaroque.com, 1 +arfad.ch, 0 +arforingenieria.com, 1 +arg.zone, 1 +argama-nature.com, 1 +arganaderm.ch, 0 +arganwinkel.nl, 1 +argb.de, 1 +argekultur.at, 1 +argentinachat.tk, 1 +argentinatrabaja.org, 1 +argentinaxp.com, 1 +argentumonline.tk, 1 +argh.io, 1 +argon2.online, 1 +argonium.com.au, 1 +argovpay.com, 1 +argovpn.com, 1 +argrafiche.it, 1 +argumentative-essay.gq, 1 +argyrakis.gr, 1 +arheh.com, 1 +arhipka.tk, 1 +arhitekti.hr, 1 +aria.be, 1 +aria2.cf, 1 +ariacreations.net, 1 +ariadermspa.com, 1 +ariag.tk, 1 +ariajourney.com, 1 +ariamag.com, 1 +ariamovie.xyz, 1 +arian.io, 1 +ariana.wtf, 1 +arianagrande.pro, 1 +arias.re, 1 +ariashii.tk, 1 +ariba.info, 1 +aridhia.com, 1 +aridhia.io, 1 +ariege-pyrenees.net, 1 +arielasher.cf, 1 +ariellefrioza.com, 1 +arielpereira.tk, 1 +ariens.com, 1 +ariensco.com, 1 +arienscohospitality.com, 1 +ariensfoundation.org, 1 +arieswdd.com, 1 +arifburhan.online, 1 +arifp.me, 1 +arifpurnama.my.id, 0 +arigato-java.download, 1 +arihunt.com.au, 1 +arijitdg.net, 1 +arilto.com, 1 +arima.co.ke, 1 +arimarie.com, 1 +arina.is, 1 +arinde.ee, 1 +arinflatablefun.co.uk, 1 +arionta.com, 1 +aripiprazolee.gq, 1 +arirabinowitz.com, 1 +arise19.com, 1 +arisechurch.com, 1 +ariseconference.org.nz, 1 +arisevendor.net, 1 +aristocrates.co, 1 +aristokratia.tk, 1 +ariston-center.gq, 1 +aristotle.tk, 1 +aritec-la.com, 1 +arithmetic.ga, 1 +aritmetic.com, 1 +arivo.com.br, 1 +ariyaoil.ir, 1 +arizonaautomobileclub.com, 1 +arizonabondedtitle.com, 1 +arjan.nl, 1 +arjandejong.eu, 1 +arjanenthijs.nl, 1 +arjansteevels.nl, 1 +arjanvaartjes.net, 1 +arjasmaa.fi, 1 +arjunasdaughter.pub, 1 +arjweb.co.uk, 1 +arkacrao.org, 1 +arkadelphia.gov, 1 +arkadian.tk, 1 +arkadiyt.com, 1 +arkaic.dyndns.org, 1 +arkantos.agency, 1 +arkenco.cl, 1 +arkenstone.ml, 1 +arkfoundationrepair.com, 1 +arkhamasylum.tk, 1 +arkhangelsk.cf, 1 +arkhangelsk.gq, 1 +arkhangelsk.tk, 1 +arkhvoid.com, 1 +arkhvoid.xyz, 1 +arkitextonico.com, 1 +arknights.work, 0 +arknodejs.com, 1 +arkrowd.eu.com, 1 +arksan.com.tr, 1 +arktalentsolutions.com.mx, 1 +arkulagunak.com, 0 +arlaperu.com, 1 +arlatools.com, 1 +arlecchinobuongustaio.it, 1 +arlen.tv, 1 +arlenarmageddon.com, 1 +arlenitas.com, 1 +arletalibrary.com, 0 +arlingtonelectric.com, 1 +arm.gov, 1 +armacom.tk, 1 +armadale.wa.gov.au, 1 +armadalelearningpathways.co.uk, 1 +armadaquadrat.com, 1 +armado.tk, 1 +armageddonclan.tk, 1 +armanddesign.com, 1 +armanddesign.nl, 1 +armandmusic.nl, 1 +armandocorazones.tk, 1 +armandsdiscount.com, 1 +armanozak.com, 1 +armansazehradis.com, 1 +armaringross.com, 1 +armarinhovirtual.com.br, 1 +armazemdaminiatura.com.br, 1 +armazemdeminasmg.com.br, 1 +armazemwarenhaus.com.br, 1 +armbrust.me, 1 +armcar.ga, 1 +armchess.tk, 1 +armedpoet.com, 1 +armenians.online, 1 +armeniaweb.tk, 1 +armeo.top, 1 +armfilm.co, 1 +armhistory.tk, 1 +armil.it, 1 +armin-cme.de, 1 +arminc.tk, 1 +arminpech.de, 1 +arminreiter.com, 1 +armleads.com, 0 +armo.re, 1 +armodobrasil.com.br, 1 +armoedebeleidgent.be, 1 +armor.ai, 1 +armorsoft.fr, 1 +armourroofinc.com, 1 +armpads.nl, 1 +armstrongsengineering.com, 1 +armtopnews.tk, 1 +army24.cz, 1 +armycyberchallenge.xyz, 1 +armyholidays.com.au, 1 +armyprodej.cz, 1 +armyrtf.com.au, 1 +armywear.ga, 1 +arn0.cc, 1 +arn0.org, 1 +arnakdanielian.com, 1 +arnamur.be, 1 +arnaqueoufiable.com, 1 +arnaudardans.com, 1 +arnaudb.net, 1 +arnaudfeld.de, 1 +arnaudlanna.com, 1 +arnaudminable.net, 1 +arnesegers.be, 1 +arnevankauter.com, 0 +arniescastles.co.uk, 1 +arno-klein.com, 1 +arno-klein.de, 1 +arno-klein.eu, 1 +arno-klein.fr, 1 +arno-klein.it, 1 +arno-klein.net, 1 +arno.digital, 1 +arno.pm, 1 +arnoklein.eu, 1 +arnoklein.fr, 1 +arnoklein.it, 1 +arnold-schwarzenegger.tk, 1 +arnoldkontz-occasions.lu, 0 +arnonerba.com, 1 +arnor.org, 1 +arnottindustries.ga, 1 +arnoudraeven.nl, 1 +arnoudvandalen.nl, 1 +arnove.fr, 1 +arnove.net, 1 +arnoweterings.nl, 1 +arnsmedia.nl, 0 +arny.ru, 1 +arobaz-informatique.org, 1 +arockets.ru, 1 +arod.tk, 1 +arogov.com, 1 +arokha.com, 1 +aromachat.eu, 1 +aromacos.ch, 1 +aromaimportado.com.br, 1 +aromateque.com.ua, 1 +aromatlas.com, 1 +aromex.ml, 1 +aron.host, 1 +aroncull.de, 1 +aronraes.be, 1 +aroonchande.com, 0 +arooshi.website, 1 +aros.pl, 1 +arose.io, 1 +around-cms.de, 1 +arouparia.com, 1 +arowsoft.tk, 1 +arox.eu, 1 +arpamip.org, 1 +arpasix.com, 1 +arpasix.email, 1 +arpasix.eu, 1 +arpasix.net, 1 +arpasix.org, 1 +arpnet.co.jp, 1 +arpsel.de, 1 +arqueo-ecuatoriana.ec, 1 +arquidigital.com, 1 +arquipielago.tk, 1 +arquitectura-ilimitada.tk, 1 +arquitet.com.br, 1 +arr-outremont.ca, 1 +arrakis.se, 1 +arrangeyour.com, 1 +arraudi.be, 1 +arraudi.eu, 1 +arrazane.com.br, 1 +arresttracker.com, 1 +arrive.by, 1 +arrive.tokyo, 1 +arrivedconsulting.com, 1 +arrmaforum.com, 1 +arroba.digital, 1 +arrow-api.nl, 1 +arrowduty.ml, 1 +arrowfastener.com, 1 +arrowgrove.com, 0 +arrowheadaddict.com, 1 +arrowit.net, 1 +arroyoins.com, 1 +ars-online.pl, 1 +arsake.cf, 1 +arsalbania.tk, 1 +arschkrebs.org, 1 +arscogitandi.com.pl, 1 +arscogitandi.pl, 1 +arsenal-trans.tk, 1 +arsenalestate.tk, 1 +arsenalzae.com, 1 +arsenideas.ga, 1 +arsenyan.cf, 1 +arshia.cf, 1 +arshispana.com, 1 +arsindecor.com, 1 +arsk1.com, 1 +arslankaynakmetal.com, 1 +arslonga.io, 1 +arsmagazine.tk, 1 +arsplus.ru, 0 +arstudentloanhelp.com, 1 +arswb.men, 1 +art-auction.jp, 1 +art-design.tk, 1 +art-dolls.com.ua, 1 +art-et-culture.ch, 0 +art-et-tonneaux.fr, 1 +art-illustration.tk, 1 +art-khotyn.tk, 1 +art-kuchni.tk, 1 +art-news.tk, 1 +art-okno.com, 1 +art-pix.com, 1 +art-pix.de, 1 +art-pix.net, 1 +art-rca.cf, 1 +art-school.tk, 1 +art-shinbi.com, 1 +art-voronov.tk, 1 +art21tv-armenian.tk, 1 +artacadia.org, 1 +artadagroup.com, 1 +artane.gq, 1 +artbalsam.com, 1 +artboja.com, 1 +artc.at, 1 +artcenter.tk, 1 +artcommunity.tk, 1 +artdeco-photo.com, 0 +artdecoration.tk, 1 +artea.ga, 1 +arteaga.co.uk, 1 +arteaga.eu, 1 +arteaga.me, 1 +arteaga.tech, 1 +arteaga.uk, 1 +arteaga.xyz, 1 +artebel.com.br, 1 +artecat.ch, 1 +artedellavetrina.it, 1 +artedona.com, 1 +arteinstudio.it, 1 +artelignum.tk, 1 +artelista.com, 1 +artelt.com, 1 +artembusiness.tk, 1 +artemida-dot.tk, 1 +artemisgroup.ga, 1 +arteproducciones.tk, 1 +arteq.ga, 1 +artera.spb.ru, 1 +arteriamagazine.tk, 1 +arterienundvenen.ch, 1 +arterydb.ru, 1 +artesacraloreto.it, 1 +artesaniascym.com.ar, 1 +artesaniaselmagodeoz.com, 1 +artesaniastonalaytlaquepaque.com, 1 +arteseideias.com.pt, 1 +arteshesorkh.tk, 1 +arteshow.ch, 0 +artesial.com, 1 +artestetica.tk, 1 +artetculture.tk, 1 +artexhibition.jp, 1 +artextasia.com, 1 +artfabrics.com, 1 +artfullyelegant.com, 1 +artgranit.tk, 1 +arthan.me, 1 +arthermitage.org, 1 +arthousecarousel.co.uk, 1 +arthritisrheumaticdiseases.com, 1 +arthrosis.ml, 1 +arthur.cn, 1 +arthurdejong.org, 1 +arthurdev.cf, 1 +arthurlaw.ca, 1 +arthurlewis.me, 1 +arthurmelo.com, 0 +arthuro.ca, 1 +arthuryidi.com, 1 +arti-group.ml, 1 +arti-islam.tk, 1 +artia.live, 1 +articaexports.com, 1 +articlesplanet.tk, 1 +articlestack.tk, 1 +articlesutiles.cf, 1 +articu.no, 1 +artifact.spb.ru, 1 +artifexnet.com, 1 +artificethefilm.com, 1 +artificial.army, 1 +artificiala.gq, 1 +artificialgrassandlandscaping.com, 1 +artificialplants.tk, 1 +artifuse.ch, 1 +artigianociao.jp, 1 +artigoagency.com, 1 +artigoos.com, 1 +artikel9.com, 1 +artimpact.ch, 1 +artinfo.tk, 1 +artintend.com, 1 +artioml.net, 1 +artionet.ch, 1 +artis-game.net, 1 +artisan-cheminees-poeles-design.fr, 0 +artisanhd.com, 0 +artisans-libres.com, 0 +artisansofsleep.com, 0 +artisansoftaste.com, 1 +artisavotins.com, 1 +artistagenda.com, 1 +artistcorporation.com, 1 +artistedeparis.fr, 1 +artisticedgegranite.net, 0 +artistrunwebsite.com, 1 +artitbe.net, 1 +artiwear.com.tw, 1 +artizlibranza.com, 1 +artj.jp, 1 +artlabdentistry.com, 1 +artlantis.nl, 1 +artleading.ru, 1 +artlifeisgood.com, 1 +artlinestix.com.au, 1 +artlogo.biz, 1 +artlogo.cz, 1 +artlogo.sk, 1 +artmarketingnews.com, 1 +artmaxi.eu, 1 +artmosfilms.co.za, 1 +arto.bg, 1 +artofclouds.ru, 1 +artofcode.co.uk, 1 +artofeyes.nl, 1 +artofhappyliving.com, 1 +artofmonitoring.com, 0 +artofwhere.com, 1 +artozoul.fr, 1 +artplaneta-leto.by, 1 +artprojectsforkids.org, 1 +artransparency.gov, 1 +artrapid.com, 1 +artratio.net, 1 +artrofisio.com.br, 1 +artroot.jp, 1 +artroscopiaperlosport.it, 1 +arts.gov, 1 +artsalon.tk, 1 +artsautomotive.com, 1 +artsbyleila.com, 1 +artschmidtoptical.com, 1 +artsmarket.ca, 1 +artspac.es, 1 +artspark.tk, 1 +arttel-media.ru, 1 +arturgaweda.de, 1 +arturopinto.com.mx, 1 +arturrossa.de, 1 +arturszalak.com, 1 +arturweb.tk, 1 +artvaastu.ru, 1 +artvertising.tk, 1 +artvinhaberleri.tk, 1 +artweby.cz, 1 +artworks.gd, 1 +artworksthatlookgood.com, 0 +artworxbathrooms.com.au, 1 +arty.name, 1 +artycoz.fr, 1 +artyengine.com, 1 +artzphotography.ie, 1 +arubasunsetbeach.com, 1 +arunjoshua.com, 1 +aruo.net, 1 +arveex.eu, 1 +arveron.ch, 0 +arvid.io, 1 +arviksa.co.uk, 1 +arvindhariharan.com, 1 +arvindhariharan.me, 1 +arvutiladu.ee, 1 +arvyncerezo.com, 1 +arw.me, 1 +arweth.com, 1 +arx-libertatis.org, 1 +arx.vg, 1 +arx8x.net, 1 +arxcs.com, 1 +aryabusines.com, 1 +aryacollege.me, 1 +aryalaroca.de, 1 +aryan-nation.com, 1 +aryani-fitriana.tk, 1 +aryankhera.xyz, 1 +aryasenna.net, 1 +arytmicznie.pl, 1 +arzid.com, 1 +arzinfo.pw, 1 +arztpraxis-kubalok.de, 1 +as-kapmea-mark-swissbear.azurewebsites.net, 1 +as200753.com, 1 +as200753.net, 1 +as204982.net, 1 +as397.com, 1 +as41073.net, 1 +as41405.net, 1 +as44222.net, 0 +as5158.com, 1 +as8423.net, 1 +asaabforever.com, 1 +asaacai.com.br, 1 +asabacortoscaseros.tk, 1 +asadatec.de, 1 +asaduddinowaisi.tk, 1 +asafaweb.com, 1 +asafilm.co, 1 +asafomba.com, 1 +asakoh.co.jp, 1 +asana.biz, 1 +asana.com, 1 +asana.plus, 1 +asananutrition.co.uk, 1 +asancharge.tk, 1 +asandu.eu, 1 +asanger.biz, 1 +asankomara.tk, 1 +asansol.tk, 1 +asantosdev.com, 1 +asanuma-clinic.jp, 1 +asaphomeinspect.com, 1 +asart.bg, 1 +asasesoria.cl, 1 +asato-jewelry.com, 1 +asbestos-awareness.ml, 1 +asbestosthedarkarts.com, 1 +asbito.de, 1 +ascamso.com, 1 +ascannes-non-officiel.tk, 1 +ascar.us, 1 +ascension.run, 1 +ascensori.biz, 1 +ascent360.com, 1 +ascgathering.com, 1 +aschismatic.com, 1 +asciitable.tips, 1 +asciiwwdc.com, 1 +ascolympia.nl, 1 +ascormovies.com, 1 +ascpaphilatelie.eu, 1 +asd.gov.au, 0 +asdainfomanager.co.uk, 1 +asdchieti.tk, 1 +asdesk.nl, 1 +asdf.one, 1 +asdunumerique.fr, 1 +asdwfwqd.com, 1 +asdyx.de, 1 +asean-wen.org, 1 +asec01.net, 1 +asecus.ch, 1 +asegem.es, 1 +aseith.com, 1 +aseko.gr, 0 +aselectionoffice.gov, 1 +asenno.com, 1 +aseoblog.com, 1 +aserbx.ga, 1 +aserver.co, 1 +asesoramientosolay.es, 1 +asesoriavalledor.es, 1 +asexualitat.cat, 1 +asfaleianet.gr, 1 +asg-egy.com, 1 +asgapps.co.za, 1 +asgardsuper.com, 1 +asgrd.org, 1 +ashastalent.com, 0 +ashd1.goip.de, 1 +ashd2.goip.de, 1 +ashd3.goip.de, 1 +ashdodisrael.com, 1 +ashenm.ml, 1 +asher.cloud, 1 +asher.tools, 1 +ashessin.com, 1 +ashevillemenshealth.com, 1 +ashimwe.com, 1 +ashlarimoveis.com.br, 1 +ashley.net.in, 1 +ashleyadum.com, 1 +ashleyashbee.com, 0 +ashleyedisonuk.com, 1 +ashleyfoley.photography, 1 +ashleykaryl.com, 1 +ashleymadison.com, 1 +ashleynicholsboudoir.com, 1 +ashleythouret.com, 1 +ashlocklawgroup.com, 1 +ashmportfolio.com, 1 +ashridgetrees.co.uk, 1 +ashtonbromleyceramics.co.uk, 1 +ashtonc.ca, 1 +ashtonwealth.com, 1 +ashutoshmishra.org, 1 +ashutov.rocks, 1 +ashwainfo.in, 1 +asia-gazette.com, 1 +asia-global-risk.com, 1 +asia.dating, 1 +asiacommerce.id, 1 +asiaflash.com, 1 +asiafood-curator.com, 1 +asiagate.ga, 1 +asiaheavens.com, 1 +asialeonding.at, 1 +asialivenewscafe.gq, 1 +asian-archi.com.tw, 1 +asian-industry.eu, 1 +asian-sirens.net, 1 +asianbusinesscards.com, 1 +asiandubfoundation.tk, 1 +asianet.tk, 1 +asianodor.com, 1 +asianspa.co.uk, 1 +asianwebcams.webcam, 1 +asiaproductsdirect.tk, 1 +asiasmi.tk, 1 +asiaticas.cf, 1 +asiaview.ml, 1 +asiaview.tk, 1 +asiba.com.au, 1 +asiesvenezuela.com, 1 +asiinc-tex.com, 1 +asikqq.id, 1 +asile-colis.fr, 1 +asilo.roma.it, 1 +asinetasima.com, 1 +asisee.co.il, 1 +asistencialegal.tk, 1 +asitanc.com, 1 +asitanc.cz, 1 +ask-thenutritionist.com, 1 +ask.fi, 1 +ask.stg.fedoraproject.org, 1 +ask1.org, 1 +askapkmod.com, 1 +askawayhealth.org, 1 +askbonus.com, 1 +askcaisse.com, 1 +askcascade.com, 1 +asker-massasje.no, 1 +askerweb.cf, 1 +askeustache.com, 1 +askexpert.in, 0 +askhow.co.il, 1 +askingmonkey.com, 1 +askizzy.org.au, 1 +askkaren.gov, 1 +askmagicconch.com, 0 +askme-events.vip, 0 +askme-fast.tk, 1 +askme24.de, 1 +askmetutoring.com, 1 +askmetutoring.org, 1 +asko.ee, 1 +asktanzania.com, 1 +askvg.com, 1 +askwhy.cz, 1 +askwhy.eu, 1 +asla.info, 1 +aslamazyan.tk, 1 +aslinfinity.com, 1 +asm.io, 1 +asm802.com, 1 +asm802.es, 1 +asmbsurvey.com, 1 +asmdz.com, 1 +asmeets.nl, 1 +asmm.cc, 0 +asmood.net, 1 +asmui.ml, 1 +asmuncandle.com, 1 +asngear.biz, 1 +asniereslesdijon.fr, 1 +asoagroca.com, 1 +asoccu.ga, 1 +asocedune.com, 1 +asokan.org, 1 +asonaderi2002.tk, 1 +asoul.tw, 1 +asoziales-netzwerk.net, 1 +asoziales-wiki.de, 1 +asp.net, 1 +aspatrimoine.com, 0 +aspcl.ch, 1 +aspectcontext.com, 1 +aspectuw.com.au, 1 +aspenrealestate.com, 1 +asperatechnology.com, 1 +asperatechnology.cz, 1 +asperatechnology.de, 1 +asperox.com.tr, 1 +asperti.com, 1 +aspformacion.com, 1 +asphaltfruehling.de, 1 +asphyxia.su, 1 +aspiechattr.me, 1 +aspiescentral.com, 1 +aspiradorasbaratas.net, 1 +aspirantum.com, 1 +aspiraplasticsurgery.com, 1 +aspirateur-anti-pollution.fr, 1 +aspire-irb.com, 1 +aspires.co.jp, 1 +aspirestore.co.uk, 1 +aspireuniversal.com, 1 +aspirevc-prod.com, 1 +aspirevc.com, 1 +aspisdata.com, 1 +asprion.org, 1 +asprobet.com, 1 +asproni.it, 1 +asps.biz, 1 +aspviress.gq, 1 +asr.cloud, 1 +asr.li, 1 +asr.rocks, 1 +asr.solar, 1 +asr9k.de, 1 +asra.gr, 1 +asral7.com, 1 +asriyatno.tk, 1 +asrob.eu, 0 +assaabloygaragedoors.ca, 1 +assamtenders.gov.in, 1 +assana.dk, 1 +assars.se, 1 +assassinasian.tk, 1 +assdecoeur.org, 1 +assedo.tk, 1 +asseenfromthesidecar.org, 1 +assemblage.gq, 1 +assemble-together.org, 1 +assemblee-copropriete.fr, 1 +assemblywithoutthewalls.org, 1 +assentooriginal.com.br, 1 +assertion.de, 1 +assessoriati.com.br, 1 +assessorindie.tk, 1 +assetbacked.capital, 0 +assetsec.io, 1 +assetsman-assetsvalue.com, 1 +assettocorsa.tk, 1 +assetvault.co.za, 1 +assguidesporrentruy.ch, 0 +assid.com, 1 +assign-it.co.uk, 1 +assignacii.ml, 1 +assignmentshelp.co.ke, 1 +assikerujked.tk, 1 +assinecontrole4g.com.br, 0 +assis.partners, 1 +assistance-personnes-agees.ch, 1 +assistel.com, 1 +assistenzaferrodastiro.org, 1 +assistenzafrigorifero.org, 1 +assistenzamicroonde.org, 1 +assisteu.eu, 1 +associate.today, 1 +associatedwomenshealthcare.com, 1 +associationguillaume.com, 1 +associationhorizon.tk, 1 +associazionerimborsi.it, 1 +assodigitale.it, 1 +assomydesk.fr, 1 +asspinter.me, 1 +asspoop.com, 1 +assta.ga, 1 +assumptionpj.org, 1 +assured.se, 1 +assuredspc.com, 1 +asta-bar.de, 0 +astana.cf, 1 +astanainform.tk, 1 +astanakz.tk, 1 +astaninki.com, 1 +astaoffshore.com.au, 1 +astarbouncycastles.co.uk, 1 +astarforu.com, 1 +astarfrommosul.cf, 1 +astarmathsandphysics.com, 1 +astateoftrance.tk, 1 +astaxanthin-sport.de, 1 +astaxanthin.de, 1 +asteelflash.com, 1 +astellaria.ee, 1 +astengox.com, 1 +astenotarili.online, 0 +astenretail.com, 1 +asteq.com.ar, 1 +asterix-obelix.ga, 1 +astha.fr, 1 +asthenisusa.com, 1 +asthma-explained.com, 1 +astiamministrazioni.it, 1 +asticon.de, 1 +astifan.online, 1 +astigmatic.gq, 1 +astormueble.tk, 1 +astraalivankila.net, 0 +astrakhan-gorod.ga, 1 +astrakhan.cf, 1 +astrakhan.ga, 1 +astrakhan.gq, 1 +astrakhan.ml, 1 +astrakhan.tk, 1 +astral-imperium.com, 1 +astral.com.ar, 1 +astral.gq, 1 +astral.org.pl, 1 +astralyx.net, 1 +astrath.net, 1 +astrea-voetbal-groningen.nl, 1 +astro4u.tk, 1 +astrociencia.tk, 1 +astrodog.com.au, 1 +astrogate.tk, 1 +astrogift.cf, 1 +astrogift.ga, 1 +astrogift.gq, 1 +astrogift.ml, 1 +astrogift.tk, 1 +astrograph.io, 1 +astrojunkies.com, 1 +astrolab.tk, 1 +astroloeches.tk, 1 +astrologiatarocchi.tk, 1 +astrologic.cf, 1 +astrologie12.tk, 1 +astrologjia.com, 1 +astrology-for-beginners.com, 1 +astrology.stream, 1 +astrology42.com, 1 +astrologywizard.com, 1 +astrolojiyorumcusu.com, 1 +astroluxe.io, 1 +astrong.pl, 1 +astronomija.cf, 1 +astronomija.tk, 1 +astropar.tk, 1 +astrophena.name, 1 +astroscopy.ch, 0 +astrosnail.pt.eu.org, 1 +astrosoc.ml, 1 +astrostart.tk, 1 +astroteam.tk, 1 +astrovandalistas.cc, 1 +astrumadvies.nl, 1 +astsummer.tk, 1 +astucedirecte.tk, 1 +astucewebmaster.com, 1 +astuna.de, 1 +astural.org, 0 +astutr.co, 1 +astyork.com, 1 +asua.ca, 1 +asuclassfinder.com, 1 +asucrews.com, 1 +asukalangley.tk, 1 +asun.co, 1 +asurbernardo.com, 1 +asurepay.cc, 0 +asurgiant.ca, 1 +asustreiber.de, 1 +asvsa.ch, 0 +aswakbladi.com, 1 +asws.nl, 1 +asyikbelanja.com, 1 +asylbarn.no, 1 +asylinfo.no, 1 +asylumguild.tk, 1 +asynchrono.cf, 1 +asystent-dzierzawy.pl, 1 +aszurkolassport.com, 1 +at-machining.com, 1 +at.md, 1 +at.search.yahoo.com, 0 +at.vg, 1 +at5.nl, 1 +at7s.me, 1 +atab.se, 1 +atabekkoleji.k12.tr, 1 +ataber.pw, 1 +atacadocervejeiro.com.br, 1 +atacadodesandalias.com.br, 1 +atafu-village.tk, 1 +atahualpa.com, 1 +atakac.com, 1 +atallo.com, 1 +atallo.es, 1 +atanas.ch, 1 +atary.tk, 1 +ataton.ch, 0 +atayia.com, 1 +atbwebservices.co.uk, 1 +atc-fr.com, 1 +atc.cuneo.it, 1 +atc.io, 0 +atchleyjazz.com, 1 +atchleyjazz.org, 1 +atchleylab.org, 1 +atcom.cl, 1 +atcreform.gov, 1 +atcstl.org, 1 +atds.ch, 0 +ateamsport.dk, 1 +atease-salon.jp, 1 +atebaa.ga, 1 +atec.pt, 1 +atedificacion.com, 1 +ateli.com, 1 +atelier-coiffure.ch, 0 +atelier-des-apprentissages.com, 1 +atelier-naruby.cz, 1 +atelier-viennois-cannes.fr, 1 +atelieracbaby.com.br, 1 +atelieraphelion.com, 1 +atelierbw.com, 1 +ateliercoquelicot.fr, 1 +atelierdefrancais.ch, 0 +atelierdeloulou.fr, 1 +atelierdesflammesnoires.fr, 1 +atelierfantazie.sk, 1 +atelierhsn.com, 1 +atelierjs.com, 1 +ateliernaruby.cz, 1 +atelierssud.ch, 0 +atelierssud.swiss, 1 +atelierverbeelding.nl, 1 +atenasconservadora.com.br, 1 +atencionbimbo.com, 0 +atendimentodelta.com.br, 0 +ateneucomercialporto.pt, 0 +ateneumontbui.tk, 1 +atenolol25mg.ga, 1 +atenolol50mg.ga, 1 +aterlectric.com, 1 +aterskapa-data.se, 1 +atf.gov, 1 +atfstudios.tk, 1 +atg.soy, 1 +atgoetschel.ch, 0 +atgseed.co.uk, 1 +atgseed.uk, 1 +ath0.org, 0 +atheatac.com, 1 +atheist-faq.com, 1 +atheist-refugees.com, 1 +atheistfrontier.com, 1 +athekiu.com, 1 +athemis.de, 1 +athena-garage.co.uk, 1 +athena-security.net, 1 +athenacle.xyz, 1 +athenainvestmentsystems.com, 1 +athenainvsys.com, 1 +athenainvsys.net, 1 +athenaspark.com, 1 +athenasystems.com, 1 +athenasystems.net, 1 +athenstn.gov, 1 +athensvantours.com, 1 +athensvantours.gr, 1 +atherosense.ga, 1 +athlin.de, 1 +athomedeco.fr, 1 +athorcis.ovh, 1 +athritisexplained.com, 1 +athydro.com, 1 +atide.cf, 1 +atigerseye.com, 1 +atik.kr, 1 +atikokanfht.com, 1 +atikokaninfo.com, 1 +atikokansnoho.com, 1 +atilo.sh, 1 +atinylittle.space, 1 +atis-ars.ru, 1 +atishchenko.com, 1 +atisoft.biz, 1 +atisoft.com.tr, 1 +atisoft.net, 1 +atisoft.net.tr, 1 +atisoft.web.tr, 1 +atisoftwebtasarim.com, 1 +atisoftwebyazilim.com, 1 +ativapsicologia.com.br, 1 +atix.tk, 1 +atizanvip.com, 1 +atk-huolto.com, 1 +atk.me, 1 +atkinshealthcenter.com.au, 1 +atkstore.com, 1 +atl-paas.net, 1 +atlantabethelaci.org, 1 +atlantacustomfab.com, 0 +atlantahealthcare.tk, 1 +atlantareroof.com, 1 +atlanticcitycasino.news, 1 +atlanticcitycasinonews.com, 1 +atlanticdatastream.ca, 1 +atlanticfcu.com, 1 +atlantichomes.com.au, 1 +atlanticmarina.com, 1 +atlanticmenshealth.com, 1 +atlanticomp.pt, 1 +atlanticpediatricortho.com, 1 +atlanticradio.fr, 1 +atlantida-amber.org, 1 +atlantik.ml, 1 +atlantik.tk, 1 +atlantikwall.ga, 1 +atlantischild.hu, 1 +atlantishq.de, 1 +atlantiswaterproofing.com, 1 +atlas-5.site, 1 +atlas-heritage.com, 1 +atlas-multimedia.de, 1 +atlas-staging.ml, 1 +atlasauthority.com, 1 +atlasbrown.com, 1 +atlascloud.cn, 1 +atlascoffeeclub.com, 1 +atlascultural.com, 1 +atlasdev.nl, 1 +atlasdog.org, 1 +atlaso.cz, 1 +atlasone.us, 1 +atlassian.io, 1 +atlassignsandplaques.com, 1 +atlastax.ga, 1 +atlastaxi.eu, 1 +atlaswu.com, 1 +atlcoaters.com, 1 +atletico-guacuano.tk, 1 +atletika.hu, 1 +atlseccon.com, 1 +atm.net, 1 +atmalta.com, 1 +atmelook.com, 1 +atmilanomoda.com, 1 +atmind.nl, 1 +atmmantenimiento.co, 1 +atmmicrowave.com, 1 +atmocdn.com, 1 +atmondigital.com, 0 +atmos.tk, 1 +atmosferno.cf, 1 +atmox.eu, 1 +atmydesk.tech, 1 +atnis.com, 1 +atnteam.tk, 1 +ato4sound.com, 1 +atolm.net, 1 +atom-china.org, 1 +atom.solutions, 1 +atom86.net, 1 +atombase.org, 1 +atomic-bounce.com, 1 +atomic.red, 1 +atomicbounce.co.uk, 1 +atomicheart.tk, 1 +atomichomehealth.com, 1 +atomictag.com, 1 +atomicwallet.io, 1 +atomik.biz, 1 +atomism.com, 1 +atomsdigital.com, 1 +atomsit.site, 1 +aton-ensemble.tk, 1 +atope.art, 1 +atopy-sendai.com, 1 +atorcidabrasileira.com.br, 1 +atoz-union.org, 1 +atozblinds.net, 1 +atozeventrentalsofpa.com, 1 +atplonline.co, 1 +atrafloor.com, 1 +atraining.ru, 1 +atrakcjenaeventy.com.pl, 1 +atrands.com, 1 +atraverscugy.ch, 0 +atrevillot.com, 1 +atriamcoaching.com, 1 +atrias.net, 1 +atrinik.org, 1 +atris-qa.media, 1 +atris.media, 1 +atsoftware.de, 1 +atspeeds.com, 1 +att-lda.pt, 1 +attac.us, 1 +attain.com, 1 +attcleaning.com, 1 +atte.fi, 1 +attendanceondemand.com, 1 +attendantdesign.com, 1 +attendu.cz, 1 +attengo.ga, 1 +attention.horse, 1 +attentionpleats.com.tw, 1 +atthehelmins.com, 1 +atticusblog.com, 1 +attilagyorffy.com, 1 +attilavandervelde.nl, 1 +attinderdhillon.com, 1 +attiremr.tk, 1 +attitudes-bureaux.fr, 1 +attlane.fr, 1 +attoch.org, 1 +attogtech.com, 1 +attorneystrialgroup.com, 1 +attosoft.tk, 1 +attractant.com, 1 +attractieparken.tk, 1 +attuned.se, 1 +attunedstore.com, 1 +attwood.org, 1 +attwoodmarshall.com.au, 1 +atuendomr.com, 1 +atunel.tk, 1 +atviras.lt, 0 +atvirtual.at, 1 +atvsafety.gov, 1 +atwar-mod.com, 1 +atwonline.org, 1 +atxchirocoverage.com, 1 +atxtraumatherapycenter.com, 1 +atyourleisureculinary.com, 1 +atyourprice.net, 1 +atypicom.es, 1 +atypicom.fr, 1 +atypicom.it, 1 +atypicom.pt, 1 +atyuan.me, 1 +atzenchefin.de, 1 +atzzz.com, 1 +au-be.net, 1 +au2pb.net, 1 +au2pb.org, 1 +aube.kr, 1 +aubepine-restaurant.com, 1 +aubergegilly.ch, 0 +aubg.org, 0 +aubio.org, 1 +aubonheurdeshuiles.fr, 1 +aubonmanger.fr, 0 +auburn-housekeeper.com, 1 +auburnmedicalservices.com, 1 +auburnperio.com, 1 +aucarresainteloi.com, 1 +aucielrose.com, 1 +aucklandcastles.co.uk, 1 +aucospa.com, 1 +auctionbv.tk, 1 +aucubin.de, 0 +aude-mdb-hypnose.fr, 1 +audian.com, 1 +audiclubbahrain.com, 1 +audiencedefolie.com, 1 +audiense.com, 0 +audio-detector.com, 1 +audioblackmagic.com, 1 +audiobookboo.com, 1 +audiobookstudio.com, 1 +audioboom.com, 1 +audioboomers.ga, 1 +audiocd.tk, 1 +audioconspiracy.tk, 1 +audiofrases.com, 1 +audiohub.com, 1 +audiohub.de, 1 +audiohub.fr, 1 +audiolibri.org, 1 +audiologiasinfronteras.com, 1 +audiolot.com, 1 +audiomaze.com, 1 +audiomedica.com, 1 +audiomind.tk, 1 +audiomir.tk, 1 +audion.cc, 1 +audionames.com, 1 +audionamix.com, 1 +audionpack.de, 1 +audioonly.stream, 1 +audiophile.ch, 0 +audiophix.com, 1 +audiorecording.me, 1 +audiorental.net, 1 +audioschoolonline.com, 1 +audiotrace.tk, 1 +audiovisualmurciano.tk, 1 +audiovoodoo.pl, 0 +audirsq3.de, 1 +audisto.com, 1 +audit.ovh, 1 +audite.de, 1 +auditingfirm.tk, 1 +audition-radio.tk, 1 +auditmatrix.com, 1 +auditore-host.tk, 1 +auditos.com, 1 +auditsquare.com, 1 +audrak.com, 1 +audreyhossepian.fr, 1 +audreyjudson.com, 1 +auenhof-agrar.de, 1 +auerbach-verlag.de, 1 +auf-feindgebiet.de, 1 +auf-nach-mallorca.info, 1 +aufmerksamkeitsstudie.com, 1 +aufprise.de, 1 +aufwecken.dynu.net, 1 +augehost.com, 1 +augen-seite.de, 1 +augenlaser-chemnitz.de, 1 +augenlaser-dresden.de, 1 +augenlasercenter-dresden.de, 1 +augenlaserzentrum-dresden.com, 1 +augenlaserzentrum-dresden.de, 1 +augenlaserzentrum-dresden.eu, 1 +augesen.tk, 1 +augix.net, 1 +augmentable.de, 0 +augmentationx.io, 1 +augmentin.ga, 1 +augmentin.gq, 1 +augmentines600.ga, 1 +augredutemps.ca, 1 +augur.us, 1 +august-don.site, 1 +august-hoegn.tk, 1 +augustanews.tk, 1 +augustian-life.cz, 1 +augustiner-kantorei-erfurt.de, 1 +augustiner-kantorei.de, 1 +auify.xyz, 1 +auk.hopto.org, 1 +aukanaw.tk, 1 +aukaraoke.su, 1 +aukcioon-domenov.cf, 1 +aukcioon-domenov.gq, 1 +aukcioon-domenov.ml, 1 +auksel.net, 1 +auksnest.ca, 1 +aulaschrank.gq, 1 +aulasprofdanilo.com.br, 1 +aulasvirtualesperu.com, 1 +aulaweb.co, 1 +aulica-conseil.com, 1 +aumentada.net, 1 +aumilieudumonde.gf, 1 +aumisc.com, 1 +aunali1.com, 1 +auntie-eileens.com.au, 1 +auntiesnorkel.com, 1 +auntmia.com, 1 +aunto.xyz, 1 +auntodev.com, 1 +aupaysdesanes.com, 1 +auplidespages.fr, 1 +aur.rocks, 1 +aura7chakr.com, 1 +auralinna.blog, 1 +aurbrowser.tk, 1 +aurea.bg, 1 +aurelieburn.fr, 1 +aurelienaltarriba.fr, 1 +aureus.pw, 1 +auricblue.com, 1 +aurika.ag, 1 +auriko-games.de, 1 +aurnik.com, 1 +aurora403.com, 1 +auroraassociationofrealtors.com, 1 +auroraofficefurniture.com.au, 1 +aurorarecordings.com, 1 +aurorasa-coaching.com, 1 +aurorasa.com, 1 +ausbildungskredit.info, 1 +auscanalliancecorp.com, 1 +auscube.tk, 1 +ausec.ch, 0 +auskunftsbegehren.at, 1 +ausmwoid.de, 1 +auspicacious.org, 1 +ausschreibungen-suedtirol.it, 1 +aussiefunadvisor.com, 1 +aussiemilfs.com, 1 +aussieparrotlets.com.au, 1 +aussieseo.com.au, 1 +aussieseoadelaide.com.au, 1 +aussieseobrisbane.com.au, 1 +aussieservicedown.com, 1 +aussiestoresonline.com, 1 +aussiestories.dk, 1 +austenplumbing.com, 1 +austin-pearce.com, 1 +austin-security-cameras.com, 1 +austinbestdjs.com, 1 +austincardiac.com, 1 +austinchase.com, 1 +austinheap.com, 0 +austinlockout.com, 1 +austinmobilestorage.com, 1 +austinsutphin.com, 1 +austintxacrepairtoday.com, 1 +austinuniversityhouse.com, 1 +australiadaily.ga, 1 +australian.dating, 1 +australian.tk, 1 +australianairbrushedtattoos.com, 1 +australianairbrushedtattoos.com.au, 1 +australianallnaturalskincare.com.au, 1 +australianattractions.com.au, 1 +australiancattle.dog, 1 +australianhimalayanfoundation.org.au, 1 +australianhomemade.com, 1 +australianimmigrationadvisors.com.au, 1 +australianonlineappliances.ga, 1 +australianpropertyanalytics.ga, 1 +australiantemporarytattoos.com, 1 +australiantemporarytattoos.com.au, 1 +australien-tipps.info, 1 +austriaguide.tk, 1 +austriahikingtours.tk, 1 +austriantekken.tk, 1 +austriatravel.tk, 1 +austromorph.space, 1 +auszeit-lanzarote.com, 1 +auszeit-walsrode.de, 1 +auszeit.bio, 1 +autek.com.br, 1 +autenticismo.tk, 1 +autenticoperfumes.com.br, 1 +auth.adult, 1 +auth.mail.ru, 1 +authanet.ga, 1 +authcom.ca, 1 +authenticate.be, 1 +authenticate.computer, 1 +authenticationhub.io, 1 +authentictrucks.com.br, 1 +authenticwoodcraft.com, 1 +authinfo-bestellen.de, 1 +authinity.com, 1 +authint.com, 1 +authland.com, 1 +author24.biz, 1 +author24.info, 1 +authorise.computer, 1 +authorise.network, 1 +authoritysolutions.com, 1 +authorize.computer, 1 +authorize.network, 1 +authsrv.nl.eu.org, 1 +autism-explained.com, 1 +autismewoerden.nl, 1 +autisten.club, 1 +autizmo.xyz, 1 +auto-anleitung.de, 1 +auto-arsenal.tk, 1 +auto-dealership-news.com, 1 +auto-i-dat.ch, 1 +auto-motor-i-sport.pl, 1 +auto-none.com, 1 +auto-parts-store.tk, 1 +auto-plus.tn, 1 +auto-reklame.tk, 1 +auto-res.ru, 1 +auto-skills.ru, 1 +auto.nl, 1 +auto1.fi, 1 +autoangels.ga, 1 +autoauctionsohio.com, 1 +autoauctionsvirginia.com, 1 +autoaudio.pt, 1 +autobarn.co.nz, 1 +autobazarcentrum.cz, 1 +autobedrijfgarant.nl, 1 +autobella-hurtownia.pl, 1 +autobelle.it, 1 +autobiz.tk, 1 +autoblogs.ml, 1 +autoblok.com.ua, 1 +autobot.com.ua, 1 +autobourcier.com, 1 +autobraga.ru, 1 +autobusiness.ml, 1 +autocadperfmon.azurewebsites.net, 1 +autocartruck.com, 1 +autocashmachine.tk, 1 +autoclassics.com, 1 +autocmall.com, 1 +autocontrol.online, 1 +autocorner.com, 1 +autocross.tk, 1 +autocrossfoto.tk, 1 +autocrossonline.tk, 1 +autocrypt.org, 1 +autodalmacija.com, 1 +autodemolizioni.roma.it, 1 +autodidactic.ai, 1 +autodidacticstudios.com, 1 +autodidacticstudios.net, 1 +autodidacticstudios.org, 1 +autodius.com, 1 +autodocument.tk, 1 +autodynamics.tk, 1 +autoecoledumontblanc.com, 1 +autoelettricaperbambini.com, 1 +autoentrepreneurinfo.com, 1 +autoepc.ro, 1 +autoexprez.com, 1 +autofficina.roma.it, 1 +autofinancing.ga, 1 +autofolderstekoop.nl, 1 +autogarant.sk, 1 +autogear.ga, 1 +autoglass.com.my, 1 +autohausmf-nord.de, 1 +autohit.ro, 1 +autohomehub.com, 1 +autohunt.ga, 1 +autohut.ca, 1 +autoi.ch, 1 +autoinsurancehavasu.com, 1 +autojur.com.br, 1 +autokasko.tk, 1 +autokeyinaustin.com, 1 +autokeyreplacementsanantonio.com, 1 +autoklub.cz, 1 +autoknife.cf, 1 +autokovrik-diskont.ru, 1 +autokredit.org, 1 +autolatex.cf, 1 +autolawetawroclaw.pl, 1 +autoleaders.gr, 1 +autoledky.sk, 1 +autolet.tk, 1 +autoliga.net.ua, 1 +automaatic.com, 1 +automacity.com, 1 +automat1c.ru, 1 +automatethis.com.au, 1 +automaticgrowth.com, 1 +automationpro.me, 1 +automationsmarthome.com, 1 +automekano.com, 0 +automiata.de, 1 +automir.online, 1 +automobile-gadgets.ru, 1 +automosanto.pt, 1 +automotive.org.ua, 1 +automotivegroup-usedcars.be, 0 +automotivemechanic.org, 0 +automotiveunlimited.net, 1 +automoto-tom.net, 1 +automuovifix.fi, 1 +autonewsreview.com, 1 +autonewssite.com, 1 +autonoleggio.milano.it, 1 +autoone.sk, 1 +autoosijek.com, 1 +autopapa.wien, 1 +autopapo.com.br, 1 +autopark-ost-fichtner.de, 1 +autoparts-for-foreigncars.tk, 1 +autoparts.im, 1 +autoparts.sh, 1 +autoparts.wf, 1 +autopaulito.pt, 1 +autoplus.com.co, 1 +autoportal.tk, 1 +autoprice.info, 0 +autopril.com, 1 +autoprogconsortium.ga, 1 +autoproshouston.com, 1 +autopsyhouston.com, 1 +autorai.nl, 1 +autorama.cf, 1 +autorando.com, 1 +autorefuellings.com, 1 +autorefuellings.ru, 1 +autoreinigung-noack.de, 1 +autorepairinlasvegas.com, 1 +autorepairseattle.com, 1 +autorepguide.com, 1 +autoreply.services, 1 +autorepmans.com, 1 +autoreview.ml, 1 +autorijschool-mydrive.nl, 0 +autorijschooljohanbos.nl, 1 +autorijschoolrichardschut.nl, 1 +autorijschoolstorm.nl, 1 +autos-mertens.com, 1 +autosaan.ro, 1 +autosalesmachine.net, 1 +autoschade-mosman.nl, 1 +autoschadeschreuder.nl, 1 +autoschool.ga, 1 +autoscuola.roma.it, 1 +autosecurityfinance.com, 1 +autoshinka72.ru, 1 +autoshopsolutions.com, 1 +autosiero.nl, 1 +autoskolaplzen.cz, 1 +autosneed.com, 1 +autosolution.tk, 1 +autosprint.tk, 1 +autospurghi.milano.it, 1 +autospurgo.com, 1 +autospurgo.it, 1 +autospurgo.milano.it, 1 +autosrivada.com, 1 +autostock.me, 1 +autostodulky.cz, 1 +autostop-occasions.be, 1 +autostrady.tk, 1 +autostramites.com, 1 +autostramites.com.ar, 1 +autotechschool.com, 0 +autoteplo.org, 1 +autoterminus-used.be, 0 +autotimez.com, 1 +autoto.hr, 1 +autotrac.com.br, 1 +autotransportquoteservices.com, 1 +autotras.com, 1 +autotyreprest.ro, 1 +autouncle.at, 1 +autouncle.co.uk, 1 +autouncle.com, 1 +autouncle.de, 1 +autouncle.dk, 1 +autouncle.fi, 1 +autouncle.fr, 1 +autouncle.it, 1 +autouncle.pl, 1 +autouncle.pt, 1 +autouncle.ro, 1 +autouncle.se, 1 +autoverhuur-tilburg.nl, 0 +autovesti.cf, 1 +autowallpapers.tk, 1 +autowatch.tk, 1 +autowerkstatt-puchheim.de, 1 +autozane.com, 1 +autozaz.ml, 1 +autozuki.com, 1 +autre.cn, 1 +autres-talents.fr, 1 +autshir.com, 1 +auvernet.org, 1 +auvidos.ru, 1 +aux-arts-de-la-table.com, 1 +aux-scape.tk, 1 +auxbrinstresses.fr, 1 +auxessenceselfiques.fr, 1 +auxiliame.com, 1 +auxille.com, 1 +av-th.net, 1 +av-yummy.com, 1 +av01.tv, 1 +av0ndale.de, 1 +av163.cc, 1 +ava-creative.de, 0 +ava-sky.ga, 1 +ava-software.at, 1 +avaaz.org, 1 +avabouncehire.co.uk, 1 +avacariu.me, 1 +avacatossiu.tk, 1 +avaclub.ga, 1 +avaemr-development-environment.ca, 1 +avaeon.com, 1 +avagroup.ga, 1 +available.direct, 1 +availablecastles.com, 1 +avalancha.tk, 1 +avaland.tk, 1 +avalon-ami.tk, 1 +avalon-island.ru, 1 +avalon-rpg.com, 1 +avalon-studios.de, 1 +avalonaardoom.nl, 1 +avalonbelltown.com, 1 +avalondevelopment.tk, 1 +avalontechsv.com, 1 +avalyuan.com, 1 +avamax.cz, 1 +avamax.eu, 1 +avamereatmountainridge.com, 1 +avancen.com, 1 +avanet.com, 1 +avangard-tovar.tk, 1 +avangard.tk, 1 +avanguardia.tk, 1 +avangvpn.ga, 1 +avanovum.de, 1 +avanpost.co, 1 +avantech.it, 1 +avantitualatin.com, 1 +avaralar.tk, 1 +avarcom.tk, 1 +avariya.tk, 1 +avarty.com, 1 +avastantivirus.ro, 1 +avatardiffusion.com, 1 +avatarka.tk, 1 +avatype.ir, 1 +avcafe.ru, 0 +avcilarescort.com, 1 +avclub.com, 1 +avdagic.net, 1 +avdh.top, 0 +ave.zone, 1 +aveapps.com, 0 +aveclunettesoleil.fr, 1 +avedesk.org, 0 +avelinodiaz.gal, 1 +avelux.ru, 1 +avengersonline.ml, 1 +avengersonlinemovie.ga, 1 +avenuedesbebes.com, 1 +avepol.cz, 1 +avepol.eu, 1 +averageinspired.com, 1 +averen.co.uk, 1 +avernis.de, 1 +avertoni.ru, 1 +avestagames.tk, 1 +avestawebbtjanst.se, 0 +avexon.com, 1 +avg.club, 1 +avg7.de, 1 +avgeeksunited.com, 1 +avgindiantech.com, 1 +avhwelding.com, 0 +avi12.com, 0 +avi9526.pp.ua, 1 +aviaphoto.tk, 1 +aviapic.com, 1 +aviapic.eu, 1 +aviapic.fr, 1 +aviapic.info, 1 +aviapic.net, 1 +aviapic.org, 1 +aviareis.tk, 1 +aviasalon.spb.ru, 1 +aviationmilitaire.tk, 1 +aviationonline.tk, 1 +aviations-engineering.tk, 1 +aviationstrategies.aero, 1 +aviationstrategy.aero, 1 +aviationweather.gov, 1 +aviationzone.tk, 1 +aviconverter.tk, 1 +avidmode-dev.com, 1 +avidmode-staging.com, 1 +avidmode.com, 1 +avidthink.com, 0 +avinguard.com, 1 +avinilo.com, 1 +aviokarte.rs, 1 +avionicbooks.tk, 1 +avions.ga, 1 +aviruptribedi.com, 1 +avisbabes.com, 1 +avisofi-credit-immobilier.fr, 1 +avisoshuaraz.tk, 1 +aviteng.cloud, 1 +avito.ooo, 1 +avitus.hu, 1 +avivaplasticsurgery.com, 1 +aviweisfogel.co, 1 +aviweisfogelinfo.org, 1 +avlhostel.com, 1 +avm-multimedia.com, 1 +avmemo.com, 1 +avmoo.com, 1 +avmrc.nl, 1 +avmup.com, 1 +avn-buses.tk, 1 +avnet.ws, 1 +avoandco.com, 1 +avocad.studio, 1 +avocadooo.stream, 1 +avocatcivil.net, 1 +avocatpenal.net, 1 +avocatro.net, 1 +avocode.com, 1 +avodart.ml, 1 +avogel-company.ch, 1 +avogel.ca, 1 +avogel.ch, 1 +avogel.co.uk, 1 +avogel.de, 1 +avogel.es, 1 +avogel.gr, 1 +avogel.ie, 1 +avogel.nl, 1 +avogel.pt, 1 +avogel.si, 1 +avogelusa.com, 1 +avoids-troops.gq, 1 +avoinna24.fi, 1 +avoka.do, 1 +avonlearningcampus.com, 1 +avonture.be, 1 +avonvets.co.uk, 1 +avova.de, 1 +avpres.net, 0 +avptp.org, 1 +avqueen.cn, 0 +avra.co, 1 +avrilshine.tk, 1 +avrora-nov.ru, 1 +avsox.com, 1 +avspot.net, 1 +avtecmedia.com, 0 +avtek.pl, 1 +avticket.ru, 0 +avto-bazar.tk, 1 +avto-signal.ga, 1 +avto-signal.gq, 1 +avto-signal.ml, 1 +avtobania.pro, 1 +avtochip.tk, 1 +avtodoki.tk, 1 +avtodot.tk, 1 +avtoforex.ru, 1 +avtogara-isperih.com, 1 +avtojurist.tk, 1 +avtomaniya.tk, 1 +avtomarket.ru, 1 +avtoobzor.tk, 1 +avtorlab.ru, 1 +avtosept.by, 0 +avtostolica.tk, 1 +avtoucheba.tk, 1 +avtoveles.by, 1 +avtovikup.ml, 1 +avtovokzaly.ru, 1 +avtoyurist.cf, 1 +avtoyurist.ga, 1 +avtoyurist.gq, 1 +avtoyurist.ml, 1 +avtoyurist.tk, 1 +avv.li, 1 +avvaterra.ch, 1 +avvcorda.com, 0 +avvocato.bologna.it, 1 +aw.gov.pl, 1 +aw.net, 1 +awakengr.com, 1 +awakenwow.ga, 1 +awangardaszkola.pl, 1 +awanteverde.tk, 1 +awarenessadvisor.ga, 1 +awaresec.com, 1 +awaresec.no, 1 +awarify.io, 1 +awarify.me, 1 +awaro.net, 1 +awaybot.com, 1 +awaygroundguide.com, 1 +awe130.com, 1 +awebsome.fr, 1 +awedience.tv, 1 +awei.pub, 1 +awersomecreatorfromrussia.tk, 1 +awesome-coconut-software.fr, 1 +awesomebouncycastles.co.uk, 1 +awesomelifedeals.today, 1 +awesomenamegenerator.com, 1 +awesomeness.tk, 1 +awesomesit.es, 0 +awf0.xyz, 1 +awfulsport-news.tk, 1 +awh.ink, 1 +awic.ca, 1 +awinninghabit.com, 1 +awk.tw, 1 +awksolutions.com, 1 +awlgolf.com, 0 +awningcanopyus.com, 1 +awningsaboveus.com, 1 +awningsatlantaga.com, 1 +awningsydney.ga, 1 +awoau.com.au, 1 +awomansplacenj.com, 1 +awsbs.de, 1 +awscloudrecipes.com, 1 +awsl.blog, 1 +awsl.wtf, 1 +awsmdev.de, 1 +awsnuke.com, 1 +awsome-books.co.uk, 1 +awsumchan.org, 1 +awtogid.com, 1 +awxg.com, 1 +awxg.eu.org, 1 +awxg.org, 1 +ax25.org, 1 +axa-middleeast.com, 1 +axa.de, 1 +axamansard.com, 1 +axavalon.tk, 1 +axchap.ir, 1 +axearrow.nl, 1 +axel-fischer.net, 1 +axel-fischer.science, 1 +axel-voss.eu, 0 +axel.red, 1 +axelname.ru, 1 +axelr.me, 1 +axelteichmann.net, 1 +axelvoss.eu, 0 +axin888.vip, 1 +axiodl.com, 1 +axiomeosteopathie.ca, 1 +axiomer.com, 1 +axiomtechnologies.tk, 1 +axios.tk, 1 +axis-of-evil.tk, 1 +axis-stralis.co.uk, 1 +axisdesignarchitects.co.uk, 1 +axisdesignarchitects.com, 1 +axishw.com, 1 +axispara-bg.com, 1 +axom.online, 1 +axon-toumpa.gr, 1 +axoncoho.tk, 1 +axone-computers.fr, 0 +axonholdingse.eu, 1 +axontechnologies.com, 1 +axre.de, 1 +axrec.de, 1 +axton.ink, 0 +axtux.tk, 1 +axxa.one, 1 +axxess-marine.com, 1 +axxis.co.jp, 1 +ay-net.jp, 1 +ayahuasca.info, 1 +ayahya.me, 0 +ayamchikchik.com, 1 +ayanomimi.com, 1 +ayatosuzuki.com, 1 +aycasac.com, 1 +aycomba.de, 1 +aydacosmetics.com, 1 +aydesignco.com, 1 +aye.sh, 1 +ayecode.ca, 1 +ayesh.win, 1 +ayhankaraman.com, 1 +ayj.solutions, 1 +aykonet.de, 1 +aykutcevik.com, 1 +aykyamultifest.com, 1 +aylak.com, 1 +aylesburycastlehire.co.uk, 1 +aymaramusica.com.ar, 1 +aymerick-dupouey.fr, 1 +aymerick.fr, 1 +aymericlagier.com, 1 +ayoka.eu, 1 +ayon-games.tk, 1 +ayon.group, 1 +ayothemes.com, 1 +ayrohq.com, 1 +ayrshirebouncycastlehire.co.uk, 1 +ayselonia.onl, 1 +ayubesportes.com.br, 1 +ayudacloud.com, 1 +ayudalabs.com, 1 +ayudamutua.red, 1 +ayudapreview.com, 1 +ayudaprogramacion.net, 1 +ayumi.network, 1 +ayumindev.net, 1 +ayumix3.xyz, 1 +ayur-veda.tk, 1 +ayurveda-france.com, 1 +ayuwidodari.my.id, 1 +ayvalikgezgini.com, 1 +ayyz66.cc, 1 +az-forum.ga, 1 +az-moga.bg, 1 +az-vinyl-boden.de, 1 +az.net.au, 1 +az.search.yahoo.com, 0 +az11018.com, 1 +azabani.com, 1 +azadliq.info, 1 +azadliq.online, 1 +azaria.blog, 1 +azarus.ch, 1 +azarweb.tk, 1 +azcensus2020.gov, 1 +azerbelarbi.tk, 1 +azeriland.tk, 1 +azerinews.ga, 1 +azerinews.tk, 1 +azeronline.tk, 1 +azertyjobs.com, 1 +azh-kunden.de, 1 +azhamevents.com, 1 +azia.info, 1 +aziatki.tk, 1 +azienda-tv.tk, 1 +azimech.net, 1 +azimut.fr, 1 +azithromycin.ga, 1 +azithromycinbuy.ga, 1 +azithromycine.gq, 1 +azitromicina.gq, 1 +azizfirat.com, 0 +azjlbc.gov, 1 +azl-app.be, 1 +azlink.tk, 1 +azlk-team.ru, 1 +azmabepors.com, 1 +aznaetelivy.ru, 1 +azon.gr, 1 +azoogi.com.au, 1 +azora.cf, 1 +azort.com, 1 +azotobacter.nl, 1 +azoulaygroup.org, 1 +azpogomap.com, 1 +azrangers.gov, 1 +azrazalea.net, 1 +azrhymes.com, 1 +azsgeniedev.azurewebsites.net, 1 +azso.pro, 1 +azsupport.com, 1 +aztraslochi.it, 1 +aztrix.me, 1 +aztummytuck.com, 1 +azu-l.com, 1 +azu-l.jp, 1 +azuki.cloud, 1 +azukie.com, 1 +azula.tk, 1 +azulimparcial.pt, 1 +azur.ovh, 1 +azurecraft.ga, 1 +azurecrimson.com, 1 +azurecup.cz, 1 +azurecup.online, 1 +azurefabric.com, 1 +azuriasky.com, 1 +azuriasky.net, 1 +azuriom.com, 1 +azurlane.cool, 1 +azuxul.fr, 1 +azvpn.tk, 1 +azzaroarancebio.it, 1 +azzorti.com, 1 +azzurrapelletterie.it, 1 +b-angel.info, 1 +b-b-law.com, 1 +b-bam.com, 1 +b-boom.nl, 1 +b-cyclesshop.ch, 0 +b-entropy.com, 1 +b-freerobux.ga, 1 +b-honey.gr, 1 +b-kontur.ru, 1 +b-landia.net, 1 +b-o.de, 1 +b-performance.de, 1 +b-root-force.de, 1 +b-services.net, 0 +b-techflow.com, 1 +b-ticket.ch, 1 +b-tree.be, 1 +b0000.co, 1 +b00228.com, 1 +b00de.ga, 1 +b0305.com, 1 +b0306.com, 1 +b0307.com, 1 +b0309.com, 1 +b03aa.com, 1 +b03bb.com, 1 +b03cc.com, 1 +b0hr.ai, 1 +b0k.org, 1 +b0rk.com, 1 +b0x0.com, 1 +b1111.co, 1 +b131000.com, 1 +b144.co.il, 1 +b1758.com, 1 +b1c1l1.com, 1 +b1nzy-pinged.me, 1 +b1rd.tk, 1 +b2222.co, 1 +b23-tv.tk, 1 +b24.pt, 1 +b2b-leads.nl, 1 +b2b-nestle.com.br, 1 +b2bmail.ga, 1 +b2bmuzikbank.com, 1 +b3.nu, 1 +b303.me, 1 +b30365.com, 0 +b3101.com, 1 +b3103.com, 1 +b31aa.com, 1 +b31cc.com, 1 +b31dd.com, 1 +b31ee.com, 1 +b31ff.com, 1 +b3390.com, 1 +b3391.com, 1 +b3392.com, 1 +b33app.com, 1 +b3collections.com, 1 +b3gin.com, 1 +b3pacific.com, 1 +b422edu.com, 1 +b4a-learn.ir, 1 +b4bouncycastles.co.uk, 1 +b4ckbone.de, 1 +b4lint.hu, 1 +b4r7.de, 1 +b4tech.eu, 0 +b4z.eu, 1 +b5197.co, 1 +b5289.net, 1 +b58365.com, 1 +b58app.com, 1 +b58appb58app.com, 1 +b58appb58appb58app.com, 1 +b5901.com, 1 +b5902.com, 1 +b5903.com, 1 +b5904.com, 1 +b5906.com, 1 +b5907.com, 1 +b5908.com, 1 +b5909.com, 1 +b5910.com, 1 +b5989.com, 1 +b5dev.com, 1 +b61688.com, 1 +b62102.com, 1 +b62103.com, 1 +b62105.com, 1 +b62a.com, 1 +b62aa.com, 1 +b62b.com, 1 +b62bb.com, 1 +b62c.com, 1 +b62cc.com, 1 +b62d.com, 1 +b62dd.com, 1 +b62e.com, 1 +b62ee.com, 1 +b62f.com, 1 +b62g.com, 1 +b62h.com, 1 +b64.club, 1 +b6701.com, 1 +b6703.com, 1 +b6704.com, 1 +b6705.com, 1 +b6720.com, 1 +b6729.co, 1 +b6730.com, 1 +b6740.com, 1 +b6750.com, 1 +b67701.com, 1 +b67702.com, 1 +b67703.com, 1 +b67704.com, 1 +b67705.com, 1 +b67774.com, 1 +b67801.com, 1 +b67802.com, 1 +b67803.com, 1 +b67805.com, 1 +b67881.com, 1 +b67882.com, 1 +b67883.com, 1 +b67884.com, 1 +b67885.com, 1 +b67901.com, 1 +b67902.com, 1 +b67903.com, 1 +b67904.com, 1 +b67905.com, 1 +b6957.co, 1 +b70301.com, 1 +b70302.com, 1 +b70303.com, 1 +b70304.com, 0 +b70305.com, 1 +b70661.com, 1 +b70663.com, 1 +b70664.com, 1 +b70771.com, 1 +b70772.com, 1 +b70773.com, 1 +b70774.com, 1 +b70775.com, 1 +b70884.com, 1 +b70885.com, 1 +b70991.com, 1 +b70992.com, 1 +b70993.com, 1 +b70994.com, 1 +b70995.com, 1 +b72.com, 1 +b72.net, 1 +b7306.com, 1 +b73bb.com, 1 +b73dd.com, 1 +b767.net, 1 +b77018.com, 1 +b789.co, 1 +b81365.com, 1 +b82365.com, 1 +b86255.com, 1 +b8831.com, 1 +b88vip1.com, 1 +b88vip10.com, 1 +b88vip2.com, 1 +b88vip3.com, 1 +b88vip4.com, 1 +b88vip5.com, 1 +b88vip6.com, 1 +b88vip7.com, 1 +b88vip8.com, 1 +b88vip9.com, 1 +b89ff.com, 1 +b89gg.com, 1 +b89hh.com, 1 +b8a.me, 1 +b9168.com, 1 +b91688.com, 1 +b9297.co, 1 +b9498.com, 1 +b9586.net, 1 +b9588.net, 1 +b95888.net, 1 +b9589.net, 1 +b960.com, 1 +b9658.com, 1 +b96899.com, 1 +b9728.co, 1 +b979333.com, 1 +b979555.com, 1 +b979666.com, 1 +b979999.com, 1 +b9883.net, 1 +b9884.net, 1 +b9885.net, 1 +b9886.com, 1 +b9886.net, 1 +b9887.net, 1 +b9888.net, 1 +b98886.com, 1 +b9889.net, 1 +b99011.com, 1 +b99022.com, 1 +b99033.com, 1 +b9904.com, 1 +b99044.com, 1 +b9905.com, 1 +b99055.com, 1 +b99066.com, 1 +b99077.com, 1 +b99088.com, 1 +b99099.com, 1 +b99118.com, 1 +b9912.com, 1 +b99218.com, 1 +b9930.com, 1 +b99318.com, 1 +b99418.com, 1 +b9948.net, 1 +b9951.com, 1 +b99518.com, 1 +b9954.com, 1 +b9957.com, 1 +b9961.com, 1 +b99618.com, 1 +b9962.com, 1 +b9970.com, 1 +b99718.com, 1 +b9973.com, 1 +b9976.com, 1 +b99818.com, 1 +b99881.com, 1 +b99882.com, 1 +b99883.com, 1 +b99885.com, 1 +b99886.com, 1 +b99918.com, 1 +b9999ff.com, 1 +b9999hh.com, 1 +b9999ii.com, 1 +b9999jj.com, 1 +b9999ll.com, 1 +b9999mm.com, 1 +b9999nn.com, 1 +b9999oo.com, 1 +b9999pp.com, 1 +b9999qq.com, 1 +b9999tt.com, 1 +b9999uu.com, 1 +b9999vv.com, 1 +b9999ww.com, 1 +b9999yy.com, 1 +b9999zz.com, 1 +b99iosapp.com, 1 +b9winner.com, 1 +ba47.net, 1 +baac-dewellmed.com, 1 +baalsworld.de, 1 +baanpingchan.com, 0 +baaradvies.nl, 1 +baas-becking.biology.utah.edu, 1 +baazee.de, 1 +babacasino.net, 1 +babacloud.ddns.net, 1 +babacuhocica.tk, 1 +babaei.net, 1 +babaei.org, 1 +babaganousha.net, 1 +babai.ru, 1 +babakhanalia.tk, 1 +babakortane.ga, 1 +babarkata.com, 1 +babaseo.ml, 1 +babayaga-bg.ga, 1 +babbel.tk, 1 +babekids.tk, 1 +babeleo.com, 1 +babelfisch.eu, 1 +babet365.com, 1 +babettelandmesser.de, 1 +babineaux.zone, 1 +babki-mgnovenno.ga, 1 +babkitut.ga, 1 +bablodel.biz, 1 +bablodel.com, 1 +babo.tk, 1 +babounet.com, 1 +babsbibs.com, 1 +babursahvizeofisi.com, 1 +babushkin-mir.tk, 1 +baby-bath-tub.com, 0 +baby-care.ir, 1 +baby-digne.com, 0 +baby-massage.tk, 1 +baby-skin-care.ga, 1 +baby-tester.tk, 1 +babyandchild.ae, 1 +babyappear.com, 1 +babyatacado.com.br, 1 +babyboom.pl, 1 +babybuddah.ga, 1 +babybunnypictures.tk, 1 +babyfotograf-schweiz.ch, 1 +babygearessentials.com, 1 +babygender.info, 1 +babygirlholidaydresses.tk, 1 +babyinthehouse.com.br, 1 +babykappy.com, 1 +babyliss-pro.net, 0 +babylontraffic.com, 1 +babymasaze.cz, 1 +babymozg.ga, 1 +babynames.net, 1 +babypaparadise.com, 0 +babypharm.ga, 1 +babyphototime.com, 1 +babypibu.com, 1 +babyportal.net, 1 +babysdishes-bowls.tk, 1 +babyshoprimini.com, 1 +babyshopsupport.com.au, 1 +babyshower.cf, 1 +babystrollers.ml, 1 +babystudio.es, 1 +babytan.tk, 1 +babyvillagegt.com, 1 +babyzen.tk, 1 +bac-fiches.tk, 1 +bacahorror.com, 1 +bacaneriahlg.com, 1 +bacanora.tk, 1 +bacardi.cf, 1 +bacgrouppublishing.com, 1 +bach-frederiksen.dk, 1 +bachata.info, 1 +bachelorampel.de, 1 +baches-piscines.com, 1 +bachlongbeach.com, 1 +bachmannyachts.com, 1 +bachmatt-baar.ch, 1 +bachomp.net, 1 +bachweid-baar.ch, 1 +baciu.ch, 0 +back-streets.tk, 1 +backbenchersart.com, 1 +backeby.eu, 1 +backenmachtgluecklich.de, 0 +backflow.pl, 1 +background-checks-systems.com, 1 +background-checks.asia, 1 +background-checks.biz, 1 +background-checks.mobi, 1 +background4free.com, 1 +backgroundchecks.online, 1 +backgroundscreenersofamerica.com, 1 +backgroundz.net, 1 +backinstockalerts.com, 1 +backjump.tk, 1 +backlinksgenerator.in, 1 +backlinktr.tk, 1 +backlogapp.io, 1 +backlotgaming.com, 1 +backmitra.com, 1 +backmitra.mx, 1 +backmitra.nl, 1 +backmountaingas.com, 1 +backpacken.org, 1 +backpacker.dating, 1 +backpackinglight.com, 1 +backpackingtours.com, 1 +backporchartists.com, 1 +backscattering.de, 0 +backschues.com, 1 +backschues.de, 1 +backschues.net, 1 +backseatbandits.com, 1 +backsideverbier.ch, 0 +backsliderz.uk, 1 +backspace.dev, 1 +backspace.rocks, 1 +backstienkboys.tk, 1 +backterris.com, 1 +backtest.org, 1 +backtheeffup.com, 1 +backup-kurumsal.com, 1 +backupassist.de, 1 +backupcloud.ru, 1 +backupsinop.com.br, 0 +backwardsalphabet.tk, 1 +bacom1.com, 1 +baconismagic.ca, 0 +bacoux.com, 1 +bacsmegye.hu, 1 +bacteriakit.com, 1 +bactrim-antibiotic.ml, 1 +bactrim-ds.ga, 1 +bactrim-medicine.ml, 1 +bactrim.ga, 1 +bactrim.gq, 1 +bactrimds.cf, 1 +bactrimprice.tk, 1 +bacula.jp, 1 +bad-wurzach.de, 1 +bad.horse, 1 +bad.pet, 1 +bad.spdns.de, 1 +badaa.info, 1 +badam.co, 1 +badanteinfamiglia.it, 1 +badaparda.com, 1 +badass-women.club, 1 +badassfantastico.tk, 1 +badbee.cc, 1 +badbird.tk, 1 +badblock.fr, 1 +badboyzclub.de, 1 +badcreditcarsfinance.co.uk, 1 +badeand.net, 1 +badf00d.de, 1 +badge.rs, 1 +badges.fedoraproject.org, 1 +badges.stg.fedoraproject.org, 1 +badgirlfoto.ga, 1 +badgirlsbible.com, 1 +badhusky.com, 0 +badkamermarkt.be, 1 +badkamermarkt.com, 1 +badkamermarkt.net, 1 +badkamermarkt.nl, 1 +badmessage.tk, 1 +badmice.tk, 1 +badmintonargentina.tk, 1 +badmintonbible.com, 1 +badmintonoverdag.tk, 1 +badmusic.tk, 1 +badnails.tk, 1 +badnjar.rs, 1 +badodds.ga, 1 +badoo.com, 1 +badoo.de, 1 +badoo.eu, 1 +badoo.us, 1 +badpreachers.tk, 1 +badrequest.me, 1 +badrock.tk, 1 +badseacoffee.com, 1 +badstar.tk, 1 +badules.tk, 1 +badwi.com, 1 +baecker-know-how.de, 1 +baeconhills.tk, 1 +baeder-luboss.de, 1 +baehost.com, 1 +baenoticias.com.ar, 1 +baer.one, 1 +baer.space, 1 +bafus.ru, 1 +bafwsprod-bafwsprodnew.azurewebsites.net, 1 +bag.bg, 1 +bag66.ru, 1 +bageez.us, 1 +bagelcraft.net, 1 +bagelsbakery.com, 0 +bageluncle.com, 1 +baggy.me.uk, 1 +bagheera.me.uk, 1 +baghtelecom.net, 1 +bagiobella.com, 1 +bagira.guru, 1 +baglu.com, 0 +bagni-chimici.roma.it, 1 +bagnichimici.milano.it, 1 +bagnichimici.roma.it, 1 +bagoria.by, 1 +bags-ua.com, 1 +bagsofbounce.co.uk, 1 +bagspecialist.nl, 1 +bagssale.ga, 1 +bagwrap.com, 1 +bah.im, 0 +bahadirh.ml, 1 +bahai-rdc.org, 1 +bahaiprayers.io, 1 +bahana.net, 1 +bahiastudios.com, 1 +bahnbonus-praemienwelt.de, 1 +bahnenimbild.de, 1 +bahnenimbild.eu, 1 +bahnhelden.de, 1 +bahninrotweissrot.at, 1 +bahnmagazine.de, 1 +bahrainonline.tk, 1 +bahrep.com, 1 +baidu-s.com, 0 +baiduo.com, 1 +baikal.cf, 1 +baikalfond.ml, 1 +baikalppk.tk, 1 +baildonbouncycastles.co.uk, 1 +baildonhottubs.co.uk, 1 +baileebee.com, 1 +bailonga.com, 1 +baindayman.com, 1 +baircentral.com, 1 +bairrosonline.com, 1 +bairuo.top, 0 +bait55.ru, 1 +baitable.ml, 1 +baitap.net, 0 +baitaplamvan.com, 1 +baitcon.com, 1 +baithe.co.za, 1 +baitulongbaycruises.com, 1 +baity.net, 1 +baixadordemusica.tk, 1 +baixarvideosgratis.com.br, 1 +baiyangliu.com, 1 +bajacalifornia.tk, 1 +bajahealthsolutions.com, 1 +bajarjuegos.com, 1 +bajic.ch, 1 +bajj.de, 1 +bajofondoradio.tk, 1 +baka-gamer.net, 1 +baka.network, 1 +baka.org.cn, 1 +baka.red, 1 +bakabt.info, 1 +bakanin.ru, 1 +bakaproxy.moe, 1 +baker-street.tk, 1 +bakerbasements.com, 1 +bakerranchdentistry.com, 1 +bakersafari.co, 1 +bakersfieldhomeoffer.com, 1 +bakerviewdentalcentre.com, 1 +bakeup.be, 1 +bakibal.com, 1 +bakkerij-janschrieks.nl, 1 +bakkerinjebuurt.be, 1 +bakongcondo.com, 1 +baks.cf, 1 +baksclub.cf, 1 +baksclub.gq, 1 +bakubest.tk, 1 +bakuze.net, 1 +bakxnet.com, 1 +balaam-black.tk, 1 +balade-commune.ch, 0 +baladecommune.ch, 0 +balafon.cloud, 1 +balaganlimited.cf, 1 +balaganoff.tk, 1 +balakovo-news.tk, 1 +balancascia.com.br, 1 +balance.courses, 1 +balance.education, 1 +balance.equipment, 1 +balance.technology, 1 +balance7.jp, 1 +balancedbrawl.net, 1 +balancehits.com.br, 1 +balancenaturalhealthclinic.ca, 1 +balancer.gq, 1 +balanda.ga, 1 +balashiha-podmoskovie.ml, 1 +balasingandaru.cf, 1 +balaskas.gr, 1 +balboa.io, 1 +balboa.org.uk, 1 +balcaonet.com.br, 1 +balcarek.pl, 1 +balconnr.com, 1 +balconsverdun.com, 0 +balcony.cf, 1 +baldvinringsted.com, 1 +baldwin-mania.tk, 1 +baleen.us, 1 +balerma.tk, 1 +balesetvedelem.hu, 1 +balia.de, 1 +balibells.com, 1 +balicekzdravi.cz, 0 +balicyclingtours.id, 1 +baliklar.tk, 1 +balikonos.cz, 1 +balilingo.ooo, 0 +balinese.dating, 1 +balist.es, 1 +balivacationhomes.com, 1 +balivakantiewoning.nl, 1 +balivillassanur.com, 0 +baliwebsitedesign.info, 1 +baliyano.com, 1 +balkanclan.com, 1 +balkancrystals.com, 1 +balkannightlife.ga, 1 +balkanpharmstore.com, 1 +balkanturist.com, 0 +balkenbushmechanical.com, 1 +balkoni.gq, 1 +balkonien.org, 1 +ball-bizarr.de, 1 +ball4training.com, 1 +ballaratcapital.com, 1 +ballaratcapital.com.au, 1 +ballarin.cc, 1 +ballast.tk, 1 +ballbusting-cbt.com, 1 +ballejaune.com, 1 +ballensiefen.net, 1 +ballerkneipe.com, 1 +ballettstudio-ost.de, 1 +ballinw.com, 1 +ballisticbrass.tk, 1 +ballisticdetailing.com, 1 +ballitolocksmith.com, 1 +ballmerpeak.org, 1 +ballon-ballon.de, 1 +ballonella.de, 1 +ballonnenopdakpannen.tk, 1 +ballonsportclub-erlangen.de, 1 +ballotapi.com, 1 +ballothero.com, 1 +ballparkbuns.com, 0 +ballpythonsaspets.com, 1 +ballroom.info, 1 +ballyhacksmokehouse.com, 1 +balmeo.co.uk, 1 +balmofgilead.org.uk, 1 +baloch-intelligence.tk, 1 +baloncestoarqueros.tk, 1 +baloncestolliria.tk, 1 +balonmano.co, 1 +balopal.tk, 1 +balosport.com, 1 +balp.com, 1 +balsallcommonbouncycastles.co.uk, 1 +balsamaiso.es, 1 +balski.com, 1 +balslev.io, 1 +balter.com, 1 +balthazarlondon.com, 1 +balticmed.pl, 1 +balticnetworks.com, 1 +baltimorecashflow.com, 1 +baltimoreroofingservices.com, 1 +bamahammer.com, 1 +bamaland.org, 1 +bamboehof.nl, 1 +bambooforest.nl, 1 +bamboorelay.com, 1 +bambuitalia.it, 1 +bambukshop.ml, 1 +bambumania.com.br, 1 +bambusushibar.com, 0 +bamily.rocks, 1 +bamoza.com, 1 +bampers.tk, 1 +bampizza.com, 1 +bamsmackpow.com, 1 +bamtoki.com, 1 +ban-list.gq, 1 +banajanitorialservices.com, 1 +bananabandy.com, 1 +bananacloud.fr, 0 +banananet.work, 1 +bananathrash.tk, 1 +bananavapes.com, 1 +bananice.moe, 1 +bananium.fr, 1 +bancacrs.it, 1 +bancastato.ch, 1 +bancobai.ao, 1 +bancobpm.it, 1 +bancoctt.pt, 1 +bancodeloja.fin.ec, 1 +bancor.network, 1 +bancosdominicanos.net, 1 +bancoserfinanza.com, 1 +bandally.net, 1 +bandamirandadeebro.tk, 1 +bandarifamily.com, 1 +bandaumnikov.ru, 1 +bandeira1.com.br, 1 +bandeiraimoveisitu.com.br, 1 +bandeirasnacionais.com, 1 +banderas-mundo.es, 1 +banderasdelmundo.xyz, 1 +banderol.tk, 1 +bandiere-mondo.it, 1 +bandiga.it, 1 +bandirmaevdenevenakliyat.tk, 1 +bandito.re, 1 +bandnames.tk, 1 +bandolino-bewind.nl, 1 +bandolino.nl, 1 +bandures.tk, 1 +bandvideos.tk, 1 +bandwagon.tk, 1 +bandymasarna.tk, 1 +baneh-academic.com, 1 +banerka.tk, 1 +banes.ch, 1 +banffcanmorespeedskating.ca, 1 +banfieldtravel.it, 1 +banfun.org, 1 +bangcompras.com, 1 +bangdream.ga, 1 +bangim.co.il, 1 +bangkok-dark-night.com, 1 +bangkok.dating, 1 +bangkokcity.de, 1 +bangkokcookingclass.com, 1 +bangladesimagi.tk, 1 +banglarfont.com, 1 +banglatypography.com, 1 +banglets.com, 1 +bangorfederal.com, 1 +bangujero.tk, 1 +bangun.in, 1 +bangyu.wang, 1 +banham.co.uk, 0 +banham.com, 1 +banja-kulasi.ga, 1 +banjostringiz.com, 1 +bank, 1 +bank-yahav.co.il, 1 +bank.barclays.co.uk, 1 +bank.simple.com, 0 +banka.space, 1 +bankanswers.gov, 1 +bankapp.se, 1 +bankapply.eu, 1 +bankbranchlocator.com, 1 +bankcardoffer.com, 1 +bankcircle.co.in, 1 +bankee.us, 1 +banketbesteld.nl, 1 +bankfreeoffers.com, 1 +bankgradesecurity.com, 1 +bankheadvegetables.com, 1 +bankimsk.cf, 1 +bankin.com, 1 +bankinter.pt, 1 +bankio.se, 1 +bankipmr.ru, 1 +bankitt.network, 1 +bankmoney.cf, 1 +banknet.gov, 1 +banknews.ga, 1 +bankofdenton.com, 1 +bankofireland.com, 1 +bankofrealty.review, 1 +bankpolicies.com, 1 +bankruptcy.ky, 1 +banksaround.com, 1 +banksite.ga, 1 +bankstownapartments.com.au, 1 +bankvanbreda.be, 1 +bankwebinars.com, 1 +banland.net, 1 +banlinhdanong.com, 1 +banned-bitches.tk, 0 +banner-design.tk, 1 +bannermarquees.ie, 1 +bannerworld.co.uk, 1 +banning.gq, 1 +banningca.gov, 1 +bannisbierblog.de, 1 +bannsecurity.com, 1 +banquevanbreda.be, 1 +banri.me, 1 +bantaihost.com, 1 +banter.city, 1 +banterera.com, 1 +bantik.by, 1 +banzay.ml, 1 +banzhuti.com, 1 +baobabgroup.com, 1 +baobaoquming.net, 1 +baocaosuhp.com, 1 +baocheng.tech, 1 +baofuzhuan.com, 1 +baogao.store, 1 +baoge55.com, 1 +baogiathicongnoithat.com, 1 +baogougou.com, 1 +baokhangfood.com, 1 +bapeel.tk, 1 +bapha.be, 1 +baptiste-peugnez.fr, 1 +baptisteplanckaert.tk, 1 +barabrume.fr, 1 +barakayu.com, 1 +barandazstorm.com, 1 +barandazstorm.net, 1 +barandazstorm.org, 1 +baranmovie.tk, 1 +baranyavar.hu, 1 +barao.tk, 1 +barataeletrica.tk, 1 +baravalle.com, 1 +baraxolka.ga, 1 +baraxolka.ml, 1 +baraxolka.ru, 1 +barbaderespeito.com.br, 1 +barbaleonecuador.com, 1 +barbara-fuchs-gruene-fuerth.de, 1 +barbarabowersrealty.com, 1 +barbaraedanielsantos.ga, 1 +barbarafabbri.com, 1 +barbarafeldman.com, 1 +barbarians.com, 0 +barbaros.info, 1 +barbate.fr, 1 +barbe-n-blues.fr, 1 +barberscorner.tk, 1 +barbershop-harmony.org, 0 +barbiecollectorjapan.ga, 1 +barbiere.it, 1 +barbonnetje.nl, 1 +barborakucerova.cz, 1 +barbosha.ru, 1 +barbu.family, 1 +barburas.com, 1 +barca-movie.jp, 1 +barcamp.koeln, 1 +barcats.co.nz, 1 +barcats.com, 1 +barcats.com.au, 1 +barcel.com.mx, 1 +barcelonabagels.cat, 1 +barcelonapremium.es, 1 +barcelonapremiummini.es, 1 +barcelonawinewalk.com, 1 +barclays.net, 1 +barcoder.tk, 1 +bardak.ga, 1 +bardes.org, 1 +bardiharborow.com, 1 +bardiharborow.tk, 1 +barefoodinrome.it, 1 +bareknucklenews.com, 1 +baresquare.com, 1 +bargainsettelement.com, 1 +barganhanaweb.ml, 1 +bargest.su, 1 +bargroup.ga, 1 +bariatricsurgerynewjersey.com, 1 +bariatricsurgerysmg.com, 1 +barihandin.tk, 1 +baripedia.org, 0 +baris-sagdic.com, 1 +bariseau-mottrie.be, 0 +barisi.me, 1 +baristabetter.com, 1 +baristador.com, 1 +baristanetwork.co.uk, 1 +bariumoxide.com, 1 +barkerjr.xyz, 1 +barkingaboutbusiness.com, 1 +barkingmadpetproducts.co.za, 1 +barkingspidersaspets.com, 1 +barkstop.net, 1 +barlamane.com, 1 +barlex.pl, 1 +barlotta.net, 1 +barmenteros.com, 1 +barnabycolby.io, 1 +barnakstudio.com, 1 +barnaul-altai.tk, 1 +barneveldcentrum.nl, 1 +barneydavey.com, 1 +barnflix.net, 1 +barnfotografistockholm.se, 1 +barnhardt4berks.com, 1 +barnrats.com, 1 +barnvets.co.uk, 1 +baroloboys.de, 1 +baron14.be, 1 +baronet.cf, 1 +baronspices.com, 1 +barpodsosnami.pl, 1 +barprive.com, 1 +barqo.co, 0 +barrack.tk, 1 +barracuda.blog, 1 +barracuda.com.tr, 1 +barrancos.tk, 1 +barratennis.com.br, 1 +barrenwuffett.com, 1 +barrera.io, 1 +barrierefreie-medien.info, 1 +barrikade.tk, 1 +barriofut.com, 1 +barrioitalia.com, 1 +barriotoboardroom.com, 1 +barruntos.tk, 1 +barrydenicola.com, 1 +barrymarkus.tk, 1 +barsashop.com.br, 1 +barsgroup.com, 1 +barss.io, 1 +barsukas.net, 1 +bart-f.com, 1 +barta.me, 1 +bartavi.nl, 1 +bartbania.com, 1 +bartcoppens.be, 1 +bartdaelman.tk, 1 +bartdesign.tk, 1 +bartel.ws, 1 +bartelt.name, 1 +barter.vg, 1 +barter4crypto.com, 1 +barth.services, 1 +bartholf.nu, 1 +bartkramer.nl, 0 +bartlamboo.nl, 1 +bartolomebellido.com, 1 +bartula.de, 1 +bartvandamme.tk, 1 +bartzutow.xyz, 1 +baruch.me, 1 +barwaldesigns.com, 1 +barwave.com, 1 +barzallof.com, 1 +barzus.com.ua, 1 +bas.co.jp, 1 +basamadco.ir, 1 +basar-horrheim.de, 1 +basauristudios.com, 1 +basculasconfiables.com, 1 +base-autonome-durable.com, 0 +base-n.ru, 1 +base-radio.cf, 1 +basebalance.net, 1 +baseballpitchingmachine.tk, 1 +baseballsavings.com, 1 +basebyte.nl, 1 +basecamp.cf, 1 +baseconvert.com, 1 +basedos.com, 1 +baseerapp.com, 1 +basel-gynaecology.com, 1 +basel-gynaekologie.ch, 1 +baselang.com, 1 +baselnazifrei.info, 0 +basement961.co.nz, 1 +basementdoctornorthwest.com, 1 +basementdoctorwestvirginia.com, 1 +basementdoctorwv.com, 1 +basementfinishingohio.com, 1 +basementproblems.com, 1 +basementwaterproofingannarbor.com, 1 +basementwaterproofingasheville.com, 1 +basementwaterproofingdesmoines.com, 1 +basementwaterproofingknoxvilletn.com, 1 +basementwaterproofingsaintlouis.com, 1 +basementwaterproofingwi.com, 1 +baserverz.ga, 1 +basetruck.cn, 1 +baseweb.design, 0 +bash.news, 1 +bashc.at, 1 +bashhack.cf, 1 +bashing-battlecats.com, 1 +bashkiri.cf, 1 +bashkiria.cf, 1 +bashkiria.ga, 1 +bashkirlife.tk, 1 +bashsoftware.tk, 1 +bashstreetband.co.uk, 1 +bashtel.tk, 1 +basic.is, 1 +basicamente.digital, 0 +basicapparel.de, 1 +basicattentiontoken.org, 1 +basicguitarlessons.com, 1 +basiclimits.tk, 1 +basicports.com, 1 +basicports.eu, 1 +basicports.net, 1 +basicports.org, 1 +basics.domains, 1 +basics.net, 1 +basictools.tk, 1 +basicwallpapers.tk, 1 +basilicaknights.org, 1 +basilm.co, 1 +basilsys.com, 1 +basisbedarf.de, 1 +basisonline.nl, 1 +basisonlinefiles.nl, 1 +basketball-brannenburg.de, 1 +basketball-malavan.tk, 1 +basketballnewz.tk, 1 +basketforex.com, 1 +basllp.co.uk, 1 +basnoslovno.ru, 1 +basonlinemarketing.nl, 1 +basradio.tk, 1 +bass-pro.ru, 1 +bassblog.net, 1 +bassethound.tk, 1 +bassment.ph, 1 +bassresource.com, 1 +bassrhymeposse.tk, 1 +bassrider.eu, 1 +bassys.com.co, 1 +bastardator.tk, 1 +bastawholesale.com, 1 +bastelstu.be, 1 +bastelzauberwelt.de, 0 +bastide-viens.com, 1 +bastionadvokat.ml, 1 +bastionentifo.tk, 1 +bastiv.com, 1 +bastivmobile.com, 1 +bastolino.de, 1 +bastter.com, 1 +basw.eu, 1 +baswag.de, 1 +baswetter.photography, 1 +basyrova.ml, 1 +basyspro.net, 1 +batailleros.tk, 1 +batcave.tech, 1 +batch.com, 1 +batchewanabingo.com, 1 +baterioverolety.cz, 1 +bath.men, 1 +bathbodyshop.tk, 1 +bathrobes.tk, 1 +bathroomremodelinggeorgia.com, 1 +bati-alu.fr, 1 +batiburrillo.net, 1 +batipiscine.com, 1 +batipresta.ch, 0 +batiskaf.ua, 1 +batistareisfloresonline.com.br, 1 +batitrakya.org, 1 +batmanvsupermanfullmovie.ga, 1 +batmod.com, 1 +batoit.gq, 1 +batolis.com, 1 +batonchik.tk, 1 +batook.org, 1 +batschu.de, 1 +batten.eu.org, 1 +batterijeshop.com, 0 +batteryboys.ca, 1 +batteryboys.com, 1 +batteryreconditioning.ml, 1 +batterystaple.pw, 1 +battle-game.com, 1 +battleboxx.com, 0 +battlefield1942.tk, 1 +battleforkhashuri.tk, 1 +battlefrontoldschool.cf, 1 +battleguard.net, 1 +battleofthegridiron.com, 1 +battlepetsonline.com, 1 +battlerealms.cc, 1 +battlerite.tk, 1 +battletech.tk, 1 +battreil.tk, 1 +batucadastore.nl, 1 +batukhan.tk, 1 +batwatt.com, 1 +bauer-reininghorses.com, 1 +bauer.network, 1 +bauernmarkt-fernitz.at, 1 +baufi24.de, 1 +baufinanzierung-ludwigsburg.de, 1 +baugeldspezi.de, 1 +baugelitt.eu, 1 +baugemeinschaftbernstein.de, 1 +bauingenieur24.de, 1 +baukebies.nl, 1 +baukelek.tk, 1 +baumannfabrice.com, 1 +baumfreund.ch, 1 +baumkuchen-aus-dresden.de, 1 +baur.de, 1 +bausep.de, 1 +bausparkassen.tk, 1 +baustils.com, 1 +bauthier-occasions.be, 0 +bautied.de, 1 +bautizodelucia.com, 1 +bauunternehmen-herr.de, 1 +bavaria-feuerloeschershop.de, 1 +bavarian-firebird.de, 1 +bavaroparadise.com, 1 +bavaropuntacanahotels.com, 1 +bavarovillage.com, 1 +bavartec.de, 1 +bawamedical.com, 1 +bawbby.com, 1 +bayanbennett.com, 1 +bayanradio.tk, 1 +bayareaenergyevents.com, 1 +bayareagynecology.com, 1 +bayareaplasticsurgery.com, 1 +bayden.com, 1 +bayer-stefan.com, 1 +bayer-stefan.de, 1 +bayer-stefan.eu, 1 +bayer.earth, 1 +bayerhazard.de, 1 +bayerstefan.com, 1 +bayerstefan.de, 1 +bayerstefan.eu, 1 +bayherbalist.com, 1 +bayilelakiku.com, 1 +bayly.eu, 1 +baymard.com, 1 +bayofseo.com, 1 +bayportbotswana.com, 1 +bayportghana.com, 1 +bayportuganda.com, 1 +bayraklar.info, 1 +bayramov.tk, 1 +bayscollisionrepairs.co.nz, 1 +baysideaba.com, 1 +baysidefamilydentist.com.au, 1 +baystreet.com.mt, 1 +bayt.com, 1 +baytalebaa.com, 1 +baytobayaircon.com.au, 1 +baytownent.com, 1 +baytv.it, 1 +baywatch.io, 1 +bayz.de, 0 +baza-gai.com.ua, 1 +bazaarbhaav.com, 1 +bazaarcompass.com, 1 +bazaart.me, 1 +bazaclub.ru, 0 +bazar-online.tk, 1 +bazar-pc.tk, 1 +bazar.bg, 1 +bazarfds.com.br, 1 +bazari.com.pl, 1 +bazarotehijos.com, 1 +bazdell.com, 0 +bazhan.me, 1 +bazinga-events.nl, 1 +bazos.at, 1 +bazos.cz, 1 +bazos.pl, 1 +bazos.sk, 1 +bazziergraphik.com, 1 +bb-ek.de, 1 +bb-moisel.de, 1 +bb-sportnahrung.de, 1 +bb00228.com, 1 +bb057.com, 1 +bb087.com, 1 +bb168.cc, 1 +bb2-group.com, 1 +bb37roma.it, 1 +bb5197.co, 1 +bb6729.co, 1 +bb6729.com, 1 +bb6957.co, 1 +bb882.com, 1 +bb9297.co, 1 +bb9721.com, 1 +bb9728.co, 1 +bbagramante.it, 1 +bbalposticino.it, 1 +bbamsch.com, 1 +bbaovanc.com, 1 +bbb1991.me, 0 +bbbasicspodcast.com, 1 +bbbff.net, 1 +bbc67.fr, 1 +bbcastles.com, 1 +bbclyra.tk, 1 +bbcomcdn.com, 1 +bbcustomremodeling.com, 1 +bbforums.com, 1 +bbgeschenke.ch, 0 +bbhsolutions.com, 1 +bbimarketing.com, 1 +bbinsure.com, 1 +bbk365m.com, 1 +bbk365t.com, 1 +bbk365zz.com, 1 +bbka.co.uk, 1 +bbka.org.uk, 1 +bbkanews.co.uk, 1 +bbkanews.com, 1 +bbkanews.org, 1 +bbkanews.uk, 1 +bbkl.org, 1 +bbkworldwide.jp, 1 +bbld.de, 1 +bblsa.ch, 0 +bbmagnagrecia.it, 1 +bbmassageandfloat.com, 1 +bbnx.net, 1 +bbqs-algarve.com, 1 +bbrigittae.hu, 1 +bbs8080.com, 1 +bbschat.tk, 1 +bbsec.xyz, 1 +bbsgood.com, 1 +bbuio.com, 0 +bbunits.de, 1 +bbw-wrestling.com, 1 +bbw.dating, 1 +bbwcs.co.uk, 1 +bbwsexclips.com, 1 +bbwteens.org, 1 +bbxin9.net, 1 +bc-bd.org, 0 +bc-cdc.org, 1 +bc-diffusion.com, 1 +bcabs.com, 1 +bcansw.com.au, 1 +bcbulle.ch, 0 +bcdiesel.ca, 1 +bcdonadio.com, 1 +bcdonadio.com.br, 1 +bcdonadio.org, 1 +bceventhire.co.uk, 1 +bch7al.ma, 0 +bchep.com, 1 +bchnews.info, 1 +bck-koethen.de, 1 +bck-lelystad.nl, 1 +bckaccompressoroz.com, 1 +bclogandtimberbuilders.com, 1 +bcmguide.com, 1 +bcmhire.co.uk, 1 +bcmlu.org, 1 +bcnet.com.hk, 1 +bcoffices.com.mx, 1 +bcome.nl, 1 +bcomm.com.au, 1 +bcpc-ccgpfcheminots.com, 1 +bcrnews.tk, 1 +bcrook.com, 1 +bcswampcabins.com, 1 +bcsytv.com, 0 +bcubeanalytics.com, 1 +bcubic.net, 1 +bcyw56.live, 0 +bcyw56.top, 1 +bd-media.tk, 1 +bd.foundation, 1 +bd2positivo.com, 1 +bda-boulevarddesairs.com, 0 +bdbe.ga, 1 +bdbxml.net, 1 +bdd.fi, 1 +bdeshi.space, 1 +bdfriends.tk, 1 +bdikaros-network.net, 1 +bdmusic25.us, 1 +bdpachicago.tech, 1 +bdpestsolutionsstlouis.com, 1 +bdsmcontrol.com, 1 +bdsmdating.tk, 1 +bdsmwiki.hu, 1 +bdtc.com.bd, 1 +bdtd.nl, 1 +bdvg.org, 1 +be-a-password.ninja, 1 +be-free.gq, 1 +be-ka-tec.de, 1 +be-real.life, 0 +be-up-developpement.com, 1 +be-webdesign.com, 1 +be.ax, 1 +be.gy, 1 +be.search.yahoo.com, 0 +be2cloud.de, 1 +be9418.com, 1 +be9418.info, 1 +be9418.net, 1 +be9418.org, 1 +be9458.info, 1 +be9458.net, 1 +be9458.org, 1 +be958.info, 1 +be958.org, 1 +be9966.com, 1 +bea.expert, 0 +bea.gov, 1 +beacham.online, 1 +beachcitybody.com, 1 +beachcitycastles.com, 1 +beachmarketing.co.uk, 1 +beachpoint.tk, 1 +beachsoccer.tk, 1 +beachwayhomes.com, 1 +beachworldchampion.tk, 1 +beacinsight.com, 1 +beaconfed.org, 1 +beadare.com, 1 +beadare.nl, 1 +beaglesaspets.com, 1 +beaglesecurity.com, 1 +beakbirds.com, 1 +beaker.coffee, 1 +beallure.it, 1 +bealpha.pl, 1 +beam-life.tk, 1 +beam-to.me, 1 +beama.org, 1 +beambdi.com, 1 +beamitaly.tk, 1 +beamitapp.com, 1 +beamstat.com, 1 +beanbagaa.com, 1 +beanbot.party, 1 +beancount.io, 1 +beanilla.com, 1 +beanjuice.me, 1 +beansgalore.com.au, 1 +beaquarium.com, 1 +bearcms.com, 1 +bearcosports.com.br, 1 +beardboys.co.za, 1 +bearded.sexy, 1 +bearden.io, 1 +beardic.cn, 1 +beardsome.me, 1 +bearfactory.tk, 1 +bearfarm.tk, 1 +beargoggleson.com, 1 +bearings.tk, 1 +bearingworks.com, 1 +bearlakelife.com, 1 +bearrecords.tk, 1 +bearskin-rugs.com, 1 +beasel.biz, 1 +beashandmade.com, 1 +beastiejob.com, 1 +beastlog.tk, 1 +beastowner.li, 1 +beastshirt.com, 1 +beatfeld.de, 1 +beatfreaks.tk, 1 +beatmaker.ml, 1 +beatquantum.com, 1 +beatrice-nightscout.herokuapp.com, 1 +beatrice-raws.org, 1 +beatrizaebischer.ch, 0 +beatsdope.com, 1 +beatsearch.net, 1 +beatthebastards.tk, 1 +beatthecpa.com, 1 +beatuprobot.net, 1 +beau.pw, 1 +beaulieu.ch, 1 +beaute-eternelle.ch, 0 +beautifulreflectionsmedspa.com, 1 +beautifulsouth.tk, 1 +beauty-blog.gq, 1 +beauty-form.ir, 1 +beauty-italy.ru, 1 +beauty-mens.com, 1 +beauty-salon-lino.com, 1 +beauty-stories.tk, 1 +beauty-style.ml, 1 +beauty-woman.tk, 1 +beauty-yan-enterprise.com, 1 +beauty.moe, 0 +beauty24.de, 1 +beauty2home.net, 1 +beautyandfashionadvice.com, 1 +beautyandthebeast.tk, 1 +beautyarticles.tk, 1 +beautybh.com, 1 +beautybism.com, 1 +beautybox.ro, 1 +beautyby.tv, 1 +beautycarepack.com.ng, 1 +beautycom.club, 1 +beautycon.ir, 1 +beautyest.net, 1 +beautyevent.fr, 1 +beautyeyewear.ga, 1 +beautyinfos.de, 1 +beautyinweb.net, 1 +beautyisfine.tk, 1 +beautyland.com.co, 1 +beautylookz.nl, 1 +beautyseasons.ru, 1 +beautyspot.tk, 1 +beaver-creek.ga, 1 +beavercountian.com, 1 +beaverdamautos.com, 1 +beavertales.ca, 1 +beavillabea.it, 1 +bebaspedia.com, 1 +bebe2luxe.fr, 1 +bebeautiful.business, 1 +bebecar.com, 1 +bebef.de, 1 +bebefofuxo.com.br, 1 +bebemamae.com, 1 +bebes.uno, 1 +bebest.gov, 1 +bebetrotteur.com, 1 +beboldpr.com, 1 +bebout.domains, 1 +bebout.pw, 1 +becausecapitalism.org, 1 +beccaanne.photography, 1 +beccajoshwedding.com, 1 +bech32.net, 1 +beckdesign.tk, 1 +beckijayes.family, 1 +becklove.cn, 1 +beckylicious.tk, 1 +beclan.tk, 1 +becleverwithyourcash.com, 1 +becollective.com, 1 +become-lucky.com, 1 +beconnect.cf, 1 +becquerelgroup.com, 1 +becs.ch, 0 +becubed.co, 1 +becydog.cz, 1 +bedamedia.com, 1 +bedandbreakfast.dk, 1 +bedandbreakfasthoekvanholland.com, 1 +bedding.ro, 1 +bedels.nl, 1 +bedez.pl, 1 +bedfordnissanparts.com, 1 +bedinsi.com.br, 1 +bedlingtonterrier.com.br, 1 +bedofcorpses.tk, 1 +bedouille.com, 1 +bedreinvestering.dk, 1 +bedrijfsfotoreportages.nl, 1 +bedrijfsportaal.nl, 1 +bedrijvencentrum-maartenslaan.nl, 1 +bedrijvencentrum-malberg.nl, 1 +bedrockcommunity.ml, 1 +bedrocklinux.org, 1 +bedset.me, 1 +bedtimeflirt.com, 1 +bee-creative.nl, 1 +bee-kart.com, 1 +bee-line.org.uk, 1 +bee-removal-dublin.com, 1 +bee.clothing, 1 +bee.supply, 1 +bee.tools, 1 +beeapro.com, 1 +beebeads.ga, 1 +beecare.ch, 0 +beedsolyjas.tk, 1 +beefclan.tk, 1 +beehealthyllc.com, 1 +beehive.govt.nz, 1 +beehive42.com, 1 +beehive42.eu, 1 +beehive42.net, 1 +beehive42.nl, 1 +beehive42.org, 1 +beehosting.pro, 1 +beekbier.nl, 1 +beekeeper.blog, 1 +beekeeper.clothing, 1 +beekeeper.supplies, 1 +beekeeper.supply, 1 +beekeeper.tools, 1 +beekeeping.clothing, 1 +beekeeping.tools, 1 +beeksnetwork.nl, 1 +beeldbankgent.be, 1 +beelen.fr, 1 +beelit.com, 1 +beemenergy.fr, 1 +beeming.net, 1 +beer-sheva.city, 1 +beer9.com, 1 +beerarchy.tk, 1 +beercandle.com, 1 +beercast.co.uk, 1 +beeremovalspretoria.co.za, 1 +beergifts.tk, 1 +beerglasses.tk, 1 +beerhouse.tk, 1 +beerians.com, 1 +beerians.info, 1 +beerjet.bg, 1 +beerjet.cz, 1 +beerjet.ro, 1 +beerjet.sk, 1 +beerjetcz.cz, 1 +beerloga.tk, 1 +beerly.eu, 0 +beermedlar.com, 1 +beernews.ga, 1 +beerradar.no, 1 +beerradar.party, 1 +beers.my, 1 +beersandco.ch, 1 +beersconf.com, 1 +beersheba.co.il, 1 +beersheva.city, 1 +beersheva.co.il, 1 +beerview.ga, 1 +beerxa.cz, 1 +beestar.it, 1 +beestation13.com, 1 +beeswarmrehoming.com.au, 1 +beeswax-orgone.com, 1 +beesweethoney.co.za, 1 +beetgroup.id, 1 +beethoveninlove.com, 1 +beetman.net, 1 +beeutifulparties.co.uk, 1 +beexfit.com, 0 +beezkneezcastles.co.uk, 1 +beeznest.com, 1 +befoodsafe.gov, 1 +beforeafter.gq, 1 +beforeyoueatoc.com, 1 +beframed.ch, 0 +befreewifi.info, 1 +befundonline.de, 1 +bega-dc.gov, 1 +begabungsfoerderung.info, 1 +begemoth.tk, 1 +begethost.cf, 1 +begin-motorcycling.co.uk, 1 +begovel.shop, 1 +begravningsbyranhumana.se, 1 +behamepresrdce.sk, 1 +behamzdarma.cz, 1 +behanger.eu, 1 +behar-selimi.tk, 1 +behavenet.com, 1 +behavhealth.ml, 1 +behaviorchangeimpact.org, 1 +behemoth.cf, 1 +beherit.pl, 1 +behinam.co.il, 1 +behind-the-mask.tk, 1 +behindenemyminds.be, 1 +behindenemyminds.eu, 1 +behindertenagentur.de, 1 +behlamp.ir, 1 +behmmjc.com, 1 +behoerden-online-dienste.de, 1 +behold.gq, 1 +behoreal.cz, 1 +bei18.com, 1 +beichtgenerator.de, 1 +beijinglug.club, 1 +beimchristoph.de, 1 +beinad.com, 1 +beinad.ru, 1 +beingmad.org, 1 +beinsports.pro, 1 +beinteractive.pl, 1 +beirutclis.com, 1 +beitmidrashrambam.com, 1 +beizsley.com, 1 +beizsoft.co.uk, 1 +bejarano.io, 1 +bekabazar.cz, 1 +bekmekci.tk, 1 +beko.ie, 1 +bekolite.com, 1 +bel-snegirek.ru, 0 +belacapa.com.br, 1 +belacine.com, 1 +belafonte.co, 1 +belajar.store, 1 +belajarpsikology.tk, 1 +belanews.tk, 1 +belanglos.de, 1 +belani.eu, 1 +belanja.express, 1 +belarto.es, 1 +belarto.pl, 1 +belarustoday.tk, 1 +belarustravel.tk, 1 +belastingdienst-in-beeld.nl, 0 +belastingmiddeling.nl, 1 +belavis.com, 1 +beleadsteam.com, 1 +belebey.city, 1 +beleggingspanden-financiering.nl, 0 +belegit.org, 1 +belezadateresa.com.br, 1 +belezashopping.com.br, 1 +belf.ml, 1 +belfastbounce.co.uk, 1 +belfastlocks.com, 1 +belfasttechservices.co.uk, 1 +belfix.be, 1 +belfor-probleme.de, 1 +belge.rs, 1 +belgers.com, 1 +belgia.tk, 1 +belgian-naturists.tk, 1 +belgian-swimmers-united.tk, 1 +belgianfilipinolovers.be, 1 +belgiantennis.tk, 1 +belgianwesthoekclassic.tk, 1 +belgicaservices.be, 1 +belgie-postcodes.be, 1 +belgischerijpony.tk, 1 +belgorod-host.cf, 1 +belgorod.ml, 1 +belgradestatebank.com, 1 +belgraver.email, 1 +belgraver.eu, 1 +belgraver.xyz, 1 +belhopro.be, 1 +belic.net, 1 +belics.com, 1 +belidzs.hu, 1 +belien-tweedehandswagens.be, 0 +believablebook.com, 0 +believeinyourmind.com, 1 +beliishko.tk, 1 +belinsky.tk, 1 +belive.tv, 1 +beliyo.tk, 1 +belizemap.tk, 1 +belkamfish.com, 1 +belki.tk, 1 +belkys.net, 0 +bell.id.au, 1 +bella-abyssinia.tk, 1 +bella-arte.eu, 0 +bella.network, 1 +bellaaroma.com.tw, 1 +bellabrowbydesign.com, 1 +bellafashion.tk, 1 +bellamodeling.com, 1 +bellamy.cloud, 1 +bellanews.tk, 1 +bellapierre.ee, 1 +bellarosemarketing.com, 1 +bellatight.com, 1 +bellavistaoutdoor.com, 1 +belle-lingerie.co.uk, 0 +bellebakes.blog, 1 +bellecarmen.tk, 1 +bellesetrebelles.tk, 1 +bellevuechiropracticassociates.com, 1 +bellevueduilawyers.com, 1 +bellevueowners.tk, 0 +bellezademujeres.com, 1 +bellezanatural.life, 1 +bellezzasenzalimiti.it, 1 +bellinghamdetailandglass.com, 1 +bellissime.tk, 1 +belllegal.com.au, 1 +belloweb.tk, 1 +belloy.net, 0 +bellreguard.tk, 1 +bellsweets.com, 1 +bellthrogh.com, 1 +bellware.io, 0 +belly-button-piercings.com, 1 +belmontgoessolar.org, 1 +belmundo.gent, 0 +belmundo.org, 1 +beloevino.ml, 1 +belos.at, 1 +belouga.org, 1 +belowzero.tk, 1 +belpbleibtbelp.ch, 1 +belquant.cf, 1 +belrosstrakh.tk, 1 +belrybalka.cf, 1 +belt.black, 1 +beltar.nl, 1 +beltman-shipping.tk, 1 +belug.de, 1 +belugadev.ml, 1 +belvitajoreggelt.hu, 1 +belvoirbouncycastles.co.uk, 1 +belwederczykow.eu, 1 +belzlongroup.com, 1 +bembee.tk, 1 +bemcorp.de, 1 +bemindly.com, 1 +bemiservis.sk, 1 +bemsertanejo.com, 1 +ben-energy.com, 0 +ben-stock.de, 1 +ben.ninja, 1 +ben2.co.il, 1 +benabbott.nz, 1 +benabrams.it, 1 +benadesign.fr, 1 +benadryl.ml, 1 +benadryld.tk, 1 +benalexisjohnson.com, 1 +benary.org, 1 +benatherton.com, 1 +benatskezrkadla.sk, 1 +benazir-reaction.tk, 1 +benbalter.com, 1 +benbozsa.ca, 1 +benc.io, 1 +benceskorka.com, 1 +benchling.com, 1 +benchmarkmonument.com, 1 +benchstoolo.com, 1 +bencorby.com, 1 +bendechrai.com, 0 +bendelllawfirm.com, 1 +bendemaree.com, 1 +bender.ga, 1 +bendigoland.com.au, 1 +bendingtheending.com, 1 +bendix.co, 1 +bendminding.com, 1 +bendyworks.com, 1 +beneathvt.com, 1 +beneazy.cf, 1 +benedetti.ca, 1 +benedict-balzer.de, 1 +benedict.tk, 1 +benedictoaguilar.tech, 1 +benee-awraham.nl, 1 +benefits.gov, 1 +benefitsbookcase.com, 1 +benepiscinas.com.br, 1 +benepla.com, 1 +beneri.se, 1 +benetcasablancas.tk, 1 +benevisim.com, 1 +benevita.bio, 1 +benevita.life, 1 +benevita.live, 1 +benevita.organic, 1 +benewpro.com, 1 +bengalcat.tk, 1 +bengalcatscare.com, 1 +bengaldisom.tk, 1 +bengaltourism.ml, 1 +bengalurugifts.com, 1 +bengisureklam.com, 1 +bengkelkeramik.tk, 1 +bengkle.id, 1 +benhamplateau.tk, 1 +benhaney.com, 1 +benhartmann.de, 0 +benhoeg.com, 1 +benjamin-hering.com, 1 +benjamin-horvath.com, 1 +benjamin-mary.herokuapp.com, 1 +benjamin-suess.de, 1 +benjaminbedard.com, 1 +benjaminblack.net, 1 +benjamindietrich.com, 1 +benjamindietrich.de, 1 +benjaminfox.net, 1 +benjaminjurke.com, 1 +benjaminkopelke.com, 1 +benjaminleupold.com, 1 +benjaminpiquet.fr, 0 +benjaminprevot.fr, 1 +benjaminrancourt.ca, 1 +benjamins.com, 1 +benjaminvasel.de, 1 +benjamorphism.com, 1 +benjii.me, 1 +benjijaldoner.nl, 1 +benjonline.tk, 1 +benkelmed.com, 1 +benleb.de, 0 +benleemd.com, 1 +benmack.net, 1 +benmarron.co.uk, 1 +benmatthews.com.au, 1 +benmedia.nl, 1 +benmillett.us, 0 +bennet.org, 1 +bennettsbouncycastlehire.co.uk, 1 +bennettshire.co.uk, 1 +benni1.eu, 1 +bennierobinson.com, 1 +bennink.me, 1 +benno.frl, 1 +benny003.de, 1 +bennygommers.nl, 1 +bennythink.com, 1 +benobi.one, 1 +benohrbrill.com, 1 +benoitchantre.com, 1 +benoniplumber24-7.co.za, 1 +benpro.fr, 1 +benrogers.tk, 1 +bensbouncycastles.co.uk, 1 +benschnarr.com, 1 +benscobie.com, 1 +benshoof.org, 1 +bensinflatables.co.uk, 1 +bensjamtracks.com, 1 +bensokol.com, 1 +benstevinson.com, 1 +bensvriend.tk, 1 +bent-nails.com, 1 +bentcreekvineyards.com.au, 1 +bentertain.de, 1 +bentley.blog, 1 +bentley.link, 1 +bento-kurumaya.co.jp, 1 +bentoncountyia.gov, 1 +bentongroup.co.uk, 1 +bentonweatherstone.co.uk, 1 +bentpunk.tk, 1 +bentrask.com, 1 +benu.cz, 1 +benulekaren.sk, 1 +benz-hikaku.com, 1 +benzblog.tk, 1 +benzi.io, 1 +benzin.tk, 1 +benzou-space.com, 1 +beonas.ddns.net, 1 +beonline.ml, 1 +beoordelingen.be, 1 +beospain.tk, 1 +bep.gov, 1 +bepayd.com, 1 +bephoenix.org.uk, 0 +beplephan.com, 1 +bepositive.ml, 1 +bepzi.com, 1 +bequ1ck.com, 1 +bequiia.com, 1 +berandalcorp.tk, 1 +beranovi.com, 1 +berasavocate.com, 1 +beraten-entwickeln-steuern.de, 1 +beratungswelt.dvag, 1 +berbervandenberg.tk, 1 +berchtesgaden-hilft.de, 1 +berdaguermontes.eu, 1 +berdu.id, 1 +bereaplumber.co.za, 1 +bereelcorporation.com, 1 +bereginy.com.ua, 1 +bereginya-lada.ru, 1 +beregusha.com, 1 +bereikbaargent.be, 1 +berela.com.pl, 1 +berend.tk, 1 +berendsvanhouttum.nl, 1 +beresbalazs.tk, 1 +bergelevrad.tk, 1 +bergenson.nl, 0 +berger-chiro.com, 1 +bergevoet-fa.nl, 0 +bergfex.at, 1 +bergfex.com, 1 +berghuus.ch, 1 +berglust-pur.de, 1 +bergman-gmbh.de, 1 +bergmanbeachproperties.com, 1 +bergmann-fotografin-berlin.de, 1 +bergsjomannen.tk, 1 +bergstoneware.com, 1 +bergvallsmassage.se, 1 +berhampore-gateway.tk, 1 +berichandcreamy.com, 1 +berichtsheft-vorlage.de, 1 +berightthere.eu, 1 +berikod.ru, 1 +beris.us, 1 +berita.press, 1 +beritalima.com, 1 +beritanow.tk, 1 +beritatopbanten.com, 1 +berjou.me, 1 +berk.tk, 1 +berkat-luqs.ddns.net, 1 +berkbrands.com, 1 +berkkalkan.com.tr, 1 +berksabstract.com, 1 +berksestateplanning.com, 1 +berksnetworking.com, 1 +berksteensmatter.org, 1 +berlin-cuisine.com, 1 +berlin-flirt.de, 1 +berlin.dating, 1 +berlindecouverte.fr, 1 +berlingeriresort.it, 1 +berluga.com, 1 +berluskoni.tk, 1 +bermellar.tk, 1 +bermos.net, 1 +bermytraq.bm, 1 +bern.bz, 1 +berna.fr, 1 +bernack.ga, 1 +bernadette.tk, 1 +bernadetteanderes.ch, 0 +bernama.com.my, 1 +bernar.do, 1 +bernard-securite-protection.fr, 1 +bernardcontainers.be, 0 +bernardez-photo.com, 1 +bernarditadiaz.tk, 1 +bernardo.fm, 1 +bernat.ch, 1 +bernat.im, 1 +bernbrucher.com, 1 +bernbrucher.de, 1 +bernd-leitner-fotodesign.com, 1 +bernd-leitner-fotodesign.de, 1 +bernd-leitner.de, 1 +berndartmueller.com, 1 +berndbousard.com, 1 +bernerland.cf, 1 +bernerland.tk, 1 +bernexskiclub.ch, 1 +bernhard-eicher.ch, 1 +bernhard-seidenspinner.de, 1 +bernhardkau.de, 1 +bernhardluginbuehl.ch, 1 +bernhardluginbuehl.com, 1 +bernie.lol, 1 +bernie.pics, 1 +bernieware.de, 1 +bernmail.ch, 1 +bernyweb.net, 1 +beroepenhuis.gent, 1 +berr.yt, 1 +berra.se, 1 +berriescomunicacion.com, 1 +berruezoabogados.com, 1 +berrus.com, 1 +berry.cat, 1 +berrywan.com, 1 +berserk.tk, 1 +bersierservices.ch, 0 +bersotavocats.fr, 0 +berst.cz, 1 +berthabailey.com, 1 +berthaundcarlbenzpreis.de, 1 +berthelier.me, 1 +bertold.org, 1 +bertoliniodontoiatria.it, 1 +bertrandkeller.info, 1 +bertrell.com, 1 +bertsmithvwparts.com, 1 +beryko.cz, 1 +beryl.net, 1 +berz.one, 1 +besate.ec, 1 +besb.io, 1 +besb66.club, 1 +besb66.me, 1 +besb66.ninja, 1 +besb66.rocks, 1 +besb66.us, 1 +bescoutednow.com, 1 +besedovichi.tk, 1 +besensi.com, 1 +beserberg.tk, 1 +besiconstruct.be, 1 +besnik.de, 0 +besnik.tk, 1 +besole.ch, 1 +besolov.tk, 1 +besox.be, 1 +bespaarenergie.click, 1 +bespaarnu.click, 1 +bespoiled.nl, 1 +bespokebathrooms.com.au, 1 +bespokemortgages.co.uk, 1 +bespokestraps.com, 1 +bespredel.tk, 1 +bessels.tk, 1 +bessems.com, 1 +bessems.eu, 1 +besser-golfen.tk, 1 +besslavnye-ublyudki.tk, 1 +bessmertie.ml, 1 +best-accounting-schools.com, 1 +best-art-colleges.com, 1 +best-baptist-colleges.com, 1 +best-beauty-schools.com, 1 +best-book.gq, 1 +best-business-colleges.com, 1 +best-buyessaysonline.com, 1 +best-cat.tk, 1 +best-catholic-colleges.com, 1 +best-cats.tk, 1 +best-chiter.tk, 1 +best-community-colleges.com, 1 +best-credit.de, 0 +best-culinary-colleges.com, 1 +best-education-schools.com, 1 +best-engineering-colleges.com, 1 +best-essay-service.com, 1 +best-graduate-programs.com, 1 +best-hvac-schools.com, 1 +best-lutheran-colleges.com, 1 +best-management-schools.com, 1 +best-marketing-schools.com, 1 +best-music-colleges.com, 1 +best-nursing-colleges.com, 1 +best-of-bounce.co.uk, 1 +best-pharmacy-schools.com, 1 +best-photobooth.ro, 1 +best-seminar.gq, 1 +best-seminar.ml, 1 +best-software.tk, 1 +best-tickets.co.uk, 1 +best-tickets.com.au, 1 +best-trucking-schools.com, 1 +best-wedding-quotes.com, 1 +best10websitebuilders.com, 1 +best2pay.net, 1 +best66.me, 1 +bestanswer.tech, 1 +bestantidandruffshampoo.net, 1 +bestappliancedoctor.com, 1 +bestasquadradas.org, 1 +bestattungen-kammerer.de, 1 +bestattungshaus-kammerer.de, 0 +bestautoinsurance.com, 1 +bestbatteriesonline.com, 1 +bestbefore.com, 1 +bestbestbitcoin.com, 1 +bestbonuses.co.uk, 1 +bestboot.cf, 1 +bestbrakes.com, 1 +bestbrokerindia.com, 1 +bestbudget.io, 1 +bestbuyatvs.com, 1 +bestbuyzone.com, 1 +bestcarscyprus.com, 1 +bestcivilattorneys.com, 1 +bestcms.tk, 1 +bestcouponvouchercodes.com, 1 +bestcreditcards.biz, 1 +bestcreditcards.me, 1 +bestcreditcards.news, 1 +bestcreditcards.tv, 1 +bestcreditcards.xyz, 1 +bestcrossbowguide.com, 0 +bestdeal.co.in, 0 +bestdietpillss.com, 1 +bestdownloadscenter.com, 1 +bestdslrcameras.tk, 1 +bestecbdolie.com, 1 +bestechgadgets.tk, 1 +bestedeal.nl, 1 +besteenergieleverancier.com, 1 +bestehostingproviders.nl, 1 +bestelectricnd.com, 1 +bestelhetmaar.nl, 1 +bestellipticalmachinereview.info, 1 +bestelsportprijzen.nl, 1 +bestemailmarketingsoftware.org, 1 +bestesb.net, 1 +bestessayhelp.com, 1 +bestestofzuiger.com, 1 +bestestquote.com, 1 +besteuitvaartverzekering.com, 1 +bestfacts.ru, 1 +bestfitnesswatchreview.info, 1 +bestfornutrition.com, 1 +bestfotostudio.com, 1 +bestfriend.ga, 1 +bestfriendsequality.org, 1 +bestgiftever.ca, 1 +bestglobalpayments.com, 1 +bestgriefbooks.com, 1 +besthairsale.com, 1 +besthemes.tk, 1 +besthomescents.com, 1 +besthost.cz, 1 +besthotsales.com, 1 +besti.it, 1 +bestiahosting.com, 1 +bestidea.io, 1 +besties4life.ml, 1 +bestinbarter.com, 1 +bestinductioncooktop.us, 1 +bestinfo.com.au, 1 +bestinshowing.com, 1 +bestinsider.net, 0 +bestinsulatedwaterbottle.tk, 1 +bestinver.es, 0 +bestitwork.tk, 1 +bestjumptrampolines.be, 1 +bestkenmoredentists.com, 1 +bestkeys.ga, 1 +bestkitchenbuy.com, 1 +bestladyshaver.co.uk, 0 +bestlawyernear.com, 1 +bestleftwild.com, 1 +bestliege.be, 1 +bestmedsmmj.com, 1 +bestmodels.ua, 1 +bestmotherfucking.website, 1 +bestmotorcyclehelmets.net, 1 +bestnetentcasino.info, 1 +bestnetflowanalyzer.com, 1 +bestnewsmag.com, 1 +bestofbooks.gq, 1 +bestoldmusic.tk, 1 +bestoliveoils.com, 1 +bestomania.tk, 1 +bestparking.xyz, 1 +bestpartyhire.com, 1 +bestperfumebrands.com, 1 +bestpig.fr, 1 +bestplus.ml, 1 +bestplus.tk, 1 +bestpornclip.com, 1 +bestporngirls.com, 1 +bestpractice.domains, 1 +bestproductsaudit.com, 1 +bestreleases.tk, 1 +bestremote.io, 1 +bestreviewcenter.com, 1 +bestrevs.com, 1 +bestsatoshifaucet.ga, 1 +bestschools.io, 1 +bestsellers.co, 1 +bestseo4u.co.uk, 1 +bestseries.tv, 1 +bestsextoys.com, 1 +bestsgadgets.com, 1 +bestshoesmix.com, 1 +bestshops.ga, 1 +bestsingingbowls.com, 1 +bestsiteporn.com, 1 +besttipsntricks.tk, 1 +besttrade.tk, 1 +bestvetmortgage.com, 1 +bestvpnservice.com.au, 1 +bestwap2.in, 1 +bestwebcams.ml, 1 +bestwebsite.gallery, 1 +bestweleenbeetje.nl, 1 +bestwirelessdoorbell.ml, 1 +bestwriterjobs.tk, 1 +bestzoo.tk, 1 +bet-platform.com, 1 +bet031.com, 1 +bet03vip.com, 0 +bet064.com, 1 +bet06vip.com, 1 +bet074.com, 1 +bet08vip.com, 1 +bet09vip.com, 1 +bet166111.com, 1 +bet166333.com, 1 +bet166444.com, 1 +bet166555.com, 1 +bet166888.com, 1 +bet1668888.com, 1 +bet166999.com, 1 +bet166b.com, 1 +bet166bbb.com, 1 +bet166c.com, 1 +bet166ddd.com, 1 +bet166eee.com, 1 +bet166fff.com, 1 +bet166hhh.com, 1 +bet166tt.com, 1 +bet166uu.com, 1 +bet166ww.com, 1 +bet166xx.com, 1 +bet166yy.com, 1 +bet338c.com, 1 +bet3639.com, 1 +bet365bc.net, 1 +bet365bet2020.com, 1 +bet365cn-casino.com, 1 +bet365cn-game.com, 1 +bet365cn-keno.com, 1 +bet365cn-livecasino.com, 1 +bet365cn-poker.com, 1 +bet365cn-sports.com, 1 +bet365cn-vegas.com, 1 +bet365cnq.com, 1 +bet365cnr.com, 1 +bet365cns.com, 1 +bet365cnt.com, 1 +bet365cnu.com, 1 +bet365cnv.com, 1 +bet365cnw.com, 1 +bet365cnx.com, 1 +bet365cny.com, 1 +bet365cnz.com, 1 +bet365g8.com, 1 +bet365n1.com, 1 +bet365n2.com, 1 +bet365n6.com, 1 +bet365n8.com, 1 +bet365n9.com, 1 +bet365q0.com, 1 +bet365q6.com, 1 +bet365q8.com, 1 +bet365q9.com, 1 +bet365r8.com, 1 +bet365vip1.com, 1 +bet365vip2.com, 1 +bet365vip2020.com, 1 +bet365vip7.com, 1 +bet365x0.com, 1 +bet365x1.com, 1 +bet365x2.com, 1 +bet365x3.com, 1 +bet365x6.com, 1 +bet365x8.com, 1 +bet365x9.com, 1 +bet391.com, 1 +bet392.com, 1 +bet397.com, 1 +bet3xx.com, 1 +bet3zz.com, 1 +bet43app.com, 1 +bet44402.com, 1 +bet44403.com, 1 +bet44404.com, 1 +bet44405.com, 1 +bet44406.com, 1 +bet44407.com, 1 +bet44409.com, 1 +bet44410.com, 1 +bet444401.com, 1 +bet444403.com, 0 +bet444404.com, 1 +bet444405.com, 1 +bet444406.com, 1 +bet444407.com, 1 +bet444408.com, 1 +bet444409.com, 1 +bet444410.com, 1 +bet444421.com, 1 +bet444422.com, 1 +bet444424.com, 0 +bet444425.com, 0 +bet444426.com, 0 +bet444429.com, 0 +bet444430.com, 1 +bet5119.com, 1 +bet5234.com, 1 +bet531.com, 1 +bet567111.com, 1 +bet567222.com, 1 +bet567333.com, 1 +bet567444.com, 1 +bet567555.com, 1 +bet5757.com, 1 +bet5868.com, 1 +bet599.com, 1 +bet631.com, 1 +bet66669999.com, 1 +bet666888.vip, 1 +bet7234.com, 1 +bet819.com, 1 +bet86ah.com, 1 +bet86am.com, 1 +bet86cq.com, 1 +bet86fj.com, 1 +bet86gs.com, 1 +bet86gx.com, 1 +bet86gz.com, 1 +bet86hlj.com, 1 +bet86hn.com, 1 +bet86jl.com, 1 +bet86js.com, 1 +bet86jx.com, 1 +bet86ln.com, 1 +bet86nmg.com, 1 +bet86nx.com, 1 +bet86qh.com, 1 +bet86sc.com, 1 +bet86sd.com, 1 +bet86sh.com, 1 +bet86sx.com, 1 +bet86tj.com, 1 +bet86tw.com, 1 +bet86xj.com, 1 +bet86xz.com, 1 +bet86yn.com, 1 +bet86zj.com, 1 +bet909.com, 1 +bet9ja.com, 1 +beta-site-staging.azurewebsites.net, 1 +betaa0.com, 1 +betaa1.com, 1 +betaa2.com, 1 +betaa3.com, 1 +betaa5.com, 1 +betaa6.com, 1 +betaa8.com, 1 +betaa9.com, 1 +betaal.my, 1 +betaalbaarverbouwen.com, 1 +betaclouds.net, 1 +betacommand.tk, 1 +betalgroup.com, 1 +betandslots.com, 1 +betandyou.com, 1 +betanoapp.com, 1 +betaoptimize.com, 1 +betaprofiles.com, 1 +betata.tk, 1 +betatester.ml, 1 +betawi.com, 1 +betaworx.de, 1 +betaworx.eu, 1 +betb33.com, 1 +betb73.com, 1 +betbed.ml, 1 +betbravo.et, 1 +betcn-mart.com, 1 +betecnet.de, 1 +betemyja.tk, 1 +betexperts.tk, 1 +betformular.com, 1 +bethanyhome.org, 1 +bethematch.org, 1 +bethematchclinical.org, 1 +betheredge.us, 1 +bethpage.net, 1 +bethzone.tk, 1 +betimely.com, 1 +betleakbot.com, 1 +betmobilenigeria.com, 1 +betobaccofree.gov, 1 +betolerant.fr, 1 +betonbit.com, 1 +betonmarkets.info, 1 +betonsport.ga, 1 +betor.cz, 1 +betpamm.com, 1 +betrifft-mich-dsgvo.ch, 1 +betrimus.xyz, 1 +bets.gg, 1 +betseven.pt, 1 +betseybuckheit.com, 1 +betsharpangles.com, 1 +betshoot.com, 1 +betsonlinefree.com.au, 1 +betsyshilling.com, 1 +bett1.at, 1 +bett1.ch, 1 +bett1.de, 1 +bett1.fr, 1 +bett1.pl, 1 +bettaline.com.au, 1 +bettashoerepairs.com.au, 1 +bettehochberger.com, 1 +better.com, 1 +better.fyi, 1 +betterbabyshop.com.au, 1 +betterbladders.com, 1 +betterboards.net, 1 +betterbusiness.xyz, 1 +bettercallsully.com, 1 +bettercareclinic.co.uk, 1 +bettercleaningcompany.co.uk, 1 +betterconsult.com, 1 +bettercrypto.org, 1 +betterjapanese.blog, 1 +betterjapanese.org, 1 +betterjapanese.xyz, 1 +betterna.me, 1 +betterscience.org, 1 +bettersecurity.co, 1 +betterselfbetterworld.cz, 1 +bettersocialmedia.co.uk, 1 +betterteam.com, 1 +bettertest.it, 1 +bettertime.jetzt, 1 +betterweb.fr, 0 +betterworlded.org, 1 +betterworldinternational.org, 1 +bettflaschen.ch, 1 +bettie.tk, 1 +bettingbusiness.ru, 1 +bettingonaverage.com, 1 +bettingsider.dk, 1 +bettmer.at, 1 +bettmer.de, 1 +bettolinokitchen.com, 1 +betty-baloo.com, 1 +bettyweber.com, 1 +betulashop.ch, 1 +betweenthehills.be, 1 +betwin9.net, 1 +betwinner-zerkalo.ru, 1 +betwinner.cm, 1 +betwinner.de.com, 1 +betwinnergiris.org, 1 +betwinnerkenya.com, 1 +betwinnerlive.com, 1 +betwinnernigeria.com, 1 +betwinnerportugal.com, 1 +betwinneruganda.com, 1 +betxx1.com, 1 +betxx2.com, 1 +betza.online, 1 +beulen.email, 1 +beulen.link, 1 +beulen.pro, 1 +beus.ink, 1 +beuteugeu.com, 1 +bevallarta.com, 1 +bevedo.cz, 1 +bevedo.sk, 1 +beveiligingscamerawestland.nl, 1 +bevelbeer.com, 1 +bevelpix.com, 1 +beverhof.nl, 1 +beverley.tk, 1 +beverleycounselling.co.uk, 1 +beverly.tk, 1 +beverlyinternational.com, 1 +bevif.com, 1 +bevinco2020.com, 1 +bevinsco.org, 1 +bevmoir.com, 1 +bevnut.com, 1 +bewegigsruum.ch, 1 +bewegingdenk.nl, 1 +bewegtes-lagern.at, 1 +bewegtes-lagern.ch, 1 +bewegtes-lagern.com, 1 +bewegtes-lagern.de, 1 +bewegteslagern.ch, 1 +bewegteslagern.com, 1 +bewegteslagern.de, 1 +bewegungsfluss.com, 0 +bewerbungsfibel.de, 1 +bewerbungsfoto-deinfoto.ch, 1 +bewildered.gq, 1 +bexit-hosting.nl, 1 +bexit-security.eu, 1 +bexit-security.nl, 1 +bexit.nl, 1 +bexithosting.nl, 1 +bexleycastles.co.uk, 1 +bexx-engineering.co.uk, 0 +bey.io, 1 +beybiz.com, 1 +beybladesource.tk, 1 +beyerautomation.com, 1 +beyerm.de, 1 +beykozmekan.com, 1 +beyond-infinity.org, 0 +beyond-rational.com, 1 +beyond360view.com, 1 +beyond3dview.com, 1 +beyond3dviews.com, 1 +beyondalderaan.net, 1 +beyondauth.io, 1 +beyondbounce.co.uk, 1 +beyondboxgifts.com, 1 +beyondgameplay.com, 1 +beyondpricing.com, 1 +beyondthecode.io, 1 +beyondthecreek.com, 1 +beyondthefive.org, 1 +beyondthepitch.net, 1 +beyondtodaymediagroup.com, 1 +beyondtrust.com, 1 +beyondweb.net, 1 +beyours.be, 1 +bezagentstva.cf, 1 +bezahlbare-praemien.ch, 1 +bezchyb.sk, 1 +bezlepkovamatka.cz, 1 +bezmlska.cz, 0 +bezoek-benidorm.tk, 1 +bezoomnyville.com, 1 +bezopasna-rabota.tk, 1 +bezpecnostsiti.cf, 1 +bezposrednio.net.pl, 1 +bezzia.com, 1 +bfam.tv, 1 +bfbet365.com, 1 +bfdz.ink, 1 +bfem.gov, 1 +bfh.science, 1 +bfkcloud.ddns.net, 1 +bfob.gg, 1 +bforb.sk, 1 +bfp-mail.de, 1 +bfpg.org, 1 +bfrailwayclub.cf, 1 +bft-media.com, 0 +bfw-online.de, 1 +bg-sexologia.com, 1 +bgbaby.net, 1 +bgbet365.com, 1 +bgbhsf.top, 1 +bgemi.net, 1 +bgeo.io, 1 +bgfashion.net, 1 +bghddevelopment.com, 1 +bghope.com, 1 +bghost.xyz, 1 +bgjargon.com, 1 +bgkoleda.bg, 1 +bglobal.com, 1 +bglsingles.de, 1 +bgm.bg, 1 +bgmall.tk, 1 +bgmn.me, 1 +bgp.space, 1 +bgr34.cz, 1 +bgs-game.com, 1 +bgtoyou.com, 1 +bgtraffic.tk, 1 +bguidinger.com, 1 +bh-oberland.de, 1 +bh.sb, 1 +bhacit.com, 1 +bharat-media.tk, 1 +bharatanatyam-dancer.tk, 1 +bharath-g.in, 1 +bharatology.org, 1 +bhat.vn, 1 +bhavansvidyamandir.tk, 1 +bhaweshkumar.com, 1 +bhbet365.com, 1 +bhglamour.com, 1 +bhhscalhomes.com, 1 +bhi.consulting, 1 +bhodisoft.com, 1 +bhogavati.tk, 1 +bhosted.nl, 1 +bhpropco.com, 1 +bhrenovations.com, 1 +bhserralheria.com.br, 1 +bhthome.com, 1 +bhub.tk, 1 +bhuntr.com, 1 +bhutanonlinetravels.com, 1 +bhxch.moe, 1 +bhyn.ca, 1 +bi.search.yahoo.com, 0 +bi1gif.radio, 1 +bi8cku.club, 1 +bi8cku.tech, 1 +bia.gov, 0 +bia2takhfif.com, 1 +biabop.com, 1 +biaggeo-prod.herokuapp.com, 1 +biaggeo.com, 1 +biancapulizie.it, 1 +biancasalgueiro.tk, 1 +biancazapatka.com, 1 +biancolievito.it, 1 +bianinapiccanovias.com, 1 +biano-ai.com, 1 +bianyanan.xyz, 1 +biapinheiro.com.br, 1 +biasmath.es, 1 +biathloncup.ru, 1 +biaxin.cf, 1 +biaxin.ml, 1 +bibet365.com, 1 +bibhub.org, 1 +bibi-xxx.com, 1 +bibica.net, 1 +bibisbootypalace.de, 1 +bibitbunga.com, 1 +bible-maroc.com, 1 +bible.ru, 1 +bible4u.net, 1 +bibleonline.ru, 1 +biblesignposts.com, 1 +bibleversesfordailyliving.com, 1 +biblia.es, 1 +bibliaon.com, 1 +bibliatodo.com, 1 +biblio.wiki, 1 +biblioblog.fr, 1 +bibliobus.ch, 1 +bibliogram.art, 1 +bibliomarkt.ch, 1 +biblionaut.net, 1 +biblionix.com, 1 +biblioporn.com, 1 +bibliotecadeseguranca.com.br, 1 +bibliotecaguate.ml, 1 +biblioteka-online.tk, 1 +biblioteka17.tk, 1 +bibliotekasnow.org, 1 +biboran.ga, 1 +biboumail.fr, 1 +bibuch.com, 1 +bic.co.bw, 1 +bicecontracting.com, 1 +bicha.net, 1 +bichonfrise.com.br, 1 +bichonmaltes.com.br, 1 +bicicletassym.com, 1 +bicicletassym.com.co, 1 +bicignet.ga, 1 +bicommarketing.com, 1 +bicromoestudio.com, 1 +bicstone.me, 1 +bicubic.tk, 1 +bicycle-events.com, 1 +bicycle-works.com, 1 +bicycleframeiz.com, 1 +bidaah.tk, 1 +bidadari.my, 1 +biddl.com, 1 +biddle.co, 1 +bidman.cz, 1 +bidman.eu, 1 +bidonline.tk, 1 +bieg.tk, 1 +biegal.ski, 1 +biegi.tk, 1 +biegner-technik.de, 1 +biehlsoft.info, 1 +biekos.com, 1 +bielefailed.de, 1 +bien-etre-sante.info, 1 +biene.rocks, 1 +bienestarfacial.com, 1 +bienestarinmobiliarioyaliadas.com, 1 +bienhacerlimpiezas.es, 1 +bienici.com, 1 +bienoubien.org, 1 +biensenvue.com, 1 +bienstar.tv, 1 +bienvenidoamerica.com, 1 +bienvenue.tk, 1 +bier-brothers.tk, 1 +bierbaumer.net, 1 +bierbrouwerijderoos.nl, 1 +bierochs.org, 1 +bierwebshop.be, 1 +bieser.ch, 1 +biester.pro, 1 +bietinidesign.be, 1 +bietthudangcap.vn, 1 +bieville-beuville.fr, 1 +biflosgknm.tk, 1 +bifm.de, 1 +bifrost.cz, 1 +biftin.net, 1 +big-books.gq, 1 +big-bounce.co.uk, 1 +big-file.tk, 1 +big-music.tk, 1 +big-papa.tk, 1 +big-tits-video.ru, 1 +bigalba.ga, 1 +bigambitions.co.za, 1 +bigband.tk, 1 +bigbangcompetitions.co.uk, 1 +bigbank.ee, 1 +bigbearkh.com, 0 +bigbeats.tk, 1 +bigbendcoffeeroasters.com, 0 +bigbendguide.com, 1 +bigbenny.tk, 1 +bigbluecomputers.tk, 1 +bigbluedoor.net, 1 +bigboard.tk, 1 +bigboris.tk, 1 +bigbouncebouncycastles.co.uk, 1 +bigbouncetheory.co.uk, 1 +bigbounceuk.com, 1 +bigbunce.ru, 1 +bigbyte.com.np, 1 +bigcakes.dk, 1 +bigchance.tk, 1 +bigchris.tk, 1 +bigclassaction.com, 1 +bigcorestintas.com.br, 1 +bigcountry.com.br, 1 +bigdaddyslash.tk, 1 +bigdatatop.cf, 1 +bigdinosaur.org, 1 +bigdiscounts.tk, 1 +bigeaglesacademy.gq, 1 +bigeasyfences.com, 1 +bigeasygrille.com, 1 +bigfreebielist.tk, 1 +bigfuckin.rocks, 1 +biggernews.gq, 1 +biggerpicture.agency, 1 +biggles.io, 1 +bighome.ml, 1 +bighouse-events.co.uk, 1 +bigideasnetwork.com, 1 +bigio.com.br, 1 +biglagoonrentals.com, 1 +biglistofporn.com, 1 +bigmoney.nu, 1 +bigmountainmail.com, 1 +bigone.com, 1 +bigorbitgallery.org, 1 +bigpage.tk, 1 +bigpicture-learning.com, 1 +bigprintinglasvegas.com, 1 +bigpurse.tk, 1 +bigrender.tk, 1 +bigsam.us, 1 +bigserp.com, 1 +bigshare.ga, 1 +bigshopper.com, 1 +bigshopper.nl, 1 +bigshort.org, 1 +bigsister.tk, 1 +bigsisterchannel.com, 1 +bigskylifestylerealestate.com, 1 +bigskymontanalandforsale.com, 1 +bigthree.ga, 1 +bigthunder.ca, 1 +bigtimeiq.com, 1 +bigudi.ee, 1 +bihaberkalma.com, 1 +bijancompany.com, 1 +bijlesbart.nl, 1 +bijlesportal.nl, 1 +bijloke.gent, 1 +bijlokesite.be, 1 +bijlokesite.gent, 1 +bijou.be, 1 +bijoulux.co.uk, 1 +bijouxcherie.com, 1 +bijuteriicualint.ro, 1 +bijzonderekiekjes.nl, 1 +bijzonderekoorprojecten.nl, 1 +bike-kurse.ch, 1 +bike-liptov.tk, 1 +bike-shack.com, 1 +bike-style.tk, 1 +bikebay.it, 1 +bikebristol.com, 1 +bikeclub.tk, 1 +bikehistory.org, 1 +bikemod.de, 1 +biker.dating, 1 +bikerebel.com, 0 +bikersclub.tk, 1 +bikesandbits.tk, 1 +bikeshopitalia.com, 1 +bikesquadron.com, 1 +bikestream.tk, 1 +biketrainer.tk, 1 +bikhof.com, 1 +biki.com, 1 +bikini-shop.tk, 1 +bikinibich.tk, 1 +bikinis.tk, 1 +bikiniseli.com, 1 +bikkelbroeders.com, 0 +bikkelbroeders.nl, 0 +bikyaku.fun, 1 +bilalic.com, 1 +bilalkilic.de, 1 +bilbao.tk, 1 +bilbayt.com, 1 +bilder-designs.de, 1 +bildermachr.de, 1 +bildiri.ci, 1 +bildkomponist.de, 1 +bildschirmflackern.de, 1 +biletru.net, 1 +biletvkrym.ga, 1 +biletyplus.com, 1 +biletyplus.ua, 1 +bilgehan.net, 1 +bilgiliksel.com, 1 +bilgo.com, 1 +bilibili.link, 1 +bilibili.ooo, 1 +bilicdn.pw, 1 +bilimal.kz, 1 +bilimoe.com, 1 +bilingualunit.tk, 1 +bilke.org, 1 +billaud.eu.org, 1 +billboard-panama.ml, 1 +billbuddy.co.uk, 1 +billcompare.ga, 1 +billcomparison.ga, 1 +billets-avion.tk, 1 +billfazz.com, 1 +billgoldstein.name, 1 +billgradywebdesign.com, 1 +billhartzer.com, 1 +billiardmaster.com.ua, 1 +billiebikes.com, 1 +billigastehemsidan.se, 1 +billiger-mietwagen.de, 1 +billigerfinder.de, 1 +billigespill.no, 1 +billigpoker.dk, 1 +billingsmtpublicworks.gov, 1 +billionaire.ml, 1 +billionaire365.com, 1 +billionkiaparts.com, 1 +billkochman.com, 1 +billogr.am, 1 +billogram.be, 1 +billogram.ch, 1 +billogram.co, 1 +billogram.co.uk, 1 +billogram.com, 1 +billogram.de, 1 +billogram.es, 1 +billogram.eu, 1 +billogram.fi, 1 +billogram.fr, 1 +billogram.io, 1 +billogram.it, 1 +billogram.me, 1 +billogram.net, 1 +billogram.nl, 1 +billogram.nu, 1 +billogram.org, 1 +billogram.se, 1 +billogramcontent.com, 1 +billograminternal.com, 1 +billogramstatic.com, 1 +billogramtest.com, 1 +billopay.com, 1 +billopay.de, 1 +billopay.se, 1 +billpro.com, 0 +billpro.com.au, 1 +billrobinson.io, 1 +billy.pictures, 1 +billy.wales, 1 +billybob.tk, 1 +billyoh.com, 1 +billywig.stream, 1 +biloxihistoricalsociety.org, 1 +biloxisportfishing.com, 1 +bilsho.com, 1 +biltmoreatthepark.com, 1 +biltullen.com, 1 +bilyonaryo.com.ph, 1 +bim.physio, 1 +bim0s.com, 1 +bimachi.ir, 1 +bimacitizen.com, 1 +bimbobakeriesusa.com, 0 +bimbole.it, 1 +bimechanics.com, 1 +bimibroccoli.co.uk, 1 +bimibroccoli.com, 1 +bimibroccoli.dk, 1 +bimibroccoli.it, 1 +bimibroccoli.nl, 1 +bimibroccoli.se, 1 +bimibrocoli.fr, 1 +bimibrokkoli.de, 1 +bimmae.com, 1 +bimmerlabs.com, 1 +bimoge.tk, 1 +bimsynergistics.com, 1 +bin95.com, 1 +bina.az, 1 +binairy.com, 1 +binairy.nl, 1 +binam.center, 0 +binans.co, 1 +binans.com, 1 +binans.com.tr, 1 +binans.io, 1 +binans.net, 1 +binans.xyz, 1 +binaries.fr, 1 +binarization.net, 1 +binary.house, 1 +binary.ninja, 1 +binaryabstraction.com, 1 +binaryappdev.com, 1 +binarycreations.scot, 1 +binarydream.fi, 1 +binaryevolved.com, 1 +binarypuzzle.nl, 1 +binarystud.io, 1 +binaryvision.tk, 1 +binbin9.com, 1 +bind.ch, 1 +binding-problem.com, 1 +bing.com, 1 +bingcheung.com, 1 +bingchunmoli.com, 0 +bingedb.com, 1 +bingle.nu, 1 +bingo-wear.com, 1 +bingo9.net, 1 +bingobank.org, 1 +bingoclub.ga, 1 +bingoela.com, 1 +bingofriends.com, 1 +bingohalls.ca, 1 +binhdang.me, 0 +binhex.net, 1 +binhminhpc.com, 1 +binhp.com, 1 +binimo.com, 1 +biniou.net, 1 +binkanhada.biz, 1 +binkconsulting.be, 1 +binnenmeer.de, 1 +binoqlo.com, 1 +binoro.de, 1 +binproz.com, 1 +binson-museum.tk, 1 +binsp.net, 1 +bintach.com, 1 +bintangsyurga.com, 1 +bintelligence.cl, 1 +bintelligence.info, 1 +bintelligence.nl, 1 +binti.com, 1 +bintoca.com, 1 +bintooshoots.com, 1 +bintube.com, 1 +bio-disinfestazione.it, 1 +bio-farma.net, 1 +bio-feed.org, 1 +bio-place.com, 1 +bio24.si, 0 +bioamtw.com, 1 +bioastin.de, 1 +bioatelier.it, 1 +bioblog.tk, 1 +biobuttons.ch, 1 +biocal.eu, 1 +biocal.nl, 1 +biochart.ga, 1 +biocheminee.com, 1 +bioclaudia.it, 1 +bioconus.com, 1 +biocrafting.net, 1 +biodiagnostiki.clinic, 1 +biodieselbr.com, 1 +biodieseldata.com, 1 +biodit.com, 1 +biodobavki.tk, 1 +biodots.at, 1 +biodots.eu, 1 +biodots.info, 1 +biodots.it, 1 +bioedilizia.roma.it, 1 +bioemprendiendo.com, 1 +bioequivalence.design, 1 +bioetco.ch, 1 +bioexistencialismo.tk, 1 +bioexploratorium.pl, 1 +biofattorietoscane.it, 1 +bioforce.tk, 1 +bioformula.org, 1 +biogaspuxin.es, 1 +biogecho.ch, 0 +biogecho.swiss, 0 +biogeist.de, 1 +biogenius.ca, 1 +bioghalm.com, 1 +biogiardinaggio.it, 1 +biographywiki.net, 1 +biohappiness.com, 1 +bioharmony.ca, 1 +biohazardland.tk, 1 +biohazardonline.tk, 1 +biohazardous.tk, 1 +biointelligence-explosion.com, 1 +biokal-labsystems.eu, 1 +biokal-labsystems.nl, 1 +biokal.com, 1 +biokal.eu, 1 +biokal.nl, 1 +biokemonline.com, 1 +bioknowme.com, 1 +biol.moscow, 1 +biol.spb.ru, 1 +biolack.cf, 1 +biolact.tk, 1 +bioleev.sklep.pl, 1 +biolegsanonims.tk, 1 +bioligo.ch, 0 +biolika.ua, 1 +biolmarket.ru, 1 +biologie-seite.de, 1 +biologis.ch, 1 +biologo.club, 1 +biology-colleges.com, 1 +biomag.it, 1 +biomassinfo.jp, 1 +biomathalliance.org, 1 +biomax-mep.com.br, 1 +biomechanics.tk, 1 +biomechanoid.tk, 1 +biomed-hospital.ch, 1 +biomed.ch, 1 +biometrics.gov, 1 +biomin.co.uk, 1 +biomod.tk, 1 +biomodra.cz, 1 +biomon.lt, 1 +bionaturalcosmetic.it, 1 +bionezis.com, 1 +bionic-karnage.tk, 1 +bionicman.name, 1 +bionovanaturalpools.com, 1 +biopreferred.gov, 1 +biopsychiatry.com, 1 +bioresonanz-ibiza.com, 1 +biosafe.ch, 0 +biosalts.it, 1 +biosbits.org, 1 +biosearch.tk, 1 +bioselect.com.cy, 1 +bioshine.com.sg, 1 +bioshome.de, 1 +biosignalanalytics.com, 1 +biospeak.solutions, 1 +biospw.com, 1 +biotal.ua, 1 +biotanquesbts.com, 1 +biotec.tk, 1 +biotecommunity.com, 1 +bioteebook.com, 1 +biotin.ch, 1 +biotin24.cf, 1 +biowtage.gq, 1 +bip.gov.sa, 0 +bipedecurieux.com, 1 +bipolardisorderexplained.com, 1 +bipyo.com, 1 +birbaumer.li, 1 +birchbarkfurniture.ch, 1 +birchbarkfurniture.com, 1 +birchbarkfurniture.fr, 1 +birchlane.com, 1 +birdbrowser.com, 1 +birdfeeder.online, 1 +birdgifs.nz, 1 +birdie.pt, 1 +birdiehosting.nl, 1 +birdsite.ga, 1 +birdslabel.com, 1 +birdsnow.com, 1 +birdspundit.com, 1 +birdygaia.com, 1 +birdymanbestreviews.com, 1 +birgit-rydlewski.de, 1 +birgitandmerlin.com, 1 +birjdid.tk, 1 +birkengarten.ch, 1 +birkenstab.de, 1 +birkhoff.me, 1 +birlikdayanisma.com, 1 +birmans.tk, 1 +birminghamal911.gov, 1 +birminghamsunset.com, 1 +birobidjan.tk, 1 +birosuli.hu, 1 +birsinghdhami.com.np, 1 +birtamode.tk, 1 +birthday-to-you.com, 1 +birthdaytip.com, 1 +birthright.host, 1 +birulevo.tk, 1 +birzan.org, 1 +birzman.ga, 1 +bischoff-mathey.family, 1 +biscuit.town, 1 +biscuitcute.com.br, 1 +biscuits-rec.com, 1 +biscuits-shop.com, 1 +biser-borisov.eu, 1 +biser.online, 1 +bishopp.com.au, 1 +bishopscourt-hawarden.co.uk, 1 +bishoptx.com, 1 +bisik.ml, 1 +bisisecurity.com, 1 +bisix.tk, 1 +bismarck-tb.de, 1 +bismi.solutions, 1 +biso.ga, 1 +bisoga.ga, 1 +bisq.community, 1 +bisq.network, 1 +bisq.services, 1 +bisq.wiki, 1 +bisrockonline.tk, 1 +bissalama.org, 1 +bisschopssteeg.nl, 1 +bistro-dengi.ml, 1 +bistrocean.com, 1 +bistrodeminas.com, 1 +bistroservice.de, 1 +bistrotdelagare.fr, 1 +bistrozaim.ml, 1 +bit-and.com, 1 +bit-cloud.de, 0 +bit-sentinel.com, 1 +bit-service-aalter.be, 1 +bit.biz.tr, 1 +bit8.com, 0 +bitaccelerate.com, 1 +bitace.com, 0 +bitar.is, 1 +bitazza.com, 1 +bitbank.cc, 1 +bitbank.cf, 1 +bitbincomputers.com, 1 +bitbonus.cf, 1 +bitbonusss.tk, 1 +bitbox.me, 1 +bitbroker.exchange, 1 +bitbucket.com, 1 +bitbucket.io, 1 +bitbucket.org, 1 +bitburner.de, 1 +bitcalt.eu.org, 1 +bitcalt.ga, 1 +bitclusive.de, 1 +bitcoin-casino-no-deposit-bonus.com, 1 +bitcoin-casino.monster, 1 +bitcoin-class.com, 1 +bitcoin-daijin.com, 1 +bitcoin-exchange.ga, 1 +bitcoin-fauset.cf, 1 +bitcoin-india.net, 1 +bitcoin-india.org, 1 +bitcoin-news.info, 1 +bitcoin-wizards.com, 1 +bitcoin-youtube.net, 1 +bitcoin.asia, 1 +bitcoin.ch, 1 +bitcoin.co.nz, 1 +bitcoin.de, 1 +bitcoin.im, 1 +bitcoin.info, 1 +bitcoin.org, 1 +bitcoin.us, 1 +bitcoinbitcoin.com, 1 +bitcoinbot.tk, 1 +bitcoincasino.blog, 1 +bitcoincasino.link, 1 +bitcoincasino.monster, 1 +bitcoincasino.tech, 1 +bitcoincasino.today, 1 +bitcoincasinos.pro, 1 +bitcoincore.org, 1 +bitcoineffect.ml, 1 +bitcoinera-review.com, 1 +bitcoinfaucet.tech, 1 +bitcoinfees.net, 1 +bitcoingambling.club, 1 +bitcoingambling.pro, 1 +bitcoingames.world, 1 +bitcoingroup.ga, 1 +bitcoinheaders.org, 1 +bitcoinindia.com, 1 +bitcoinissafe.com, 1 +bitcoinjpn.com, 1 +bitcoinkaufen.me, 1 +bitcoinkaufen.news, 1 +bitcoinkurs.world, 1 +bitcoinmakesense.com, 1 +bitcoinnews.digital, 1 +bitcoinnews.guru, 1 +bitcoinnews.world, 1 +bitcoinprice.buzz, 1 +bitcoinprice.cloud, 1 +bitcoinprice.international, 1 +bitcoinprice.news, 1 +bitcoinprice.pizza, 1 +bitcoinprice.rocks, 1 +bitcoinprice.world, 1 +bitcoinrush.tk, 1 +bitcoinseed.net, 1 +bitcoinset.pl, 1 +bitcoinslots.info, 1 +bitcoinsv.io, 1 +bitcointech.ga, 1 +bitcointhefts.com, 1 +bitcoinwalletscript.tk, 1 +bitcoinx.ro, 1 +bitcoinyab.com, 1 +bitcork.io, 1 +bitcrazy.org, 1 +bitech-ec.com, 1 +bitedge.com, 0 +bitenose.com, 1 +bitenose.net, 1 +bitenose.org, 1 +bitewinggames.com, 1 +bitex.la, 1 +bitfarm-archiv.com, 1 +bitfarm-archiv.de, 1 +bitfasching.de, 0 +bitfehler.net, 1 +bitfinder.nl, 1 +bitforge.tk, 1 +bitfuse.net, 1 +bitgain-leverage.com, 1 +bitgarant.tk, 1 +bitgo.com, 1 +bitgrapes.com, 1 +bitguerrilla.com, 1 +bithausen.io, 1 +bither.net, 1 +bititrain.com, 1 +bitjunkiehosting.com, 1 +bitking-trading.com, 1 +bitkub-app.com, 1 +bitkub-invest.com, 1 +bitlaunch.io, 1 +bitljettnu.gq, 1 +bitlo.com, 1 +bitlo.com.tr, 1 +bitlo.io, 1 +bitlo.org, 1 +bitloco.org, 1 +bitmag.ml, 1 +bitmain.com.ua, 1 +bitmaincare.com.ua, 1 +bitmaincare.ru, 1 +bitmainwarranty.com.ua, 1 +bitmainwarranty.ru, 1 +bitmarket.net, 1 +bitmart.com, 1 +bitmessage.ch, 1 +bitmexin.com, 1 +bitmidi.com, 1 +bitmine.gq, 1 +bitminer.com.br, 1 +bitminter.com, 1 +bitmix.biz, 1 +bitmoji.com, 1 +bitnoise.nl, 1 +bito3d.com.br, 1 +bitoll1.com, 1 +bitolls.com, 1 +bitovayatehn.tk, 1 +bitplay.space, 1 +bitpod.de, 1 +bitpoll.de, 1 +bitpoll.org, 1 +bitpress.pro, 1 +bitpumpe.net, 1 +bitradius.com, 1 +bitrate.tk, 1 +bitref.com, 1 +bitrefill.com, 1 +bitrefill.info, 1 +bitroll.com, 0 +bitrush.nl, 1 +bits-hr.de, 1 +bits.org.ng, 1 +bitsafe.com.my, 1 +bitsalt.com, 1 +bitsandpc.co.za, 1 +bitsellx.com, 1 +bitshaker.net, 1 +bitsight.net, 1 +bitsite.com, 1 +bitski.com, 1 +bitskins.co, 1 +bitsler.ie, 1 +bitso.com, 1 +bitsoffreedom.nl, 1 +bitspaceonline.ml, 1 +bitstage.uk, 1 +bitstep.ca, 1 +bitstorm.nl, 1 +bitstorm.org, 1 +bitsum.com, 1 +bitsync.nl, 1 +bitten.pw, 1 +bitterspringscabins.com.au, 1 +bittersweetcandybowl.com, 1 +bittervault.xyz, 1 +bittimaatti.fi, 1 +bittiraha.fi, 1 +bittivarasto.fi, 1 +bittounsi.com, 1 +bittylicious.com, 1 +bituptick.com, 0 +bitvegas.com, 0 +bitvest.io, 1 +bitvps.com, 1 +bitwarden.com, 1 +bitwoci.pt, 1 +bitwok.es, 1 +bitwolk.nl, 1 +bitwrought.net, 1 +bitxel.com.co, 0 +bityes.org, 1 +biupay.com.br, 1 +biurokarier.edu.pl, 1 +biuropulawy.pl, 1 +bivi.us, 0 +bixbasement.com, 1 +bixbydevelopers.com, 1 +bixmaster.tk, 1 +bixservice.com, 1 +biysk.ml, 1 +biz-architect.com, 1 +biz-pak.ml, 1 +biz-secrety.gq, 1 +biz-secrety.ml, 1 +biz-seecrets.gq, 1 +biz4x.com, 1 +bizbelarus.tk, 1 +bizdir.tk, 1 +bizeasesupport.com, 1 +bizeau.ch, 1 +bizedge.co.nz, 1 +bizfavor.ml, 1 +bizgo.nl, 1 +bizify.co.uk, 1 +bizlatinhub.com, 1 +biznakenya.com, 1 +biznes-sekrety.cf, 1 +biznes-sekrety.gq, 1 +biznes-sekrety.tk, 1 +biznes.cf, 1 +biznesinfo.pl, 1 +biznesone.ga, 1 +biznesonline.info, 1 +biznet.tk, 1 +bizniskatalog.mk, 1 +biznpro.ru, 1 +bizor.tk, 1 +bizpay.su, 1 +bizstarter.cz, 1 +bizsugar.ga, 1 +bizteam.ga, 1 +biztera.com, 1 +biztok.eu, 1 +biztouch.work, 1 +bizzdesign.com, 1 +bizzit.se, 0 +bizzvisor.site, 0 +bizzybee.buzz, 1 +bjarnerest.de, 1 +bjarno.xyz, 1 +bjc.hu, 1 +bjecard.buzz, 1 +bjelimici.com, 1 +bjfuli.com, 1 +bjl688.cc, 1 +bjmgeek.science, 1 +bjmun.cn, 1 +bjoe2k4.de, 1 +bjolanta.pl, 1 +bjordanov.com, 1 +bjornhelmersson.se, 1 +bjornjohansen.no, 1 +bjrn.io, 1 +bjs.com.au, 1 +bjsbouncycastles.com, 1 +bjtxl.cn, 1 +bjut.photos, 1 +bk-wife.com, 1 +bk622.com, 1 +bk725.com, 1 +bka.li, 1 +bkamp.de, 1 +bkentertainments.co.uk, 1 +bkgatl.com, 1 +bkhpilates.co.uk, 1 +bkkf.at, 1 +bkkposn.com, 1 +bklaindia.com, 1 +bklynsoap.com, 1 +bkositspartytime.co.uk, 1 +bkr.com, 1 +bkramericas.com, 1 +bkt.to, 1 +bkulup.com, 1 +bl-builder.tk, 1 +bl00.se, 1 +bl4ckb0x.biz, 1 +bl4ckb0x.com, 1 +bl4ckb0x.de, 1 +bl4ckb0x.eu, 1 +bl4ckb0x.info, 1 +bl4ckb0x.net, 1 +bl4ckb0x.org, 1 +blaargh.com, 1 +blaarmeersen.be, 1 +blaauwgeers.pro, 1 +blaauwgeers.wiki, 1 +blabber.im, 1 +blablacar.co.uk, 1 +blablacar.com, 1 +blablacar.com.tr, 1 +blablacar.com.ua, 1 +blablacar.de, 1 +blablacar.es, 1 +blablacar.fr, 1 +blablacar.hr, 1 +blablacar.hu, 1 +blablacar.in, 1 +blablacar.it, 1 +blablacar.mx, 1 +blablacar.nl, 1 +blablacar.pl, 1 +blablacar.pt, 1 +blablacar.ro, 1 +blablacar.rs, 1 +blablacar.ru, 1 +black-air-rpg.com, 1 +black-blog.com, 1 +black-diamonds.cf, 1 +black-friday.org.il, 1 +black-gay-porn.biz, 1 +black-holes.org, 1 +black-khat.com, 1 +black-magic-love-spells.com, 1 +black-mail.nl, 1 +black-market.ga, 1 +black-pool.net, 1 +black-raven.fr, 1 +black.dating, 1 +black1ce.com, 1 +blackandwhite.tk, 1 +blackapron.com.br, 1 +blackarch.sk, 1 +blackarts.co.za, 1 +blackbag.nl, 1 +blackbam.at, 1 +blackbbwvideos.com, 1 +blackberrycentral.com, 1 +blackbird-whitebird.com, 1 +blackbirdproperties.tk, 1 +blackboxcity.tk, 1 +blackboxconnections.com, 1 +blackburn.link, 0 +blackbyte.it, 1 +blackcat.ca, 1 +blackcatinformatics.ca, 1 +blackcatinformatics.com, 1 +blackchristmas.tk, 1 +blackcicada.com, 1 +blackco.ga, 1 +blackdiam.net, 1 +blackdot.casa, 1 +blackdown.de, 1 +blackdragoninc.org, 1 +blackeaglenet.tk, 1 +blackedbyte.com, 1 +blackevent.be, 1 +blackfire.io, 1 +blackfirecrew.tk, 1 +blackflysolutions.ca, 1 +blackforeststheoriginal.cf, 1 +blackforlife.me, 1 +blackfridaynew.com, 1 +blackgamelp.de, 1 +blackgate.org, 1 +blackhat.dk, 1 +blackhat.nz, 0 +blackhawkup.com, 1 +blackhealthwealth.com, 1 +blackhelicopters.net, 1 +blackhillsinfosec.com, 1 +blackhost.org, 1 +blackishtv.com, 1 +blackjackballroomcasino.info, 1 +blackkeg.ca, 1 +blackl.net, 1 +blacklane.com, 1 +blacklightparty.be, 1 +blacklodge.tk, 1 +blackmafia.tk, 1 +blackmagic.sk, 1 +blackmagickwitch.com, 1 +blackmagicshaman.com, 1 +blackmaskpro.gq, 1 +blackminds.tk, 1 +blackmodelsusa.tk, 1 +blacknova.io, 1 +blackoutzone.tk, 1 +blackpapermoon.de, 1 +blackpayment.ru, 1 +blackphantom.de, 1 +blackphoenix.de, 1 +blackpi.dedyn.io, 1 +blackriverfalls.tk, 1 +blackroadphotography.de, 1 +blackroses.tk, 1 +blackscytheconsulting.com, 1 +blackseals.net, 1 +blacksearegion.ru, 1 +blacksega.ga, 1 +blackshark.cf, 1 +blacksheepsw.com, 1 +blacksniffer.tk, 1 +blackspark.tk, 1 +blacksport.ru, 1 +blackstonepress.tk, 1 +blackstrapsecurity.com, 1 +blackstump.xyz, 1 +blacksuitmedia.com, 1 +blacksvets.co.uk, 1 +blackswan.tk, 1 +blackteam.org, 1 +blacktemplars.tk, 1 +blackthrone.tk, 1 +blacktown.eu, 1 +blacktownbuildingsupplies.com.au, 1 +blacktubes.cf, 1 +blacktubes.ga, 1 +blacktubes.ml, 1 +blacktype.bet, 1 +blackwaterutilities.tk, 1 +blackwidow.tk, 1 +blackwoodrugby.tk, 1 +blackworld.ga, 1 +blackyau.cc, 0 +blackys-chamber.de, 0 +blackzebra.audio, 1 +bladebotlist.xyz, 0 +bladesofteal.com, 1 +blago-sostoyanie.ga, 1 +blago-sostoyanie.ml, 1 +blago.tk, 1 +blagosvet.ml, 1 +blahaj.eu, 1 +blaindalefarms.com, 1 +blainecosheriff-ok.gov, 1 +blairmitchelmore.com, 1 +blaise.io, 1 +blaizer.tk, 1 +blakecoin.org, 1 +blakekhan.com, 1 +blakezone.com, 1 +blako-squad.tk, 1 +blamefran.net, 1 +blaming.me, 1 +blanboom.org, 1 +blancamartinez.com, 1 +blanickymanifest.eu, 1 +blankersfamily.com, 1 +blanket.technology, 1 +blankhang.com, 1 +blankpage.link, 1 +blankpagebiz.com, 1 +blankstore.com.pe, 1 +blankstyle.com, 1 +blantik.net, 1 +blantr.com, 1 +blanx.de, 1 +blasorchester-runkel.de, 1 +blastentertainment.co.nz, 1 +blastentertainment.com.au, 1 +blastersklan.com, 1 +blastoffbuisness.in, 1 +blatnic.eu, 1 +blatnice.fun, 1 +blatnice.ml, 1 +blatnice.online, 1 +blatnice.tk, 1 +blau-weiss-stolberg.de, 1 +blaudev.es, 1 +blauequelle.de, 1 +blaulicht-giessen.de, 1 +blaumedia.com, 1 +blautiefe.de, 1 +blauwgras.nl, 1 +blauwwit.be, 1 +blavaty.tk, 1 +blayne.me, 0 +blayneallan.com, 0 +blazebd.com, 1 +blazeit.io, 1 +blazing.cz, 1 +blazingsaddles.ga, 1 +blazingsuns.tk, 1 +blazor.nl, 1 +blbcleaningservices.com.au, 1 +blbet365.com, 1 +blblblblbl.fr, 1 +bleaching-tipps.de, 1 +bleaklyrics.tk, 1 +bleatingsheep.org, 0 +blechbuexn.de, 1 +bleche-onlineshop.at, 1 +bleche-onlineshop.de, 1 +blechinger.io, 1 +bleekerenbleeker.nl, 1 +bleep.zone, 1 +bleepplc.co.uk, 1 +blender.io, 1 +blenderinsider.com, 1 +blenderrecipereviews.com, 1 +blenderwallet.io, 1 +blending.kr, 1 +blendle.com, 1 +blendle.nl, 1 +blendr.com, 1 +blendstudios.com, 1 +blenheimears.com, 1 +blenneros.net, 0 +blessedgeeks.org, 1 +blessedgeeks.social, 1 +blessedguy.com, 1 +bleutecmedia.com, 1 +blewebprojects.com, 1 +blheritage-tours.com, 0 +bli.li, 1 +blic-zajm.gq, 1 +blichmann.eu, 1 +blicy.net, 1 +blideobames.com, 1 +blidz.com, 1 +blieque.co.uk, 1 +bliesekow.net, 1 +blightnight.games, 1 +blightnight.live, 1 +blightnight.net, 1 +blightnightgame.com, 1 +blijfbij.com, 1 +blijfbij.eu, 1 +bliker.ga, 1 +blikund.swedbank.se, 1 +blindaryproduction.tk, 1 +blindfold.cf, 1 +blindpigandtheacorn.com, 1 +blinds-unlimited.com, 1 +blindscribblings.com, 1 +blindsjoburg.com, 1 +blingsparkleshine.com, 1 +blingwang.cn, 0 +blink-security.com, 1 +blinkdir.tk, 1 +blinkdrivex.com, 1 +blinken.co, 1 +blinkenlight.co.uk, 1 +blinkenlight.com.au, 1 +blinking.link, 1 +blinking.ml, 1 +blinkspeed.eu, 1 +blinniza.tk, 1 +blint.nl, 1 +blio.tk, 1 +bliss.id, 1 +blissbox.com, 1 +blissdrive.com, 1 +blissjoe.com, 1 +blissplan.com, 1 +blist.xyz, 1 +blisterreview.com, 1 +blitzarena.io, 1 +blitzga.me, 1 +blitzkrieg.tk, 1 +blitzlotto.tk, 1 +blitzpaintball.net, 1 +blitzvendor.com, 1 +blivawesome.dk, 1 +blivdj.dk, 1 +blivvektor.dk, 1 +blixtv.com, 1 +blizhost.com, 1 +blizhost.com.br, 1 +blizko.tk, 1 +blizora.com, 1 +blk-booking.com, 1 +blk-lunch.com, 1 +blkbx.eu, 1 +bllb.ru, 1 +blm.gov, 1 +blm36.cc, 1 +blm69.cc, 1 +blo-melchiorshausen.de, 1 +blobemoji.com, 1 +blobfolio.com, 1 +blobs.gg, 1 +blocher.ch, 1 +blochoestergaard.com, 1 +block-planet.xyz, 1 +block-this.com, 1 +block65.com, 1 +blockchain.com, 1 +blockchain.info, 1 +blockchain.poker, 1 +blockchainbulteni.com.tr, 1 +blockchaindaigakko.jp, 1 +blockchaininfo.news, 1 +blockchainmagazine.net, 1 +blockcheck.network, 1 +blockclique.io, 1 +blocked.icu, 1 +blockedyourcar.com, 1 +blockedyourcar.net, 1 +blockedyourcar.org, 1 +blockexplorer.online, 1 +blockfi.com, 1 +blockified.io, 1 +blockmetry.com, 1 +blocknodes.live, 1 +blocksettle.com, 1 +blockshopauto.com, 1 +blockstudio.it, 1 +blocktab.io, 1 +blockwatch.cc, 0 +blockxit.de, 1 +bloemenbesteld.nl, 1 +bloemendal.me, 1 +blog-garage.com, 1 +blog-investimenti.it, 1 +blog-ludmily.ml, 1 +blog-page.tk, 1 +blog-story.tk, 1 +blog.gparent.org, 1 +blog.gt, 1 +blog.kg, 1 +blog.lookout.com, 0 +blog.torproject.org, 0 +blog.vu, 1 +blogabout.ru, 1 +blogaid.net, 1 +bloganchoi.com, 1 +blogaram.tk, 1 +blogarts.net, 1 +blogbooker.com, 1 +blogcast.com, 1 +blogconcours.net, 1 +blogcosmeticsurgeon.ga, 1 +blogcuaviet.com, 1 +blogdelgloton.com, 1 +blogdelosjuguetes.com, 1 +blogdeyugioh.com, 1 +blogdieconomia.it, 1 +blogdimoda.com, 1 +blogdimotori.it, 1 +blogexpress.org, 1 +bloggermumofthreeboys.com, 1 +bloggerse.com, 1 +bloggersonlinetrainings.tk, 1 +blogging-life.com, 1 +bloggingkits.org, 1 +bloggingsaif.com, 1 +bloggingtipsfornewblogger.com, 1 +bloggingwithchildren.com, 1 +bloggytalky.com, 1 +bloginbeeld.nl, 1 +blogit.fi, 1 +bloglogistics.com, 1 +blognews.cf, 1 +blognone.com, 1 +blogofant.de, 1 +blogofapps.com, 1 +blogom.at, 1 +blogonblogspot.com, 0 +blogpress.co.il, 1 +blogpronto.com.br, 1 +blogredmachine.com, 1 +blogreen.org, 1 +blogsked.com, 1 +blogsnote.xyz, 1 +blogstar.tk, 1 +blogtechnologiczny.pl, 1 +blogtechvn.com, 1 +blogthetindung.com, 1 +blogtroterzy.pl, 1 +bloguser.ru, 1 +blogvadim.ga, 1 +blogyaren.com, 1 +blokuhaka.fr, 1 +blomberg.name, 1 +blomberguk.com, 1 +bloms.de, 1 +blonde-hexe.net, 1 +blood-kirsche.tk, 1 +blood4pets.tk, 1 +bloodandbones.tk, 1 +bloodhunt.eu, 1 +bloodhunt.pl, 1 +bloodpop.tk, 1 +bloodsports.org, 1 +bloody-hosting.tk, 1 +bloody.pw, 1 +bloodybiz-news.tk, 1 +bloodycraft.ml, 1 +bloom-avenue.com, 1 +bloom.sh, 1 +bloomingwoods.tk, 1 +bloomnail.net, 1 +bloomppm.com, 1 +bloomscape.com, 1 +blopezabogado.es, 1 +blossomsflowerboutique.com.au, 1 +blrjmt.com, 1 +blsindia-canada.com, 1 +blsindia.sg, 1 +bltc.co.uk, 1 +bltc.com, 1 +bltc.net, 1 +bltc.org, 1 +bltc.org.uk, 1 +bluavido.ml, 1 +blubbablasen.de, 1 +blubop.fr, 1 +blubux.tk, 1 +blucouriers.com.au, 1 +bludnykoren.ml, 1 +blue-gmbh-erfahrungen.de, 1 +blue-gmbh.de, 1 +blue-leaf81.net, 1 +blue-nijmegen.nl, 0 +blue-olive.co.za, 1 +blue-python.tk, 1 +blue42.net, 1 +blueangel.org.tw, 1 +blueatlasmarketing.com, 1 +bluebahari.gq, 1 +blueberrywinery.com.au, 0 +bluebie.com, 1 +bluebill.net, 1 +bluebirdelc.com, 1 +bluebirdservice.us, 1 +blueblou.com, 1 +bluebnc.com, 1 +bluecanvas.io, 1 +bluecat.tk, 1 +bluecherry.tk, 1 +bluecoastelectric.com, 1 +bluecoatnetflowsupport.com, 1 +bluecollarfetishwear.com, 1 +bluecrazii.nl, 1 +blued.moe, 1 +bluedeck.org, 1 +bluedog-security.com, 1 +blueenergy.tk, 1 +blueflare.org, 1 +bluefrag.com, 1 +bluefuzz.nl, 1 +bluegifts.ro, 1 +bluegrasscleaning.com, 1 +bluegrottoscuba.com, 1 +bluehillhosting.com, 1 +blueimp.net, 1 +bluekrypt.com, 1 +blueliquiddesigns.com.au, 1 +bluemail24.com, 1 +bluemango-studios.com, 1 +bluemanhoop.com, 1 +bluemoonrescue.org, 1 +bluemosh.com, 1 +bluemtnrentalmanagement.ca, 1 +bluenailsstudio.nl, 1 +blueneuron.tk, 1 +bluenote9.com, 1 +blueoakart.com, 1 +blueparrotpainting.com, 1 +bluepearl.tk, 1 +blueperil.de, 1 +bluepoint.foundation, 1 +bluepoint.me, 1 +bluepostbox.de, 1 +blueprintma.com, 1 +blueprintrealtytn.com, 1 +bluepromocode.com, 1 +bluerabbit.cc, 1 +bluerootsmarketing.com, 1 +blues-and-pictures.com, 1 +blues.at, 1 +bluesbarn.tk, 1 +bluesecret.co.uk, 1 +blueshouse.ro, 1 +blueskybrokerage.tk, 1 +blueskycoverage.com, 1 +blueskyinsure.com, 1 +bluesnews.tk, 1 +bluesoap.com.au, 1 +bluestardiabetes.com, 1 +bluestarroofing.com, 1 +bluestoneconstruction.com, 1 +bluestreamme.com, 1 +bluesuncamping.com, 1 +bluesunhotels.com, 1 +blueswandaily.com, 1 +bluesync.co, 1 +bluesystem.tk, 1 +bluetexservice.com, 1 +bluetomatographics.com, 1 +bluetoothspecialist.ga, 1 +bluetroodon.com, 1 +bluetrout.nl, 1 +bluewavewebdesign.com, 1 +bluewizardart.net, 1 +bluex.im, 1 +bluex.info, 1 +bluex.net, 1 +bluex.org, 1 +blueyonder.com, 1 +bluffplumber.co.za, 1 +bluheron.ca, 1 +blui.xyz, 1 +bluiandaj.ml, 1 +bluicraft.tk, 1 +bluimedia.com, 1 +bluinet.com, 1 +blumando.de, 1 +blumen-garage.de, 1 +blumenfeldart.com, 1 +blumenreviews.com, 1 +blumenversand.tk, 1 +blumiges-fischbachtal.de, 0 +blummedia.de, 1 +blundell.wedding, 1 +bluntandsnakes.com, 1 +blupig.net, 1 +bluproducts.com.es, 1 +blurringexistence.net, 1 +blurt.cf, 1 +blusens.com, 1 +blushbymounika.com, 1 +blusmurf.net, 1 +blutopia.xyz, 1 +bluuglass.com, 1 +bluxus.com, 1 +blw.moe, 1 +blyat.science, 1 +blyth.me.uk, 1 +blythwood.com, 1 +bm-i.ch, 0 +bm-immo.ch, 0 +bmbfiltration.com, 1 +bmcorp.online, 1 +bmhglobal.com.au, 1 +bmipestcontrol.com, 1 +bmk-kramsach.at, 1 +bmm.com.co, 1 +bmoabogados.com, 1 +bmoattachments.org, 1 +bmoe.eu.org, 1 +bmone.net, 1 +bmotorsports.com, 1 +bmriv.com, 1 +bmros.com.ar, 1 +bmw-motorradclub-seefeld.de, 1 +bmwcolors.com, 1 +bmyjacks.cn, 0 +bmzm.nl, 0 +bn4t.me, 1 +bnb-buddy.nl, 1 +bnb.direct, 1 +bnboy.cn, 1 +bnbsinflatablehire.co.uk, 1 +bnck.me, 1 +bngs.pl, 1 +bngsecure.com, 1 +bnin.org, 1 +bnjscastles.co.uk, 1 +bnkconsulting.info, 1 +bnstree.com, 1 +bnty.net, 1 +bnzblowermotors.com, 1 +bo-rad.de, 1 +bo1689.com, 0 +bo4tracker.com, 1 +boanastudio.com, 1 +boardfree.tk, 1 +boardgameforces.com, 1 +boardgamegeeks.de, 1 +boards.ie, 1 +boardspot.com, 1 +boat-engines.eu, 1 +boatlogs.herokuapp.com, 1 +boattour.ru, 1 +boattrader.com.au, 1 +bob-dylan.tk, 1 +bobaly.es, 1 +bobancoamigo.com, 1 +bobandducky.com, 1 +bobaobei.net, 1 +bobaobei.org, 1 +bobasy.pl, 1 +bobazar.com, 0 +bobbleheads.com, 1 +bobbyblueplumbing.com, 1 +bobbyfischer.tk, 1 +bobbyhensley.com, 1 +bobbyrobinson.tk, 1 +bobcoffee.com.br, 1 +bobcopeland.com, 1 +bobek.cz, 1 +bobertscoinrings.com, 1 +bobfilm.ml, 1 +bobigames.com, 1 +bobiji.com, 0 +bobijoel.ml, 1 +bobkoetsier.nl, 1 +bobnbounce.ie, 1 +bobnbouncedublin.ie, 1 +bobobox.net, 1 +bobruysk.tk, 1 +bobsfhairstyles.ga, 1 +bobstenancycleaning.co.uk, 1 +bobstikkers.be, 1 +bobstronomie.fr, 1 +bobtiell.com, 1 +bobvincent.com, 1 +bocaaboca.ml, 1 +bocada.com, 1 +bocahkampus.com, 1 +bocamo.it, 1 +bocawa.es, 1 +boccabell.com, 0 +bocciatitanium.com, 1 +bochantinobgyn.com, 1 +bochfernsh.com, 1 +bochs.info, 1 +bockenauer.at, 1 +bocloud.eu, 1 +bocreation.fr, 1 +bodagratis.com, 1 +bodas.com.mx, 1 +bodas.net, 1 +bodasgratis.com, 1 +bodclansite.tk, 1 +bodegagarces.tk, 1 +bodemplaten4x4.nl, 1 +bodhi.fedoraproject.org, 1 +bodin.cz, 1 +bodis.nl, 1 +bodixite.com, 1 +bodrumfarm.com, 1 +bodrus.com, 1 +bodsch.com, 1 +body-demo.tk, 1 +bodybuilding.com, 1 +bodybuilding.events, 1 +bodybuildingsupplementsexplained.com, 1 +bodybuildingworld.com, 1 +bodyconshop.com, 1 +bodygearguide.com, 1 +bodymod.tk, 1 +bodymusclejournal.com, 1 +bodypainter.pl, 1 +bodypainting.waw.pl, 1 +bodyshaping.ml, 1 +bodyshopnews.net, 1 +bodyweb.com.br, 1 +bodyworksautorebuild.com, 1 +boeah.com, 1 +boeddhashop.nl, 1 +boegli.tk, 1 +boehm.sh, 1 +boeing747.tk, 1 +boel073.nl, 1 +boeleo.ru, 1 +boem.gov, 0 +boernecancerfonden.dk, 1 +boese.one, 1 +boevik.ml, 1 +bofashion.site, 1 +boffin.tk, 1 +bofoxdesign.com, 0 +bogazreflusu.com, 1 +bogdanbiris.com, 1 +bogdancornianu.com, 1 +bogdanepureanu.ro, 1 +bogdanov.ga, 1 +bogdanow.tk, 1 +bogdatrend.ml, 1 +boggsinvesting.com, 1 +bogner.sh, 1 +bogosity.tv, 1 +bogoslov.tk, 1 +bogs-consulting.de, 1 +bogs.de, 1 +bogurl.com, 1 +bogwitch.tk, 1 +bohaishibei.com, 1 +bohan.co, 1 +bohobasics.nl, 1 +bohostijl.nl, 1 +bohramt.de, 1 +bohyn.cz, 1 +boimmobilier.ch, 0 +boingboing.net, 1 +boingo00.wtf, 1 +boip.in, 1 +boiseonlinemall.com, 1 +boizeau.fr, 1 +bojan.tk, 1 +bojanowskiszkolka.pl, 1 +bojiu99.cc, 1 +bokadoktorn-test.net, 1 +bokadoktorn.se, 1 +boke112.com, 1 +bokhylle.eu, 1 +bokka.com, 1 +bokkeriders.com, 1 +boksburgplumber24-7.co.za, 1 +bokutake.com, 1 +bol.io, 1 +bolalocobrews.co.uk, 1 +boldhaus.de, 1 +boldlegal.cz, 1 +boldogsagadni.hu, 1 +bolektro.de, 1 +boleyn.su, 1 +bolgarnyelv.hu, 1 +bolgarus.ru, 0 +bolico.de, 1 +bolivar-circuit-clerk.ms, 1 +bolivar80.com, 1 +bolivarfm.com.ve, 1 +boliviaverde.tk, 1 +bolli.tech, 1 +bollymarket.com, 1 +bollywoodacapellas4djs.tk, 1 +bollywoodgk.tk, 1 +bollywoodhdsongs.tk, 1 +bollywoodstrot.tk, 1 +bologna-disinfestazioni.it, 1 +bologoe.tk, 1 +bololo.fun, 1 +bololo.online, 1 +bolosbatiente.tk, 1 +bolotnaya.online, 1 +bolovegna.it, 1 +bolsa.tk, 1 +bolsashidrosolubles.com, 1 +bolshevik.tk, 1 +bolshoi.tk, 1 +bolshoy.tk, 1 +bolt.cm, 0 +bolt.com, 1 +boltbeat.com, 1 +bolte.org, 1 +boltenergy.ca, 1 +boltmobile.ca, 1 +bolton-consulting.org, 1 +boluwebtasarim.cf, 1 +bomb.codes, 1 +bombard.ga, 1 +bombe-lacrymogene.fr, 1 +bomberosceuta.tk, 1 +bomberus.de, 1 +bombgame.tk, 1 +bombgirls.cf, 1 +bombiaturkiye.cf, 1 +bombo.xyz, 1 +bomboniere.roma.it, 1 +bomhard.de, 1 +bomhard.net, 1 +bomhard.org, 1 +bompus.com, 1 +bonaccorso.eu, 1 +bonaemi.ga, 1 +bonami.cz, 1 +bonami.hu, 1 +bonami.pl, 1 +bonami.ro, 1 +bonami.sk, 1 +bonapeti.ml, 1 +bonawehouse.co.uk, 1 +bonbini.ga, 1 +bonbonmania.com, 0 +bonbonshop.ro, 1 +bonchaboncha.com.tw, 1 +bondagefetishstore.com, 1 +bondank.com, 1 +bondarenko.dn.ua, 1 +bondingwithbaby.ca, 1 +bondoptimiser.co.za, 1 +bondpro.gov, 1 +bondscript.tk, 1 +bondskampeerder.nl, 1 +bonebreakers.tk, 1 +bonebunny.de, 1 +boneko.de, 1 +bonesserver.com, 1 +bonfi.net, 1 +bonfireleads.com, 1 +bonfloss.com, 1 +bongbabyhouse.com, 1 +bongbabyhouse.vn, 1 +bongloy.com, 1 +bongo.cat, 1 +bongocams.webcam, 1 +bongoland.tk, 1 +bongoo.fr, 1 +bonic.tk, 1 +bonifatius-friedrich.de, 1 +bonita.com.br, 1 +bonitamacas.tk, 1 +bonito.pl, 1 +bonk.pw, 1 +bonkleagues.ml, 1 +bonn.digital, 1 +bonnant-associes.ch, 0 +bonnant-partners.ch, 0 +bonnebouffe.fr, 1 +bonniecoloring.com, 1 +bonniedraw.com, 1 +bonniekitchen.com, 1 +bonnieradvocaten.nl, 1 +bonniestylez.net, 1 +bonnsustainabilityportal.de, 1 +bonnyprints.fr, 1 +bonobo.cz, 1 +bonomi-koffie.nl, 1 +bonprix.co.uk, 1 +bonra.com, 1 +bonsaiclubkengai.tk, 1 +bonsaiclubsanvi.tk, 1 +bonsaimedia.nl, 1 +bonsi.net, 1 +bonukset.cf, 1 +bonus-kran.tk, 1 +bonus.ca, 1 +bonus.net.nz, 1 +bonusov.tk, 1 +bonusup.tk, 1 +bonux.co, 1 +boodledose.ddns.net, 1 +boodmo.com, 1 +boof.com, 0 +book-in-hotel.com, 1 +book-online.tk, 1 +bookameeting.se, 1 +bookaway.com, 1 +bookbazar.co.in, 1 +booker.ly, 1 +bookingready.com, 1 +bookingsrit.tk, 1 +bookingtool.com, 1 +bookingtool.net, 1 +bookingworldspeakers.com, 1 +bookkeepingsolutions.com.au, 1 +bookluk.com, 1 +bookmark.gq, 1 +bookmarkblog.tk, 1 +bookmarkclub.gq, 1 +bookmarked.cf, 1 +bookmarkingyourbusiness.ga, 1 +bookmarklive.cf, 1 +bookmarkup.ml, 1 +bookmarkup.tk, 1 +bookourdjs.com, 1 +bookposh.com, 1 +bookreport.ga, 1 +books-dowload.tk, 1 +books-ru.tk, 1 +books.co.ua, 1 +booksandcoffee.ml, 1 +bookshopofindia.com, 1 +booksinthefridge.at, 1 +booksjar.com, 1 +bookslibrarybooks.gq, 1 +booksmp3.com, 1 +bookstores.gq, 1 +bookstrap.ga, 1 +booktoan.com, 1 +bookworld.gr, 1 +bookzaga.com, 1 +bool.be, 1 +booldamm.llc, 1 +boomerangworkouts.com, 1 +boomersclub.com.au, 1 +boomersurf.com, 1 +boomfestival.org, 1 +boomkins.net, 1 +boomshadow.net, 1 +boomshelf.com, 1 +boomshelf.org, 1 +boomsocial.com, 1 +boomsual.com, 1 +boomtownevents.com, 1 +boomvm.pw, 1 +boonecountyfpdmo.gov, 1 +boontech.xyz, 1 +booox.biz, 1 +booox.cc, 1 +booox.info, 1 +booox.net, 1 +booox.org, 1 +booox.pw, 1 +boop.gq, 1 +boop.pro, 1 +booq.org, 1 +booquiz.com, 1 +booshka.ga, 1 +boosinflatablegames.co.uk, 1 +boosman.nu, 1 +boosmanpoolservice.com, 1 +boost.fyi, 1 +boost.ink, 1 +boostdesign.tk, 1 +boostgame.win, 1 +boostplm.com, 1 +booter.pw, 1 +bootina.com, 1 +bootjp.me, 1 +bootlesshacker.com, 1 +boots-shop.tk, 1 +bootspropertycentral.co.uk, 1 +bootswinter.tk, 1 +boozinyan.com, 1 +bopiweb.com, 1 +bopyx.com, 0 +borahan.net, 1 +boran.cl, 1 +boranco.tk, 1 +borasol.tk, 1 +borba-umov.tk, 1 +borche-imm.eu, 1 +borchers-media.de, 1 +borchers.ninja, 1 +bordadoenpedreria.com, 1 +borde.network, 1 +borderfever.cf, 1 +borderless.ro, 1 +borderless360.com, 1 +borderzoo.tk, 1 +bordes.com.ar, 1 +bordes.me, 1 +boredhackers.com, 1 +boredhousewifeconfessions.cf, 1 +borein.cf, 1 +boreo.si, 1 +boresmail.ru, 1 +borgmestervangen.xyz, 1 +borgoaureo.com, 1 +borgodigatteraia.it, 1 +boringnews.tk, 1 +boris64.net, 1 +borisenko.by, 1 +borisovv.com, 1 +borja.io, 1 +borman.biz, 1 +born2bounce.co.uk, 1 +born2dance.tk, 1 +bornandgrazed.com, 1 +bornemisszavendeghazak.hu, 1 +borneodictionary.com, 1 +bornfiber.dk, 1 +bornhack.dk, 1 +bornreality.tk, 1 +borntocover.pl, 1 +borowski.pw, 1 +borrelioz.com, 1 +borriquillacuenca.tk, 1 +borsodsakk.hu, 1 +bortebest.no, 1 +borysek.net, 1 +borysenko.se, 1 +borza.blog, 0 +borzaresearch.com, 1 +borzov.tk, 1 +bosabosa.org, 0 +bosattondskap.tk, 1 +boscbooks.com, 1 +boschee.net, 1 +boschhirtshals.dk, 1 +boschsplit.co, 1 +boschveldtuin.nl, 1 +boscoyacht.ch, 0 +boscq.fr, 1 +bosekarmelitky.cz, 1 +bosiquanao.vn, 1 +boskant.tk, 1 +boskeopolis-stories.com, 1 +bosnia-online.tk, 1 +bosonogka.tk, 1 +bospor.tk, 1 +bosquedelasimagenes.tk, 1 +boss.az, 1 +bossbabe.com, 1 +boston-sailing.com, 1 +bostonadvisors.com, 1 +bostonaoii.com, 1 +bostonblockchainassociation.org, 1 +bostonews.tk, 1 +bostonivy.co, 1 +bostonprocleaning.com, 1 +bosufitness.cz, 1 +bosun.io, 1 +bot-manager.pl, 1 +bot-socket.tk, 1 +botbrother.ml, 1 +botcamp.org, 1 +botcop.de, 1 +botcore.ai, 1 +botealis.ch, 0 +botelegram.tk, 1 +botezdepoveste.ro, 1 +botguard.net, 1 +bothive.io, 1 +boticadiservicio.com, 1 +botikadiservisio.com, 1 +botipedia.tk, 1 +botlab.ch, 1 +botmaker.tk, 1 +botmanager.pl, 1 +botmastery.com, 1 +botmedia.cf, 1 +botox.bz, 1 +botoxclinic.gr, 1 +botserver.de, 1 +botsiah.fail, 1 +botsindiscord.me, 1 +botstack.host, 1 +botticelli.tk, 1 +bottineauneighborhood.org, 1 +bottinquebec.com, 1 +bottke.berlin, 1 +bottle.li, 1 +bottom9clothing.com, 1 +bottomfeedings.tk, 1 +bou.cloud, 1 +bou.ke, 1 +bouah.net, 1 +bouchard-mathieux.com, 1 +boucherie-lesnes.fr, 1 +bouchonville-knifemaker.com, 1 +bouckaert-usedcars.be, 0 +boudah.pl, 1 +bougeret.fr, 1 +bougerpourmasante.com, 1 +bougetesfesses.fr, 1 +boughariosbros.com, 1 +boukoubengo.com, 1 +bouldercolorado.gov, 1 +bouldercountydronepilot.com, 1 +boulderlibrary.org, 1 +boulderswap.com, 1 +boulderwagonroad.org, 1 +boulevardbuildingdsm.com, 1 +boulzicourt.fr, 1 +bounce-a-roo.co.uk, 1 +bounce-abouts.com, 1 +bounce-n-go.co.uk, 1 +bounce-on.co.uk, 1 +bounce-r-us.co.uk, 1 +bounce-xtreme.co.uk, 1 +bounce4fun.co.uk, 1 +bounce4kidz.com, 1 +bounce4less.ie, 1 +bouncea-bout.com, 1 +bounceaboutandplay.co.uk, 1 +bounceaboutnewark.co.uk, 1 +bounceaboutsussex.co.uk, 1 +bouncealotcastlehire.co.uk, 1 +bouncealotnorthwest.co.uk, 1 +bounceandwobble.co.uk, 1 +bounceapp.com, 1 +bouncearoundevents.co.uk, 1 +bouncearoundsheffield.co.uk, 1 +bounceawaycastles.com, 1 +bouncebackcastles.co.uk, 1 +bouncebookings.com.au, 1 +bouncecrazy.ie, 1 +bouncejumpboston.co.uk, 1 +bouncemaniaevents.co.uk, 1 +bouncemaniainflatables.co.uk, 1 +bouncenortheast.co.uk, 1 +bouncenpaint.co.uk, 1 +bounceroos-bouncycastles.co.uk, 1 +bounceroosevents.co.uk, 1 +bouncers-bouncycastlehire.co.uk, 1 +bouncesquad.co.uk, 1 +bouncetasticuk.co.uk, 1 +bouncetheparty.co.uk, 1 +bounceunlimited.co.uk, 1 +bouncewithbovells.com, 0 +bouncewrightcastles.co.uk, 1 +bouncincastles.co.uk, 1 +bouncing4joy.co.uk, 1 +bouncingbeansinflatables.co.uk, 1 +bouncingbuddiesleicester.co.uk, 1 +bouncingbuzzybees.co.uk, 1 +bouncinghigher.co.uk, 1 +bouncy-castles-surrey.co.uk, 1 +bouncy-tots.co.uk, 1 +bouncybaileys.co.uk, 1 +bouncyball.eu, 1 +bouncyballs.org, 1 +bouncybouncyboocastlehire.co.uk, 1 +bouncycastle.net.au, 1 +bouncycastlehire-norwich.com, 1 +bouncycastlehire.co.uk, 1 +bouncycastlehireauckland.co.nz, 1 +bouncycastlehirebexley.co.uk, 1 +bouncycastlehirechelmsford.org.uk, 1 +bouncycastlehirehull.co.uk, 1 +bouncycastlehirelouth.co.uk, 1 +bouncycastlehiremalvern.co.uk, 1 +bouncycastlehireoldham.co.uk, 1 +bouncycastlehirestroud.co.uk, 1 +bouncycastlehiresurrey.co.uk, 1 +bouncycastlehiretameside.co.uk, 1 +bouncycastlehirewinchester.co.uk, 1 +bouncycastleman.co.uk, 1 +bouncycastleparade.com, 1 +bouncycastlesgalway.com, 1 +bouncycastleshire.co.uk, 1 +bouncycastleshireleeds.co.uk, 1 +bouncycastlesin.co.uk, 1 +bouncycastlesinderby.co.uk, 1 +bouncycastlesisleofwight.co.uk, 1 +bouncycastlesmonaghan.com, 1 +bouncycastlesperth.net, 1 +bouncycastlessheerness.co.uk, 1 +bouncydays.co.uk, 1 +bouncygiggles.com.au, 1 +bouncyhigher.co.uk, 1 +bouncykingdom.co.uk, 1 +bouncykings.co.uk, 1 +bouncykingsnortheast.co.uk, 1 +bouncykingsofleicester.co.uk, 1 +bouncymacs.co.uk, 1 +bouncyrainbows.co.uk, 1 +bouncytime.co.uk, 1 +bound2bounce.co.uk, 1 +boundarybrighton.com, 1 +boundaryford.com, 1 +boundaryvets.co.uk, 1 +boundless-designs.com, 1 +bounouh.tk, 1 +bountiful.gov, 1 +bounty.fund, 1 +bounty.software, 1 +bountyfactory.io, 1 +bountyhuntermetaldetector.tk, 1 +bountyx.com, 1 +bourasse.fr, 1 +bourbo.net, 1 +bourestonmedia.com, 1 +bourgeoisdoor.com, 1 +bourgeoisdoorco.com, 1 +bournefun.co.uk, 1 +bourse-aux-jouets.org, 0 +bourse-aux-vetements.org, 0 +bourse-puericulture.org, 0 +bourseauxservices.com, 1 +boutiquedelhogar.cl, 1 +boutiqueguenaelleverdin.com, 1 +boutoncoupdepoing.fr, 1 +bouvier-des-flanders.com, 1 +bouville.fr, 1 +bouw.live, 1 +bouwbedrijfdevor.nl, 1 +bouwhuisman.nl, 1 +bouzouada.com, 1 +bouzouks.net, 1 +bovenwebdesign.nl, 1 +bovworkplacepensions.com, 1 +bowdens.me, 1 +bowedwallcrackrepair.com, 1 +bowlcake.fr, 1 +bowling.com, 1 +bowmanwilliams.com, 1 +bowmar.gov, 1 +bowntycdn.net, 1 +bowtie.com.hk, 1 +boxcritters.wiki, 1 +boxcryptor.com, 0 +boxdevigneron.fr, 1 +boxdropcc.com, 1 +boxeomexicano.tk, 1 +boxerdogsaspets.com, 1 +boxing-kangaroo.ga, 1 +boxintense.com, 1 +boxlink.de, 1 +boxlitepackaging.com, 1 +boxofficebengal.tk, 1 +boxofninjas.ca, 1 +boxpirates.to, 1 +boxsite.ga, 1 +boxspringbett-160x200.de, 1 +boxt.com.au, 1 +boxtub.com, 1 +boxturtlesaspets.com, 1 +boxvergelijker.nl, 1 +boxview.com, 1 +boxwcard.com, 1 +boyard.tk, 1 +boydstree.com, 1 +boyfriendcookbook.com, 1 +boyhost.cn, 1 +boyinglanguage.com, 1 +boykovo.tk, 1 +boyo.cloud, 1 +boyscoutschile.tk, 1 +boysontech.com, 1 +boysorebro.tk, 1 +boz.nl, 0 +bozdech.eu, 1 +bozdoz.com, 1 +bozenadusseau.tk, 1 +bozhok.tk, 1 +bozit.com.au, 1 +bp-wahl.at, 1 +bpa.gov, 1 +bpadvisors.eu, 1 +bpaste.net, 1 +bpastudies.org, 1 +bpedia.org, 1 +bphostels.com, 1 +bpisites.eu, 1 +bplan.tk, 1 +bpo.ovh, 1 +bpol-forum.de, 1 +bpreguica.com.br, 1 +bps.vc, 1 +bpsis.fr, 1 +bpvr.ddns.net, 1 +bpvr.nl, 1 +bqcp.net, 1 +bqp.io, 0 +bqr.ch, 0 +bqtoolbox.com, 1 +bqueen.salon, 1 +br-miyamoto.spdns.org, 1 +br.search.yahoo.com, 0 +br1334shop.com.br, 1 +br3in.nl, 0 +br7.city, 1 +br7.ru, 1 +br8.pl, 1 +braams.nl, 1 +braathe.no, 1 +brabank.no, 1 +brabank.se, 1 +braccialini.tk, 1 +bracebridgechiro.com, 1 +braceletcuivre.com, 1 +braces-supports.tk, 1 +bracho.xyz, 1 +brachotelborak.com, 1 +bracken.jp, 1 +bracketofficial.com, 1 +brackets-salad.com, 1 +bracknellvets.co.uk, 1 +bradbrockmeyer.com, 1 +bradeales.com, 1 +bradenanderin.com, 1 +bradfordhottubhire.co.uk, 1 +bradfordmascots.co.uk, 1 +bradkovach.com, 1 +bradler.net, 0 +bradleyeaton.com, 1 +bradlinder.org, 1 +bradstafford.com, 1 +bradypatterson.com, 1 +braemer-it-consulting.de, 1 +braeunlich-gmbh.com, 1 +bragasoft.com.br, 0 +bragaweb.com.br, 1 +braggalabel.cf, 1 +brahma.world, 1 +brahmins.com, 1 +braiampeguero.xyz, 1 +brailsford.xyz, 1 +brain-club.info, 1 +brain-e.co, 1 +brain-force.ch, 1 +brainatwork.it, 1 +brainball.fr, 0 +brainboxai.com, 1 +brainburger101.tk, 1 +braindiamond.com, 1 +braindiamonds.com, 1 +braineet.com, 1 +brainfork.org, 1 +brainhealth.gov, 1 +brainhub.nl, 1 +brainit.at, 1 +brainobeat.com, 1 +brainotony.com, 1 +brainoutlevel.com, 1 +brainrush.ga, 1 +brainserve.ch, 0 +brainserve.com, 0 +brainserve.swiss, 0 +brainshare.tk, 1 +brainsik.net, 1 +brainstorm.social, 1 +brainstormproductions.tk, 1 +braintensive.com, 1 +braintonus.tk, 1 +brainvation.de, 1 +brainwav.es, 1 +brainwork.space, 1 +brajenovic.com, 1 +brakemanpro.com, 1 +brakketrecruit.com, 1 +bralnik.com, 1 +bramburek.net, 1 +bramhallsamusements.com, 1 +bramhopetails.uk, 1 +bramming-fysio.dk, 1 +bramois.tk, 1 +bramptonscrapcarremoval.com, 1 +bramsikkens.be, 1 +bramstaps.nl, 1 +bramvanaken.be, 1 +bramygrozy.pl, 1 +bran.cool, 1 +bran.land, 1 +bran.pw, 1 +bran.soy, 1 +bran.to, 1 +branch-bookkeeper.com, 1 +branch.ga, 1 +branchenbuch-potsdam.com, 1 +branchtrack.com, 1 +brandand.co.uk, 1 +brandbil.dk, 1 +brandbuilderwebsites.com, 1 +brandcodestyle.com, 0 +brandfolder.com, 1 +brandhost.tk, 1 +brandhout-b-tree.be, 1 +brandingclic.com, 1 +brandingclick.com, 1 +brandingcoapps.com, 1 +brandingforthepeople.com, 1 +brandketers.com, 1 +brandnucreations.com, 1 +brando753.xyz, 1 +brandon-manilow.tk, 1 +brandon.so, 0 +brandoncricket.tk, 1 +brandondivorcelawyer.com, 1 +brandongomez.me, 1 +brandonhaynesmd.com, 1 +brandonhubbard.com, 1 +brandonjacksonphoto.com, 1 +brandonlin.me, 1 +brandonlui.com, 1 +brandonlui.ml, 1 +brandonsample.com, 1 +brandontaylor-black.com, 1 +brandonwalker.me, 1 +brandpit.nl, 1 +brandrocket.dk, 1 +brands-clothings.tk, 1 +brandsclub.tk, 1 +brandstead.com, 1 +brandt.tech, 1 +brandtechdesign.co.uk, 1 +brandtrapselfie.nl, 1 +brandweer-sgravendeel.tk, 1 +brandweerbarboek.nl, 1 +brandweerfraneker.nl, 1 +brandweergent.be, 1 +brandweertrainingen.nl, 1 +brandweeruitgeest.nl, 1 +brandweerweb.tk, 1 +brandweerzonecentrum.be, 1 +brandwizo.com, 1 +branefive.com, 1 +braniebananie.nl, 1 +brank.as, 1 +branno.org, 1 +bransive.com.au, 1 +branw.xyz, 0 +brard.it, 1 +brasco.tk, 1 +brashear.me, 1 +brasil66.tk, 1 +brasilduino.tk, 1 +brasildxn.com.br, 1 +brasiliademinasnet.tk, 1 +brasilianskbikini.se, 1 +brasilmedia.com, 1 +brasilmobi.cf, 1 +brasiltopnews.tk, 1 +brasilwear.biz, 1 +brasilweb.tk, 1 +braslet-bianshi.tk, 1 +brasserie-mino.fr, 1 +brasspipedreams.org, 1 +bratan.ga, 1 +bratstvo.tk, 1 +bratteng.me, 1 +bratteng.solutions, 1 +bratteng.xyz, 1 +bratunaconline.tk, 1 +bratvanov.com, 1 +brau-ingenieur.de, 1 +braudoktor.de, 1 +brauer-augenoptik.de, 1 +brauingenieur.de, 1 +braun-soddisfattiorimborsati.it, 1 +braunsteinpc.com, 1 +braunwarth.info, 0 +brava.bg, 1 +brave-foods.ch, 0 +brave-foods.com, 0 +brave.com, 1 +bravebaby.com.au, 1 +bravebiz-news.tk, 1 +bravebooks.berlin, 1 +bravehearts.org.au, 1 +bravelittlesquirrel.com, 1 +bravenboer.tk, 1 +bravewiki.tk, 1 +bravica.tk, 1 +bravoasociados.com, 1 +bravobet.et, 1 +brawlstarsitalia.com, 1 +brawny.com, 1 +braxtonehle.com, 1 +braychappell.com, 1 +brazenfol.io, 1 +brazilhealth.com.br, 1 +brazilian.dating, 1 +brazilianbikinishop.com, 1 +braziliex.com, 1 +brazillens.com, 1 +brazoriabar.org, 1 +brb.city, 1 +brba.nl, 1 +brbcbd.com, 1 +brck.nl, 1 +brd.ro, 1 +bread.fish, 1 +bread.red, 1 +breadandlife.org, 1 +breadofgod.org, 1 +breadpirates.chat, 1 +breakberlin.tk, 1 +breakcraft.tk, 1 +breakerlink.com, 1 +breakeven.tk, 1 +breakfree.tk, 1 +breaking-security.net, 1 +breakingdeal.fr, 1 +breakingnewskenya.tk, 1 +breakingsfnews.com, 1 +breakingtech.fr, 0 +breakingthesilence.org.il, 1 +breakingvap.fr, 1 +breakofdawn.tk, 1 +breakout.careers, 1 +breakwall.ml, 1 +breaky.de, 1 +breard.tf, 1 +breastaugmentationky.com, 1 +breastenlargement.gq, 1 +breathedreamgo.com, 0 +breathfinder.io, 1 +breathingblanket.com, 1 +breathingsound.ml, 1 +breathlesssheranda.tk, 1 +brechadigital.tk, 1 +brecht.ch, 1 +brechtheldens.xyz, 1 +breckle.com.ua, 1 +brecknell.biz, 1 +brecknell.com, 1 +brecknell.info, 1 +brecknell.name, 1 +brecknell.net, 1 +brecknell.org, 1 +breda.computer, 1 +bredabeds.com, 1 +breechdepot.com, 1 +breen.com.br, 1 +breeyn.com, 1 +breffa.pl, 1 +brefy.com, 1 +brege.org, 1 +bregnedal.dk, 1 +bregnedalsystems.dk, 1 +breitband.bz.it, 1 +breizh.pm, 1 +breket.ml, 1 +brelahotelberulia.com, 1 +bremen-restaurants.de, 1 +bremensaki.com, 1 +bremerfriedensforum.de, 1 +bremermaschinenbau.de, 1 +bremmaslooms.tk, 1 +brenbarnes.com, 1 +brenbarnes.com.au, 1 +brendabecker.com, 1 +brendansbits.com, 0 +brendanscherer.com, 1 +brenden.net.au, 0 +brentacampbell.com, 1 +brentalbright.tk, 1 +brentnewbury.com, 1 +breonart.com, 1 +breshka.be, 1 +bressier.fr, 1 +brest-bel.tk, 1 +brest-biz-belarus.tk, 1 +brest-brest.tk, 1 +brest-master.tk, 1 +brest-news.tk, 1 +brest-region.tk, 1 +brest24.tk, 1 +brestnews.tk, 1 +brestradio.tk, 1 +brestshop.tk, 1 +bret-mcgee.me.uk, 1 +bretcarmichael.com, 1 +breteuilcommerceartisanat.com, 1 +brett.icu, 1 +brettabel.com, 1 +brettcornwall.com, 1 +bretti.net, 1 +brettlawyer.com, 1 +brettpostin.com, 1 +brettw.xyz, 1 +bretzner.fr, 0 +brevboxar.se, 1 +brewercollinsleadership.com, 1 +brewit.online, 1 +brewsouth.com, 0 +brewspark.co, 1 +brewvo.com, 1 +brex.money, 1 +brex.pw, 1 +brexit.tk, 1 +breyerslakeshoreresort.com, 1 +breyerslakesideresort.com, 1 +breyersresort.com, 1 +brezani.tk, 1 +breznet.com, 1 +brfvh24.se, 1 +brgins.com, 1 +brguk.com, 1 +brian-gordon.name, 1 +brianalaway.com, 1 +brianalawayconsulting.com, 1 +briandorey.com, 0 +briandwells.com, 0 +brianfoshee.com, 1 +briangarcia.ga, 1 +brianjohnson.co.za, 1 +brianlanders.us, 1 +brianleemarketing.com, 1 +brianmwaters.net, 1 +brianpagan.net, 1 +brianroadifer.com, 1 +briansemrau.com, 1 +briansmith.org, 1 +brianum.de, 1 +brianum.net, 1 +brianvalente.tk, 1 +brianwalther.com, 1 +brianwesaala.com, 0 +brianwilson.tk, 1 +briarproject.org, 1 +bribriescolawfirm.com, 1 +brickadia.com, 1 +brickfilmfestival.tk, 1 +brickland.tk, 1 +bricks-clicks.com, 1 +bricks4kidzelearn.com, 1 +bricksandmotor.co.uk, 1 +brickstreettrio.com, 1 +brickvortex.com, 1 +brickweb.co.uk, 1 +brickwerks.io, 1 +bricmon.tk, 1 +bricolajeux.ch, 0 +bricolea.fr, 1 +bricomium.com, 1 +brid.gy, 0 +bridal.tk, 1 +bridalfabrics.co.uk, 1 +bridalfabrics.com, 1 +bridalfabrics.fr, 1 +bridalfabrics.ru, 1 +bridalweddingshow.ga, 1 +bride-forever.com, 1 +bride.vn, 1 +bridesbouquet.ml, 1 +bridestarco.com, 1 +bridge-online.cloud, 1 +bridge-to-knowledge.nl, 1 +bridge.nl, 1 +bridgecobuilders.com, 1 +bridgedigest.tk, 1 +bridgedirectoutreach.com, 1 +bridgefield.de, 1 +bridgeforcefinancial.com, 1 +bridgehomeloans.com, 1 +bridgement.com, 1 +bridgeout.com, 1 +bridgeportlaboratory.tk, 1 +bridgercanyonfiremt.gov, 1 +bridges.ml, 1 +bridges2understanding.com, 1 +bridgesinbelize.org, 1 +bridgetroll.org, 1 +bridholm.se, 1 +bridltaceng.com, 1 +brie.tech, 1 +briefassistant.com, 1 +briefbiz-news.tk, 1 +briefvorlagen-papierformat.de, 1 +briellenj.gov, 1 +briffoud.fr, 1 +brigadasazules.tk, 1 +brigade-electronics.com, 1 +brigantinebeachguide.com, 1 +briggsleroux.com, 1 +brighouse-leisure.co.uk, 1 +brightbiz-news.tk, 1 +brightbock.co.uk, 1 +brightbock.com, 1 +brightbock.net, 1 +brightbock.org, 1 +brightbock.tw, 1 +brightbock.uk, 1 +brightday.bz, 1 +brightendofleasecleaning.com.au, 1 +brighterimagelab.com, 1 +brightesttv.com, 1 +brightfuturemadebyme.com, 1 +brightlingseamusicfest.co.uk, 1 +brightonbank.com, 0 +brightonbouncycastles.net, 1 +brightonchilli.org.uk, 1 +brightonfc.tk, 1 +brightonhoney.com, 1 +brightpool-markets.com, 1 +brightside.com, 1 +brightsparks.com.sg, 1 +brightsport-news.tk, 1 +brightview.net.cn, 1 +brightwhiz.com, 1 +brightworkcreative.com, 1 +brightzonecleaning.com.au, 1 +brightzoneofficecleaning.com.au, 1 +brigidaarie.com, 1 +brigittaseasons.com, 1 +brigitte.nyc, 1 +brigittebutt.tk, 1 +brigittefontaine.tk, 1 +brilalux.pe, 1 +briliant.tk, 1 +brilliant-minds.tk, 1 +brilliantbouncyfun.co.uk, 1 +brilliantproductions.co.nz, 1 +brillio.com, 1 +brimspark.com, 1 +brimspark.systems, 1 +brindesgrafica.com.br, 1 +bring-heaven.com, 1 +bringfido.com, 1 +bringingbackthesweatervest.com, 1 +brinkbem.com, 1 +brinkhu.is, 1 +brinksurl.com, 1 +brinokidzonline.tk, 1 +brio-shop.ch, 1 +brio-ukraine.store, 1 +brio.news, 1 +briograce.com.mx, 1 +brioukraine.store, 1 +brisbanecashforcars.com.au, 1 +brisbaneflamenco.com.au, 0 +brisbanelogistics.com.au, 1 +brisbine.cloud, 1 +brisceremony.com, 1 +brisignshop.com.au, 1 +briskbase.com, 1 +bristebein.com, 1 +bristolandwestonsuperbounce.com, 1 +brit-thoracic.org.uk, 1 +britania.tk, 1 +britanniapandi.com, 1 +britelocate.com, 1 +britishbee.org.uk, 1 +britishbee.uk, 1 +britishbeef.com, 1 +britishbeekeepers.com, 1 +britishbeekeepers.net, 1 +britishbeekeepers.org, 1 +britishbeekeepers.org.uk, 1 +britishbeekeepers.uk, 1 +britishbeekeepersassociation.org.uk, 1 +britishbookmakers.co.uk, 1 +britishbullshitfoundation.cf, 1 +britishchronicles.com, 1 +britishcountrymusicfestival.com, 1 +britishgeneralelection.cf, 1 +britishgroupsg.com, 1 +britishmeat.com, 1 +britishpearl.com, 1 +britishrafting.com, 1 +britishsfaward.org, 1 +britishsnoring.co.uk, 1 +britney-galaxy.com, 1 +britneyclause.com, 1 +britneymanias.tk, 1 +britneyuniverse.com, 1 +britofootball.com, 1 +brittainconsulting.ca, 1 +brittanyferriesnewsroom.com, 1 +britton-photography.com, 1 +brizawen.com, 1 +brizzo.net, 1 +brk.dk, 1 +brk.st, 1 +brmascots.com, 1 +brmsalescommunity.com, 1 +brn.by, 1 +brndtfy.nl, 1 +brnojebozi.cz, 1 +brnrx.com, 1 +bro.hk, 1 +broadax.ml, 1 +broadbandchoices.co.uk, 1 +broadbandnd.com, 1 +broadbiz-news.tk, 1 +broadleft.org, 1 +broadmooroutfitters.com, 1 +broadsheet.com.au, 1 +broadwayfamilydentalpc.com, 1 +broadwayvets.co.uk, 1 +broadyexpress.com.au, 1 +broca.io, 0 +brockmeyer.net, 1 +brockmeyer.org, 1 +brockwayministorage.com, 1 +brodowski.cc, 1 +brody.digital, 1 +brody.ninja, 1 +broe.ie, 1 +broerict.nl, 1 +broersma.com, 1 +broerweb.nl, 1 +broeselei.at, 0 +broilertrade.com, 1 +brojagraphics.de, 1 +brokenbiz-news.tk, 1 +brokenhands.io, 1 +brokenminds.tk, 1 +brokenneckgang.com, 1 +brokentoaster.tk, 1 +brokerdecredite.ro, 1 +brokernet.ie, 0 +brokernotes.co, 1 +brokerstalk.com, 1 +brokgency.com, 1 +broland.ca, 1 +brols.eu, 1 +bromo.cf, 1 +brompton-cocktail.com, 1 +bronetb2b.com.br, 1 +bronevichok.ru, 1 +bronn.ee, 1 +bronwynlewis.com, 1 +bronx-ny-dentist.com, 1 +broodbesteld.nl, 1 +broodingblogger.com, 1 +brookes.xyz, 1 +brookframework.org, 1 +brooklynabortionclinic.nyc, 1 +brooklynboyblues.cf, 1 +brooklyncosmetics.net, 1 +brooklynentdoc.com, 1 +brooklyngynplace.com, 1 +brooklynrealestateblog.com, 1 +brooklynsigns.com, 1 +brooklyntheborough.com, 1 +brookscountyga.gov, 1 +brookworth.com, 0 +brosay-legko.ml, 1 +brosephstalin.com, 1 +brossman.it, 1 +brossmanit.com, 1 +brouillard.ch, 0 +brouskat.be, 1 +brouwerijdeblauweijsbeer.nl, 1 +brovelton.com, 0 +browfai.casa, 1 +brown-bros.ca, 1 +brownandjoseph.com, 1 +brownavto-news.tk, 1 +brownesgas.com, 1 +brownfieldstsc.org, 1 +brownforces.desi, 1 +brownforces.org, 1 +brownie.plus, 1 +brownihc.com, 1 +brownrice-life.com, 1 +brownsgroup.com, 1 +brownsprinkler.com, 1 +browntiger.tk, 1 +browntowncountryclub.com, 1 +brownwolfstudio.com, 1 +browsbybecca.ca, 1 +browse-tutorials.com, 1 +browsedns.net, 1 +browsemycity.com, 1 +browserleaks.com, 1 +brrr.fr, 1 +brskt.be, 1 +brtve.tk, 1 +bru6.de, 1 +brubank.com, 1 +brubankv1-staging.azurewebsites.net, 1 +bruce-springsteen.tk, 1 +brucebenes.com, 1 +brucekovner.com, 1 +bruceleeitems.com, 1 +brucemartin.net, 1 +bruckmuehler-kanu-club.de, 1 +bruckner.li, 1 +brudkista.nu, 1 +brudkista.se, 1 +brudkistan.nu, 1 +brudkistan.se, 1 +brugerklub.info, 1 +brugpensioen.tk, 1 +brujoincaperuano.com, 1 +brujonegroperuano.com, 1 +brun.rocks, 1 +bruna-cdn.nl, 1 +brunamarquezine.tk, 1 +brunanet.tk, 1 +brunchandmatch.be, 1 +brunetderochebrune.com, 0 +brunettipesco.com, 1 +brunhilde.ml, 1 +brunick.de, 0 +brunnenhof-welze.de, 1 +brunner.ninja, 1 +bruno-pelletier.tk, 1 +brunoamaral.eu, 1 +brunoarruda.com.br, 0 +brunocesarlima.com.br, 1 +brunodomingos.com, 1 +brunolt.nl, 1 +brunoproduit.ch, 0 +brunoramos.com, 1 +brunoramos.org, 1 +brunoreno.be, 1 +brush.ninja, 1 +brushcreekdistillery.com, 1 +brushcreekyachts.com, 1 +brusselsexpolive.ga, 1 +brusselsexpoloft.ga, 1 +brusselsexpostudio.ga, 1 +brusselslouisepenthouse.ga, 1 +brusselslouisestudio.ga, 1 +brusselsmidiapartment.ga, 1 +brusselsmidistudio.ga, 1 +brusselswestapartment.ga, 1 +brutalica.tk, 1 +brutality.cf, 1 +brutdecom.fr, 1 +brutecloud.com, 1 +brutus2.ga, 0 +bruun.co, 1 +bryanarmijomd.com, 1 +bryancastillo.site, 1 +bryandesrosiers.com, 1 +bryanfalchuk.com, 1 +bryankaplan.com, 1 +bryanquigley.com, 1 +bryanski.tk, 1 +bryansmith.net, 1 +bryansmith.tech, 1 +bryantluk.com, 1 +bryggebladet.dk, 1 +brzy-svoji.cz, 1 +bs-network.net, 1 +bs-security.com, 1 +bs.to, 1 +bs3xy.com, 1 +bsa-dom.ru, 1 +bsa157.org, 1 +bsaab.se, 1 +bsaft.ml, 1 +bsalyzer.com, 1 +bsapack564.org, 1 +bsatroop794.org, 1 +bsbet365.com, 1 +bsc-rietz.at, 1 +bsc01.dyndns.org, 1 +bscc.support, 1 +bscquimicos.com.br, 1 +bscyb.ch, 1 +bsd-box.net, 1 +bsd-sec.com, 1 +bsd.com.ro, 1 +bsdes.net, 1 +bsdfreak.dk, 1 +bsdlab.com, 1 +bsdracing.ca, 1 +bsdug.org, 1 +bsdunix.xyz, 1 +bsee.gov, 1 +bserved.de, 0 +bsf-knowledgecity.com, 1 +bsg.ro, 1 +bsgamanet.ro, 1 +bsgcredit.ro, 1 +bsidesf.com, 1 +bsidesf.org, 1 +bsidessf.com, 1 +bsktweetup.info, 1 +bslim-e-boutique.com, 1 +bsmn.ga, 1 +bsmsl.com, 1 +bso-buitengewoon.nl, 1 +bsociabl.com, 1 +bsolution.edu.vn, 1 +bsp-southpool.com, 1 +bspecialfx.nl, 1 +bsquared.org, 1 +bsrueti.ch, 1 +bss-systems.net, 1 +bss.com.ph, 1 +bss.net.ph, 1 +bss.solutions, 1 +bss.systems, 1 +bssolvfagen-pre-storeswa-wap.azurewebsites.net, 1 +bsstainless.com, 1 +bst-brandschutz.at, 1 +bsteele.tk, 1 +bstoked.net, 1 +bsuess.de, 1 +bsurfcr.com, 1 +bsuru.xyz, 1 +bsvfincorp.com, 1 +bsw-solution.de, 1 +bsystem.net, 1 +bszoft.hu, 1 +bt-kc.de, 1 +bt121.com, 1 +bt121.org, 1 +bt123.xyz, 1 +bt3655.com, 1 +bt3657.com, 1 +bt3658.com, 1 +bt780.com, 1 +bta.lv, 0 +btc-alpha.com, 1 +btc-doge.ga, 1 +btc-wallet.tk, 1 +btcanalyse.com, 1 +btcarmory.com, 1 +btcbenthuizen.nl, 1 +btcbolsa.com, 1 +btcontract.com, 1 +btcp.space, 1 +btcpop.co, 1 +btcshower.com, 1 +btdproductions.tk, 1 +bthub.site, 1 +bthub.xyz, 1 +btimprintables.com, 1 +btine.tk, 1 +btio.pw, 0 +btku.org, 1 +btln.cloud, 1 +btln.de, 1 +btmstore.com.br, 1 +btnissanparts.com, 1 +btopc.jp, 1 +btorrent.xyz, 1 +btraviswright.com, 1 +btraviswrightmps.com, 1 +btrb.ml, 1 +btrfs.no, 1 +btsapem.com, 1 +btshe.net, 1 +btsline.co.id, 1 +btslr.co, 1 +btsoft.eu, 1 +btsou.org, 1 +btsource.tk, 1 +btsous.org, 1 +btsow.com, 0 +btsybt.com, 0 +btt-39.com, 1 +btt-59.com, 1 +btt2020.com, 1 +btt217.com, 1 +btt3311.com, 1 +btt381g.com, 1 +btt686.com, 1 +btt8.me, 1 +btt88.net, 1 +btt882.com, 1 +btt88818.com, 1 +btt907.com, 1 +btt918958.com, 1 +btta13.com, 1 +btta16.com, 1 +bttc.co.uk, 0 +btth.live, 1 +btth.pl, 1 +btth.tv, 1 +btth.xyz, 1 +bttna.com, 1 +bttorj45.com, 1 +bttt999.com, 1 +bttyulecheng0.com, 1 +bttyulecheng7.com, 1 +bturboo.com, 1 +bu-dun.com, 1 +buatcv.online, 1 +buayacorp.com, 1 +bubba.cc, 1 +bubbelwafel.nl, 1 +bubblegumblog.com, 1 +bubblelist.tk, 1 +bubblespetspa.com, 1 +bubblin.io, 1 +bubblinghottubs.co.uk, 1 +bubblybouncers.co.uk, 1 +bubet365.com, 1 +bubhub.io, 1 +bubnovsky.org, 1 +bubsngrubs.com.au, 1 +bubu1.eu, 1 +bubulazi.com, 0 +bubulazy.com, 1 +bucek.cz, 1 +buch-angucken.de, 1 +buchangroupinc.com, 1 +buchhaltung-muehelos.de, 1 +buchwegweiser.com, 1 +buck-hydro.de, 1 +buck.com, 1 +buckanddoe.farm, 1 +buckdoeand.co, 1 +bucket.tk, 1 +buckethead.tk, 1 +buckfast.tk, 1 +bucksfund.com, 1 +buckthorn.ml, 1 +buckypaper.com, 1 +buda.com, 1 +budaev-shop.ru, 1 +budapestairport.tk, 1 +budapestjazzclub.hu, 1 +budbringerne.tk, 1 +buddhism.cf, 1 +buddhismedia.com, 1 +buddhismus.net, 1 +buddhistische-weisheiten.org, 1 +buddie5.com, 1 +buddiescomputers.com.au, 1 +buddingoptimist.com, 1 +buddlycrafts.com, 1 +buddy-acceptance-authentication-frontend.azurewebsites.net, 1 +buddy-acceptance-backoffice-frontend.azurewebsites.net, 1 +buddy-acceptance-web-frontend.azurewebsites.net, 1 +buddy-development-backoffice-webapp.azurewebsites.net, 1 +buddy-development-rabodirectconnect-api.azurewebsites.net, 1 +buddycompany.net, 1 +buddyme.me, 1 +buddytop.com, 1 +buddyworks.net, 1 +budeanu.com, 1 +buderus-family.be, 1 +budgerigarbirds.com, 1 +budget-cuts.tk, 1 +budget.gov, 1 +budgetboats.net, 1 +budgetimize.com, 1 +budgetlob.gov, 1 +budgetlovers.nl, 1 +budgetrf.tk, 1 +budgiesballoons.com, 1 +budilnik.ml, 1 +budntod.com, 1 +budofjoy.com, 1 +budolangnau.ch, 1 +budolfs.de, 1 +budowle.pl, 1 +buena-vista.cz, 1 +buena.me, 1 +buenosproductos.net, 1 +bueny.com, 1 +bueny.net, 1 +buerger-lenke.de, 1 +buerliag.ch, 1 +bueromoebel-experte.de, 1 +bueroplus.de, 1 +bueroshop24.de, 1 +buesiforquo.cf, 1 +buettgens.net, 1 +bufete.tk, 1 +buff-buff.tk, 1 +buffaloautomation.com, 1 +buffaloturf.com.au, 1 +buffalowdown.com, 1 +buffetbouc.com, 1 +buffup.media, 1 +buffus.cz, 1 +bufla.net, 1 +bufo.tk, 1 +bug.blue, 1 +bug.ee, 1 +bug321.com, 1 +bugbounty.ch, 1 +bugcrowd.com, 1 +bugfender.com, 1 +bugfuzz.com, 1 +buggiano.com, 1 +bugginslab.co.uk, 1 +buggshop.com, 1 +buggy777.me, 1 +buggymaven.com, 1 +buggywonderland.tk, 1 +bugreader.com, 1 +bugs.chromium.org, 1 +bugsmashed.com, 1 +bugu.org, 0 +buguardian.com, 1 +bugwie.com, 1 +bugzil.la, 1 +bugzilla.mozilla.org, 1 +buhayguro.com, 1 +buhayprincipal.com, 1 +buhlerthomaslaw.com, 1 +buhonline.ru, 1 +buick1958.tk, 1 +build.chromium.org, 1 +buildbackbetter.com, 1 +buildbackbetter.gov, 1 +buildbytes.com, 1 +buildconcierge.ga, 1 +builderrentals.com, 1 +buildhoscaletraingi.com, 1 +building-cost-estimators.com, 1 +building-materials.tk, 1 +buildingclouds.de, 1 +buildingcostestimators.co.uk, 1 +buildingmaterials.tk, 1 +buildingpoint.pt, 1 +buildingpointne.com, 1 +builditfl.com, 0 +builditsolutions.net, 1 +buildkite.com, 1 +buildmate.ml, 1 +buildmorebuslanes.com, 1 +buildnews.tk, 1 +buildplease.com, 1 +buildpriceoption.com, 1 +builds.gg, 1 +buileo.com, 1 +builterra2.azurewebsites.net, 1 +builtingym.com, 1 +builtinseattle.com, 1 +builtinsf.com, 1 +builtory.my, 1 +builtvisible.com, 1 +builtwith.com, 1 +buissonchardin.fr, 1 +buitenposter.nl, 1 +buka.jp, 1 +buketnevesti.cf, 1 +bukinist.tk, 1 +bukiskola.hu, 1 +bukivallalkozasok.hu, 1 +bukkenfan.jp, 1 +bukowski.tk, 1 +bukpcszerviz.hu, 1 +bukularis.ga, 1 +bul3seas.eu, 1 +bulario.com, 1 +bulario.net, 1 +bularmas.com, 1 +bulavki.tk, 1 +bulbcompare.com, 1 +bulbgenie.com, 1 +bulbonidos.tk, 1 +buldogueingles.com.br, 1 +bulgakov.ml, 1 +bulgakov.tk, 1 +bulgariablog.tk, 1 +bulgarianhouse.tk, 1 +bulgariya.cf, 1 +bulkcandystore.com, 1 +bulkowespacerkowo.nl, 1 +bulktshirtsjohannesburg.co.za, 1 +bull.id.au, 0 +bulldog-hosting.de, 0 +bulldogkennel.tk, 1 +bulldogscuba.com, 1 +bulledair-savons.ch, 0 +bulletbabu.com, 0 +bulletpoint.cz, 1 +bullettags.com, 1 +bullfitta.tk, 1 +bullpendaily.com, 1 +bullseyemetrics.com, 1 +bullterrier.nu, 1 +bullterrierspain.tk, 1 +bullvalleyil.gov, 1 +bullyprotection.ml, 1 +bulmanat.tk, 1 +bulmastife.com.br, 1 +bulutkey.com, 1 +bulvar.tk, 1 +bulwarkhost.com, 1 +bumble.com, 1 +bumblebeekids.co.uk, 1 +bumblebeekids.uk, 1 +bumenn.is, 1 +bumpi.gq, 1 +bunadarbankinn.is, 1 +bunbun.be, 1 +bund-von-theramore.de, 1 +bundespolizei-forum.de, 1 +bundesverband-krisenintervention.de, 1 +bundesverbandkrisenintervention.de, 1 +bundesvvehr.de, 1 +bundito.com, 1 +bune.city, 1 +bungabuket.com, 1 +bungaspa.com, 1 +bungee.pw, 1 +bunix.de, 0 +bunker307.tk, 1 +bunkyo-life.com, 1 +bunlarateist.space, 1 +bunniesoflasvegas.com, 0 +bunny-rabbits.com, 1 +bunnybloythost.com, 1 +bunnycarenotes.com, 1 +bunnydiamond.de, 1 +bunnymud.com, 1 +bunnyvishal.com, 1 +bunnyworld.xyz, 1 +bunq.love, 1 +bunzy.ca, 1 +buongiornolatina.it, 1 +buonventosbt.eu, 1 +buphachat.com, 1 +bupropion.com, 1 +bupropionhclsr.ga, 1 +buqi.cc, 1 +buquesdeguerra.tk, 1 +burakogun.com, 0 +burakogun.com.tr, 0 +burakogun.net, 0 +burakogun.net.tr, 0 +burakogun.org, 0 +buralteria.tk, 1 +buratino.tk, 1 +buratiya.tk, 1 +burbaguena.tk, 1 +burbankdental.com, 1 +burcevo.info, 1 +burchfabrics.com, 1 +burdine-andersoninc.com, 1 +burdurhaber.tk, 1 +bureaubraam.nl, 1 +bureaugoodwork.nl, 1 +bureauscript.nl, 1 +bureaux-entrepots.fr, 1 +bureniemoscow.ru, 1 +burenvoorburen.gent, 1 +burevestnik.tk, 1 +burewala.tk, 1 +burg-hohnstein.com, 1 +burg-hohnstein.info, 1 +burgawnc.gov, 1 +burgerbites.be, 1 +burgerbudget.gent, 1 +burgernet.nl, 1 +burgers.io, 1 +burghardt.pl, 1 +burghtstam.tk, 1 +burgoslacrosse.tk, 1 +burgundia.pl, 1 +buri.be, 1 +burialinsurancenetwork.com, 1 +buricloud.fr, 1 +burienergy.com, 1 +buriramradio.com, 1 +burke.services, 1 +burkhardt.at, 1 +burkoff.tk, 1 +burkow.ru, 1 +burlapsac.ca, 1 +burling.cz, 1 +burmania.tk, 1 +burmeister-gmbh.de, 1 +burmesecatscare.com, 1 +burmesepythonpet.com, 1 +burncorp.org, 1 +burnerfitness.com, 1 +burnimage.co.uk, 1 +burning-wheels.tk, 1 +burningbird.net, 1 +burningflame.tk, 1 +burningflipside.com, 0 +burnsland.com, 1 +burntfish.com, 1 +burnworks.com, 1 +buronwater.com, 1 +burr.is, 1 +burreli.tk, 1 +burritosalsa.com, 1 +burroughsid.com, 1 +bursamusik.tk, 1 +bursapartner.tk, 1 +burtai.com, 1 +burtrum.family, 1 +burtrum.me, 1 +burtrum.name, 1 +burtrum.org, 1 +burunucu.ga, 1 +buryat-mongol.cf, 1 +buryatia.tk, 1 +burz.media, 1 +burz.net, 1 +burz.one, 1 +burzcast.media, 1 +burzcast.ro, 1 +burzgroup.com, 1 +burzmali.com, 1 +burzmedia.com, 1 +burzstudios.com, 1 +burzum.ch, 1 +busanhs.bid, 1 +buscacpf.se, 1 +buscaebooks.tk, 1 +buscalotodo.com, 1 +buscandolosmejores.com, 1 +buscarcarros.com.br, 1 +buscasimple.com, 1 +buscatodo.tk, 1 +buscolu.tk, 1 +buscoop.co, 1 +buselefante.tk, 1 +buserror.cn, 1 +busflag.tk, 1 +bush41library.gov, 1 +bushbaby.com, 1 +bushcraftfriends.com, 1 +bushfirerecovery.gov.au, 1 +bushico.com, 1 +bushland.tk, 1 +busindre.com, 1 +business-creators.ru, 1 +business-explosion-fortune.tk, 1 +business-garden.com, 1 +business-secreti.cf, 1 +business-secreti.ga, 1 +business-secreti.gq, 1 +business-secreti.tk, 1 +business.facebook.com, 0 +business.gov, 0 +businessamongus.com, 1 +businessanalyst.ml, 1 +businessanalytics24.com, 1 +businesscentermarin.ch, 0 +businesscircle.com.my, 0 +businessconnect.ml, 1 +businesscrafter.ga, 1 +businessdirect.ml, 1 +businessdrive.biz, 1 +businessesdirectory.eu, 1 +businessethics.ml, 1 +businessetmarketing.com, 1 +businessfactors.de, 1 +businessfurs.info, 1 +businessgram.eu, 1 +businessgrants.gov.sg, 1 +businessgrowthleaders.com, 1 +businesshub.cz, 0 +businessimmigration-eu.com, 1 +businessimmigration-eu.ru, 1 +businessinside.ml, 1 +businessinvest.cf, 1 +businessinvestment.tk, 1 +businessjaunt.com, 1 +businessk.ml, 1 +businessloanconnection.org, 0 +businessmarketingblog.org, 1 +businessmind.ml, 1 +businessnames.ga, 1 +businessnet.cf, 1 +businesspartner.tk, 1 +businessportal.tk, 1 +businesspride.ga, 1 +businessquality.ml, 1 +businessradar.com.au, 1 +businessrights.in, 1 +businesstravelmelbourne.ga, 1 +businessusa.gov, 1 +businesswebadmin.com, 1 +businka.tk, 1 +busit.be, 1 +busiteyiengelle.com, 1 +busold.ws, 1 +buspark.com, 1 +buspark.cz, 1 +busphotos.tk, 1 +busqnet.com, 1 +busstation.tk, 1 +bustabit.com, 1 +bustadice.com, 1 +bustany.org, 1 +buster.me.uk, 1 +bustickets.ph, 1 +bustillodeloro.tk, 1 +bustimes.org, 1 +bustingbrackets.com, 1 +bustmold.com, 1 +busuttil.org.uk, 1 +buswiki.ml, 1 +busybee360.com, 1 +busyon.cloud, 1 +butarque.es, 1 +butcherpaxtattoo.com, 1 +butik-mechty.tk, 1 +butikvip.ru, 1 +butlercountyhistory.org, 1 +butlerdisposal.com, 1 +butlerfm.dk, 1 +butlist.com, 1 +butowka.tk, 1 +butserdocumentary.tk, 1 +butt.repair, 0 +buttacakes.com, 1 +butter.horse, 1 +butteramotors.com, 1 +butterhost.ga, 1 +buttermilk.cf, 1 +buttgun-tattoo.de, 1 +buttonizer.pro, 1 +buttonline.ch, 1 +butts-are.cool, 1 +butz.cloud, 1 +butzies.ddnss.org, 1 +buurtgenotencollectief.nl, 1 +buurtkeukens.nl, 1 +buurtpreventiefraneker.nl, 1 +buxum-communication.ch, 0 +buy-aleve.gq, 1 +buy-amitriptyline.tk, 1 +buy-amoxil.ml, 1 +buy-an-essay.gq, 1 +buy-avodart.ga, 1 +buy-camera-cases.ga, 1 +buy-cozaar.tk, 1 +buy-decadron.tk, 1 +buy-deltasone.tk, 1 +buy-essay-online.ga, 1 +buy-indocin.cf, 1 +buy-jeansbiz.tk, 1 +buy-lasix-without-a-doctor-s-prescription.ga, 1 +buy-lingerie.tk, 1 +buy-lipitor.tk, 1 +buy-los-angeles-auto-insurance.com, 1 +buy-out.jp, 1 +buy-prednisolone.ga, 1 +buy-premarin.ml, 1 +buy-robaxin.gq, 1 +buy-rumalaya.gq, 1 +buy-seroquel.tk, 1 +buy-skelaxin.ml, 1 +buy-stuffed-toys.tk, 1 +buy-terramycin.gq, 1 +buy-topamax.tk, 1 +buy-zimulti.ga, 1 +buy-zofran.ga, 1 +buy2dollars.com, 1 +buyaccessible.gov, 1 +buyaccutane.gq, 1 +buyacompliaonline.ga, 1 +buyalbendazole.cf, 1 +buyalbuterolonline.ga, 1 +buyallopurinol.tk, 1 +buyamerican.gov, 1 +buyamoxicillin875mg.tk, 1 +buyamoxil.ml, 1 +buyantabuse.gq, 1 +buyasheep.tw, 1 +buyatarax.gq, 1 +buyazithromycin.gq, 1 +buybaclofen.ga, 1 +buybike.shop, 1 +buybuspar.ga, 1 +buybutton.store, 1 +buycafergot.ml, 1 +buycarpet.shop, 1 +buycbd.store, 1 +buycccam.tv, 1 +buycheapandlow.tk, 1 +buycialissmx.tk, 1 +buycitalopram.ga, 1 +buyclaritin.ml, 1 +buycompanyname.com, 1 +buycook.shop, 1 +buycostarica.tk, 1 +buydataonline.tk, 1 +buydegree.info, 1 +buydeltasone.ga, 1 +buydeltasone.ml, 1 +buydiamox.cf, 1 +buydiflucan.ga, 1 +buydiflucan.ml, 1 +buydissertations.com, 1 +buyebook.xyz, 1 +buyebooks.tk, 1 +buyeffexor.tk, 1 +buyer.pro, 1 +buyerdocs.com, 1 +buyessay.org, 1 +buyessays.net, 1 +buyfluoxetineonline.gq, 1 +buyguideonline.com, 1 +buyharpoon.com, 1 +buyhydrochlorothiazide.ml, 1 +buyinginvestmentproperty.com, 1 +buyingstatus.com, 1 +buyitmalta.online, 1 +buyitnowfast.com, 1 +buyjewel.shop, 1 +buylasix.ml, 1 +buylevaquin.tk, 1 +buymetforminonline.tk, 1 +buymobic.ml, 1 +buyneurontin.ml, 1 +buynowbol.com, 1 +buypapercheap.net, 1 +buyplore.com, 1 +buyplussize.shop, 1 +buyprednisolone24h.ml, 1 +buyprednisoloneonline.ga, 1 +buyprilosec.tk, 1 +buyprofessional.shop, 1 +buypropecia.cf, 1 +buyproperty.az, 1 +buyproscaronlinecanada.ga, 1 +buyprovera.tk, 1 +buyprozac.cf, 1 +buypurenature.ga, 1 +buyretinamicro.cf, 1 +buyrimonabant.cf, 1 +buyrogaine.ga, 1 +buyshoe.org, 1 +buysildenafil.ml, 1 +buysoft.co.uk, 1 +buystromectol.cf, 1 +buystromectol.ml, 1 +buysuisse.shop, 1 +buytermpaper.com, 1 +buytetracycline.cf, 1 +buytramadol.ga, 1 +buytramadol.ml, 1 +buyucoin.com, 1 +buyupstorepremium.net, 1 +buyusa.gov, 1 +buyventolin.cf, 1 +buyventolininhaler.ga, 1 +buywellbutrinonline.gq, 1 +buywifi.tk, 1 +buywine.shop, 1 +buywood.shop, 1 +buyzithromax.ga, 1 +buyzithromaxonline.ml, 1 +buyzofranonline.tk, 1 +buyzoloft.cf, 1 +buziaczki.pl, 1 +buzzconcert.com, 1 +buzzcontent.com, 1 +buzzer-sosmed.site, 1 +buzzfeast.com, 1 +buzzhub.tk, 1 +buzzkuri.com, 1 +buzzman.ga, 1 +buzzmedianetworks.com, 1 +buzzpop.tv, 0 +buzzprint.it, 1 +buzztrending.tk, 1 +buzzword24.de, 1 +bv-driver.tk, 1 +bva.dyndns.info, 1 +bvbbuzz.com, 1 +bvbmedia.nl, 1 +bvexplained.co.uk, 1 +bvgt.org, 1 +bvionline.eu, 1 +bviphotovideo.com, 1 +bvl.aero, 1 +bvop.org, 1 +bvrd.com.do, 1 +bvrlodge.com, 1 +bvrlodge.ro, 1 +bvsa.co.za, 0 +bvv-europe.eu, 1 +bw.codes, 1 +bwanglab.com, 1 +bwashing.tk, 1 +bwasoimoveis.net, 1 +bwcscorecard.org, 1 +bwf11.com, 1 +bwf55.com, 1 +bwf6.com, 1 +bwf77.com, 1 +bwf99.com, 1 +bwfc.nl, 1 +bwgjms.com, 1 +bwgjms.net, 1 +bwgjms.org, 1 +bwh1.net, 0 +bwhbwh.net, 1 +bwilkinson.co.uk, 1 +bwin18.cc, 1 +bwin2288.com, 1 +bwin369.cc, 1 +bwin58.cc, 1 +bwired.ca, 1 +bwl-earth.club, 1 +bwmcnc.com, 1 +bws16.de, 1 +bwserhoscaletrainaz.com, 1 +bwzc.be, 1 +bx-n.de, 1 +bx49.cc, 1 +bxdj3.com, 1 +bxegypt.com, 1 +bxin.de, 1 +bxp40.at, 1 +by-robyn.nl, 1 +by1u.com, 1 +byange.pro, 1 +byanjushka.com, 1 +byatte.com, 1 +byaustere.com, 1 +bybet365.com, 1 +bycrates.com, 1 +bydik.com, 1 +bydisk.com, 0 +bye-bye.us, 1 +byeskille.no, 1 +byfare.com, 1 +byfeldt.dk, 1 +byggindrustrin.ga, 1 +byggonline.ga, 1 +bygningsregistrering.dk, 1 +bygoselink.nl, 1 +byhe.me, 1 +byhenryvera.com, 1 +byjamesrush.com, 1 +byji.com, 1 +byjuschennai.com, 1 +byken.cn, 1 +byket.lviv.ua, 1 +byladyverdelet.bzh, 1 +bylivetrp.no, 1 +byll.de, 1 +byluthier.com, 1 +bymark.co, 1 +bymike.co, 1 +bymogarna.se, 1 +bynder.com, 1 +bynet.cz, 1 +bynumlaw.net, 1 +byootify.com, 1 +bypass.kr, 1 +bypass.sh, 1 +bypassgfw.tk, 1 +bypetula.cz, 1 +byraje.com, 1 +byrddogpaving.com, 1 +byrest.com, 1 +byriderfranchise.com, 1 +byrko.cz, 1 +byrko.sk, 1 +byronkg.us, 1 +byrtz.de, 1 +bysb.net, 1 +bysgo.com, 1 +byshop.tk, 1 +byskafasi.com, 1 +bystryj-zajm.gq, 1 +bystryj-zajm.tk, 1 +byte.nl, 1 +byte128.com, 0 +bytearts.net, 0 +bytebe.at, 0 +bytebucket.org, 1 +bytecrafter.com, 1 +bytecrafter.net, 1 +byteflies.com, 1 +bytema.cz, 1 +bytema.eu, 1 +bytema.re, 1 +bytema.sk, 1 +bytemix.cloud, 1 +bytepen.com, 1 +bytes.co, 1 +bytes.fyi, 1 +byteshift.ca, 1 +bytesign.de, 1 +bytesizedalex.com, 1 +bytesofcode.de, 1 +bytesoftech.ml, 1 +bytesund.biz, 1 +byteswave.cl, 1 +bytesystems.com, 1 +bytetechy.com, 1 +byteterrace.com, 1 +bytetime.net, 0 +byteultra.com, 1 +bytheglass.gr, 1 +bythen.cn, 0 +bytheswordinc.com, 1 +bytovetextilie.cz, 1 +bytrain.net, 1 +bytwork.com, 1 +byuro.org, 1 +byvdev.com, 1 +byvshie.com, 1 +byw.cymru, 1 +byxong.com, 1 +bzbet365.com, 1 +bzh.tf, 1 +bzhserv.ovh, 1 +bzhub.bid, 1 +bziaks.xyz, 1 +bzsparks.com, 0 +bztech.com.br, 1 +bztraveler.com, 1 +bzv-fr.eu, 1 +c-14.de, 1 +c-3.moe, 1 +c-3po.fr, 1 +c-aeroconsult.com, 1 +c-c-europeen.org, 1 +c-chaud.com, 1 +c-g-h.net, 1 +c-ma-copro.com, 1 +c-netsys.fr, 1 +c-rpg.eu, 1 +c-rtx.com, 1 +c-shock.org, 1 +c-style.net, 1 +c-world.co.uk, 1 +c.cc, 1 +c.im, 1 +c00ke.com, 1 +c057cl7.com, 1 +c0rn3j.com, 1 +c0rporation.com, 1 +c16t.uk, 1 +c1cdn.com, 1 +c2athletics.com, 1 +c2m-staging.com, 1 +c2o2.xyz, 1 +c3.pm, 1 +c35.design, 1 +c36533.com, 1 +c3boc.com, 1 +c3hv.cn, 1 +c3kidspace.de, 1 +c3s.hu, 1 +c3sa.com, 1 +c3sign.de, 0 +c3soc.de, 1 +c3softworks.com, 1 +c3speak.com, 1 +c3speak.de, 1 +c3stream.de, 1 +c3vo.de, 0 +c3w.at, 1 +c3wien.at, 1 +c4539.com, 1 +c4dstudio.com, 1 +c4k3.net, 1 +c4safety.com, 1 +c5197.co, 1 +c52iv.com, 1 +c5h8no4na.net, 1 +c6729.co, 1 +c6729.com, 1 +c6957.co, 1 +c7dn.com, 1 +c7n.ch, 1 +c7ra.com, 1 +c81365.com, 1 +c82365.com, 1 +c86255.com, 1 +c899365.com, 1 +c9297.co, 1 +c9397.com, 1 +c9721.com, 1 +c9728.co, 1 +ca-canovelles.tk, 1 +ca-key.de, 1 +ca-saintdie.fr, 1 +ca.gparent.org, 1 +ca.search.yahoo.com, 0 +ca5.de, 1 +caalmn.org, 1 +caanepal.gov.np, 1 +caaps.org.au, 1 +caarecord.org, 1 +caasd.org, 1 +cabaal.net, 1 +cabaladada.org, 1 +cabale.fr, 1 +caballeroalba.cf, 1 +cabanactf.com, 1 +cabarave.com, 1 +cabaretadanowskyfan.tk, 1 +cabazon-tu.com, 1 +cabbage.software, 1 +cabeceirasdebasto.pt, 0 +cabecera-descendimiento.tk, 1 +cabelgrano.tk, 1 +cabezadeframontanos.tk, 1 +cabezadelcaballo.tk, 1 +cabina-photobooth.ro, 1 +cabincrewcareercenter.com, 1 +cabineritten.nl, 1 +cabinet-life.fr, 0 +cabinetfurnituree.com, 1 +cabinetmtc.com, 1 +cablehighspeed.net, 1 +cablemod.com, 1 +cables-pro.com, 1 +cablesandkits.com, 1 +cabodream.ml, 1 +caboodle-technology.co.uk, 1 +cabooneconstruction.com, 1 +cabosaferide.com, 1 +caboverde.tk, 1 +cabrachicagritona.tk, 1 +cac-ua.com, 1 +cacao-chocolate.com, 1 +cacao.supply, 1 +cacaogenomedb.org, 1 +cacaolalina.com, 1 +cacaumidade.com.br, 1 +cachacacha.com, 1 +cachacasantaterezinha.com.br, 1 +cache-checker.com, 1 +cachedview.nl, 1 +cachethome.com, 1 +cachetur.no, 1 +cackette.com, 0 +cacombos.com, 1 +cacoriccionline.tk, 1 +cacr.pw, 1 +cacrm.com, 1 +cactusarium.tk, 1 +cactuspedia.ga, 1 +cad-noerdlingen.de, 1 +cadafamilia.de, 1 +cadams.io, 1 +cadastroloteamento.com.br, 1 +cadcc.cl, 0 +caddyfashionshop.com, 1 +cadecobots.com, 1 +cadeengineering.com, 1 +cadeirasparaescritorio.ind.br, 1 +cadetsge.ch, 0 +cadflow.pt, 1 +cadici.ga, 1 +cadifit.ga, 1 +cadiskitchen.ca, 1 +cadiztrabaja.com, 1 +cadmail.nl, 1 +cadman.pw, 1 +cadman.uk, 1 +cadmanlaw.ca, 1 +cadmanlaw.com, 1 +cadmax.pro, 1 +cadmechanic.com, 1 +cadonet.tk, 1 +cadooz.com, 1 +cadoth.net, 1 +cadovod.tk, 1 +cadra.nl, 1 +cadre.com, 1 +cadsys.net, 1 +cadventura.com, 1 +caerostris.com, 1 +caesarkabalan.com, 1 +caetanobenet.es, 1 +caetanoflotas.es, 1 +caetanoformula.es, 1 +caetanoformulacadiz.es, 1 +caetanoformulagalicia.es, 1 +caetanomotorsmalaga.es, 1 +caetanoreicomsa.es, 1 +cafe-georges.cf, 1 +cafe-habis.de, 1 +cafe-musica.org, 1 +cafe-pauline.de, 1 +cafe-service.ru, 0 +cafeamazon.tk, 1 +cafechesscourt.com, 1 +cafedelcielo.co, 1 +cafedupont.be, 1 +cafedupont.co.uk, 1 +cafedupont.de, 1 +cafedupont.nl, 1 +cafefacil.com.br, 1 +cafeferrovia.com.br, 1 +cafeimsueden.de, 1 +cafeitalia.tk, 1 +cafejulian.com, 1 +cafelandia.net, 1 +cafenix.tk, 1 +cafeobscura.nl, 1 +cafepress.com.au, 1 +cafericoy.com, 1 +cafermin.com, 1 +cafesforonda.com, 1 +cafeterasbaratas.net, 1 +cafeterya.tk, 1 +cafethevibes.com, 1 +cafevelo.org, 1 +caffe.ga, 1 +caffect.com, 1 +caffeinate.co.uk, 1 +caffeinatedengineers.com, 1 +caffeinefiend.org, 1 +caffewasyl.pl, 1 +cafled.org, 1 +cagivaclub.tk, 1 +caglarcakici.com, 1 +cahfee.com, 1 +cai4cai.ml, 1 +caiben.org, 1 +caibi.io, 1 +caijunyi.net, 0 +cailoli.com, 1 +cainhosting.com, 0 +caipai.fm, 1 +caipsnotes.com, 1 +caiqueparrot.com, 1 +cairnterrier.com.br, 1 +cairogyms.com, 1 +cairohost.ml, 1 +cais.de, 1 +caise.tk, 1 +caivps.com, 1 +caiwenjian.xyz, 1 +caizx.com, 0 +caja-pdf.es, 1 +cajadecoloreshome.com, 1 +cajadelparque.tk, 1 +cajamarca.blog, 1 +cajio.ru, 1 +cajunuk.co.uk, 1 +cakalnedobe.si, 1 +cake-n-go.com, 1 +cakearific.com, 1 +cakeoffencesact.uk, 1 +cakes.ga, 1 +cakes.tk, 1 +cakesbyzoey.com, 1 +cakestart.net, 1 +caketoindia.com, 1 +cakingandbaking.com, 1 +cakirlarshipyard.com, 0 +cal.goip.de, 1 +cal9000.com, 1 +calaad.net, 1 +calabasaselectric.com, 1 +calabasaselectrical.com, 1 +calabasaselectrician.com, 1 +calabasasexteriorlighting.com, 1 +calabasaslandscapelighting.com, 1 +calabasaslighting.com, 1 +calabasasoutdoorlighting.com, 1 +calaborlawnews.com, 1 +calaficirecords.cf, 1 +calafont.cat, 0 +calaix.click, 1 +calandrahosting.tk, 1 +calaverasmedicalcannabis.com, 1 +calcasieuparish.gov, 1 +calcedge.com, 1 +calcettomania.com, 1 +calcinacci.com, 1 +calcioragusa.tk, 1 +calconcontractors.com, 1 +calcoolator.pl, 1 +calculadoraconversor.com, 1 +calcularis.ch, 1 +calculateaspectratio.com, 1 +calculates.org, 1 +calculator-imt.com, 1 +calculator.tf, 1 +calcworkshop.com, 1 +caldecotevillagehall.co.uk, 1 +calderagallery.com, 1 +caldersoldas.com.br, 1 +caldervets.co.uk, 1 +caldoletto.com, 1 +calefones-electricos.com, 1 +calehoo.com, 1 +calendar.cf, 0 +calendar.google.com, 1 +calendarr.com, 1 +calendarsnow.com, 1 +calendly.com, 1 +calendriergn.ch, 1 +calendum.ru, 1 +calenfil.com, 1 +caletka.cz, 1 +caletka.nl, 1 +calgraf.com, 1 +caliane.de, 1 +calibra.com, 1 +calibracionhd.com, 1 +calibreapp.com, 1 +calibso.net, 1 +calichines.com, 1 +caliderumba.com, 1 +calidoinvierno.com, 1 +californiahempin.com, 1 +californiahumanrights.tk, 1 +californiakingsnakepet.com, 1 +californiamusicacademy.com, 1 +californianet.tk, 1 +californiaonlinedivorce.com, 1 +californiavalues.cf, 1 +californiawomensmedicalclinic.com, 1 +calim.com.ar, 1 +calisteniaperu.ga, 1 +calitateavietii-ardeal.ro, 1 +calixa.io, 1 +calixte-concept.fr, 1 +call.me, 1 +callabs.net, 1 +callamnow.com, 1 +callanan.nl, 1 +callanenglish.tk, 1 +callanjg.co.uk, 1 +callantonia.com, 1 +callawayracing.se, 0 +callcenterdeluxecalls.nl, 1 +callear.org, 1 +callerstrom.se, 1 +calleveryday.com, 1 +callfordataspeakers.com, 1 +callfunc.com, 1 +callhub.io, 1 +callidus-vulpes.de, 1 +calligraph.gq, 1 +calligraphychic.com, 1 +callisabel.fr, 1 +callmebetty.com, 1 +callmewhatever.com, 1 +callmewhatever.de, 1 +callmewhatever.net, 1 +callsign.com, 1 +callsigns.ca, 1 +calltothepen.com, 1 +callumgroeger.com, 1 +callumsilcock.me, 1 +calluro.hr, 1 +callvip.tk, 1 +calminteractive.fr, 1 +calmtech.com, 1 +calomel.org, 1 +calonmahasiswa.com, 1 +calories.org, 1 +calotte-academy.com, 1 +calposa.ml, 1 +calu.me, 1 +calucon.de, 1 +calvadia.duckdns.org, 1 +calvario.tk, 1 +calverleyparish.church, 1 +calvin.my, 1 +calwildgarden.com, 1 +calypso-tour.net, 1 +calypsohost.net, 1 +calyxengineers.com, 1 +calyxinstitute.org, 1 +calzadonline1-latam.com, 1 +calzadonline1.com, 1 +calzaturesira.it, 1 +cam-et-xou.fr, 1 +camago.dk, 1 +camara360grados.com, 1 +camaradecomerciosiguatepeque.hn, 1 +camaradivisas.com, 1 +camaras.uno, 1 +camaraslima.com, 1 +camarilloelectric.com, 1 +camarilloelectrical.com, 1 +camarilloexteriorlighting.com, 1 +camarillolandscapelighting.com, 1 +camarillolighting.com, 1 +camarillooutdoorlighting.com, 1 +camarzanadetera.tk, 1 +camashop.de, 1 +camastowncar.com, 1 +camazoon.com, 1 +cambados.tk, 1 +cambait.tk, 1 +camberford.com, 1 +cambiamos.tk, 1 +cambier.org, 1 +cambiowatch.ch, 0 +cambodiainfo.tk, 1 +cambodian.dating, 1 +cambramanresa.cat, 1 +cambreaconsulting.com, 1 +cambridge-security.com, 1 +cambridgeanalytica.cz, 1 +cambridgebouncers.co.uk, 1 +cambridgeinfotech.in, 1 +cambridgesecuritygroup.org, 1 +cambridgetutors.com, 1 +cambuslangharriers.org, 1 +camcapital.com, 1 +camconn.cc, 1 +camdesign.pl, 1 +camel2243.com, 1 +camelflight.tk, 1 +camelforensics.com, 1 +camelia-poezii.tk, 1 +camelion.tk, 1 +camelservers.com, 1 +cameo-membership.uk, 1 +cameo.ee, 1 +cameos.bo, 1 +camera-podvod.tk, 1 +camerahire.com.au, 1 +cameraman.tk, 1 +cameramark.nl, 1 +camerashot.tk, 1 +cameraslyphotography.tk, 1 +cameraviva.com.br, 1 +cameronsiguenza.com, 1 +cameronstar.tk, 1 +cameroonlounge.com, 1 +camerweb.es, 1 +camfire.team, 1 +camilalima.adv.br, 1 +camilamoreno.tk, 1 +camilaporto.tk, 1 +camileonline.tk, 1 +camilia.io, 0 +camilomodzz.net, 1 +caminoneocatecumenal.tk, 1 +caminreal.tk, 1 +camionerosdecoslada.tk, 1 +camipress.ga, 1 +camisado.tk, 1 +camisantiago.tk, 1 +camisetas4fun.com.br, 1 +camisetasbichopreguica.com.br, 1 +camisetasmalwee.com.br, 1 +camisetasparatodos.tk, 1 +camjackson.net, 0 +camnews.tk, 1 +camolist.com, 1 +camouflaged.tk, 1 +camp-pleinsoleil.ch, 0 +campaign-ad.com, 1 +campaignlake.com, 1 +campaignwiki.org, 1 +campamentos.info, 1 +campanhamamypoko.com.br, 1 +campbellapplianceheatingandair.com, 1 +campcambodia.org, 1 +campdesante.com, 1 +campdetarragona.tk, 1 +campeonatoalemao.com.br, 1 +campercaravanmosman.nl, 1 +camperdays.de, 1 +camperlist.com, 1 +campermanaustralia.com, 1 +campertrailerfinance.com.au, 1 +camperverzekerd.nl, 1 +campfiretails.org, 1 +camping-le-pasquier.com, 1 +camping-seilershof.de, 1 +campingbuffs.com, 1 +campingcarlovers.com, 1 +campinghuntingshooting.com, 1 +campingshop.pl, 1 +campingskyhooks.com, 1 +campistry.net, 1 +camplaza.tk, 1 +campmackinaw.com, 1 +campo-salado.com, 1 +campona.hu, 1 +campsoulfestival.com, 1 +camptuk.org, 1 +campula.cz, 1 +campus-discounts.com, 1 +campus-finance.com, 1 +campusdrugprevention.gov, 1 +campuswire.com, 1 +campvana.com, 1 +campwabashi.org, 1 +campwaltblog.com, 1 +camrecord.ml, 1 +camrn.wtf, 1 +camrosewebservices.com, 1 +camshowdir.com, 1 +camshowdir.to, 1 +camshowhive.com, 1 +camshowhive.to, 1 +camshowhub.com, 1 +camshowhub.to, 1 +camshowplace.com, 1 +camshowplace.to, 1 +camshowstorage.com, 1 +camshowstorage.to, 1 +camshowverse.com, 1 +camshowverse.to, 1 +camsky.de, 0 +camtarappliances.com, 1 +can-amchains.com, 1 +can7.fr, 1 +canada-tourisme.ch, 0 +canada.ind.br, 0 +canadaabroad.com, 0 +canadabread.com, 0 +canadaclub.tk, 1 +canadacommunity.org, 1 +canadafactcheck.ca, 1 +canadaradon.com, 1 +canadasmotorcycle.ca, 1 +canadian.dating, 1 +canadianatheists.ca, 1 +canadianatheists.com, 1 +canadianchristianity.com, 1 +canadianfriendsofyadsarah.com, 1 +canadianmilitaryspouse.tk, 1 +canadianoutdoorequipment.com, 1 +canadianpointerclub.tk, 1 +canadiansrit.tk, 1 +canadiantouristboard.com, 1 +canakkalebasin.com, 1 +canal-onanismo.org, 1 +canaldelaespartera.tk, 1 +canalecontracting.com, 1 +canalescape.tk, 1 +canali.com, 1 +canalinterativo.cf, 1 +canalinterativo.ml, 1 +canalinterativo.tk, 1 +canaresidences.com, 1 +canaria.ga, 1 +canariculturacolor.com, 1 +canaryaspets.com, 1 +canarymod.net, 1 +canarypower.tk, 1 +canarys.cf, 1 +canavilage.com, 1 +canavillage.net, 1 +canavillagepuntacana.com, 1 +canavillageresidences.com, 1 +canberraoutletcentre.com.au, 1 +cancan.ml, 1 +cancerdata.nhs.uk, 1 +cancersintomas.com, 1 +cancertherapy.tk, 1 +cancunmx.com, 1 +cancunsouvenirs.com, 1 +candaceplayforth.com, 1 +candas.tk, 1 +candelaguatemala.tk, 1 +candelec.com, 0 +candeo-books.nl, 1 +candex.com, 1 +candguchocolat.com, 1 +candicecity.com, 0 +candidasa.com, 1 +candidateexperiencemarketing.nl, 1 +candidatlibre.net, 1 +candidaturedunprix.com, 1 +candinya.com, 1 +candinya.me, 1 +candlcastles.co.uk, 1 +candlelightediting.com, 1 +candlemakingexplained.com, 1 +cando.eu, 1 +candylion.rocks, 1 +candytip.ru, 1 +canekeiros.com.br, 1 +canellayachts.com, 1 +canetelareal.tk, 1 +canfazz.com, 1 +canfield.gov, 1 +cangku.in, 1 +cangku.one, 1 +canglong.net, 1 +cangurin.com, 1 +canhas.report, 1 +canhazip.com, 1 +canhq.tk, 1 +cani-compostelle.fr, 1 +canihavesome.coffee, 0 +caniuse.email, 1 +canker.org, 1 +canliradyodinle.life, 1 +canlom.tk, 1 +canmipai.com, 1 +cannabis-marijuana.com, 1 +cannabis.pe, 1 +cannabiscare.ca, 1 +cannabislegality.info, 1 +cannabismd.com, 1 +cannabiz.tk, 1 +cannacards.ca, 1 +cannagoals.com, 1 +cannahealth.com, 1 +cannamaca.com, 1 +cannarobotics.com, 1 +cannoli.london, 1 +cannon.org.cn, 0 +cannoncountytn.gov, 1 +cannyfoxx.me, 1 +canobag.es, 1 +canonisti.fi, 1 +canoonic.se, 1 +canopy.garden, 1 +canopy.ninja, 1 +canopycleaning.com.au, 1 +canopycleaningmelbourne.com.au, 1 +canopytax.com, 1 +canperclinicaveterinaria.com, 1 +cansworld.com, 1 +cant.at, 1 +cantaloupe.ga, 1 +cantarefacile.com, 1 +cantarella.tk, 1 +cantatio.ch, 0 +canterburybouncycastlehire.co.uk, 1 +cantical.com, 1 +cantik.co, 1 +cantonroadjewelry.com, 1 +cantor.cloud, 1 +cantosdisidentes.tk, 1 +cantstopart.com, 1 +canttboardpachmarhi.org, 1 +canukseeds.com, 1 +canva-dev.com, 1 +canva.cn, 1 +canva.com, 1 +canyons.media, 0 +canyonshoa.com, 1 +canyoupwn.me, 1 +cao.gov, 1 +cao.la, 1 +caodecristachines.com.br, 0 +caodesantohumberto.com.br, 1 +caodo.cf, 1 +caoliu.tech, 1 +caostura.com, 1 +caosudautieng.com.vn, 1 +cap-adrenaline.com, 1 +cap73.fr, 1 +capa.digital, 1 +capachitos.cl, 0 +capacitateparaelempleo.org, 1 +capacityproject.org, 1 +caparicasurfing.com, 1 +caparicasurflessons.com, 1 +capatech.co, 1 +capctury.com, 1 +capeannpediatrics.com, 1 +capehipandknee.co.za, 1 +capekeen.com, 1 +capellan.pe, 1 +capellen.tk, 1 +caph.info, 1 +caphane.com, 1 +caphapupolas.ga, 1 +caphefin.com, 1 +capike.cf, 1 +capila.com.br, 1 +capillary.io, 1 +capimlimaoflores.com.br, 1 +capitainebaggy.ch, 0 +capitains.tk, 1 +capital-electronics.ml, 1 +capital-match.com, 1 +capitalcap.com, 1 +capitalcollections.org.uk, 1 +capitalgrio.com, 1 +capitalibre.com, 1 +capitalism.party, 1 +capitalism.rip, 1 +capitalist.cf, 1 +capitaliz.io, 1 +capitalmarkets.online, 1 +capitalmatters.cf, 1 +capitalmediaventures.co.uk, 1 +capitalmedicals.co.nz, 1 +capitalonecardservice.com, 1 +capitalp.jp, 1 +capitalpay.ml, 1 +capitalquadatv.org.nz, 1 +capitalscum.tk, 1 +capitalstakepool.info, 1 +capitan.ml, 1 +capitanbeilinson.tk, 1 +capitapeskanova.tk, 1 +capitein.tk, 1 +capitolpathways.org, 1 +caplangage.com, 1 +caplinbouncycastles.co.uk, 1 +capnsaddle.com, 1 +capoeiravillenavedornon.fr, 1 +capota.tk, 1 +capper.de, 1 +capradip.in, 0 +capriccio.to, 1 +caprice-holdings.co.uk, 1 +caprichosdevicky.com, 1 +caprigo.ru, 1 +caps-hats.tk, 1 +caps.equipment, 1 +caps.is, 1 +caps.solutions, 1 +caps.systems, 1 +capsicle.tk, 1 +capsogusto.com, 1 +capssouthafrica.co.za, 1 +capsstudios.com, 1 +capstansecurity.co.uk, 1 +capstansecurity.com, 1 +capsuladigital.tk, 1 +capsule.org, 0 +capsulecorp.org, 1 +capsulekitchen.co, 1 +capsulesubs.fr, 1 +captain-dandelion.com, 1 +captainark.net, 1 +captainclaw.tk, 1 +captainfit.in, 1 +captainjanks.tk, 1 +captainscarlet.tk, 1 +captainsfarm.in, 1 +captainsunshine.tk, 1 +captalize.com, 1 +captivationscience.com, 1 +captivationtheory.com, 1 +capturapp.com, 0 +capture-app.com, 1 +capturebilling.com, 1 +captured-symphonies.com, 1 +capturelead.tk, 1 +capuchinox.com, 1 +caputo.com, 1 +caputodesign.com, 1 +capybaraowner.com, 1 +car-alarm.tk, 1 +car-clean-nord.de, 1 +car-diagnose.com, 1 +car-forums.com, 1 +car-market.tk, 1 +car-seats-store.ga, 1 +car-spaw-rac.fr, 1 +car-speed.tk, 1 +car-touch.tk, 1 +car.info, 1 +car24.de, 1 +car24portal.de, 1 +car3d.gq, 1 +cara-bisnis.tk, 1 +cara-mudah-hidup-sehat.tk, 1 +carac.org.in, 1 +caraccidentslawyer.tk, 1 +caraccio.li, 1 +caracterizacion.tk, 1 +carajas.tk, 1 +caraliadeluxe.net, 1 +caramellespinell.tk, 1 +carapax.net, 1 +carassure.de, 1 +carauctionnetwork.com, 1 +carauctionsalabama.com, 1 +carauctionscarolina.com, 1 +carauctionsgeorgia.com, 1 +carauctionsillinois.com, 1 +caravaca.tk, 1 +caravansciences.tk, 1 +caravanserail.info, 1 +caravelairclub.tk, 1 +carberra.io, 1 +carberra.xyz, 1 +carbon-designz.com, 1 +carbon-project.org, 1 +carbon.coop, 1 +carbon12.org, 1 +carbon12.software, 1 +carbonadvantage.tk, 1 +carboneventsupport.be, 1 +carboneventsupport.lu, 1 +carbonholic.org, 1 +carboniaccessori.com.br, 1 +carbonkiller.org, 1 +carbonlib.com, 1 +carbonmonoxidelawyer.net, 1 +carbonnel.me, 1 +carbono.uy, 1 +carbontv.com, 1 +carbonvision.cn, 0 +carburetorcycleoi.com, 1 +carbuyersbrisbane.com.au, 1 +carbuzz.com, 1 +carcani.com, 1 +carcare.net.au, 1 +carck.co.uk, 1 +carck.uk, 1 +carcleannord.de, 1 +carclinichn.com, 1 +carcloud.ch, 1 +carcountking.com, 1 +cardano.eco, 1 +cardanoinvestment.com, 1 +cardbouns.tk, 1 +cardcaptorsakura.jp, 1 +carddelivery.com, 1 +carddreams.es, 1 +cardexchangesolutions.com, 1 +cardfightcoalition.com, 1 +cardiaccane.com, 1 +cardiagnostics.tk, 1 +cardideas.xyz, 1 +cardinauto.fr, 1 +cardingforum.co, 1 +cardington.tk, 1 +cardioagainstcancer.nl, 1 +cardioai.com, 1 +cardiology.gq, 1 +cardios.srv.br, 1 +cardiosportsilvinadelgado.com, 0 +cardjit.su, 0 +cardloan-center.jp, 1 +cardloan-manual.net, 1 +cardmart.tk, 1 +cardoneshop.it, 1 +cardoni.net, 1 +cardpaymentoptions.com, 1 +cardranking.jp, 1 +cardrecovery.fr, 1 +cardsbymaria.com, 1 +cardschat.com, 1 +cardse.net, 0 +cardsolutionsbh.com.br, 1 +cardwars.hu, 1 +care-spot.biz, 1 +care-spot.com, 1 +care-spot.info, 1 +care-spot.mobi, 1 +care-spot.net, 1 +care-spot.org, 1 +care-spot.us, 1 +care4all.com, 1 +career.support, 1 +careercapital.co.za, 1 +careerdiary.co.uk, 1 +careergo.org, 1 +careeroptionscoach.com, 1 +careerpower.co.in, 1 +careerprep101.com, 1 +careersafeonline.com, 1 +careersandeducation.com, 1 +careerset.io, 1 +careertransformed.com, 1 +careervictor.in, 1 +careerwatchlist.com, 1 +carefy.ph, 1 +careify.org, 1 +careloco.tk, 1 +caremad.io, 1 +carepan.ga, 1 +carepassport.com, 1 +carespan.clinic, 1 +carespanclinic.ph, 1 +carespot.biz, 1 +carespot.co, 1 +carespot.mobi, 1 +carespot.net, 1 +carespot.org, 1 +carespot.us, 1 +carespotexpress.com, 1 +carespotexpresshealthcare.com, 1 +carespottravelmedicine.com, 1 +carespottravelmedicine.mobi, 1 +carespoturgentcare.com, 1 +carespoturgentcare.info, 1 +carespoturgentcare.net, 1 +carespoturgentcare.org, 1 +carespoturgentcare.us, 1 +caretta.co.uk, 1 +carevo.id, 1 +careyshop.cn, 1 +carezzaperu.com, 1 +carfinancehelp.com, 1 +carfinans.ru, 1 +carforme.gr, 1 +carfraemill.co.uk, 1 +cargobas.com, 1 +cargobay.net, 1 +cargoguard.com, 1 +cargoio.com, 1 +cargomaps.com, 1 +cargorestraintsystems.com.au, 1 +cargosapiens.com.br, 1 +cargotariff.ml, 1 +carhunters.cz, 1 +caribbean.dating, 1 +caribbeancinemas.com, 1 +caribbeanexams.com, 1 +caribbeansolutionslab.com, 1 +caribeeficiente.com.co, 1 +caribougrill.com, 1 +caribuku.tk, 1 +carigami.fr, 1 +cariki.gq, 1 +carikiv.gq, 1 +carimcoder.website, 1 +carinaklijn.nl, 1 +carine.ml, 1 +caringladies.org, 1 +caringmedicine.ga, 1 +caringpups.com, 1 +carinsurance.es, 1 +carinthia.eu, 1 +cariocabelos.com.br, 1 +carisenda.com, 1 +carium.com, 1 +carkeysanantonio.com, 1 +carkeysystem.com, 1 +carl-blum-haus.tk, 1 +carl-topham.com, 1 +carl.land, 1 +carlaschiavone.tk, 1 +carlcsaposs.com, 1 +carlesjavierre.com, 1 +carlesribot.tk, 1 +carlgo11.com, 1 +carlife-at.jp, 1 +carlingfordapartments.com.au, 1 +carlingforddental.com.au, 1 +carlinmack.com, 1 +carlislepassionplay.org, 1 +carlitoxxpro.com, 1 +carlmjohnson.net, 0 +carloancalculator.tk, 1 +carlobiagi.de, 1 +carlocksmith--dallas.com, 1 +carlocksmithbaltimore.com, 1 +carlocksmithcarrollton.com, 1 +carlocksmithellicottcity.com, 1 +carlocksmithfallbrook.com, 1 +carlocksmithkey.com, 1 +carlocksmithlewisville.com, 1 +carlocksmithmesquite.com, 1 +carlocksmithtucson.com, 1 +carlolacana.tk, 1 +carlosabarbamd.com, 1 +carlosbronze.com.br, 1 +carloscar.art, 1 +carloscar.co, 1 +carloscar.com, 1 +carloscar.se, 1 +carlosfelic.io, 1 +carlosguadian.tk, 1 +carloshmm.com, 1 +carloshmm.stream, 1 +carloshmoreira.com, 1 +carlosjeurissen.com, 1 +carlosjeurissen.nl, 1 +carlospiga.fr, 1 +carlosvelezmarketing.com, 1 +carlot-j.com, 1 +carlovanwyk.com, 1 +carls-fallout-4-guide.com, 1 +carlsbadluxuryhotels.ga, 1 +carltonelitetravel.ga, 1 +carltontownfc.tk, 1 +carmageddon.tk, 1 +carmarthenradiocontrolledcarclub.tk, 1 +carmatworld.co.uk, 1 +carmela.tk, 1 +carmelglenane.com, 1 +carmelrise.co.uk, 1 +carmelss.edu.hk, 1 +carmengrayfanclub.tk, 1 +carmeni.tk, 1 +carmenluz.fr, 1 +carmeny.org, 1 +carmineforsheriff.com, 1 +carnaticalifornia.com, 1 +carnavaldeltoro.tk, 1 +carnavales.tk, 1 +carnet-du-voyageur.com, 1 +carnetdeconducir.club, 1 +carnica.tk, 1 +carnildo.com, 1 +carnivalcostumes.tk, 1 +carnivorousplants.co.uk, 1 +carocream.org, 1 +caroes.be, 1 +caroffer.ch, 1 +caroinstitute.cf, 1 +carol-lambert.com, 1 +carolcappelletti.com, 1 +carolcestas.com, 1 +carolcoleventures.com, 1 +carolcollv.com, 1 +caroletolila.com, 1 +caroli.biz, 1 +caroli.com, 1 +caroli.info, 1 +caroli.name, 1 +caroli.net, 1 +carolicious.tk, 1 +carolina.cz, 1 +carolinaclimatecontrolsc.com, 1 +carolinaoliveira.tk, 1 +carolinapainandspine.com, 1 +carolinavarletaarriagada.tk, 1 +carolinavein.com, 1 +carolineball.com, 1 +carolineeball.com, 1 +carolinegirvan.com, 1 +carolinehanania.com, 1 +carolinelanthier.com, 1 +carolineovercash.com, 1 +carolinepleuvret.fr, 1 +carolmolinari.tk, 1 +carontetourist.hr, 1 +carontetouristisoleminori.it, 1 +carousel.ga, 1 +carp4life.tk, 1 +carparo.net, 1 +carpentrybyallen.com, 1 +carpet---cleaning.com, 1 +carpetandhardwoodflooringpros.com, 1 +carpetcleanerswilmington.com, 1 +carpetcleaning-cypress.com, 1 +carpetcleaningtomball.com, 1 +carpetcobblers.ga, 1 +carpio.tk, 1 +carplus.es, 1 +carplus.net, 1 +carpticon.tk, 1 +carpuya.ga, 1 +carrabiners.tk, 1 +carrando.com, 1 +carre-jardin.com, 1 +carre-lutz.com, 1 +carreraspopularescalendario.com, 1 +carriage.fun, 1 +carriedin.com, 1 +carrier.tools, 1 +carrierplatform.com, 1 +carrieunderwood.tk, 1 +carringtonrealtygroup.com, 1 +carrion.tk, 1 +carroattrezzi.roma.it, 1 +carroattrezzimilanodaluiso.it, 1 +carroceriascarluis.com, 1 +carrolcountyohioelections.gov, 1 +carrollcountyiowa.gov, 1 +carrolltontx.gov, 1 +carrouselcompany.fr, 1 +carry.luxe, 1 +carryvanbruggen.tk, 1 +cars4salecy.com, 1 +carseatchecks.ca, 1 +carshippingcarriers.com, 1 +carskil.com, 1 +carson-aviation-adventures.com, 1 +carson-matthews.co.uk, 1 +carsonca.gov, 1 +carsonkoziol.com, 1 +carsoug.com, 1 +carspicture.tk, 1 +carspneu.cz, 1 +carsworld.cf, 1 +cartadeviajes.cl, 1 +cartadeviajes.co, 1 +cartadeviajes.com, 1 +cartadeviajes.com.ar, 1 +cartadeviajes.com.ve, 1 +cartadeviajes.de, 1 +cartadeviajes.ec, 1 +cartadeviajes.es, 1 +cartadeviajes.fr, 1 +cartadeviajes.mx, 1 +cartadeviajes.pe, 1 +cartadeviajes.uk, 1 +cartago.co.cr, 1 +cartaisapre.com, 1 +cartale.ru, 1 +cartaodigi.com, 1 +cartegrise.xyz, 1 +cartelloni.roma.it, 1 +carterdan.net, 1 +carterstad.se, 1 +cartertonscouts.org.nz, 0 +cartes-voyance.fr, 1 +cartfilm.tk, 1 +cartft.com, 1 +carthedral.com, 1 +cartierplan.ga, 0 +carto.la, 1 +cartomancieperso.tk, 1 +cartongesso.roma.it, 1 +cartons-cheap.tk, 1 +cartooncastles.ie, 1 +cartoservice.tk, 1 +cartouche24.eu, 1 +cartridge.gq, 1 +cartridgesave.co.uk, 1 +cartucce24.it, 1 +cartuchoonline.com.br, 1 +cartunings.tk, 1 +cartwrightrealestate.com, 1 +carusorealestate.com, 1 +carwashdruten.nl, 1 +carwellness-hinkelmann.de, 1 +carwreckcowboy.com, 1 +cas-chauxdefonds.ch, 1 +casa-app.de, 1 +casa-brel.ml, 1 +casa-familia.com, 1 +casa-indigo.com, 1 +casa-laguna.net, 1 +casa-lunch-break.de, 1 +casa-lunchbreak.de, 1 +casa-mea-inteligenta.ro, 1 +casa-prince.tk, 1 +casaanastasia.ro, 0 +casaasia.cat, 1 +casaasia.es, 1 +casaasia.eu, 1 +casabella.com.tw, 1 +casacazoleiro.com, 1 +casachameleonhotels.com, 1 +casacochecurro.com, 1 +casadasmolas.tk, 1 +casadasportasejanelas.com, 1 +casadedios.tk, 1 +casadegomes.com, 1 +casadilanga.com, 1 +casadoarbitro.com.br, 1 +casadomus.de, 1 +casadopulpo.com, 1 +casaessencias.com.br, 1 +casafina.tk, 1 +casaformen.com.br, 1 +casalborgo.it, 1 +casaledibuccole.it, 1 +casalindamex.com, 1 +casalinghedisperate.ga, 1 +casalopez.tk, 1 +casalor.ro, 1 +casalribeiro.com, 1 +casalunchbreak.de, 1 +casamarrom.com.br, 1 +casamentos.com.br, 1 +casamentos.pt, 1 +casamiento.com.uy, 1 +casamientos.com.ar, 1 +casandraemge.tk, 1 +casanonnaida.it, 1 +casanovafishtacos.com, 1 +casanuova.tk, 1 +casapalla.com.br, 1 +casapedra.tk, 1 +casasincreibles.com, 1 +casasparaperross.com, 1 +casasuara.com, 1 +casasuleletrodomesticos.com.br, 1 +casatendeiro.tk, 1 +casavacanze.estate, 1 +casavaleria.tk, 1 +casbia.info, 0 +casbuijs.nl, 1 +casc.cz, 1 +casca.tk, 1 +cascadesjobcorpscca.com, 1 +cascavelle.fr, 1 +cascavelle.nl, 1 +case-vacanza-salento.com, 1 +case3d.ro, 1 +casecandy.in, 1 +casecoverkeygi.com, 1 +casecurity.org, 1 +caseificio.roma.it, 1 +caselemnbarat.ro, 1 +casemaka.com, 1 +caseof.fr, 1 +caseplus-daem.de, 1 +cases.lu, 1 +caseycapitalpartners.com, 1 +casgp.com, 0 +cash-bot.tk, 1 +cash-generator.tk, 1 +cash-pos.com, 1 +cash.app, 1 +cash.me, 1 +cash.nyc, 1 +cashamerican.tk, 1 +cashati.com, 1 +cashbackcow.us, 1 +cashblog.ga, 1 +cashbook.co.tz, 1 +cashbot.cz, 1 +cashbot.sk, 1 +cashdrop.ga, 1 +cashenvoy.com, 1 +cashfazz.com, 1 +cashflowstrategist.com, 1 +cashforcarremovalsipswich.com.au, 1 +cashfortulsahouses.com, 1 +cashline.tk, 1 +cashlink.de, 0 +cashlogic.ch, 0 +cashmanagerbg.com, 1 +cashmaxtexas.com, 1 +cashontime.com, 1 +cashplk.com, 1 +cashregistry.tk, 1 +cashsector.ga, 1 +cashworks.ga, 1 +cashyourcar.sydney, 1 +casian.ir, 1 +casillasdecoria.tk, 1 +casino-cash-flow.com, 1 +casino-cash-flow.com.ru, 1 +casino-cash-flow.info, 1 +casino-cash-flow.pro, 1 +casino-cash-flow.ru, 1 +casino-cash-flow.su, 1 +casino-cashflow.ru, 1 +casino-trio.com, 1 +casino.fail, 1 +casino.tires, 1 +casino.viajes, 1 +casinocash-flow.ru, 1 +casinocashflow.pro, 1 +casinocashflow.ru, 1 +casinocashflow.su, 1 +casinocashflow.xyz, 1 +casinochecking.com, 1 +casinoexpress.cz, 1 +casinolegal.pt, 1 +casinolistings.com, 1 +casinomiami.net, 1 +casinomucho.com, 1 +casinomucho.org, 1 +casinomucho.se, 1 +casinoonlineprova.com, 1 +casinoonlinesicuri.com, 1 +casinoportugal.pt, 1 +casinoreal.com, 1 +casinorewards.info, 1 +casinorobots.com, 1 +casinosblockchain.io, 1 +casinotokelau.tk, 1 +casinoworldz.com, 1 +casio-caisses-enregistreuses.fr, 1 +casio.bg, 1 +casitawn.cf, 1 +casjay.cloud, 0 +casjay.com, 0 +casjaygames.com, 0 +casjenprome.cz, 1 +casko-insurance.tk, 1 +casman.tk, 1 +casperfirm.com, 1 +casperpanel.com, 1 +caspi.org.il, 1 +caspianrentcar.com, 1 +caspicards.com, 1 +cass.cz, 1 +casscountyia.gov, 1 +cassies.com.au, 1 +cassimo.com, 0 +cassini.ro, 1 +castagnola.tk, 1 +castalie.tk, 1 +castaneda.tk, 1 +castelannenberg.com, 1 +castella.tk, 1 +castellannenberg.com, 1 +castellet.tk, 1 +castelletto.tk, 1 +castelnuovo.xyz, 1 +casteloinformatica.com.br, 1 +casthull.co.uk, 1 +castiana.xyz, 1 +castible.de, 1 +castilla-comunera.tk, 1 +casting-vote.tk, 1 +castings.tk, 1 +castlabs.com, 0 +castle-engine.io, 1 +castlecapers.com.au, 1 +castlehack.ga, 1 +castlekingdomstockport.co.uk, 1 +castlekingkent.co.uk, 1 +castleoblivion.tk, 1 +castleparty.co.uk, 1 +castles-in-the-sky.co.uk, 1 +castlesrus-kent.com, 1 +castleswa.com.au, 1 +castorio.tk, 1 +castrillodelavalduerna.tk, 1 +castrillodelavega.tk, 1 +castrillodevillavega.tk, 1 +castroverde.tk, 1 +castrovirreyna.tk, 1 +casualclubdating.ml, 1 +casualiswebs.com, 1 +casualtime.ga, 1 +casusgrillcaribbean.com, 1 +casvpn.com, 1 +cat-encyclopedia.ml, 1 +cat-problems.ml, 1 +cat.ax, 1 +cat.net, 1 +cat1solution.com, 1 +cat2heory.es, 1 +cat73.org, 1 +catalog-clothing.tk, 1 +catalog-lingerie.tk, 1 +catalog-lingeries.tk, 1 +catalog-serverov.ml, 1 +catalog-underwear.tk, 1 +catalog.beer, 1 +catalogador.ml, 1 +catalogcomputerhardware.tk, 1 +catalogobiblioteca.com, 1 +catalogobiblioteca.net, 1 +catalogocarrefour.com, 1 +catalogosvirtualesonline.com, 1 +catalojic.tk, 1 +catalonia.tk, 1 +catalyconv.com, 1 +catalyst-ecommerce.com, 1 +catalystapp.co, 1 +catapultgroup.ca, 1 +catartofsweden.se, 1 +catastrofy.tk, 1 +catbold.space, 1 +catbox.moe, 1 +catbull.com, 1 +catcat.cc, 1 +catchall.tw, 1 +catchers.cc, 1 +catchhimandkeephim.com, 1 +catchief.com, 1 +catcontent.cloud, 1 +catcoxx.com, 1 +catenacondos.com, 1 +caterbing.com, 1 +catering-xanadu.cz, 1 +cateringvanhetland.nl, 1 +cateromarket.pl, 1 +catfood.ga, 1 +catgarden.tk, 1 +catharinesomerville.com, 1 +catharisme.net, 1 +catharisme.org, 1 +cathcartandwinn.com, 1 +cathcartconsulting.com.au, 1 +catherinejf.com, 1 +catherinejflee.com, 1 +catherinesarasin.com, 1 +catherinesofpartick.co.uk, 0 +catholic8964.org, 1 +catholicprayers.tk, 1 +catholics.dating, 1 +catholicteuchtar.cf, 1 +cathosa.nl, 1 +cathosting.org, 1 +cathouse.me, 1 +cathrine.tk, 1 +cathy.best, 1 +cathy.guru, 1 +cathy.legal, 1 +cathy.lgbt, 1 +cathy.link, 1 +cathy.website, 1 +cathyfitzpatrick.com, 1 +cathyjf.ca, 1 +cathyjf.com, 1 +cathyjf.net, 1 +cathyjf.org, 1 +cathyjfitzpatrick.com, 1 +cativa.net, 1 +catl.st, 1 +catlovingcare.com, 1 +catmash.tk, 1 +catme.org, 1 +catmoose.ca, 1 +catmoz.fr, 1 +catnmeow.com, 1 +catpic.xyz, 1 +catprincess.com.tw, 1 +catpumpsonline.com, 1 +catram.org, 1 +catriel25noticias.com, 1 +catsmagic.pp.ua, 1 +catsnow.com, 1 +catsoft.me, 1 +catstv.tk, 1 +cattery.work, 1 +catterydelmoria.tk, 1 +cattleplay.gq, 1 +cattsgym.co.uk, 1 +catuniverse.org, 1 +catus.moe, 1 +catveteran.com, 1 +catvsmice.com, 1 +catwilliford.com, 1 +catz-productions.tk, 1 +caucasusandmercury.com, 1 +caucus.fr, 1 +caudo.net, 1 +caudohay.com, 1 +caughtredhanded.co.nz, 1 +caulacbonuochoa.tk, 1 +caulfieldeastapartments.com.au, 1 +caulfieldracecourseapartments.com.au, 1 +caulkingexperts.com, 1 +caulong-ao.net, 1 +caumont-normandie.fr, 1 +cav.ac, 1 +cavac.at, 1 +cavaleirocity.com.br, 1 +cavalierkingcharlesspaniel.com.br, 1 +cave-reynard.ch, 1 +cave-vet-specialists.co.uk, 1 +cavecreekaz.gov, 1 +cavediverharry.com, 1 +cavediving.com, 1 +cavemax.com, 1 +cavenderhill.com, 1 +cavern.tv, 1 +cavinesswealth.com, 1 +cavisson.com, 1 +cavistenancy.fr, 1 +cavzodiaco.com.br, 1 +cawagiras.ga, 1 +caycehouse.com, 1 +caylee.de, 1 +caylercapital.com, 1 +cazadordebuenaonda.com, 1 +cazaviajes.es, 1 +cazes.info, 1 +cb-crochet.com, 1 +cb1388.com, 1 +cb1588.com, 1 +cbaamaga.com, 1 +cbbank.com, 1 +cbc-hire.co.uk, 1 +cbca.gov, 1 +cbcentelles.tk, 1 +cbcf.info, 1 +cbd-specialty.com, 1 +cbd.casa, 1 +cbd.supply, 1 +cbd181.com, 1 +cbd2050.com, 1 +cbdbflo.com, 1 +cbdbonplan.com, 1 +cbdcontact.eu, 1 +cbdcontact.pl, 1 +cbdeighty.com, 1 +cbdev.de, 1 +cbdlession.com, 1 +cbdmarket.space, 1 +cbdoilcures.co, 1 +cbdoils.llc, 1 +cbdtelegram.com, 1 +cbecrft.net, 1 +cbh.org, 1 +cbhq.net, 1 +cbi-epa.gov, 1 +cbin168.com, 1 +cbin9.com, 1 +cbintermountainrealty.com, 1 +cbmanager.dk, 1 +cbmusa.com, 1 +cbnainital.org.in, 1 +cboard.ml, 1 +cbproject.co.za, 1 +cbr-rcb.ca, 1 +cbr-xml-daily.ru, 1 +cbrtrainer.com, 1 +cbsdeheidevlinder.nl, 1 +cbt.tj, 1 +cbw.sh, 1 +cbws.nl, 1 +cbxp.in, 1 +cc-customer.de, 1 +cc.hn, 1 +cc00228.com, 1 +cc3m.com, 1 +cc5197.co, 1 +cc6729.co, 1 +cc6729.com, 1 +cc6957.co, 1 +cc8822.cc, 1 +cc8833.cc, 1 +cc9297.co, 1 +cc9397.com, 1 +cc9721.com, 1 +cc9728.co, 1 +cc98.eu.org, 1 +ccaag.net, 0 +ccac.gov, 1 +ccaguavivadonaciones.org, 1 +ccaj.io, 1 +ccamatilfiji.com, 1 +ccarps.com, 1 +ccatpracticetest.com, 1 +ccattestprep.com, 1 +ccayearbook.com, 1 +ccbin.tk, 1 +ccc-ch.ch, 1 +ccc-cloud.de, 1 +cccams.tv, 1 +cccanna.co, 1 +cccp-o.tk, 1 +cccwien.at, 1 +ccdgaia.pt, 0 +ccdiscussion.com, 1 +ccdlab.ooo, 1 +ccdnederland.org, 1 +ccea.fi, 1 +ccelectricaldrafting.ca, 1 +cceputnam360.com, 1 +ccgn.co, 1 +ccgx.de, 1 +cchat.de, 1 +ccl-sti.ch, 0 +cclasabana.com.co, 1 +ccli.com, 1 +ccn.com, 1 +ccnadesdecero.com, 1 +ccnexus.global, 1 +ccoooss.com, 1 +ccpaas.net, 1 +ccparishwilmington.org, 1 +ccpinvestments.com, 1 +ccprwebsite.org, 1 +ccr.ovh, 1 +ccrun.tk, 1 +ccsae.org, 1 +ccsaposs.com, 1 +ccsistema.com, 1 +ccsource.org, 1 +ccsys.com, 1 +cctf-m.com, 0 +cctv-camera.cf, 1 +cctv-supraveghere.ro, 1 +cctv-systems.tk, 1 +cctvsecurityjohannesburg.co.za, 1 +cctvview.info, 0 +ccu.in.ua, 1 +ccu.plus, 1 +ccwebdevelopment.com, 1 +ccxsta.com, 1 +cd-shopware.de, 1 +cd-sport.com, 1 +cd.search.yahoo.com, 0 +cda-aigle.ch, 1 +cdasenegal.com, 1 +cdasiaonline.com, 0 +cdbf.ch, 0 +cdbp.pro, 1 +cdbtech.com, 1 +cdburnerxp.se, 1 +cdc.cx, 1 +cdcpartners.gov, 1 +cdda.ch, 0 +cddwwj.com, 1 +cdeck.net, 1 +cdepot.eu, 1 +cdf.wiki, 1 +cdfnature2019.fr, 1 +cdhome.ga, 1 +cdhqt.com, 1 +cdigitale.com, 1 +cdirectory.tk, 1 +cdkeyprices.com, 1 +cdkeyworld.de, 1 +cdkpatterns.com, 1 +cdkrot.me, 1 +cdlinares.tk, 1 +cdmdisinfestazioni.it, 1 +cdmhp.org.nz, 1 +cdmon.tech, 1 +cdn.ampproject.org, 1 +cdn1muvix.xyz, 1 +cdn1shweflix.xyz, 1 +cdn6.de, 1 +cdnaval.tk, 1 +cdncompanies.com, 1 +cdnjs.com, 1 +cdnk39.com, 1 +cdns.cloud, 1 +cdnsys.net, 1 +cdnya.com, 1 +cdocs.ml, 1 +cdom.de, 1 +cdrjapan.co.jp, 1 +cdrom.ch, 1 +cds-infra.de, 1 +cdseditora.com.br, 1 +cdshining.com, 0 +cdsportal.uk, 1 +cdt.org, 0 +cdu-gebhardshain.de, 1 +cduckett.net, 1 +cdvl.org, 1 +ce-agentur.de, 0 +ce-pimkie.fr, 1 +ce-tuifrance.com, 1 +ce-webdesign.de, 1 +ceafinney.com, 1 +ceanimalhealth.com, 1 +ceba-cuec.ca, 1 +cebrita.tk, 1 +cecalivo.tk, 1 +cecame.ch, 1 +cecamericas.com, 1 +cecil.coop, 1 +ceciledekock.tk, 1 +cecilga.gov, 1 +cecilgreens.org, 1 +cecilia-online.nl, 1 +ceciliacolombara.com, 1 +cecilwalker.com.au, 0 +ceco.cf, 1 +ced-services.nl, 1 +cedac.com.br, 1 +cedarcitydining.com, 1 +cedric-garcia.tk, 1 +cedricbonhomme.org, 1 +cedriccassimo.ch, 0 +cedriccassimo.com, 0 +cedricwalter.ch, 1 +cee-trust.org, 1 +cee.io, 1 +ceebee.com, 1 +ceefaastresources.com, 1 +cegfw.com, 1 +cegss.org.gt, 1 +ceiba.com.co, 1 +ceifx.com, 1 +ceiling.cloud, 1 +ceilingpac.org, 1 +ceiphr.com, 1 +cejgsd.org, 1 +cejhon.cz, 0 +cekabajio.com, 1 +celadas.tk, 1 +celcelulares.com, 1 +celcomhomefibre.com.my, 1 +cele.bi, 1 +celebavirus.com, 1 +celebdaily.ga, 1 +celebmasta.com, 1 +celebrasianconference.com, 1 +celebrate-creativity.com, 1 +celebratingloveministry.com, 1 +celebrationoflifeplanning.co.uk, 1 +celebratoday.com, 1 +celebraze.tk, 1 +celebrex.ga, 1 +celebrex100mg.cf, 1 +celebrities.pictures, 1 +celebritiesblog.tk, 1 +celebritydailynews.ml, 1 +celebrityfakes.tk, 1 +celebrityhealthcritic.com, 1 +celebrityphotos.blog, 1 +celebritypics.club, 1 +celebritypics.co, 1 +celebrityscope.net, 1 +celebritysrit.tk, 1 +celebritytopnews.tk, 1 +celebxx.com, 1 +celectro-pro.com, 1 +celeirorural.com.br, 0 +celendo.ga, 1 +celeraindustries.tk, 1 +celestebonito.pt, 1 +celestia.tk, 1 +celestialenergies.com.au, 1 +celestialisms.com, 1 +celex-machinery.tk, 1 +celexa365.tk, 1 +celiac.com, 1 +celiendev.ch, 0 +celine-patisserie.fr, 1 +cellboost.cf, 1 +cellebrite.com, 1 +cellecci.com, 1 +celliberate.co.uk, 1 +cellohealth.com, 1 +cellsheet.me, 1 +celltek-server.de, 0 +celltesequ.com, 1 +celltick.com, 1 +cellufit.ga, 1 +cellulare.tk, 1 +celluliteorangeskin.com, 1 +celluliteremovaldiet.com, 1 +cellypso.com, 1 +celmetro.com, 0 +celseven.com, 1 +celsoazevedo.com, 1 +celsusnicosia.com, 1 +celtacad.tk, 1 +celtadigital.com, 1 +celti.ie.eu.org, 1 +celti.name, 1 +celticangel.org, 1 +celulares.com, 1 +celuliteonline.com, 1 +cemcerkez.com, 1 +cementscience.com, 1 +cemetary.tk, 1 +ceml.ch, 1 +cenatorium.pl, 1 +cencalvia.org, 1 +cendata.co.uk, 1 +cendi.gov, 1 +cendis.cz, 1 +cenfo.dk, 1 +cennelley.com, 1 +cennelly.com, 1 +cennetfm.tk, 1 +cennetforum.tk, 1 +censored.ml, 1 +censurfridns.dk, 1 +censurfridns.nu, 1 +censys.io, 1 +centella.tw, 1 +centenariodeuncampeon.tk, 1 +centenera.tk, 1 +centennialrewards.com, 1 +centennialseptic.com, 1 +centenodigital.es, 1 +centerforamericangreatness.com, 1 +centermk.ru, 1 +centerpereezd.ru, 0 +centerperson.org, 1 +centerpoint.ovh, 1 +centervilleutah.gov, 1 +centio.bg, 1 +centos.cz, 1 +centos.pub, 1 +centos.tips, 1 +centr.dn.ua, 1 +central-apartman.tk, 1 +central4.me, 1 +centralcityjuniorkindergarten.com, 1 +centralcoasthomeloans.com.au, 1 +centralconvergence.com, 1 +centraldelbebe.com, 1 +centraldoencanador.com.br, 1 +centrale-vapeur.pro, 1 +centralebigmat.eu, 1 +centralegedimat.eu, 1 +centralex.io, 1 +centralfor.me, 1 +centralhq.tk, 1 +centralitasbaratas.es, 1 +centraljerseyrcca.com, 1 +centrallead.net, 1 +centralmarket.com, 0 +centralmissourifoundationrepair.com, 1 +centralpaellera.com, 1 +centralpoint.be, 0 +centralpoint.nl, 0 +centralsite.tk, 1 +centralsoft.tk, 1 +centralstatecu.org, 1 +centralvoice.org, 1 +centrationgame.com, 1 +centre-equestre.net, 1 +centreagree.com, 1 +centreautofronton.com, 1 +centredaccueil.fr, 0 +centrederessourcement.com, 1 +centreparkhistoricdistrict.org, 1 +centrepointorguk-dev.azurewebsites.net, 1 +centretownshipin.gov, 1 +centricagency.co.uk, 1 +centricbeats.com, 1 +centrmebeli.by, 0 +centroavant.com, 1 +centrobill.com, 1 +centroculturalostuncalco.tk, 1 +centrodeeportesbarco.tk, 1 +centrodemioma.com.br, 1 +centroecuestrecastellar.com, 1 +centrojovencuenca.es, 1 +centrolavoro.org, 1 +centromedico.tk, 1 +centrooftalmologicomg.com.br, 1 +centroperugia.gr, 1 +centrosocialferrel.pt, 1 +centrum-edukacji.tk, 1 +centrumhodinek.cz, 1 +centrumpieknairelaksu.pl, 1 +centruvechisv.ro, 1 +centsay.info, 1 +centsay.io, 1 +centsay.net, 1 +centsay.org, 1 +centsi.io, 1 +centsiwallet.com, 1 +centum.no, 1 +centumail.com, 1 +centura.de, 1 +centurialeonina.com, 1 +centurion-consulting-cie.eu, 1 +centurion-consulting.eu, 1 +centurion-consulting.net, 1 +centurion-consulting.tech, 1 +centurion-it.site, 1 +centurion-meet.site, 1 +centurioninfosec.com, 1 +centurioninfosec.com.sg, 1 +centurioninfosec.hk, 1 +centurioninfosec.sg, 1 +centurionplumber24-7.co.za, 1 +centuryfighters.tk, 1 +centuryforum.tk, 1 +centurykiaparts.com, 1 +centurylink.cf, 1 +centurymedicaldental.com, 1 +ceopedia.org, 1 +cepek4d.com, 1 +cephalexin.ga, 1 +cephalexincapsules.ml, 1 +cephalexincapsules.tk, 1 +cepsychologie.com, 1 +cepxuo.tk, 1 +ceramic-glazes.com, 1 +ceramica.roma.it, 1 +ceramiche.roma.it, 1 +ceramixcoating.nl, 1 +ceramiya.com, 1 +cerastar.com, 1 +cerber.us, 1 +cerberis.com, 1 +cerberusecurity.com, 1 +cerberusinformatica.it, 1 +cerbottana.duckdns.org, 1 +cerda-avocats.com, 1 +cerebelo.info, 1 +cerebrosano.gov, 1 +cerecup.com, 0 +ceredowv.gov, 1 +ceremonial-magic.com, 1 +ceremonialvirtualphd.com, 1 +cerena-silver.ru, 0 +ceres-corp.org, 1 +cerivo.co.uk, 1 +cermak.photos, 1 +cernac.cz, 1 +cernakova.eu, 1 +cerno-ps.com, 1 +cerocosto.com, 1 +cerovica.tk, 1 +cerpus-course.com, 1 +cerrajeriaamericadelquindio.com, 1 +cerrajeriaenvillavicencio.com, 1 +cerstve-korenie.sk, 1 +cerstvekorenie.sk, 1 +cert.ee, 1 +cert.govt.nz, 1 +cert.or.id, 1 +cert.se, 1 +certainbiz-news.tk, 1 +certaintelligence.com, 1 +certbus.com, 1 +certevia.com, 1 +certfa.com, 1 +certible.com, 1 +certificacaoiso.com.br, 1 +certificatedetails.com, 1 +certificateoflogistics.ga, 1 +certificateofpurchasing.ga, 1 +certificatespending.com, 1 +certificatetools.com, 0 +certificato-prevenzione-incendi.it, 1 +certificazione.it, 1 +certificazioni-energetiche.it, 1 +certifiedblk.com, 1 +certifiedfieldassociate.com, 1 +certifiednurses.org, 1 +certifix.eu, 1 +certnazionale.it, 1 +certprep.fr, 1 +certpro.uk, 1 +certreg.eu, 1 +certspotter.com, 1 +certspotter.org, 1 +cervejista.com, 1 +cervenyjezek.eu, 1 +cervera.com.br, 1 +ces-ltd.co.uk, 0 +cesar-hector.tk, 1 +cesarloaiciga.com, 1 +cesarparedespacora.com, 1 +cesboard.com, 1 +cescfortuny.tk, 1 +cesdb.com, 1 +cesipagano.com, 1 +cesium.ml, 1 +ceska-polygraficka.cz, 1 +ceskaexpedice.org, 1 +ceskepivnesety.sk, 1 +ceskepivnisety.cz, 1 +cesobaly.cz, 1 +cestasedelicias.com.br, 1 +cestaswmonline.com.br, 1 +cestpasviolent.com, 1 +cetamol.com, 1 +cetelon.tk, 1 +ceu.edu, 0 +ceverett.io, 1 +cevin.at, 1 +cevo.com.hr, 1 +cevt.ar, 1 +cewek.ml, 1 +cewood.xyz, 1 +ceyhanmolla.com, 1 +ceyizlikelisleri.com, 1 +cf-ide.de, 1 +cf-tm.net, 1 +cfa.gov, 1 +cfan.space, 1 +cfc-swc.gc.ca, 1 +cfcpestcontrol.com, 1 +cfda.gov, 1 +cfdcre5.org, 1 +cfenns.ath.cx, 1 +cfent.xyz, 1 +cfigura.com, 1 +cfno.org, 1 +cfo.gov, 0 +cfo4you.com, 1 +cfotech.asia, 1 +cfotech.co.nz, 1 +cfotech.com.au, 1 +cfpa-formation.fr, 1 +cfrq.ca, 1 +cfsh.tk, 1 +cftc.gov, 1 +cftcarouge.com, 0 +cfurl.cf, 1 +cfxdesign.com, 1 +cg-systems.hu, 1 +cg.al, 1 +cg.search.yahoo.com, 0 +cga.best, 1 +cgal.org, 1 +cgan.de, 1 +cgan.pw, 1 +cgbassurances.ch, 0 +cgbproduction.tk, 1 +cgbunch.com, 1 +cgelves.com, 1 +cges.xyz, 1 +cgf-charcuterie.com, 1 +cgglobalservices.com.es, 1 +cgha.us, 1 +cgionline.tk, 1 +cgknieuwpoort.nl, 1 +cglib.xyz, 1 +cgmagonline.com, 1 +cgmbacklot.com, 1 +cgminc.net, 1 +cgn-medienservice.de, 1 +cgp.moe, 1 +cgpe.com, 0 +cgplumbing.com, 1 +cgps.xyz, 1 +cgsmart.com, 1 +cgtcaixabank.es, 1 +cgtx.us, 1 +cgurtner.ch, 1 +ch-investor.tk, 1 +ch-laborit.fr, 1 +ch-y.org, 1 +ch.bzh, 1 +ch.search.yahoo.com, 0 +ch47f.com, 1 +ch4bb.org, 1 +cha-ta.com, 1 +chaacker.tk, 1 +chabad360.me, 1 +chabadmyanmar.com, 1 +chabakainfo.com, 1 +chabaudparfum.com, 1 +chabert-provence.fr, 1 +chabik.com, 1 +chaboisseau.net, 1 +chacoonline.com.py, 1 +chacraexperimental.com.py, 1 +chad-online.tk, 1 +chad.ch, 1 +chaddidit.com, 1 +chadlenz.ca, 1 +chadoisaac.com, 1 +chadpugsley.com, 1 +chadstoneapartments.com.au, 1 +chadtaljaardt.com, 1 +chagahq.com, 1 +chaghi.tk, 1 +chahal.blog, 1 +chai-che.com, 1 +chaifeng.com, 1 +chaikaclub.tk, 1 +chainedunion.info, 1 +chainels.com, 1 +chainge-re.com, 1 +chainlinkfencestlouis.com, 1 +chainz.tk, 1 +chaip.org, 1 +chaisystems.net, 1 +chaitanyapandit.com, 1 +chaitradings.com.my, 1 +chaizhikang.com, 1 +chalanbiltv.net, 1 +chalet-maubuisson.tk, 1 +chaletdemontagne.org, 1 +chaletmanager.com, 1 +chaletpierrot.ch, 0 +chaleur.com, 1 +challengerinvestors.tk, 1 +challenges.gov, 1 +challengeskins.com, 1 +challstrom.com, 1 +chamartin.tk, 1 +chamath.co.uk, 1 +chamath.lk, 1 +chamathj.com, 1 +chamber.sa, 1 +chamberlainpropertygroup.ca, 1 +chambermeansbusiness.com, 1 +chambion.ch, 0 +chameleon-ents.co.uk, 1 +chameth.com, 0 +chamicro.com, 1 +chamonixcamera.cn, 1 +champagneandcoconuts.com, 1 +champdogs.co.uk, 1 +champdogs.com, 1 +championbet.ug, 1 +championcastles.ie, 1 +championnat-romand-cuisiniers-amateurs.ch, 1 +champions.co, 1 +championsofpowerfulliving.com, 1 +championsofregnum.com, 1 +championweb.co.nz, 0 +championweb.com, 0 +championweb.com.au, 0 +championweb.com.sg, 0 +championweb.nz, 0 +championweb.sg, 0 +champonthis.de, 1 +chamsochoa.com, 1 +chanakyanewz.com, 1 +chancekorte.com, 1 +chancekorte.org, 1 +chanddriving.co.uk, 1 +chanderson.com.au, 1 +chandr1000.ga, 1 +chandramani.tk, 1 +chang-feng.info, 0 +changan.com.co, 1 +change-coaching-gmbh.ch, 0 +changeanalytics.us, 1 +changemywifipassword.com, 1 +changes.jp, 1 +changesfor.life, 1 +changethislater.com, 1 +changinglivestoday.org, 1 +chanissue.com, 0 +channel-7.net, 1 +channelist.tk, 1 +channelizer.tv, 1 +channellife.asia, 1 +channellife.co.nz, 1 +channellife.com.au, 1 +channeloutfitters.com, 1 +channelsurf.tv, 0 +channingmotorsport.tk, 1 +chantage.tk, 1 +chantalguggenbuhl.ch, 0 +chantuong.org, 1 +chanz.com, 1 +chaos-darmstadt.de, 1 +chaos.run, 1 +chaos.stream, 1 +chaoschemnitz.de, 1 +chaoscommunication.camp, 1 +chaoscycle.tk, 1 +chaosdorf.de, 1 +chaosfield.at, 1 +chaoswars.ddns.net, 1 +chaoswebs.net, 1 +chaotichive.com, 1 +chaoticlab.io, 1 +chaoticonline.tk, 1 +chaouby.com, 0 +chaoxi.co, 1 +chaoxi.link, 1 +chapek9.com, 1 +chapelaria.tf, 1 +chapelfordbouncers.co.uk, 1 +chapelhousevet.co.uk, 1 +chapelle.co.uk, 1 +chapiteauxduleman.fr, 1 +chapmanstreeservice.com, 1 +chapstick.life, 1 +chaqueteros.tk, 1 +charbonnel.eu, 1 +charcoal-se.org, 1 +charcoalvenice.com, 1 +charge.co, 0 +chargifi.com, 1 +chargify.com, 1 +charisma.ai, 1 +charitocracy.org, 1 +charitylog.co.uk, 1 +charizmatec.com, 1 +charl.eu, 1 +charleliphile.tk, 1 +charlenevondell.com, 1 +charlenew.xyz, 1 +charles-brian.com, 1 +charles-darwin.com, 1 +charlesassaf.com, 1 +charlesbordet.com, 1 +charlesbwise.com, 1 +charlescwcooke.com, 1 +charlesdickens.tk, 1 +charlesdouglastec.com, 1 +charlespitonltd.com, 1 +charlesrogers.co.uk, 1 +charlestonfacialplastic.com, 1 +charley.tk, 1 +charlie-liveshow.com, 1 +charlie.im, 1 +charlie4change.com, 1 +charliedillon.com, 1 +charliegarrod.com, 1 +charliehr.com, 1 +charlierogers.co.uk, 1 +charlierogers.com, 1 +charliez0.cf, 1 +charliez0.ga, 1 +charliez0.gq, 1 +charliez0.js.org, 1 +charliez0.ml, 1 +charliez0.tk, 1 +charlotte-touati.ch, 1 +charlottecountyva.gov, 1 +charlotteomnes.com, 1 +charlottesvillegolfcommunities.com, 1 +charlottesvillehorsefarms.com, 1 +charlotteswimmingpoolbuilder.com, 1 +charlyclearsky.de, 1 +charlylou.de, 1 +charmander.me, 1 +charmanterelefant.at, 1 +charmcitytech.com, 1 +charmin.com, 1 +charmingsaul.com, 1 +charnego.tk, 1 +charolopezatelier.com, 1 +charon.tk, 1 +charonsecurity.com, 1 +charqawi.tk, 1 +charr.xyz, 1 +chars.ga, 0 +charset.org, 1 +charta-digitale-vernetzung.de, 1 +chartbox.tk, 1 +charteroak.org, 1 +chartkick.com, 1 +chartsy.de, 1 +charuni.ru, 1 +charuru.moe, 1 +chasafilli.ch, 1 +chascrazycreations.com, 1 +chaseandzoey.de, 1 +chasetrails.co.uk, 1 +chasing-coins.com, 1 +chasoslov.tk, 1 +chastitybelts.tk, 1 +chat-cam.tk, 1 +chat-house-adell.com, 1 +chat-porc.eu, 1 +chat.cz, 1 +chat2.cf, 1 +chat36.ga, 1 +chat4me.tk, 1 +chataberan.cz, 1 +chatbelgie.eu, 1 +chatbot.one, 1 +chatbotclic.com, 1 +chatbotclick.com, 1 +chatbots.email, 1 +chatbots.systems, 1 +chatdoguaxinim.tk, 1 +chateau-belvoir.com, 1 +chateau-de-lisle.fr, 1 +chateauderoncourt.fr, 1 +chateaudestrainchamps.com, 0 +chateaudevaugrigneuse.com, 1 +chateroids.com, 1 +chatforskning.no, 1 +chatgrape.com, 1 +chathamil.gov, 1 +chathund.de, 1 +chathurya.lk, 1 +chatline.cf, 1 +chatmaus.ml, 1 +chatnederland.eu, 1 +chatons.org, 1 +chatopia.tk, 1 +chatovod.tk, 1 +chatpoint.tk, 1 +chatroomfans.tk, 1 +chatsupport.co, 1 +chatswoodprestige.com.au, 1 +chatsworthelectrical.com, 1 +chattanoogaface.com, 1 +chattergallery.com, 1 +chattingorcheating.com, 1 +chatu.io, 1 +chatu.me, 1 +chatucomputers.com, 1 +chatup.cf, 1 +chaturbate.com, 1 +chaturbate.global, 1 +chaturbates.org, 1 +chatvizor.tk, 1 +chatweb.online, 1 +chatx.xyz, 1 +chatxp.com, 1 +chatzimanolis.com, 1 +chatzimanolis.gr, 1 +chauffage-budget.fr, 1 +chaurocks.com, 1 +chaussenot.net, 1 +chaussurerunning.fr, 1 +chaverde.org, 1 +chazalet.fr, 0 +chazay.net, 0 +chbs.me, 1 +chcemradost.sk, 1 +chch.it, 1 +chcheaptech.nz, 1 +chcoc.gov, 1 +chcsct.com, 1 +chcuscojungle.com, 1 +chdg.gq, 1 +chdg.tk, 1 +chdgaming.xyz, 1 +cheap-airtickets.ru, 1 +cheap-colleges.com, 1 +cheap-life-insurance-quote.com, 1 +cheap-mattresses.co.uk, 1 +cheapacyclovir.ml, 1 +cheapalarmparts.com.au, 0 +cheapautoinsuranceblog.com, 1 +cheapessay.net, 1 +cheapestgamecards.co.uk, 1 +cheapestgamecards.com, 1 +cheapfarestouk.com, 1 +cheapfarestousa.com, 1 +cheapgeekts.com, 0 +cheapgoa.com, 1 +cheapiesystems.com, 1 +cheaplasix.tk, 1 +cheapmarina.com, 1 +cheapnolvadex.ml, 1 +cheapsmall.tk, 1 +cheapsslsecurity.com, 1 +cheapsslsecurity.com.au, 1 +cheapsslsecurity.com.ph, 1 +cheaptadalafil.tk, 1 +cheapticket.in, 1 +cheapvaltrex.ml, 1 +cheapwritinghelp.com, 1 +cheapwritingservice.com, 1 +cheat-files.ml, 1 +cheatengine.pro, 1 +cheaterbios.ga, 1 +cheatmasters.tk, 1 +cheatsupreme.com, 1 +cheazey.co, 1 +cheazey.net, 1 +cheazey.org, 1 +chebotarevkk.tk, 1 +chebwebb.com, 1 +checalaweb.com, 1 +chechencity.tk, 1 +check.torproject.org, 0 +checkandreportlive.com, 1 +checkblau.de, 1 +checkbot.ml, 1 +checkchina.org, 1 +checkecert.nl, 1 +checkercab.tk, 1 +checkjehuis.be, 1 +checkjehuis.gent, 1 +checklistuj.cz, 1 +checkmatewebsolutions.com, 1 +checkmedia.org, 1 +checkmin.cf, 1 +checkmyessay.com, 1 +checkmyhttps.net, 1 +checkmypsoriasis.com, 1 +checkout.google.com, 1 +checkpoint-tshirt.com, 1 +checkra.in, 1 +checkras.tk, 1 +checkrente.nl, 1 +checkrz.com, 1 +checkspf.net, 1 +checktype.com, 1 +checkui.com, 1 +checkyourmath.com, 1 +checkyourprivilege.org, 1 +checkyourreps.org, 1 +checookies.com, 1 +checos.co.uk, 1 +cheddarpayments.com, 1 +cheekboss.com, 1 +cheekycharliessoftplay.co.uk, 1 +cheela.org, 1 +cheem.co.uk, 1 +cheeseemergency.co.uk, 1 +cheesefusion.com, 1 +cheeseginie.com, 1 +cheesypicsbooths.co.uk, 1 +cheetahwerx.com, 1 +cheez.systems, 1 +cheezflix.uk, 1 +chefcuisto.com, 1 +chefkoch.de, 1 +chefpablito.tk, 1 +chehalemgroup.com, 1 +cheholchik.tk, 1 +cheibegaudi.ch, 1 +cheiloplasty.tk, 1 +chekhov.gq, 1 +chel.ga, 1 +cheladmin.ru, 1 +chelema.xyz, 1 +chellame.fr, 1 +chelmsz.ml, 1 +chelpogoda.tk, 1 +chelseafs.co.uk, 1 +cheltenhambouncycastles.co.uk, 1 +cheltik.ru, 1 +chelyaba.tk, 1 +chema.ga, 1 +chemco.mu, 1 +chemgenes.com, 1 +chemical-shark.de, 1 +chemicalcrux.org, 1 +chemicalguys-ruhrpott.de, 1 +chemicalpharm.com, 1 +chemicalromance.tk, 1 +chemie-schule.de, 1 +chemiphys.com, 0 +chemistry-schools.com, 1 +chemolak.pl, 1 +chenapartment.com, 1 +cheneypartners.com, 1 +chenfengmedical.com, 1 +cheng.ink, 1 +cheng.pet, 1 +chengarda.com, 1 +chengfayun.com, 1 +chenghao360.top, 1 +chengl.com, 1 +chengta-money.com.tw, 1 +chengxindong.com, 1 +chengyutrading.com, 1 +chenky.com, 1 +chenna.me, 1 +chennien.com, 1 +chenpei.org, 1 +chentianyi.cn, 1 +chenui.design, 1 +chenx221.ml, 1 +chenx221.xyz, 1 +chenx2210.xyz, 1 +chenzhipeng.com.cn, 1 +cheque-transitionactive.fr, 1 +cheraghestan.com, 1 +cherevoiture.com, 1 +cherhenri.com, 1 +cherie-belle.com, 1 +cherkes.tk, 1 +cherkess.tk, 1 +chernikova.tk, 1 +chernogoriya.tk, 1 +chernyak.id.au, 1 +cherokee.net.br, 1 +cherrett.digital, 0 +cherry-green.ch, 1 +cherry-handmade.ml, 1 +cherryband.space, 1 +cherrybread.net, 1 +cherryonit.com, 0 +cherrywoodtech.com, 1 +chertseybouncycastles.co.uk, 1 +cherylbelber.com, 1 +cherysunzhang.com, 1 +chesapeakebank.com, 1 +chesapeakebaychristmas.com, 1 +chess.com, 1 +chessboardao.com, 1 +chesskid.com, 1 +chesspoint.ch, 1 +chesstempo.com, 1 +chessveterinary.co.uk, 1 +chesswiki.org, 1 +chestercountypediatrics.com, 1 +chestercountyroboticsurgery.com, 1 +chesterfieldplaceapartmentsstl.com, 1 +chesterman.tk, 1 +chestnut.cf, 1 +chetanrana.me, 1 +cheto.io, 1 +chetori.tk, 1 +chetwood.se, 1 +chevymotor-occasions.be, 0 +chewey.de, 1 +chewey.org, 1 +chewingucand.com, 1 +cheyennedentalgroup.com, 1 +cheyennelohnen.com, 1 +chez-janine.de, 1 +chez-oim.org, 1 +chezbernard.tk, 1 +chfr.search.yahoo.com, 0 +chhlin.com, 1 +chhory.com, 1 +chhy.at, 1 +chiakhoakhoinghiep.vn, 1 +chiamami.online, 1 +chiamatehot.com, 1 +chiangmaimontessori.com, 1 +chianti2002.jp, 1 +chiapasfutbol.com, 1 +chiara.ir, 1 +chiaraiuola.com, 0 +chiaramail.com, 0 +chiaseeds24.com, 1 +chiasepremium.com, 1 +chiavistello.it, 1 +chibiapp.ml, 1 +chibiotaku.com, 1 +chiboard.co, 1 +chiboost.net, 1 +chibr.eu, 1 +chic-leather.com, 1 +chicago-mold.com, 1 +chicagoagent.com, 1 +chicagobasementblog.com, 1 +chicagobreastaugdrs.com, 1 +chicagoemergencyclosings.com, 1 +chicagofinancesupperclub.com, 1 +chicagoillinois.gq, 1 +chicagolug.org, 0 +chicagostudentactivists.org, 1 +chicaman.tk, 1 +chicback.com, 1 +chicinttim.gq, 1 +chicjrajeevalochana.com, 1 +chick-goo-ewe-farm.com, 1 +chickencoop.ml, 1 +chickteam.tk, 1 +chicofc.tk, 1 +chicolawfirm.com, 1 +chicospanico.tk, 1 +chicourologist.com, 1 +chicurrichi.com, 1 +chielonline.tk, 1 +chiemgauflirt.de, 1 +chif16.at, 1 +chifumi.net, 1 +chijb.cc, 1 +chika.kr, 0 +chikan-beacon.net, 1 +chikenweb.jp, 1 +chiki.tk, 1 +chikory.com, 1 +chilbert.co, 1 +child-theater-bs.co.il, 1 +childcare.gov, 1 +childcaremanagementcompany.ga, 1 +childcaresolutionscny.org, 1 +childchaos.cf, 1 +childchaos.ga, 1 +childchaos.ml, 1 +childcounseling.org, 1 +childcustodylegalaid.org, 1 +childish.wtf, 1 +childno.de, 1 +children-toys.tk, 1 +childrenandmedia.org.au, 1 +childrenfirstalways.org, 1 +childrens-room.com, 1 +childrenschoicepearland.com, 1 +childrensentertainmentleicester.co.uk, 1 +childrensfurniture.co.uk, 1 +childrensrecipes.tk, 1 +childstats.gov, 1 +childswear.tk, 1 +childvisitationassistance.org, 1 +childwelfare.gov, 1 +chiletrenes.tk, 1 +chili.ml, 1 +chilihosting.eu, 1 +chilikin.pro, 1 +chilimath.com, 1 +chilimathwords.com, 1 +chilio.net, 1 +chilipepperhomes.com, 1 +chilipy.ga, 1 +chill-house.ga, 1 +chillebever.nl, 1 +chillipadi.tk, 1 +chilliwackchurchofgod.com, 1 +chiloesinpuente.tk, 1 +chilternfarming.com, 1 +chima.net, 1 +chima.us, 1 +chimcanhcut.tk, 1 +chime.com, 1 +chimebank.com, 1 +chimeratool.com, 1 +chimerity.com, 1 +chimm.cc, 1 +chimpanzee.cf, 1 +chimpanzee.net, 1 +chimpmatic.com, 1 +china-line.org, 1 +china-online-news.tk, 1 +chinablows.com, 1 +chinacdn.org, 1 +chinafree.online, 1 +chinafree.site, 1 +chinahealthcareblog.cf, 1 +chinahighlights.ru, 1 +chinaicpower.org, 0 +chinalosers.com, 1 +chinamextrading.com, 1 +chinasa.net, 1 +chinaspaceflight.com, 1 +chinastory.tk, 1 +chinasucksass.com, 1 +chinawatchinstitute.org, 1 +chinawhale.com, 1 +chinchillas.tk, 1 +chinees.restaurant, 1 +chinefrancophonie.fr, 1 +chinesedishes.tk, 1 +chinesemedicine.be, 1 +chinesepen.org, 1 +chinesephones.tk, 1 +chineserecipes.xyz, 1 +chinfolk.tk, 1 +ching.tv, 1 +chinookwebdesign.ca, 1 +chint.ai, 1 +chinwag.im, 1 +chip.pl, 1 +chipcore.com, 0 +chipdig.com, 1 +chipmixer.com, 1 +chipollinko.com.ua, 1 +chippy.ch, 0 +chips-scheduler.de, 1 +chipset.no, 1 +chiralsoftware.com, 1 +chirkunov.tk, 1 +chiro-merksplas.tk, 1 +chiro-neuchatel.ch, 0 +chiroherne.tk, 1 +chirojap.tk, 1 +chirolokalenfonteintjekoersel.be, 1 +chiromeisjes-boxberg.tk, 1 +chiron.care, 0 +chiropractic.gr, 1 +chiropracticwpb.com, 1 +chiropraktik-riemann.de, 1 +chiropraktik-wildner.de, 1 +chiropraticien-neuchatel.ch, 0 +chiropratique-neuchatel.ch, 0 +chirosphere.ch, 0 +chirr.space, 1 +chiru.no, 1 +chirurgoplastico.roma.it, 1 +chisago-isantidfl.com, 1 +chiselgems.com, 1 +chispita.tk, 1 +chistesdesebas.tk, 1 +chit.search.yahoo.com, 0 +chita.cf, 1 +chita.tk, 1 +chitaem.tk, 1 +chitashop.ml, 1 +chitinfo.tk, 1 +chitlar.ml, 1 +chittagongtextile.tk, 1 +chizouworld.tk, 1 +chjeco.com, 1 +chk-ccs.com, 1 +chkserv.com, 0 +chksite.com, 1 +chl.la, 1 +chliine.ch, 1 +chlo-products.biz, 1 +chlo-products.net, 1 +chloeallison.co.uk, 1 +chloehorler.com, 1 +chloes.gr, 1 +chloescastles.co.uk, 1 +chlth.com, 1 +chmc.ml, 1 +chmielarz.it, 1 +chmsoft.com.ua, 1 +chmsoft.ru, 1 +chmurakotori.ml, 1 +chnlib.com, 1 +choc-o-lush.co.uk, 1 +chocamekong.com, 1 +chocgu.com, 1 +chocoband.cf, 1 +chocodecor.com.br, 1 +chocolah.com.au, 0 +chocolat-suisse.ch, 0 +chocolat.work, 1 +chocolatebelga.com.br, 1 +chocolatesandhealth.com, 1 +chocolateslim.gq, 1 +chocolatesonline.com, 1 +chocolatier-tristan.ch, 0 +chocolatos.tk, 1 +chocolytech.info, 1 +chocope-peru.tk, 1 +chocoweb.net, 1 +chodaczek.pl, 1 +choe.fi, 1 +choesfirm.tk, 1 +chofan.tk, 1 +choiceautoloan.com, 1 +choiceuniontown.org, 1 +choigamevui.net, 1 +chokladfantasi.net, 1 +cholleria.es, 1 +chollima.pro, 1 +chollospain.cf, 1 +chomp.life, 1 +chonghe.org, 1 +chongming.tk, 1 +chongthamsika.tk, 1 +choochooworld.com, 1 +chook.as, 1 +choootto.net, 1 +choosemypc.net, 1 +chooseyourdesinty.tk, 1 +chopchat.com, 1 +chopperdesign.com, 1 +chopperforums.com, 1 +chopradionet.tk, 1 +chordify.net, 1 +chordmag.com, 1 +chordu.com, 1 +chorkley.co.uk, 1 +chorkley.com, 1 +chorkley.me, 1 +chorkley.uk, 1 +chornobyl.tk, 1 +chorpinkpoemps.de, 1 +chosenos.tk, 1 +chosenplaintext.org, 1 +choservices.com, 1 +chou-chinois.com, 1 +chourishi-shigoto.com, 1 +chovancova.sk, 1 +chowchowugo.com, 1 +chownie.com, 1 +chowtime.chat, 1 +choylifut.tk, 1 +choyri.com, 1 +chpwmedicare.org, 1 +chr0me.sh, 1 +chrawrizard.org, 1 +chrc-ccdp.gc.ca, 1 +chris-edwards.net, 1 +chris-siedler.at, 1 +chris.land, 1 +chrisahrweileryoga.com, 1 +chrisaitch.com, 1 +chrisbrockdiving.com, 1 +chrisbryant.me.uk, 1 +chrisburnell.com, 1 +chriscarey.com, 1 +chriscutts.uk, 1 +chrisdecairos.ca, 1 +chrisebert.net, 1 +chriseldon.com, 1 +chrisfinazzo.com, 0 +chrisgieger.com, 1 +chrisirwin.ca, 1 +chrisjean.com, 1 +chrislane.com, 1 +chrisluen.com, 1 +chrismarker.org, 1 +chrismax89.com, 1 +chrismcclendon.com, 1 +chrismckee.co.uk, 1 +chrismorgan.info, 1 +chrismurrayfilm.com, 1 +chrisnekarda.com, 1 +chrispaul.ml, 1 +chrisplankhomes.com, 1 +chrispontius.tk, 1 +chrisseoguy.com, 1 +chrisshort.net, 0 +chrissmiley.co.uk, 0 +chrisspencercreative.com, 1 +chrisspencermusic.com, 1 +chrissx.de, 1 +chrissx.ga, 1 +chrissytechaira.tk, 1 +christ.cm, 1 +christadelphians.eu, 1 +christchurchbouncycastles.co.uk, 1 +christcostum.tk, 1 +christec.net, 1 +christengroei.tk, 1 +christensenplace.us, 1 +christerwaren.fi, 1 +christiaanconover.com, 1 +christiamguerra.com, 1 +christian-fischer.pictures, 1 +christian-folini.ch, 1 +christian-gredig.de, 1 +christian-host.com, 1 +christian-liebel.com, 1 +christian-oette.de, 1 +christian-stadelmann.de, 1 +christianadventurecamps.org, 1 +christianblog.ml, 1 +christianbro.gq, 1 +christianbsl.com, 1 +christiancoleman.info, 1 +christianconcepts.gq, 1 +christiandiscourse.net, 1 +christianfaq.org, 1 +christianforums.com, 1 +christiangaro.com, 1 +christiangehring.org, 1 +christianhamacher.de, 1 +christianhaugen.tk, 1 +christianhoffmann.info, 0 +christianitas.ga, 1 +christianitas.gq, 1 +christianitas.tk, 1 +christianjens.com, 1 +christianleedunn.tk, 1 +christianliebel.com, 1 +christianlis.org.uk, 1 +christianlis.uk, 1 +christianmoore.me, 1 +christianmorales.tk, 1 +christianoliff.com, 1 +christianr.me, 1 +christianrasch.de, 1 +christians.dating, 1 +christiansayswords.com, 1 +christiansrit.tk, 1 +christianwitts.tech, 1 +christianwong.blog, 1 +christianyleny.com, 1 +christiehawkes.com, 1 +christinaaguilera.com.br, 1 +christinaclairecollins.com, 1 +christinacrawford.cf, 1 +christineandcie.fr, 1 +christineblachford.com, 1 +christinecloma.com, 1 +christinehameline.com, 1 +christineprayon.de, 1 +christmasinelmhurst.org, 1 +christmaspages.tk, 1 +christmaspartyhire.co.uk, 1 +christmasrecipe.tk, 1 +christo.ga, 1 +christoph-gadow.de, 1 +christoph.media, 1 +christophbartschat.com, 1 +christophe-dubois.tk, 1 +christophebarbezat.ch, 1 +christopher-simon.de, 1 +christopher-wright.com, 1 +christopher-zentgraf.de, 1 +christopher.sh, 0 +christopherburg.com, 1 +christopherd.me, 1 +christophergowerjohnson.com, 1 +christopherkennelly.com, 1 +christopherpfister.de, 1 +christopherpritchard.co.uk, 1 +christopherstocks.online, 1 +christophertruncer.com, 1 +christopherzoukis.com, 1 +christophfink.com, 1 +christophkreileder.com, 1 +christophsackl.de, 1 +christthekingparish.net, 1 +christtheredeemer.us, 1 +christwaycounseling.com, 1 +christyhui.com, 1 +chrisupjohn.xyz, 1 +chrisvannooten.tk, 1 +chriswald.com, 1 +chriswarbo.tk, 1 +chriswarrick.com, 1 +chriswells.io, 1 +chriswiggin.cf, 1 +chrisx.xyz, 1 +chrixonline.tk, 1 +chromaitaly.com, 1 +chromarea.fr, 1 +chromaryu.net, 0 +chromcraft-revington.com, 1 +chrome, 1 +chrome-devtools-frontend.appspot.com, 1 +chrome.com, 1 +chrome.google.com, 1 +chromebookchart.com, 1 +chromebookcompare.com, 1 +chromebooksforwork.com, 1 +chromereporting-pa.googleapis.com, 1 +chromiumbugs.appspot.com, 1 +chromiumcodereview.appspot.com, 1 +chromopho.be, 1 +chronic101.xyz, 1 +chronicals.de, 1 +chronicles.tk, 1 +chroniclesofgeorge.com, 1 +chronikdanceclub.com, 1 +chronlaw.com, 1 +chronoc.de, 1 +chronocarpe.com, 1 +chronograph.pe, 1 +chronosgroup.eu, 1 +chronoshop.cz, 1 +chronotech.fr, 1 +chrpaul.de, 0 +chrstn.eu, 1 +chrt-tcdp.gc.ca, 1 +chrxw.com, 1 +chrysanthos.net, 1 +chrystajewelry.com, 1 +chrystofer.com, 1 +chrystus.pl, 1 +chsamuel.net, 1 +chsh.moe, 0 +chshealthcare.co.uk, 1 +chshouyu.com, 1 +chsterz.de, 1 +chstrategies.com.au, 1 +chto-posmotretj.ru, 1 +chtodelat.ga, 1 +chtsi.uk, 1 +chtyvo.tk, 1 +chubr.cf, 1 +chuchote-moi.fr, 1 +chuckval.tk, 1 +chudnov.tk, 1 +chukcha.ru, 1 +chukotka.ml, 1 +chukwunyere-chambers.org, 1 +chun.pro, 1 +chun.si, 0 +chundelac.com, 1 +chunga.tk, 1 +chungsir.com.pa, 1 +chunk.science, 1 +chupadelfrasco.com, 1 +chupanhcotrang.com, 1 +chuppa.com.au, 1 +churakov.tk, 1 +churchaid.ml, 1 +churchforum.tk, 1 +churchill.co.za, 1 +churchillcountynv.gov, 1 +churchlinkpro.com, 1 +churchlw.tk, 1 +churchofchrist.tk, 1 +churchofpop.net, 1 +churchofsaintbenedict.com, 1 +churchofsaintrocco.org, 1 +churchofscb.org, 1 +churchplaza.com, 1 +churchssja.org, 1 +churchthemes.com, 1 +churchwebcanada.ca, 1 +churchwebsupport.com, 1 +churchwp.com, 1 +chus-plongee.fr, 1 +chuskocity.tk, 1 +chuvash-republic.tk, 1 +chuvash.tk, 1 +chuvashia.tk, 1 +chuvashiya.tk, 1 +chwilrank.pl, 1 +chytraauta.cz, 1 +chziyue.com, 1 +ci-fo.org, 1 +ci5.me, 1 +ciadesuporte.com.br, 1 +ciagutek.pl, 1 +cialde.it, 1 +cialis-trial.gq, 1 +cialisfreetrial.ga, 1 +cialisvtr.com, 1 +cialona.nl, 1 +cialowruchu.pl, 1 +ciancaiphotobooth.com, 1 +ciancode.com, 1 +cianmawhinney.me, 1 +cianmawhinney.xyz, 1 +ciaracode.com, 1 +ciaran.tk, 1 +ciat.no, 0 +cibdol.com, 1 +cibdol.nl, 1 +cibercactus.com, 1 +cibercat.tk, 1 +cibercheck.com, 1 +cibleclick.com, 1 +ciblogin.com, 1 +cibus.ba, 1 +cica.es, 1 +cicavkleci.cz, 1 +cicery.com, 1 +cichol.com, 1 +ciclimattio.com, 1 +ciclista.roma.it, 1 +ciclodekrebs.com, 1 +ciclodelcarbono.com, 1 +ciclohidrologico.com, 1 +cidadedossonhos.org, 1 +cidbot.com, 1 +cidcca.com, 1 +ciderclub.com, 1 +cidersus.com.ec, 1 +cidgomes.com.br, 1 +cidiart.vn, 1 +cidiframe.vn, 1 +cidikit.tk, 1 +cidones.tk, 1 +cie-theatre-montfaucon.ch, 0 +ciel.coffee, 1 +cielly.com, 1 +cielo-thefilm.com, 1 +cienciasempresariais.pt, 1 +cierreperimetral.com, 1 +cifapme.net, 1 +cifop-numerique.fr, 1 +ciftlikesintisi.com, 1 +cig-dem.com, 0 +cigar-cartel.com, 1 +cigarette-electronique.tk, 1 +cigarterminal.com, 0 +cigdelivery.com, 1 +ciginsurance.com, 1 +cign.nl, 1 +cigoteket.se, 1 +cihar.com, 1 +cihucm.com, 1 +ciicutini.ro, 1 +cikeblog.com, 0 +cilacapnews.ml, 1 +cile.tk, 1 +cilloc.be, 1 +cilt.tk, 1 +ciltskillnet.ie, 1 +cim.pe, 1 +cima-idf.fr, 1 +cimaflash.co, 0 +cimbalino.org, 1 +cimballa.com, 1 +cimfax.com, 1 +cimtools.net, 1 +cinafilm.com, 1 +cinay.pw, 1 +cinderellacloset.in, 1 +cindey.io, 1 +cindydudley.com, 1 +cine-music.de, 1 +cine.to, 1 +cinefilia.tk, 1 +cinefilzonen.se, 1 +cinefun.net, 1 +cinema-rulem.tk, 1 +cinemaclub.co, 1 +cinemadoma.tk, 1 +cinemaperto.tk, 1 +cinemarxism.com, 1 +cinemaschool.by, 1 +cinemasetfree.com, 1 +cinematherapy.org, 1 +cinematic.asia, 1 +cinematictouch.com, 1 +cinemaz.to, 1 +cinemotion.by, 1 +cinemysticism.com, 1 +cinenote.link, 1 +cineping.com, 1 +cineplex.my, 1 +cinesso.de, 1 +cineterror.tk, 1 +cineworld.co.in, 1 +cinexilio.tk, 1 +cinexmachina.com, 1 +cinicloud.com, 1 +cinicsystems.tk, 1 +ciniticket.com, 1 +cink.hu, 1 +cinkciarz.pl, 1 +cinnagar.tk, 1 +cinq-elements.com, 0 +cinq-elements.fr, 1 +cinq-elements.net, 1 +cinquecentoclubholland.tk, 1 +cinqueportsvets.co.uk, 1 +cinsects.de, 1 +cint.com, 1 +cintamanilingerie.co.uk, 1 +cintapersonalizada.es, 1 +cintaraso.es, 1 +cinteo.com, 1 +cio-ciso-interchange.org, 1 +cio-cisointerchange.org, 1 +cio.go.jp, 0 +cio.gov, 0 +ciordigital.com, 1 +cioscloud.com, 1 +cip.md, 1 +cipartyhire.co.uk, 1 +ciph.one, 1 +cipher.team, 1 +cipherboy.com, 1 +cipherli.st, 0 +ciphermail.com, 1 +ciphersuite.info, 1 +ciphrex.com, 1 +cipies.com, 1 +ciplerli.st, 1 +cippus.tk, 1 +cipri.com, 1 +cipri.net, 1 +cipri.nl, 1 +cipri.org, 1 +cipria.no, 1 +ciproantibiotic.gq, 1 +ciprofloxacin.cf, 1 +ciprofloxacin.ga, 1 +ciprogeneric.gq, 1 +cipy.com, 1 +cir.is, 1 +cira.email, 1 +cirasync.com, 1 +circady.com, 1 +circara.com, 1 +circle-people.com, 1 +circlebox.rocks, 1 +circlelytics.com, 1 +circleofhealthlongmont.com, 1 +circleofleastconfusion.com, 1 +circlepluscircle.me, 1 +circu.ml, 1 +circues.com, 1 +circuitcityelectricaladelaide.com.au, 1 +circular.tw, 1 +circulosocial77.com, 1 +circum.top, 1 +circumstances.ir, 1 +circus-maximus.de, 1 +circuses.tk, 1 +cirfi.com, 1 +ciris.info, 1 +cirocunato.tk, 1 +cirope.com, 1 +cirruslab.ch, 1 +cirruslabs.ch, 0 +cirugiasplasticas.com.mx, 1 +cirujanooral.com, 1 +cirurgicaexpress.com.br, 1 +cirurgicagervasio.com.br, 1 +cirurgicalucena.com.br, 1 +cirurgicavirtual.com.br, 1 +cirvapp.com, 1 +cisa.gov, 1 +ciscoasanetflow.com, 1 +ciscocyberthreatdefense.com, 1 +ciscodude.net, 1 +cisconetflowleader.com, 1 +cisconetflowpartners.com, 1 +cisconetflowreporting.com, 1 +cisconetflowsupport.com, 1 +cisin.com, 1 +cisincometax.ca, 1 +cisindia.tk, 1 +cisinlabs.com, 1 +cisinlive.com, 1 +cisoaid.com, 1 +cisofy.com, 1 +cispeo.org, 1 +ciss.ltd, 1 +cissa.org.au, 1 +cissofitness.com, 1 +cistenikoberculiberec.net, 1 +cistit.tk, 1 +cistitguru.ru, 0 +cisum-cycling.com, 1 +cisy.me, 1 +cisylik.gq, 1 +citace.com, 1 +citacepro.com, 1 +citadelpark.be, 1 +citae.ga, 1 +citafun.tk, 1 +citakon.cz, 1 +citalopram-20-mg.ml, 1 +citalopram20.ga, 1 +citalopramgeneric.ga, 1 +citalopramhbr.ga, 1 +citans.tk, 1 +citas-adultas.com, 1 +citationgurus.com, 1 +citations.tk, 1 +citazine.fr, 1 +citazioni.tk, 1 +citcuit.in, 1 +citfin.cz, 1 +cities.cl, 1 +cities.mx, 1 +citimarinestore.com, 1 +citizen-cam.de, 1 +citizen428.net, 1 +citizenkevin.com, 0 +citizensbankal.com, 1 +citizenscience.gov, 0 +citizenscience.org, 1 +citizensgbr.org, 1 +citizenslasvegas.com, 1 +citizensleague.org, 1 +citizing.org, 1 +citos.ga, 1 +citroner.blog, 1 +citruspi.com, 1 +citruspi.io, 1 +citrusui.me, 1 +citsc.de, 1 +city-adm.lviv.ua, 1 +city-forums.ml, 1 +city-glas.com, 1 +city-home.tk, 1 +city-online.tk, 1 +city-walks.info, 1 +cityacademyslc.org, 1 +citybeat.de, 1 +citybusexpress.com, 0 +citycalculator.ml, 1 +citycardgand.com, 1 +citycardgante.com, 1 +citycardgent.be, 1 +citycardgent.com, 1 +citycardghent.com, 1 +citycreek.studio, 1 +citycricket.tk, 1 +cityfacialplastics.com, 1 +cityfish.com, 1 +cityfloorsupply.com, 1 +cityhide.tk, 1 +citykohviteek.ee, 1 +citylift.com.ua, 1 +citylights.eu, 1 +citylocal.cf, 1 +citymoobel.ee, 1 +cityofarcolatx.gov, 1 +cityofcarsonca.gov, 1 +cityofeastpointemi.gov, 1 +cityofelynv.gov, 1 +cityofgigharborwa.gov, 1 +cityofguttenbergia.gov, 1 +cityofherculaneum.gov, 1 +cityoflakegeneva.gov, 1 +cityofmadera.gov, 1 +cityofmerced.gov, 1 +cityofmusic.be, 1 +cityofpinebluff-ar.gov, 1 +cityoftitans.com, 1 +cityoftitansmmo.com, 1 +cityofwadley-ga.gov, 1 +cityofwoodward-ok.gov, 1 +citypress.ga, 1 +citypro.tk, 1 +cityradiusmaps.com, 1 +citysportapp.com, 0 +citysquarenews.tk, 1 +citytaxiandtours.ga, 1 +citytel.ga, 1 +citytourgirls.com, 1 +cityuproject.com, 1 +cityview.tk, 1 +citywalkr.com, 1 +citywidealarms.com, 1 +citywisdom.tk, 1 +cityworksonline.com, 1 +ciubotaru.tk, 1 +ciuciucadou.ro, 1 +ciudadanosbo.com, 1 +ciudadrealtrabaja.com, 1 +ciulea.ro, 1 +ciurcasdan.eu, 1 +civey.com, 1 +civic-europe.eu, 1 +civicforum.pl, 1 +civics.us, 1 +civicunicorn.com, 1 +civicunicorn.us, 1 +civil-works-sri.com, 1 +civilbikes.com, 1 +civilcorner.com, 1 +civilg20.org, 1 +civilhost.tk, 1 +civillines.nl, 1 +civiltoday.com, 1 +civilvirus.tk, 1 +civmob.com, 1 +cj-espace-vert.fr, 1 +cj-jackson.com, 1 +cj26.club, 1 +cj8.de, 1 +cjbeckert.com, 1 +cjdby.net, 1 +cjdpenterprises.com, 1 +cjdpenterprises.com.au, 1 +cjean.fr, 1 +cjenni.ch, 1 +cjey.me, 1 +cjfinance.fr, 1 +cjhzp.net, 1 +cjimmobilier.com, 1 +cjpsrilanka.lk, 1 +cjr.host, 1 +cjr.is, 1 +cjs8866.cc, 1 +cjsounds.com, 1 +cjwagner.net, 1 +ck.cx, 1 +ck0.eu, 1 +ck1020.cc, 1 +ckcg.tk, 1 +ckdemo.herokuapp.com, 1 +ckenel.com, 1 +ckenell.com, 1 +ckenelley.com, 1 +ckenelly.com, 1 +ckenely.com, 1 +ckennel.com, 1 +ckenneley.com, 1 +ckennell.com, 1 +ckennelley.com, 1 +ckennelly.com, 1 +ckennely.com, 1 +ckgr.me, 1 +ckleemann.de, 1 +cklie.de, 1 +ckliemann.com, 1 +ckliemann.net, 1 +ckna.ca, 1 +ckostecki.de, 1 +ckp.ie, 1 +ckpl.io, 1 +ckrubble.co.za, 1 +cktennis.com, 1 +ckventura.sk, 1 +ckyalliancefinland.tk, 1 +cl-brands.com, 0 +cl-cloud.spdns.org, 1 +cl-wiki.spdns.org, 1 +cl.search.yahoo.com, 0 +cl0ud.space, 1 +claaruba.com, 1 +clacetandil.com.ar, 1 +clad.cf, 1 +claibornecountytn.gov, 1 +claim-justice.com, 1 +claimconnect.com, 1 +claimconnect.us, 1 +claimflights.at, 1 +claimflights.co.uk, 0 +claimflights.com, 0 +claimflights.de, 0 +claimflights.it, 0 +claimflights.pl, 0 +claimflights.ro, 0 +claimit.ml, 1 +claimnote.com, 1 +claimspharmacy.services, 1 +clairegold.com, 1 +clairelefort-architectes.com, 1 +clairescastles.co.uk, 1 +clairette-de-die-lantheaume.fr, 1 +clairevoyance.tk, 1 +claitec.com, 1 +clam.network, 1 +clamatohalloffame.com, 1 +clan-afa.tk, 1 +clan-destin.tk, 1 +clan-finaldestination.tk, 1 +clan-hosting.tk, 1 +clan-ogm.tk, 1 +clan-ready4war.tk, 1 +clan-wars.ml, 1 +clan-ww.com, 1 +clan-zone.dk, 1 +clanebouncycastles.com, 1 +clanlaw.tk, 1 +clanlegends.tk, 1 +clanrose.org.uk, 1 +clantemplates.tk, 1 +clanto.shop, 1 +clanwarz.com, 1 +clapbacks.com, 1 +clapping-rhymes.com, 1 +claptrap.tk, 1 +clara.de, 1 +claralabs.com, 0 +clarasegura.tk, 1 +clare-landmark.com, 1 +clare3dx.com, 1 +claremontyachtclub.org.au, 1 +claresderibota.tk, 1 +claretandbluearmy.tk, 1 +claretvillans.com, 1 +clarinet.ga, 1 +clarinexonline.gq, 1 +clarins-unlimited.fr, 1 +clarisights.com, 1 +clarisonicmiareview.tk, 1 +clariti-health.com, 1 +claritin.gq, 1 +claritin.ml, 1 +clarity-online.com, 1 +clarityskin.com, 1 +clarkaesthetics.com, 1 +clarkelectricalservices.com.au, 1 +clarkhowell.com, 1 +clarksburgma.gov, 1 +clarkwinkelmann.com, 1 +clasa-mea.tk, 1 +clase3.tk, 1 +clash-movies.de, 1 +clashersrepublic.com, 1 +clashoflights.ga, 1 +class-zone.tk, 1 +class.com.au, 1 +classdesignhome.com, 1 +classdojo.com, 1 +classic-battleship.ml, 1 +classic-diva.cf, 1 +classic-yacht-charters.com, 1 +classicalchaos.tk, 1 +classicalpilates.ca, 1 +classiccrew.tk, 1 +classiccrewhaiti.tk, 1 +classiccutstupelo.com, 1 +classicfg.com.au, 1 +classichorrornetwork.tk, 1 +classichost.gq, 1 +classicmagazine.ml, 1 +classicpattern.com, 1 +classics.io, 1 +classicstories.tk, 1 +classictheatrecumbria.co.uk, 1 +classicz.xyz, 1 +classificadostodaoferta.tk, 1 +classificar.com.br, 1 +classifiedspoint.tk, 1 +classpoint.cz, 1 +classroom.google.com, 1 +classroomconductor.com, 1 +classyhandmade.de, 1 +claude.me, 1 +claude.photo, 1 +claudeleveille.com, 0 +claudia-halfter.de, 1 +claudia-makeup.com, 1 +claudia-urio.com, 0 +claudiahalfter.de, 1 +claudiasnederlandsehangoordwergjes.tk, 1 +claudiney.eti.br, 1 +claudiney.id, 1 +claudiohdz.com, 1 +claumarservice.com, 1 +claus-bahr.de, 1 +clauseriksen.net, 1 +clausewitz-gesellschaft.de, 1 +clav1d.com, 1 +clawe.de, 1 +clawhammer.dk, 1 +clayandcottonkirkwood.com, 1 +clayelections.gov, 1 +claygregory.com, 1 +claypenblanks.com, 1 +clayprints.com, 1 +claytoncondon.com, 1 +claytonjunior.tk, 1 +clazzrooms.com, 1 +cldejessey.com, 1 +cldfile.com, 1 +cldinc.com, 1 +cldly.com, 1 +clean-mailbox.com, 1 +clean-water-and-sanitation.tk, 1 +cleanapproachnw.com, 1 +cleanbrowsing.org, 1 +cleanclearwater.co.uk, 1 +cleandetroit.org, 1 +cleaner.tk, 1 +cleanfiles.us, 1 +cleango.pl, 1 +cleangreen.tech, 1 +cleangroup.in.ua, 1 +cleanhouse2000.us, 1 +cleaningcarpet.ga, 1 +cleaningservicejulai.com, 1 +cleaningsquad.ca, 0 +cleankey.jp, 1 +cleanmysolarpanels.com, 1 +cleansewellness.com, 1 +cleanshield99.com, 1 +cleanvision.space, 0 +cleanway.dk, 1 +clear-concise.com, 1 +clear-it.ch, 1 +clearance365.co.uk, 1 +clearbooks.co.uk, 1 +clearbookscdn.uk, 1 +clearchatsandbox.com, 1 +clearcreekcountyco.gov, 1 +clearcreekcountydronepilot.com, 1 +clearer.cloud, 1 +cleargrowshine.com, 1 +clearhumor.tk, 1 +clearip.com, 1 +clearlakechildrenscenter.com, 1 +clearlinux.org, 1 +clearmaxx.ch, 1 +clearpay.co.uk, 1 +clearsafetalk.com, 1 +clearsense.com, 1 +clearspringinsurance.com, 1 +clearstep.health, 1 +clearview-creative.com, 1 +clearviewsecurity.com.au, 1 +clearviewwealthprojector.com.au, 1 +clearvoice.com, 1 +clearvoice.org, 1 +clearvoice1.com, 1 +clearwaterbidets.com, 1 +clearwatersexhealth.com, 1 +cleary.xyz, 1 +cleelum.gov, 1 +clegc-gckey.gc.ca, 1 +clemency.com, 1 +clemens-bartz.de, 1 +clemensbartz.de, 1 +clemenscompanies.com, 1 +clementfevrier.fr, 1 +clementsfamily.co, 1 +clemovementlaw.com, 1 +cleocinonline.gq, 1 +cleova.com, 1 +cles-asso.fr, 1 +cles.jp, 1 +cleveille.com, 1 +clevelandokla.com, 1 +clever-fit.com, 1 +cleverdarts.com, 1 +cleverdeal.tk, 1 +cleverinsert.com, 1 +clevermatch.com, 1 +cleveroad.com, 1 +clevertarget.ru, 1 +cleververmarkten.com, 1 +cleververmarkten.de, 1 +clevisto.com, 1 +clevvi.com.au, 1 +clevyr.ai, 1 +clevyr.biz, 1 +clevyr.careers, 1 +clevyr.co, 1 +clevyr.com, 1 +clevyr.info, 1 +clevyr.me, 1 +clevyr.mobi, 1 +clevyr.ninja, 1 +clevyr.org, 1 +clevyr.shop, 1 +clevyr.store, 1 +clevyr.us, 1 +clevyrapps.com, 1 +clevyrcares.com, 1 +clevyrcreative.com, 1 +clevyrgames.com, 1 +clevyrhosting.com, 1 +clevyrhub.com, 1 +clevyrnode.com, 1 +clevyrnodejs.com, 1 +clevyrstream.com, 1 +clevyrstreamjs.com, 1 +clevyrstudios.com, 1 +clevyrvr.com, 1 +cleysense.com, 0 +clgb.org, 1 +clic-et-site.com, 1 +clic-music.com, 1 +clica.net, 1 +clicandfioul.com, 1 +clicheshishalounge.co.uk, 1 +click-cat.tk, 1 +click-generator.com, 1 +click2order.co.uk, 1 +click4click.ga, 1 +clickalphaville.com.br, 1 +clickaplay.com, 1 +clickbasin.co.uk, 1 +clickclickfish.com, 1 +clickclickmalware.com, 1 +clickclickphish.com, 1 +clickclickvirus.com, 1 +clickclock.cc, 1 +clickcollect.boutique, 1 +clickenergy.com.au, 1 +clickforum.cf, 1 +clickheretobegin.tk, 1 +clickhouse.tech, 1 +clickinfo.tk, 1 +clickingmad.com, 1 +clickphobia.ga, 1 +clickpool-server.de, 1 +clickpress.tk, 1 +clickrising.com, 1 +clickthebucket.com, 1 +clicktolinkb.gq, 1 +clickzone.ga, 1 +clien.net, 1 +client.coach, 0 +clientboss.com, 1 +clientcms.co.uk, 1 +clientesal100.com, 1 +clientesendemanda.com, 1 +clientportal.com, 1 +cliffbreak.de, 1 +cliffburton.tk, 1 +clifflu.net, 1 +cliftonheritage.net, 1 +clik.ga, 1 +cliksource.com, 1 +climaencusco.com, 1 +climatecooperation.org, 1 +climatecrafters.com, 1 +climateinteractive.org, 1 +climatgate.tk, 1 +climaticequipment.tk, 1 +climatizzatore.it, 1 +climatizzatore.roma.it, 1 +climbing.tk, 1 +clinchcountyga.gov, 1 +clindamycin-150mg.ga, 1 +clindamycin-phosphate.ga, 1 +clindamycin.gq, 1 +clindamycinantibiotic.ga, 1 +clindamycinprice.tk, 1 +clindoeilmontagne.com, 0 +clingout.com, 1 +clinica.zapto.org, 1 +clinicaarques.es, 1 +clinicadeesteticacontagem.com.br, 1 +clinicadentalacacias.com, 1 +clinicadentalados.com, 1 +clinicadentalayomunoz.com, 1 +clinicadentalmunoz.es, 1 +clinicaeliana.com, 1 +clinicafollicles.com.br, 1 +clinicalrehabilitation.info, 1 +clinicalstats.ga, 1 +clinicaltrialpodcast.com, 1 +clinicaltrials.gov, 1 +clinicamiracueto.com, 1 +clinicarayanelacerda.com.br, 1 +clinicaschirmer.com, 1 +clinicasesteticas.com.br, 1 +clinicasmedicas.com.br, 1 +clinicminds.com, 1 +clinicortinascali.com, 1 +clinicos.cl, 1 +cliniko.com, 1 +clinique-ser.ca, 1 +cliniquecomplementaire.com, 1 +cliniquevethuy.be, 1 +clinlife.com, 1 +clintburnett.com, 1 +clinteam.dk, 1 +clintonbloodworth.com, 1 +clintonlibrary.gov, 1 +clintonoh.gov, 1 +clintonohfire.gov, 1 +clintraxglobal.com, 1 +clinux.co, 1 +clio-dev.com, 1 +clio.health, 1 +clip.cafe, 1 +clip.ovh, 1 +clipchamp.com, 1 +clipclip.com, 1 +clippings.com, 1 +clips.ga, 1 +cliqz.com, 1 +clive.io, 1 +clixa.com, 1 +clmbr.ch, 1 +clmde.de, 1 +clnc.to, 1 +clnlboard.co.uk, 1 +clnnet.ch, 1 +clnshrk.club, 0 +clo.me, 1 +cloaked.ch, 0 +clochix.net, 1 +clockcaster.com, 1 +clocklab.design, 1 +clockworksms.com, 1 +clodo.it, 1 +clodoteam.ga, 1 +clojurescript.ru, 1 +clomid100mg.ga, 1 +clomid50mg.cf, 1 +clomid50mg.ml, 1 +clomidformen.tk, 1 +clomidonline.tk, 1 +clomiphene.gq, 1 +cloneprint.com, 1 +cloneuniverse.com, 1 +clonidine-hydrochloride.ga, 1 +clonix.tk, 1 +clonyitaly.tk, 1 +cloppenburg-autmobil.com, 1 +cloppenburg-automobil.com, 1 +clorik.com, 1 +clorinda.tk, 1 +clorophilla.net, 1 +closecross.com, 1 +closeli.cn, 1 +closeli.com, 1 +closelinksecurity.co.uk, 1 +closelinksecurity.com, 1 +closernow.tk, 1 +closetemail.com, 1 +closets-cheap.tk, 1 +closingholding.com, 1 +clothes-for-school.tk, 1 +clothing-2010.tk, 1 +clothing-for-women.tk, 1 +clothingjeans.tk, 1 +cloud-hair.jp, 1 +cloud-screen.com, 1 +cloud.bugatti, 1 +cloud.fail, 1 +cloud.google.com, 1 +cloud.gov, 1 +cloud10.io, 1 +cloud255.com, 1 +cloud42.ch, 0 +cloud9bouncycastlehire.com, 1 +cloud9vets.co.uk, 1 +cloudads.ga, 1 +cloudalice.com, 1 +cloudalice.net, 1 +cloudandco.co, 1 +cloudapps.digital, 1 +cloudberlin.goip.de, 1 +cloudbleed.info, 1 +cloudboard.fr, 1 +cloudbolin.es, 1 +cloudbreaker.de, 1 +cloudbreaker.net, 1 +cloudcaprice.net, 1 +cloudcert.org, 1 +cloudchart.site, 1 +cloudcite.net, 1 +cloudcloudcloud.cloud, 1 +cloudclouds.com, 1 +cloudcrux.net, 1 +clouddark.xyz, 1 +clouddatanotes.com, 1 +clouddesk.co.uk, 1 +clouddog.com.br, 1 +clouddomain.tk, 1 +clouddownloader.net, 1 +cloudeezy.com, 1 +cloudeffects.com, 1 +cloudey.net, 1 +cloudfast.cf, 1 +cloudfiles.at, 1 +cloudflare-dns.com, 1 +cloudflare.com, 1 +cloudflareonazure.com, 1 +cloudfree.online, 1 +cloudfree.shop, 1 +cloudfree.site, 1 +cloudfree.top, 1 +cloudfudge.com, 1 +cloudhoreca.com, 1 +cloudia.org, 1 +cloudibee.com, 1 +cloudicles.design, 1 +cloudily.com, 1 +cloudimproved.com, 1 +cloudimprovedtest.com, 1 +cloudindex.io, 1 +cloudinfinit.com, 1 +cloudix.cf, 1 +cloudkeep.nl, 1 +cloudlessdreams.com, 0 +cloudlfront.net, 1 +cloudlight.biz, 1 +cloudmarathi.work, 1 +cloudmigrator365.com, 1 +cloudmoney.tk, 1 +cloudmyhome.buzz, 1 +cloudmyhome.club, 1 +cloudmyhome.com, 1 +cloudmyhome.monster, 1 +cloudmyhome.site, 1 +cloudmyhome.top, 1 +cloudmyhome.xyz, 1 +cloudninelandscapedesign.com, 1 +cloudninja.nu, 1 +cloudnote.cc, 1 +cloudns.net, 1 +cloudofertas.com.br, 1 +cloudomation.com, 1 +cloudoptimizedsmb.com, 1 +cloudoptimus.com, 1 +cloudpagesforwork.com, 1 +cloudpengu.in, 1 +cloudpipes.com, 1 +cloudplan.nl, 1 +cloudpole.de, 1 +cloudprints.ru, 1 +cloudpublic.pro, 1 +cloudrive.cf, 1 +cloudsavvyit.com, 1 +cloudse.co.uk, 1 +cloudsec.tk, 1 +cloudsecurityalliance-europe.org, 1 +cloudsecurityalliance.com, 1 +cloudsecurityalliance.net, 1 +cloudsecurityalliance.org, 1 +cloudsecurityalliancelabs.com, 1 +cloudsecuritycongress.net, 1 +cloudsecuritycongress.org, 1 +cloudservice.io, 1 +cloudsharp.io, 1 +cloudsign.jp, 1 +cloudsmart.tech, 1 +cloudspace-analytics.com, 1 +cloudspeedy.net, 1 +cloudspire.net, 1 +cloudstoragecompare.com, 1 +cloudstress.ga, 1 +cloudsys.dnsalias.net, 1 +cloudteam.de, 1 +cloudtocloud.ddns.net, 1 +cloudtocloud.tk, 1 +cloudtrics.de, 1 +cloudtropia.de, 1 +cloudtskr.com, 1 +cloudturing.chat, 1 +cloudturing.com, 1 +cloudup.com, 1 +cloudwarez.xyz, 1 +cloudwebservices.nl, 1 +cloudwellmarketing.com, 1 +cloudwise.nl, 1 +cloudwithlightning.net, 1 +cloudzentechnologies.com, 1 +cloutcloset.ga, 1 +clouz.de, 1 +clover-sendai.com, 1 +cloveros.ga, 1 +cloverpc.co.uk, 1 +clovertwo.com, 1 +clovisplumbingservices.com, 1 +clowd.haus, 1 +clowd.ovh, 1 +clownday.co.uk, 1 +clownindeklas.nl, 1 +clownish.co.il, 1 +cloxy.com, 1 +cloze.com, 1 +clr3.com, 1 +clsimage.com, 1 +clsoft.ch, 1 +clu-in.org, 1 +cluadmin.de, 1 +club-adulti.ro, 1 +club-climate.com, 1 +club-creole.com, 1 +club-dieta.ru, 1 +club-dresses.cf, 1 +club-duomo.com, 1 +club-eclipse.tk, 1 +club-jose.com, 1 +club-leondehuanuco.tk, 1 +club-oz.tk, 1 +club-premiere.com, 1 +club-reduc.com, 1 +club-slow.jp, 1 +club-yy.com, 1 +club.zj.cn, 1 +club103.ch, 0 +club10x.com, 1 +clubapk.com, 1 +clubatleticonacionalpotosi.tk, 1 +clubcorolla.cf, 1 +clubcorsavenezuela.com, 0 +clubdelzapato.com, 1 +clubdeportivocieza.tk, 1 +clubdeslecteurs.net, 1 +clubedegeografia.tk, 1 +clubedoberloque.com.br, 1 +clubedohardware.com.br, 1 +clubegolfpt.com, 1 +clubeighteen.tk, 1 +clubempleos.com, 1 +clubeohara.com, 1 +cluberiks.ga, 1 +cluberiks.gq, 1 +clubexpress.com, 1 +clubfailed.tk, 1 +clubfamily.de, 1 +clubfunday.ga, 1 +clubgalileo.com.ec, 1 +clubgenesis.tk, 1 +clubhousetownhomes.com, 0 +clubinhodobaby.com.br, 1 +clubmania.tk, 1 +clubmarina.store, 1 +clubmate.rocks, 1 +clubmini.jp, 1 +clubni.tk, 1 +clubnoetig-ink2g.de, 1 +cluboc.site, 1 +clubon.com.tw, 1 +clubpes.tk, 1 +clubsuccessjapan.com, 1 +clubtamarugal.tk, 1 +clubtecknocore.tk, 1 +clubtur.dk, 1 +clubvttlesloupsdemaixe.tk, 1 +cluj.apartments, 1 +cluj.help, 1 +clush.pw, 1 +cluster.biz.tr, 1 +cluster446.fr, 1 +clusteranalyse.net, 1 +clusterfuck.nz, 1 +clustermaze.net, 1 +clutch.ua, 1 +clvs7.com, 0 +clwrota.com, 1 +clycat.ru, 1 +cm-agueda.pt, 1 +cm-loures.pt, 1 +cm-pombal.pt, 1 +cm-portimao.pt, 1 +cm-terrasdebouro.pt, 0 +cm-valenca.pt, 0 +cm-vpaguiar.pt, 1 +cmacacias.ch, 1 +cmadeangelis.it, 1 +cmakeinstall.com, 1 +cmavs.com, 1 +cmc.pt, 1 +cmcc.network, 1 +cmcelectrical.com, 1 +cmcressy.ch, 1 +cmd2021acm.com, 1 +cmdline.org, 1 +cmdy5.com, 1 +cme-colleg.de, 1 +cmediaplayer.com, 0 +cmetana.tk, 1 +cmf.qc.ca, 1 +cmfaccounting.com, 0 +cmfcuro.com, 1 +cmftech.com, 1 +cmgacheatcontrol.com, 1 +cmillrehab.com, 1 +cmitao.com, 1 +cmlachapelle.ch, 1 +cmlancy.ch, 1 +cmlcpa.ca, 1 +cmlignon.ch, 1 +cmn-group.com, 1 +cmn-groupe.com, 1 +cmngroup.com, 1 +cmngroupe.com, 1 +cmplainpalais.ch, 1 +cmpsc.uk, 1 +cmrconstructions.com.au, 1 +cmrss.com, 1 +cms-mania.tk, 1 +cms-service24.de, 1 +cms-weble.jp, 1 +cms-world.co.jp, 1 +cmsdca.gov, 1 +cmserviscz.cz, 1 +cmskakuyasu.info, 1 +cmskeyholding.co.uk, 1 +cmskeyholding.com, 1 +cmskh.co.uk, 1 +cmsua.ca, 1 +cmtbc.ca, 1 +cmtportal.co.uk, 1 +cmusical.es, 1 +cmv.gr, 1 +cmweb.xyz, 1 +cmweller.com, 1 +cmylife.nl, 1 +cn.search.yahoo.com, 0 +cn8522.com, 1 +cna5.cc, 1 +cna5.net, 1 +cna5.org, 1 +cnabogota.tk, 1 +cnam-idf.fr, 1 +cnaprograms.online, 1 +cnatraining.network, 1 +cnbs.ch, 1 +cnc-lehrgang.de, 1 +cncado.net, 1 +cncfraises.fr, 1 +cncn3.cn, 1 +cncr.ga, 1 +cncrans.ch, 0 +cncs.gob.do, 1 +cncs.gov.pt, 1 +cnet-hosting.com, 1 +cnetw.xyz, 1 +cnfree.xyz, 1 +cni-certing.it, 1 +cni.net.id, 1 +cnitdog.com, 1 +cnlic.com, 1 +cnnc.jp, 1 +cnnet.in, 1 +cnpkg.org, 1 +cnpy.gdn, 1 +cnre.eu, 1 +cnss.io, 1 +cntraveller.com, 1 +cnvt.fr, 1 +co-driversphoto.se, 0 +co-founder-stuttgart.de, 1 +co-yutaka.com, 1 +co.fo, 1 +co.search.yahoo.com, 0 +co.td, 1 +co2eco.cn, 0 +co50.com, 1 +coa.one, 1 +coach-immobilier-neuf.fr, 1 +coach.org.uk, 0 +coachapp-ipass.herokuapp.com, 1 +coachbakery.com, 1 +coachezmoi.ch, 0 +coaching-harmonique.fr, 1 +coaching-impulse.ch, 0 +coaching-park.fr, 1 +coachingmillenium.com, 1 +coachjehond.nl, 1 +coachoutlettvb.net, 1 +coachrobcampos.com, 1 +coactive.com, 1 +coactuate.com, 1 +coag.gov.au, 1 +coalitionministries.org, 0 +coalmen.ga, 1 +coalpointcottage.com, 1 +coalvillebasketball.tk, 1 +coastalphysie.com, 1 +coastalpowder.com.au, 1 +coastalurgentcarebatonrouge.com, 1 +coastalurgentcarebossier.com, 1 +coastalurgentcaregonzales.com, 1 +coastalurgentcarehouma.com, 1 +coastalurgentcareruston.com, 1 +coastalurgentcarethibodaux.com, 1 +coastline.net.au, 1 +coastmedicalservice.com, 1 +coathangastrangla.com, 1 +coathangastrangler.com, 1 +coathangerstrangla.com, 1 +coathangerstrangler.com, 1 +coatl-industries.com, 1 +coats-and-jackets.tk, 1 +coatsandcocktails.org, 1 +cobaka.tk, 1 +cobalt.io, 1 +cobbcountygeorgia.ml, 1 +cobracastles.co.uk, 1 +cobranzasimg.com, 1 +coc.de, 1 +cocaine.ninja, 1 +cocalc.com, 1 +cocareonline.com, 1 +cocbaoan.com, 1 +coccinellaskitchen.com, 1 +coccinellaskitchen.de, 1 +coccinellaskitchen.it, 1 +coccolebenessere.it, 1 +cochem-zell-online.de, 1 +cochem-zell.de, 1 +cochesteledirigidos.net, 1 +cochin-brahma.tk, 1 +cocinasazahara.tk, 1 +cocinoyo.com, 1 +cockedey.in, 1 +cockerspanielamericano.com.br, 1 +cockerspanielingles.com.br, 1 +cockfile.com, 1 +cockmonkey.tk, 1 +cockpitcoach.eu, 1 +cocktails-club.com, 1 +cockybot.com, 1 +coco-cool.fr, 1 +coco-line.ch, 1 +cocoa-job.jp, 1 +cocodroid.com, 0 +cocokmobi.ga, 1 +cocolink.jp, 1 +cocomelody.co.za, 1 +cocomelody.com, 0 +cocomelody.de, 1 +cocomelody.jp, 1 +coconutguy.gq, 1 +coconutoil.ml, 1 +coconutoil24.com, 1 +cocoscastles.co.uk, 1 +cocounty.org, 1 +cocowine.com, 1 +cocquyt-usedcars.be, 0 +cocresa.tk, 1 +cocservice.top, 1 +cocukhekimim.com, 0 +cocukluaile.com, 1 +cocula.net, 1 +cocyou.ooo, 1 +cod-ggw.ml, 1 +cod88.cc, 1 +coda.moe, 1 +coda.today, 1 +coda.world, 1 +codabix.com, 1 +codabix.de, 1 +code-35.com, 0 +code-in-plate.tk, 1 +code-judge.tk, 1 +code-maze.com, 1 +code-poets.co.uk, 1 +code-vikings.de, 1 +code-well.com, 1 +code.facebook.com, 0 +code.fm, 1 +code.google.com, 1 +code.gov, 1 +code.taxi, 1 +code123.eu, 1 +code1llp.com, 1 +code4.hk, 1 +code4u.org, 1 +code66.ru, 1 +code67.com, 1 +code9000.be, 1 +codeandsupply.co, 1 +codeberg.org, 1 +codebrahma.com, 0 +codebrasileiro.tk, 1 +codebreakers.it, 1 +codebrew.com.au, 1 +codeclub.gq, 1 +codecommunity.io, 1 +codecrew.us, 1 +codectron.com, 1 +codedbyjim.nl, 1 +codedelarouteenligne.fr, 1 +codedesigns.ca, 1 +codedo.info, 1 +codedump.net, 1 +codedynasty.com, 1 +codeeclipse.com, 1 +codefaq.org, 1 +codefather.ml, 1 +codeferm.com, 1 +codefive.co.uk, 1 +codefordus.de, 1 +codefordus.nrw, 1 +codefoundry.it, 0 +codehangar.io, 1 +codehelper.ml, 1 +codeheroes.fr, 1 +codeidea.ga, 1 +codein.ca, 1 +codeine.co.uk, 1 +codeit.guru, 1 +codeit.us, 1 +codejots.com, 1 +codejunkie.de, 0 +codelei.fr, 1 +codeloop.pw, 1 +codemahrt.com, 1 +codemill.se, 1 +codemperium.com, 1 +codename-infinity.de, 1 +codename-infinity.org, 1 +codename24.tk, 1 +codenamelungo.tk, 1 +codenlife.kr, 1 +codenlife.xyz, 1 +codenode.io, 1 +codeofhonor.tech, 1 +codeofthenorth.com, 1 +codepoint.ml, 1 +codepoints.net, 0 +codepref.com, 1 +codera.co.uk, 1 +codercross.com, 1 +codercy.com, 1 +codered.sh, 1 +coderema.de, 1 +coderema.eu, 1 +coderescue.com, 1 +codereview.appspot.com, 1 +codereview.chromium.org, 1 +coderhangout.com, 1 +coderjesus.com, 1 +codersatlas.co, 1 +codersatlas.xyz, 1 +codes.pk, 1 +codesgroup.tk, 1 +codesplain.in, 1 +codesport.io, 1 +codesquad.com.au, 1 +codestats.net, 1 +codestep.io, 1 +codestudies.net, 1 +codetahiche.com, 1 +codetheweb.blog, 1 +codetheworld.com, 1 +codetipi.com, 1 +codetrack.se, 1 +codetripping.net, 1 +codeux.com, 1 +codeux.info, 1 +codeux.net, 1 +codevat.com, 1 +codeventure.de, 1 +codeversetech.com, 0 +codewild.de, 1 +codewithalisha.ga, 1 +codewiz.xyz, 1 +codexpert.my, 1 +codexpo.net, 1 +codeyellow.nl, 1 +codezenith.com, 1 +codific.com, 1 +codifique.tk, 1 +codigodelbonusbet365.com, 1 +codigojose.com, 1 +codigomillonario.com, 1 +coding-basic.tk, 1 +coding-minds.com, 1 +coding.lv, 1 +coding.net, 1 +codingblog.org, 1 +codingforspeed.com, 1 +codingfromhell.net, 1 +codinginfinity.me, 1 +codingrobots.com, 1 +codista.com, 1 +codo.digital, 1 +cododigital.co.uk, 1 +codoozer.com, 1 +cody.sh, 1 +codydostal.com, 1 +codyevanscomputer.com, 1 +codymoniz.com, 1 +codyqx4.com, 1 +coenraets.com, 1 +coens.me.uk, 1 +coentropic.com, 1 +coenzima.com, 1 +coeus.cloud, 1 +cofbev.com, 1 +coffee-mamenoki.jp, 1 +coffee-up.it, 1 +coffeeandcashew.com, 1 +coffeeandteabrothers.com, 1 +coffeebean.cf, 1 +coffeebeanstudios.tk, 1 +coffeeciel.com, 1 +coffeeciel.com.tr, 1 +coffeeinvestigator.com, 0 +coffeemoment.nl, 1 +coffeeonlinemagazine.com, 1 +coffeeshopsandman.nl, 1 +coffeestain.ltd, 1 +coffeetime.fun, 0 +coffeetom.de, 1 +coffeeweb.online, 1 +coffeist.com, 1 +cofidis-group.com, 1 +cofinco.nl, 1 +cofradiaqueimada.tk, 1 +cogeneration-energy.com, 1 +cogent.cc, 1 +coggin.church, 1 +cogknockers.com, 1 +cognicom-gaming.com, 1 +cognitip.com, 1 +cognitiveapplications.net, 1 +cognitivecomputingconsortium.com, 1 +cognitohq.com, 1 +cognosweb.net, 1 +cogsquad.house, 1 +cogsys.de, 1 +cogumelosmagicos.org, 1 +coiffeurschnittstelle.ch, 1 +coiffure-andrea.ch, 1 +coigach-assynt.org, 1 +coignieresentransition.fr, 1 +coimmvest.com, 1 +coin-exchange.cz, 1 +coin-group.com, 1 +coin-money.tk, 1 +coin-quest.net, 1 +coin.dance, 1 +coin.space, 1 +coinapult.com, 1 +coinbase.com, 1 +coinbit.trade, 0 +coincalc.tk, 1 +coinchat.im, 1 +coincircle.com, 1 +coinclickz.fun, 1 +coinclickz.xyz, 0 +coincoele.com.br, 1 +coincoin.eu.org, 1 +coincolors.co, 1 +coinf.it, 1 +coinflux.com, 1 +coinforce.com, 1 +coingate.com, 1 +coinjar-sandbox.com, 1 +coinloan.io, 1 +coinmaster-freespins.com, 0 +coinmewallet.com, 1 +coinmotion.com, 1 +coinnewspulse.com, 1 +coinpath.io, 1 +coinpit.io, 1 +coinroom.com, 1 +coins2001.ru, 1 +coinsconnect.co.uk, 1 +coinsmat.com, 1 +coinsuggest.com, 1 +cointosh.jp, 1 +coinvex.org, 1 +coinx.pro, 1 +coisasdemulher.org, 1 +cojam.ru, 1 +cojo.eu, 1 +cokebar.info, 1 +coker.com.au, 1 +cokestudiosongs.tk, 1 +cokomi.com, 1 +col-head.com, 1 +col.la, 1 +cola-host.tk, 1 +colaborativa.tv, 1 +colabug.com, 1 +coladv.com, 1 +colah.com.au, 1 +colapsys.net, 0 +colarelli.ch, 1 +colarose.tk, 1 +colbert.ml, 1 +colbonews.co.il, 1 +colchesterglobal.com, 1 +colchonesmoon.com, 1 +colchonminicuna.com, 0 +colcomm.com, 1 +colcompany.com, 1 +coldaddy.com, 1 +coldcardwallet.com, 1 +coldecan.edu.co, 1 +coldfff.com, 1 +coldfusion.co.jp, 1 +coldiario.com, 1 +coldjetconnect.com, 1 +coldlasers.org, 1 +coldren.org, 1 +coldspegll.gq, 1 +coldtomato.ga, 1 +coldwateraustin.com, 1 +colean.cc, 1 +colectivaradio.tk, 1 +coleg.gov, 1 +colegioalemanmcbo.com, 1 +colegiocuauhtzin.com.mx, 1 +colegiosanisidro.edu.pe, 1 +colegiosantaursula.com.br, 1 +colegiotalenti.com, 1 +colemak.com, 1 +colengo.com, 1 +coletrain.com, 1 +colf.online, 1 +colibris.xyz, 1 +colincogle.name, 1 +colinespinas.com, 1 +colinshark.de, 1 +colinsnaith.co.uk, 1 +colinstark.ca, 1 +colinyoung.scot, 1 +colisfrais.com, 0 +collab.ddnss.org, 1 +collabora-office.com, 1 +collabora.ca, 1 +collabora.co.kr, 1 +collabora.co.uk, 1 +collabora.com, 1 +collabora.kr, 1 +collabora.ninja, 1 +collabora.social, 1 +collabora.uk, 1 +collaboracloudsuite.com, 1 +collaboraoffice.co.uk, 1 +collaboraoffice.com, 1 +collaborativehealthpsychology.com, 1 +collabornation.net, 1 +collacott.org, 1 +collaction.hk, 1 +collada.org, 1 +collage.me, 1 +collagecrafting.com, 1 +collalloc.com, 1 +collapsed.de, 1 +collard.tk, 1 +collare.com.mx, 1 +collare.mx, 1 +collateral360.com, 1 +collectdocs.com, 1 +collectfood.com, 1 +collectiblebeans.com, 1 +collectif85.com, 1 +collectifitness.fr, 1 +collective-incubator.de, 1 +collectivedg.com, 1 +collectivesupply.com, 1 +collector.cf, 1 +collectorknives.net, 1 +collectorsystems.com, 1 +colleencornez.com, 1 +colleenfaulknernovels.com, 1 +collegegirlhd.com, 1 +collegemate.eu, 1 +collegemoccassin.com, 1 +collegenavigator.gov, 1 +collegephysicsanswers.com, 1 +collegeprospectsofcentralindiana.com, 1 +collegereligionandphilosophy.com, 1 +collegesecretary.cn, 1 +collegesecretary.com, 1 +collegesexvid.com, 1 +collegesrit.tk, 1 +collegestationhomes.com, 1 +collegetownstudios.tk, 1 +collegium-musicum-bocholt.de, 1 +collerosso.com, 1 +colley.tk, 1 +collinel-hossari.com, 1 +collinelhossari.com, 1 +collinklippel.com, 0 +collinmbarrett.com, 1 +collins.kg, 1 +collinselectricco.com, 1 +colloquio.tk, 1 +colloquy.mobi, 1 +colmena.biz, 1 +colo-tech.com, 1 +colocation-rennes.com, 1 +colocerin.com, 1 +colocolochile.tk, 1 +cololi.moe, 1 +colombiaemprendedora.org, 1 +colombiahoy.news, 1 +colombiajeans.co, 1 +colombian.dating, 1 +colombianas.webcam, 1 +colombiasobreruedas.com, 1 +colombiawebs.com, 1 +colombyinai.ga, 1 +colonialfilings.com, 1 +colonize.africa, 1 +coloppe.com, 1 +color01.net, 1 +coloradobluebook.gov, 1 +coloradoer.tk, 1 +coloradolottery.com, 1 +coloradoseodesign.com, 1 +coloradosos.gov, 1 +colorblindfilms.com, 1 +colorblindprogramming.com, 1 +colorbrush.ru, 0 +colorcodedlyrics.com, 1 +colorfularchive.eu.org, 1 +colorfulcloud.eu.org, 1 +colorfuldots.com, 0 +colorguni.com, 1 +colorhexa.com, 1 +colorideas.net, 1 +coloringnotebook.com, 0 +coloristcafe.com, 1 +colorlib.com, 0 +colorpalette.org, 1 +colorpicker.fr, 1 +colorsbycarin.com, 1 +colorwow.ga, 1 +colossalfoods.com, 1 +colossalit.com.au, 1 +colosseumticket.cz, 1 +colostral.com, 1 +colotimes.com, 1 +colourfulcastles.co.uk, 1 +colourmanagementpro.com, 1 +colourmeren.com, 1 +colpatriaws.azurewebsites.net, 1 +colson-occasions.be, 0 +coltellisurvival.com, 1 +coltonrb.com, 1 +columbiaboatalarms.com, 1 +columbiacountyor.gov, 1 +columbiaproemergencymovers.com, 1 +columbiascaffolding.com, 1 +columbushydroxide.com, 1 +columbushydroxide.net, 1 +columbushydroxide.org, 1 +columbusks.gov, 1 +columbuswines.com, 1 +com-news.io, 1 +com.cc, 1 +com.fo, 1 +comagexinvoice.com, 1 +comalia.com, 1 +comarcadelaranda.tk, 1 +comarch.es, 1 +comarkinstruments.net, 1 +comasystem.dk, 1 +combattrecellulite.com, 1 +combidesk.com, 1 +combigo.com, 1 +combineconquer.com, 1 +combron.be, 1 +combron.co.uk, 1 +combron.com, 1 +combron.nl, 1 +combustibilaspen.ro, 1 +comcenter.com, 1 +comchezmeme.com, 1 +comcol.nl, 1 +comdotgame.com, 1 +comdurav.com, 1 +come.ga, 1 +come2cook.com, 1 +comealong.org, 1 +comeals.com, 1 +comedicgrouperu.com, 1 +comedimagrire.it, 1 +comedyhuis.nl, 1 +comefollowme2016.com, 0 +comenc.ddns.net, 1 +comeoishii.com, 1 +comeoneileen.tk, 1 +comercialbelzunces.com, 1 +comercialcolombia.tk, 1 +comercialmattos.com, 1 +comercialroxana.com, 1 +comercialtech.cl, 1 +comercialtpv.com, 1 +comercialtrading.eu, 1 +comerford.net, 1 +comeros.be, 1 +comestoarra.com, 1 +cometbot.cf, 1 +cometcache.com, 1 +cometonovascotia.ca, 1 +comevius.com, 1 +comevius.org, 1 +comevius.xyz, 1 +comeyegroup.com, 1 +comff.net, 1 +comfintouch.com, 1 +comfis.nl, 1 +comflores.com.br, 1 +comfortablelife.tk, 1 +comfortmastersinsulation.com, 1 +comfortsolutionsair.com, 1 +comfriesland.tk, 1 +comfun.net, 1 +comfuzztible.tk, 1 +comfy.cafe, 0 +comfy.gay, 1 +comfypc.com, 1 +comhack.com, 1 +comicsans.tk, 1 +comicsanshouse.ddns.net, 1 +comicspornos.com, 1 +comicspornow.com, 1 +comicspornoxxx.com, 1 +comicwiki.dk, 1 +comicyears.com, 1 +comidina.com, 1 +comiq.io, 1 +comisarul.ro, 1 +comita.ru, 1 +comite-des-fetes-neuville.com, 1 +comiteexpertes.gc.ca, 1 +comlipa.gq, 1 +comm.cx, 1 +commania.co.kr, 1 +commco.nl, 1 +commechezvous.ch, 0 +commencepayments.com, 1 +commentjaichangedevie.fr, 1 +comments.app, 1 +commerce.gov, 1 +commercesend.com, 1 +commercezen.com, 1 +commercia.srl, 1 +commercial-academy.fr, 1 +commercial.lviv.ua, 1 +commercialzone.cf, 1 +commeunamour.com, 1 +commfortchat.tk, 1 +commissaris-vraagbaak.nl, 1 +commissionagenda.com, 1 +commissioner.tk, 1 +commitsandrebases.com, 1 +commlabindia.com, 0 +commonapp.org, 1 +commoncode.com.au, 1 +commoncode.io, 0 +commoncore4kids.com, 1 +commons-mayflower.tk, 1 +commonsenseamericanpolitics.com, 1 +commonsensedivorce.ca, 1 +commonsenseinactie.nl, 1 +communalconsulting.org, 1 +communication-services.tk, 1 +communiques.info, 1 +communiquons.org, 1 +communist-party.tk, 1 +community-pro.de, 1 +community-pro.net, 1 +community-services.cz, 0 +communityaligned.com, 1 +communitybangladesh.tk, 1 +communitycodeofconduct.com, 1 +communitydirectory.tk, 1 +communitymanagertorrejon.com, 1 +communote.net, 1 +commure.com, 1 +como-se-escribe.com, 1 +comoaliviareldolor.de, 1 +comocomprarumcarro.tk, 1 +comoculosdesol.pt, 1 +comocurarlagastritis24.online, 1 +comocurarlashemorroidesya.com, 1 +comodo.nl, 1 +comodosslstore.com, 1 +comoenviarcurriculumvitae.com, 1 +comohacerblog.net, 1 +comohacerpara.com, 1 +comoimportar.net, 1 +comomoraremportugal.ga, 1 +comomorreu.com, 1 +comomurio.info, 1 +comoperdonar.tk, 1 +comorecuperaratumujerpdf.com, 1 +comoseduzir.net, 1 +comosefazisto.com.br, 1 +comoviajarcontumascota.com, 1 +comoyoko.com, 1 +comp.kiev.ua, 1 +compactador-vendetta.tk, 1 +compactchess.cc, 1 +compagnia-buffo.de, 0 +compagniecoupable.fr, 1 +compagniedesateliers.com, 1 +compagniemartin.com, 0 +compalliance.com, 1 +companion-web.net, 1 +company-info-plugins.nl, 1 +companyaneksta.tk, 1 +comparatif-moto.fr, 1 +compare-energie.fr, 1 +compareandrecycle.co.uk, 1 +compareceleb.com, 1 +compareicomprei.com.br, 1 +compareinsurance.com.au, 1 +comparelegalforms.com, 1 +comparemymobile.com, 1 +comparesoft.com, 1 +comparetheproject.com, 1 +comparewatch.com, 1 +comparexcloudcenter.com, 1 +compartirtrenmesaave.com, 1 +compassbest.com, 1 +compassdirectportal.com, 1 +compassfinance.com, 1 +compassintladv.com, 1 +compassionaterelease.com, 1 +compasslos.com, 1 +compassregroup.com, 1 +compdermcenter.com, 1 +compdev.ru, 1 +competenceslinux.com, 1 +competencyassessment.ca, 1 +competitor.com, 1 +compeuphoria.com, 1 +compibus.fr, 1 +compilenix.org, 1 +complaint.tk, 1 +completecareair.com, 1 +completeglassutah.com, 1 +completesecurityessex.co.uk, 1 +completesecurityessex.com, 1 +completionist.me, 1 +complex-kaspiy.tk, 1 +complex-news.com, 1 +complex-organization.com, 1 +complexart.ro, 1 +complexcoral.ro, 1 +complexorganization.com, 1 +complexorganizations.com, 1 +compliance-management.ch, 0 +compliance-systeme.de, 1 +compliancedictionary.com, 1 +compliancerisksoftware.co.uk, 1 +compliantbusinessprocessing.com, 1 +complt.xyz, 1 +componentshop.co.uk, 1 +composersforum.org, 1 +compositedevtec.tk, 1 +compostella.online, 1 +compostelle-bouddha.fr, 1 +compoundingrxusa.com, 1 +compra-deuna.com, 1 +comprachida.com, 1 +compraenpijama.com, 1 +comprafasil.com, 1 +compraordenadores.com, 1 +compraporinternet.online, 1 +comprar.club, 1 +comprarcarteras.online, 1 +comprarefiereygana.com, 1 +comprarimpresoras-3d.com, 1 +comprarpapelhigienico.online, 1 +comprarparaguas.online, 1 +comprauncelular.com, 1 +comprax.nl, 1 +compreautomacao.com.br, 1 +compree.com, 1 +comprefitasadere.com.br, 1 +comprehensiveihc.com, 1 +compromis-promesse-vente.fr, 1 +compservice.in.ua, 1 +comptrollerofthecurrency.gov, 1 +comptu.com, 1 +compu-ofertas.tk, 1 +compubench.com, 1 +compucorner.mx, 1 +compunetwor.com, 1 +compuplast.cz, 1 +compusolve.nl, 1 +compusrit.tk, 1 +compustore.pe, 1 +compustuff.tk, 1 +computer-acquisti.com, 1 +computer-menschen.de, 1 +computer-science-schools.com, 1 +computer-worlds.tk, 1 +computer4me.tk, 1 +computeradvance.tk, 1 +computerassistance.co.uk, 1 +computerbas.nl, 1 +computerbase.de, 1 +computercamaccgi.com, 1 +computeremergency.com.au, 0 +computerforum.tk, 1 +computerhelpbutton.com, 1 +computerhilfe-feucht.de, 1 +computerinfobits.com, 1 +computerles.nu, 1 +computernetwerkwestland.nl, 1 +computernetwork.be, 1 +computerscience.guide, 1 +computersforlearning.gov, 1 +computersoftware.tk, 1 +computersystems.guru, 0 +computertech-ut.com, 1 +computerz.solutions, 0 +computingaustralia.com.au, 1 +computingaustralia.group, 1 +computingsociety.co.uk, 1 +computop.com, 1 +computron.ga, 1 +comschool.com.br, 1 +comsoli.com.br, 1 +comtily.com, 1 +comumlab.org, 1 +comuna-susani.ro, 1 +comunal.co, 1 +comunate.com, 1 +comunic.io, 1 +comunicat.global, 1 +comunicazionenellaristorazione.it, 1 +comuniclick.com.br, 1 +comunidadciclismo.com, 1 +comunidadeseo.com.br, 1 +comunidadmontepinar.es, 1 +comuniondelucia.com, 1 +comunistas.tk, 1 +comunitateonline.tk, 1 +comvos.de, 1 +comw.cc, 1 +con-con.nl, 1 +conalpedis.tk, 1 +conatus.ai, 1 +conbida.co, 1 +concealoutfitters.com, 1 +concellodoparamo.tk, 1 +concepcion-futbol-club.tk, 1 +concept-web.ch, 0 +concept5.co.il, 1 +conceptatelier.de, 1 +conceptcompany.com, 1 +conceptground.com, 1 +conceptual.ga, 1 +concern.cloud, 1 +concern.co.nz, 1 +concertcrushers.ga, 1 +concertengine.com, 1 +concerto.amsterdam, 1 +concerts-metal.ch, 0 +concertsenboite.fr, 1 +concertsponent.tk, 1 +concertsto.com, 1 +concetrabajos.cl, 0 +conciencia.fit, 1 +conciencianimal.tk, 1 +concierge.diet, 1 +conciliumnotaire.ca, 1 +conclave.global, 1 +conclave.gq, 1 +conclinica.com.br, 0 +conclude.ga, 1 +conclusion.nl, 1 +conclusive.co.za, 1 +concordiagaming.com, 1 +concordsoftwareleasing.com, 1 +concretedreamsoftexas.com, 1 +concretehermit.com, 0 +concreterepairatlanta.com, 1 +concreterepairconcreteleveling.com, 1 +concreterepairconcreteraising.com, 1 +concursopublico.com.br, 1 +concursos.com.br, 1 +concursosabertos.com.br, 1 +concursuri.biz, 0 +condecom.com.br, 1 +condenast.co.uk, 1 +condepenalba.com, 0 +condesaelectronics.com, 1 +condictor.pl, 1 +condit.ml, 1 +conditionyellowacademy.com, 1 +condolencemessages.net, 1 +condomania.com, 1 +condominiosi.it, 1 +condominioweb.com, 1 +condonescadistas.tk, 1 +condosforcash.com, 1 +condroz-motors.be, 0 +conecta.team, 1 +conectadev.com, 1 +conectumfinanse.pl, 1 +conejovalleyelectrical.com, 1 +conejovalleyelectrician.com, 1 +conejovalleyexteriorlighting.com, 1 +conejovalleylandscapelighting.com, 1 +conejovalleylighting.com, 1 +conejovalleyoutdoorlighting.com, 1 +coneser2gl.com, 1 +conesin.com, 1 +conexaotecidos.com.br, 1 +conexionok.com, 1 +conexiontransporte.com, 1 +conexstudios.online, 1 +conf.tn, 1 +conference-expert.eu, 1 +conference.dnsfor.me, 1 +confia.io, 1 +confiancefoundation.org, 1 +confidential.network, 1 +confidentliving.gq, 1 +confidentliving.tk, 1 +config.schokokeks.org, 0 +configwizard.xyz, 1 +confio.pt, 1 +confirmit.ca, 1 +confirmit.com.au, 1 +confiscate.ga, 1 +confiscation.tk, 1 +confiwall.de, 1 +conflicting.tk, 1 +conformal.com, 0 +conformax.com.br, 1 +conformist.jp, 1 +confort-sante.com, 1 +confrerie-rp.fr, 1 +conftree.com, 1 +confucio.cl, 1 +confusion-band.ch, 1 +confygo.com, 1 +congafasdesol.com, 1 +congdongnhatviet.com, 1 +congelado.tk, 1 +congenio.com, 0 +congenio.de, 0 +congineer.com, 1 +congnghe.so, 1 +congoproject.tk, 1 +congregacionmitacol.org, 1 +congresistas-ap.tk, 1 +congressmankirk.com, 1 +coniectoinvestments.com, 1 +conju.cat, 1 +conjugacao.com.br, 1 +conkret.ch, 1 +conkret.co.uk, 1 +conkret.eu, 1 +conkret.mobi, 1 +conmedapps.com, 1 +conn.cx, 1 +connect-ed.network, 1 +connect-me.com, 1 +connect.dating, 1 +connect.facebook.net, 1 +connect.gov, 1 +connect2pure.com, 1 +connecta.store, 1 +connectavid.com, 1 +connectedbynexus.com, 1 +connectedrisksolutions.com, 1 +connectfss.com, 1 +connecticare.com, 1 +connectingdevonandsomerset.co.uk, 1 +connectingrentals.com, 1 +connectingrentalsofbethel.com, 1 +connectionplanet.nl, 1 +connectionstrings.com, 1 +connective.com.au, 1 +connectivia.it, 1 +connectmath.com, 1 +connectme.com.mx, 1 +connectmy.car, 1 +connecto-data.com, 1 +connectum.eu, 1 +connelink.fr, 1 +conner.work, 1 +conneropticals.ga, 1 +connexas.eu, 1 +connexion.health, 1 +connexionht.com, 1 +connext.de, 1 +connictro.de, 1 +conniesacademy.com, 1 +connorhatch.com, 1 +connorlim.net, 1 +conntrack.com, 1 +connyduck.at, 1 +conocchialidasole.it, 1 +conocedordigital.com, 1 +conociendosalama.com, 1 +conoha.vip, 1 +conorboyd.info, 1 +conory.com, 1 +conotoxia.com, 1 +conpath.net, 1 +conphungtourist.com, 1 +conpins.nl, 1 +conpulpademanzana.es, 1 +conpunk.tk, 1 +conrad-kostecki.de, 1 +conrad.am, 1 +conradboraboranuiresort.com, 1 +conradcartagena.com, 1 +conradkostecki.de, 1 +conradsautotransmissionrepair.com, 1 +conrail.blue, 1 +conrasd.tk, 1 +conrazon.me, 1 +cons.one, 1 +consagracionamariasantisima.org, 1 +consciente.ch, 1 +consciente.ngo, 1 +consciente.ong, 1 +conscientia.com.mx, 1 +consec.systems, 1 +consegnafioridomicilio.net, 1 +consegne.it, 1 +consejociudadanomx.org, 1 +consejosdenutricion.com, 1 +consens.us.org, 1 +consensoprivacy.it, 1 +consertodecelulares.com.br, 1 +conservadoraembh.com.br, 1 +conservationfreedivers.com, 1 +conservationgeography.com, 1 +consideredgifts.com, 1 +consideryourways.net, 1 +consilium-vitae.ch, 1 +consiliumvitae.ch, 1 +consill.com, 1 +consoe.com, 1 +console-tribe.com, 1 +console.ninja, 1 +console.rest, 1 +consolebros.com, 1 +consoletech.tk, 1 +consoleuniverse.tk, 1 +consommateuraverti.com, 1 +consommation-locale.fr, 1 +consonare.de, 1 +consorcionacionalideal.com.br, 1 +conspectstudios.com, 1 +conspiracionweb.tk, 1 +conssec.com, 1 +constant-rough.de, 1 +constant.ga, 1 +constelacion3d.com, 1 +constellations.ga, 1 +consteval.org, 1 +constexpr.org, 1 +constinit.org, 1 +constituenttracker.com, 1 +constru-vegas.com.mx, 1 +construccionesceyve.com, 1 +construct.net, 1 +constructexpres.ro, 1 +constructieve.nl, 1 +construction-colleges.com, 1 +construction-digitale.fr, 0 +construction-group.ga, 1 +construction-student.co.uk, 1 +constructionstudent.uk, 1 +constructive.men, 1 +construred.tk, 1 +construyetuempresa.com, 1 +consul-coton.ru, 1 +consul-novocherkassk.ml, 1 +consul.io, 0 +consulenza.pro, 1 +consulenzanobiliare.com, 1 +consultadepsicoterapia.com, 1 +consultahn.com, 1 +consultation.ai, 1 +consultation.biz.tr, 1 +consultcelerity.com, 1 +consultimator.com, 1 +consultimedia.de, 1 +consulting-brokerage.tk, 1 +consulting-cloud.com, 1 +consultingconnection.co, 1 +consultinghero.es, 1 +consultinghousenet.tk, 1 +consultoresrey.cl, 1 +consultoriadeseguranca.com.br, 1 +consultoriadigital.pt, 1 +consultoriosodontologicos.com.br, 1 +consultorseobr.com.br, 1 +consultpetkov.com, 1 +consumer.ee, 1 +consumer.gq, 1 +consumeraction.gov, 1 +consumerfiles.com, 1 +consumerindex.ga, 1 +consumersentinel.gov, 1 +consuwijzer.nl, 1 +contabilidadebhpampulha.com.br, 1 +contabilidadebrooklin.com.br, 1 +contact.inc, 1 +contact.xyz, 0 +contactaffix.com, 1 +contactelus88.fr, 1 +contactsolo.tk, 1 +contactsrl.it, 1 +contagiousaf.com, 1 +contailor.de, 1 +containerbeveiliging.nl, 1 +containerspace.com.au, 1 +contaminatie.nl, 1 +contato.vip, 1 +conteelegant.ro, 1 +contemplativeeducation.org, 1 +contenedoresdereciclaje.online, 1 +content-api-dev.azurewebsites.net, 0 +content-hub-1.com, 1 +contentmarathon.com, 1 +contentpass.net, 1 +contentq.nl, 1 +contents.ga, 1 +contessa32experience.com, 1 +contextolog.cf, 1 +conti-profitlink.co.uk, 1 +continuation.io, 1 +continuernom.tk, 1 +continuitycenters.com, 0 +continuum.memorial, 0 +continuumrecoverycenter.com, 1 +contrabass.net, 1 +contractdigital.co.uk, 0 +contractdirectory.gov, 1 +contractormountain.com, 1 +contractorswestga.com, 1 +contractstore.com, 1 +contractwriters.com, 1 +contralaespeculacioninmobiliaria.tk, 1 +contralegem.it, 1 +contrapeso.es, 1 +contrarreforma.tk, 1 +contraspin.co.nz, 1 +contrastchecker.online, 1 +contrastecolombia.com, 1 +contratatupoliza.com, 1 +contratti.it, 1 +contributopia.org, 1 +contributor.google.com, 1 +controlautocom.com.br, 1 +controlbooth.com, 1 +controle.net, 1 +controleer-maar-een-ander.nl, 1 +controlewiki.be, 1 +controllertech.com, 1 +controlshiftlabs.com, 1 +controlvoltage.cc, 1 +controlyourwifi.com, 1 +controversialrisks.com, 1 +controversialrisks.se, 1 +contuestilo.tk, 1 +contunda.de, 1 +conv2pdf.com, 1 +convergence.fi, 1 +convergencela.com, 1 +convergnce.com, 1 +conversatis.cf, 1 +converser.tk, 1 +conversionsciences.com, 1 +convert.im, 1 +convert.zone, 1 +convert2sql.com, 1 +converter.ml, 1 +convertidormp3.co, 1 +convertimg.com, 1 +convexset.org, 1 +conveyance.pro, 1 +convierteenabudancia.com, 1 +convocatoriafundacionpepsicomexico.org, 0 +convoluted.solutions, 1 +convozcontamos.com, 1 +conxcon.de, 1 +coochiehacks.io, 1 +coocook.org, 1 +cook-maestro.com, 1 +cook.gg, 1 +cookandgame.com, 1 +cookcountyclerkil.gov, 1 +cookescastles.co.uk, 1 +cookicons.co, 1 +cookie-directive.cf, 1 +cookie4.com, 1 +cookieandkate.com, 1 +cookiecorner.com, 1 +cookiecrook.com, 1 +cookiehulp.nl, 1 +cookiepedia.co.uk, 1 +cookiepro.com, 1 +cookiesoft.de, 1 +cookiestudies.cf, 1 +cooking-food.cf, 1 +cooking-sun.com, 1 +cookingaround.town, 1 +cookingcrusade.com, 1 +cookinglife.nl, 0 +cookingperfected.com, 1 +cookingreporter.com, 1 +cookinsumos.com, 1 +cookmedical.com, 0 +cooko.at, 1 +cooks.house, 1 +cooksite.tk, 1 +cooktoprepairaustin.com, 1 +cookwithmanali.com, 1 +cool-parties.co.uk, 1 +cool-wallpapers.jp, 1 +cool.haus, 1 +cool110.tk, 1 +cool110.xyz, 1 +coolaser.clinic, 1 +coolattractions.co.uk, 1 +coolbitx.com, 1 +coolboys.ga, 1 +coolcamping.com, 1 +cooldan.com, 1 +cooldomains.tk, 1 +coole-fete.de, 1 +coolerssr.space, 1 +coolfilm.cf, 1 +coolgifs.de, 1 +coolink.pub, 1 +cooljs.me, 1 +cooljv.com, 1 +coolkidsbouncycastles.co.uk, 1 +coolmath.cf, 1 +coolmoda.com.ua, 1 +coolpi.nl, 1 +coolprylar.se, 1 +coolsculptingmanhattanbeach.com, 1 +coolshirt.tk, 1 +coolsoftware.tk, 1 +coolspring8.com, 1 +cooltang.ooo, 1 +cooltrades.co.za, 1 +cooltura.do, 1 +coolvox.com, 1 +coolwaterevergreendrilling.com, 1 +coolweirdfacts.ga, 1 +coomer.me, 0 +coomonte.tk, 1 +coon.fr, 1 +coonelnel.net, 1 +coop-land.ru, 1 +coop.com.py, 1 +coopal.jp, 1 +coopelectricidaddevoto.com.ar, 1 +coopemep.live, 0 +coore.jp, 1 +coorpacademy.com, 1 +copa.cf, 1 +copan.com.br, 0 +copdfoundation.org, 1 +copdrop.ga, 1 +copedeportes.tk, 1 +copenhagenleadtech.org, 1 +copewithdata.com, 1 +cophumouraustralia.com, 1 +copleylawfirm.com, 1 +copperandtileroofing.com, 1 +copperexports.tk, 1 +copperheados.com, 1 +coppermein.co.za, 1 +copplaw.com, 1 +coprotag.com, 1 +coprotag.fr, 1 +coptel.cz, 1 +coptkm.cz, 1 +copycaught.co, 1 +copycaught.xyz, 1 +copycenter.cf, 1 +copycrafter.net, 1 +copyfast.cf, 1 +copygeneral.pl, 1 +copypoison.com, 1 +copyright-watch.org, 1 +copyrightcoins.com, 1 +copyrightcoins.help, 1 +copyrightcoinsnews.com, 1 +copyrightshares.com, 1 +copyshrug.ca, 1 +copytext.ml, 1 +copywriting-on-demand.tk, 1 +coqiptv.com, 1 +coral-study.eu, 1 +coralcanticorumbarcelona.tk, 1 +coralreef.blue, 1 +corarcraft.com, 1 +coratxa.tk, 1 +corazoncaliente.tk, 1 +corazondemelon.es, 1 +corbi.net.au, 1 +corbusier.gq, 1 +corcoranmn.gov, 1 +cordejong.nl, 1 +cordemar.info, 1 +cordenka.com, 1 +corder.tech, 1 +cordeydesign.ch, 0 +cordis.io, 1 +cordlessdog.com, 1 +corduroyproducts-velvetjackets.tk, 1 +core-arata.co.jp, 1 +core-collective.co.uk, 1 +core-concepts.de, 0 +core-networks.de, 1 +core.md, 1 +core.mx, 1 +core.org.pt, 1 +core3k.biz, 1 +core3k.com, 1 +core3k.info, 1 +core3k.mobi, 1 +core3k.net, 1 +core3k.org, 1 +core3k.us, 1 +coreapm.com, 1 +coreapm.org, 1 +corecdn.org, 1 +coredns.rocks, 1 +corehealthberks.com, 1 +coreless-initiative.net, 1 +coreless-stretchfilm.com, 1 +coremcnetwork.ml, 1 +coremicro.com, 1 +coremove.tk, 1 +corepartners.com.ua, 1 +corerad.net, 1 +coresos.com, 1 +coretema.eu, 1 +coreum.ca, 1 +coreup.de, 1 +corevetconnect.co.uk, 1 +corexpert.com, 1 +coreyjmahler.com, 1 +coreylmartin.com, 1 +corgi.party, 1 +corgiaspets.com, 1 +corhellemons.tk, 1 +coribi.com, 1 +corinastefan.ro, 1 +corinnanese.de, 1 +corinsamsterdam.com, 1 +corintech.net, 1 +coriolis.ch, 1 +corisu.co, 1 +corkcityfc.tk, 1 +corkedwinebar.com, 1 +corksoncolumbus.com, 1 +corky.tk, 1 +corl3ss.com, 1 +corleoncatering.com, 1 +corlija.com, 1 +corlinde.nl, 1 +cornelia-schiemann.de, 1 +corner-cabinets.tk, 1 +cornercircle.co.uk, 1 +cornergarage.coop, 1 +cornerstone.network, 1 +cornerstonecmc.org, 1 +cornerstonefoundationrepairllc.com, 1 +cornerstonenorthwest.com, 1 +cornertoyshop.ga, 1 +cornfestgiethoorn.nl, 1 +corniche.com, 1 +corningcu.org, 1 +cornishcamels.com, 0 +cornitek.tk, 1 +cornmachine.com, 1 +cornodo.com, 1 +cornsoyexpo.org, 1 +coromade.com, 1 +corona-academy.com, 1 +corona-data.eu, 1 +corona-less.tk, 1 +corona-renderer.cloud, 1 +corona-renderer.com, 1 +corona-stats.online, 1 +coronasafe.network, 1 +coronastationphotography.com, 1 +coronavirus-19.es, 1 +coronavirus.de, 1 +coronavirus.gov, 1 +coronavirusfortbend.gov, 1 +coronavirustesting.gov, 1 +coronersconnect.co.uk, 1 +coropiacere.org, 1 +corp.goog, 1 +corpfin.net, 1 +corpio.nl, 1 +corpkitnw.com, 1 +corpoflow.nl, 1 +corpomotriztokio.com, 1 +corporacionprodigy.tech, 1 +corporateclash.net, 1 +corporatecomputingsolutions.com, 1 +corporatehitech.com.au, 0 +corporateinbound.com, 1 +corporateinfluencers.com, 1 +corporatesubscriptions.com.au, 0 +corporativoarval.info, 1 +corpsepaint.life, 1 +corpulant.coffee, 1 +corpulantcoffee.com, 1 +corpulent.coffee, 1 +corpulentcoffee.com, 1 +corpuschristisouthriver.org, 1 +corpusslayer.com, 1 +corrales-sanchez.tk, 1 +corrbee.com, 1 +correctconstructions.com.au, 1 +correctemails.com, 1 +correcthorse.cf, 1 +correcthorse.pw, 1 +correctiv.org, 1 +correctlydesign.com, 1 +corredorampr.com, 1 +correo.club, 1 +correoscorporativos.com, 1 +correotemporal.org, 1 +correspond.gq, 1 +correspondent.ga, 1 +corrick.io, 1 +corriere.roma.it, 1 +corrupted.io, 0 +corruptos.tk, 1 +corsa-b.uk, 1 +corsectra.com, 1 +corsetacademy.tk, 1 +corsi.tk, 1 +corsicalaw.com, 1 +corsihaccpsicurezzalavoro.it, 1 +corsisicurezza.it, 1 +corso.cf, 1 +corsorspp.roma.it, 1 +cortadoradeplasma.online, 1 +cortapelos.site, 1 +cortealcastello.it, 1 +cortege.cf, 1 +cortesparapelo.com, 1 +cortex-development.de, 1 +cortexx.nl, 1 +cortino.ga, 1 +cortis-consulting.ch, 1 +cortizo.com.ar, 1 +cortonaeranieri.com.br, 1 +corum.fr, 1 +corvaglia.com, 1 +corvax.kiev.ua, 1 +corvettesalvage.com, 1 +corvetto.tk, 1 +corvus.eu.org, 1 +coryadum.com, 1 +coryluba.com, 1 +corytyburski.com, 1 +cosasque.com, 1 +cosciamoos.com, 1 +cosec.cn, 1 +cosirex.com, 1 +coskun.tk, 1 +coslinker.com, 1 +cosmasiakraft.tk, 1 +cosmechic.fr, 1 +cosmekaitori.jp, 1 +cosmetic-surgery-prices.co.uk, 1 +cosmeticappraisal.com, 1 +cosmeticosnet.com.br, 1 +cosmetify.com, 1 +cosmetiq.tk, 1 +cosmetique-totale.nl, 1 +cosmetology.co.za, 1 +cosmiatria.pe, 1 +cosmic-os.org, 1 +cosmic-relations.co.jp, 1 +cosmic-service.com, 1 +cosmicdrifters.com, 1 +cosmicnavigator.com, 1 +cosmicworlds.mobi, 1 +cosmodacollection.com, 1 +cosmohit.ua, 1 +cosmohosting.site, 1 +cosmonaut.tk, 1 +cosmos-indirekt.de, 1 +cosmos-ink.net, 1 +cosmos-software.tk, 1 +cosmoschaos.net, 1 +cosmosearch-azerbaijan.tk, 1 +cosmosenalerta.tk, 1 +cosmosmkt.com.mx, 1 +cosmoz.ga, 1 +cosmundi.de, 1 +cosni.co, 1 +cosplayer.com, 1 +cospol.ch, 0 +cosset.com.tw, 1 +costa-ballena.tk, 1 +costablanca.villas, 1 +costablancavoorjou.com, 1 +costantinogaming.it, 1 +costarellos.com, 1 +costazulinmobiliaria.com, 1 +costco.co.jp, 1 +costco.co.kr, 1 +costco.co.uk, 1 +costco.com.au, 1 +costco.com.mx, 1 +costco.com.tw, 1 +costco.is, 1 +costcoinsider.com, 1 +costellofc.co.uk, 0 +costflow.ga, 1 +costi.cf, 1 +costinstefan.eu, 1 +costoflipitor.gq, 1 +costreportdata.com, 0 +costruzioni.milano.it, 1 +costulessdirect.com, 1 +costum-for-men.tk, 1 +cosummitconstruction.com, 1 +cotandoseguro.com, 1 +coteax.com, 1 +coteax.nl, 1 +coteibem.com.br, 0 +cotejardin.gent, 1 +coteries.com, 0 +coth.ml, 1 +cotoacc.com, 1 +cotodigital.net, 1 +cotofoto.tk, 1 +coton.tk, 1 +cotonmusic.ch, 0 +cotta.dk, 1 +cottage.direct, 1 +cottica-kwaka.com, 1 +cottonage.tk, 1 +cotwe-ge.ch, 0 +cou.re, 1 +coubron-escrime.fr, 1 +couchidiomas.com, 1 +couetteduvet.fr, 1 +cougar-bordeaux.fr, 1 +cougar.dating, 1 +cougarlyon.fr, 1 +coughlan.de, 1 +could.jp, 1 +coumoul.fr, 1 +coun.be, 1 +councilwise.com, 1 +counselingfw.com, 1 +counsellingtime.co.uk, 1 +counsellingtime.com, 1 +counstellor.com, 0 +countdowntrader.com, 1 +counter-team.ch, 0 +counterenlol.com, 1 +countermats.net, 1 +countersolutions.co.uk, 1 +countetime.com, 1 +countrify.net, 1 +country-creativ.de, 1 +country-games.tk, 1 +country-house.ga, 1 +countrybrewer.com.au, 1 +countryfrog.uk, 1 +countrylife.cz, 1 +countrymountaininn.com, 1 +countryoutlaws.ca, 1 +countrysidebar.tk, 1 +countrysidemarquees.co.uk, 1 +countrysmile.org, 0 +countybankdel.com, 1 +countyjailinmatesearch.com, 1 +coup-dun-soir.ch, 1 +coupestanley.com, 1 +couplay.org, 1 +couplesapp.co, 1 +couponbates.com, 1 +couponchief.com, 1 +couponcodesme.com, 1 +coupy.net, 1 +cour4g3.me, 1 +couragefound.org, 1 +courier.lk, 1 +couriergrey.com, 1 +couriersrs.com, 1 +coursables.com, 1 +course.rs, 1 +courseconfidence.com, 1 +coursehunter.net, 1 +courseorbit.com, 1 +coursera.org, 1 +courses.nl, 1 +courseworkbank.info, 1 +coursingweb.tk, 1 +courtlistener.com, 1 +courtneybearse.com, 1 +courtsunlimitedut.com, 1 +courttranscriptontario.ca, 1 +couscous.recipes, 1 +cousine.tk, 1 +cousins.tk, 1 +couvreur-hinault.fr, 1 +covbounce.co.uk, 1 +coventry.com, 1 +coveragecareservices.co.uk, 1 +coveredinspiders.com, 1 +coverful.io, 1 +covermytrip.com.au, 1 +covershousing.nl, 1 +covert.sh, 1 +covid-19advice.com, 1 +covid-games.herokuapp.com, 1 +covid-graphs.info, 1 +covid-model.net, 1 +covid19.gov.ph, 1 +covid19.govt.nz, 1 +covid19.melbourne, 1 +covid19dataportal.si, 1 +covid19details.com, 1 +covid19resilience.org, 1 +covid19responsepod.com, 1 +covid19scotland.co.uk, 0 +covid19statstracker.com, 1 +covidcoldfacts.com, 1 +coviddrawings.org.uk, 1 +covidfreeathome.org, 1 +covidinfo.com.br, 1 +covidlive.com.au, 1 +covidmodel.net, 1 +covidpppstore.co.za, 1 +covidstatistiek.nl, 1 +covuro.com, 1 +covve.com, 0 +covybrat.cz, 1 +cowbird.org, 1 +cowboyim.com, 1 +cowcreek-nsn.gov, 1 +coweo.cz, 1 +coworkanywhere.ch, 1 +coworking-luzern.ch, 1 +coworking-space.tk, 1 +coworking.tk, 1 +cowsay.blog, 1 +coxcapitalmanagement.com, 1 +coxxs.me, 1 +coxxs.moe, 1 +coya.tw, 1 +coyote.cf, 1 +coze.zone, 1 +cozmoapp.com, 1 +cozmoyachts.com, 1 +cozo.me, 1 +cozumel-activities.com, 1 +cozy.town, 1 +cozyeggdesigns.com, 1 +cozzack.com, 1 +cp-st-martin.be, 1 +cp014.com, 1 +cp015.com, 1 +cp061.com, 1 +cpad.org.pk, 1 +cpaexamguy.com, 1 +cpafirmnyc.com, 1 +cpanels.us, 1 +cpaneltips.com, 1 +cpap.com, 1 +cpaporttraining.org, 1 +cpars.gov, 1 +cparta.pro, 1 +cpasperdu.com, 1 +cpbanq.com, 1 +cpcheats.co, 1 +cpchur.ch, 1 +cpd-education.co.uk, 1 +cpdhealthcare.com, 1 +cpe-colleg.de, 1 +cpegypt.tk, 1 +cpfrancophonie.org, 1 +cpfs-group.com, 1 +cpgarmor.com, 1 +cpgiiaragon.es, 1 +cphollywoodproduct.ml, 1 +cphpvb.net, 1 +cpilot.cz, 1 +cplala.com, 1 +cpls.me, 1 +cplus.me, 1 +cplusplus.se, 1 +cppan.org, 1 +cppaste.org, 1 +cppressinc.com, 1 +cpqcol.gov.co, 1 +cprewritten.net, 1 +cpro.pt, 1 +cps-sante.ml, 1 +cpsa.co.uk, 1 +cpsc.gov, 1 +cpsecureapp.com, 1 +cpshr.us, 1 +cpsq.fr, 1 +cpsurvey.com, 1 +cptechsupport.us, 1 +cptoon.com, 1 +cpu.biz.tr, 1 +cpucheu.com, 1 +cpufanshop.ga, 1 +cpy.pt, 1 +cqn.ch, 0 +cqr.pt, 1 +cqradio.tk, 1 +cqswxx.com, 1 +cqvradio.ddns.net, 1 +cr-it.net, 1 +cr.search.yahoo.com, 0 +cr05.fr, 1 +cr1coffee.com, 1 +cr4pr.com, 1 +cr8haven.com, 1 +cr9499.com, 1 +cra-bank.com, 1 +cra-search.net, 1 +craazzyman21.at, 1 +crabfactory.com.my, 1 +crabgrasslawn.com, 1 +crabrave.space, 1 +crabtreestore.nl, 1 +crackajack.cf, 1 +crackcat.de, 1 +crackedsoftware.cf, 1 +cracker.in.th, 1 +crackerjohn.tk, 1 +crackers4cheese.com, 1 +crackheros.site, 1 +crackle.io, 1 +crackload.net, 1 +crackpfer.de, 1 +cracksnet.tk, 1 +crackstation.net, 1 +craft-beer.life, 1 +craft-me-in.com, 1 +craftandbuild.de, 1 +craftbyhand.com, 1 +craftcms.com, 1 +crafted.cat, 1 +crafterbase.de, 1 +crafters.co.jp, 1 +craftgalore.com.au, 1 +craftination.net, 1 +craftingcrow.com, 1 +craftist.de, 1 +craftmachinec.com, 1 +craftngo.hu, 1 +craftottawa.ca, 1 +craftshiponline.tk, 1 +craftsmandruggets.com, 1 +craftsmany.net, 1 +crafttalk.tk, 1 +craftwmcp.xyz, 1 +craftychameleonbar.com, 1 +craftydev.design, 1 +craftyguy.net, 1 +craftyphotons.net, 1 +craftyproducts.co.za, 1 +crag.com.tw, 1 +craig-mullins.com, 1 +craigary.net, 1 +craigbates.co.uk, 0 +craigdavis.ga, 1 +craigfrancis.co.uk, 1 +craigleclaireteam.com, 1 +craigphillips-work.cf, 1 +craigrouse.com, 1 +craigsaper.com, 1 +craigwfox.com, 1 +craine.tech, 1 +cralarm.de, 1 +cramersoft.com, 1 +cran-automobiles.fr, 1 +crandall.io, 1 +cranems.com.ua, 1 +cranenburgh.nl, 1 +cranenburgh.tk, 1 +cranes.ga, 1 +cranforddental.com, 1 +cranioo.nl, 1 +cranshafengin.com, 1 +cranstonri.gov, 1 +craphound.com, 1 +crapitalism.biz, 1 +crapmail.tk, 1 +crapouill.es, 1 +crash-de-1929-et-grande-depression.tk, 1 +crash.net, 1 +crashbolsa.com, 1 +crashboy.ws, 1 +crashcoursecenter.com, 1 +crashcrafter.de, 1 +crashdebug.fr, 1 +crashedata.tk, 1 +cratedb-dev.cloud, 1 +cratedb.cloud, 1 +cratedb.net, 1 +crates-io.cn, 1 +cratss.co.uk, 1 +craveativemedia.com, 0 +cravecraftonline.com, 1 +crawcial.de, 1 +crawford.cloud, 1 +crawfordcountyohioboe.gov, 1 +crawfordcountytcc.org, 1 +crawler.ninja, 1 +crawlspaceandbasementsolutions.com, 1 +crayon.co, 1 +crayonartgallery.com, 1 +crazy-cat.net, 1 +crazy-coders.com, 1 +crazybear-underground.tk, 1 +crazybulk.co.uk, 1 +crazybulk.de, 1 +crazybulk.fr, 1 +crazycastles.ie, 1 +crazycen.com, 0 +crazychicken.tk, 1 +crazycliq.com, 1 +crazycouple.ml, 1 +crazycraftland.net, 1 +crazycube.fr, 1 +crazycube.tk, 1 +crazydrivers.tk, 1 +crazyfoodninja.com, 1 +crazygifts.cf, 1 +crazyhost.ga, 1 +crazyhost.tk, 1 +crazymarvin.com, 1 +crazymeeshu.com, 1 +crazymonkey.gq, 1 +crazypaul.com, 1 +crazypete.ga, 1 +crazypotato.tk, 1 +crazypowered.com, 1 +crazysavings.ga, 1 +crazystories.tk, 1 +crbug.com, 1 +crc-bank.com, 1 +crc-search.com, 1 +crc32.online, 1 +crc64.online, 1 +crdmendoza.net, 1 +crea-etc.net, 0 +crea-shops.ch, 0 +crea-th.at, 1 +crea-that.fr, 1 +crea.bg, 1 +crea.me, 1 +creacioneslri.com, 1 +creacode.tech, 1 +creadoc.fr, 1 +creadstudy.com, 1 +creafitchile.cl, 1 +creaintel.net, 1 +crealogix-online.com, 1 +creamcastles.co.uk, 1 +creampiepornvids.com, 1 +creamsoft.com, 1 +creamyfox.com, 1 +creandoydesarrollando.com, 1 +creared.edu.co, 1 +crearesiteweb.tk, 1 +creareup.com, 1 +creartcol.tk, 1 +creartcompany.com, 1 +creasetheband.tk, 1 +create-ls.jp, 1 +create-website.ga, 1 +createbeing.com, 1 +createbot.ml, 1 +createcode.pt, 1 +createcos.com, 0 +createcpanama.com, 1 +creategyx.ga, 1 +createwithcynthia.com, 1 +creati.me, 1 +creatic.co, 1 +creatieven.com, 1 +creatieverd.nl, 1 +creatingchange.us, 1 +creation-photos.com, 1 +creationfox.gq, 1 +creations-edita.com, 1 +creationsgate.com, 1 +creative-thinking.ro, 1 +creative-wave.fr, 1 +creativeangles.in, 1 +creativebenefits.ca, 1 +creativebites.de, 1 +creativebloq.tk, 1 +creativecaptiv.es, 1 +creativecityofmusic.be, 1 +creativecommons.gr, 1 +creativecommons.org, 0 +creativecommonscatpictures.com, 1 +creativeconceptsvernon.com, 1 +creativedesign.pt, 1 +creativedigital.co.nz, 1 +creativeeducation.tk, 1 +creativeground.com.au, 1 +creativeideasagency.com, 1 +creativeimagery.com.au, 1 +creativeink.de, 1 +creativekkids.com, 1 +creativelaw.eu, 1 +creativeliquid.com, 1 +creativemanoj.com, 1 +creativemysterymind.com, 1 +creativephysics.ml, 1 +creativescorpio.tk, 1 +creativesectors.tk, 1 +creativesurvey.com, 1 +creativeweb.biz, 1 +creativewolf.net, 1 +creativlabor.ch, 1 +creativosonline.org, 1 +creatixx-network.de, 0 +creators-design.com, 1 +creators.direct, 1 +creatujoya.com, 1 +creature-comforts.co.za, 1 +crebita.de, 1 +crecips.com, 1 +crecman.fr, 1 +credee.org, 1 +credex.bg, 1 +credigo.se, 1 +credit-10.com, 1 +credit-default-swaps.tk, 1 +creditandfinancialmanagement.com, 1 +creditcard52.com, 1 +creditdigital.uk, 1 +creditif.tk, 1 +creditkarma.ca, 1 +creditkarma.com, 1 +credito360.pt, 1 +creditor.ga, 1 +creditor.tk, 1 +creditorapido.pt, 1 +creditos-rapidos.com, 1 +creditozen.es, 1 +creditozen.mx, 1 +creditsense.com.au, 1 +creditshop.com, 1 +credittoken.io, 1 +creeks-coworking.com, 1 +creeksidebiblechurch.org, 1 +creep.im, 1 +creepycraft.nl, 1 +creepypastas.com, 1 +creer-une-boutique-en-ligne.com, 1 +creermonsite-wp.com, 1 +creerunsitepro.com, 1 +crefelder.com, 1 +crem.in, 0 +crematory.tk, 1 +cremedigital.com, 1 +cremepassion.de, 1 +crena.ch, 1 +crepa.ch, 0 +crepusculofansmexico.tk, 1 +cresoweb.it, 1 +cresserons.fr, 1 +crest.com, 1 +crestasantos.com, 1 +crestor20mg.ml, 1 +crestorgeneric.ml, 1 +crestwoodky.gov, 1 +cretdupuy.com, 0 +creteangle.com, 1 +cretica.no, 1 +creusalp.ch, 0 +crew.moe, 1 +crew505.org, 1 +crewplanner.eu, 1 +crewsing.tk, 1 +crex24.com, 1 +crfcap.org, 1 +crgalvin.com, 1 +crgm.net, 1 +criandosites.com.br, 1 +criativedesign.com.br, 1 +cribcore.com, 1 +cricketnmore.com, 1 +crickey.eu, 1 +cricklewood.condos, 1 +cricoff.com, 1 +criena.com, 1 +criena.net, 1 +criktrik.com, 1 +crimeainspire.com, 1 +crimean-wines.tk, 1 +crimebarta.com, 1 +crimefire.in, 1 +crimefreeliving.com, 1 +crimesolutions.gov, 1 +crimethincx.tk, 1 +crimevictims.gov, 1 +criminal-attorney.ru, 1 +criminal-market.ml, 1 +criminal-news.tk, 1 +criminal.enterprises, 1 +criminalcasecheats.ml, 1 +criminallawyerjobdescription.gq, 1 +criminalminds.tk, 1 +crimson.no, 0 +crimsonconnect.co.uk, 1 +crimsoncoward.com, 1 +crimsondragoncosplay.tk, 1 +crimsoninators.ga, 1 +crimsonlettersmusic.com, 1 +crimsonmedia.co.uk, 1 +crinesdanzantes.be, 1 +crip-usk.ba, 1 +criptex.tk, 1 +criptocert.com, 1 +criptofy.com, 1 +criptoinvest.pt, 1 +criptolog.com, 1 +criptomonedas365.com, 1 +criptomonedaz.com, 1 +criptomoneylite.tk, 1 +criptozoologia.tk, 1 +crisantacademy.com, 1 +criscitos.it, 1 +criscond.co.uk, 1 +crisisactual.com, 1 +crisisdelos40.tk, 1 +crisisnextdoor.gov, 1 +crismar-flora.tk, 1 +crismatthews.com, 1 +crisp.chat, 1 +crisp.email, 1 +crisp.help, 1 +crisp.im, 1 +crisp.watch, 1 +crispinusphotography.com, 1 +crispybacon.ml, 1 +criss.com.ua, 1 +crisssmanmix.tk, 1 +cristaleslitios.com.mx, 1 +cristals.ga, 1 +cristalva.com, 0 +cristarta.com, 1 +cristau.org, 1 +cristenberens.tk, 1 +cristian-alexander.tk, 1 +cristiandumitru.tk, 1 +cristianhares.com, 1 +cristianonascimento.ml, 1 +cristiengoller.ga, 1 +cristina.tk, 1 +cristnasar.tk, 1 +cristomoradocusco.tk, 1 +critcola.com, 1 +criterion.ga, 1 +critical-result.com, 1 +critical.software, 1 +critical.today, 0 +criticalcaredvm.com, 1 +criticalculture.cf, 1 +criticalgenesis.tk, 1 +criticalmention.com, 1 +criticalrace.org, 1 +criticalsurveys.co.uk, 1 +critiker.com, 1 +critterculture.com, 1 +crixto.io, 1 +crizin.io, 1 +crl-autos.com, 1 +crlna.com, 1 +crm.onlime.ch, 0 +crm114d.com, 1 +crmdumariage.com, 1 +croceverdevb.it, 1 +crochetkim.com, 1 +crockettmyers.com, 1 +croco.vision, 1 +crocop.tk, 1 +crocuscoaching.co.uk, 1 +croeder.net, 1 +cromefire.de, 1 +cromefire.myds.me, 1 +cromosomax.com, 1 +cromwell-intl.com, 1 +cromwellvets.co.uk, 1 +cronberg.ch, 1 +croncron.io, 1 +cronenberg.cc, 1 +cronicademuro.tk, 1 +cronix.cc, 1 +cronjob.de, 1 +cronologie.de, 1 +cronometer.com, 1 +cronoscentral.be, 1 +crookedcru.tk, 1 +crop-alert.com, 1 +cropdiagnosis.com, 1 +crosbug.com, 1 +cross-culture.tk, 1 +cross-led-sign.com, 1 +cross-view.com, 1 +cross-x.com, 1 +cross.lol, 1 +crossair.tk, 1 +crosscom.ch, 1 +crossconnected.co.uk, 1 +crossedwires.net, 1 +crossfiremovies.tk, 1 +crossfitblackwater.com, 1 +crossformer.com, 1 +crossfunctional.com, 1 +crossfw.com, 1 +crossingna.com, 1 +crosslifenutrition.co.uk, 0 +crosslimit.ga, 1 +crossnet.io, 1 +crossorange.jp, 1 +crossorig.in, 1 +crossoverit.com, 1 +crosspeakoms.com, 1 +crossroads-gmbh.ch, 1 +crossway.nl, 1 +crosswayz.tk, 1 +crosty.tk, 1 +crotchrockets.tk, 1 +crow.tw, 1 +crowcloud.com, 1 +crowd.supply, 1 +crowdbox.net, 1 +crowdcloud.be, 1 +crowdfavorite.com, 1 +crowdfundinggent.be, 1 +crowdliminal.com, 1 +crowdpress.it, 1 +crowds.host, 1 +crowdsim3d.com, 1 +crowdstack.com, 1 +crowdstack.io, 1 +crowdsupply.com, 1 +crowleymarine.com, 1 +crownaffairs.ch, 1 +crowncastles.co.uk, 1 +crownchessclub.com, 1 +crownedhijab.com, 1 +crownmarqueehire.co.uk, 1 +crownpoint.com, 1 +crownsterling.io, 1 +crows.io, 1 +crox.co, 1 +croxu.com, 1 +croydonapartments.com.au, 1 +crrev.com, 1 +crsmsodry.cz, 1 +crsoresina.it, 1 +crsserviceogkloak.dk, 1 +crstat.ru, 1 +crt.cloud, 1 +crt.sh, 1 +crt2014-2024review.gov, 1 +crtalleres.com, 1 +cruceroadicto.com, 1 +cruelalice.net, 1 +cruelcarbon.tk, 1 +cruelgirls.tk, 1 +crufad.org, 0 +cruicky.uk, 1 +cruiseaddicts.com, 1 +cruisecheap.com, 1 +cruisefashion.tk, 1 +cruiseguy.com, 1 +cruisemoab.com, 1 +cruises.tk, 1 +crumbcontrol.com, 1 +crumobr.com, 1 +crunchrapps.com, 1 +crunchy.rocks, 1 +crushingcasinos.com, 1 +crushthelsatexam.com, 1 +crushthepmexam.com, 1 +crustytoothpaste.net, 1 +crute.me, 1 +cruzadamorada.tk, 1 +cruzitoproducciones.gq, 1 +crvegas.com, 1 +crvenikrst.tk, 1 +crvv.me, 1 +cry.nu, 0 +cryoblaster.com, 0 +cryoflesh.com, 1 +cryoit.com, 1 +cryothanasia.com, 1 +cryp.no, 1 +crypkit.com, 1 +cryps.pl, 1 +crypt-app.net, 1 +crypt.is-by.us, 1 +cryptcheck.fr, 1 +cryptearth.de, 1 +cryptecks.cf, 1 +crypted.chat, 1 +crypteianetworks.com, 1 +cryptex.net, 1 +cryptic-game.net, 1 +crypticface.tk, 1 +crypticstench.tk, 1 +cryptizy.com, 1 +cryptme.in, 1 +crypto-clix.xyz, 1 +crypto-gaming.tk, 1 +crypto.graphics, 1 +crypto.is, 0 +cryptoafternoon.com, 1 +cryptoanarchist.tk, 1 +cryptobin.co, 1 +cryptobonus.tk, 1 +cryptocaseproject.com, 1 +cryptoclix.website, 1 +cryptocon.org, 1 +cryptocurrencyfare.com, 1 +cryptocurrencynews.today, 1 +cryptoearnblog.xyz, 1 +cryptoeighty.com, 1 +cryptofan.org, 1 +cryptofomo.capital, 1 +cryptofomocapital.com, 1 +cryptofox.nl, 1 +cryptography.ch, 1 +cryptography.io, 1 +cryptoguidemap.com, 1 +cryptohinge.com, 1 +cryptoinvoke.com, 1 +cryptoisnotacrime.org, 1 +cryptojacks.io, 1 +cryptoki.fr, 1 +cryptolab.tk, 1 +cryptoleed.com, 1 +cryptolocalatm.com, 1 +cryptology.ch, 1 +cryptomail.nl, 1 +cryptomaniaks.com, 1 +cryptomixer.io, 1 +cryptomkt.com, 1 +crypton.vercel.app, 1 +cryptonaire.ga, 1 +cryptonetlife.com, 1 +cryptonit.cf, 1 +cryptonom.org, 1 +cryptonx.io, 1 +cryptonym.com, 1 +cryptool.org, 1 +cryptoparty.at, 1 +cryptoparty.dk, 1 +cryptoparty.tv, 1 +cryptopartynewcastle.org, 1 +cryptopartyutah.org, 1 +cryptopaste.org, 1 +cryptophobia.nl, 1 +cryptopro.shop, 1 +cryptorival.com, 1 +cryptoseb.pw, 1 +cryptoshot.pw, 1 +cryptosolicitations.com, 1 +cryptotrendclub.com, 1 +cryptoya.io, 1 +cryptozoologyguide.com, 1 +cryptsus.com, 1 +crys.cloud, 1 +crys.email, 1 +crys.hu, 1 +crys.me, 1 +crys.ovh, 1 +crys.pw, 1 +crys.tv, 1 +crystal-media.tk, 1 +crystal-zone.com, 1 +crystalapp.ca, 1 +crystalblockchain.com, 1 +crystalcave.nl, 0 +crystalchandelierservices.com, 1 +crystalcherryonline.tk, 1 +crystalcube.tk, 1 +crystaldown.de, 1 +crystalgrid.net, 1 +crystaloscillat.com, 1 +crystone.me, 1 +cryz.ru, 1 +cs-algeria.tk, 1 +cs-colorscreed-betongulve.dk, 1 +cs-kurnik.pl, 1 +cs-powa.tk, 1 +cs.money, 1 +csa-clan.tk, 1 +csaapac.com, 1 +csaapac.org, 1 +csabg.org, 1 +csacongress.com, 1 +csacongress.org, 1 +csacongress.us, 1 +csaerotherm.com, 1 +csaposs.com, 1 +csarchispace.com, 1 +csbya.com, 1 +csca.me, 1 +cscdn.net, 1 +csci571.com, 1 +csd-sevnica.si, 1 +csd-slovenije.si, 1 +csdacadcv.ga, 1 +csdcareerday.com, 1 +csdisaster.club, 1 +csds.md, 1 +csehnyelv.hu, 1 +cselzer.com, 1 +csengle.de, 1 +csevolution.tk, 1 +csfcloud.com, 1 +csfd.cz, 1 +csfm.com, 1 +csgf.fun, 1 +csgf.ru, 1 +csgo.help, 1 +csgo.su, 1 +csgo.wiki, 1 +csgo77.com, 1 +csgomtr.com, 1 +csgostash.com, 1 +csgoswap.com, 1 +csgotwister.com, 1 +csgoyournal.com, 1 +csharp.love, 1 +csharpmarc.net, 1 +cshe.de, 1 +cshive-cdn.com, 1 +cshive-img.com, 1 +cshive-static.com, 1 +cshive.com, 1 +cshopify.com, 1 +cshub.nl, 1 +csilies.de, 1 +csimarket.com, 1 +csinfo.us, 1 +csinterstargeneve.ch, 0 +csirt.ee, 1 +csis.dk, 1 +csisgroup.com, 1 +csitarz.com, 1 +cskentertainment.co.uk, 1 +cslaboralistas.pe, 1 +cslbuild.com, 1 +csmainframe.com, 1 +csnet.live, 1 +csodaorszagovoda.hu, 1 +csokolade.hu, 1 +csp.ch, 0 +cspeti.hu, 1 +csps-efpc.gc.ca, 1 +cspvalidator.org, 1 +csrichter.com, 1 +csroot.cf, 1 +csru.net, 1 +css-krebs.ch, 1 +css-tricks.com, 1 +css-tricks.tk, 1 +css.direct, 0 +cssai.eu, 1 +cssaunion.com, 1 +csszamotuly.pl, 1 +cst-vbg.ru, 1 +cst188.cc, 1 +cstanley.net, 1 +cstb.ch, 0 +cstmadrid.tk, 1 +cstp-marketing.com, 1 +cstrong.nl, 1 +csu.st, 1 +csust.net, 1 +csuw.net, 1 +csvalpha.nl, 1 +csvplot.com, 1 +cswapps.com, 1 +cswarzone.com, 1 +cswgmbh.de, 1 +csx.co.za, 1 +csy.hu, 1 +ct-watches.dk, 1 +ct.search.yahoo.com, 0 +ctc-transportation.com, 1 +ctchosting.net.au, 1 +ctcloud.ml, 1 +ctcom-peru.com, 1 +ctcp.pt, 1 +ctcue.com, 1 +ctech.cf, 1 +ctemplar.com, 1 +ctes.cz, 1 +ctf-albstadt.de, 1 +ctf.link, 1 +cthomas.work, 1 +cthu.io, 1 +cthulhuden.com, 1 +ctir.gov.br, 1 +ctknight.me, 1 +ctkwwri.org, 1 +ctliu.com, 1 +ctmrepository.com, 1 +ctnguyen.de, 1 +ctnguyen.net, 1 +ctnigeria.com, 1 +ctns.de, 0 +ctoin.tw, 1 +ctonovenkogo.tk, 1 +ctor.ch, 1 +ctoresms.com, 1 +ctpe.info, 1 +ctpe.net, 1 +ctr-sante.eu, 1 +ctrl.blog, 1 +ctrl.gr, 1 +ctrlcvz.tk, 1 +ctrld.me, 1 +ctsl.net, 1 +ctstoowoomba.com.au, 1 +ctt.global, 1 +cttso.gov, 1 +cturpoc.com, 1 +ctyrisinkneri.cz, 1 +cu247secure.ie, 1 +cuaresmaysemanasanta.tk, 1 +cuartetocontinental.tk, 1 +cuartob.tk, 1 +cuasotinhyeu.vn, 1 +cuatroymedia.com, 1 +cub-bouncingcastles.co.uk, 1 +cubaal.com, 1 +cubanchino.tk, 1 +cubatel.com, 1 +cube-filing.com, 1 +cube.builders, 1 +cubebot.io, 1 +cubebuilders.net, 1 +cubecraft.net, 1 +cubecraftcdn.com, 1 +cubecraftstore.com, 1 +cubecraftstore.net, 1 +cubekrowd.net, 1 +cubela.tech, 1 +cubeo.xyz, 1 +cubepasses.com, 1 +cubeperformancecentre.com.au, 1 +cubetech.co.jp, 1 +cubex.ltd, 1 +cubia.com, 1 +cubia.de, 1 +cubia3.com, 1 +cubia4.com, 1 +cubiest.com, 1 +cubigames.tk, 1 +cubikus.fr, 1 +cubile.xyz, 1 +cubing.net, 1 +cublick.com, 1 +cubocell.com, 1 +cuboxmovies.ga, 1 +cubsbestteaminbaseball.com, 1 +cubsradio.tk, 1 +cubua.com, 1 +cubyhome.com, 1 +cucaracha.tk, 1 +cuchichi.es, 1 +cuckoo.ee, 1 +cuddlecat.io, 1 +cuddlecomfort.com, 1 +cuddlingyaks.com, 1 +cuddlybeardaycare.com.au, 1 +cudesa.gq, 1 +cudesyb.tk, 1 +cudoo.de, 1 +cueca.com.br, 1 +cuecasonline.com.br, 1 +cuegee.com, 1 +cuencos-tibetanos.online, 1 +cuentadias.cl, 1 +cuentamecomopaso.es, 1 +cuentas-gratis.ga, 1 +cuentasmutualamr.org.ar, 1 +cues.org.uk, 1 +cuestiondegustos.es, 1 +cuetoems.com, 1 +cuevafelina.tk, 1 +cugetliber.ro, 1 +cuhawaii.com, 1 +cuibonobo.com, 1 +cuio.net, 1 +cuir-lipari.fr, 1 +cuisine-ultime.fr, 1 +cuisinecastle.com, 1 +cuitrau.tk, 1 +cukrinelape.com, 1 +culha.net, 1 +culinary.ga, 1 +culpoilu.tk, 1 +cultbeauty.co.uk, 1 +cultbeauty.com, 1 +cultiv.nl, 1 +cultofd50.org, 1 +cultofperf.org.uk, 1 +cultrix.co.uk, 1 +cultrixdigital.co.uk, 1 +cultura10.com, 1 +culturabrasilia.tk, 1 +culturaldiversity.tk, 1 +culturalmaninhos.tk, 1 +culturalparadiso.tk, 1 +culturalsabotage.cf, 1 +culturedcode.com, 1 +cultureetsoft.tk, 1 +culturelivresque.fr, 1 +culturerain.com, 1 +cultureroll.com, 1 +culturesgames.tk, 1 +cultureshift.co, 1 +culturesouthwest.org.uk, 1 +culturess.com, 1 +culturism.ml, 1 +culturoquiz.com, 1 +cultuur.gent, 1 +cultuurinonderwijs.be, 1 +cumberlandrivertales.com, 1 +cumbiaperuana.tk, 1 +cumbredelamaternidad.com, 1 +cuminas.com, 1 +cuminas.jp, 1 +cumnock.name, 1 +cumnock.org, 1 +cumplegenial.com, 1 +cumseface.eu, 1 +cumsext.me, 1 +cumshots-video.ru, 1 +cumtd.com, 1 +cumulogranite.fr, 1 +cumulus.photo, 1 +cunha.be, 1 +cuntflaps.me, 1 +cuoc.org.uk, 1 +cuongthach.agency, 1 +cuongthach.com, 1 +cuongthach.net, 1 +cup.al, 1 +cupcake.pt, 1 +cupcao.gov, 1 +cupclub.com, 1 +cupdunarea.ro, 1 +cupoane-reducere.net, 1 +cupom.net, 1 +cupomdeapp.com, 1 +cupomeu.com.br, 1 +cupomia.com.br, 1 +cuppycakes.fi, 1 +cur.by, 1 +curacao-firma.com, 1 +curacao-license.com, 1 +curacaodiveguide.com, 1 +curamail.co.uk, 1 +curaprox.co.th, 1 +curareldolordeespalda.com, 1 +curatedtaste.com, 0 +curbside.com, 1 +cureatr.com, 1 +curia.fi, 1 +curieux.digital, 0 +curio-shiki.com, 1 +curiosity-driven.org, 1 +curiositytrained.com, 1 +curl.tw, 1 +curlify.com, 1 +curlingbelgium.tk, 1 +curlingclass.com, 1 +curlybracket.co.uk, 1 +curontwerptoolgroenbeton.nl, 1 +currency-one.com, 1 +currency-strength.com, 1 +currencyfreaks.com, 1 +current-usa.com, 1 +current.com, 1 +currentbitcoin.news, 1 +currentchaos.tk, 1 +currentcryptocurrency.news, 1 +currentcryptocurrencynews.com, 1 +currenthaus.com, 1 +currentlystreaming.com, 1 +currentlyusa.com, 1 +currynissanmaparts.com, 1 +curseria.com, 1 +curseus.com, 1 +cursive.io, 1 +cursoalia.com, 1 +cursoandroid.com, 1 +cursocatolico.com, 1 +cursodememorizacao.ml, 1 +cursointeractivo.com, 1 +cursomente.online, 1 +cursorcam.tk, 1 +cursos-trabajadores.net, 1 +cursos.com, 1 +cursosdeinglesmexico.com, 1 +cursosemmaus.es, 1 +cursosforex.com, 1 +cursosgratuitos.pe, 1 +cursosingles.com, 1 +cursosprogramacion.online, 1 +cursossena.co, 1 +cursosypostgrados.com, 1 +cursuri-de-actorie.ro, 1 +curtacircuitos.com.br, 0 +curtis-smith.me.uk, 1 +curtis-smith.uk, 1 +curtislinville.net, 1 +curtisplumstone.com, 1 +curtispope.com, 1 +curtissmith.me.uk, 1 +curtissmith.uk, 1 +curts-showcars.com, 1 +curva.co, 0 +curvemedia.co, 1 +curveprotect.com, 1 +curveprotect.cz, 1 +curveprotect.net, 1 +curveprotect.org, 1 +curvissa.co.uk, 1 +curvylove.de, 1 +cuscocontable.com, 1 +cusfit.com, 1 +cushlaofgullion.com, 1 +cushytushiediapers.com, 1 +custamped.com, 1 +custer.tk, 1 +custercounty-co.gov, 1 +custodiamobili.roma.it, 1 +custodian.nl, 1 +custodyxchange.com, 1 +custom-wear.ua, 1 +custombobbleheads.com, 1 +custombuttonco.com, 1 +customcodeit.com.au, 1 +customcompleteautomotive.com, 1 +customdissertation.com, 1 +customerbox.ir, 1 +customerfocus.co.za, 1 +customessaystation.gq, 1 +customfitbymj.net, 1 +customgear.com.au, 1 +customhash.com, 1 +customizeyoursink.com, 1 +custompac.co.uk, 1 +custompapers.com, 1 +custompoolsbydesign.com, 1 +customradio.tk, 1 +customromlist.com, 1 +customsandals.tk, 1 +customshort.link, 1 +customsportsocks.com, 1 +customssupport.com, 1 +customtel.com.au, 1 +customwebsitesplus.com, 1 +customwritings.com, 1 +customwritten.com, 1 +custosd.com, 1 +custosd.io, 1 +custosd.net, 1 +custosd.org, 1 +cute2u.com, 1 +cutehost.ga, 1 +cutemodel.ml, 1 +cutephil.com, 1 +cutie-viewty.tk, 1 +cuties.chat, 1 +cutimbo.ovh, 1 +cutlinks.ml, 1 +cutmylink.gq, 1 +cutner.co, 1 +cutpasteprofit.tk, 1 +cutter.li, 1 +cuttingedgeperiodontist.com, 1 +cuvva.co, 1 +cuvva.co.uk, 1 +cuvva.com, 1 +cuvva.eu, 1 +cuvva.io, 1 +cuvva.it, 1 +cuvva.me, 1 +cuvva.net, 1 +cuvva.org, 1 +cuvva.uk, 1 +cuvva.us, 1 +cuwebinars.com, 1 +cuxpool.club, 1 +cuxpool.net, 1 +cuyahogacountyvotesoh.gov, 1 +cvbp.nl, 1 +cvc.digital, 1 +cvdeexpo.com, 1 +cve-le-carrousel.ch, 0 +cve.sh, 1 +cvetpodokonnik.tk, 1 +cvglobal.cf, 1 +cviip.ca, 1 +cviip.com, 1 +cvj.me, 1 +cvjd.me, 0 +cvl.ch, 0 +cvlibrary.co.uk, 1 +cvmatch.me, 1 +cvmu.jp, 1 +cvo-group.com, 1 +cvr.dk, 1 +cvsmash.io, 1 +cvtemplatemaster.com, 1 +cvtenerife.tk, 1 +cvursache.com, 1 +cvutdecin.cz, 1 +cvv.cn, 1 +cw-bw.de, 0 +cw.center, 1 +cwaclub.tk, 1 +cwallpapersheb.tk, 1 +cwaurora.top, 1 +cwbrtrust.ca, 1 +cwc.gov, 1 +cwgallery.de, 1 +cwgaming.co.uk, 1 +cwgpllc.com, 1 +cwilson.ga, 1 +cwinfo.fi, 1 +cwinfo.net, 1 +cwmart.in, 1 +cwr.gov, 1 +cwrau.com, 1 +cwrau.de, 1 +cwrau.info, 1 +cwrau.io, 1 +cwrau.me, 1 +cwrau.name, 1 +cwrau.rocks, 1 +cwrau.tech, 1 +cwrcoding.com, 1 +cwwise.com, 1 +cx100.io, 1 +cxbmystore.com, 1 +cxologic.io, 1 +cy.ax, 1 +cy.technology, 1 +cy01.ch, 1 +cyanghost.com, 1 +cyanhexagon.com, 1 +cybbh.space, 1 +cybeautiful.com.br, 1 +cyber-computer.club, 1 +cyber-core.co.uk, 1 +cyber-ksa.com, 1 +cyber-links.tk, 1 +cyber-m.net, 1 +cyber-mech.tk, 1 +cyber-shield.de, 0 +cyber-sikkerhed.dk, 1 +cyber-travel.com, 1 +cyber-world.tk, 1 +cyber-yaroslavl.tk, 1 +cyber.cafe, 0 +cyber.gc.ca, 1 +cyber.gov, 1 +cyber.je, 1 +cyber.securitytactics.com, 1 +cyberallegiance.com, 1 +cyberarmy.cc, 1 +cyberatlantis.com, 1 +cyberattackincidentresponse.com, 1 +cyberautomobile.tk, 1 +cyberbotx.com, 1 +cyberburek.tk, 1 +cybercareers.gov, 1 +cybercat-tver.tk, 1 +cybercave.tk, 1 +cybercloud.cc, 1 +cybercrew.cc, 1 +cybercrew.rocks, 1 +cybercrime-forschung.de, 1 +cybercrime.gov, 1 +cybercustodian.com, 1 +cyberdean.fr, 1 +cyberdevelopment.es, 1 +cyberdiscoverycommunity.uk, 1 +cyberduck.io, 1 +cyberdyne.ie, 1 +cyberdyne.llc, 1 +cyberex.es, 1 +cyberexplained.info, 1 +cyberforensics.com, 1 +cyberforge.ml, 1 +cybergame-host.tk, 1 +cybergroup.cf, 1 +cyberguerrilla.info, 1 +cyberguerrilla.org, 1 +cyberhazard.eu, 1 +cyberhipsters.nl, 1 +cyberianhusky.com, 0 +cyberinc.nl, 1 +cyberislam.tk, 1 +cyberium-planet.cf, 1 +cyberlin.org, 1 +cybermaniac.tk, 1 +cybermatrixone.tk, 1 +cyberme.sh, 1 +cybermeldpunt.nl, 1 +cybermotives.com, 1 +cybernest.de, 1 +cybernetivdigital.com, 1 +cyberogism.com, 1 +cyberon.it, 1 +cyberoptic.de, 1 +cyberpanel.cf, 1 +cyberpathogen.me, 1 +cyberpcforum.com, 1 +cyberphaze.com, 1 +cyberphoenix.tk, 1 +cyberplus.net.id, 1 +cyberprogramming.tk, 1 +cyberpubonline.com, 1 +cyberpunk.guru, 1 +cyberquest.cf, 1 +cyberregister.nl, 1 +cyberregister.org, 1 +cyberrepair.de, 1 +cyberry.eu, 1 +cybersa.online, 1 +cybersamurai.tk, 1 +cyberscan.io, 1 +cyberschmiede.at, 1 +cyberschmiede.com, 1 +cyberschmiede.de, 1 +cybersecurite-info.fr, 1 +cybersecurity.gov, 1 +cybersecurity.gr, 1 +cybersecurity.nz, 1 +cybersecurity.run, 1 +cybersecuritychallenge.be, 0 +cybersecurityincidentresponse.com, 1 +cybersecurityketen.nl, 1 +cyberseguranca.com.br, 1 +cyberserver.org, 1 +cybershark.space, 1 +cybershot.tk, 1 +cybersins.com, 1 +cyberskyline.com, 1 +cybersmart.co.uk, 1 +cybersmartdefence.com, 1 +cybersolution.tk, 1 +cybersound.tk, 1 +cyberspace.community, 1 +cyberspace.today, 1 +cyberspect.com, 1 +cyberspect.io, 1 +cyberstatus.de, 1 +cyberthreatdata.com, 1 +cybertik.net, 1 +cybertorsk.org, 1 +cybertrinity.co.uk, 1 +cybertron.cf, 1 +cybertronics.tk, 1 +cybertu.be, 1 +cyberwars.dk, 1 +cyberweightloss.com, 1 +cyberwire.nl, 1 +cyberworldexpert.tk, 1 +cyberwritersink.com, 1 +cyberxpert.nl, 1 +cyberzones.gq, 1 +cyborgtheory.tk, 1 +cybozu.cn, 1 +cybozu.com, 1 +cyclamen.tk, 1 +cycledownunder.com, 1 +cyclehackluxembourgcity.lu, 1 +cycleshop.com.ua, 1 +cycleterrace.jp, 1 +cycling74.com, 1 +cyclingbiker.com, 1 +cyclinggoodso.com, 1 +cyclisjumper.gallery, 1 +cyclonedesign.ca, 1 +cyclop-editorial.fr, 1 +cycomm.ro, 1 +cydetec.com, 1 +cyelint.com, 1 +cyfly.org, 1 +cygnaltech.com, 1 +cygnan.com, 1 +cygnatus.com, 1 +cygnius.net, 1 +cyhour.com, 1 +cykelbanor.se, 1 +cyklistika24.cz, 1 +cylindehea.com, 1 +cylindricity.com, 1 +cyllos.me, 1 +cynetco.com, 1 +cynop.me, 1 +cynthiacherry.com, 1 +cyon.ch, 1 +cype.dedyn.io, 1 +cyph.audio, 1 +cyph.com, 1 +cyph.healthcare, 1 +cyph.im, 1 +cyph.io, 1 +cyph.me, 1 +cyph.video, 1 +cyph.ws, 1 +cyphar.com, 1 +cypherpunk.at, 1 +cypherpunk.observer, 1 +cypherpunk.ws, 1 +cypressinheritancesaga.com, 1 +cypresslegacy.com, 1 +cyprus-company-for.gr, 1 +cyprus-company-service.com, 1 +cyptechost.co.ke, 1 +cyqual.com, 1 +cyrano-books.com, 1 +cyraus.com, 0 +cyric.eu, 1 +cyrilstoll.ch, 1 +cyrix-systems.tk, 1 +cysec.biz, 1 +cysmo.de, 1 +cyson.tech, 1 +cytat.tk, 1 +cytegic-update-packages.com, 1 +cythereaxxx.com, 1 +cytophil.com, 1 +cyumus.com, 1 +czakey.net, 1 +czaw.org, 1 +czbix.com, 1 +czbtm.com, 1 +czc.cz, 1 +czech.is, 1 +czechcrystals.co.uk, 1 +czechglaskralen.nl, 1 +czechvirus.cz, 1 +czeh.us, 1 +czh999.com, 1 +czirnich.org, 1 +czk.mk, 1 +czlx.co, 0 +czprothz.tk, 1 +czqu.xyz, 1 +czteryporyroku.edu.pl, 1 +czwartybrat.pl, 1 +czymamdzisimieniny.pl, 1 +czzs.org, 0 +d-20.fr, 1 +d-consultant.ru, 1 +d-eisenbahn.com, 1 +d-ku.de, 1 +d-loop.de, 1 +d-macindustries.com, 1 +d-parts.de, 1 +d-parts24.de, 1 +d-soft.tk, 1 +d-solutions.com.au, 1 +d-systems.tk, 1 +d-taube.de, 1 +d-tousei.co.jp, 1 +d-toys.com.ua, 1 +d-training.de, 1 +d-va.cf, 1 +d-vision-create.com, 1 +d.nf, 1 +d.nr, 1 +d00228.com, 1 +d00d.de, 1 +d0g.cc, 1 +d0xq.net, 1 +d166.net, 1 +d1k1dblh0pghv8.cloudfront.net, 1 +d1pbyafuxn3mkm.cloudfront.net, 1 +d1pyhxxwnnp9rt.cloudfront.net, 1 +d1qvlbepn0kduz.cloudfront.net, 1 +d1v7neu4o1h4vp.cloudfront.net, 1 +d2.gg, 1 +d21laxujm54z8h.cloudfront.net, 1 +d24.net, 1 +d24zgh0u05bzjw.cloudfront.net, 1 +d25sxbgdpzj1st.cloudfront.net, 1 +d2ph.com, 1 +d2woj1dt0tk6sn.cloudfront.net, 1 +d30365.com, 0 +d36533.com, 1 +d36594.com, 1 +d3a.xyz, 1 +d3d3.tk, 1 +d3dev.cf, 1 +d3lab.net, 1 +d3xt3r01.tk, 1 +d42.no, 1 +d4b.in.ua, 1 +d4done.com, 1 +d4fx.de, 1 +d4h.live, 1 +d4wson.com, 1 +d4x.de, 1 +d5197.co, 1 +d58beu28.com, 1 +d64.nl, 1 +d6729.co, 1 +d6729.com, 1 +d6957.co, 1 +d6c5yfulmsbv6.cloudfront.net, 1 +d8.io, 1 +d8118.com, 1 +d81365.com, 1 +d8181.com, 1 +d8228.com, 1 +d82365.com, 1 +d8787.net, 1 +d88-livechat.com, 0 +d88.ag, 1 +d88.cc, 1 +d88.cn.com, 1 +d88.com, 1 +d88.xyz, 1 +d881.net, 1 +d8811.net, 1 +d88118.com, 1 +d8812.com, 1 +d8814.com, 1 +d8816.com, 1 +d8819.com, 1 +d8834.com, 1 +d883vip.com, 1 +d8842.com, 1 +d8845.com, 1 +d8846.com, 1 +d8847.com, 1 +d884vip.com, 1 +d8850.net, 1 +d885188.com, 1 +d8852.net, 1 +d8853.com, 1 +d8855.vip, 1 +d8859.com, 1 +d885vip.com, 1 +d886.net, 1 +d8860.net, 1 +d8861.com, 1 +d88688.com, 1 +d886vip.com, 1 +d8870.net, 1 +d8872.net, 1 +d8874.com, 1 +d8878.com, 1 +d887vip.com, 1 +d88818.com, 1 +d8886.net, 1 +d88868.com, 1 +d88869.com, 1 +d88871.com, 1 +d88873.com, 1 +d88877.com, 1 +d888818.com, 1 +d88882.com, 1 +d88883.com, 1 +d88886.com, 1 +d88889.com, 1 +d889.app, 1 +d8890.net, 1 +d8891.net, 1 +d8898.com, 1 +d88988.com, 1 +d8899.vip, 1 +d88a.vip, 1 +d88agent.com, 1 +d88agqj.com, 1 +d88b.vip, 1 +d88c.vip, 1 +d88d99.com, 1 +d88e.vip, 1 +d88md03.com, 1 +d88siteintro.com, 1 +d898.app, 1 +d899365.com, 1 +d8998.com, 1 +d8studio.net, 1 +d9297.co, 1 +d9397.com, 1 +d9721.com, 1 +d9728.co, 1 +d9c.eu, 1 +da42foripad.com, 1 +daaje-und-andre.de, 1 +daallexx.eu, 1 +dabai.club, 1 +dabai.photo, 1 +dabasstacija.lv, 1 +dabbingtee.com, 1 +dabblegoat.com, 0 +dabhand.pl, 1 +dabhand.studio, 1 +dabstairs.com, 1 +dabuzz.tk, 1 +dacada-porn.com, 1 +daceurope.co.uk, 1 +dacha-letom.ml, 1 +dachb0den.net, 1 +dachbeschichtung-zentrum.de, 1 +dachbleche24-shop.de, 1 +dachdecker-ranzenberger.de, 1 +dachdeckerei-hagen.de, 1 +dachdeckermeister-egon-weiss.de, 1 +dachengquan.ca, 1 +dachshundsaspets.com, 1 +dachshundtalk.com, 1 +daciamodellen.nl, 1 +dad256.tk, 1 +dada.is, 1 +dadadani.xyz, 1 +dadafterforty.be, 1 +dadcentral.ca, 1 +daddybio.com, 1 +daddyfinger.me, 1 +daddysluder.net, 1 +dado.fr, 1 +dado.me, 1 +dado.virtual.museum, 1 +dadons-laserdiscs.com, 1 +dadosch.de, 0 +dadrian.io, 1 +dadsarmy.tk, 1 +dadstersgroup.com, 1 +daduke.org, 1 +daemen.org, 1 +daemon-hentai.tk, 1 +daemon.xin, 1 +daemons.ml, 1 +daemonslayer.net, 1 +daemwool.ch, 1 +daevel.com, 1 +daevel.fr, 1 +daevel.net, 1 +dafassl.com, 1 +dafater.sa, 1 +dafe2021.ee, 1 +dafnik.me, 1 +dafont.com, 1 +dafricapress.com, 1 +daftarhajiumroh.com, 1 +dafuli.net, 1 +dafunda.com, 1 +dafyddcrosby.com, 1 +dag-berlin.tk, 1 +dag-hebergement.fr, 1 +dag-konsult.com, 1 +dag-ogni.tk, 1 +daganzo.tk, 1 +dagbestedingwarrie.nl, 1 +dagensannonser.se, 1 +dagestan.cf, 1 +dagestanci.tk, 1 +dagestanec.tk, 1 +dagirl.uno, 1 +dagjetreinen.nl, 1 +dagmar2018.cz, 1 +dagmarhamalova.cz, 1 +dagrs.se, 1 +dagyirivera.com, 1 +dahfasad.com, 1 +dahl-pind.dk, 1 +dahlberg.cologne, 1 +dahobo.tk, 1 +dai.top, 0 +daibetter.com, 1 +daidogei.com, 1 +daidr.me, 0 +daie-inc.com, 1 +daigakujuken-plus.com, 1 +daikoz.com, 1 +daily-city.com, 1 +daily-exps.herokuapp.com, 1 +daily-puzzle.tk, 1 +dailyalerts.ga, 1 +dailybihar.com, 1 +dailybits.be, 1 +dailyblocks.com, 1 +dailyblogged.com, 1 +dailychristianpodcast.com, 1 +dailycricnews.tk, 1 +dailydealika.com, 1 +dailydosehealth.com, 1 +dailydote.com, 1 +dailyemailinboxing.com, 1 +dailyenglishchallenge.com, 1 +dailyhealthylife.ml, 1 +dailykos.com, 1 +dailynewsclubs.ga, 1 +dailynewsfrommedjugorje.ml, 1 +dailyphototips.com, 1 +dailypop.ru, 1 +dailyreels.ga, 1 +dailyrenewblog.com, 1 +dailyrover.com, 1 +dailyroverr.com, 1 +dailysuperheroes.com, 1 +dailyw88.com, 1 +dailyw88.net, 1 +dailyxenang.com, 1 +daim-avtoelektrika.ru, 1 +daimafengzi.com, 1 +daimonikos.com, 1 +dairikab.go.id, 1 +dairyshrine.org, 1 +daisakuikeda.org, 1 +daisidaniels.co.uk, 1 +daisuki.pw, 1 +daisy-peanut.com, 1 +daisyindia.org, 1 +daisypeanut.com, 1 +daisypeel.com, 1 +daisyscars.cf, 1 +daiwa-union.jp, 1 +dajiadu.net, 0 +dajiale.org, 1 +dajjal.org, 1 +dak.org, 1 +daken.hu, 1 +daki-host.tk, 1 +dakin.nyc, 1 +dakindesign.com, 1 +dakinnyc.com, 1 +daknob.net, 1 +dakota-spain.tk, 1 +dakotacil.org, 1 +dakotasjoint.com, 1 +daktarisys.com, 1 +daktariwildlife.org, 1 +dal-loop.xyz, 1 +dal.net.sa, 1 +dalaran.city, 1 +dalb.in, 1 +dalbitresb.com, 1 +dalcomseo.com, 1 +dale-bancruz.tk, 1 +dale-west.com, 1 +dalek.co.nz, 1 +dalepresencia.com, 0 +dalfsennet.nl, 1 +dalianbbq.com, 1 +dalingk.com, 1 +dalkhola-city.tk, 1 +dalkhola.tk, 1 +dalkholaphotos.tk, 1 +dallapartedeltorto.tk, 1 +dallas.gov, 1 +dallas.lu, 1 +dallaslu.com, 1 +dallasmenshealth.com, 1 +dallastxdivorce.com, 1 +dallaswestinternational.ga, 1 +dallatana.tk, 1 +dalliard.ch, 1 +dallmeier.net, 1 +dalmatiersheusden.be, 1 +daltcore.com, 1 +daltonedwards.me, 1 +daltonlabs.tk, 1 +dam74.com.ar, 1 +damadam.pk, 1 +damaged.org, 1 +damarsarkilar.tk, 1 +damasexpress.com, 1 +damebe.com.br, 1 +damedrogy.cz, 1 +dameeq.cf, 1 +damejidlo.cz, 1 +dameocio.com, 1 +damianus.hr, 1 +damianuv-blog.cz, 0 +damicris.ro, 1 +damiengobron.com, 1 +damienoreilly.org, 1 +damifph.com, 1 +daminiphysio.ca, 1 +damip.net, 1 +damirsystems.com, 1 +damjanovic.it, 1 +damjanovic.work, 1 +dammam-clean.com, 1 +dammekens.be, 1 +damnation.tk, 1 +damngoodpepper.com, 0 +damnkid.ml, 1 +damonline.dk, 1 +dampedia.com, 1 +dampfbahn-leverkusen.com, 1 +dampfbahn-leverkusen.de, 1 +dampferchef.ch, 1 +damuhan.tk, 1 +damvdolg.gq, 1 +dan-bureau.com, 1 +dan-informacijske-varnosti.si, 1 +dan-maskiner.tk, 1 +dan.me.uk, 1 +dan124.com, 1 +danadameson.tk, 1 +danads.com, 1 +danaglennsmith.com, 1 +danajamin.com, 1 +danalina.by, 1 +danalytics.com.pe, 1 +danamica.dk, 1 +danandrum.com, 1 +danangcitytours.com, 1 +danarozmarin.com, 1 +danashamsters.tk, 1 +danbaldwinart.com, 1 +danbarrett.com.au, 0 +danbergen.com, 1 +danca.com, 1 +dance-colleges.com, 1 +dance-school.tk, 1 +dancefm.tk, 1 +danceonline.fi, 1 +danceproducciones.com, 1 +dancesafe.org, 1 +danchen.org, 1 +danchestertonphoto.co.uk, 1 +dancingcubs.co.uk, 1 +dandan101.com, 1 +dandelikaliadventure.com, 1 +dandenongroadapartments.com.au, 1 +dandia.ro, 1 +dandymodz.tk, 1 +dandymrsb.com, 1 +daneiakartes.info, 1 +danel.ski, 1 +danelska.pl, 1 +danelski.pl, 1 +danesara.com, 1 +danfromit.co.uk, 1 +danfromit.com, 1 +dang-designs.com, 1 +dangeredwolf.com, 1 +dangerscience.com, 1 +dangmai.tk, 1 +dangr.zone, 1 +danhalliday.com, 1 +danholloway.online, 1 +danhotels.co.il, 1 +danhotels.com, 1 +dania.gq, 1 +dania.ml, 1 +daniel-ayala.tk, 1 +daniel-baumann.ch, 1 +daniel-cholewa.de, 1 +daniel-leblanc.tk, 1 +daniel-milnes.co.uk, 1 +daniel-milnes.uk, 1 +daniel-ruf.de, 1 +daniel-san.de, 1 +daniel-stahl.net, 1 +daniel-wildhaber.ch, 1 +daniel.sb, 1 +danielacocco.it, 1 +danieladentista.com, 1 +danielaeichberger.com, 1 +danielaferpe.tk, 1 +danielalvarez.net, 1 +danielas.boutique, 1 +danielbankhead.com, 1 +danieldavies.co.uk, 1 +danieldevine.tk, 1 +danieldrozdik.cz, 1 +danielduran.tk, 1 +daniele.tech, 1 +danielehniss.de, 0 +danieleluttazzi.tk, 1 +danieleoneta.it, 1 +danielepestilli.com, 1 +danielesalatti.com, 1 +danielgaughan.com, 1 +danielgorr.de, 1 +danielgray.email, 1 +danielgray.me, 1 +danielgraziano.ca, 1 +danielhammond.tk, 1 +danielheal.net, 0 +danielhinterlechner.eu, 1 +danielhurley.com, 1 +danielhurley.eu, 1 +danielhurley.ie, 1 +danielhurley.info, 1 +danielhurley.org, 1 +danieliancu.com, 1 +danielittlewood.xyz, 1 +danielives.co.uk, 1 +danieljamesscott.org, 1 +danieljstevens.com, 1 +danielkanchev.com, 1 +danielkeppler.com, 1 +danielkoster.nl, 1 +daniellecavazos.com, 1 +danielleskosky.com, 1 +danielluisrodriguezs.com, 1 +danielmartin.de, 1 +danielmiessler.com, 1 +danielmoch.com, 1 +danielmorales917.com, 1 +danielmorell.com, 1 +danielnaaman.net, 1 +danielnaaman.org, 1 +danielparker.com.au, 1 +danielpeukert.cz, 1 +danielran.com, 1 +danielrozenberg.com, 1 +danielsblog.org, 1 +danielsfirm.com, 1 +danielshaw.co.nz, 1 +danielsinsuranceinc.com, 1 +danielstach.cz, 1 +danielsteiner.net, 1 +danielstiner.me, 1 +danielt.co.uk, 0 +danielthompson.info, 1 +danielve.ga, 1 +danielverlaan.nl, 1 +danielwellington.com, 1 +danielwelty.com, 1 +danielwildhaber.ch, 1 +danielzuzevich.com, 1 +danifabi.eu, 1 +danilapisarev.com, 1 +danilov-abrosimov.org.ua, 1 +danish.cf, 1 +danispage.tk, 1 +danituuu7.tk, 1 +daniweb.com, 1 +danjesensky.com, 1 +dank.ninja, 1 +dankim.de, 0 +dankredues.com, 1 +danla.nl, 1 +danmaby.com, 1 +danmarksbedstefredagsbar.dk, 1 +danmassarano.com, 1 +danminkevitch.com, 0 +danna-salary.com, 1 +danndorf.com, 0 +dannemora.tk, 1 +dannhanks.com, 1 +dannicholas.net, 1 +danniellealbrechtdesigns.com, 1 +danny-tittel.de, 1 +danny.fm, 1 +dannycairns.com, 1 +dannycavanagh.tk, 1 +dannygaidateraelgar.com, 1 +dannyjota.tk, 1 +dannyoficial.tk, 1 +dannyrohde.de, 1 +dannys.cloud, 1 +dannys.space, 1 +dannyscloud.tk, 1 +dannystevens.co.uk, 1 +dannytemming.tk, 1 +dannywall.com.au, 1 +danoji.cf, 1 +danonsecurity.com, 1 +danotage.tv, 1 +danovamix.com.br, 1 +danoz.net, 1 +danpiel.net, 1 +danq.me, 1 +danrl.de, 1 +dansa.com.co, 1 +dansaunders.me, 1 +dansdiscounttools.com, 1 +dansedesalonsaintave.fr, 1 +danselibre.net, 1 +danselibre.org, 1 +danseressen.nl, 1 +dansk8bit.dk, 1 +danskefilm.dk, 1 +danskoya.com, 1 +danslan.org, 1 +danstillman.com, 1 +danstoncu.be, 1 +dantana.de, 1 +dantelistan.com, 1 +dantesinferno.tk, 1 +dantransports.fr, 1 +danusyakti.com, 1 +danux.co.uk, 1 +danw.io, 1 +danwaibel.com, 1 +danwelty.co, 1 +danwelty.me, 1 +danwelty.net, 1 +danwelty.org, 1 +danwillenberg.com, 1 +danwin1210.me, 1 +danwise.online, 1 +danwolff.se, 1 +danyabanya.com, 1 +danzac.com, 1 +danzantebay.com, 1 +danzavila.com, 1 +danzka.tk, 1 +dao.spb.su, 1 +daofficers.com, 1 +daop.co.uk, 1 +daoplattunhien.com.vn, 1 +daoro.net, 0 +daoudi.it, 1 +daphne.informatik.uni-freiburg.de, 1 +daphnes-restaurant.co.uk, 1 +dapoxetinagenerico.cf, 1 +dapoxetine.gq, 1 +dapperdom.net, 1 +dapps.earth, 1 +dappui.com, 1 +dappworld.com, 1 +daprint.tk, 1 +daracokorilo.com, 1 +darador.net, 1 +darani.ch, 1 +daravk.ch, 1 +darbi.org, 1 +darc-mak.de, 1 +darchoods.net, 0 +darci.tech, 1 +darcyinspired.com, 1 +darcymarshall.com, 1 +dare.deals, 1 +darenet.org, 1 +daretogain.com, 1 +dareyou.be, 1 +darf.nl, 1 +darfurwall.org, 1 +dariaburger.de, 1 +daridarkom.fr, 1 +darioackermann.ch, 0 +darioclip.com, 1 +dariosirangelo.me, 1 +darioturchetti.me, 1 +dark-ages.tk, 1 +dark-archive.com, 1 +dark-crystal.tk, 1 +dark-infection.de, 1 +dark-lake.com, 1 +dark-legion.tk, 1 +dark-nova.me, 1 +dark-nova.tk, 1 +dark-programs.com, 1 +dark-vision.cz, 1 +dark.fail, 1 +dark.ninja, 1 +darkag.ovh, 1 +darkartstudios.tk, 1 +darkcards.xyz, 1 +darkcelebration.tk, 1 +darkcores.net, 1 +darkct.com, 1 +darkcure.tk, 1 +darkdestiny.ch, 1 +darkengine.io, 1 +darkengine.net, 1 +darkenluster.space, 1 +darkerlystormy.com, 0 +darkerstormy.com, 0 +darkestproductions.net, 1 +darkeststar.org, 1 +darkfilm.tk, 1 +darkfire.ch, 1 +darkfirestudios.tk, 1 +darkforceofhappiness.tk, 1 +darkgames.cf, 1 +darkgrid.eu, 1 +darkhall.tk, 1 +darkhunter.eu, 1 +darkishgreen.com, 1 +darkknights.tk, 1 +darklang.com, 1 +darklaunch.com, 1 +darkleia.com, 1 +darklite.ml, 1 +darkmail.cf, 1 +darkmanthra.tk, 1 +darkmemo.com, 1 +darkmilknyeremeny.hu, 1 +darknessflickers.com, 0 +darknessinme.tk, 1 +darknetlive.com, 1 +darknight.blog, 1 +darkoff.tk, 1 +darkovepredmety.cz, 1 +darkpassionsite.tk, 1 +darkperu.tk, 1 +darkrisks.com, 1 +darksecret.dk, 1 +darkserver.fedoraproject.org, 1 +darkserver.stg.fedoraproject.org, 1 +darkshop.nl, 1 +darksideprod.tk, 1 +darksignsgame.tk, 1 +darkskymap.com, 1 +darkspacelab.com, 1 +darktechnology.tk, 1 +darkthreat.ai, 1 +darktime.ru, 1 +darkvape.net, 1 +darkwater.info, 1 +darkweb.wtf, 1 +darkwebkittens.xyz, 0 +darkx.me, 1 +darlehen-ratgeber.de, 1 +darlene.hu, 1 +darlo.co.uk, 0 +darnashop.fr, 1 +darom.jp, 1 +darpa.mil, 1 +darraghbr.co.uk, 1 +darrenellis.xyz, 1 +darrenlines.uk, 1 +darrenm.net, 1 +dart-tanke.com, 1 +dart-tanke.de, 1 +dartcarrousel.tk, 1 +dartcode.org, 0 +dartdriving.com, 1 +dartetdemetiers.fr, 1 +darth-sonic.de, 1 +dartmold.com, 1 +dartnallministorage.com, 1 +dartydiscount.fr, 1 +darululum.ga, 1 +darwinkel.net, 1 +darwinsearch.org, 1 +darxx.com, 1 +daryl-wilcher.tk, 1 +daryl.moe, 1 +darylcrouse.com, 1 +darylcumbo.net, 1 +das-clanpage.tk, 1 +das-forum24.de, 1 +das-mediale-haus.de, 1 +das-quiz-plugin.com, 1 +das-sommercamp.de, 1 +dasgeestig.nl, 1 +dashadmit123.com, 1 +dashboard.gov.ph, 1 +dashboard.run, 1 +dashboardph.com, 1 +dashboardphilippines.com, 1 +dashice.com, 1 +dashlane.com, 1 +dashnearby.com, 1 +dashofmedia.com, 1 +dashofting.com, 1 +dashwebconsulting.com, 1 +dasignsource.com, 1 +dasinternetluegt.at, 1 +daskirschhaus.com, 1 +dasolindustrialpark.tk, 1 +dassolutions.eu, 1 +dastannevis.com, 1 +daste2kala.ir, 1 +dasteichwerk.at, 0 +dastelefonbuch.de, 1 +dasug.de, 1 +dat4u.de, 1 +data-access-point.com, 1 +data-captive.com, 1 +data-detox.de, 1 +data-jt.de, 1 +data-loader.com, 1 +data-mail.tk, 1 +data-mining.co.uk, 1 +data-reader.de, 1 +data-replicator.cloud, 1 +data-replicator.com, 1 +data-wing.ga, 0 +data.bayern, 1 +data.gov, 1 +data.govt.nz, 1 +data.haus, 1 +data.world, 1 +data3w.nl, 1 +database-excel-integration.com, 1 +database-word-integration.com, 1 +databasedrivers.cloud, 1 +databasez.net, 1 +databeam.de, 1 +databionix.com, 1 +databiz.ga, 1 +datablender.nl, 1 +databricks.com, 1 +databutlr.com, 1 +databutlr.net, 1 +datacalle.com, 1 +datacandy.com, 1 +datacaptive.com, 1 +datacave.is, 1 +datacenterbrasil.ga, 1 +datacenternews.asia, 1 +datacenternews.co.nz, 1 +datacenternews.us, 1 +datacentrenews.eu, 1 +datacommissioner.gov.au, 1 +datacool.tk, 1 +datadit.hu, 1 +datadorf.de, 1 +datadraugen.no, 1 +datadyne.technology, 1 +datafarms.com, 1 +datafd.com, 0 +datafd.net, 0 +datafix.fi, 1 +datagate.com.br, 1 +datagir.ir, 0 +datagrail.io, 1 +datagrid.ga, 1 +dataguru.lv, 1 +dataharvest.at, 1 +datahive360.com, 1 +datahjalp.nu, 1 +datahoarder.xyz, 1 +datahove.no, 0 +datakick.org, 1 +datakl.com, 1 +datalife.gr, 1 +datalysis.ch, 0 +dataman.ml, 1 +datamatic.ru, 1 +datanexa.com, 1 +dataprivacyandsecurityinsider.com, 1 +dataprivacysolution.com, 1 +dataproulx.com, 1 +datapun.ch, 1 +dataregister.info, 1 +datasat.solutions, 1 +datascience.cafe, 1 +datascience.ch, 0 +datascientest.com, 1 +dataspace.pl, 1 +datastream.org, 1 +datastream.re, 0 +datastudio.google.com, 1 +datasubject.com, 1 +datasubjects.com, 1 +datasupport-stockholm.se, 1 +datasupport.one, 1 +dataswamp.org, 1 +datatekniikka.fi, 0 +datatekniker.nu, 1 +datateknologsektionen.se, 0 +datatree.nl, 1 +datatruckers.com, 1 +datatruckers.email, 1 +datatruckers.eu, 1 +datatruckers.net, 1 +datatruckers.nl, 1 +datatruckers.org, 1 +datatube.tk, 1 +datatypes.net, 1 +datavizable.org, 1 +datax-cloud.de, 1 +datazoo.com, 1 +date-chi.world, 1 +date-hijri.net, 1 +datecougarslocal.com, 1 +dateien.at, 1 +datelligent.com, 1 +datememe.com, 1 +datenbitch.org, 1 +datenendlager.org, 1 +datengrab.ws, 1 +datengrab.xyz, 1 +datenkeks.de, 1 +dateno1.com, 1 +datenreiter.cf, 1 +datenreiter.gq, 1 +datenreiter.org, 1 +datenschutz-consult.de, 1 +datenschutz-gruenwald.de, 1 +datenschutz-individuell.de, 1 +datenschutz-isny.de, 1 +datenschutz-leutkirch.de, 1 +datenschutz-luebbecke.de, 1 +datenschutz-oberschwaben.de, 1 +datenschutz-ravensburg.de, 1 +datenschutz-recht-medizin.de, 1 +datenschutz-wangen.de, 1 +datenschutz-weingarten.de, 1 +datenschutzgrundverordnung.de, 1 +datenschutztag.org, 1 +datenschutzzentrum.de, 1 +datenwerkstatt.net, 1 +datessrit.tk, 1 +datewon.net, 1 +dating.wedding, 1 +datingadvice.gq, 1 +datingandrelationshipsuccess.com, 1 +datingfakecheck.com, 1 +datinglocalgirls.com, 1 +datingonlinecheck.com, 1 +datingsite.ml, 1 +datingso.com, 1 +datingsrit.tk, 1 +datingticino.ch, 0 +datingyourmate.ga, 1 +datisstom.nl, 1 +datmancrm.com, 1 +datnenhamiltongarden.com, 1 +datometry.com, 1 +dator-test.se, 1 +datorb.com, 1 +datorhjalp-stockholm.se, 1 +datorhjalptaby.se, 1 +datorservice-stockholm.se, 1 +datosfreak.tk, 1 +datovyaudit.cz, 1 +datumou-osusume.com, 1 +datumplus.co.uk, 1 +datumstudio.jp, 1 +datutoday.tk, 1 +datutorials.tk, 1 +daubecity.de, 1 +daubehosting.de, 1 +daum-group.de, 1 +daunatotala.ro, 1 +dav.com.au, 1 +davalochki.tk, 1 +davangarte.com, 1 +dave-pearce.com, 1 +davecardwell.com, 1 +davedevries.nl, 1 +daveedave.de, 0 +davefuller.com.au, 1 +davelage.com, 1 +daveoc64.co.uk, 1 +daveops.net, 1 +davepage.me.uk, 1 +davepearce.com, 1 +davepermen.net, 1 +davepullig.co.uk, 1 +daveroverts.nl, 1 +davescomputertips.com, 1 +davesharpe.com, 1 +davesinclair.com.au, 1 +davetempleton.com, 1 +davethom.net, 1 +davevelopment.net, 1 +davewardle.com, 1 +daveyconstructions.com, 1 +david-clarke.id.au, 1 +david-corry.com, 1 +david-edu.com, 1 +david-hinschberger.me, 1 +david-jeffery.co.uk, 1 +david-merkel.de, 1 +david-osipov.me, 1 +david-osipov.vision, 1 +david-pearce.com, 1 +david-reess.de, 1 +david-schiffmann.de, 1 +david.kitchen, 1 +davidadrian.org, 1 +davidandersson.se, 1 +davidandrewcoaching.com, 1 +davidband.com.au, 1 +davidbranco.me, 1 +davidbrito.tech, 1 +davidbrookes.me, 0 +davidbyrne.tk, 1 +davidelstob.com, 1 +davideonlain.tk, 1 +davidereinato.tk, 1 +davidetmagali.fr, 1 +davidfetveit.com, 1 +davidfindlay.org, 1 +davidforward.net, 1 +davidfrancoeur.com, 0 +davidgouveia.net, 1 +davidgow.net, 1 +davidgreig.uk, 1 +davidgroup.co.id, 1 +davidgrudl.com, 1 +davidhanle.com, 1 +davidje13.com, 1 +davidjusto.com, 1 +davidkeane.com, 1 +davidkennardphotography.com, 1 +davidking.xyz, 1 +davidlamprea.eu, 1 +davidlane.io, 0 +davidlillo.com, 1 +davidlindekilde.dk, 1 +davidlyness.com, 1 +davidmcevoy.org.uk, 1 +davidmessenger.co.uk, 1 +davidmlujan.com, 1 +davidmn.org, 1 +davidmocq.com, 1 +davidnadaski.com, 1 +davidops.com, 0 +davidovskakreu.tk, 1 +davidpearce.com, 1 +davidpearce.org, 1 +davidpescarolo.it, 1 +davids.online, 1 +davidschadlich.com, 1 +davidscherzer.at, 1 +davidschlachter.com, 1 +davidsimner.me.uk, 1 +davidskinnerantiques.com, 0 +davidsopas.com, 1 +davidstuff.net, 1 +davidtiffany.com, 1 +davidvilla.tk, 1 +davidzarza.tk, 1 +davidzeegers.nl, 1 +davidzimmerman3.com, 1 +davimun.org, 1 +davinamccall.tk, 1 +davisdieselandautorepair.com, 1 +davmimer-mercerie.ro, 1 +davo-usedcars.be, 0 +davros.eu, 1 +davros.ru, 1 +davusito.com, 1 +davy-server.com, 1 +davyatletiek.tk, 1 +davyjones.com.br, 1 +davypropper.com, 1 +davys.com.br, 1 +dawgs.ga, 1 +dawidpotocki.com, 1 +dawnbringer.eu, 1 +dawnbringer.net, 1 +dawnofeden.net, 1 +dawnofhope.tk, 1 +dawnson.is, 1 +dawoud.org, 1 +dawrimiz.com, 1 +dawson-floridavilla.co.uk, 1 +dax.guide, 1 +daxenexpress.com, 1 +daxici.com.tr, 1 +daxpatterns.com, 1 +daxperience.eu, 1 +daxrunbase.com, 1 +daycontactlens.com, 1 +daycubrem.com, 1 +daydream.team, 1 +daygametraining.com, 1 +daylightpirates.org, 1 +dayman.net, 1 +daymantrust.com, 1 +daymarksi.com, 1 +daymprove.life, 1 +daynia.net, 1 +dayofdays.be, 1 +dayofthegirl.gc.ca, 1 +days.one, 1 +daysgolfclub.net, 1 +daysnews.tk, 1 +daysoftheyear.com, 1 +dayswithnostabbings.ca, 1 +daytonahealthsolutions.com, 1 +dayuse-hotels.it, 1 +dayuse.co.uk, 1 +dayuse.com, 1 +dayuse.cz, 1 +dayuse.es, 1 +dayuse.fr, 1 +dayuse.pt, 1 +dayuse.se, 1 +dazenelevator.ph, 1 +dazz.it, 1 +dazzit.ca, 1 +dazzit.com, 1 +dazzit.io, 1 +dazzit.net, 1 +dazzit.org, 1 +dazzit.xyz, 1 +dazzlestart.com, 1 +db-sanity.com, 1 +db-works.nl, 1 +db.ci, 1 +db.fyi, 1 +dbapress.org, 1 +dbaron.org, 1 +dbas.cz, 1 +dbase.cf, 1 +dbb.wtf, 1 +dbcartography.com, 1 +dbdc.co.za, 1 +dbentertainment.co.uk, 1 +dbgamestudio.com, 1 +dbic.ro, 1 +dbjc.tk, 1 +dblcastles.co.uk, 1 +dbldub.net, 1 +dblfree.com, 1 +dblx.io, 1 +dbmiller.org, 1 +dbnext.de, 1 +dborcard.com, 0 +dbox.ga, 1 +dbplanview.com, 1 +dbq.com, 1 +dbradley771.com, 1 +dbrand.com, 1 +dbrgn.ch, 1 +dbs.cl, 1 +dbsbeautystore.cl, 1 +dbtotalnet.tk, 1 +dbtsai.com, 0 +dbw678.com, 1 +dc-acupuncture.com, 0 +dc-design.tk, 1 +dc-elektro.com, 1 +dc-elektro.de, 1 +dc-elektro.eu, 1 +dc-occasies.be, 0 +dc-service.by, 1 +dc-solution.de, 0 +dc-texas.com, 1 +dc562.org, 1 +dc585.info, 1 +dc9.me, 1 +dcain.me, 1 +dcards.in.th, 1 +dcareer.tk, 1 +dcarou.com, 1 +dcave.net, 1 +dcbouncycastles.co.uk, 1 +dcbreastenlargement.com, 1 +dcc.cat, 1 +dccomputerrepair.com, 1 +dccwiki.com, 1 +dcdestetica.it, 1 +dcdn.lt, 1 +dcepler.net, 1 +dchatelain.ch, 0 +dchest.org, 1 +dcimpianti.it, 1 +dckd.nl, 1 +dcl.re, 1 +dclaisse.fr, 1 +dclmwp.com, 1 +dcmarvelunited.com, 1 +dcmediahosting.com, 1 +dcmt.co, 1 +dcnews.ro, 1 +dcomedieta.it, 1 +dcorporation.org, 1 +dcpower.eu, 1 +dcrdev.com, 1 +dctrl.ch, 1 +dcw.io, 1 +dcyph.de, 1 +dd-groupinc.com, 1 +dd.art.pl, 1 +dd.center, 1 +dd00228.com, 1 +dd118d.com, 1 +dd11d.net, 1 +dd202d.com, 1 +dd207d.com, 1 +dd215d.com, 1 +dd33d.net, 1 +dd44d.net, 1 +dd5197.co, 1 +dd6729.co, 1 +dd6729.com, 1 +dd6957.co, 1 +dd9297.co, 1 +dd9397.com, 1 +dd9721.com, 1 +dd9728.co, 1 +ddatsh.com, 1 +ddays2008.org, 1 +ddcakedeliveryservice.co.uk, 1 +dddmelbourne.com, 1 +ddel.de, 1 +dden.ca, 0 +dden.website, 1 +ddepot.us, 1 +dderyce.com, 1 +ddi.one, 1 +ddjia.com, 0 +ddjlawtampa.com, 1 +ddk.dn.ua, 1 +ddkkitchens.com, 1 +ddlcmods.com, 1 +ddmeportal.com, 1 +ddns-anbieter.de, 1 +ddns-test.de, 1 +ddnsweb.com, 0 +ddos-mitigation.co.uk, 1 +ddos-mitigation.info, 1 +ddosguard.cf, 1 +ddosolitary.org, 1 +ddproxy.cf, 1 +ddr.gmbh, 1 +ddracepro.net, 1 +dds.mil, 0 +dds.pe, 1 +ddsmatchsouthwest.com, 1 +ddy.tw, 1 +de-basiliek.tk, 1 +de-google-ify.org, 1 +de-groot.it, 1 +de-gucci.com, 1 +de-kramers.nl, 1 +de-medici.nl, 1 +de-mossadeq.tk, 1 +de-osopanda.com, 1 +de-rwa.de, 1 +de-servers.de, 1 +de-spil.be, 1 +de.gt, 1 +de.ls, 1 +de.md, 1 +de.search.yahoo.com, 0 +de.vg, 1 +dead-letter.email, 1 +deadbeef.ninja, 1 +deadboyskilling.tk, 1 +deadc0de.re, 1 +deadhead.tk, 1 +deadlockcoaching.com, 1 +deadmann.com, 1 +deadmorose.ru, 1 +deadpoolonline.ga, 1 +deadpulse.com, 1 +deadpvp.eu, 1 +deadroot.tk, 1 +deadsea.tk, 1 +deadshortaudio.com, 1 +deadspin.com, 1 +deaf.dating, 1 +deaf.eu.org, 1 +deafsound.tk, 1 +deai-life.biz, 1 +deaktualisierung.org, 0 +deal-runners.cf, 1 +deal45.ga, 1 +dealapp.nl, 1 +dealbanana.com, 1 +dealbanana.no, 1 +dealbenzbkk.com, 1 +dealbx.com, 1 +dealcruiser.nl, 1 +dealdelicate.com, 1 +dealdump.nl, 1 +dealerselectric.com, 1 +dealerwriter.com, 1 +dealinflatables.co.uk, 1 +dealosa.com, 1 +dealproject.org.au, 1 +dealroom.co, 1 +dealsammler.de, 1 +dealsbythebay.com, 1 +dealsemperor.com, 1 +dealsfromheaven.com, 1 +dealspotr.com, 1 +dealstream.com, 1 +dealstreet.fr, 1 +dealwithstatistics.com, 1 +deamonmail.tk, 1 +deamsterdam.ml, 1 +deamuseum.org, 1 +deanandnatalia.co.za, 1 +deanbank.com, 1 +deanconsultancy.co.uk, 1 +deane.li, 1 +deanjerkovich.com, 1 +deano-s.co.uk, 1 +deanosplace.net, 1 +deanpearce.me, 1 +deanpearce.net, 1 +deantiguos.es, 1 +dear-children.ga, 1 +dearktiel.nl, 1 +dearnevalleybouncycastles.co.uk, 1 +deasyvow.com, 1 +death-note.tk, 1 +death.social, 1 +deathberry.ddns.net, 1 +deathcult.fun, 1 +deathlords.tk, 1 +deathofspring.com, 0 +deathorglory.cc, 1 +deathrockstar.tk, 1 +deathsdomain.com, 1 +deathwar.tk, 1 +deathwarrior.tk, 1 +deathy.ro, 1 +deavel.com, 1 +deavel.fr, 1 +deavel.net, 1 +deavon.tk, 1 +debarkader34.tk, 1 +debarras-diogene.paris, 1 +debarrasantony.com, 1 +debarrasasnieressurseine.com, 1 +debarrasboulognebillancourt.com, 1 +debarrasclichy.com, 1 +debarrascolombes.com, 1 +debarrasnanterre.com, 1 +debatereport.com, 1 +debats.tk, 1 +debattinnlegg.no, 1 +debauchery.ml, 1 +debbyefurd.com, 1 +debeer.tech, 1 +debie-usedcars.be, 0 +debierhandel.nl, 1 +debigare.com, 1 +debijloke.be, 1 +debijloke.gent, 1 +debitterballetjes.tk, 1 +deblocking.ga, 1 +debora-singkreis.de, 1 +debora.com.au, 1 +deborahmarinelli.eu, 1 +debostero.tk, 1 +deboutpourlemali.ml, 1 +debraydesign.com.au, 1 +debrusoft.ch, 1 +debtrecycling.com.au, 1 +debuemon.com, 1 +debuis.nl, 1 +debut-mebel.ru, 1 +debzsh.tk, 1 +dec-ced.gc.ca, 1 +dec6.gc.ca, 1 +decadentdvices.com, 1 +decal-times.com, 1 +decalquai.ch, 0 +decarrouseloss.nl, 1 +decathlon.com.co, 1 +decaturcountyiowa.gov, 1 +decaturwomensports.com, 1 +decay24.de, 0 +dechat.nl, 1 +dechetor.fr, 1 +decibelnewmusic.com, 1 +decidetreatment.org, 1 +decidio.cc, 1 +decimatechnologies.eu, 1 +decimation.tk, 1 +decipe.com, 1 +decis.fr, 1 +decisionssometimes.ml, 1 +decisiontime.online, 0 +decisivetactics.com, 1 +deck.academy, 1 +deckersheaven.com, 1 +declarativ.ga, 1 +declivitas.com, 1 +deco-parisienne.fr, 1 +decoating.pl, 1 +decock-usedcars.be, 0 +decode.ga, 1 +decodeanddestroy.com, 1 +decohome.ee, 1 +decompiled.de, 1 +deconstructind.ro, 1 +decoora.com, 1 +decor-d.com, 1 +decor-live.ru, 1 +decor-prazdnik.ru, 1 +decorarei.com, 1 +decorarmicasa.com, 1 +decoratingadvice.co.uk, 1 +decorations-elmotamaiz.com, 1 +decorativeconcretewa.com.au, 1 +decorativecosmetics.tk, 1 +decorativeflooring.com, 1 +decorator.uk, 1 +decoratore.roma.it, 1 +decorestilo.com.br, 1 +decorincasa.com.br, 1 +decormiernissanparts.com, 1 +decorotti.com.tr, 1 +decorpol-renovation.fr, 1 +decorsolucionesgraficas.es, 1 +decorumcomics.com, 1 +decosoftware.com, 1 +decrousaz-ceramique.ch, 0 +decrypt.co, 1 +decrypto.net, 1 +decs.es, 1 +decsys.work, 1 +dedelta.net, 1 +dedetizacaoinsetan.com.br, 1 +dedg3.com, 1 +dedge.org, 1 +dedicatedservers.cf, 1 +dedicatedtowomenobgyn.com, 1 +dedirten.com, 1 +dedmoroz.ga, 1 +dedmoroz.gq, 1 +dedmorozrzn.ru, 0 +dedoho.pw, 1 +dedoles.at, 1 +dedoles.com, 1 +dedoles.cz, 1 +dedoles.de, 1 +dedoles.hu, 1 +dedoles.pl, 1 +dedoles.ro, 1 +dedoles.sk, 1 +deduijventil.nl, 1 +dedyk.gq, 1 +dee.pe, 1 +dee.su, 1 +deechtebakkers.nl, 1 +deedyinc.com, 1 +deegeeinflatables.co.uk, 1 +deejayevents.ro, 0 +deejayladen.de, 1 +deelmijnreis.nl, 1 +deelodge.art, 0 +deemasfashion.co.uk, 1 +deemasfashion.com, 1 +deemasfashion.com.au, 1 +deemlove.com, 1 +deenergiecentrale.be, 1 +deenergiecentrale.gent, 1 +deeonix.eu, 1 +deep-chess.com, 0 +deep-labs.com, 1 +deep.club, 1 +deepaero.com, 1 +deeparamaraj.com, 1 +deepbluecrafting.co.uk, 1 +deepblueemail.com, 1 +deepcode.io, 1 +deepcreampie.com, 1 +deephill.com, 1 +deepinnov.com, 1 +deepinsight.io, 1 +deepl.xyz, 1 +deeplink-medical.com, 1 +deepnet.cc, 1 +deeps.cat, 1 +deeps.me, 1 +deepserve.info, 1 +deepsky.tk, 1 +deepsoulutions.cf, 1 +deepspace.dedyn.io, 1 +deepu-mathew.tk, 1 +deepumathew.tk, 1 +deepvalley.tech, 1 +deepwoodshop.com, 1 +deerfieldapartmentsstl.com, 1 +deerwoodrvpark.com, 1 +deesylab.com, 0 +deezeno.com, 1 +def-pos.ru, 1 +defamiliehagen.com, 1 +defaultisafault.com, 1 +defcon.org, 1 +defcongame.tk, 1 +defcongroups.org, 1 +defeestboek.nl, 1 +defektologiya.tk, 1 +defend2.org, 1 +defendas.com, 1 +defendbearbutte.org, 1 +defender-pro.com, 1 +defendinnovation.org, 1 +defendtheweb.net, 1 +defenestrazionedipra.ga, 1 +defenseweapon.tk, 1 +defensivefirearmsinstruction.org, 1 +defensoresunidos.tk, 1 +defero.io, 1 +defesaaereanaval.com.br, 1 +deffo.com.au, 0 +defi-metier.org, 1 +defiant.com, 1 +defiantrust.com, 1 +defietsambassade.be, 1 +defietsambassade.gent, 1 +defietsambassadegent.be, 1 +defifa.ga, 1 +defile.ml, 1 +defimetier.fr, 1 +define-atheism.com, 1 +define-atheist.com, 1 +defineatheism.com, 1 +defineatheist.com, 1 +definingterms.com, 1 +definitely.cn, 0 +definitions360.com, 1 +definitivesynergy.com, 1 +defis-franciliens.fr, 1 +defiscalisation.ml, 1 +deflect.ca, 1 +deflumeri.com, 1 +deflumeriker.com, 1 +defme.eu, 1 +defont.nl, 1 +defreecefinancial.com, 1 +defreitas.no, 1 +deftek.com, 1 +defterikebir.tk, 1 +deftig-und-fein.de, 1 +deftnerd.com, 1 +defunct-engineers.ml, 1 +defuse.ca, 1 +defygaminguk.com, 1 +degeberg.com, 1 +degeberg.dk, 1 +degeeks.xyz, 1 +degen-elektrotechnik.de, 1 +degeneracy.xyz, 1 +degenerativediscdiseaseexplained.com, 1 +degentseflikkenzoekenu.be, 1 +degestamptepot.nl, 1 +degirmenkasi.tk, 1 +degit.de, 1 +degoeiewebsite.cf, 1 +degooglisons-internet.com, 1 +degooglisons-internet.fr, 1 +degooglisons-internet.org, 1 +degooglisons.org, 1 +degooglisonsinternet.org, 1 +degooglize.org, 1 +degoticapunk.xyz, 1 +degoulet.net, 1 +degraafschapdierenartsen.nl, 1 +degracetechnologie.com, 1 +degradarium.com, 1 +degrasboom.nl, 1 +degrasboom.org, 1 +degravel.net, 1 +degreeducation.tk, 1 +degressif.com, 1 +degroupage.info, 1 +dehaanadvocatenkantoor.nl, 1 +dehoga-reisen.de, 1 +dehopre.com, 1 +deiamodas.com.br, 1 +deidee.nl, 1 +deimist.ru, 1 +deimos.gq, 1 +dein-baumdienst.de, 1 +dein-trueffel.de, 1 +deinballon.de, 1 +deinelakaien.tk, 1 +deinfoto.ch, 1 +deinsparen24.de, 1 +deionized.ga, 1 +deitec-global.com, 1 +deitti.net, 1 +deja-lu.de, 1 +dejandayoff.com, 1 +dejavu.ml, 1 +dejected.ga, 1 +dejfcold.cz, 1 +dejongonline.eu, 1 +dejting-sidor.com, 1 +dejure.org, 0 +dejvsoft.pl, 1 +dekasegi-kansai.com, 1 +dekasegifuzoku.com, 1 +dekasiba.com, 1 +dekasseguiempregos.com, 1 +dekel.co.il, 0 +dekeurslagers.nl, 1 +dekko.io, 1 +dekonix.ru, 1 +dekoration.tk, 1 +dekulk.nl, 1 +del-ex.de, 1 +dela-django-app.herokuapp.com, 1 +delahrzolder.nl, 1 +delam.site, 1 +delawarehousebuyers.online, 1 +delawarenation-nsn.gov, 1 +delaydengy.tk, 1 +delaysoft.tk, 1 +delbecqvo.be, 0 +delcopa.gov, 1 +delduca.casa, 1 +deleenheir.be, 1 +delegao.moe, 1 +deleidscheflesch.nl, 1 +delete.cf, 1 +delfi.lt, 1 +delfic.org, 1 +delfinus.tk, 1 +delftstudy.nl, 1 +delhicleanairforum.tk, 1 +delhionlinegifts.com, 1 +deliacreates.com, 1 +deliandiver.org, 1 +deliberatedigital.com, 0 +delicale.com.br, 1 +delicatewonders.com, 1 +deliciascomercial.com, 1 +delicious.gq, 1 +deliciousmedia.co.uk, 1 +delicioustable.com, 1 +delicon.jp, 1 +delijan24.ir, 1 +delika.io, 1 +delikodu.com, 1 +delikom.de, 1 +delio.tk, 1 +delirecetas.com, 1 +delitto.top, 1 +deliverability.guru, 1 +delivereasy.tk, 1 +delivr.com, 1 +dellacasapizzasemassas.com.br, 1 +dellasano.com, 1 +dellipaoli.com, 1 +delogo.nl, 1 +deloittequant.com, 0 +delontewest.tk, 1 +delopt.co.in, 1 +delorenzi.dk, 1 +deloretta.com, 1 +delosgaia.nl, 1 +delpark.de, 1 +delphia.ai, 1 +delphia.com, 1 +delphibasics.tk, 1 +delphinarabic.tk, 1 +delphine.dance, 1 +delpilarrungue.cl, 1 +delta-data.ch, 1 +delta-games.tk, 1 +delta-host.ml, 1 +delta-smart.ch, 1 +delta-wings.net, 1 +delta.ru, 1 +delta8.one, 1 +deltabadger.com, 1 +deltacountymi.org, 1 +deltadentalmo.com, 1 +deltadentalsc.com, 1 +deltafinanceiro.com, 1 +deltafinanceiro.com.br, 0 +deltaloja.com.br, 1 +deltamusik.tk, 1 +deltanio.nl, 1 +deltaonlineguards.com, 1 +deltaphiepsilon.tk, 1 +deltaservers.blog.br, 1 +deltaservers.com.br, 1 +deltasigmachi.org, 1 +deltasigmaxi1971.tk, 1 +deltasuprimentos.com.br, 1 +deltav.ml, 1 +deltava.org, 1 +deltaworkssecurity.com, 1 +deltaworkssecurity.nl, 1 +deltna.com, 1 +deluxe-bot.tk, 1 +deluxe-dubai.com, 1 +deluxeblogtips.com, 1 +delvinoadegas.com.br, 1 +delycate.com, 1 +delzottolink.com, 1 +demaison.pro, 1 +demand.io, 1 +demandbase.com, 1 +demarit.fi, 1 +demarle.ch, 0 +demastglazenwasserij.nl, 1 +demedx.at, 1 +dementiacaring.com.au, 1 +dementiafactsexplained.com, 1 +dementiapraecox.de, 1 +dementieva-pennetta.tk, 1 +dementievriendelijk.gent, 1 +dementievriendelijkgent.be, 1 +demeraallergy.com, 1 +demes.tk, 1 +demesos.tk, 1 +demeyere-usedcars.be, 0 +demfloro.ru, 1 +demibaguette.com, 1 +demicon.biz, 1 +demicrofonos.com, 1 +demijn.nl, 1 +demilletech.net, 1 +demiranda.com, 1 +demirdokum.tk, 1 +demisch-tim.de, 1 +demischtim.de, 1 +demmer.one, 1 +demo-ferma.ga, 1 +demo-school.nl, 1 +demo.sb, 1 +demo.swedbank.se, 1 +demo9.ovh, 1 +democracy-news.tk, 1 +democracy.cf, 1 +democracychronicles.com, 1 +democracydirect.com, 1 +democracyineurope.eu, 1 +democraziaineuropa.eu, 1 +demodata.eu, 1 +demografia.tk, 1 +demokisisel.tk, 1 +demokrasi.tk, 1 +demolandia.net, 1 +demomanca.com, 1 +demonbuster.tk, 1 +demondms.com, 1 +demonforums.tk, 1 +demoniak.ch, 0 +demonicresurrection.tk, 1 +demonmassacre.tk, 1 +demonologyfieldguide.com, 1 +demontage.tk, 1 +demonwav.com, 1 +demonwithin.tk, 1 +demonwolfdev.com, 1 +demopanel.tk, 1 +demostweb.ga, 1 +demotivatorbi.ru, 1 +demoweb.pro, 1 +dempsters.ca, 0 +demsh.org, 1 +demuzere.be, 1 +demuzere.eu, 1 +demuzere.net, 1 +demuzere.org, 1 +demxausa.com, 1 +den.taxi, 1 +denabot.pw, 1 +denaehula.com, 1 +denahrumah.co, 1 +denali.net, 1 +denardbrewing.com, 1 +denariu.ddns.net, 1 +denarium.com, 1 +denatured.tk, 1 +denbkh.ru, 0 +dencel.lv, 1 +denchik.tk, 1 +dendisoftware.com, 0 +denegka-mgnovenno.cf, 1 +denegmnogo.tk, 1 +denejki.tk, 1 +dengg.name, 1 +dengidoma24.ml, 1 +dengisrazu.tk, 1 +dengivdolg.ml, 1 +dengivdolg.tk, 1 +dengivdom.tk, 1 +denhartogracing.com, 1 +denhotels.com, 1 +denika.com, 1 +denimtoday.com, 1 +denince.net, 1 +denis-martinez.photos, 1 +denisadinu.com, 1 +denisdimoski.tk, 1 +denisewakeman.com, 1 +denisglobal.com, 1 +denisgrandverger.de, 1 +denismusic.ga, 1 +denissalignat.fr, 1 +denissealatinsoul.com, 1 +denistruffaut.fr, 0 +denisyakovlev.ml, 1 +denisyan.ml, 1 +deniszczuk.pl, 1 +deniz.uk, 1 +denizdesign.co.uk, 1 +denizsartdiary.com, 1 +denizuydur.nl, 1 +denkeandersblog.de, 1 +denken-durchdenken.de, 1 +denkmalagentur.ch, 1 +denkmalsetzung.at, 1 +denkubator.de, 1 +denninger.jp, 1 +dennis-aumiller.de, 1 +dennisang.com, 1 +dennisdoes.net, 0 +dennisforbes.ca, 1 +dennishzg.com, 1 +denniskoot.nl, 1 +dennislicht.tk, 1 +dennismurphy.biz, 1 +dennisswiers.tk, 1 +dennistyfus.tk, 1 +dennisvandenbos.nl, 1 +dennmart.me, 1 +dennogumi.org, 1 +denous.nl, 1 +densmirnov.com, 1 +densocean.net, 1 +dent.uy, 1 +denta-ua.com, 1 +dentad.com.ua, 1 +dental-colleges.com, 1 +dental-reboot.com, 1 +dental.gq, 1 +dentalcareerfinder.com, 1 +dentalcolleges.tk, 1 +dentalgap.org, 1 +dentallaborgeraeteservice.de, 1 +dentaloptimizer.com, 1 +dentals.cf, 1 +dentalscams.org, 1 +dentaltalent.nl, 1 +dentalturism.com, 1 +dentechnica.co.uk, 1 +dented.gq, 1 +dentist-profi.ga, 1 +dentistaaroma.com, 1 +dentistalagoasanta.com.br, 1 +dentistesdarveauetrioux.com, 1 +dentistglasgow.com, 1 +dentistinbrooklyn.com, 1 +dentistsgainesvillega.com, 1 +dentistslilburnga.com, 1 +dentoncounty.gov, 1 +dentrassi.de, 1 +dentystabirmingham.co.uk, 1 +denuevestore.com, 1 +denugka-vezde.gq, 1 +denugka-vezde.tk, 1 +denunzieren.tk, 1 +denver-design.cf, 1 +denverbph.com, 1 +denverilluminations.com, 1 +denvernews.ml, 1 +denwauranailab.com, 1 +denydarko.tk, 1 +deonlineassistente.nl, 1 +deonlinedrogist.nl, 1 +deonlinespecialist.nl, 1 +deontology.com, 1 +depaco.com, 1 +depak.de, 1 +depannage-traceur.fr, 1 +depapboeren.tk, 1 +deparis.me, 1 +departmentofdefense.tk, 1 +departmentofoncology.com, 1 +departureboard.io, 1 +depeces.com, 1 +depeche.ga, 1 +depechemode-live.com, 1 +deped.io, 1 +depedcommons.org, 1 +depedsurigaodelnorte.com, 1 +depedtambayan.net, 1 +depedtayo.com, 1 +depedtayo.ph, 1 +depelos.co, 1 +depelteau.com, 1 +dependablehvacrefrigeration.com, 1 +deperewi.gov, 1 +depicus.com, 1 +depilacioncon.com, 1 +depilestil.es, 1 +depistage-bejune.ch, 1 +depleteduranium.tk, 1 +deplis.fr, 1 +deplorablesdaily.com, 1 +depone.net, 0 +depop.com, 1 +deportes.in, 1 +deportestalcahuano.tk, 1 +deportivo-pasto.tk, 1 +depositart.com, 1 +depositomerci.it, 1 +depositomobili.it, 1 +depot24.nl, 0 +depotsquarekerrville.com, 1 +depotter-usedcars.be, 0 +deprecate.de, 1 +deprobe.pro, 1 +depuratori.milano.it, 1 +dequemurio.com, 1 +der-bank-blog.de, 1 +der-fliesenzauberer.de, 1 +der-gardinenmann.de, 1 +der-lan.de, 1 +der-rohrstock.club, 1 +der-rudi.eu, 1 +derango.tk, 1 +derattizzazione.name, 1 +derattizzazioni.biz, 1 +derattizzazioni.milano.it, 1 +derattizzazioni.org, 1 +derbuntering.de, 1 +derbybouncycastles.com, 1 +derbyshire-language-scheme.co.uk, 1 +derbysound.com, 1 +derbyware.com, 1 +derchris.me, 1 +derdewereldrommelmarkt.nl, 1 +dereddingsklos.nl, 1 +dereferenced.net, 1 +derejilla.online, 1 +derekbooth.co.uk, 1 +derekheld.com, 1 +derekkent.com, 1 +derekseaman.com, 0 +derekseaman.studio, 0 +derenderkeks.me, 1 +derf.fr, 1 +derf.red, 1 +derf.us, 1 +derfritz.at, 1 +derguns.town, 1 +derhil.de, 1 +derinsular.tk, 1 +derival.co.za, 1 +derivativeshub.pro, 1 +derive.cf, 1 +derivedata.com, 1 +derk-jan.com, 0 +derkach.io, 1 +derkarl.tk, 1 +derkuki.de, 1 +dermacarecomplex.com, 1 +dermaldistinction.com, 1 +dermapaz.net, 1 +dermapuur.nl, 1 +dermato.floripa.br, 1 +dermatologie-morges.ch, 0 +dermax.tk, 1 +dermediq.nl, 1 +dermnet.ai, 1 +dermnetai.com, 1 +dermopigmentista.it, 1 +dermot.org.uk, 1 +dermscc.com, 1 +dermsf.com, 1 +dermu.ai, 1 +dermx.ai, 1 +deroo.org, 1 +derp.army, 1 +derp.chat, 1 +derpibooru.org, 1 +derpicdn.net, 1 +derpy.pp.ua, 1 +derre.fr, 1 +derreichesack.com, 1 +derrybasketball.tk, 1 +derseebestatter.com, 1 +dersimizmatematik.cf, 1 +dersoundhunter.de, 1 +derstulle.de, 1 +derw.pw, 1 +des-hommes-et-des-clous.com, 1 +desafiomovilidadsustentable.com, 1 +desagaz.com, 1 +desalas.org, 1 +desanctispro.com, 1 +desanta.top, 1 +desapego.com.br, 1 +desarrollando.web.ve, 1 +descargar-apk.org, 1 +descargarwhatsappplusgratis.net, 1 +descobrim.com, 1 +desconfiats.tk, 1 +desec.io, 1 +desentupidorademais.com.br, 1 +deseosvip.tk, 1 +desergo.com, 1 +desertbloomplasticsurgery.com, 0 +desertbluffs.com, 1 +desertedisland.name, 1 +desertfiredesigns.com, 1 +desertfury.tk, 1 +deserti.tk, 1 +desertlinealuminium.com, 1 +desertlinegroup.com, 1 +desertmedaesthetics.com, 1 +desertsounds.org, 1 +desgenst.ch, 1 +deshevle-net.com, 1 +deshobi.cloud, 1 +desiderantes.tk, 1 +design-in-bad.eu, 1 +design-production.jp, 1 +design-tooning.de, 1 +design-total.com, 1 +design-tricks.gq, 1 +design-your-life.info, 1 +design2u.eu, 1 +designanyware.com.br, 1 +designartepublicidad.com, 1 +designburners.com, 1 +designcanada.com, 1 +designconformitylibrary.com, 1 +designed-cybersecurity.com, 1 +designedcybersecurity.com, 1 +designeline.com, 1 +designepublicidade.com.br, 1 +designer-drug.com, 1 +designera.se, 1 +designerchad.com, 1 +designertrees.com.au, 1 +designgears.com, 1 +designgraphic.fr, 1 +designhuddle.com, 1 +designovus.com, 1 +designrhome.com, 1 +designs.codes, 1 +designsbyjanith.com, 1 +designschmiede-oberlausitz.de, 1 +designsite.tk, 1 +designskin.ch, 0 +designsociety.tk, 1 +designtrc.com, 1 +designville.cz, 1 +designville.sk, 1 +desimpelaere.eu, 1 +desinfectantemanos.org, 1 +desingslash.tk, 1 +desire-host.tk, 1 +desish.cf, 1 +desiskinscience.com, 0 +desivideos.tk, 1 +deskaservices.com, 1 +deskdesign.nl, 1 +deskeen.fr, 1 +desklite.gr, 1 +desktopd.eu.org, 0 +desktopfibra.com, 1 +desktopfx.net, 0 +deskture.com, 1 +deskvip.com, 0 +desmaakvanplanten.be, 1 +desmo.gg, 1 +desmu.fr, 1 +desonnemannen.tk, 1 +desormiers.com, 1 +despachomariscal.com, 1 +despachomartinyasociados.com, 1 +despacitobeer.com, 1 +desperate.solutions, 1 +desperatesailors.com, 1 +desperec.ddns.net, 1 +despertadoronline.com.es, 1 +despinavandi.gr, 1 +desplats.com.ar, 1 +despora.de, 1 +despotika.de, 1 +dessinemoilademocratie.ch, 0 +dest-gottskar-nidingen.se, 1 +destakbrasilbrindes.com.br, 1 +destech.nl, 1 +desteniiprocess.com, 1 +desterman.ru, 1 +desterproducts.nl, 1 +desterrada.tk, 1 +destileria.net.br, 1 +destinattorneyjohngreene.com, 1 +destiney-arkaden.de, 1 +destinfloor.com, 1 +destinyofthephoenix.me, 0 +destom.be, 1 +destroymc.net, 1 +destroysilence.cf, 1 +destructive-revolution.tk, 1 +destyntek.com, 1 +desu.ne.jp, 1 +desuchan.eu, 1 +desuchan.org, 1 +desucla.com, 1 +desveja.com.br, 1 +deswaffelaars.tk, 1 +desyatnichenko.ml, 1 +desynced.rocks, 1 +det-te.ch, 1 +detalhecomercio.com.br, 1 +detali-if.com, 1 +detalika.ru, 1 +detalyedesigngroup.com, 1 +detao.org, 1 +detc.tk, 1 +detdom.tk, 1 +detecmon.com, 1 +detecte-fuite.ch, 0 +detecte.ch, 0 +detectefuite.ch, 0 +detectify.com, 1 +detectivedesk.com.au, 1 +detectro.cc, 1 +deteken.be, 1 +detekenmuze.nl, 1 +detenterprise.com, 1 +determapp.de, 1 +dethemium.com, 1 +deti-online.com, 1 +deti-vse.ml, 1 +deti.ga, 1 +detiklife.com, 1 +detiks.cf, 1 +detki.cf, 1 +detki24.ru, 1 +detodojuegos.com, 1 +detoxic.vn, 1 +detoxtorehab.com, 1 +detrapdoor.com, 1 +detreannamaria.tk, 1 +detroit-english.de, 1 +detroitjockcity.com, 1 +detroitlocksmiths.net, 1 +detroitnews.tk, 1 +detroitzoo.org, 1 +detsad.ml, 1 +detsad.tk, 1 +detski.center, 1 +detskie-avto-kresla.tk, 1 +detskysad.com, 1 +detuinmuze.nl, 1 +detulado.com, 1 +detusmascotas.com, 1 +detyamobuv.tk, 1 +detyobuv.tk, 1 +detype.nl, 1 +deu.sh, 1 +deuchnord.fr, 1 +deude.de, 1 +deurenfabriek.nl, 1 +deustech-media.tk, 1 +deustech.tk, 1 +deutsch-vietnamesisch-dolmetscher.com, 1 +deutsche-seniorenbetreuung.de, 1 +deutsche-tageszeitungen.de, 1 +deutschebusiness.com, 1 +deutschemilf.online, 1 +deutscher-bericht.de, 1 +deutscher-rollenspielpreis.de, 1 +deutsches-schulportal.de, 1 +deutsches-schutzportal.de, 1 +deutscheshoponline.com, 1 +deutschland-dsl.de, 1 +deux.solutions, 1 +deuxsol.co, 1 +deuxsol.com, 1 +deuxsolutions.com, 1 +dev, 1 +dev-advancedservicesportal.com, 1 +dev-aries.com, 1 +dev-brandywineglobal.com, 1 +dev-greavesindia.pantheonsite.io, 1 +dev-gutools.co.uk, 1 +dev-pmcc.net, 1 +dev-redwood.azurewebsites.net, 1 +dev-sev-web.pantheonsite.io, 1 +dev-tek.de, 1 +dev-test.nl, 1 +dev.moe, 1 +dev.vu, 1 +devafterdark.com, 1 +devagency.fr, 1 +devahi.gq, 1 +devalps.eu, 1 +devapi.pro, 1 +devb.nl, 1 +devcf.com, 1 +devchuli.ml, 1 +devconf.nl, 1 +devcore.pl, 1 +devcu.net, 1 +devdeb.com, 1 +devdesco.com, 1 +devdomain.cf, 1 +devdoodle.net, 1 +deve.software, 1 +devel.cz, 1 +develify.co, 1 +develope.cz, 1 +developer.android.com, 1 +developer.moe, 1 +developer.mydigipass.com, 0 +developerdan.com, 1 +developers.facebook.com, 0 +developingtheworkforce.co.uk, 1 +developmentaid.org, 1 +developmentsites.melbourne, 1 +developpeur-freelance.io, 1 +developr.uk, 1 +develops.co.il, 1 +develoupe.com, 1 +develux.net, 1 +devendradox.ml, 1 +devensys.com, 1 +devenv.ml, 1 +devflop.fr, 1 +devh.de, 1 +devh.net, 1 +deviant.email, 1 +devicesgadget.com, 1 +devicom.mx, 1 +devignstudios.co.uk, 1 +devil.wtf, 1 +devilbyte.tk, 1 +devildog.tk, 1 +devillers-occasions.be, 0 +devilrecords.tk, 1 +devils-co.tk, 1 +devils-point.de, 1 +devilshakerz.com, 1 +devinfo.net, 0 +devinite.com, 1 +devinslick.com, 1 +devirc.net, 1 +devisnow.fr, 1 +devkid.net, 1 +devlabroid.com, 1 +devlatron.net, 1 +devlogr.com, 1 +devloope.com, 1 +devmode.fm, 1 +devnet.tk, 1 +devnull.team, 1 +devnull.zone, 1 +devoc.net, 1 +devochki.ga, 1 +devoetenbus.nl, 1 +devolution.ws, 1 +devonsawatzky.ca, 1 +devonvintagechina.co.uk, 1 +devopedia.org, 1 +devopers.com.br, 1 +devops.moe, 1 +devops.pf, 1 +devopsbookmarks.org, 1 +devopsish.com, 0 +devos.ml, 1 +devpage.lv, 1 +devpost.com, 1 +devpp.com.br, 1 +devpsy.info, 1 +devr.nl, 1 +devragu.com, 1 +devrandom.net, 1 +devries.one, 1 +devrim.io, 1 +devs.men, 1 +devsdata.com, 1 +devsjournal.com, 1 +devskiller.com, 1 +devskyport.com, 1 +devslash.net, 1 +devsrvr.ru, 1 +devstaff.gr, 1 +devstores.io, 1 +devstroke.io, 1 +devswag.io, 1 +devtea.cz, 1 +devtestfan1.gov, 1 +devtoys.ru, 1 +devtty.org, 1 +devun.limited, 1 +devushki.cf, 1 +devxify.com, 1 +devyanijayakar.com, 1 +devz.life, 1 +devzero.io, 1 +dewalch.net, 1 +dewapress.com, 1 +dewblog.ml, 1 +dewereldvankina.be, 1 +dewereldwerktthuis.com, 1 +dewereldwerktthuis.eu, 1 +dewereldwerktthuis.net, 1 +dewereldwerktthuis.nl, 1 +dewereldwerktthuis.org, 1 +dewerveling.tk, 1 +dewingerdfreinet.be, 1 +dewitjes.nl, 1 +dewitteprins.nl, 1 +dewolden.nl, 0 +dexalo.de, 1 +dexcellentesidees.tk, 1 +dexign.ro, 1 +dexigner.com, 1 +dexonrest.azurewebsites.net, 1 +dexonservicedeskws.azurewebsites.net, 1 +dexonsoftware.com, 1 +dextra.tk, 1 +deyanadeco.com, 1 +deyute.com, 1 +dez-online.de, 1 +dezea.net, 1 +dezeregio.nl, 1 +dezet-ev.de, 1 +dezevenster.com, 1 +dezinfekcianaruky.com, 1 +dezintranet.com, 1 +dezmembrariromania.ro, 1 +dezzoroofing.co.za, 1 +df1nif.de, 1 +df1paw.de, 1 +df3313.com, 1 +df3314.com, 1 +df3315.com, 1 +df3316.com, 1 +df3317.com, 1 +df3318.com, 1 +df3319.com, 1 +df5.se, 1 +df5102.com, 1 +df5103.com, 1 +df5104.com, 1 +df5105.com, 1 +df5aa.com, 1 +df5bb.com, 1 +df5cc.com, 1 +df5dd.com, 1 +df5ee.com, 1 +df63.cc, 1 +dfagent.com, 1 +dfc.gov, 1 +dfc52.com, 1 +dfctaiwan.org, 1 +dfekt.no, 1 +dfepharma.com, 1 +dflcares.com, 1 +dfmn.berlin, 1 +dfmvf.org, 1 +dfranke.com, 1 +dfstoryteller.com, 1 +dfwm.vote, 1 +dfwmv.com, 1 +dfwmv.org, 1 +dfwmv.us, 1 +dfwmv.vote, 1 +dfwwp.com, 1 +dg-1.jp, 1 +dg-pic.tk, 1 +dg1-test.com, 1 +dg1.com, 1 +dg1.services, 1 +dg1298.com, 1 +dg1jp-test.com, 1 +dg68.cc, 1 +dgangsta.net, 1 +dgblaw.com.au, 0 +dgbouncycastlehire.com, 1 +dgitup.com, 1 +dgl-24.de, 1 +dgmedia.tk, 1 +dgportals.co.uk, 1 +dgpot.com, 1 +dgt-portal.de, 1 +dgtakano.co.jp, 1 +dgund.com, 1 +dgvservices.com, 1 +dgx.io, 1 +dh6729.com, 1 +dh9397.com, 1 +dh9721.com, 1 +dhakawebhost.com, 1 +dhamdhamaanchalikcollege.tk, 1 +dhammacitta.org, 1 +dharamkot.com, 1 +dharma-clinic.com, 1 +dharveydev.com, 1 +dhautefeuille.eu, 1 +dhauwer.nl, 1 +dhaynes.xyz, 1 +dhconcept.ch, 0 +dheart.net, 1 +dhedegaard.dk, 0 +dhelixnet.de, 1 +dhemant.de, 1 +dhhs.gov, 1 +dhirendrayadav.com, 1 +dhit.pl, 1 +dhl-smart.ch, 1 +dhlcotizadorexpo-qa.azurewebsites.net, 1 +dhlinux.org, 1 +dhlkh.com, 1 +dhome.at, 1 +dhruv.nz, 1 +dhs-rizlona.com, 1 +dhtr.pw, 1 +dhub.xyz, 1 +dhuy.net, 1 +dhxxls.com, 1 +di-basketballscouting.com, 1 +di2pra.com, 0 +di2pra.fr, 0 +dia-de.com, 1 +dia.com.br, 1 +diabetessucks.net, 1 +diabhal-staff.com, 1 +diabhal-staff.it, 1 +diabhalstaff.it, 1 +diables-noirs.tk, 1 +diablescastell.tk, 1 +diablo-2.net, 0 +diablocarpet.com, 1 +diablos-obon.tk, 1 +diablovalleytech.com, 1 +diabolic.chat, 1 +diabolique.pt, 1 +diaconat.ch, 0 +diadiemdangsong.com, 1 +diadoc.ru, 1 +diadora-media.hr, 1 +diadorafitness.es, 1 +diadorafitness.it, 1 +diagilev.ml, 1 +diagnocentro.cl, 1 +diagnoseo.com, 1 +diagnoseo.pl, 1 +diagnoseo.se, 1 +diagnostix.org, 1 +dialapicnic.co.za, 1 +dialect-agency.eu.org, 1 +dialectic-og.com, 1 +dialoegue.com, 1 +dialupnerdstech.com, 1 +diamant.family, 1 +diamant.nyc, 1 +diamante.ro, 1 +diamantovaburza.cz, 1 +diamgroup.pl, 1 +diamond-hairstyle.dk, 1 +diamondcontent.com, 1 +diamondgoldmarkcity.cf, 1 +diamondhead-umc.org, 1 +diamondpkg.org, 1 +diamondyacca.co.uk, 1 +diamorphine.com, 1 +diamsmedia.ch, 0 +dianaconsultancy.com, 1 +dianadrive.com, 1 +dianafaraj.de, 1 +dianakaarina.tk, 1 +diananeves.pt, 0 +dianas.sk, 1 +dianefriedli.ch, 0 +dianurse.com, 1 +diare-na-miru.cz, 1 +diario-egipto.com, 1 +diariocibao.com, 1 +diariodearaxa.com.br, 1 +diarionoticia.pe, 1 +diariorp.com.br, 1 +diariosurnoticias.com, 1 +diaroma.it, 1 +diarynote.jp, 1 +diaryspace.tk, 1 +diasdasemana.com, 1 +diasp.org, 1 +diasporan.cf, 1 +diaspordc.com, 1 +diatrofi-ygeia.gr, 1 +diavo.de, 1 +diba.org.cn, 1 +dibai.tv, 1 +dibal.ua, 1 +dibiphp.com, 1 +dicaprio.tk, 1 +diccionarioabierto.com, 1 +diccionariodedudas.com, 1 +diccionariomexico.com, 1 +diccionarqui.com, 1 +dice.tokyo, 1 +dicelab-rhul.org, 1 +dicelab.co.uk, 1 +dicesites.com, 1 +dicgaming.net, 1 +dichvudangkygiayphep.com, 1 +dicio.com.br, 1 +dicionario.org, 1 +dicionariodegirias.com.br, 1 +dicionariodelatim.com.br, 1 +dicionariodenomesproprios.com.br, 1 +dicionariodesimbolos.com.br, 1 +dicionarioetimologico.com.br, 1 +dicionariofinanceiro.com, 1 +dicionariopopular.com, 1 +dicionarios.cc, 1 +dick.red, 1 +dickord.cloud, 1 +dickp.it, 1 +dickpics.ru, 1 +dicksakowicz.com, 1 +diclofenac-75mg.ga, 1 +diclofenacgel.ml, 1 +diclofenacgel1.tk, 1 +diclofenaconline.gq, 1 +diclofenactopical.ga, 1 +dico-charentais.tk, 1 +dicoeste.com, 1 +diconium.com, 1 +dictatronics.com, 1 +dictionarypro.net, 1 +dictzone.com, 1 +dida.xin, 1 +didacte.com, 1 +didakeanimaciones.es, 1 +didaktik4you.de, 1 +didche.net, 0 +diddens.de, 1 +dideeducacion.com, 1 +didefamilia.com, 1 +didesalud.com, 1 +didier-equipereussite.com, 1 +didierfle-decibel.fr, 1 +didierfle-latelier.fr, 1 +didierfle.com, 1 +didierghez.com, 1 +didierlaumen.be, 1 +didigotoffer.com, 1 +didtrumpopengovernmentyet.com, 1 +die-bergfuehrer.de, 1 +die-besten-weisheiten.de, 1 +die-blahuts.de, 1 +die-borts.ch, 1 +die-gruenen-teufel.de, 1 +die-machons.de, 1 +die-partei-reutlingen.de, 1 +die-partei.de, 0 +die-pizzabaeckerei.de, 1 +die-seide.de, 1 +die-seiler.de, 1 +die-sinlosen.de, 1 +die-speisekammer-reutlingen.de, 1 +die.de, 1 +diebasis-partei.de, 1 +diebestengutscheine.de, 1 +diebetriebsraete.de, 1 +diedenhofen.tk, 1 +diedrehen.de, 1 +diedrich.co, 1 +dieecpd.org, 1 +diegelernten.de, 1 +diegerbers.de, 1 +diegobarrosmaia.com.br, 1 +diegocoy.com, 1 +diegoforlan.tk, 1 +diegogelin.com, 0 +diegogonzalez.com.co, 1 +diegogranada.tk, 1 +diegoisla.ga, 1 +diegorbaquero.com, 1 +diegosalgado.tk, 1 +diehildebrands.de, 1 +diehl.io, 1 +diekperaiwseis.gr, 1 +diem-project.org, 1 +diemattels.at, 1 +diemperu.com, 1 +dienaturbinderei.at, 1 +dienchaninstitute.com, 1 +diendorfer.space, 1 +diengiolachoa.com, 1 +dienmattroichonthanh.com, 1 +dienmay88.vn, 1 +diennhienshop.com, 1 +diennobi.com, 1 +dienstplan.cc, 1 +dierabenmutti.de, 1 +dieradvies.nl, 1 +dierenartsdeconinck.be, 1 +dierencompleet.nl, 1 +dieselanimals.lt, 1 +dieselfiltersonline.com, 1 +dieselgalleri.com, 1 +diesicheremail.de, 1 +dieslowhtx.com, 1 +diesse.nl, 1 +diesteppenreiter.de, 1 +dieta-figura.tk, 1 +dietaedietas.com.br, 1 +dietandexercises.tk, 1 +dietaparaadelgazar1.com, 1 +dietbrand.eu, 1 +dieterglas.de, 1 +dietergreven.de, 0 +dieterstinglhamber.me, 0 +dietetykonline.com.pl, 1 +dietfordiabetics.tk, 1 +diethood.com, 1 +dieti-natura.com, 1 +dieti.ga, 1 +dieti.gq, 1 +dieti.net, 1 +dietlein.tech, 1 +dietlin.com, 1 +dietolog.gq, 1 +dietpi.com, 1 +dietrich.cx, 1 +dietrichinocencio.com, 1 +dieumfrage.com, 1 +dievozodis.lt, 1 +difc.ae, 1 +diferenca.com, 1 +diff-speed.de, 0 +different.cz, 1 +differenta.ro, 1 +differentgirleveryday.ml, 1 +differmint.com, 1 +difficulty.ga, 1 +diffnow.com, 1 +diffuzehr.com.au, 1 +diflucangeneric.ml, 1 +diflucanonline.tk, 1 +diflucanpill.ga, 1 +difoosion.com, 1 +digazu.com, 1 +digchip.com, 1 +digchip.info, 1 +digchip.net, 1 +digchip.org, 1 +digchips.com, 1 +digdata.de, 1 +dighans.com, 1 +digiaika.com, 1 +digiaika.fi, 1 +digiarc.net, 1 +digibean.com.au, 1 +digibull.email, 1 +digibull.link, 1 +digicami.co.uk, 1 +digicasso.nl, 1 +digicelidgy.com, 1 +digicert-support.com, 1 +digicode.hu, 1 +digicy.cloud, 1 +digideli.ee, 1 +digidroom.be, 1 +digifloat.io, 1 +digikohan.com, 1 +digikol.net, 1 +digiland.tk, 1 +digilicious.com, 1 +digiloop.co, 1 +digimaat.agency, 1 +digimagical.com, 1 +digimedia.cd, 0 +digimoncard.io, 1 +digino.co.uk, 1 +digino.jp, 1 +digino.us, 1 +digino.xyz, 1 +digipolis.gent, 1 +digipost.no, 1 +digirechnung.de, 1 +digired.ro, 1 +digirence.org, 1 +digiriik.ee, 1 +digiskool.co.za, 1 +digit.ec, 1 +digitaaltalent.be, 1 +digitai.net, 1 +digital-coach.it, 0 +digital-compounds.com, 1 +digital-e-library.tk, 1 +digital-eastside.de, 1 +digital-home.tk, 1 +digital-insurance-engine.com, 1 +digital-insurance-engine.de, 1 +digital-insurance-platform.com, 1 +digital-insurance-platform.de, 1 +digital-insure.fr, 1 +digital-liberal.ch, 1 +digital-sculpture.org, 1 +digital-techs.com, 1 +digital-workshop.at, 1 +digital.gov, 1 +digital.govt.nz, 1 +digital1st.co.uk, 1 +digital2web.com, 0 +digitalagedeals.com, 1 +digitalagencynetwork.com, 1 +digitalakatsuki.com, 1 +digitalalektioner.se, 1 +digitalallies.co.uk, 1 +digitalandsocialmediaacademy.com, 1 +digitalarchitecture.com, 1 +digitalbd.tk, 1 +digitalbitbox.com, 1 +digitalblood.eu, 1 +digitalbox.jp, 0 +digitalcanvas.com.br, 1 +digitalcarbide.com, 1 +digitalcash.cf, 1 +digitalch.ng, 1 +digitalchurch.ng, 1 +digitalcitizen.life, 1 +digitalcitizen.ro, 1 +digitalcloud.ovh, 1 +digitalcoffeepodcast.com, 1 +digitalcompudev.biz, 1 +digitalcraftmarketing.co.uk, 1 +digitalcrisis.com, 1 +digitaldashboard.gov, 1 +digitaldeli.com, 1 +digitaldeli.org, 1 +digitaldeli.tv, 1 +digitaldeli.us, 1 +digitaldeliarchive.com, 1 +digitaldem.it, 1 +digitaldesign.ga, 1 +digitaldisaster.tk, 1 +digitale-oekonomie.ch, 1 +digitalecom.ga, 1 +digitalehandtekeningen.nl, 1 +digitalentertainmentnews.com, 1 +digitaleplus.fr, 1 +digitalerror.net, 1 +digitaletanker.com, 1 +digitalewelten.de, 1 +digitalezukunft-hagen.de, 1 +digitalezukunft.nrw, 1 +digitalfoodbook.com, 1 +digitalforensicsdubai.com, 1 +digitalfoster.org, 1 +digitalframe.nl, 1 +digitalfury.co.uk, 1 +digitalfuturenow.com, 1 +digitalgeckos.com, 1 +digitalgeek.social, 1 +digitalgov.gov, 1 +digitalgymnastics.tk, 1 +digitalhands.tk, 1 +digitalhealth.gov.au, 1 +digitalheart.tk, 1 +digitalhurricane.io, 0 +digitaliandm.com, 1 +digitalid-sandbox.com, 1 +digitalid.com, 1 +digitalid.com.au, 1 +digitalimpactlab.org, 1 +digitalingot.org, 1 +digitalis-france.com, 1 +digitalitglobal.com, 1 +digitalizzazioneverona.it, 1 +digitalkashmir.ml, 1 +digitalliteracy.gov, 1 +digitalmaniac.co.uk, 1 +digitalmarketingindallas.com, 1 +digitalninja.tk, 1 +digitalnomadsunderground.com, 1 +digitalphone.tk, 1 +digitalphoto.group, 1 +digitalphoto.tech, 1 +digitalpiloten.org, 1 +digitalpocketpedometer.tk, 1 +digitalponsel.com, 1 +digitalposition.com, 1 +digitalprimate.my, 1 +digitalprofilers.com, 1 +digitalproj.com, 1 +digitalradio.ie, 1 +digitalreborn.com, 1 +digitalredshirts.com, 1 +digitalrights.center, 1 +digitalrights.fund, 1 +digitalroma.tk, 1 +digitalsearchlab.com, 1 +digitalservices.lk, 1 +digitalsignagedisplay.com, 1 +digitalskillswap.com, 1 +digitalsphere.tk, 1 +digitalsurge.io, 1 +digitaltcertifikat.dk, 1 +digitalupcoming.tk, 1 +digitalwasteland.net, 0 +digitec.ch, 1 +digitecgalaxus.ch, 1 +digitise.io, 1 +digitium.fr, 1 +digitizer.co.il, 1 +digitkon.com, 1 +digitlyx.com, 1 +digitreads.com, 1 +digivan.ml, 1 +digivet.co.za, 1 +digixcellence.com, 1 +digminecraft.com, 1 +dignity.tk, 1 +digpath.co.uk, 1 +digpubdev.org, 1 +digpubprd.org, 1 +digpubqa.org, 1 +digwp.com, 1 +dih-technology.com, 1 +dih-technology.info, 1 +dih-technology.net, 1 +dih-technology.org, 1 +dih.email, 1 +dihesan.com, 1 +dihinternational.com, 1 +dihinternational.info, 1 +dihinternational.net, 1 +dihinternational.org, 1 +dihmedical.info, 1 +dihmedical.net, 1 +dihmedical.org, 1 +diis.plus, 1 +dijitaller.com, 1 +dijitalzade.com, 1 +dijkmanmuziek.nl, 0 +dijks.com, 1 +dik-manusch.tk, 1 +dikant.eu, 1 +dikiaap.id, 1 +dikkevettescania.tk, 1 +dilation.party, 1 +dilberkebab.co.uk, 0 +dilchahtah.com, 1 +dildoexperten.se, 1 +diletec.com.br, 1 +dilibel.be, 1 +diligenciasprime.com.br, 1 +diligo.ch, 0 +dillewijnzwapak.nl, 1 +dillon-mcnamara.com, 1 +dillonm.io, 1 +dilmarames.com, 1 +dimagrimentoincorso.it, 1 +dimanet.fr, 1 +dimanss47.net, 1 +dimaweb.tk, 1 +dime-staging.com, 1 +dime.io, 1 +dimeponline.com.br, 1 +dimequebuscas.cl, 1 +dimesanmedical.com, 1 +dimez.ru, 1 +dimi-inside.com, 1 +dimigo.codes, 1 +dimiskovska.de, 1 +dimism.eu, 1 +dimitrihomes.com, 1 +dimitris.tk, 1 +dimitrovi.tk, 1 +dimitryknoops.xyz, 1 +dimmersagourahills.com, 1 +dimmerscalabasas.com, 1 +dimmersdosvientos.com, 1 +dimmershiddenhills.com, 1 +dimmerslakesherwood.com, 1 +dimmersnewburypark.com, 1 +dimmersoakpark.com, 1 +dimmersthousandoaks.com, 1 +dimmerswestlakevillage.com, 1 +dimo-analytics.fr, 1 +dimo-crm.fr, 1 +dimo-dematerialisation.com, 1 +dimo-tresorerie.fr, 1 +dimomaint.com, 1 +dimomaint.de, 1 +dimomaint.es, 1 +dimomaint.it, 1 +dimomaint.nl, 1 +dimomaint.pt, 1 +dimonb.com, 1 +dimosoftware.com, 1 +dimosoftware.fr, 1 +dimseklubben.dk, 1 +dinamikarosta.ml, 1 +dinamofilms.cl, 1 +dinda.tk, 1 +dinderllc.com, 1 +dinero4all.xyz, 1 +dinerroboticurology.com, 1 +dinevigroup.bg, 1 +dingcc.me, 1 +dingelbob-schuhcreme.gq, 1 +dingsbums.shop, 1 +dingss.com, 1 +dinheirolucrar.com, 1 +dinkommunikasjon.no, 1 +dinmtb.dk, 1 +dinnerclub.tk, 1 +dino.lol, 1 +dinocarrozzeria.com, 1 +dinotv.at, 1 +dinposition.nu, 1 +dintillat.fr, 1 +dintrafic.net, 1 +dinube.com, 1 +diodo.me, 1 +dioesfoto.com, 1 +diogbatech.tk, 1 +diogeneshoy.com, 1 +dionysos-ios.gr, 1 +dionysus.se, 1 +diozoid.com, 1 +dipakgajjar.com, 1 +dipalma.me, 1 +dipanshuparashar.ml, 1 +dipdaq.com, 1 +dipietro.id.au, 1 +dipling.de, 1 +diplom-ru.tk, 1 +diplomatcruises.co.uk, 1 +diplomatiegabon.ga, 1 +diplona.de, 1 +dippydyes.com, 1 +dipro.id, 1 +dipulse.it, 1 +dir2epub.com, 1 +dir2epub.org, 1 +dirba.io, 1 +direcore.xyz, 1 +direct-sel.com, 1 +direct.cz, 1 +direct365.es, 1 +directeca.com, 1 +directecommerce.co.uk, 1 +directelectricalltd.co.uk, 1 +directfinance.cz, 1 +directfitnesssolutions.com, 1 +directhomeremodelinginc.com, 1 +directinspectionskc.com, 1 +directitude.com.au, 1 +directlendingsolutions.com, 1 +directlinkfunding.co.uk, 1 +directly.ga, 1 +directmailctr.com, 1 +directme.ga, 1 +directnews.be, 1 +directoriostelefonicos.com, 1 +directorseries.com, 1 +directory-aldo.tk, 1 +directory-ecco.tk, 1 +directory-sunglasses.tk, 1 +directorydashboard.ga, 1 +directorydisc.ga, 1 +directoryhub.io, 1 +directorylib.com, 1 +directoryworld.tk, 1 +directpaydayloansonline.ga, 1 +directreal.sk, 1 +directspa.fr, 1 +directtwo.solutions, 1 +directtwosolutions.org, 0 +directvacations.com, 1 +directveilig.nl, 1 +directverify.in, 1 +direktvermarktung-schmitzberger.at, 1 +direwolfsoftware.ca, 1 +diriya.lk, 1 +dirk-dogs.tk, 1 +dirk-weise.de, 1 +dirkdoering.de, 1 +dirkjonker.nl, 1 +dirkwolf.de, 1 +dirtcraft.ca, 1 +dirtinmyshoes.com, 1 +dirty-tina.net, 1 +dirtycat.ru, 1 +dirtycode.tk, 1 +dirtygeek.ovh, 1 +dirtygirl.ml, 1 +dirtyherri.de, 1 +dirtyporno.tk, 1 +dirtypretties.cf, 1 +dirtyprettyartwear.com, 1 +dirtysox.ch, 1 +dirtysox.eu, 1 +dirtytiles.xyz, 1 +dirtywarez.org, 1 +dirtywoman.tk, 1 +disa.uk, 1 +disability.gov, 1 +disabilitydischarge.com, 1 +disabled-world.com, 1 +disabled.dating, 1 +disableipv4.se, 1 +disabuse.cf, 1 +disadattamentolavorativo.it, 1 +disanteimpianti.com, 0 +disbug.io, 1 +disc.uz, 1 +discarica.bari.it, 1 +discarica.bologna.it, 1 +discarica.firenze.it, 1 +discarica.it, 1 +discarica.milano.it, 1 +discarica.napoli.it, 1 +discarica.roma.it, 1 +disch.com.de, 1 +dischempharmacie.com, 1 +disciples.io, 1 +disciplescloud.com, 1 +disciplesmakingdisciples.ca, 1 +disco-crazy-world.de, 1 +discodery.com, 1 +discofitta.com, 1 +discohook.org, 1 +disconformity.net, 1 +disconnect.tk, 1 +discord-chan.net, 1 +discord.com, 1 +discord.gg, 1 +discord.gift, 1 +discord4j.com, 1 +discordapp.com, 1 +discordbee.com, 1 +discordextremelist.xyz, 1 +discordghost.space, 1 +discordhome.com, 1 +discordia.me, 1 +discordservers.com, 1 +discordsworld.tk, 1 +discotheque.tk, 1 +discount-course.com, 1 +discountforelectronics.tk, 1 +discountlumberspokane.com, 1 +discounto.de, 1 +discountpark.fr, 1 +discountpokale.at, 1 +discountpokale.de, 1 +discover-mercure.com, 1 +discover-shaken.com, 1 +discoverapp.com, 1 +discoveraustralia.tk, 1 +discoverchinanow.gq, 1 +discoverelement.com, 1 +discoverfloridasprings.com, 1 +discoverhealthage.com, 0 +discoveringdocker.com, 1 +discovermarbellahomes.com, 1 +discoverthreejs.com, 1 +discoverucluelet.com, 1 +discoveryaima.com, 1 +discoveryballoon.org, 1 +discoveryottawa.ca, 1 +discrede.tk, 1 +discrete-passion.com, 1 +discrypt.ca, 1 +discshop.co.nz, 1 +disctranulis.gq, 1 +discus-communications.dk, 1 +discuss-data.net, 1 +discuzindo.net, 1 +discuzturkiye.tk, 1 +dise-online.de, 1 +disengaged.tk, 1 +disenialia.com, 1 +disenowebakus.net, 1 +diseyst.com.ar, 1 +disguise.cf, 1 +dishwashermagic.tk, 1 +dishwasherrepair-austin.com, 1 +disinclined.org, 1 +disinfectingassociation.com, 1 +disinfectingassociation.org, 1 +disinfectingdoctor.com, 1 +disinfectingdoctors.com, 1 +disinfectiondoctor.com, 1 +disinfectiondoctors.com, 1 +disinfesta.it, 1 +disinfestando.info, 1 +disinfestatore.roma.it, 1 +disinfestatori.com, 1 +disinfestazione-roma.org, 1 +disinfestazione.brescia.it, 1 +disinfestazione.napoli.it, 1 +disinfestazione.torino.it, 1 +disinfestazione.venezia.it, 1 +disinfestazione.verona.it, 1 +disinfestazione24.it, 1 +disinfestazioneblatte.it, 1 +disinfestazionecimici.napoli.it, 1 +disinfestazionecimici.roma.it, 1 +disinfestazioni-sardegna.org, 1 +disinfestazioni-umbria.it, 1 +disinfestazioni.bari.it, 1 +disinfestazioni.bergamo.it, 1 +disinfestazioni.cagliari.it, 1 +disinfestazioni.caserta.it, 1 +disinfestazioni.catania.it, 1 +disinfestazioni.co, 1 +disinfestazioni.firenze.it, 1 +disinfestazioni.genova.it, 1 +disinfestazioni.gorizia.it, 1 +disinfestazioni.info, 1 +disinfestazioni.it, 1 +disinfestazioni.milano.it, 1 +disinfestazioni.napoli.it, 1 +disinfestazioni.net, 1 +disinfestazioni.padova.it, 1 +disinfestazioni.rimini.it, 1 +disinfestazioni.roma.it, 1 +disinfestazioni.torino.it, 1 +disinfestazioni.treviso.it, 1 +disinfestazioni.udine.it, 1 +disinfestazioni.venezia.it, 1 +disinfestazioni.verona.it, 1 +disinfestazioni24.it, 1 +disinfestazionivespe.milano.it, 1 +disinfestazionizanzare.milano.it, 1 +disinfestazionizanzare.roma.it, 1 +disinisharing.com, 1 +disk.do, 1 +diskbit.com, 1 +diskbit.nl, 1 +diskdoctors.tk, 1 +disketa.cf, 1 +disketteetikette.tk, 1 +diskgem.info, 1 +diskonsepatu.ga, 1 +diskussionsbereich.de, 1 +dismail.de, 1 +disneywallpapers.tk, 1 +disobey.net, 1 +disougstroy.com.ua, 1 +dispatchitsolutions.com, 1 +dispatchitsolutions.io, 1 +dispemec.com, 1 +displayenergycertificate.co.uk, 1 +displayrd.com, 1 +displaysandholders.com, 1 +displaysfas.com, 1 +disposable.link, 1 +disproweb.com, 1 +dispur.nic.in, 1 +disrupters.ch, 0 +dissectcyber.com, 1 +dissectix.io, 1 +dissertationhelp.com, 1 +dissidence.ovh, 0 +dissident.host, 1 +dissieux.com, 1 +dist-it.com, 1 +dist.torproject.org, 0 +distancelove.ml, 1 +distelbentelo.nl, 1 +disti.com, 1 +distiduffer.org, 1 +distilleren.tk, 1 +distillery.com, 1 +distinctdesign2009.com, 1 +distinguishedprisoner.com, 1 +distortionx.tk, 1 +distortmotion.com, 1 +distracteddriving.gov, 1 +distraction.gov, 1 +distratus.com, 1 +distri.com.ua, 1 +distribuidoradecierres.com, 1 +distribuidoraplus.com, 1 +distribuidorveterinario.es, 1 +distributed.cafe, 1 +distributedsource.com, 1 +distributedsystems.science, 1 +distributore.it, 1 +distributori.roma.it, 1 +district09.be, 1 +district09.gent, 1 +districtcapital.com, 1 +districtcourtislamabad.tk, 1 +distrilentes.com.br, 1 +distrilogservices.com, 1 +distrim.pt, 1 +distrim2.pt, 1 +distro.fr, 1 +distro.re, 0 +ditdot.hr, 1 +ditec.sk, 1 +diterzafra.tk, 1 +ditex.ddns.net, 1 +ditfiorinicamargo.com.ar, 1 +diti.me, 1 +dities.tk, 1 +ditissaskia.nl, 1 +div.im, 0 +div12.org, 1 +diva.nl, 1 +divari.nl, 1 +divarjonob.ir, 1 +divcoder.com, 1 +dive-japan.com, 1 +divegearexpress.com, 1 +divegearexpress.net, 1 +diveidc.com, 1 +divelement.ro, 1 +divelyon.fr, 1 +diveplan.org, 1 +diver-equipment.eu, 1 +diveretailing.com, 1 +diverscott.com, 1 +diversificarte.com, 1 +diversify.ga, 1 +diversity-otherwise.tk, 1 +diversityflags.com.au, 1 +diversityflags.nz, 1 +diversitywatch.asia, 1 +diversitywatch.co.nz, 1 +diversitywatch.com.au, 1 +divewithfrank.com, 1 +divfinsolutions.com, 1 +divi-experte.de, 1 +dividedstates.tk, 1 +dividendz.net, 1 +divienna.nl, 1 +divinasaiamodas.com.br, 1 +divinecnainstitute.com, 1 +divinegames.studio, 1 +divineglowinghealth.com, 0 +divinemercyparishvld.com, 1 +divinho.com.br, 1 +divinitas.tk, 1 +divisuite.com, 1 +divjak.at, 1 +divo-remont.tk, 1 +divorceformsfiller.com, 1 +divorcelawyer365.com, 1 +divort.org, 1 +divup.com, 1 +diwakarlaproperties.com, 1 +diwei.vip, 1 +dixibox.com, 1 +dixie.com, 1 +dixieweld.com, 1 +dixmag.com, 1 +diyanet.nl, 1 +diycc.org, 1 +diyeat.com, 1 +diyeta.cf, 1 +diyeventhire.co.nz, 1 +diygeek.com, 1 +diyibo.com, 1 +diymediahome.org, 1 +diyosun.com, 0 +diysec.tk, 1 +diysonline.com, 1 +diytechguides.com, 1 +diyvideoeditor.com, 1 +dizainkyhni.ml, 1 +dizayner.tk, 1 +dizidegilfilm.com, 1 +diziyah.com, 1 +dizzie.org, 1 +dizzieforums.com, 1 +dizzyskills.tk, 1 +dizzythewizard.co.uk, 1 +dj-ac.com, 1 +dj-dfo.tk, 1 +dj-iliri.tk, 1 +dj-kupidon.gq, 1 +dj-leszwolle.nl, 1 +dj-morfu.tk, 1 +dj-phil.fr, 1 +dj-x.info, 1 +dj16888.com, 1 +dj16888a.com, 1 +dj16888b.com, 1 +dj16888c.com, 1 +dj16888d.com, 1 +dj62.tk, 1 +djaad.tk, 1 +djakuza.tk, 1 +djalberto.tk, 1 +djalessandrobrain.tk, 1 +djamiroquai.tk, 1 +djang.tk, 1 +django-lessons.com, 1 +django.city, 1 +djangobirthday.com, 1 +djangogolf.com, 1 +djangoproject.com, 1 +djangoproject.tk, 1 +djangosnippets.org, 1 +djanpana.com, 1 +djax.tk, 1 +djazair.ml, 1 +djazair.tk, 1 +djazim.tk, 1 +djbell.tk, 1 +djbessi.tk, 1 +djbobbytables.com, 1 +djboekingskantoor.nl, 1 +djboomarang.tk, 1 +djc.me, 1 +djcezar.tk, 1 +djcheka.tk, 1 +djconker.tk, 1 +djcontact.tk, 1 +djcursuszwolle.nl, 1 +djdarkz.tk, 1 +djdavid98.art, 0 +djddt.tk, 1 +djdebayanofficial.ga, 1 +djdebodas.com, 1 +djdennis.tk, 1 +djefsane.tk, 1 +djembeforum.tk, 1 +djerba-tunisie.tk, 1 +djfafafa.com, 1 +djfantum.com, 1 +djfaruk.tk, 1 +djfed.tk, 1 +djfelix.tk, 1 +djfilms.tk, 1 +djfrenchy.com, 1 +djfunkyju.de, 1 +djgarcia.tk, 1 +djh-nordmark.de, 1 +djharun.tk, 1 +djhypnoticstate.tk, 1 +djinstinct.tk, 1 +djipanov.com, 1 +djjonimix.tk, 1 +djkemal.tk, 1 +djkhalid.tk, 1 +djkonor.tk, 1 +djl188.cc, 1 +djl63.com, 1 +djl63001.com, 1 +djleon.net, 1 +djlifemusic.tk, 1 +djlinux.cz, 1 +djlive.ga, 1 +djlmk.tk, 1 +djlnetworks.co.uk, 1 +djlogic.tk, 1 +djlove.tk, 1 +djluca.tk, 1 +djmarian.com, 1 +djmetrix.tk, 1 +djmilad.tk, 1 +djmoremusic.ng, 0 +djmullet.tk, 1 +djnandoalmenara.tk, 1 +djnasvatbuzlin.cz, 1 +djnext.tk, 1 +djosu.tk, 1 +djpiere.tk, 1 +djpromo.tk, 1 +djrider.tk, 1 +djrizwan.tk, 1 +djrofex.tk, 1 +djroynomden.nl, 1 +djrush134.tk, 1 +djsbouncycastlehire.com, 1 +djsciencecollege.tk, 1 +djsearch.tk, 1 +djshivbabu.tk, 1 +djshox.tk, 1 +djsk.nl, 1 +djskippy.tk, 1 +djslash.tk, 1 +djsm.ga, 1 +djt-vom-chausseehaus.de, 1 +djtavo.tk, 1 +djul.net, 1 +djurklinikenangelholm.se, 1 +djursland-psykologen.dk, 1 +djviks-rap.tk, 1 +djvintagevinyl.com, 1 +djvintagevinyl.de, 1 +djvintagevinyl.nl, 1 +djwaynepryke.com, 1 +djwilson.tk, 1 +djyoungcruse.tk, 1 +dk-kromeriz.cz, 1 +dk.com, 1 +dk.search.yahoo.com, 0 +dk1818.cc, 1 +dkcomputers.com.au, 1 +dkds.us, 1 +dkids.com.br, 1 +dkim-validator.com, 1 +dklao.com, 1 +dkn.go.id, 1 +dknoops.xyz, 1 +dko-steiermark.ml, 1 +dkonline.tk, 1 +dkravchenko.su, 0 +dkstage.com, 1 +dkwedding.gr, 1 +dl-protect.tk, 1 +dl.google.com, 1 +dlagos.com, 1 +dlagoss.com, 1 +dlbouncers.co.uk, 1 +dlcwilson.com, 1 +dld.to, 1 +dlde.ru, 1 +dldl.fr, 1 +dleet.com, 1 +dleger.space, 1 +dlepavilion.com, 1 +dlf.exchange, 1 +dlfsymposium.nl, 1 +dlitz.net, 1 +dll4free.com, 1 +dlld.biz, 1 +dlld.com, 1 +dlld.org, 1 +dlld.us, 1 +dlmit.be, 1 +dlmixcloud.com, 1 +dlouwrink.nl, 1 +dlp-demo.com, 1 +dlrg-cux-ohz.de, 1 +dlrsp.org, 1 +dlscomputers.com.au, 1 +dlsolutions-inc.com, 1 +dluxelab.com, 1 +dlyabega.tk, 1 +dlyaribalki.tk, 1 +dlyatepla.ml, 1 +dlyl888.com, 1 +dm-ppp.jp, 1 +dm-tools.co.uk, 1 +dm.link, 1 +dm.lookout.com, 0 +dm1.in, 1 +dm4productions.com, 1 +dm7ds.de, 1 +dmaglobal.com, 1 +dmailshop.ro, 1 +dmarc.com, 1 +dmarc.dk, 1 +dmarc.tech, 1 +dmarcian.com, 1 +dmclix.com, 1 +dmd.lv, 1 +dmdd.org.uk, 1 +dmdpayroll.com, 1 +dmehub.com, 1 +dmerkel.de, 1 +dmess.ru, 1 +dmesure.xyz, 1 +dmfd.net, 1 +dmfj.io, 1 +dmhomedesign.pl, 1 +dmhtwebordering.com, 1 +dmi.es, 1 +dmiapis.id, 1 +dmilb.org, 1 +dmitriid.com, 1 +dmix.ca, 1 +dmliving.nl, 1 +dmlogic.com, 1 +dmmedya.com, 1 +dmmkenya.co.ke, 0 +dmmultionderhoud.nl, 1 +dmn.sh, 1 +dmni.my, 1 +dmoj.ca, 1 +dmosk.ru, 1 +dmoutlet.com.br, 1 +dmparish.com, 1 +dmramp.com, 1 +dmshynk.com, 1 +dmwall.cn, 1 +dmwaste.com, 1 +dmwclan.tk, 1 +dmx.xyz, 1 +dmxledlights.com, 1 +dmzlab.se, 1 +dn-inc.biz, 1 +dn3s.me, 1 +dn42.us, 1 +dna.li, 0 +dnacloud.pl, 1 +dnakids.co.uk, 1 +dnalounge.com, 1 +dnapizza.com, 1 +dnash.tk, 1 +dnb.co.in, 1 +dnc.org.nz, 1 +dndblog.tk, 1 +dnddobbelstenen.nl, 1 +dndr.se, 1 +dndtools.net, 1 +dnepropetrovck.tk, 1 +dneprovski.tk, 1 +dnestr.tk, 1 +dnfc.rocks, 1 +dngrexplorer.cf, 1 +dnmlab.it, 1 +dnns.no, 1 +dnplegal.com, 1 +dnratthee.me, 1 +dns-check.nl, 1 +dns-control.eu, 1 +dns-swiss.ch, 1 +dns.expert, 1 +dns.google.com, 1 +dns.sb, 1 +dnsaio.com, 1 +dnsbird.org, 1 +dnscaa.com, 1 +dnscrawler.com, 1 +dnscrypt-blacklist.tk, 1 +dnscrypt.info, 1 +dnscrypt.nl, 1 +dnscurve.io, 1 +dnshallinta.fi, 1 +dnsinfo.ml, 1 +dnskeep.com, 1 +dnskeeper.com, 1 +dnslog.com, 1 +dnsman.se, 1 +dnsmate.net, 1 +dnspod.ml, 1 +dnspropagation.net, 1 +dnsrate.com, 1 +dnssecandipv6.se, 1 +dnstwister.report, 1 +dnsvrfy.com, 1 +dnsvrfy.eu, 1 +dnsvrfy.net, 1 +dnsvrfy.org, 1 +dnt1egh97ehxx.cloudfront.net, 1 +dnzz123.com, 0 +do-do.tk, 1 +do-prod.com, 0 +do.gd, 1 +do.search.yahoo.com, 0 +do13.net, 1 +do67.de, 1 +do67.net, 1 +doamatto.xyz, 1 +doanhai.tk, 1 +dobavki.club, 1 +dobbshvac.com, 1 +dobraprace.cz, 0 +dobrazdrava.ru, 1 +dobre-programy.xyz, 1 +dobrekupony.cz, 1 +dobrekupony.pl, 1 +dobrekupony.sk, 1 +dobreoknaszczecin.pl, 1 +dobreprogramy.pro, 1 +dobrev.family, 1 +dobrinya.tk, 1 +dobrisan.ro, 1 +doc-baza.ru, 1 +doc-baza.tk, 1 +doc.ai, 1 +doc.new, 1 +doc.python.org, 1 +doc.to, 0 +docabo.ch, 1 +docassure.de, 1 +docbox.ch, 1 +docbrown.dk, 1 +docdoc.ru, 1 +docdoc.tel, 1 +docedic.es, 1 +docemeldoces.com, 1 +docesmartini.com.br, 1 +dochimera.com, 1 +dochub.com, 1 +dockerbook.com, 0 +dockerm.com, 1 +dockerup.net, 1 +docket.systems, 1 +dockflow.com, 1 +dockmastersonline.com, 1 +dockstarter.com, 1 +dockysearch.com, 1 +doclassworks.com, 1 +docline.gov, 1 +docloudu.info, 1 +docmed360.com, 1 +docpc86.fr, 1 +docpile.cloud, 1 +docplexus.com, 1 +docs-kelis.fr, 1 +docs.google.com, 1 +docs.python.org, 1 +docs.tw, 1 +docsend.com, 1 +docskiff.ai, 1 +docsrev-aws.io, 1 +docswallet.com, 1 +doctabaila.com, 1 +doctafit.com, 1 +docteurcardin.com, 0 +doctor-locks.co.uk, 1 +doctor.dating, 1 +doctor360.com.au, 1 +doctorbini.com, 1 +doctorcalefon.com, 1 +doctorebonie.com, 1 +doctorfox.co.uk, 1 +doctoriko.tk, 1 +doctoripfix.com, 1 +doctormahamudul.tk, 1 +doctormartinclavo.tk, 1 +doctornaima.ml, 1 +doctorperu.com, 1 +doctorpluss.com, 1 +doctorpower.ga, 1 +doctorpup.com, 1 +doctorwho.cz, 1 +doctour.eu, 1 +doctour.fr, 1 +doctruyencotich.vn, 1 +docu.io, 1 +docubox.info, 1 +docuconta.es, 1 +docucopies.com, 1 +docufiel.com, 0 +documaniatv.com, 1 +documentat.ga, 1 +documentations-sociales.com, 1 +documentnode.io, 1 +documods.com, 1 +docupaymentuat.xyz, 1 +docusearch.com, 1 +docusend.biz, 1 +docusign.ca, 1 +docusign.co.uk, 1 +docusign.com, 1 +docusign.com.au, 1 +docusign.com.br, 1 +docusign.com.es, 1 +docusign.de, 1 +docusign.fr, 1 +docusign.in, 1 +docusign.jp, 1 +docusign.mx, 1 +docusign.nl, 1 +docxtemplater.com, 1 +doczlo.tk, 1 +doda.space, 1 +dodacommunity.tk, 1 +dodard.link, 1 +dodds.cc, 1 +doddy.tk, 1 +dodi-alhelo.tk, 1 +dodikod.tk, 1 +dodolle.co.uk, 1 +dodomy.com.ua, 1 +dodopri.com, 1 +dodotek.digital, 1 +doejedansvereniging.nl, 1 +doeleman.nl, 1 +doencadobeijo.com, 1 +doener-curator.com, 1 +doenjoylife.com, 1 +doeren.com, 1 +doerz.com, 1 +doesburg-comp.nl, 1 +doesinfotech.com, 1 +doesmycodehavebugs.today, 1 +doesnotscale.com, 0 +doetwat.nl, 1 +dofuspvp.com, 0 +dofux.org, 1 +dog-likeeyes.tk, 1 +dogable.net, 1 +dogadayiz.net, 1 +dogan.ch, 0 +doganoglu.net, 1 +dogcam.tk, 1 +dogcratereview.info, 1 +dogday.tk, 1 +doge.town, 1 +dogear.ch, 0 +dogecoinnews.net, 1 +dogecoinnews.org, 1 +dogespeed.gq, 1 +dogespeed.tk, 1 +dogfights.tk, 1 +dogforum.de, 1 +dogfriendly.co.uk, 1 +dogft.com, 1 +doggingclub.tk, 1 +doggo-staging.herokuapp.com, 1 +doggo.cloud, 1 +doggo.email, 1 +doggo.tech, 1 +doggroomingcourse.com, 0 +doghauspottery.com, 1 +doginaflat.com, 1 +doglist.ga, 1 +dogma.it, 1 +dogma2000.tk, 1 +dogmagic.tk, 1 +dogmap.jp, 1 +dogodki.today, 1 +dogoo.com, 1 +dogpawstudio.com, 1 +dogprograms.net, 1 +dogsdailylife.com, 1 +dogsnaturallymagazine.com, 1 +dogsnow.com, 1 +dogtowneastpowell.com, 1 +dogtrack.tk, 1 +dogvolution.com, 1 +dogwithblog.in, 1 +dogwoodceramics.com, 1 +dogworld.com.br, 1 +doi.org, 1 +doihavetoputonpants.com, 1 +doitauto.de, 1 +dojifish.space, 1 +dojin.nagoya, 1 +dojki.ga, 1 +dojocasts.com, 1 +dojozendebourges.fr, 1 +dokee.cn, 1 +dokelio-idf.fr, 1 +doki-list.com, 1 +doki.space, 0 +dokidokimodding.org, 1 +dokipy.no, 1 +dokonline.tk, 1 +dokspot.cf, 1 +dokspot.ga, 1 +dokterkelaminjakarta.com, 1 +doktorplyusheva.ml, 1 +doku-gilde.de, 1 +dokuboard.com, 1 +dokudu.com, 1 +dokument.tk, 1 +dokuraum.de, 1 +dokutech.fr, 1 +dolarenmexico.com, 1 +dolce-vita-mia.tk, 1 +dolcesalatoweb.it, 1 +dolcett.pw, 1 +dolceuvita.com, 1 +dolci-delizie.de, 1 +dolciariasimonini.com, 1 +dolciterapie.com, 1 +doldersumenzoon.tk, 1 +dolg.cf, 1 +dolg.ga, 1 +dolg.gq, 1 +dolg.ml, 1 +dolg.tk, 1 +dolgopolova.ga, 1 +dolgorukovo.cf, 1 +doli.se, 1 +dolice.net, 1 +dolinathome.com, 1 +doll.ml, 1 +dollanid.xyz, 1 +dollarhero.ga, 1 +dollarprofit.tk, 1 +dollarrp.pl, 1 +dollarweb.cf, 1 +dolle-shop.com.ua, 1 +dollemore.com, 1 +dollhouseaustralia.com, 1 +dollhousetoyo.com, 1 +dolliesauce.com, 1 +dolliesmaker.tk, 1 +dolly.ga, 1 +dolmencleanroom.com, 1 +dolmenejecutores.com, 1 +dolmeningenieria.com, 1 +dolorism.com, 1 +dolph.de, 1 +dolphin-cloud.com, 1 +dolphin-hosting.com, 1 +dolphin-it.de, 1 +dolys.fr, 1 +dom-byt.tk, 1 +dom-desertov.tk, 1 +dom-riviere.tk, 1 +dom.blog, 1 +dom2news.tk, 1 +dom2seychelles.tk, 1 +dom2tnt.tk, 1 +doma.in, 1 +domacikavarna.cz, 1 +domadillo.com, 1 +domain-ermittlung.de, 1 +domain-skachat.cf, 1 +domain-speicher.com, 1 +domain-speicher.de, 1 +domain-swiss.ch, 1 +domain.ch, 1 +domain001.info, 1 +domaine-aigoual-cevennes.com, 1 +domainedemiolan.ch, 0 +domainevanina.fr, 1 +domainexpress.de, 0 +domainforfree.gq, 1 +domainhacks.io, 1 +domainhostingcompany.tk, 1 +domainkauf.de, 1 +domainoo.com, 0 +domainproactive.com, 1 +domains-hoarden-ist-ein-ernstes-problem-suchen-sie-sich-hilfe.jetzt, 1 +domains.google.com, 1 +domains.lt, 1 +domainsetup.email, 1 +domainsilk.com, 1 +domainspeicher.com, 1 +domainspeicher.one, 1 +domainstaff.com, 1 +domainvoider.cf, 1 +domakidis.com, 1 +domarkperu.com, 1 +domashnie-zhiwotnye.ru, 1 +domashnij-pk.ru, 1 +domashnijpk.ru, 1 +domashniy-server.tk, 1 +domaxpoker.com, 1 +domeconseil.fr, 1 +domein-direct.com, 1 +domein-direct.nl, 1 +domeindns.nl, 1 +domekklimkowka.com, 1 +domen-reg.ru, 1 +domenaru.ga, 1 +domenic.me, 1 +domenicam.com, 1 +domfee.com, 1 +domhaase.me, 1 +domhos.tk, 1 +domian.cz, 1 +domicile-clean.fr, 1 +dominationgame.co.uk, 1 +dominctheroofguy.com, 1 +dominicandfelixroco.tk, 1 +dominicanisimo.tk, 1 +dominicanosenpr.com, 1 +dominicjackson.ga, 1 +dominicself.co.uk, 1 +dominicself.com, 1 +dominicself.uk, 1 +dominictaylor.co.uk, 1 +dominik-bergmann.de, 1 +dominik-steiner.at, 1 +dominik.st, 1 +dominikaner-vechta.de, 1 +dominioanimal.com.br, 1 +dominiopruebados.ml, 1 +dominique-haas.fr, 0 +dominobot.ir, 1 +dominobreaker.ml, 1 +dominoknihy.cz, 1 +dominolessons.ga, 1 +dominomatrix.com, 1 +domitori.tk, 1 +domix.fun, 1 +domizx.de, 1 +domjh.com, 1 +domlist.tk, 1 +dommascate.com.br, 1 +dommod.tk, 1 +domob.eu, 1 +domodeco.fr, 1 +domop.net, 1 +domop.org, 1 +domostroiy.tk, 1 +domoticzfaq.ru, 1 +domovitae.io, 1 +domovitae.nl, 1 +domowe-potrawy.pl, 1 +domowejroboty.pl, 1 +domprojects.com, 1 +domreg.lt, 1 +domscripting.com, 1 +domster.com, 1 +domucmayintainha.com.vn, 1 +domus-global.com, 1 +domus-global.cz, 1 +domvsibiri.ml, 1 +domyassignments.com, 1 +domycasestudy.com, 1 +domycoursework.com, 1 +domycreativewritings.com, 1 +domydissertations.com, 1 +domyessay.net, 1 +domyessays.com, 1 +domyhomework123.com, 1 +domyhomeworks.net, 1 +domyiadaptacje.pl, 1 +domynetwork.com, 1 +domypapers.com, 1 +domyresearchpaper.com, 1 +domyreview.net, 1 +domyspeech.com, 1 +domytermpaper.com, 1 +domythesis.net, 1 +domyzitrka.cz, 1 +domznak.ru, 1 +don-news.tk, 1 +donabeneko.jp, 1 +donacarlota.net.br, 1 +donaciondeorganos.gov, 1 +donalblaney.cf, 1 +donaldjenkins.com, 1 +donaldm.co.uk, 1 +donaldtrump.ga, 1 +donaldwarner.com, 1 +donamflor.com, 1 +donarmany.online, 1 +donateabox.org, 1 +donateaday.net, 1 +donatellapratas.com.br, 1 +donatemefunds.com, 1 +donation.ph, 1 +donatus.nl, 1 +donazione.it, 1 +dondepiso.shop, 1 +dondiabolo.com, 1 +dondibogusky.com, 1 +donera.tk, 1 +donewhen.email, 1 +donewhen.eu, 1 +donewhen.net, 1 +donewhen.nl, 1 +donewhen.org, 1 +donfelino.tk, 0 +dongcdn.com, 1 +donge.fr, 1 +donghochinhhang.store, 1 +dongor.tk, 1 +dongxuwang.com, 1 +donia-almla3b.com, 1 +donislawdev.com, 1 +donkeytrekkingkefalonia.com, 1 +donna-bellini-fotografie-wien.de, 1 +donnaandscottmcelweerealestate.com, 1 +donnabrothers.com, 1 +donnacha.blog, 1 +donnachie.net, 1 +donnapepe.tk, 1 +donner-reuschel.de, 1 +donngle.com, 1 +donnons.org, 0 +donnoval.ru, 0 +donostiweb.tk, 1 +donotcallgov.com, 1 +donotlink.it, 1 +donpanda.cz, 1 +donpietraos.tk, 1 +donpomodoro.com.co, 1 +donsremovals.com.au, 1 +dont.re, 1 +dont.watch, 1 +dontasktoask.com, 1 +dontbeevil.com, 1 +dontbubble.me, 1 +dontcageus.org, 1 +donteaetcrayons.tk, 1 +donteffwithmyvote.com, 1 +donteffwithmyvote.org, 1 +donteffwithmyvote.us, 1 +dontefwithmyvote.com, 1 +dontefwithmyvote.org, 1 +dontefwithmyvote.us, 1 +dontenedor.com, 1 +dontfuckwithmy.vote, 1 +dontfuckwithmyvote.com, 1 +dontfuckwithmyvote.net, 1 +dontfuckwithmyvote.org, 1 +dontfuckwithmyvote.us, 1 +dontfwithmy.vote, 1 +dontfwithmyvote.com, 1 +dontfwithmyvote.net, 1 +dontfwithmyvote.org, 1 +dontfwithmyvote.us, 1 +donthedragonwilson.com, 1 +dontkeylog.me, 1 +dontkillspike.tk, 1 +dontlistentoruss.com, 1 +dontpayfull.com, 1 +dontstopcoffee.com, 1 +donttrust.me, 1 +donutcompany.co.jp, 1 +donwhen.com, 1 +donwhen.email, 1 +donwhen.eu, 1 +donwhen.net, 1 +donwhen.nl, 1 +donwhen.org, 1 +donwilkssculptor.com, 1 +dooby.fr, 1 +doodle.com, 1 +dookhtaniha.ir, 1 +doolac.com, 1 +dooleylabs.com, 1 +doom.fm, 1 +doomsdaymag.tk, 1 +doomsworld.com, 1 +doomtech.net, 1 +doomus.me, 1 +doooooops.com, 1 +doop.im, 1 +doordash.com, 1 +doordash.red, 1 +doordecor.bg, 1 +doorflow.com, 1 +doorframe.com, 1 +doorgate.pt, 0 +doorhandlese.com, 1 +doorlinekktc.tk, 1 +doors-and-windows.tk, 1 +doorservice.ml, 1 +doorshingekit.com, 1 +doorswest.net, 1 +doortim.nl, 1 +doottrucks.com.au, 1 +dopesoft.de, 1 +dophys.top, 1 +dopiatku.pl, 1 +doppeleinhorn.de, 1 +doppenpost.nl, 1 +dopsi.ch, 1 +dor-tak.com, 1 +dor-tak.ru, 1 +dora.cat, 1 +dora.moe, 1 +doradocomputer.com, 1 +dorados.tk, 1 +doradoscampeon.tk, 1 +doraemonchile.tk, 1 +doramamusic.gq, 1 +doramiru.com, 1 +doranobi-fansub.id, 1 +dorco.be, 1 +dorde.eu, 1 +dordtpas.nl, 1 +dorfbrunnen.eu, 1 +dorfpark-falkenburg.de, 1 +dorfzittig.de, 1 +doriangirod.ch, 0 +dorianharmans.nl, 1 +dorianmuthig.com, 1 +doridian.com, 1 +doridian.de, 1 +doridian.net, 1 +doridian.org, 1 +dorisdeluxe.com, 1 +dorizonline.tk, 1 +dorkface.tk, 1 +dorly.blog, 1 +dormi.hu, 1 +dorminyeremenyjatek.hu, 1 +dormirmucho.com, 1 +dormitengernyikaland.hu, 1 +dormiu.com, 1 +dormiu.com.br, 1 +dormkitty.com, 1 +dornhecker.me, 1 +dorogaminina.tk, 1 +dorpshuis-dwarsgracht.nl, 1 +dorpshuiskesteren.nl, 1 +dorpsparade.tk, 1 +dorquelle.com, 1 +dorsavi.com, 1 +dorsaycreative.com, 1 +dorsetentertainments.co.uk, 1 +dorth.nl, 1 +dortmund.directory, 1 +dorwartsgarage.com, 1 +dos-team.tk, 1 +dosavor.com, 1 +dosbox.tk, 1 +dosei.net, 1 +dosenbierrepublik.com, 1 +dosenkiwi.at, 1 +dosenpintar.com, 1 +dosensosiologi.com, 1 +doserres.tk, 1 +dosgratus.tk, 1 +dosimabag.com, 1 +dosite.gq, 1 +dosje.org, 1 +doska.by, 1 +doska.cf, 1 +doska.ru, 1 +doskapozora.tk, 1 +dosomeworks.biz, 1 +dossierbaudet.nl, 1 +dossierweb.tk, 1 +dostal.co, 1 +dostalsecurity.com, 1 +dostav.tk, 1 +dostavkakurierom.ru, 1 +dostlar.fr, 1 +dosug.so, 1 +dosvientoselectric.com, 1 +dosvientoselectrical.com, 1 +dosvientoselectrician.com, 1 +dosvientosexteriorlighting.com, 1 +dosvientoslandscapelighting.com, 1 +dosvientoslighting.com, 1 +dosvientosoutdoorlighting.com, 1 +doswap.com, 1 +dosyaa.tk, 1 +dosyanet.tk, 1 +dosyauzantisi.com, 1 +dot42.no, 1 +dot9dev.com, 1 +dota2free.tk, 1 +dotacni-parazit.cz, 1 +dotadotaman.tk, 1 +dotbigbang.com, 1 +dotbox.org, 1 +dotcircle.co, 1 +dotcomtest02-single.azurewebsites.net, 1 +doterrashop.ec, 1 +dotesports.com, 1 +dotfile.tk, 1 +dotgov.gov, 1 +dothebangthingsalon.com, 1 +dothegangnamstyle.tk, 1 +dothesecurity.com, 1 +dotjesper.com, 1 +dotjesper.dk, 1 +dotjesper.net, 1 +dotjs.party, 1 +dotkniseandroida.cz, 1 +dotkod.pl, 1 +dotless.tk, 1 +dotlight.ga, 1 +dotneko.net, 1 +dotnetdocs.ir, 1 +dotnetsandbox.ca, 1 +dotphoto.com, 1 +dotplex.com, 1 +dotpoint.ga, 1 +dotrel.com, 1 +dotrox.net, 1 +dotshule.ug, 1 +dotsiam.co.th, 1 +dotsiam.com, 1 +dotsiam.in.th, 1 +dotsmesh.com, 1 +dottore.roma.it, 1 +dottormarc.it, 1 +dotya.ml, 1 +dotyk-snov.tk, 1 +dotyk.me, 1 +douai.me, 1 +douban.city, 1 +double20.gg, 1 +doubleaste.com, 1 +doubleavineyards.com, 1 +doublebangmusic.com, 0 +doublefun.net, 1 +doubleglazingmasters.com.au, 1 +doubleness.gq, 1 +doublestat.me, 1 +doubleup.com.au, 1 +doublewood.tk, 1 +doubly.tk, 1 +doubtaboutwill.org, 1 +douceurcarlet.com, 1 +doucheba.gs, 0 +doughseeker.com, 1 +douglas-ma.gov, 1 +douglascuddletoy.com, 1 +douglasrumbaugh.com, 0 +douglegomovie.tk, 1 +dougsautobody.com, 1 +doujin-domain.cz, 1 +doujin.nagoya, 1 +doujinshi.info, 1 +doujinspot.com, 1 +douzer.de, 1 +douzer.earth, 1 +douzer.industries, 1 +dovecraft.com.ua, 1 +doveholesband.co.uk, 1 +dovemoe.com, 1 +dovenzorgmalawi.nl, 1 +dovermotion.com, 1 +doverye.tk, 1 +dovetailapp.com, 1 +dovizborsa.com, 1 +dowell.media, 1 +dowellconsulting.com, 1 +dowhatmakegood.de, 1 +dowhatyoucannow.com, 1 +dowling.nz, 1 +down-load.dynu.net, 1 +downandouts.tk, 1 +downbook.org, 1 +downfall-records.tk, 1 +downfreak.tk, 1 +download-audacity.org, 1 +download-image.ga, 1 +download-knigi.gq, 1 +download.dk, 1 +downloadaja.com, 1 +downloadapk.co.id, 1 +downloadapkpokemongo.ga, 1 +downloadasik.com, 1 +downloadbestapps.com, 1 +downloadfiles.cf, 1 +downloadforum.ml, 1 +downloadforum.tk, 1 +downloadgram.com, 1 +downloadhindimovie.com, 1 +downloadhindimovie.net, 1 +downloadhindimovies.net, 1 +downloadmoremousepad.ml, 1 +downloads.zdnet.com, 1 +downloadsoftwaregratisan.com, 1 +downloadvipgames.tk, 1 +downrightcute.com, 1 +downset.tk, 1 +downtimerobot.com, 1 +downtownafrica.com, 1 +downtownautospecialists.com, 1 +downtowncharm.is, 1 +downtownsuiteliving.com, 1 +downtownvernon.com, 1 +downunderbeach.nl, 1 +downunderporn.com, 1 +downwithchina.com, 1 +dox-box.eu, 1 +doxal.ro, 1 +doxcelerate.com, 1 +doxepin1.gq, 1 +doxepinonline.gq, 1 +doxtex.com, 1 +doxyciclin.tk, 1 +doxycyclin.gq, 1 +doxycycline-online.cf, 1 +doxycycline1.gq, 1 +doxycyclinehyclate100mgcap.cf, 1 +doxycyclineprices.cf, 1 +doyarki.ga, 1 +doyleshamrock.com, 1 +doyo.email, 1 +doyo.tech, 1 +doyoucheck.com, 0 +doyoulyft.com, 1 +doyouspeakenglish.tk, 1 +doyoutax.com, 1 +doypacky.cz, 0 +doze-cloud.tech, 1 +dozecloud.com, 1 +dozens.com, 1 +dozor.ga, 1 +dozor.gq, 1 +dp.cx, 1 +dpc.fr, 1 +dpd.com.pl, 1 +dpecuador.com, 1 +dperson.net, 1 +dpfsolutionsfl.com, 1 +dpg.no, 1 +dphipartner.com, 1 +dpi-design.de, 1 +dpim.org.my, 1 +dpisecuretests.com, 1 +dpk.es, 1 +dplpmtud.com, 1 +dpm-ident.de, 0 +dpmc.govt.nz, 1 +dponetwork.nl, 0 +dposit.com, 1 +dposit.email, 1 +dposit.eu, 1 +dposit.net, 1 +dposit.org, 1 +dpower.tk, 1 +dppstar.com, 1 +dprb.biz, 1 +dpress24.it, 1 +dps.srl, 1 +dpsg-hohenlinden.de, 1 +dpsg-roden.de, 0 +dpucarriersma.gov, 1 +dpwsweeps.co.uk, 1 +dr-becarelli-philippe.chirurgiens-dentistes.fr, 1 +dr-beyer.de, 1 +dr-detailing.com, 1 +dr-diffusion.fr, 1 +dr-ermilov.com, 1 +dr-it.co.uk, 0 +dr-kissler.de, 1 +dr-klotz.info, 1 +dr-laber.at, 1 +dr-maike-juergens.de, 1 +dr-marlen-nystroem.de, 1 +dr-nystroem.de, 1 +dr-peter-jahn.de, 1 +dr-schlamminger.de, 1 +dr-schmutzer.de, 1 +dr-stoetter.de, 1 +dr-www.de, 1 +dr.mg, 1 +dr2dr.ca, 1 +draadloos-besturen.nl, 1 +draadloze-noodstop.nl, 1 +draakjefosfor.be, 1 +drabadir.com, 1 +drabbin.com, 1 +drabim.org, 1 +drach.xyz, 1 +dracheisolation.tk, 1 +drachenleder.de, 1 +dracisvet.cz, 1 +dracoon.team, 1 +dracox.com, 0 +dracula.city, 1 +draemar.com, 1 +draft.cards, 1 +draftguru.com.au, 1 +drafton.com, 1 +dragcave.net, 1 +dragdroplearning.com, 1 +dragfiles.com, 1 +draghetti.it, 1 +draghive.asia, 1 +draghive.ca, 1 +draghive.co.uk, 1 +draghive.com, 1 +draghive.net, 0 +draghive.org, 1 +draghive.tv, 1 +dragon-aspect.com, 1 +dragon-ballz.tk, 1 +dragon-chem.eu, 1 +dragon-craft.tk, 1 +dragon-hearts.co.uk, 1 +dragon-hearts.com, 1 +dragon-hearts.net, 1 +dragon.nu, 1 +dragon00.com, 1 +dragon26.com, 1 +dragon95.com, 1 +dragon98.com, 1 +dragonballzfigures.com, 1 +dragonbike.by, 1 +dragonboatfestival.tk, 1 +dragoncave.me, 1 +dragoncityhack.tips, 1 +dragonclean.gr, 1 +dragonflycms.cf, 1 +dragonfosfor.be, 1 +dragonheartsrpg.com, 1 +dragonhill.tk, 1 +dragonkin.net, 1 +dragonmoviesz.ga, 1 +dragonoid.tk, 1 +dragonprogrammer.com, 1 +dragonradar.tk, 1 +dragonraja.tk, 1 +dragonreal.estate, 1 +dragonroost.tk, 1 +dragonscale.tk, 1 +dragonshare.tk, 1 +dragonsorcerers.tk, 1 +dragonsunited.at, 1 +dragonsunited.ch, 1 +dragonsunited.de, 1 +dragonsunited.eu, 1 +dragonsunited.info, 1 +dragonsunited.net, 1 +dragonsunited.org, 1 +dragonwork.me, 1 +dragowebdesign.com, 1 +drahcro.uk, 1 +drainagedirect.com, 0 +draintechnorthwest.net, 1 +draintheswampparty.com, 1 +drainwllc.com, 1 +drak.tk, 1 +drake.partners, 1 +drakecommercial.com, 1 +drakeexcavating.com, 1 +drakeluce.com, 1 +drakencan.gq, 1 +drakenprospero.com, 0 +drakensberg-tourism.com, 1 +drakenson.de, 1 +drakfot.se, 1 +drakiada.tk, 1 +drakoraw.my.id, 1 +draliabadi.com, 1 +dramakorea.tk, 1 +dramaquarter.com, 1 +dramaslayer.ga, 1 +dramatherapie.tk, 1 +dramaticpeople.com, 1 +dramyalderman.com, 1 +dranderle.com, 1 +drandrewarnold.com, 1 +dranik.ga, 1 +dranik.ml, 1 +dranous.com, 1 +drapeauxdespays.fr, 1 +draper.wtf, 1 +dras.hu, 1 +drastik.cz, 1 +drathaisdentista.com.br, 1 +dratini0.hu, 1 +draughts64.org, 1 +draugr.de, 1 +draw.uy, 1 +drawchan.org, 1 +drawesome.uy, 1 +drawguess.fun, 1 +drawing.tk, 1 +drawingcode.net, 1 +drawtwo.gg, 1 +drawvesly.ovh, 1 +drawxp.com, 1 +draycotthotel.com, 1 +drbarnabus.com, 1 +drbenlight.com, 1 +drblog.tk, 1 +drbresnick.com, 1 +drbriones.com, 1 +drc.ua, 1 +drcardiofit.com, 1 +drcarolynquist.com, 1 +drchrislivingston.com, 1 +drchristophepanthier.com, 0 +drclub.tk, 1 +drcp.tokyo, 1 +drdavidricketts.com, 1 +drdeath.tk, 1 +drdegenhart.de, 1 +drdenisvincenzi.com.br, 1 +drdipilla.com, 1 +drdripplumbingsydney.com.au, 1 +dreadd.org, 1 +dreadfulsanity.com, 1 +dreadlocks.tk, 1 +dreadlord.tk, 1 +dream-design.tk, 1 +dream-domain.tk, 1 +dream-factory.tk, 1 +dream-pools.cf, 1 +dreamaholic.club, 1 +dreambbs.tk, 1 +dreambolivia.com, 1 +dreamboxpro.com, 1 +dreamcleaningservice.com, 1 +dreamcrack.tk, 1 +dreamday-with-dreamcar.de, 1 +dreamdestine.com, 1 +dreamdivers.com, 1 +dreamelegant.ml, 1 +dreamersgiftshopec.com, 1 +dreamfm.gr, 1 +dreamhack.com, 0 +dreamhostremixer.com, 1 +dreaming.solutions, 1 +dreamingwolf.sk, 1 +dreaminjewelz.tk, 1 +dreamlab.co.jp, 1 +dreamlandmagic.com, 1 +dreamlifeproperty.cf, 1 +dreamlinks.tk, 1 +dreamlordpress.it, 1 +dreamlux.cz, 1 +dreamlux.sk, 1 +dreammaker-nw.com, 1 +dreamof.net, 0 +dreamotis.com, 1 +dreampages.tk, 1 +dreampointech.com, 1 +dreamreality.tk, 1 +dreams-2-reality.com, 1 +dreamsea.tk, 1 +dreamsforabetterworld.com.au, 1 +dreamsinbits.com, 1 +dreamsjob.cf, 1 +dreamsolution.nl, 1 +dreamstream.nl, 1 +dreamstream.tv, 1 +dreamstream.video, 1 +dreamstudio.com, 1 +dreamstudios.tk, 1 +dreamsubmitting.tk, 1 +dreamswelcome.com, 1 +dreamsxxl.com, 1 +dreamweavers.live, 1 +dreamworldstudio.tk, 1 +dreamytheatre.com, 1 +dreamz-staging.zone, 1 +dreamz.com, 1 +dreax.win, 1 +dredwerkz.tk, 1 +dreemurr.com, 1 +drei01.com, 1 +drei01.de, 1 +drei01.technology, 1 +dreid.org, 1 +dreieich.schule, 1 +dreischneidiger.de, 1 +dreiweiden.de, 1 +dreizwosechs.de, 0 +drema.tk, 1 +drendermobilyaservisi.com, 1 +drenergysaverpdx.com, 1 +drenergysaverpnw.com, 1 +dresden-kaffee-24.de, 1 +dresden-kaffeeroesterei.de, 1 +dresdener-mandelstollen.de, 1 +dresdens-pfefferkuchenprinzessin.de, 1 +dresdner-christstollen-von-reimann.de, 1 +dresdner-kaffeeroesterei.de, 1 +dresdner-mandelstollen.de, 1 +dresdner-stollen-von-reimann.de, 0 +dresdner-stollen.shop, 1 +dress-cons.com, 1 +dressabelle.tk, 1 +dressesbal.tk, 1 +dressestore.tk, 1 +dressingmaternity.fr, 1 +dresstique.in, 1 +dreumesshakira.tk, 1 +drevo-door.cz, 0 +drevoline.com.ua, 1 +drew.beer, 1 +drew.ga, 1 +drew.life, 1 +drewapianostudio.com, 1 +drewlearns.com, 1 +drewsilcock.co.uk, 1 +drewzar.com, 1 +drexelwood.com, 1 +dreyfussplasticsurgery.com, 1 +drezzy.it, 1 +drfrey.ch, 0 +drgazeto.com.br, 1 +drgazivet.com, 1 +drgeadsdavinci.com, 1 +drghomi.com, 1 +drglassgyn.com, 1 +drgn.li, 1 +drgn.no, 1 +drgregroberts.com, 1 +drguyfacialplastics.com, 1 +drhathazi.hu, 1 +drheibel.com, 1 +drherndonent.com, 1 +drhildebrand.net, 1 +drhyler.com, 1 +drianpublishing.tk, 1 +driesjtuver.nl, 1 +driessoftsec.tk, 1 +driestwegkerk.nl, 1 +driftdude.nl, 1 +drifter.tk, 1 +driftingruby.com, 1 +driftsjournal.dk, 1 +drighes.com, 1 +drikuansvarligt.dk, 1 +drillcalendar.ga, 1 +drillingsupply.info, 1 +drillingsupplystore.com, 1 +drillion.net, 1 +drillshackresort.com, 1 +drinkcontrolapp.com, 1 +drinkgas-jihlava.cz, 1 +drinkgo.vn, 1 +drinklife.tk, 1 +drinkplanet.eu, 1 +drinkvhemp.com, 1 +driv.io, 1 +drive.google.com, 1 +drive.xyz, 1 +drivecrestwood.com, 1 +drivedannyherman.com, 1 +drivedavis.com, 1 +drivedmbowman.com, 1 +driveexport.com, 1 +driveforact.com, 1 +driveforadtransport.com, 1 +driveforartur.com, 1 +drivehub.win, 1 +drivemere.com, 1 +drivemorganvanlines.com, 1 +driven2shine.eu, 1 +drivenes.net, 1 +driventoday.com, 1 +driveoakleytransport.com, 1 +drivepaultransportation.com, 1 +driver.ru, 1 +driveral.com, 1 +driveral.hu, 1 +driverless.id, 1 +driverprofiler.co.uk, 1 +driversandsoftware.com, 1 +driverscollection.com, 1 +drivesly.in, 1 +drivestarfreight.com, 1 +drivetonortheast.com, 1 +driveyouradblockcounterup.com, 1 +driving-lessons.co.uk, 1 +drivingacademy.tk, 1 +drivingcalculator.ga, 1 +drivinginstruction.tk, 1 +drivinhors.com, 1 +drivio.co.uk, 1 +drivio.uk, 1 +drixn.info, 1 +drixn.net, 1 +drizz.com.br, 0 +drjacquesmalan.com, 1 +drjart.com, 1 +drjenafernandez.com, 0 +drjoe.ca, 1 +drjosebarrera.com, 1 +drjulianneil.com, 1 +drjungspine.com, 1 +drkansal.com, 1 +drkashany.ir, 1 +drkathrynhall.com, 1 +drkhsh.at, 0 +drkmtrx.xyz, 1 +drlandis.com, 1 +drlangsdon.com, 1 +drlevi.cf, 1 +drlevi.ga, 1 +drlinkcheck.com, 1 +drmcdaniel.com, 1 +drmonicatadros.com, 1 +drms.us, 1 +drmtransit.com, 1 +drnjewels.com, 1 +drogariasantoantonio.pt, 1 +drogariasnovafarma.com.br, 1 +drogoz.moe, 1 +droid101.com, 1 +droidandy.com, 1 +droidapp.nl, 1 +droidchart.com, 1 +droidguide.ga, 1 +droidhere.com, 1 +droidific.com, 1 +droidtuto.com, 1 +droidwars.tk, 1 +droidwiki.de, 1 +droitalecole.org, 1 +dromax.hu, 1 +dromotique.com, 1 +drone-it.net, 0 +drone-mapping.expert, 1 +drone33.fr, 1 +dronebase.cf, 1 +dronebl.org, 1 +dronedeploy.com, 1 +droneland.nl, 1 +dronepanorama.nl, 1 +dronepilotgeorgia.com, 1 +dronepit.dk, 1 +droneservices.com.fj, 1 +dronesquadcoptersales.ga, 1 +droneways.com.au, 1 +droneways.tech, 1 +droni.cz, 1 +dronix.tk, 1 +dronografia.es, 1 +dronova-art.ru, 1 +droomhuis-in-zuid-holland-kopen.nl, 1 +drop-zone.tk, 1 +drop.com, 1 +dropbox.com, 1 +dropboxer.net, 1 +dropchat.cf, 1 +dropchat.ga, 1 +dropchat.ml, 1 +dropcop.com, 1 +droperplus.com, 1 +dropeverythingrecords.com, 1 +droplen.com, 1 +dropmb.com, 1 +droppia.io, 1 +dropping-seeds.com, 1 +dropq.nl, 1 +dropscloud.spdns.de, 1 +dropshare.cloud, 1 +dropshipp.site, 1 +dropshippers.gq, 1 +dropsite.com.au, 1 +droso.dk, 1 +drosophila.tk, 1 +drost.la, 1 +drown.photography, 1 +drpa.ca, 1 +drpetersenobgynal.com, 1 +drpetervoigt.ddns.net, 1 +drpetervoigt.de, 1 +drpico.com.au, 1 +drpil.nl, 1 +drpure.top, 1 +drrachellemeaux.com, 1 +drradin.com, 1 +drrenointerior.sg, 1 +drrhonda.com, 1 +drros.ru, 1 +drrr.chat, 1 +drrr.com, 1 +drrr.wiki, 1 +drryanstanton.com, 1 +drsajjadian.com, 1 +drsamuelkoo.com, 1 +drsejf.cz, 1 +drserena.com, 1 +drshadankabiri.com, 1 +drslawfirm.com, 1 +drstephanieteotia.com, 1 +drstevenwarnock.com, 1 +drsturgeonfreitas.com, 1 +drsubbio.com, 1 +drszucs.hu, 1 +drthalhammer.at, 1 +drtimmarch.com, 1 +drtimothybradley.com, 1 +drtimothysteel.com.au, 1 +drtimothysteeljournal.com, 1 +drtimothysteelnetwork.com, 1 +drtimothysteelresults.com, 1 +drtimothysteelvideos.com, 1 +drtristanberry.com, 1 +drtti.io, 1 +drturner.com.au, 1 +drubn.de, 1 +druckerei-huesgen.de, 1 +druggist.uk, 1 +drugs.com, 1 +drugstore4you.net, 1 +drugtestingcourses.com, 1 +drugwars.tk, 1 +drugzone.tk, 1 +druides.tk, 1 +druko.cf, 1 +druko.ga, 1 +druko.gq, 1 +drum-majo-ijsselstrand.tk, 1 +drum.tk, 1 +drumbe.at, 1 +drumlines.org, 1 +drummachines.ga, 1 +drummondframing.com, 1 +drumnbass.tk, 1 +drunkcalc.com, 1 +drunkendropkes.tk, 1 +drupal-expert.it, 1 +drupal.org, 1 +drupalspb.org, 0 +drusantia.net, 1 +drusillas.co.uk, 1 +druwe.net, 0 +druznek.rocks, 1 +druznek.xyz, 1 +druzya.store, 1 +drvaidyas.com, 1 +drvr.xyz, 1 +drwang.group, 0 +drweissbrot.net, 1 +dry-cleaning.tk, 1 +drybjed.net, 1 +drybysuperior.com, 1 +drycleancoalition.org, 1 +drycreekphoto.com, 1 +drydensfairfax.com, 1 +drydor.com, 1 +drydrydry.com, 1 +dryerrepairaustin.com, 1 +dryerventcleaningarlington.com, 1 +dryerventcleaningcarrollton.com, 1 +dryip.com, 1 +dryjersey.com, 1 +drymx.cn, 1 +drywallresponse.gov, 1 +drywtea.com, 1 +dryzgov.tk, 1 +ds-hostingsolutions.net, 1 +ds-statistik.de, 1 +ds.lol, 1 +ds138.cc, 1 +ds168.cc, 1 +ds28s.com, 1 +ds388.cc, 1 +ds67.de, 1 +ds915.com, 1 +dsa.cy, 1 +dsad209.ml, 1 +dsaengineering.com, 1 +dsancomics.com, 1 +dsayce.com, 1 +dsbcnet.com, 1 +dsble.de, 1 +dsbutler.de, 1 +dscharrer.com, 1 +dschwarzachtaler.de, 1 +dscmotorsport.co.za, 1 +dscsigncert.com, 1 +dsds-ltd.com, 0 +dsebastien.net, 1 +dsektionen.se, 0 +dsg.lol, 1 +dsg.red, 1 +dsg.work, 1 +dsgarms.com, 1 +dsgholsters.com, 1 +dsgnet.hu, 1 +dsgvo-addon.eu, 1 +dsgvo.name, 1 +dshield.org, 1 +dsiteam.in, 1 +dsm5.com, 1 +dsmjs.com, 1 +dsmnet.org, 1 +dsn-it.com, 1 +dsn-k.com, 1 +dso-izlake.si, 1 +dsol.hu, 1 +dsouzamusic.com, 1 +dspace.pl, 1 +dspnor.com, 1 +dspretoria.co.za, 1 +dspropertyservicesltd.co.uk, 1 +dsreal.de, 1 +dsswise.org, 1 +dstamou.de, 1 +dsteiner.at, 1 +dstvinstallkemptonpark.co.za, 1 +dsuinnovation.com, 1 +dsv-salesmanager.de, 1 +dtbouncycastles.co.uk, 1 +dtbw.eu, 1 +dtbw.net, 1 +dtbw.org, 1 +dtcp8.com, 1 +dtdsh.com, 1 +dtf.digital, 1 +dtg-fonds.com, 1 +dtg-fonds.de, 1 +dtg-fonds.net, 1 +dtgmns.com, 1 +dtinel.org, 1 +dtk-vom-chausseehaus.de, 1 +dtleague.eu, 1 +dtmbnl.com, 1 +dtmbx.com, 1 +dtmbx.email, 1 +dtmbx.eu, 1 +dtmbx.net, 1 +dtmbx.nl, 1 +dtmbx.org, 1 +dtmf.io, 1 +dtmlnp.com, 1 +dtngny.com, 1 +dtnx.email, 1 +dtnx.eu, 1 +dtnx.net, 1 +dtnx.org, 1 +dtnxny.com, 1 +dtrifonov.cf, 1 +dtuaarsfest.dk, 1 +dtune.me, 1 +dtx.sk, 1 +du-alex.ru, 1 +dual-universe.ga, 1 +dual.pw, 0 +dualascent.com, 1 +dualbix.com, 1 +dualias.xyz, 0 +duama.top, 1 +duan.li, 0 +duanre.tk, 1 +duansunshinesdiamond.com, 1 +duarteeleiteconsultoria.com.br, 1 +dubai-company.ae, 1 +dubaibliss.com, 1 +dubaizone.cf, 1 +dubaosheng.com, 1 +dubbingkursus.dk, 1 +dubl.tk, 1 +dublinrail.tk, 1 +duboisinternational.com, 1 +duboisinvestissements.com, 1 +dubrava.tk, 1 +dubridgeweb.be, 1 +dubrovnikfoodtours.com, 1 +dubrovskiy.cf, 1 +dubrovskiy.net, 1 +dubrovskiy.pro, 1 +dubslow.tk, 1 +dubstep.fr, 1 +dubtrack.fm, 1 +dubuquecountyiowa.gov, 1 +dubyou.tw, 1 +ducadu.com, 1 +ducalendars.com, 1 +duch.cloud, 1 +duchyoffeann.com, 1 +ducius.net, 1 +duckbase.com, 1 +duckblade.com, 1 +duckcorp.org, 1 +duckduck.horse, 1 +duckduckstart.com, 1 +duckfam.us, 1 +duckfx.tk, 1 +duckinc.net, 1 +duckman.tk, 1 +duckonthepond.com, 1 +ducksify.com, 1 +ducksoft.fi, 1 +duckstad.net, 1 +duckyubuntu.tk, 1 +ductcare.com, 1 +dudedood.tk, 1 +dudeexpert.cf, 1 +dudesunderwear.com.br, 0 +due-diligence-security.com, 1 +duelingaces.com, 1 +duellin.tv, 1 +duelsow.eu, 1 +duenas.cat, 1 +duerlund-falkenberg.dk, 1 +duerlundfalkenberg.dk, 1 +duernberg.at, 0 +dues-eckert.com, 1 +duesee.org, 1 +duesseldorf.tk, 1 +duesseldorferheineburschenschaft.tk, 1 +duesterhus.eu, 1 +duffau.net, 1 +dufrei.com, 1 +dug.net.pl, 1 +duggtec.com, 1 +dugnet.io, 0 +dugnet.net, 0 +dugnet.tech, 0 +dugunedavet.com, 1 +dugwood.com, 1 +duh.se, 1 +duhini.ru, 1 +duhivip.ml, 1 +duijf.info, 1 +duijf.io, 1 +duijfathome.nl, 1 +duitang.com, 1 +dujsq.com, 1 +dukan-recepty.ru, 1 +dukatek.cz, 1 +duke-nukem.tk, 1 +dukeandduchessdrivingschool.co.uk, 1 +dukegat.de, 0 +dukeipai.org, 1 +dukeofmetal.tk, 1 +dukers-baelemans.nl, 0 +dukun.de, 1 +dulanic.com, 1 +dulcinea.tk, 1 +dulcinela.es, 1 +dulei.si, 1 +dullapp.com, 1 +duloxetinbestellen.gq, 1 +duloxetine.gq, 1 +dulse.fr, 1 +dum.moe, 1 +dumax.fr, 1 +dumax.xyz, 1 +dumb-laws.net.ru, 1 +dumbeartech.com, 1 +dumberger-bau.de, 1 +dumbfunded.co.uk, 1 +dumboverflow.com, 1 +dumfriespropertyservices.co.uk, 0 +dumino.bg, 1 +dumping.tk, 1 +dumpper.ch, 1 +dumpper.com, 1 +dumspiro.ch, 1 +duna.com.co, 1 +dunamiscommunity.com, 1 +dunangel.com, 1 +dunberghof.tk, 1 +duncancmt.com, 1 +duncanfamilytrust.org, 1 +duncanmoffat.com, 1 +duncanwinfrey.com, 1 +dunce.cf, 1 +duncm.com, 1 +dundalk.ie, 1 +dundalkdonnie.com, 1 +dundalkskillnet.ie, 1 +dundeerecycling.ca, 1 +dunedot.tk, 1 +dunesadventure.net, 1 +dunescorporation.tk, 1 +dungbui.co, 0 +dungbui.net, 1 +dungeon-bbs.de, 1 +dungeoncity.com, 1 +dungeonfire.tk, 1 +dunklau.fr, 1 +dunkle-seite.org, 1 +dunmanelectric.com, 1 +dunmanpoolandspa.com, 1 +dunneworthy.com, 1 +dunyahalleri.com, 1 +duo.com, 1 +duobus.nl, 1 +duodeno.tk, 1 +duohao.xyz, 1 +duoluodeyu.com, 1 +duonganhtuan.com, 1 +duoqichina.cn, 1 +duoqichina.com, 1 +duoquadragintien.fr, 1 +duoyin.com, 1 +dupforex.com, 1 +dupfx.com, 1 +dupisces.com.tw, 1 +duplicazionechiavi.it, 1 +duplika.com, 0 +dupree.co, 1 +dupuis.xyz, 1 +durabletravailler.tk, 1 +duraes.pt, 0 +duramaximportaciones.com, 1 +duranceofhate.com, 1 +durand.tf, 1 +durand.tk, 1 +durangoenergyllc.com, 1 +duranthon.eu, 1 +durbanlocksmiths.co.za, 1 +durcal.tk, 1 +durchblick-shop.de, 1 +durdal.no, 1 +durdle.com, 1 +duredo.com, 0 +dureuil.info, 1 +durexwinkel.nl, 1 +durfteparticiperen.nl, 1 +durganews.com, 1 +duria.de, 1 +duriaux-dentiste.ch, 0 +duriemas.com, 1 +durin-art.com, 1 +duroterm.ro, 1 +durulezzetler.com, 1 +durys.be, 1 +dushu.cat, 1 +duskraven.tk, 1 +dusmomente.com, 1 +dusnan.com, 1 +dust.bio, 1 +dust4you.tk, 1 +dustbox.tk, 1 +dustpla.net, 1 +dustplanet.de, 1 +dustri.org, 0 +dustshop.tk, 1 +dusty.gr, 1 +dustycloth.com, 1 +dustygroove.com, 1 +dustyro.se, 1 +dustyspokesbnb.ca, 1 +dutabisnis.com, 1 +dutabisniz.com, 0 +dutch.desi, 1 +dutch1.nl, 1 +dutchassistancedogs.nl, 1 +dutchbeautyacademy.nl, 1 +dutchcariblaw.nl, 1 +dutchconcreations.com, 1 +dutchfoodie.nl, 1 +dutchforkrunners.com, 1 +dutchpentathlon.nl, 1 +dutchperformanceproducts.nl, 1 +dutchplayers.com, 1 +dutchsailors.com, 1 +dutchskinning.nl, 1 +dutchwanderers.nl, 1 +dutchweballiance.nl, 1 +duthywines.com, 1 +dutkoteam.com, 1 +dutrac.co.id, 1 +duttur.com, 1 +dutyfreeinformation.com, 1 +duv.al, 1 +duval.info, 1 +duval.li, 1 +duval.ovh, 1 +duval.paris, 1 +duval.pm, 1 +duval.re, 1 +duvalo.eu, 1 +duvalo.info, 1 +duvalo.net, 1 +duvalo.org, 1 +duvalo.sk, 1 +duxbow.de, 0 +duxi-s-feromonami.ga, 1 +duyao.de, 0 +duysondang.name.vn, 1 +duzavo.cz, 1 +dv189.com, 1 +dvbris.co.uk, 1 +dvbris.com, 1 +dvclub.tk, 1 +dvdinmotion.com, 1 +dvdland.com.au, 1 +dvdmania.ga, 1 +dveri-lugansk.tk, 1 +dvhosting.be, 1 +dvipadmin.com, 1 +dvn.pt, 1 +dvnatura.ch, 0 +dvor.ml, 1 +dvorek-karlin.cz, 1 +dvorekkarlin.cz, 1 +dvorupotocnych.sk, 1 +dvotx.org, 1 +dvprogram.us, 1 +dvwc.org, 1 +dvx.cloud, 1 +dw-loewe.de, 0 +dwaallicht.tk, 1 +dwarf.com.tw, 1 +dweb.link, 1 +dweilorkest-frederikshaven.tk, 1 +dwgf.xyz, 1 +dwhightmolina.com, 1 +dwi-sued.de, 1 +dwnld.me, 1 +dwood.store, 1 +dworzak.ch, 1 +dwp-solutions.nl, 1 +dwscdv3.com, 1 +dwt-inc.com, 1 +dwtf.de, 1 +dwtm.ch, 1 +dwword.com, 0 +dwworld.co.uk, 1 +dwwt.eu, 1 +dwwt.net, 1 +dwwt.nl, 1 +dwwt.org, 1 +dwz-solutions.com, 1 +dwz-solutions.de, 1 +dwz-solutions.eu, 1 +dwz-solutions.net, 1 +dwz.wtf, 1 +dx-revision.com, 1 +dx2o.com, 1 +dxa.io, 0 +dxgl.info, 1 +dxgl.org, 1 +dxm.no-ip.biz, 1 +dxtours.com, 1 +dxzsj.cn, 1 +dy.express, 1 +dy1d.com, 1 +dyachenko.ml, 1 +dybuster.at, 1 +dybuster.ch, 1 +dybuster.com, 1 +dybuster.de, 1 +dybuster.es, 1 +dybuster.it, 1 +dybuster.se, 1 +dycoa.com, 1 +dyeager.org, 1 +dyktig.as, 1 +dyktig.no, 1 +dylan-motorcross.tk, 1 +dylan-park.com, 1 +dylandeconinck.cf, 1 +dylangattey.com, 1 +dylanhansch.net, 1 +dylankatz.com, 1 +dylanknoll.ca, 1 +dylanscott.com.au, 1 +dylanspcrepairs.com, 1 +dylanuwr.pl, 1 +dylanwise.net, 1 +dylanwolff.com, 1 +dylmye.me, 0 +dylnuge.com, 1 +dym.asia, 1 +dym.bz, 1 +dym2012.com, 1 +dym2013.com, 1 +dym2014.com, 1 +dym2017.com, 1 +dymdajce.ovh, 1 +dymersion.com, 1 +dymfbbs.com, 1 +dymmovie.com, 1 +dymovskiy.ru, 1 +dymowski.de, 0 +dyn-dnhensel.de, 1 +dyn-nserve.net, 1 +dyn.im, 1 +dynabob.tk, 1 +dynacrop.space, 1 +dynadns.de, 1 +dynalab.pl, 1 +dynaloop.net, 0 +dynamic-movie.com, 1 +dynamic-networks.be, 1 +dynamicathletes.ga, 1 +dynamicbusinessconsultants.ga, 1 +dynamicconsultantsgroup.com, 1 +dynamicdesignuk.com, 1 +dynamicpl.us, 1 +dynamicplus.it, 1 +dynamicsdays.info, 1 +dynamicsnetwork.net, 1 +dynamicsretailnotes.com, 1 +dynamictostatic.com, 1 +dynamicyou.co.uk, 1 +dynamisk.dk, 1 +dynamitejobs.com, 1 +dynamofanforum.de, 1 +dynapptic.com, 1 +dynasoft.co.ke, 1 +dynastic.co, 1 +dynasty-warriors.net, 1 +dynastybreaks.com, 1 +dynastyredzone.com, 1 +dynatos-cloud.com, 1 +dyncdn.me, 1 +dyneco.io, 1 +dynet.ru, 1 +dynn.be, 0 +dynocc.xyz, 1 +dynorphin.com, 1 +dynorphins.com, 1 +dynsoundmax.tk, 1 +dynts.pro, 1 +dynx.pl, 1 +dypromed.com, 1 +dyregrave.dk, 1 +dyremyhr.no, 1 +dyrenesverden.no, 1 +dyrkar.com, 1 +dyrstad.net, 1 +dys-coaching.com, 1 +dysautonomia-postsyndrome.com, 1 +dyscalculia-blog.com, 1 +dysthymia.com, 1 +dyuimovochka.tk, 1 +dyxe.me, 1 +dyykkarit.tk, 1 +dyyn.de, 1 +dyz.pw, 1 +dz6729.com, 1 +dz6957.com, 1 +dzar.nsupdate.info, 1 +dzeina.ch, 0 +dzet.de, 1 +dziaduch.pl, 1 +dziary.com, 1 +dziekonski.com, 1 +dzimchuk.net, 1 +dziscover.com, 1 +dziura.me, 1 +dziurdzia.pl, 1 +dzmonarchie.tk, 1 +dzndk.net, 1 +dzndk.org, 1 +dznn.nl, 1 +dzomo.org, 0 +dzsi.bi, 0 +dzsibi.com, 1 +dzsula.hu, 1 +dzu.fund, 1 +dzu.life, 1 +dzus.tk, 1 +dzworld.com, 1 +dzyabchenko.com, 1 +dzyszla.pl, 1 +dzz.by, 1 +e-account.by, 1 +e-alink.com, 1 +e-alive.com, 1 +e-antikvar.tk, 1 +e-bags.tk, 1 +e-balloons.tk, 1 +e-baraxolka.ru, 1 +e-belgia.tk, 1 +e-beyond.de, 1 +e-bikesdirect.co.uk, 1 +e-biografias.net, 1 +e-bodybuilding.tk, 1 +e-boekhouden.nl, 1 +e-bookshelf.de, 1 +e-borneoshop.com, 1 +e-boss.tk, 1 +e-branchekoden.dk, 1 +e-buro.tk, 1 +e-classroom.tk, 1 +e-coexist.com, 1 +e-colle.info, 1 +e-copys.com, 1 +e-cottage.com.br, 1 +e-daftar.com, 1 +e-dengi.tk, 1 +e-diabolo.tk, 1 +e-diapers.tk, 1 +e-diasporan.cf, 1 +e-dv.eu, 1 +e-emploi.be, 1 +e-enterprise.gov, 1 +e-estonia.com, 1 +e-facture.net, 1 +e-fireplaces.tk, 1 +e-fishing.tk, 1 +e-fitnes.tk, 1 +e-games-board.tk, 1 +e-gemeinde.at, 1 +e-geologia.tk, 1 +e-global.pt, 0 +e-guardian.com.br, 1 +e-hair.tk, 1 +e-havenotime.tk, 1 +e-homebiz.tk, 1 +e-id.ee, 1 +e-informatyk.tk, 1 +e-interactivenet.tk, 1 +e-interview.tk, 1 +e-islam.tk, 1 +e-jackets.tk, 1 +e-jewelrys.tk, 1 +e-kartinki.tk, 1 +e-klempir.cz, 1 +e-knitting.tk, 1 +e-knitwear.tk, 1 +e-lambre.com, 1 +e-lamp.tk, 1 +e-learningbs.com, 1 +e-lifetechnology.com, 1 +e-loshadka.tk, 1 +e-mak.eu, 1 +e-massage.tk, 1 +e-medicines.tk, 1 +e-michiganinsurance.com, 1 +e-migration.ch, 1 +e-nail.tk, 1 +e-nanum.kr, 1 +e-nature.tk, 1 +e-node.net, 1 +e-node.ru, 1 +e-osago.ru, 1 +e-otdyx.tk, 1 +e-peeling.tk, 1 +e-peets.tk, 1 +e-placement.tk, 1 +e-planshet.tk, 1 +e-pokupki.eu, 1 +e-polygraphy.tk, 1 +e-privat.info, 1 +e-procurement.co.mz, 1 +e-ptn.com, 1 +e-receta.cl, 1 +e-recruitment.tk, 1 +e-referendum.cz, 1 +e-repairs.tk, 1 +e-resident.gov.ee, 1 +e-rest.tk, 1 +e-sauna.tk, 1 +e-servicerms.com, 1 +e-shonai.com, 1 +e-slots.tk, 1 +e-smile.tk, 1 +e-sneakers.tk, 1 +e-speak24.pl, 1 +e-standardstore.org, 1 +e-student.tk, 1 +e-styling.tk, 1 +e-surety.net, 1 +e-sushi.net, 1 +e-sweaters.tk, 1 +e-tables.tk, 1 +e-tablets.tk, 1 +e-teacher.pl, 1 +e-teachers.me, 1 +e-tech-solution.com, 1 +e-tech-solution.net, 1 +e-techsolution.com, 1 +e-techsolutions.net, 1 +e-tires.tk, 1 +e-tmf.org, 1 +e-tonery.cz, 1 +e-top.uz, 1 +e-traceur-france.fr, 1 +e-transformer.tk, 1 +e-tresor.at, 1 +e-trucking.tk, 1 +e-tune-mt.net, 1 +e-typ.eu, 1 +e-umbrellas.tk, 1 +e-underwear.tk, 1 +e-vau.de, 0 +e-verify.gov, 1 +e-webos.com, 0 +e-wishlist.net, 1 +e-worksmedia.com, 0 +e-yachts.tk, 1 +e-zine.tk, 1 +e.gg, 1 +e.ki, 1 +e.mail.ru, 1 +e00228.com, 1 +e15r.co, 1 +e27.co, 1 +e2ebrindes.com.br, 1 +e2electric.ir, 1 +e2essentialelements.com, 1 +e2feed.com, 1 +e30.ee, 1 +e30365.com, 0 +e30gruppe.com, 1 +e365.vip, 1 +e36533.com, 1 +e3q.de, 1 +e4.chat, 1 +e42.org, 1 +e4work.com.br, 1 +e5197.co, 1 +e5tv.hu, 1 +e5xbps.com, 1 +e6729.co, 1 +e6729.com, 1 +e6957.co, 1 +e6e.io, 1 +e6web.com, 1 +e7180.com, 1 +e7d.io, 1 +e7fun.net, 1 +e81365.com, 1 +e82365.com, 1 +e899365.com, 1 +e8bet.net, 1 +e901.com, 0 +e9297.co, 1 +e9397.com, 1 +e9582.com, 1 +e965.ru, 1 +e9728.co, 1 +ea-lateleassistance.com, 1 +ea2drocks.com, 1 +eac.gov, 1 +eac010.com, 1 +eac020.com, 1 +eac021.com, 1 +eac022.com, 1 +eac023.com, 1 +eac024.com, 1 +eac025.com, 1 +eac027.com, 1 +eac028.com, 1 +eac029.com, 1 +eac0310.com, 1 +eac0311.com, 1 +eac0312.com, 1 +eac0313.com, 1 +eac0314.com, 1 +eac0315.com, 1 +eac0316.com, 1 +eac0317.com, 1 +eac0318.com, 1 +eac0319.com, 1 +eac0335.com, 1 +eac0350.com, 1 +eac0351.com, 1 +eac0352.com, 1 +eac0353.com, 1 +eac0354.com, 1 +eac0355.com, 1 +eac0356.com, 1 +eac0357.com, 1 +eac0358.com, 1 +eac0359.com, 1 +eac0370.com, 1 +eac0371.com, 1 +eac0372.com, 1 +eac0373.com, 1 +eac0374.com, 1 +eac0375.com, 1 +eac0376.com, 1 +eac0377.com, 1 +eac0378.com, 1 +eac0379.com, 1 +eac0391.com, 1 +eac0392.com, 1 +eac0393.com, 1 +eac0394.com, 1 +eac0395.com, 1 +eac0396.com, 1 +eac0398.com, 1 +eac0410.com, 1 +eac0411.com, 1 +eac0412.com, 1 +eac0413.com, 1 +eac0414.com, 1 +eac0415.com, 1 +eac0416.com, 1 +eac0417.com, 1 +eac0418.com, 1 +eac0419.com, 1 +eac0421.com, 1 +eac0427.com, 1 +eac0429.com, 1 +eac0431.com, 1 +eac0432.com, 1 +eac0433.com, 1 +eac0434.com, 1 +eac0435.com, 1 +eac0436.com, 1 +eac0437.com, 1 +eac0438.com, 1 +eac0439.com, 1 +eac0440.com, 1 +eac0450.com, 1 +eac0451.com, 1 +eac0452.com, 1 +eac0453.com, 1 +eac0454.com, 1 +eac0455.com, 1 +eac0456.com, 1 +eac0457.com, 1 +eac0458.com, 1 +eac0459.com, 1 +eac0470.com, 1 +eac0471.com, 1 +eac0472.com, 1 +eac0473.com, 1 +eac0474.com, 1 +eac0475.com, 1 +eac0476.com, 1 +eac0477.com, 1 +eac0478.com, 1 +eac0479.com, 1 +eac0482.com, 1 +eac0483.com, 1 +eac0510.com, 1 +eac0511.com, 1 +eac0512.com, 1 +eac0513.com, 1 +eac0514.com, 1 +eac0515.com, 1 +eac0516.com, 1 +eac0517.com, 1 +eac0518.com, 1 +eac0519.com, 1 +eac0523.com, 1 +eac0530.com, 1 +eac0531.com, 1 +eac0532.com, 1 +eac0533.com, 1 +eac0534.com, 1 +eac0535.com, 1 +eac0536.com, 1 +eac0537.com, 1 +eac0538.com, 1 +eac0539.com, 1 +eac0550.com, 1 +eac0551.com, 1 +eac0552.com, 1 +eac0553.com, 1 +eac0554.com, 1 +eac0555.com, 1 +eac0556.com, 1 +eac0557.com, 1 +eac0558.com, 1 +eac0559.com, 1 +eac0561.com, 1 +eac0562.com, 1 +eac0563.com, 1 +eac0564.com, 1 +eac0565.com, 1 +eac0566.com, 1 +eac0570.com, 1 +eac0571.com, 1 +eac0572.com, 1 +eac0573.com, 1 +eac0574.com, 1 +eac0575.com, 1 +eac0576.com, 1 +eac0577.com, 1 +eac0578.com, 1 +eac0579.com, 1 +eac0580.com, 1 +eac0591.com, 1 +eac0592.com, 1 +eac0593.com, 1 +eac0594.com, 1 +eac0595.com, 1 +eac0596.com, 1 +eac0597.com, 1 +eac0598.com, 1 +eac0599.com, 1 +eac0660.com, 1 +eac0661.com, 1 +eac0662.com, 1 +eac0663.com, 1 +eac0691.com, 1 +eac0692.com, 1 +eac0701.com, 1 +eac0710.com, 1 +eac0711.com, 1 +eac0712.com, 1 +eac0713.com, 1 +eac0714.com, 1 +eac0715.com, 1 +eac0716.com, 1 +eac0717.com, 1 +eac0718.com, 1 +eac0719.com, 1 +eac0722.com, 1 +eac0724.com, 1 +eac0728.com, 1 +eac0730.com, 1 +eac0731.com, 1 +eac0732.com, 1 +eac0733.com, 1 +eac0734.com, 1 +eac0735.com, 1 +eac0736.com, 1 +eac0737.com, 1 +eac0738.com, 1 +eac0739.com, 1 +eac0743.com, 1 +eac0744.com, 1 +eac0745.com, 1 +eac0746.com, 1 +eac0751.com, 1 +eac0752.com, 1 +eac0753.com, 1 +eac0754.com, 1 +eac0755.com, 1 +eac0756.com, 1 +eac0757.com, 1 +eac0758.com, 1 +eac0759.com, 1 +eac0760.com, 1 +eac0762.com, 1 +eac0763.com, 1 +eac0765.com, 1 +eac0766.com, 1 +eac0768.com, 1 +eac0769.com, 1 +eac0770.com, 1 +eac0771.com, 1 +eac0772.com, 1 +eac0773.com, 1 +eac0774.com, 1 +eac0775.com, 1 +eac0776.com, 1 +eac0777.com, 1 +eac0778.com, 1 +eac0779.com, 1 +eac0790.com, 1 +eac0791.com, 1 +eac0792.com, 1 +eac0793.com, 1 +eac0794.com, 1 +eac0795.com, 1 +eac0796.com, 1 +eac0797.com, 1 +eac0798.com, 1 +eac0799.com, 1 +eac0810.com, 1 +eac0811.com, 1 +eac0812.com, 1 +eac0813.com, 1 +eac0814.com, 1 +eac0816.com, 1 +eac0817.com, 1 +eac0818.com, 1 +eac0819.com, 1 +eac0826.com, 1 +eac0827.com, 1 +eac0830.com, 1 +eac0831.com, 1 +eac0832.com, 1 +eac0833.com, 1 +eac0834.com, 1 +eac0835.com, 1 +eac0836.com, 1 +eac0837.com, 1 +eac0838.com, 1 +eac0839.com, 1 +eac0840.com, 1 +eac0851.com, 1 +eac0852.com, 1 +eac0853.com, 1 +eac0854.com, 1 +eac0855.com, 1 +eac0856.com, 1 +eac0857.com, 1 +eac0858.com, 1 +eac0859.com, 1 +eac0870.com, 1 +eac0871.com, 1 +eac0872.com, 1 +eac0873.com, 1 +eac0874.com, 1 +eac0875.com, 1 +eac0876.com, 1 +eac0877.com, 1 +eac0878.com, 1 +eac0879.com, 1 +eac0881.com, 1 +eac0883.com, 1 +eac0886.com, 1 +eac0887.com, 1 +eac0888.com, 1 +eac0890.com, 1 +eac0891.com, 1 +eac0898.com, 1 +eac0899.com, 1 +eac0910.com, 1 +eac0911.com, 1 +eac0912.com, 1 +eac0913.com, 1 +eac0914.com, 1 +eac0915.com, 1 +eac0916.com, 1 +eac0917.com, 1 +eac0930.com, 1 +eac0931.com, 1 +eac0932.com, 1 +eac0933.com, 1 +eac0934.com, 1 +eac0935.com, 1 +eac0936.com, 1 +eac0937.com, 1 +eac0938.com, 1 +eac0941.com, 1 +eac0943.com, 1 +eac0951.com, 1 +eac0952.com, 1 +eac0953.com, 1 +eac0954.com, 1 +eac0971.com, 1 +eac0972.com, 1 +eac0973.com, 1 +eac0974.com, 1 +eac0975.com, 1 +eac0976.com, 1 +eac0977.com, 1 +eac0991.com, 1 +eac222.com, 1 +eac333.com, 1 +eac444.com, 1 +eac555.com, 1 +eacero.com, 1 +ead-italia.it, 1 +eagar.com.au, 1 +eagle-yard.de, 1 +eaglecountyco.gov, 1 +eagleindustriesltd.com, 1 +eaglemessaging.com, 1 +eaglemoe.com, 1 +eaglenation.net, 1 +eagleridgecampground.com, 1 +eaglerockseattle.com, 1 +eagletechz.com.br, 1 +eaglewreck.info, 1 +eaglexiang.org, 1 +eagleyecs.com, 1 +eaimty.com, 1 +ealadel.com, 1 +ealev.de, 1 +eames-clayton.us, 1 +eamigo.com, 1 +eamproperties.com, 1 +eanraig.top, 1 +eaofcarrollton.com, 1 +eapcounselling.com.au, 1 +earfolds.com, 1 +earlybetter.com, 1 +earlyimage.com.au, 1 +earlyvoting.gq, 1 +earlyyearshub.com, 1 +earmarks.gov, 1 +earn.wiki, 1 +earn99.co, 1 +earningthatis.tk, 1 +earth-people.org, 1 +earth-quake.tk, 1 +earthcorporation.cf, 1 +earther.com, 1 +earthpixz.com, 1 +earthpoints.org, 1 +earthsocialism.org, 1 +earthspundesigns.com, 1 +earthsystemprediction.gov, 1 +earticleblog.com, 1 +eas.ee, 1 +easaccounting.com, 1 +easew.com, 1 +eashwar.com, 1 +eason-yang.com, 1 +east-line.su, 1 +eastarm.net, 1 +eastbaycontractor.com, 1 +eastblue.org, 1 +eastbourne-eip.org, 1 +eastcairo-egypt.com, 1 +eastcoastbubbleandbounce.co.uk, 1 +eastcoastexports.tk, 1 +eastdream.tk, 1 +eastendonline.tk, 1 +eastheaven.ml, 1 +eastlothianbouncycastles.co.uk, 1 +eastmaintech.com, 1 +eastnorschool.co.uk, 1 +easton.ga, 1 +eastpeoria-il.gov, 1 +eastping.com, 1 +eastplan.co.kr, 1 +eastportcorp.tk, 1 +eastprovidenceri.gov, 1 +eastshare.ml, 1 +eastside.tk, 1 +eastsidecottages.co.uk, 1 +eastsideroofingcontractor.com, 1 +eaststudios.net, 1 +eastwesttmc.com.au, 1 +eastyorkshirebuses.co.uk, 1 +easukasbestos.co.uk, 1 +easy-affiliations.tk, 1 +easy-company.tk, 1 +easy-design.tk, 1 +easy-factures.fr, 1 +easy-katka.ga, 1 +easy-rpg.org, 0 +easyadsnbanners.tk, 0 +easybot.tk, 1 +easybrazilianrecipes.com, 1 +easycoding.org, 1 +easyconstat.com, 1 +easycontentplan.com, 1 +easycredit.se, 1 +easycrochet.tk, 1 +easydoityourself.com, 1 +easydumpsterrental.com, 0 +easyeditcms.com, 1 +easyenrollment.net, 1 +easyfiles.ch, 1 +easyfiles.gq, 1 +easyit.ga, 1 +easylinker.tk, 1 +easylogics.tk, 1 +easymeditation.tk, 1 +easymotionskin-japan.jp, 1 +easymun.com, 1 +easyocm.hu, 1 +easyonlinetest.tk, 1 +easypay.bg, 1 +easypayment.cf, 1 +easypaymentnow.com, 1 +easypayments.pro, 1 +easypets.fr, 0 +easypricebook.com, 1 +easypv.ch, 1 +easyqr.codes, 1 +easyradio.gq, 1 +easyreal.ru, 1 +easyserver.io, 1 +easyshare.gq, 1 +easyslide.be, 1 +easysoft.tk, 1 +easystore.co, 1 +easysubmit.tk, 1 +easytechguides.com, 1 +easytestonline.tk, 1 +easytext.ga, 1 +easytrackghana.com, 1 +easytube.ga, 1 +easyweenies.com, 1 +easywin.ml, 1 +easywio.com, 1 +eat-sleep-code.com, 1 +eat-the-world.ch, 1 +eatery.co.il, 1 +eatfitoutlet.com.br, 1 +eatinghouz.com, 1 +eatinglinks.tk, 1 +eatingonions.com, 1 +eatmebudapest.hu, 1 +eaton-works.com, 1 +eatry.io, 1 +eats.soy, 1 +eatsleeprepeat.net, 1 +eatson.com, 1 +eatz-and-treatz.com, 1 +eaucube.com, 1 +eaugalliediscountpharmacy.com, 1 +eaugenethomas.cf, 1 +eautocollision.com, 1 +eautolease.com, 1 +eauxdespleiades.ch, 0 +eazyfreight.co.uk, 1 +eazyg.tk, 1 +eazyinvoice.tk, 1 +eazyproject.net, 1 +eazytailors.ga, 1 +eb-net.de, 1 +eb7.jp, 1 +ebabis.cz, 1 +ebaby.bg, 1 +ebaifzf.com.br, 1 +ebankcbt.com, 1 +ebanking.indovinabank.com.vn, 1 +ebankingabersicher.ch, 1 +ebankingbutsecure.ch, 1 +ebankingentoutesecurite.ch, 1 +ebankingmasicuro.ch, 1 +ebas.ch, 1 +ebashim.tk, 1 +ebataw.com, 1 +ebayinc.com, 1 +ebcfx.com, 1 +ebcue.org, 1 +ebenda.org, 1 +ebenezersbarnandgrill.com, 1 +ebenvloedaanleggen.nl, 1 +ebermannstadt.de, 0 +ebertlang.com, 1 +eberwe.in, 1 +ebest.co.jp, 1 +ebikemod.de, 1 +ebill.pl, 1 +ebino.pl, 1 +ebiografia.com, 1 +ebiografias.com.br, 1 +ebisee.com, 1 +ebisi.be, 1 +ebizarts.com, 1 +ebjork.se, 1 +eblog.cf, 1 +eblog.ink, 1 +eboardsolutions.com, 1 +ebola-hosting.cz, 1 +ebolacharts.ga, 1 +ebolavirus.tk, 1 +ebonyriddle.com, 1 +eboocker.de, 1 +ebookabc.tk, 1 +ebookdrive.tk, 1 +ebooki.eu.org, 1 +ebooknetworking.net, 1 +ebooks-pdf.cf, 1 +ebooks4all.tk, 1 +ebooksa.com, 1 +ebooksbag.com, 1 +ebooksgratis.tk, 1 +ebooksgratuits.org, 1 +ebooksinfocus.com, 1 +ebooksmile.net, 1 +ebookspy.tk, 1 +ebooktoan.com, 1 +ebookweb.gq, 1 +ebop.ch, 1 +ebpgateway.com, 1 +ebpglobal.com, 0 +ebrnd.de, 1 +ebrowz.com, 1 +ebuha.ga, 1 +ebuku.tk, 1 +eburg.ml, 1 +ec-baran.de, 1 +ec-current.com, 1 +ec.ath.cx, 1 +ec.mine.nu, 1 +ecaa.ee, 1 +ecamisetas.com.br, 1 +ecampusontario.ca, 1 +ecarch.cf, 1 +ecard.ml, 1 +ecardoo.com, 1 +ecardoo.de, 1 +ecardoo.net, 1 +ecardoo.org, 1 +ecarscash.com, 1 +ecaterina.tk, 1 +ecbt.co.il, 1 +ecchidreams.com, 1 +eccma.org, 1 +eccologic.net, 1 +eccux.com, 1 +ecdn.cz, 1 +ecelembrou.ovh, 1 +ecfnorte.com.br, 1 +ecfunstalls.com, 1 +ecgclic.fr, 1 +echarity.ae, 1 +echarlascartas.es, 1 +echbay.com, 1 +echelle-escamotable.info, 1 +echi.pw, 1 +echidna-rocktools.eu, 1 +echidna-usa.com, 0 +echidna.com.au, 1 +echinus.solutions, 1 +echo-in.info, 1 +echo-n.nz, 1 +echo-security.co, 1 +echo.cc, 1 +echo.co.uk, 0 +echoanalytics.com, 1 +echobridgepartners.com, 1 +echodio.com, 1 +echofoxtrot.co, 1 +echoit.net, 1 +echoit.net.au, 1 +echoit.services, 1 +echopaper.com, 1 +echorain.net, 1 +echorecovery.org, 1 +echosim.io, 1 +echosixmonkey.com, 1 +echosnature.fr, 1 +echosystem.fr, 1 +echotango.fr, 1 +echoteam.gq, 1 +echoteam.ml, 1 +echoworld.ch, 0 +echtebewertungen.com, 1 +echternach-immobilien.de, 1 +echtes-hutzelbrot.de, 1 +ecigfind.com, 1 +ecirtam.net, 0 +eciso.io, 1 +eckel.co, 1 +eckotech.fr, 1 +eckstein.tech, 1 +eclecticbeaver.com, 1 +eclectiv.com, 1 +eclipse.ws, 1 +eclipse4academia-startups.com, 1 +eclipseba.com, 1 +eclipseforum.tk, 1 +eclypsium.io, 0 +ecn.ir, 1 +ecnetworker.com, 1 +eco-derattizzazione.it, 1 +eco-flowplumbing.com, 1 +eco-repair.be, 1 +eco-solu.co.jp, 1 +eco-wiki.com, 1 +eco-work.it, 1 +eco2u.ru, 1 +eco69.com, 1 +eco69.eu, 1 +eco69.pl, 1 +ecobin.nl, 1 +ecobrotherss.com, 1 +ecoc2021.org, 1 +ecoccinelles.ch, 0 +ecoccinelles.com, 0 +ecoconut.org, 1 +ecocreativity.org, 1 +ecocuisinedesign.com, 1 +ecodedi.com, 1 +ecodepur.co.ao, 1 +ecodepur.fr, 1 +ecodesign-labo.jp, 1 +ecodesigns.nl, 1 +ecodigital.social, 1 +ecoeuropa.cf, 1 +ecofac-bs.com, 1 +ecoformeurope.com, 1 +ecofriendlytravels.com, 1 +ecogarden.design, 1 +ecogen.com.au, 1 +ecogen.net.au, 1 +ecohaus-pinklao-salaya.com, 1 +ecohaus-wongwaen-lumlukka.com, 1 +ecoheatcool.co.uk, 1 +ecohimdv.tk, 1 +ecohomebuild.org, 1 +ecohostingservices.uk, 1 +ecohousejapan.com, 1 +ecojob.ga, 1 +ecolala.my, 1 +ecolan37.ru, 1 +ecole-attalens.ch, 0 +ecole-iaf.fr, 0 +ecole-saint-yves-rennes.fr, 1 +ecoledusabbat.org, 0 +ecolemathurincordier.com, 0 +ecologiahoy.com, 1 +ecologica.it, 1 +ecologikashop.com, 1 +ecologiya.tk, 1 +ecombustibil.ro, 1 +ecomia.dk, 1 +ecommercefastlane.com, 1 +ecomonline.ru, 1 +ecomoov.com, 1 +ecompen.co.za, 1 +ecomycie.com, 1 +econativa.pt, 1 +econmarketingdigital.com, 1 +economiafinanzas.com, 1 +economias.pt, 1 +economic-sanctions.com, 1 +economicnews.ga, 1 +economics-colleges.com, 1 +economie2.alsace, 1 +economiefidu.ch, 0 +economies.ch, 0 +economixportal.tk, 1 +economycarrentalscyprus.com, 1 +economydiva.com, 1 +economyroofingco.com, 1 +econsorzio.com, 1 +econstitution.bg, 1 +econsumer.gov, 1 +ecoon.net, 1 +ecopak.org, 1 +ecorak.de, 1 +ecorp-australia.tk, 1 +ecorp.cc, 1 +ecos-ev.de, 1 +ecos.srl, 1 +ecosas.org, 1 +ecosdesociedad.tk, 1 +ecoshare.info, 1 +ecosial.org, 1 +ecosistema.ai, 1 +ecoskif.ru, 1 +ecosoftconsult.com, 0 +ecosound.ch, 0 +ecostarfoam.com, 1 +ecostruxureit.com, 1 +ecosuperb.com, 1 +ecosystem.atlassian.net, 1 +ecosystemmanager-uat1.azurewebsites.net, 1 +ecotecelevator.com, 1 +ecotransfer.bio, 1 +ecotur.org, 1 +ecoturismo.tk, 1 +ecoupakovka.ga, 1 +ecourbano.tk, 1 +ecovetawindoors.com, 1 +ecovision.com.br, 1 +ecowoman-armenian.tk, 1 +ecowoman-bengalian.tk, 1 +ecowoman-indonezian.tk, 1 +ecowoman-turkey.tk, 1 +ecowoman-ukraine.tk, 1 +ecozona.tk, 1 +ecpannualmeeting.com, 1 +ecpic.gov, 1 +ecr-test-partnapp.azurewebsites.net, 1 +ecrandouble.ch, 0 +ecredits-dev-app-backoffice01.azurewebsites.net, 1 +ecredits-dev-app-partner01.azurewebsites.net, 1 +ecriminalrecords.com, 1 +ecrownoffire.com, 1 +ecstaticentertainment.com, 1 +ecsupplyinc.com, 1 +ectopic.info, 1 +ectora.com, 1 +ectpro.co.th, 1 +ecuadorbienesraices.com, 1 +ecuadorextremo.com, 1 +ecuadorlibrered.tk, 1 +ecuapaginas.com, 1 +ecubr.com, 1 +ecup.mx, 1 +ecxforum.com, 1 +eczanemheryerde.com, 1 +ed-studios.tk, 1 +ed.gs, 1 +eda.gov, 1 +edailystar.com, 1 +edam.org.tr, 1 +edapt.org.uk, 1 +edas.info, 0 +edcaptain.com, 1 +edchart.com, 1 +edd-miles.com, 1 +eddesign.ch, 1 +eddie.website, 1 +eddmil.es, 1 +eddokloosterman.com, 1 +eddsworld.tk, 1 +eddyn.net, 0 +eddysystem.tk, 1 +edeals.co, 1 +edeals.co.com, 1 +edeals.com.co, 1 +edeca.net, 1 +edefrutos.me, 1 +edefrutos2020.com, 1 +edegulkoyu.tk, 1 +edehsa.com, 1 +edeka-jbl-treueaktion.de, 1 +edelveiys.tk, 1 +edelweiss-pinzolo.com, 1 +eden-project-insight.tk, 1 +eden.bz, 1 +eden.co.uk, 1 +edenfactory.tk, 1 +edenming.info, 1 +edenvaleplumber24-7.co.za, 1 +eder-steiner.at, 1 +edesseglabor.hu, 1 +edfinancial.com, 1 +edgarz.tk, 1 +edgebilisim.com, 1 +edgecustomersportal.com, 1 +edgedynasty.com, 1 +edgeless.pp.ua, 0 +edgelogs.com, 1 +edgeservices.co.uk, 1 +edgetalk.net, 1 +edgezzz.com, 1 +edh.email, 1 +edhesive.com, 1 +edholm.pub, 1 +edi-gate.com, 1 +edi-gate.de, 1 +edibarcode.com, 1 +edibleforest.co, 1 +edicct.com, 1 +edicionescrimentales.tk, 1 +edihair.com, 1 +edik.tk, 1 +edilane.com, 1 +edilane.de, 1 +edilservizi.it, 1 +edilservizivco.it, 1 +edinburghsportsandoutdoorlearning.com, 1 +edincmovie.com, 1 +edirnehaber.tk, 1 +edirnehaberleri.tk, 1 +edisa.xyz, 1 +ediscomp.sk, 1 +edisonchee.com, 1 +edisongroup.ru, 1 +edisonlee55.com, 1 +edisonluiz.com, 1 +edisonnissanparts.com, 1 +edisonstreet.com, 1 +edit.co.uk, 1 +edit.yahoo.com, 0 +edited.de, 1 +edition-bambou.com, 0 +edition-sonblom.de, 1 +editionsnoiretrouge.com, 1 +editoraacademiacrista.com.br, 1 +editorakanope.com.br, 1 +editorialnew.com, 1 +editorinleaf.com, 1 +edlinger.at, 1 +edlinger.mobi, 1 +edlinus.cn, 1 +edman007.com, 1 +edmedications.tk, 1 +edmm.jp, 1 +edmoncu.com, 1 +edmundcelis.com, 1 +edok.com.br, 1 +edoss.co.za, 0 +edp-collaborative.com, 1 +edplan.io, 1 +edr-d.expert, 1 +edragneainpuscarie.ro, 1 +edrepay.com, 1 +edrosd.cf, 1 +edrost.tk, 1 +edsby.com, 1 +edscolors.com, 1 +edservicing.com, 1 +edshogg.co.uk, 1 +edsm.net, 1 +edstem.org, 1 +edstep.com, 1 +edtech-hub.com, 1 +edtech.ee, 1 +edtechwebb.com, 1 +edu6.cloud, 1 +eduard-dopler.de, 1 +eduardnikolenko.com, 1 +eduardnikolenko.ru, 1 +eduardofranco-luthier.tk, 1 +eduart.tk, 1 +edubase.net, 1 +edubirdie.com, 1 +edublognews.tk, 1 +educa2.es, 1 +educabis.tk, 1 +educacionnm.ml, 1 +educacionvirtual.com.ar, 1 +educaestado.com, 1 +educalis.altervista.org, 1 +educanada.in, 1 +educatek.es, 1 +educateyourskin.com, 1 +education-info.cf, 1 +educationconnect.tk, 1 +educationdepartment.ml, 1 +educationevolving.org, 1 +educationfirst.ml, 1 +educationfutures.com, 1 +educationhighquality.ml, 1 +educationism.tk, 1 +educationmalaysia.co.uk, 1 +educationone.ml, 1 +educationsupport.org.uk, 1 +educationtree.tk, 1 +educationweek.tk, 1 +educative.io, 1 +educator-one.com, 1 +educators.co.nz, 1 +educatoys.com.br, 1 +educbook.ga, 1 +educlove.com, 1 +educnum.fr, 1 +eductf.org, 1 +edufrog.it, 1 +edugeton.com, 1 +eduid.se, 1 +eduif.nl, 0 +edularidea.com, 1 +edularism.com, 1 +edulinks.ml, 1 +edumaritime.net, 1 +edumaster.pro, 1 +edumerson.com, 1 +edunaut.com.au, 1 +edunet.gq, 1 +edunian.com, 1 +edupedia.vn, 1 +eduproject.tk, 1 +eduroam.no, 1 +eduroam.org, 1 +eduroam.uy, 1 +edusanjal.com, 1 +eduschool.ml, 1 +edusercontent.com, 1 +edusitios.com, 0 +eduson.pl, 1 +edutrum.com, 1 +eduxpro.com, 1 +edv-biela.de, 1 +edv-lehrgang.de, 1 +edv-ringhofer.de, 1 +edv-schmittner.de, 1 +edvance.co.za, 1 +edvgarbe.de, 1 +edvmesstec.de, 1 +edward-tagle.tk, 1 +edwardbrowninvestment.tk, 1 +edwardkong.top, 1 +edwards.me.uk, 1 +edwardscommercialcleaning.com, 1 +edwardsgrounds.co.uk, 1 +edwardsnowden.com, 1 +edwardspeyer.com, 1 +edwardwall.me, 1 +edweb.tk, 1 +edwellbrook.com, 1 +edwinlugo.gq, 1 +edwinmattiacci.com, 1 +edwinroelvink.tk, 1 +edwinyrkuniversity.de, 1 +edxg.de, 0 +edxn.de, 1 +edyhenry.tk, 1 +edyou.eu, 1 +edyou.org, 1 +edzilla.info, 1 +edzo.dk, 1 +ee-terminals.com, 1 +ee00228.com, 1 +ee362.com, 1 +ee367.com, 1 +ee371.com, 1 +ee372.com, 1 +ee373.com, 1 +ee396.com, 1 +ee397.com, 1 +ee5197.co, 1 +ee575.com, 1 +ee631.com, 1 +ee632.com, 1 +ee6729.co, 1 +ee6729.com, 1 +ee6957.co, 1 +ee736.com, 1 +ee9297.co, 1 +ee9397.com, 1 +ee951.com, 1 +ee9721.com, 1 +ee9728.co, 1 +ee973.com, 1 +eeb98.com, 1 +eebt.hu, 1 +eeeeeeeeee.de, 1 +eeetrust.org, 1 +eehitus.ee, 1 +eekelen.net, 1 +eelcapone.nl, 1 +eellak.gr, 1 +eelsaspets.com, 1 +eelsden.net, 1 +eelzak.nl, 1 +eemcevn.com, 1 +eemoor.com, 1 +een-eenvoudige-test-voor-de-maximum-lengte-van-een-nederlandse.nl, 1 +eencompass.com, 1 +eentertain.com.my, 1 +eentweevijf.be, 1 +eenvren.com, 1 +eenvxing.com, 1 +eeqj.com, 1 +eer.io, 1 +eerstejaarsweekend.nl, 1 +eerstemaanlanding.tk, 1 +eery.de, 1 +eesti.xyz, 1 +eet.nu, 1 +eetestingcenter.com, 1 +eewna.org, 1 +eez.ee, 1 +ef.gy, 1 +efaas.nl, 1 +efag.com, 1 +efay.ml, 1 +efcross.com, 1 +efe.name.tr, 1 +efektyvnist.pro, 1 +eff-bee-eye.de, 1 +eff.org, 1 +effdocs.com, 1 +effe.ch, 0 +effective-altruist.com, 1 +effectivecoffee.com, 1 +effectivecommunication.tk, 1 +effectivepapers.com, 1 +effer.me, 1 +effex.ru, 1 +effexorgeneric.ml, 1 +effiasoft.com, 0 +efficientsolutions.tk, 1 +effinfun.com, 1 +efflam.net, 1 +effortlesshr.com, 1 +effortlesshr.net, 1 +eficsolar.com, 1 +efinity.io, 1 +efipsactiva.com, 1 +efleetcare.com.au, 1 +eflorashop.be, 1 +eflorashop.ch, 1 +eflorashop.co.uk, 1 +eflorashop.com, 1 +eflorashop.de, 1 +eflorashop.es, 1 +eflorashop.fr, 1 +eflorashop.it, 1 +eflorashop.mx, 1 +eflorashop.net, 1 +eflorashop.us, 1 +efmcredentialing.org, 1 +efmo.de, 1 +efoood.org, 1 +eforw.com, 1 +efp.nl, 1 +efs-auto.com, 1 +eft.boutique, 1 +eftcorp.biz, 1 +eftelingcraft.net, 1 +eftopia.org, 1 +efutbol.tk, 1 +eg7.co.jp, 1 +eg7.jp, 1 +egablo.black, 1 +egabroaventuras.tk, 1 +egarden.it, 1 +egb.at, 0 +egbc.ca, 1 +egbert.net, 1 +egdigital.com.au, 1 +egedebirgun.com, 1 +egegesh.ru, 1 +egeozcan.com, 1 +egevpare.tk, 1 +egfl.org.uk, 1 +egg-ortho.ch, 1 +eggblast.com, 1 +eggendorfer.at, 1 +eggendorfer.be, 1 +eggendorfer.biz, 1 +eggendorfer.ch, 1 +eggendorfer.co.uk, 1 +eggendorfer.de, 1 +eggendorfer.info, 1 +eggendorfer.it, 1 +eggendorfer.li, 1 +eggendorfer.name, 1 +eggendorfer.net, 1 +eggendorfer.online, 1 +eggendorfer.org, 1 +eggendorfer.pro, 1 +eggendorfer.rocks, 1 +eggendorfer.tv, 1 +eggendorfer.uk, 1 +eggendorfer.us, 1 +eggendorfer.wine, 1 +eggert.org, 1 +egglestonyouthcenter.org, 1 +eggman.tk, 1 +eggqvq.com, 1 +eggrolls.ml, 1 +eggzr.com, 1 +egh.ir, 1 +egiftcards.be, 1 +egilopaseryh.tk, 1 +egittophilia.tk, 1 +egles.eu, 1 +eglisedenantes.fr, 1 +egm-sakura.com, 1 +ego4u.com, 1 +ego4u.de, 1 +egold-keeper.com, 1 +egomania.tk, 1 +egomaniaque.tk, 1 +egonews.ga, 1 +egonix.de, 1 +egorazarkevich.ga, 1 +egorka.ml, 1 +egoroskope.tk, 1 +egoscolumn.tk, 1 +egotripproductions.org, 1 +egov4.ch, 1 +egovernment-podcast.com, 1 +egregius.be, 1 +egres.xyz, 1 +egretail.no, 0 +egrojsoft.info, 1 +egrp365.ru, 1 +egsl.pro, 1 +egt-bg.com, 1 +egt.ee, 1 +egw-ceramica.de, 1 +egweb.tv, 1 +egyhometex.com, 1 +egypt-tourism.ga, 1 +egypte.tk, 1 +egyptenet.tk, 1 +egypteweb.tk, 1 +egyptexposed.tk, 1 +egyptian.gq, 1 +egytimes.tk, 1 +egzekucija.tk, 1 +ehaccp.it, 1 +ehazi.hu, 1 +ehbsecuritydavy.be, 1 +ehbssl.com, 1 +ehcommerce.com, 1 +ehcommerce.org, 1 +ehealth.gov.au, 1 +eheliche-disziplin.schule, 1 +ehipaa.com, 1 +ehlersdanlos.tk, 1 +ehmsen.nu, 1 +ehmtheblueline.com, 1 +ehne.de, 1 +ehome.im, 1 +ehometools.com, 1 +ehomusicgear.com, 1 +ehorizon.jp, 1 +ehr.gov, 1 +ehrenburg.info, 1 +ehrlichesbier.de, 1 +ehtgov.org, 1 +ehtp.pt, 1 +ehtu.tk, 1 +ehub.cz, 1 +ehub.hu, 1 +ehub.pl, 1 +ehub.sk, 1 +ehuber.info, 1 +ei-bo.org, 1 +eiao.me, 1 +eiber.net, 1 +eichel.eu, 1 +eichendorffschule.online, 1 +eichinger-stelzl.com, 1 +eichinger-stelzl.de, 1 +eichler.work, 1 +eickemeyer.nl, 1 +eickhof.co, 1 +eickhof.us, 1 +eickhofcolumbaria.com, 1 +eidelpes.info, 1 +eifel.website, 1 +eigenbubi.de, 1 +eigenetiket.tk, 1 +eigenpul.se, 1 +eigenpulse.com, 1 +eightballde.luxe, 1 +eightvirtues.tk, 1 +eighty-aid.com, 1 +eightyfour.ca, 1 +eightyfour.pictures, 1 +eightysoft.de, 1 +eigpropertyauctions.co.uk, 1 +eihaikyo.com, 1 +eiji.fr, 1 +eikentafels.nl, 1 +eikerposten.no, 1 +eikounoayumi.jp, 1 +eilhan.com, 1 +eimacs.com, 1 +eimmigration.com, 1 +ein-erbe-fuer-jeden.de, 1 +einaros.is, 1 +eine-andere-welt.org, 1 +einfach-fitz.at, 1 +einfachbahn.de, 1 +einheft.info, 1 +einheizpreis.de, 1 +einhorn.space, 1 +einkaufi.de, 1 +einmonolog.de, 1 +einomanner.com, 1 +einreiseanmeldung.de, 1 +einrichtwerk.de, 1 +einsatzstiefel.info, 1 +einscube.com, 1 +einser.com, 1 +einsteinathome.org, 1 +einsteincapital.ca, 1 +einsteins.tk, 1 +eintageinzug.de, 1 +eipione.com, 1 +eirastudios.co.uk, 0 +eirb.fr, 1 +eirik.eu, 1 +eisaev.ru, 1 +eisblau.org, 1 +eisei-iinkai.com, 1 +eisen-biomed.ch, 1 +eisenbahnfreunde-lengerich.de, 1 +eisenberg.co.za, 1 +eisenhowerlibrary.gov, 1 +eisernes-kreuz.tk, 1 +eiskratzer-bedrucken.de, 0 +eit-solutions.com.au, 1 +eit-web.de, 0 +eiti.online, 1 +eiyoushi-shigoto.com, 1 +ej.uz, 1 +ejcabinets.com, 1 +ejderrapgott.de, 1 +ejdv-anmeldung.de, 1 +ejelectrical-qld.com.au, 1 +ejit.eu, 1 +ejkhosting.nl, 1 +ejkmedia.nl, 1 +ejkmuseum.nl, 1 +ejknet.nl, 1 +ejkwebdesign.nl, 1 +ek-networks.de, 0 +ekaigotenshoku.com, 1 +ekalisch.de, 1 +ekati.ru, 1 +ekawaiishop.com, 1 +ekcrags.ru, 1 +ekd.de, 1 +ekdoseis.gr, 1 +ekeblock.com, 1 +ekedc.com, 1 +ekedp.com, 1 +ekhabar.ml, 1 +ekimaeseitai.com, 1 +ekimma.com, 1 +eklepka.com, 1 +eklitzke.org, 1 +eko-vitalis.ru, 1 +eko69.pl, 1 +ekobudisantoso.net, 1 +ekocleaningllc.com, 1 +ekoclin.com, 1 +ekogroszekpieklo.pl, 1 +ekokpandm.tk, 1 +ekole.shop, 1 +ekologija.tk, 1 +ekonbenefits.com, 1 +ekong366.com, 1 +ekonomska.tk, 1 +ekostecki.de, 1 +ekouniejow.pl, 1 +ekowibowo.com, 1 +ekpj.jp, 1 +ekranos.me, 1 +ekre.club, 1 +eksbaks.com, 1 +eksisozluk.com, 1 +eksk.pl, 1 +eksploraz.com, 1 +ekspoint-mods.ru, 1 +eku.com.tr, 1 +ekvastra.in, 1 +ekwgroup.co.uk, 1 +ekyu.moe, 1 +ekz-crosstour.ch, 1 +ekzarta.ru, 0 +ekzcrosstour.ch, 1 +ekzotika.tk, 1 +el-cell.com, 1 +el-hossari.com, 1 +el-mundo.tk, 1 +el-soul.com, 0 +elaax.de, 0 +elabela.com.br, 1 +elad.wtf, 1 +eladalfassa.com, 1 +eladlak-ingatlan.com, 1 +eladvardi.co.il, 1 +elagplus.com, 1 +elaheze.com, 0 +elahp.com.br, 1 +elahuehuete.art, 1 +elainefroese.com, 1 +elainerock.com, 1 +elakiri.cf, 1 +elalmibar.com, 1 +elaon.de, 0 +elarmariodelucia.com, 1 +elars.de, 1 +elartedelapaz.org, 1 +elarvee.xyz, 1 +elastiekschieten.tk, 1 +elaxy-online.de, 1 +elazighaber.tk, 1 +elb500ttl.nl, 1 +elbaal.gov, 1 +elbersdometechniek.tk, 1 +elbetech.net, 1 +elbiaadmin.sk, 1 +elbitsystems.com, 1 +elbohlyart.com, 1 +elboogieboutique.com, 1 +elbrus.ooo, 1 +elbrus360.ru, 1 +elburgozagalicos.com, 1 +elbvision.de, 1 +elchamandelaprosperidad.org, 1 +elcin.tk, 1 +elcirculo.mx, 1 +elcontadorsac.com, 1 +elcozinante.com, 1 +eldenelesat.com, 1 +eldercare.gov, 1 +eldercaring.ca, 1 +elderjustice.gov, 1 +elderreviews.gq, 1 +elderscrolls.tk, 1 +eldertons.co.uk, 1 +eldevo.com, 1 +eldiariodemof.com, 0 +eldiedesign.com, 1 +eldisagjapi.de, 1 +eldoradocylinders.com, 1 +eldoradoinsurance.com, 1 +eldrid.ge, 1 +ele-sm.com, 1 +elecpromo.com, 1 +electerious.com, 1 +electicofficial.com, 0 +electionpresidentiellegabon2009.ga, 1 +electionrunners.com, 1 +electionsbycounty.com, 1 +electionsdatabase.com, 1 +electr0sheep.com, 1 +electragirl.com, 1 +electras.cf, 1 +electric-clippers.tk, 1 +electric-samara.tk, 1 +electric-vault.co.uk, 1 +electricagoura.com, 1 +electricagourahills.com, 1 +electrical-schools.com, 1 +electricalagoura.com, 1 +electricalagourahills.com, 1 +electricalandelectronicsengineerinformation.ga, 1 +electricalcalabasas.com, 1 +electricalcamarillo.com, 1 +electricalconejovalley.com, 1 +electricaldosvientos.com, 1 +electricalfencingbedfordview.co.za, 1 +electricalfencingedenvale.co.za, 1 +electricalhiddenhills.com, 1 +electricallakesherwood.com, 1 +electricalmalibu.com, 1 +electricalmoorpark.com, 1 +electricalnewburypark.com, 1 +electricaloakpark.com, 1 +electricalpacificpalisades.com, 1 +electricalsimivalley.com, 1 +electricalthousandoaks.com, 1 +electricalwestlakevillage.com, 1 +electricannihilation.tk, 1 +electricbeast.co, 1 +electriccalabasas.com, 1 +electriccamarillo.com, 1 +electriccitysf.com, 1 +electricconejovalley.com, 1 +electricdosvientos.com, 1 +electricfencebenoni.co.za, 1 +electricfireplaces.tk, 1 +electricgatemotorsalberton.co.za, 1 +electricgatemotorskemptonpark.co.za, 1 +electricgypsies.nl, 1 +electrichiddenhills.com, 1 +electrichome.fr, 0 +electrician-umhlangaridge.co.za, 1 +electricianagoura.com, 1 +electricianagourahills.com, 1 +electricianbedfordview.co.za, 1 +electricianboksburg24-7.co.za, 1 +electriciancalabasas.com, 1 +electriciancamarillo.com, 1 +electricianconejovalley.com, 1 +electriciandosvientos.com, 1 +electricianedenvale24-7.co.za, 1 +electriciangermiston24-7.co.za, 1 +electricianhiddenhills.com, 1 +electriciankemptonpark24-7.co.za, 1 +electricianlakesherwood.com, 1 +electricianlalucia.co.za, 1 +electricianmalibu.com, 1 +electricianmidrand24-7.co.za, 1 +electricianmoorpark.com, 1 +electriciannewburypark.com, 1 +electricianoakpark.com, 1 +electricianpacificpalisades.com, 1 +electriciansimivalley.com, 1 +electricianthousandoaks.com, 1 +electricianwestlakevillage.com, 1 +electricienasnieres.fr, 1 +electricimagination.co.uk, 1 +electricit.uk, 1 +electricity.tk, 1 +electriclakesherwood.com, 1 +electricmalibu.com, 1 +electricmoorpark.com, 1 +electricnewburypark.com, 1 +electrico.tk, 1 +electricoakpark.com, 1 +electricpower.tk, 1 +electricsimivalley.com, 1 +electricthousandoaks.com, 1 +electricwestlakevillage.com, 1 +electro-pak.com.pk, 1 +electrocomplect.com.ua, 1 +electrodomesticos.tk, 1 +electrodomesticosmiro.com, 1 +electrodvig.ru, 1 +electroforum.tk, 1 +electrolivefest.spb.ru, 1 +electromagnetism.gq, 1 +electromenager.tk, 1 +electromotor.tk, 1 +electronic-ignition-system.com, 1 +electronicafacil.net, 1 +electronicayseguridadmonserrate.com, 1 +electronicfasteners.com, 0 +electronicssrit.tk, 1 +electronictucuman.com, 1 +electroniko.cf, 1 +electronis.ru, 1 +electronmag.tk, 1 +electroservice.co.za, 1 +electrosoftcloud.com, 1 +electrostatics.com, 1 +electrotainment.com, 1 +electroworld.cz, 1 +electrum.org, 1 +eled.io, 1 +elefantebrasil.com.br, 1 +elefantevoador.com, 1 +elegance-lingerie.com, 1 +elegance-sm.com, 1 +elegancecement.com, 1 +eleganceperfumes.com.br, 1 +elegant-design.tk, 1 +elegantlatex.tk, 1 +elegantly-clean.co.uk, 1 +elegro.cz, 1 +eleicoes2014.com.br, 1 +eleicoes2016.com.br, 1 +eleicoes2018.com, 1 +elejordemarketingconsultancy.com, 1 +eleken.jp, 1 +elekharris.com, 1 +elektriker-notdienst-zentrale.de, 1 +elektro-adam.de, 1 +elektro-diehm.de, 1 +elektro-doerr.com, 1 +elektro-hammes.net, 1 +elektro-hofmann-gmbh.de, 1 +elektro-hornetz.de, 1 +elektro-kahlen.de, 1 +elektro-koehl.de, 1 +elektro-liebeskind.de, 1 +elektro-metz.de, 1 +elektro-pfeiffer.de, 1 +elektro-praha10.cz, 1 +elektro-rossbach.de, 1 +elektro-roth.de, 1 +elektro-stock.de, 1 +elektro-woerdehoff.de, 1 +elektrobusch.com, 1 +elektroclub.tk, 1 +elektrofinke.de, 1 +elektroistrument.tk, 1 +elektrokarges.de, 1 +elektrolang.com, 1 +elektrolety.com, 1 +elektrolety.cz, 1 +elektrometz.de, 1 +elektromont.tk, 1 +elektromotor.tk, 1 +elektronickakancelar.cz, 1 +elektronische-post.org, 1 +elektropartner.nu, 1 +elektropost.org, 1 +elektroprom.tk, 1 +elektrotango.tk, 1 +elektrotechnik-heisel.de, 1 +elektrotechnik-kaetzel.de, 1 +elektrotechnik-schreck.de, 1 +elektrownie-tanio.net, 1 +elemenop.tk, 1 +element.io, 1 +elemental.software, 1 +elementalengine.com, 1 +elementalengine.org, 1 +elementalengines.com, 1 +elementalengines.org, 1 +elementalrobotics.com, 1 +elementalsoftware.net, 1 +elementalsoftware.org, 1 +elementarewatson.it, 1 +elementarium.cf, 1 +elementarium.ga, 1 +elementarty.com, 1 +elementarywave.com, 1 +elementblend.com, 0 +elementbookings.com, 1 +elementoraddons.com, 1 +elementricks.com, 1 +elements-space-time.com, 1 +elements.guide, 1 +elementshop.co.uk, 1 +elementsoftware.tk, 1 +elena-paparizou.tk, 1 +elena-risteska.tk, 1 +elena-soset.cf, 1 +elena-soset.ga, 1 +elena-soset.ml, 1 +elena-soset.tk, 1 +elenagherta.ga, 1 +elenamuerza.com, 1 +elenapulizieroma.it, 1 +elenaristeska.tk, 1 +elenaristeskaweb.tk, 1 +elenashilko.ga, 1 +elenaskincarespa.com, 1 +elenatranslations.nl, 1 +elenatroncone.tk, 1 +elenavoce.cf, 1 +elencinar.tk, 1 +elenorsmadness.org, 1 +elenta.lt, 1 +eleonardo.tk, 1 +eleonoraanzini.tk, 1 +eleonoramazzola.com, 1 +eleonorapapallo.tk, 1 +eleonorengland.com, 1 +eleonrp.tk, 1 +elephantia.cf, 1 +elephants.net, 1 +elephants.tk, 1 +elephantstone.net, 1 +elepover.com, 1 +eletesstilus.hu, 1 +eletminosegert.ro, 1 +eletor.com, 1 +eletor.pl, 1 +eletrotel.com, 1 +elettricista-roma.it, 1 +elettricista-roma.org, 1 +elettricista.roma.it, 1 +elettricisti.roma.it, 1 +elettrodomestici.roma.it, 1 +elettrolinkimpianti.it, 1 +elettronicagroup.com, 1 +eleusis-zur-verschwiegenheit.de, 1 +elev8fashion.ca, 1 +elevacionesrama.com, 1 +elevateandprosper.com, 1 +elevatedconstructionltd.com, 1 +elevationcreative.net, 1 +elevationplumbingandheating.com, 1 +elevationtech.co.za, 1 +elevator.ee, 1 +elevatoraptitudetest.com, 1 +elevenensemble.tk, 1 +elevenpaths.com, 1 +elexel.ru, 1 +elexprimidor.com, 1 +elexxos.com, 1 +elfe.de, 1 +elforno.gr, 1 +elfranco.tk, 1 +elfring.eu, 1 +elftoy.com, 1 +elfuerteclamor.org, 1 +elfussports.com, 1 +elgalponazo.com.ar, 1 +elgargajo.tk, 1 +elgenero.com, 1 +elgin.tk, 1 +elgoog.im, 1 +elgosblanc.com, 1 +elgrecohotel.gr, 1 +elgringosrentals.com, 1 +elguadia.faith, 0 +elguillatun.cl, 1 +elgustdecreixer.cat, 1 +elgustodecrecer.es, 1 +elhamadimi.com, 1 +elherraderoloscabos.com, 1 +elhorizontal.com, 1 +elhossari.com, 1 +elia.cloud, 1 +elias-erdmann.tk, 1 +eliasfox.com, 1 +eliasfranklinn.tk, 1 +eliasojala.me, 1 +eliasong.com, 1 +eliav.tk, 1 +elibidore.ml, 1 +elibom.com, 1 +elie.net, 1 +elielaloum.com, 1 +elifesciences.org, 1 +eligasht.com, 1 +eligibilis.com, 1 +eligible.com, 1 +eligibleapi.com, 1 +eligrey.com, 1 +elijahbrown.tk, 1 +elijahgrey.com, 1 +elijahzawesome.casa, 1 +elikers.ml, 1 +elimidrol.com, 1 +eliminations.tk, 1 +eliminercellulite.com, 1 +elimitecreamforsale.ga, 1 +elindependiente.co.cr, 1 +eline168.com, 1 +elinevanhaaften.nl, 1 +elinformatico.tk, 1 +elink.io, 1 +elinvention.ovh, 1 +eliolita.com, 1 +eliott.cc, 1 +eliottlavier.com, 1 +elisa.ee, 0 +elisabeth-kostecki.de, 1 +elisabeth-raendel.de, 1 +elisabeth-strunz.de, 1 +elisabethbegle.at, 1 +elisabethborgermans.com, 1 +elisabethcasanova.ch, 1 +elisabethkostecki.de, 1 +elisabethrene.com, 1 +elisechristie.com, 1 +elit-fitnes.tk, 1 +elit-host.tk, 1 +elite-design.tk, 1 +elite-forums.tk, 1 +elite-nakhodka.tk, 1 +elite-porno.ru, 1 +elite-tools.tk, 1 +elite-units.tk, 1 +elite12.de, 1 +eliteaudiovideohomes.com, 1 +elitebasementsohio.com, 1 +elitebike.com.co, 1 +eliteco.tk, 1 +elitedns.info, 1 +elitegameservers.net, 1 +elitehouse.tk, 1 +elitel.nl, 1 +elitelatinas.com, 1 +elitelounge.tk, 1 +elitemud.tk, 1 +elitepainmanagement.com, 1 +elitephysiotherapy.com.au, 1 +eliterequestboard.tk, 1 +elitesidingandgutters.com, 1 +elitesim.ga, 1 +elithub.com, 1 +elitsa.gr, 1 +elivenet.com, 1 +elixi.re, 1 +elixir.bzh, 1 +elixirbih.ba, 1 +elizabethbuitrago.com, 1 +elizabethgreenfield.com, 1 +elizabethmacdonaldbooks.com, 1 +elizabethrominski.com, 1 +elizabethtaderera.me, 1 +elizeugomes.com.br, 1 +eljay.cc, 1 +eljef.me, 1 +elka-piter.ga, 1 +elkampeuzo-musique.tk, 1 +elkgroveil.gov, 1 +elkhalillaw.com, 1 +elkim.cz, 1 +elkvalley-nsn.gov, 1 +ell-net.tokyo, 1 +ella-kwikmed.com, 0 +ellak.gr, 1 +ellatotal.com, 1 +ellbusiness.com, 1 +elldus.de, 1 +elle-weine.de, 1 +ellegaard.dk, 1 +ellemental.me, 1 +ellemo.net, 1 +ellencorddry.com, 1 +ellesoft-freeware.tk, 1 +ellevit.ch, 0 +ellhofen-peccioli.de, 1 +elliboettcher.de, 1 +elligre.tk, 1 +ellinaras.tk, 1 +elliot.cat, 1 +elliot.wtf, 1 +elliottbernstein.com, 1 +ellipsoid.cf, 1 +elliquiy.com, 1 +ellisamusements.co.uk, 1 +ellisleisure.co.uk, 1 +ellisvanlaarhoven.tk, 1 +elloadingjr.ga, 1 +ellsinger.me, 1 +elmahost.net, 1 +elmandria.com, 1 +elmarchive.ir, 1 +elmasajuice.com, 1 +elmehandez.com, 1 +elmenreich.tk, 1 +elmeson.tk, 1 +elmolar.tk, 1 +elmresan.ir, 1 +elmundoconpenelope.es, 1 +elnan.do, 1 +elnegocioperfecto.tk, 1 +elo-forum.org, 1 +elo-rocket.com, 1 +elobservadordiario.com, 1 +elodieclerc.ch, 1 +elodrias.de, 1 +eloge.se, 1 +elohellp.com, 0 +elolo.ru, 1 +elon-musk.ml, 1 +elon.gov, 1 +elona-wvw.de, 1 +elonaspitze.de, 1 +elonbase.com, 1 +elonm.ru, 0 +elonma.gov, 1 +elontime.de, 1 +elosoavila.tk, 1 +elosuite.com, 1 +elovip.com.br, 1 +eloxt.com, 1 +elpaseadordeperros.com, 1 +elperiodicodeycodendaute.es, 1 +elphnt.io, 1 +elpo.net, 1 +elpoderdelespiritu.org, 1 +elpreciosostud.com, 1 +elpreparacionista.com, 1 +elprofeshows.com, 1 +elpueblo.com.do, 1 +elradiobuffet.tk, 1 +elradix.be, 1 +elradix.eu, 1 +elranchofeliz.org, 1 +elreportero.net, 1 +elri.blog, 1 +elrincondeltrabajo.com, 1 +elrinconderovica.com, 1 +elsadonaire.tk, 1 +elsemanariodesalamanca.tk, 1 +elsentech.com, 0 +elsenzhafen.de, 1 +elsg.co.uk, 1 +elshou.com, 1 +elshrif.com, 1 +elsignificadodesonar.com, 1 +elskling.no, 1 +elstopstelten.nl, 0 +elsuccionador.com, 1 +elsvanderlugt.nl, 1 +elsword.moe, 0 +eltair.com, 1 +eltar.pl, 1 +eltconsultants.com.mx, 1 +eltd.com.vn, 1 +eltern-verein.ch, 1 +elternbeiratswahl.online, 1 +elternforum-birmensdorf.ch, 1 +elternverein-utzenstorf.ch, 1 +eltip.click, 1 +eltjon.duckdns.org, 1 +elto.ch, 0 +eltonpastilha.me, 1 +eltormo.tk, 1 +eltransportquevolem.org, 1 +eltrompomedia.com, 1 +eltron.com.ua, 1 +eltuito.tk, 1 +elucron.com, 1 +eluhome.de, 1 +eluvio.com, 1 +elvcino.com, 0 +elvendrim.xyz, 1 +elverdaderoamor.tk, 1 +elvikom.co.uk, 1 +elvikom.pl, 1 +elviraszabo.com, 1 +elvis-presley.tk, 1 +elvismania.tk, 1 +elvispresley.net, 1 +elvn.tokyo, 0 +elwave.org, 1 +elweronete.tk, 1 +elwix.com, 1 +elyasweb.com, 1 +elycoin.io, 1 +elypia.art, 1 +elypia.com, 1 +elypia.org, 1 +elypia.space, 1 +elysiandigital.co, 1 +elysiria.fr, 1 +elysium.coop, 1 +elysiumware.com, 1 +em888.vip, 0 +emaging-productions.fr, 1 +emaging.fr, 1 +email-pipeline.xyz, 1 +email-verifier.tk, 1 +email.repair, 0 +email24.cf, 1 +emailadressen.nl, 1 +emailalaperformance.fr, 1 +emailbusters.tk, 1 +emailexpress.ga, 1 +emailfreeshop.tk, 1 +emailhunter.co, 1 +emailing.alsace, 1 +emailmeform.com, 1 +emailprivacytester.com, 1 +emailservers.tk, 1 +emailtemporal.org, 0 +emailtools.io, 0 +emaks.tk, 1 +emalm.com, 1 +emanol.co.uk, 1 +emanuel.photography, 1 +emanuela-gabriela.co.uk, 0 +emanuelduss.ch, 1 +emanueleanastasio.com, 1 +emanuelemazzotta.com, 1 +emaratalyoum.com, 1 +emarketingmatters.com, 1 +emasex.es, 1 +emavending.club, 1 +emavok.eu, 1 +embarkboathire.com.au, 1 +embassycargo.eu, 1 +embebelo.com, 1 +embedded.com, 1 +embellir-aroma.com, 1 +embellir-kyujin.com, 1 +embello.co.uk, 1 +emberlife.com, 1 +embodiaacademy.com, 1 +embodiaapp.com, 1 +embonus.dk, 1 +embox.net, 1 +embracecontext.com, 1 +embraceni.org, 1 +embracethedarkness.co.uk, 1 +embsaypreschool.co.uk, 1 +emby.cloud, 1 +emby.live, 1 +emcentrix-com-site-mvc.azurewebsites.net, 1 +emcspotlight.com, 1 +emdadkhodrokaraj.ir, 1 +emdadulislam.tk, 1 +emdrupholm.dk, 1 +emdyn.com, 1 +emdynint.io, 1 +emecew.com, 1 +emedos.es, 1 +emeetattd.ddns.net, 1 +emeliemai.com, 1 +emelies-inspiration.tk, 1 +ememsei.com, 1 +emeraldcbdshop.com, 0 +emeraldcityswagger.com, 1 +emeraldcoasturgentcare.com, 1 +emeraldheights.tk, 1 +emeraldislerealty.com, 1 +emeraldshield.com, 1 +emergency-broadcast-system.tk, 1 +emergency-federal-register.gov, 1 +emergencyautolocksmithmanchester.com, 1 +emergencycommand.us, 1 +emergencyshutoff.com, 1 +emergentvisiontec.com, 1 +emergenzaduepuntozero.it, 1 +emero.de, 0 +emersoncanada.ca, 1 +emersonreview.tk, 1 +emex.ro, 1 +emgroup.co, 1 +emi.im, 1 +emielraaijmakers.nl, 1 +emigranto.ru, 1 +emigratieplanner.com, 1 +emigrussia.org, 1 +emil-dein-baecker.com, 1 +emil-dein-baecker.de, 1 +emil-reimann-lieferservice-stuttgart.de, 1 +emil-reimann.com, 1 +emil-reimann.de, 1 +emil.click, 0 +emil.one, 1 +emilecourriel.com, 1 +emiliederavinspain.tk, 1 +emiliehouse.net, 1 +emiliendevos.be, 1 +emilieporte.fr, 1 +emilio.media, 1 +emilion.dk, 0 +emiliops.com, 1 +emilong.com, 1 +emilreimann.de, 1 +emils-1910.de, 1 +emils-chemnitz.de, 1 +emils1910.de, 1 +emilstahl.com, 1 +emilstahl.de, 1 +emilstahl.dk, 1 +emilvarga.com, 1 +emily.moe, 1 +emilybellydance.com.au, 1 +emilymarques.ga, 1 +emilypennock.com, 1 +emilywufaith.tk, 1 +emina-arapovic.tk, 1 +eminem.kim, 1 +emirabiz.com, 0 +emirates247.com, 1 +emirefek.net, 1 +emirichardson.com, 1 +emisia.com, 1 +emita.ee, 1 +emivauthey.com, 0 +emkanrecords.com, 1 +emkode.pl, 1 +emkrivoy.com, 1 +emma-o.com, 1 +emma-secret.com, 1 +emma.ly, 0 +emmababy420.com, 1 +emmagarland.com, 1 +emmagraystore.com, 1 +emmagullstrand.se, 1 +emmaliddell.com, 1 +emmamillernovels.com, 1 +emmanuelle-et-julien.ch, 1 +emmanuelorocker.com, 1 +emmasfunerals.uk, 1 +emmastree.com, 1 +emmausmexico.com, 1 +emmawatsonking.tk, 1 +emmawild.de, 1 +emmepole.tk, 1 +emmiwelentain.com, 1 +emmynet.de, 1 +emo-poris.com, 1 +emobilityforum.org, 1 +emoforum.tk, 1 +emoji.bzh, 0 +emoji.web.tr, 1 +emojiteka.pl, 1 +emolafarm.com, 1 +emond-usedcars.net, 0 +emote.bot, 1 +emotebank.com, 1 +emotebot.com, 1 +emotionalonlinestorytelling.com, 1 +emotionsgroup.kz, 1 +emotive.productions, 1 +emoxie.com, 0 +empathogen.com, 1 +empathogens.com, 1 +empathy.ca, 1 +empathyband.tk, 1 +empatico.org, 1 +empatico.xyz, 1 +empatos.cf, 1 +emperola.com, 1 +emperor-penguin.com, 1 +emperor-penguins.com, 1 +emperor.blog, 1 +emperoranimeindo.tk, 1 +emperors.net, 1 +empese.com, 1 +empherino.net, 1 +empingbalado.com, 1 +empire-forum.tk, 1 +empire-group.co.nz, 1 +empire-univ.com, 1 +empire24.co, 1 +empireauto-2000.com, 1 +empiredenham.ga, 1 +empiria.site, 1 +emplealis.com, 1 +empleandon0s.com, 1 +empleosearch.com, 1 +emploi-collectivites.fr, 0 +employeeexpress.gov, 1 +employeemanual.com.au, 1 +employer.gov, 1 +employer411.com, 1 +employerlawresource.com, 1 +employersupport.co.uk, 1 +employmax.co.za, 1 +employmaxetd.co.za, 1 +employment-applicant.com, 1 +employment.uk.com, 1 +employmentlawworldview.com, 1 +emporikonathenshotel.com, 1 +emporioarchitect.com, 1 +emporiodascalcinhas.com.br, 1 +emporiodosperfumes.com.br, 1 +emporioonline.com.br, 1 +emporiopurochile.com.br, 1 +empowerdb.com, 1 +empoweren.com, 0 +empowernation.org, 1 +empoweryou.ca, 1 +emprechtinger.com, 1 +empreex.com, 1 +emprego.pt, 1 +empregosrj.com, 1 +empreinte.ca, 1 +emprendeconchrisfx.com, 1 +emprendedoresdesevilla.es, 1 +emprendefinanzas.com, 1 +emprendeperuano.com, 1 +emprendimientoweb.co, 1 +empresa365.com, 1 +empreusitsupport.com.au, 1 +emprunterlivre.ci, 1 +emptiness.cf, 1 +empty.host, 1 +emptyarcade.com, 1 +emptybox.org, 1 +empyrean-advisors.com, 1 +emrah.io, 1 +emreaydinfan.tk, 1 +emrenovation.com, 1 +emresaglam.com, 1 +emrullahsahin.com, 1 +ems.gov, 1 +emsa-casm.ca, 1 +emsliespharmacy.com.au, 1 +emtofis.com, 1 +emtradingacademy.com, 1 +emu.land, 1 +emulationking.com, 1 +emulator.ml, 1 +emulefans.com, 1 +emulovers.com, 1 +emulsifier.ga, 1 +emunahstudio.com, 1 +emunet.net, 1 +emusicuz.tk, 1 +emvitals.com, 1 +emvoiceapp.com, 1 +emw3.com, 1 +emxvn.co.za, 1 +emyr.net, 1 +emyself.org, 1 +emystars.tk, 1 +emzi0767.com, 1 +emzy.de, 1 +en-booster.jp, 1 +en-este.link, 1 +en-maktoob.search.yahoo.com, 0 +en-wp.com, 1 +en-wp.org, 1 +en0.io, 1 +en4rab.co.uk, 1 +en4u.org, 1 +enaah.de, 1 +enabling.ga, 1 +enactusteesside.org, 1 +enakari.com, 1 +enalean.com, 1 +enamae.net, 1 +enamelpin.club, 1 +enbecom.net, 1 +enbulleiugnen.com, 1 +encd.life, 1 +encfs.win, 1 +encircleapp.com, 1 +encircled.org, 1 +encode.agency, 1 +encode.host, 1 +encode.training, 1 +encodecloud.net, 1 +encontra-me.org, 1 +encontro.online, 1 +encontroespiritadeinverno.com.br, 1 +encore.io, 0 +encoro.org, 1 +encountercss.com, 1 +encouragemarketing.com, 1 +encredible.de, 0 +encredible.org, 0 +encretplomb.ch, 0 +encrypt.my.id, 1 +encrypt.org.uk, 1 +encrypted.at, 1 +encrypted.google.com, 1 +encryptedaudience.com, 1 +encryptionweb.tk, 1 +encryptmy.site, 1 +encryptmycard.com, 1 +encryptmysite.net, 1 +encuentrabajo.net, 1 +encycarpedia.com, 1 +endangeredwatch.com, 1 +endbegins.tk, 1 +endbox.email, 1 +ende-x.com, 1 +endeal.nl, 1 +endee.de, 1 +ender.co.at, 1 +ender.fr, 1 +ender.moe, 1 +enderandrew.com, 1 +enderbycamping.com, 1 +enderdrachelp.ddns.net, 1 +enderhost.tk, 1 +enderle.cloud, 1 +enderszone.com, 0 +endgame-economics.com, 1 +endiana.cf, 1 +endingthedocumentgame.gov, 1 +endlessdiy.ca, 1 +endlessfashion.tk, 1 +endlessvideo.com, 1 +endlesswebsite.tk, 1 +endofevolution.com, 1 +endofinternet.goip.de, 1 +endofodo.goip.de, 1 +endoftenancycleaninglondon.co.uk, 1 +endohaus.us, 1 +endondehay.com, 1 +endpaydayloandebt.net, 1 +endspamwith.us, 1 +enduranceday.be, 1 +enduranceseries.ca, 1 +endurogp.org, 1 +endustriyelfirinlar.com, 1 +endviolence.gc.ca, 1 +endzeit-architekten.com, 1 +eneamarcantoni.com, 1 +enecivilela.com, 1 +eneko.com, 1 +enekogarrido.com, 1 +enemyofman.com, 1 +enemyterritory.tk, 1 +energaia.de, 1 +energetiquetraditionnellechinoise.be, 1 +energie-sante.ch, 0 +energiebesparingsexpert.nl, 1 +energiecentrale.gent, 1 +energiekeurplus.nl, 1 +energija-visiems.lt, 1 +energozrouti.cz, 1 +energy-drink-magazin.de, 1 +energy-fm.tk, 1 +energy-healings.com, 1 +energy-in-balance.eu, 1 +energy-robotics.com, 1 +energyatlas.com, 1 +energyaupair.dk, 1 +energyaupair.nl, 1 +energyaupair.no, 1 +energyaupair.se, 1 +energycodes.gov, 1 +energydistributorsllc.com, 1 +energydrinkblog.de, 1 +energyefficientservices.com, 1 +energyelephant.com, 1 +energyforum.tk, 1 +energygenie.com.au, 1 +energygroup.gq, 1 +energygroup.tk, 1 +energyguru.tk, 1 +energylocals.com, 1 +energylocals.com.au, 1 +energymedia.tk, 1 +energysaveroregon.com, 1 +energysite.tk, 1 +energysolutionstech.com, 1 +energystar.gov, 1 +energytrust.tk, 1 +energywisdom.tk, 1 +enerity.eu, 1 +enerity.io, 1 +enersaveapp.org, 1 +enersec.co.uk, 1 +enersolelectrical.com.au, 1 +enerte.ru, 1 +eneryetika.com, 1 +enerypa.tk, 1 +enescrackmerkezi.tk, 1 +enet-navigator.de, 1 +enett.team, 1 +enfantsdelarue.ch, 1 +enfermedaddelbeso.com, 1 +enfinmince.fr, 1 +enflow.nl, 1 +enforcement-trends-dev.azurewebsites.net, 1 +enforcement-trends-test.azurewebsites.net, 1 +enforcement-trends.azurewebsites.net, 1 +enfu.se, 1 +eng-erlangen.de, 1 +eng3corp.com, 1 +eng4arab.tk, 1 +engagelogic.com, 1 +engagewell.com, 1 +enganches.es, 1 +enganchesevilla.es, 1 +engaugetools.com, 1 +engelke-optik.de, 0 +engelmann.com, 0 +engelsholm.dk, 1 +engelsism.tk, 1 +engelundlicht.ch, 1 +engelwerbung.com, 1 +engelwerbung.de, 1 +engen.co.za, 1 +engg.ca, 1 +enghero.com, 1 +engi.fyi, 1 +engie-laadpalen.nl, 1 +engima.nl, 1 +engineeringbigdata.com, 1 +enginefirefighter.com, 1 +engineowning.com, 1 +enginepit.com, 1 +enginsight.com, 1 +enginx.net, 1 +enginytech.com, 1 +engione.com, 1 +engl-server.de, 1 +engl-systems.de, 1 +englandbeach.com, 1 +englandschool.tk, 1 +english-to-russian-translation.tk, 1 +english-training.tk, 1 +englishbulgaria.net, 1 +englishcast.com.br, 1 +englishclassworksheets.com, 1 +englishdirectory.de, 1 +englishfamilyzone.tk, 1 +englishforums.com, 1 +englishlol.com, 1 +englishouse.tk, 1 +englishphonopass.com, 1 +englishstudio.com, 1 +englishtofrench.eu, 1 +englishtype.com, 0 +englishyamal.ru, 0 +engrepair.com, 1 +engrish.ml, 1 +engution.biz, 0 +engvid.com, 1 +engweld.co.uk, 1 +engym.com.tw, 1 +enhanced-mail.tk, 1 +enia.com, 1 +enigheten.tk, 1 +enigma.swiss, 0 +enigmacpt.com, 0 +enigmadjradio.com, 1 +enijew.com, 1 +enitso.de, 1 +enity.tk, 1 +eniwa-eye.com, 1 +enixgaming.com, 1 +eniyicrmprogramlari.tk, 1 +enizioshop.com, 1 +enjin.io, 1 +enjin.zone, 1 +enjincoin.io, 1 +enjinwallet.io, 1 +enjinx.cn, 1 +enjinx.io, 1 +enjoy-drive.com, 1 +enjoybeer.dk, 1 +enjoytransferitalia.com, 1 +enky.be, 1 +enlace.vip, 1 +enlacesgranotas.tk, 1 +enlamochiladeadri.com, 1 +enlightenedhr.com, 1 +enlightsec.se, 1 +enlnf.link, 1 +enloestatebank.com, 1 +enlyft.com, 0 +enmieux.be, 1 +enmowe.com, 1 +enmowe.tech, 1 +ennori.jp, 1 +enns-photography.com, 1 +enodais.gr, 1 +enofmusic.com, 1 +enoisdaturma.tk, 1 +enomada.net, 1 +enoou.com, 1 +enorekcah.com, 1 +enot32.ru, 1 +enoteca.do, 1 +enotecabortone.it, 1 +enotecastore.it, 1 +enotefile.com, 1 +enotovil.ru, 1 +enpalmademallorca.info, 1 +enpasenerji.com.tr, 1 +enputu.tk, 1 +enquetebeteiligung.de, 1 +enquos.com, 1 +enrack.tk, 1 +enremoto.online, 1 +enrich.email, 1 +enrique-monroy.tk, 1 +enrique.wtf, 1 +enriquepiraces.com, 1 +enrollapp.com, 1 +enroo-tech.com, 1 +enroutemalaysia.com, 1 +ensage.io, 1 +ensaladasvinagreta.com, 1 +ensap.gouv.fr, 1 +enscosupply.com, 1 +ensemble-rubato.de, 1 +ensembling.com, 1 +enshin-karate.tk, 1 +ensilencio.tk, 1 +ensingpodotherapie.nl, 1 +enskat.de, 1 +enskatson-sippe.de, 1 +ensley.tech, 1 +ensons.de, 1 +enstroga.at, 1 +enstructo.net, 1 +ensured.com, 1 +ensured.nl, 1 +ensurtec.com, 1 +ensy.cz, 1 +entabe.jp, 1 +entactogen.com, 1 +entactogens.com, 1 +entaurus.com, 1 +enteente.com, 1 +entegrations.io, 1 +enter.eco, 1 +enteratesoria.tk, 1 +entercenter.ru, 1 +enterdown.com, 1 +enterprisecarclub.co.uk, 0 +enterprisenetworksecurity.net, 1 +enterpriset.cf, 1 +enterprisey.enterprises, 1 +enterprivacy.com, 1 +entersoftsecurity.com, 1 +entersynapse.com, 1 +entertaiment-news.tk, 1 +entertainmentblog.tk, 1 +entertainmentformitzvahs.com, 1 +entertainmentsrit.tk, 1 +entertainmentwrapped.com, 1 +enthasso.gr, 1 +entheogens.com, 1 +entheorie.net, 1 +enthusiaformazione.com, 1 +enthusiast.space, 1 +entomobolivia.com, 1 +entorangecounty.com, 1 +entradaweb.cl, 1 +entrainr.com, 1 +entrecieletpierres.com, 0 +entremass.com, 1 +entrenossocialinfo.com, 1 +entreprenet.gq, 1 +entrevistadesucesso.ga, 1 +entrezdansladanse.fr, 1 +entropia.de, 0 +entropy.su, 1 +entropyofdelicatewonders.com, 1 +entrup.io, 1 +entrusted.io, 1 +entryboss.cc, 1 +entrypoint.sh, 1 +entryscape.com, 1 +entspannter-arbeiten.de, 0 +entwickler.land, 1 +enuchi.jp, 1 +enuygun.com, 1 +envaldemoro.com, 1 +envant.co.uk, 1 +enveloppenopmaat.nl, 1 +envescent.com, 1 +enviam.de, 1 +enviarcurriculumvitae.com, 1 +enviartucurriculumvitae.com, 1 +enviatufoto.com, 1 +enviro-umweltservice.de, 1 +envirobizcollective.com.au, 1 +enviroli.co.uk, 1 +enviroli.com, 1 +enviroli.org.uk, 1 +enviroli.uk, 1 +environment.ai, 1 +environmental-colleges.com, 1 +enviroprobasements.com, 1 +envirotecstructures.com.au, 1 +envisionsproperty.com, 1 +envisolarvind.tk, 1 +enviyatar.tk, 1 +envman.io, 1 +envoie.moi, 1 +envoyez.moi, 1 +envoypresents.com, 1 +envydesigns.tk, 1 +envygeeks.io, 1 +envysmile.com, 1 +envywe.com, 1 +enweb.ml, 1 +enwikipedia.tk, 1 +enxadahost.com, 1 +enythoracicsurgery.com, 1 +eo-literaturo.tk, 1 +eocservices.co.uk, 1 +eod-dissemination-uat.azurewebsites.net, 1 +eod-dissemination.com, 1 +eod.su, 1 +eoitek.com, 1 +eola.co, 1 +eolme.ml, 1 +eon.tech, 1 +eonclub.tk, 1 +eonhive.com, 1 +eons.io, 0 +eonwavesstudio.com, 1 +eooe.me, 1 +eoonglobalresources.jp, 1 +eopugetsound.org, 0 +eos-utvalget.no, 1 +eosagonline.ru, 1 +eoscryptocurrency.com, 1 +eosinofilos.com, 1 +eoskoch.com, 1 +eosol.de, 1 +eosol.net, 1 +eosol.services, 1 +eosolutions.co, 1 +ep-cortex.com, 1 +ep-plus.jp, 1 +epa.com.es, 1 +epagos.com.ar, 1 +epal.pt, 1 +epasar.my, 0 +epassafe.com, 1 +epave.paris, 1 +epawnatl.com, 1 +epay.bg, 1 +epaygateway.net, 1 +epcomputacion.com.ar, 1 +epcreation.nl, 1 +epcreport.net, 1 +epdeveloperchallenge.com, 1 +eperformax.com, 1 +epharmasolutions.com, 1 +ephesusbreeze.com, 1 +ephraim-medical.com, 1 +epi-lichtblick.de, 1 +epi.no, 1 +epi.one, 0 +epic-vistas.com, 1 +epic-vistas.de, 1 +epic.gl, 1 +epicapos.cz, 1 +epicauth.azurewebsites.net, 1 +epicbouncycastles.co.uk, 1 +epiccdn.net, 1 +epicdesign1.tk, 1 +epicdesign2.tk, 1 +epicdowney.com, 1 +epicentar.mk, 1 +epicenter.ga, 1 +epicenter.work, 1 +epicenter.works, 1 +epicentre.works, 1 +epicfail.be, 1 +epicginger.fi, 1 +epichouse.net, 0 +epicinflatables.co.uk, 1 +epiclub.com.au, 1 +epicmoney.tk, 1 +epicmusicradio.ml, 1 +epicnex.com, 1 +epicpages.com, 1 +epicridesbahamas.com, 1 +epicsecure.de, 1 +epicserver.ru, 1 +epicsoft.de, 1 +epicteam.tk, 1 +epicteller.com, 1 +epicvistas.com, 1 +epicvistas.de, 1 +epidastudio.com, 1 +epidauros.be, 1 +epigrafes-led-farmakeia.gr, 1 +epikomagazine.com, 1 +epilepsiyle.com, 1 +epilino.jp, 1 +epilis.gr, 1 +epinesdeparadis.com, 1 +epiphaniusmacar.com, 1 +epiphyte.network, 1 +episkevh-plaketas.gr, 1 +epistas.com, 1 +epistas.de, 1 +epitafija.ru, 1 +epitelial.com, 1 +epitesz.co, 1 +epiteugma.com, 1 +epitome.cc, 1 +epitome.games, 1 +epizentrum.work, 1 +epizentrum.works, 1 +eplayer.cz, 1 +eplayer.sk, 1 +eplenet.tk, 1 +epliar.com, 1 +epmcentroitalia.it, 1 +epo32.ru, 1 +epoch.com, 1 +epoker6.com, 1 +epolitiker.com, 1 +epopia.com, 1 +epos-distributor.co.uk, 1 +epos.az, 1 +eposbirmingham.co.uk, 1 +eposbrighton.co.uk, 1 +eposbristol.co.uk, 1 +eposcardiff.co.uk, 1 +eposig.net, 1 +eposkent.co.uk, 1 +eposleeds.co.uk, 1 +eposleicester.co.uk, 1 +eposliverpool.co.uk, 1 +eposlondon.co.uk, 1 +eposmidlands.co.uk, 1 +eposnottingham.co.uk, 1 +eposreading.co.uk, 1 +epossheffield.co.uk, 1 +epossussex.co.uk, 1 +eposswansea.co.uk, 1 +epossystems.co.uk, 0 +epost.pub, 1 +epostplus.li, 1 +eposwales.co.uk, 1 +eposyork.co.uk, 1 +eposzilos.nl, 1 +eppelblei.lu, 1 +eppelduerferjugend.lu, 1 +eppelpress.lu, 1 +eppione.com, 1 +epreskripce.cz, 1 +eprezto.com, 1 +eprojectfreetv.com, 1 +eprosto.cf, 1 +eprzybornik.pl, 1 +epsamsg.com, 1 +epsilonone.me, 1 +epsmil.it, 1 +epspolymer.com, 1 +epublibre.org, 1 +epyonsuniverse.net, 1 +eq-serve.com, 1 +eqab.net, 1 +eqassociates.com, 1 +eqtravel.us, 1 +equabanking.cz, 1 +equalcloud.com, 1 +equate.net.au, 1 +equatetechnologies.com.au, 0 +equi.ac, 1 +equiac.com, 1 +equidam.com, 1 +equifaxobjection.com, 1 +equilibriumx.com, 1 +equinecoaching.ca, 1 +equinenow.com, 1 +equinetherapy.ca, 1 +equinox.io, 1 +equipamentosparapostos.com.br, 1 +equipandoloja.net.br, 1 +equipedefrance.tv, 0 +equipedefrente.tk, 1 +equipeferramentas.com.br, 1 +equipment-pool.tk, 1 +equipoweb.info, 1 +equippers.de, 1 +equisecu.com, 1 +equisoft.io, 1 +equitable-igwm.com, 1 +equitazionepertutti.it, 1 +equityelevate.com, 1 +equityflows.com, 1 +equityloupe.com, 1 +equityloupe.org, 1 +equityloupe.ru, 1 +equityset.com, 1 +equitytrack.co, 1 +er-mgmt.com, 1 +er-music.com, 1 +er.pl, 1 +er.tl, 1 +er1s.xyz, 1 +era-tec.de, 0 +era.fi, 1 +eradigital.net, 1 +eradoom.net, 1 +erandymoreira.ga, 1 +erapotensia.com, 1 +erasmo.info, 1 +erasmusantoine.tk, 1 +erasmusplusrooms.com, 1 +erasure.tk, 1 +erasyou.com, 1 +erate.fi, 1 +erath.fr, 0 +eravurnet.tk, 1 +erback.tk, 1 +erboristeria.milano.it, 1 +erboristeria.roma.it, 1 +erbt.tk, 1 +erciyesspor.tk, 1 +erclab.kr, 1 +erclaim.com, 1 +erctra.com, 1 +erdethamburgeronsdag.no, 1 +ereader.uno, 1 +erechimimoveis.com.br, 1 +erector.tk, 1 +eredmenye.xyz, 1 +erektion1.gq, 1 +eremnews.com, 1 +erenvakfi.org, 1 +erethon.com, 1 +erevan-news.tk, 1 +erfolgsmaschine.ch, 1 +ergaomnes.cz, 1 +ergo-open.de, 1 +ergobyte.eu, 1 +ergobyte.gr, 1 +ergodark.com, 1 +ergonomic-products.com, 1 +ergovita.com.br, 1 +eriador.io, 1 +eric-kolelas.tk, 1 +eric1932.tk, 1 +ericabrahamsen.net, 1 +ericairwin.com, 1 +ericca.org, 1 +ericdiao.com, 1 +ericfo.cf, 1 +erichmann.com, 1 +erichoekstra.com, 1 +erichoekstra.nl, 1 +erichogue.ca, 1 +erichoins.com, 1 +erichollander.photography, 1 +erichorstmanshof.nl, 1 +erichware.tk, 1 +ericjohnltd.com, 1 +erick.blog, 1 +ericksonvasquez.com, 1 +ericktello.tk, 1 +ericleuthardt.com, 1 +ericleuthardtphotography.club, 1 +ericloud.tk, 1 +erico-hm.com, 1 +ericoc.com, 1 +erics.site, 1 +ericsaadeonline.tk, 1 +ericsilva.org, 1 +ericspeidel.de, 1 +erictgilmour.ca, 1 +ericvaughn-flam.com, 1 +eridanus.uk, 1 +eridas.ml, 1 +erigrid.eu, 1 +eriix.org, 1 +erik-stomp.de, 1 +erikaepedro.ga, 1 +erikapsicologia.com, 1 +erikatanithphotography.co.uk, 1 +erikbraam.com, 1 +erikbraam.nl, 1 +erikheemskerk.nl, 1 +erikhubers.nl, 1 +erikkruithof.nl, 1 +eriksen.im, 1 +erikserver2.tk, 1 +erikseth.de, 1 +erikswan.com, 1 +erinaceinae.com, 1 +erincarmody.cf, 1 +eriner.me, 1 +eringmaguire.com, 1 +erinmyers.us, 1 +erinn.io, 1 +erisrenee.com, 1 +eristajanmutka.com, 1 +erisys.net, 1 +eritropoyetina.com, 1 +erkaelderbarenaaben.dk, 1 +erkankavas.com, 1 +erkenntniswen.de, 1 +erkiss.club, 1 +erkiss.live, 1 +erkkiaronen.fi, 1 +erlebe-salsa.de, 1 +erlebnisarchaeologie-bayern.de, 1 +erman.ga, 1 +ermeglio.com, 1 +ermitano.cf, 1 +ernal.net, 1 +ernest.ly, 1 +ernst-fuchs.tk, 1 +ero-video.net, 1 +ero.ink, 0 +erodvd.com, 0 +erogen.su, 1 +eroimatome.com, 1 +erokat.ga, 1 +erolib.ga, 1 +eromasajes.com, 1 +eromon.net, 1 +eron.info, 1 +eropics.org, 1 +erosbeautyandwellness.com, 1 +eroscomixitalia.tk, 1 +erosofia.tk, 1 +eroticgirlfriend.com, 1 +eroticlist.com, 1 +eroticsexy.com.br, 1 +eroticsochi.com, 1 +erotikstahrtseite.gq, 1 +erotycznehistorie.pl, 1 +erozine.jp, 1 +erp-band.ru, 1 +erp.band, 1 +erpax.com, 1 +erpband.ru, 1 +erpcargo.com, 0 +erpelstolz.at, 1 +erperium.com, 1 +erperium.nl, 1 +erpollo.com, 1 +erpsolutionsmart.com, 1 +errietta.me, 1 +errlytics.com, 1 +errolmarkland.com, 1 +errolstambler.com, 1 +erronort.com, 1 +error.fail, 1 +error418.nl, 1 +errortools.com, 1 +ers35.com, 1 +ersa-shop.com, 1 +ersdfaredsaeem.tk, 1 +erseni.net, 1 +ershiwo.com, 1 +ersinbiltekin.tk, 1 +ersinerce.com, 1 +erspro.net, 1 +erstehilfeprodukte.at, 1 +ert.ovh, 1 +ertebatatjelve.ir, 1 +eru.im, 0 +eru.moe, 1 +erudicia.com, 1 +erudicia.de, 1 +erudicia.es, 1 +erudicia.fr, 1 +erudicia.it, 1 +erudicia.nl, 1 +erudicia.se, 1 +erudicia.uk, 1 +erudikum.cz, 1 +erudio-usluge.hr, 1 +erulezz.nl, 1 +ervirmaison.tk, 1 +erwanlepape.com, 1 +erwannlaflute.tk, 1 +erwerbslosenforum.de, 1 +erwin.saarland, 1 +erwinonline.tk, 1 +erwinpaal.nl, 1 +erwinschmaeh.ch, 1 +erwinwensveen.nl, 1 +erythromycinonline.gq, 1 +erythroxylum-coca.com, 1 +erzaehlwerkstatt-heilbronn.de, 1 +es-geenen.de, 1 +es-sharing.eu, 1 +es-sicherheit.ch, 1 +es-tools.at, 1 +es-tools.com, 1 +es-tools.de, 1 +es-trade.biz, 1 +es-vps.eu, 1 +es.ax, 1 +es.search.yahoo.com, 0 +es8888.net, 1 +es888999.com, 1 +es999.net, 1 +esaborit.ddns.net, 0 +esagente.com, 1 +esajokinen.net, 1 +esale.co, 1 +esalesclub.com, 1 +esamievalori.com, 1 +esarreglocomercial.com, 1 +esatn.gov, 1 +esauth.xyz, 1 +esautotech.com.au, 1 +esb1314.net, 1 +esb1668.com, 1 +esb16888.com, 1 +esb369.com, 0 +esb556.com, 1 +esb5889.com, 1 +esb5889.net, 1 +esb666.com, 1 +esb688.com, 1 +esb68888.com, 1 +esb775.net, 0 +esb777.cc, 1 +esb777.com, 1 +esb777.me, 1 +esb777.net, 1 +esb777.us, 1 +esb8886.com, 1 +esb999.com, 1 +esb999.info, 1 +esb999.us, 1 +esba11.cc, 1 +esba11.in, 1 +esba11.net, 1 +esball.in, 1 +esball888.com, 1 +esball888.net, 1 +esc-romania.tk, 1 +esc-turkey.tk, 1 +esc.gov, 1 +escael.org, 1 +escalesensorielle.com, 1 +escandille.com, 0 +escapeforyou.com, 1 +escapeplaza.de, 1 +escaperoomdoctor.com, 1 +escaperoomsolutions.com, 1 +escapetalk.nl, 1 +escapeup.es, 0 +escavador.com, 1 +escg.digital, 1 +esclear.de, 1 +escmatrix.com, 1 +escobarservice7000.com, 1 +escobpb.com.br, 1 +escogitasrls.com, 1 +escoladepilota.tk, 1 +escolaisttucano.com.br, 1 +escolamais.com.br, 1 +escolibri.com, 1 +escontact.ch, 0 +escordilla.tk, 1 +escort-fashion.com, 1 +escortaccess.net, 1 +escortbee.com, 1 +escortbruxelles.be, 1 +escortdisplay.com, 1 +escortlistings.ca, 1 +escortlistings.eu, 1 +escortlistings.fr, 1 +escortlistings.ph, 1 +escortlistings.us, 1 +escortlistingsuk.co.uk, 1 +escortmantra.com, 1 +escortsontop.co.uk, 1 +escovator-records.tk, 1 +escritoresdelcomahue.tk, 1 +escritoriodearte.com, 0 +escrocratie.tk, 1 +escrowalliance.com, 1 +escuelabiblica.com, 1 +escueladego.tk, 1 +escueladelsabor.com, 1 +escuelaelae.org, 1 +escuelaelretamo.cl, 1 +escuelagobierno.org, 1 +escuelainfantilpizcas.com, 1 +escuelaparapapas.tk, 1 +escuelasargento.tk, 1 +escuelitasansebastian.cl, 1 +escuelotika-online.tk, 1 +escyr.top, 1 +esd.cc, 1 +esdacademy.eu, 1 +esdenera.com, 1 +esdiscuss.org, 1 +eseances.ch, 1 +esecuredata.com, 1 +esehospitalsabanagrande.com, 1 +esemprego.com.br, 0 +eservices-greece.com, 1 +eset.ml, 1 +eseth.de, 1 +esexchange.ga, 1 +esfiledecrypter.com, 1 +esforces.com, 1 +esg-abi2001.de, 1 +esgen.org, 1 +esgfoundation.org, 1 +esgr.in, 1 +esher.ac.uk, 1 +eshigami.com, 1 +eshoeft.com, 1 +eshop-prices.com, 1 +eshop-ptz.ru, 1 +eshoprzd.ru, 1 +eshspotatoes.com, 1 +eshtapay.com, 1 +eshterry.com, 1 +esiac.net, 1 +esibun.net, 1 +esiefektivs.lv, 1 +esigmbh.de, 1 +esignly.com, 1 +esignprod.herokuapp.com, 1 +esigtorg.ru, 0 +esilicon.com, 1 +esim.cz, 1 +esite.ch, 1 +eskapi.fr, 1 +eskdale.net, 1 +eskiegaming.com, 1 +eskimosboards.ga, 1 +eskola.cc, 1 +eskriett.com, 0 +eslamahmed.tk, 1 +eslint.org, 0 +eslove.jp, 1 +esm.run, 1 +esmag.ru, 1 +esmart.ro, 1 +esmejor.tk, 1 +esmibot.com, 1 +esmincg2t1.com, 1 +esnekkaucuk.com, 1 +esoa.net, 1 +esocite.la, 1 +esoko.eu, 1 +esolcourses.com, 1 +esolitos.com, 1 +esomeprazole1.gq, 1 +eson.eu, 1 +esono.de, 1 +esoteric.website, 1 +esotericcosmos.com, 1 +esoterik.link, 1 +esoterikerforum.de, 1 +esovita.de, 1 +espace-caen.fr, 0 +espace-gestion.fr, 1 +espace-habitat-francais.fr, 1 +espace-orenda.ch, 0 +espace-tech.ru, 0 +espace.network, 1 +espace.spb.ru, 0 +espacejabugo.com, 1 +espacelanguetokyo.fr, 1 +espaceroseauteinturiers.fr, 1 +espacetemps.ch, 0 +espacetendance.fr, 1 +espacetheosophie.fr, 1 +espachavo.tk, 1 +espacioantiguo.com, 1 +espacioprofundo.com.ar, 0 +espaciosdelalma.com, 1 +espacioseideas.mx, 1 +espacioweb.tk, 1 +espacosaudesuplementos.com.br, 1 +espaiblancandorra.ml, 1 +espanol.search.yahoo.com, 0 +espanyoldebarna.tk, 1 +espci.fr, 1 +especialistagoogleadwords.com.br, 1 +especificosba.com.ar, 1 +espectrocrom.com, 1 +espectrometria.com, 1 +espehus.dk, 1 +espejo.tk, 1 +espeleogel.tk, 1 +espenandersen.no, 1 +espeo.eu, 1 +esperantio.tk, 1 +esperanto.co, 1 +espgg.org, 1 +espigol.org, 1 +espiragen.com, 1 +espiritugay.com, 1 +espirituracer.com, 1 +esport-agency.fr, 1 +esporters.today, 1 +esportslac.com, 1 +espower.com.sg, 1 +espressob2b.com, 1 +esprit.tn, 1 +espritrait.com, 0 +espyder.net, 1 +esquirebrotherhood.tk, 1 +esquirou-trieves.fr, 0 +esra.gq, 1 +esrhd.com, 1 +esrinfo.com, 1 +esrs.gov, 1 +essay-writing-topics-fce.tk, 1 +essaybrand.com, 1 +essaychecker.com, 1 +essaydirectory.com, 0 +essayforsale.net, 1 +essayforum.com, 0 +essayhave.com, 1 +essayjob.com, 1 +essaylib.com, 1 +essaymaker.gq, 1 +essaynews.com, 1 +essaypro.net, 1 +essays.me, 1 +essayscam.org, 0 +essayshark.com, 1 +essaytalk.com, 1 +essaywebsite.com, 1 +essenah.com, 1 +essenalablog.de, 1 +essencesdeprana.org, 0 +essencespresso.es, 1 +essenciasparis.com.br, 1 +essential12.com, 1 +essentialgp.org, 1 +essentialinteriors.ga, 1 +essentialoils.nl, 1 +essentialoilsimports.com, 1 +essentialstudiomanager.com, 1 +essentiel-physique.com, 1 +essentta.com, 1 +essenttamarketplace-essenttamarketplaceqa.azurewebsites.net, 1 +esseriumani.com, 1 +essethon.xyz, 0 +essex.cc, 1 +essexcosmeticdentists.co.uk, 0 +essextimbercraft.co.uk, 1 +essite.net, 1 +esslm.sk, 1 +esslym.com, 1 +essmokinbbq.com, 1 +essoduke.org, 1 +essplusmed.org, 1 +essteebee.ch, 0 +est-it.de, 1 +est8.ai, 1 +establo.pro, 1 +estada.ch, 1 +estadoreclamos.com, 1 +estafallando.es, 1 +estafallando.mx, 1 +estahl.dk, 1 +estaleiro.org, 1 +estallidodigital.cl, 1 +estampascriativas.com.br, 1 +estaryshop.com.br, 1 +estate360.co.tz, 1 +estateczech-eu.ru, 1 +estateways.com, 1 +estcequonmetenprodaujourdhui.info, 1 +esteam.se, 1 +esteban-abadahs.tk, 1 +estebanborges.com, 1 +estebanoria.net, 1 +estedafah.com, 1 +estefan.dyndns.org, 1 +estela-artes.com, 1 +esteladigital.com, 1 +esteriliza-me.org, 1 +esterilizacion-perros.es, 1 +esterilizador.online, 1 +estet.tk, 1 +esteticanorte.com.br, 1 +esteticaprofana.it, 1 +estetici.com, 1 +estetista.net, 1 +esthe-zukan.com, 1 +estherlew.is, 1 +esthesoleil.jp, 1 +estilopack-loja.com.br, 1 +estintori.roma.it, 1 +estonia.ee, 1 +estonia.net, 1 +estoniananonymous.tk, 1 +estoniantrade.ee, 1 +estonoentraenelexamen.com, 1 +estoppels.com, 1 +estradiolbestellen.gq, 1 +estreetshuffle.com, 1 +estremeconseguenze.it, 1 +estrietoit.com, 0 +estrogenonline.gq, 1 +estrogens.gq, 1 +estruendo.tk, 1 +estudarfora.org.br, 1 +estudiaenrusia.com, 1 +estudiarparaser.com, 1 +estudiaryaprenderingles.com, 1 +estudiemosvirtualmente.com, 1 +estudio21pattern.com, 0 +estudioaguiar.com.br, 1 +estudiogarcia-rada.com, 1 +estudiomantis.tk, 1 +estudios-biblicos.tk, 1 +estudiosalmogavares.tk, 1 +estudosnacionais.com, 1 +estufitas.com, 1 +estumarca.com, 1 +estver.ru, 1 +esu.moe, 1 +esu.wiki, 1 +esu.zone, 1 +esuretynew.azurewebsites.net, 1 +esvaco.cf, 1 +esy.nl, 1 +esyoil.com, 1 +esys.ga, 1 +esystems.tk, 1 +esyume.com, 1 +et-inf.de, 1 +eta.cz, 1 +etaes.eu, 1 +etajerka-spb.ru, 1 +etajerka.spb.ru, 1 +etaldelune.fr, 1 +etalent.net, 1 +etalktome.com, 1 +etaoinwu.com, 1 +etaoinwu.win, 1 +etath.com, 1 +etax.com.au, 1 +etaxigraz.com, 1 +etbtoursegypt.com, 1 +etccooperative.org, 0 +etch.co, 1 +etch44.com, 1 +etcivil.com, 1 +etdonline.co.za, 1 +etdp.co.za, 1 +etduvindemoselle.fr, 1 +etech-solution.com, 1 +etech-solution.net, 1 +etech-solutions.com, 1 +etechsolution.net, 1 +eteesheet.com, 1 +eternal-warriors.de, 1 +eternalflame.cn, 1 +eternalflame.info, 1 +eternalparking.com, 1 +eternalparking.eu, 1 +eternalparking.net, 1 +eternalparking.org, 1 +eternalsymbols.com, 1 +eternegy.co, 1 +eternia.online, 1 +eternit.roma.it, 1 +etestyonline.tk, 1 +etf.nu, 1 +etf2l.org, 1 +etfacta.com, 1 +eth-news.info, 1 +eth-services.de, 1 +eth0.nl, 0 +eth1.fi, 0 +ethaligan.fr, 1 +ethan.pm, 1 +ethanjones.me, 1 +ethanlew.is, 1 +ethantskinner.com, 0 +ethanyoo.com, 1 +ethelbrooks.com, 1 +ethelbrooks.es, 1 +ether.school, 1 +etherandir.com, 1 +etherapeut.de, 1 +etherderbies.com, 1 +ethereal-skies.tk, 1 +ethereal.games, 1 +ethereum-news.info, 1 +ethereumnews.best, 1 +ethereumnews.digital, 1 +ethereumnews.io, 1 +ethereumnews.live, 1 +ethereumnews.news, 1 +ethereumnews.online, 1 +ethereumnews.site, 1 +ethereumnews.xyz, 1 +etheria-software.tk, 1 +etherium.org, 1 +ethermine.org, 1 +ethernetservers.com, 1 +ethernia.fr, 1 +ethernium.fun, 1 +etheron.com, 1 +etherpad.nl, 1 +ethers.news, 1 +ethicalads.io, 1 +ethicalconsumer.org, 1 +ethicaldata.co.uk, 1 +ethicalescorts.com, 1 +ethicalexploiting.com, 1 +ethicallogistics.com, 1 +ethicalpolitics.org, 1 +ethicaltek.com, 1 +ethicsburg.gov, 1 +ethika.com, 1 +ethil-faer.fr, 1 +ethiobaba.com, 1 +ethiopian.dating, 1 +ethitter.com, 1 +ethnews.today, 1 +ethnopsychoanalyse.tk, 1 +ethosinfo.com, 1 +ethotupala.tk, 1 +etienne.cc, 1 +etiennes.work, 1 +etikus-hacker.hu, 1 +etimmer.nl, 1 +etincelle.ml, 1 +etindustries.com, 1 +etiquetaunica.com.br, 1 +etkaddict.com, 1 +etkarle.de, 1 +etnis.id, 1 +etnoria.com, 1 +etny.nl, 1 +etoile-rc.jp, 1 +etoile-usedcars.com, 0 +etororeview.net, 1 +etororeviews.com, 1 +etrades.tk, 1 +etre-soi.ch, 0 +etre-vivant.fr, 0 +etrecosmeticderm.com, 1 +etrolleybizstore.com, 1 +etskinner.com, 0 +etssquare.com, 1 +etsu.edu, 1 +ettbl.net, 1 +ettebiz.com, 1 +ettgottliv.com, 1 +ettounsi.net, 1 +etudepresse.tk, 1 +etudes-litteraires.com, 1 +etudesbibliques.fr, 0 +etudesbibliques.net, 0 +etudesbibliques.org, 0 +etula.ga, 1 +etury.online, 1 +etutsplus.com, 1 +etv.cx, 1 +etwalldentalpractice.co.uk, 1 +etyd.org, 1 +etyka.cz, 1 +eu-darlehen-finanzierung.de, 1 +eu-datenbank.de, 1 +eu-gamers.com, 1 +eu-prodaja.com, 1 +eu-stellenangebot.de, 1 +eu.ax, 1 +euaggelion.blog.br, 0 +euanbarrett.com, 1 +euc.world, 1 +euchre.us, 1 +eucimen.com, 0 +eucollegetours.com, 1 +eucustody.com, 1 +eucybernet.eu, 1 +eudireto.com, 1 +eudore.org, 1 +euexia.fr, 1 +eugenetech.org, 1 +eugeniocorso.com, 1 +eugenioperez.tk, 1 +eugostodefilmesbrasileiros.tk, 1 +eujuicers.bg, 1 +eujuicers.com, 1 +eujuicers.com.hr, 1 +eujuicers.com.tr, 1 +eujuicers.com.ua, 1 +eujuicers.cz, 1 +eujuicers.de, 1 +eujuicers.es, 1 +eujuicers.fr, 1 +eujuicers.hu, 1 +eujuicers.it, 1 +eujuicers.pl, 1 +eujuicers.pt, 1 +eujuicers.ro, 1 +eujuicers.rs, 1 +eujuicers.ru, 1 +eujuicers.si, 1 +eujuicers.sk, 1 +eulenschmiede.de, 1 +euleres.tk, 1 +eulessplumbers.com, 1 +euman.ml, 1 +eumananc.ro, 1 +eumk6.ml, 1 +eumr.org, 1 +eung.ga, 1 +eupay.de, 1 +euph.eu, 1 +eurasierwelpen.tk, 1 +eurban.life, 1 +eureka.archi, 1 +eurekaarchi.com, 1 +eurekaarchitecture.com, 1 +eurmarketing.com, 1 +euro-construction.co.uk, 1 +euro-issues.tk, 1 +euro-servers.de, 1 +euro.se, 1 +euroalter.com, 1 +eurobadmaasbracht.nl, 1 +eurobilltracker.tk, 1 +eurocars2000.es, 1 +eurocenterobuda.hu, 1 +eurocertificazione.it, 1 +eurocom.bg, 1 +eurocomcompany.cz, 1 +eurodentaire.com, 1 +eurodesk.eu, 1 +euroenergy.tk, 1 +euroestetica.ec, 1 +euroexpres.info, 1 +euroflora.com, 1 +euroflora.mobi, 1 +euroflorist.ga, 1 +eurofrank.eu, 1 +eurogarden-parts.de, 1 +eurogarden.be, 1 +eurogarden.com, 1 +eurogarden.nl, 1 +euroherp.com, 1 +eurolocarno.es, 1 +euroman.ga, 1 +euronic.fi, 1 +europack.kiev.ua, 1 +europainchemnitz.de, 1 +europapier.net, 1 +europarts-sd.com, 1 +europastudien-chemnitz.de, 1 +europastudien.de, 1 +europatour2005.tk, 1 +european-agency.org, 1 +european-hospital.ga, 1 +european-hospital.ml, 1 +european-hospital.tk, 1 +europeanandjapaneseautorepair.com, 1 +europeanbizhealthcare.co.uk, 1 +europeancuisine.tk, 1 +europeancupinline.eu, 1 +europeanpreppers.com, 1 +europeanstudies-chemnitz.de, 1 +europeantimberconnectors.ca, 1 +europeantransportmanagement.com, 1 +europeanwineresource.com, 1 +europeonline.tk, 1 +europeos.es, 1 +europesearbeiders.be, 1 +europesrit.tk, 1 +europetourism.ga, 1 +europetraveler.tk, 1 +europetravelservice.co.uk, 1 +europop.com, 1 +eurora.de, 1 +eurorecambios24.com, 1 +euroroad17.dk, 1 +euroscot.de, 1 +euroshop.or.at, 1 +euroshop.tk, 1 +euroskano.nl, 1 +eurospecautowerks.com, 1 +eurostrategy.vn.ua, 1 +eurosun.tk, 1 +eurotech-cnc.eu, 1 +eurotop.net.pl, 1 +eurotour.tk, 1 +eurotramp.com, 1 +eurousa.us, 1 +eurovision-romania.tk, 1 +eurovision.ie, 1 +eurseo.com, 1 +euruni.edu, 1 +eusarse.tk, 1 +euskaltzaleak.tk, 1 +eusou.ml, 1 +euterpiaradio.ch, 1 +eutiximo.com, 1 +eutotal.com, 1 +euvo.tk, 0 +euwid-energie.de, 1 +euwid.de, 1 +ev-menden-meindorf.de, 1 +ev-menden.de, 1 +ev-zertifikate.de, 1 +eva-briegel-fanpage.tk, 1 +eva-select.com, 1 +eva.cz, 1 +eva24h.tk, 1 +eva42.com, 1 +evaali.fi, 1 +evaalordiah.tk, 1 +evadi.ca, 1 +evafojtova.cz, 1 +evai.me, 1 +evailoil.ee, 1 +evaisanta-mariaalmudever.tk, 1 +evaisanta.tk, 1 +evakuator-tut.by, 1 +evakuator.services, 1 +evalesc.com, 1 +evaluate.jp, 1 +evamachkova.cz, 0 +evamathil.de, 1 +evamira.com, 1 +evanavevan.me, 1 +evandevizio.com, 1 +evanescencenorge.tk, 1 +evanescenceturkey.tk, 1 +evanfiddes.com, 1 +evange.co.jp, 1 +evangelicalmagazine.com, 1 +evangelionmagi.tk, 1 +evangelise.asia, 1 +evanreev.es, 1 +evansdesignstudio.com, 0 +evansville-wy.gov, 1 +evantage.org, 1 +evantageglobal.com, 1 +evante-bus.com, 1 +evaolson.se, 1 +evapp.org, 1 +evaria-network.fr, 1 +evasion-energie.com, 1 +evasioncreole.com, 1 +evasovova.cz, 1 +evavolfova.cz, 1 +evbn.org, 1 +evcarbontracker.com, 1 +evdenevenakliyatankara.name.tr, 1 +eve-online-com.ru, 1 +eve-skilltracker.com, 1 +eve-ua.com, 1 +eve.pub, 1 +eve0s.com, 1 +eveapk.com, 1 +eveaz.com, 0 +eveco-mebel.ga, 1 +evedanjailbreak.com, 1 +eveetcie.com, 1 +eveil-et-savoirs.com, 1 +evelienzorgt.nl, 1 +evelyndayman.com, 1 +evemarketer.com, 1 +evendesign.gq, 1 +evenementenhoekvanholland.nl, 1 +evenfall.tk, 1 +eveningtaxservices.com, 1 +evenstar-gaming.com, 1 +evenstargames.com, 1 +event-blick.de, 1 +event-fullyyours.com, 1 +event4fun.no, 1 +eventaro.com, 1 +eventblog2017.tk, 1 +eventdays.tk, 1 +eventerlebnis.ch, 1 +eventfun.tk, 1 +eventide.space, 1 +eventim-business.com, 1 +eventim-business.de, 1 +eventive.org, 0 +eventjams.com, 1 +eventmake.es, 1 +eventnexus.co.uk, 1 +eventosbgp.com, 1 +eventosenmendoza.com.ar, 1 +eventosformativos.tk, 1 +eventprazdnik.ru, 1 +eventsatthefarm.com, 1 +eventsbytma.com, 1 +eventservicestockholm.se, 1 +eventsframe.com, 1 +eventtech.com, 0 +eventticketscenter.com, 1 +eventusgc.ru, 1 +eveonline.com, 1 +ever.sale, 1 +everaerts.eu, 1 +everain.me, 1 +everberg.tk, 1 +everettduiattorneys.com, 1 +everettsautorepair.com, 0 +everfine.com.tw, 1 +evergladesrestoration.gov, 1 +everglow.co.jp, 1 +evergreenilder.tk, 1 +evergreenmichigan.com, 1 +evergreennewsonline.com, 1 +everhome.de, 1 +everichspice.com, 1 +everify.gov, 1 +everitoken.io, 1 +everling.lu, 1 +everlong.org, 1 +everly.market, 1 +evermade.fi, 1 +evermarkstudios.com, 1 +evernaut.com, 1 +everpcpc.com, 1 +everready.tk, 1 +everseo.tk, 1 +evertonarentwe.com, 1 +evertradeelectronics.com, 1 +evertus.com, 1 +everwaking.com, 0 +everwinter.tk, 1 +every-day-life.com, 0 +everyarti.st, 1 +everycorneroftheworld.cf, 1 +everycorneroftheworld.ml, 1 +everycorneroftheworld.tk, 1 +everyday.eu.org, 1 +everydaycaitfitness.com, 1 +everydaygary.com, 1 +everydaymarts.com, 1 +everydaypower.com, 1 +everydaytherich.com, 1 +everydaywot.com, 1 +everyex.com, 1 +everyfad.com, 1 +everyhq.com, 1 +everykidoutdoors.gov, 1 +everymove.org, 1 +everyoneadmins.tk, 1 +everysaving.ae, 1 +everysaving.ca, 1 +everysaving.co.uk, 1 +everysaving.co.za, 1 +everysaving.com.au, 1 +everysaving.ph, 1 +everysaving.sg, 1 +everystudent.bg, 1 +everystudent.com.tw, 1 +everysync.co.jp, 1 +everything-everywhere.com, 1 +everythingaccess.com, 1 +everythingbarca.com, 1 +everythingcebu.com, 1 +everythingcovid-19.com, 1 +everythinginoneblog.gq, 1 +everythinglidia.com, 1 +everythingstech.com, 1 +everythinq.com, 1 +everytrycounts.gov, 1 +everywhere.cloud, 1 +eveshaiwu.com, 1 +eveshamglass.co.uk, 1 +eveswell.com, 1 +evexia.xyz, 1 +evezqurbanli.tk, 1 +evhoeft.com, 1 +eviadc.com, 1 +eviction.cf, 1 +evidecor.com.br, 1 +evidencebased.net, 1 +evidenceusa.com.br, 1 +evidencija.ba, 1 +evil-empire.tk, 1 +evilbeasts.ru, 1 +evilbrood.tk, 1 +evilbunnyfufu.com, 1 +evilduck.tk, 1 +evilla.ru, 0 +evilmartians.com, 1 +evilmoisture.tk, 1 +evilness.nl, 1 +evilsay.com, 0 +evilsite.cf, 1 +evion.nl, 0 +evisa.us.com, 1 +eviz.co, 1 +evlear.com, 1 +evlorin.com, 1 +evlqa1sp1tzb05zo-reoo0vhj9a1t5pousfudnkg.com, 0 +evntage.com, 1 +evobox.store, 1 +evoco.vc, 1 +evodation.com, 1 +evodation.org, 1 +evodia-spirits.de, 1 +evohomecare.com, 1 +evojska.tk, 1 +evokepk.com, 1 +evokewonder.com, 1 +evolucioneducativa.com.ec, 1 +evolucionestudios.com.bo, 1 +evoludis.net, 1 +evolution-host.ga, 1 +evolution.codes, 1 +evolutionbiote.com, 1 +evolutioninflatables.co.uk, 1 +evolutionlending.co.uk, 1 +evolutionpets.com, 1 +evolutive-records.tk, 1 +evolvedevlabs.de, 1 +evolvetechnologies.co.uk, 1 +evolvicity.org, 1 +evolvingsouls.com, 1 +evolvingthoughts.net, 1 +evonet.co.za, 1 +evony.eu, 1 +evopack.net, 1 +evoplay.gq, 1 +evosyn.com, 1 +evote-ch.ch, 1 +evotec.pl, 1 +evotec.xyz, 1 +evoting-test.ch, 1 +evoting.ch, 1 +evowl.com, 1 +evrial.com, 1 +evromandie.ch, 1 +evronews.ga, 1 +evscicats.com, 1 +evscstudentwifi.com, 1 +evsinemasistemleri.tk, 1 +evstatus.com, 1 +evtasima.name.tr, 1 +evthing.se, 0 +evtripping.com, 1 +evtscan.io, 1 +evxp.it, 1 +evyn.eu, 1 +ewa-hayward.co.uk, 1 +ewaf.club, 1 +ewaipiotr.pl, 1 +ewanm89.co.uk, 1 +ewanm89.com, 1 +ewanm89.uk, 1 +ewansinclair.tk, 1 +ewanto.de, 1 +ewatchers.org, 1 +ewc.co.jp, 1 +ewcd.co.jp, 1 +ewe2.ninja, 1 +ewelinagrochowina.pl, 1 +ewesparky.com, 1 +ewhitehat.com, 1 +ewie.name, 1 +ewinstore.com, 1 +ewizmo.com, 1 +ewok.io, 1 +eworkflow.ca, 1 +eworksmedia.com, 0 +eworldmedia.ml, 1 +eworldmedia.tk, 1 +ewoutpool.tk, 1 +ewritingservice.com, 1 +ewrk.se, 0 +ewsfeed.com, 1 +ewtl.es, 1 +ewuchuan.com, 1 +ewus.de, 1 +ewy.nl, 1 +ewycena.pl, 1 +ex-deli.jp, 1 +exablue.de, 1 +exact-online-apps-by-invantive.com, 1 +exactlyinfinite.com, 1 +exactphilosophy.net, 1 +exadime.net, 1 +exaduosport.fr, 1 +exagoni.com.au, 1 +exagoni.com.my, 1 +exaktus.pt, 0 +examedge.com, 1 +examesrush.com, 1 +examesrush.com.br, 1 +examlab.tk, 1 +example.sc, 1 +exampleessays.com, 1 +examroll.fr, 1 +examroll.io, 1 +examroo.nl, 1 +examsexpert.in, 0 +examsite.tk, 1 +examsmate.in, 1 +examticket.tk, 1 +exaplac.com, 1 +exarcheia.link, 1 +exarcheia.ru, 1 +exashop.tn, 1 +exatmiseis.net, 0 +exbasi.com, 0 +excaliburtitle.com, 0 +excavation.ga, 1 +exceed-clan.tk, 1 +exceed.global, 1 +excel-mechanical.com, 1 +excel-utbildning.nu, 1 +excelbroadcast.com, 1 +excelglobalpartners.com, 1 +excelhot.com, 1 +excelkurs.one, 1 +excelkursdirekt.eu, 1 +excella.me, 1 +excellence-eventos.com, 1 +excellence.corsica, 1 +excellentrencontrer.tk, 1 +exceloreflexology.com, 1 +excelsiorcomics.com.br, 1 +exceltechoman.com, 1 +exceltobarcode.com, 1 +excentos.com, 1 +exceptionalbits.com, 1 +exceptionalservices.us, 1 +excerp.tech, 1 +excess-baggage.com, 1 +excessamerica.com, 1 +exchanger.tk, 1 +exchangers.top, 1 +exchaser.com, 1 +excite.co.id, 1 +exciters.tk, 1 +excitingbulgaria.com, 1 +excitoninteractive.com, 1 +exclusive-okno.ru, 1 +exclusive-world.tk, 1 +exclusivebeautystudio.com.au, 1 +exclusivebouncycastles.co.uk, 1 +exclusivedesignz.com, 1 +exclusivemarket.net, 1 +exclusivityglobal.tech, 1 +excluzive.ml, 1 +excoins.biz, 1 +excomm.io, 1 +excontinuum.de, 1 +excursionescaribe.com, 1 +exdamo.de, 1 +exdev.nl, 1 +exe-boss.tech, 1 +execbar.com, 1 +exechip.com, 1 +execupharm.jp, 1 +execution.biz.tr, 1 +executiveice.com, 1 +exegese.ch, 0 +exegol.co.uk, 1 +exehack.net, 1 +exeintel.com, 1 +exemples-de-stands.com, 1 +exentio.sexy, 1 +exerforge.com, 1 +exerforge.net, 1 +exerpm.tk, 1 +exesoft.ml, 1 +exexcarriers.com, 1 +exeypanteleev.com, 1 +exforo.tk, 1 +exiled.land, 1 +exiled.world, 1 +existest.com, 1 +exit9wineandliquor.com, 1 +exitooutdoor.com, 1 +exitoseguro.tk, 1 +exitreality.tk, 1 +exmart.ng, 1 +exmoe.com, 1 +exnce.com, 1 +exo136.com, 1 +exocen.com, 0 +exodiac.ph, 1 +exodium.tk, 1 +exogenous.ga, 1 +exomind.cf, 1 +exon.io, 1 +exordiumconcepts.com, 1 +exoscale.ch, 1 +exoscale.com, 1 +exoten-spezialist.de, 1 +exotic-bengal-cattery.ml, 1 +exoticads.com, 1 +exoticaz.to, 1 +exoticspecialist.com, 1 +exotictravel.tk, 1 +exousiakaidunamis.pw, 1 +exozwiki.com, 0 +expancio.com, 0 +expanda.org, 0 +expandabil.cf, 1 +expanddigital.media, 1 +expandtheroom.com, 1 +expansion-lidl.es, 1 +expatads.com, 1 +expatfinancial.com.hk, 1 +expatfire.com, 1 +expatmortgage.uk, 1 +expe.voyage, 1 +expectation.management, 1 +expeditiegrensland.nl, 0 +expeditions.com, 0 +experens.com, 1 +experienceoutdoors.org.uk, 1 +experienceoz.com.au, 1 +experiment-626.tk, 1 +experimentalguruji.cf, 1 +experimentaltheatreclub.tk, 1 +experimentator.cz, 1 +experimentrak.com, 1 +experimetrix.com, 1 +experise.fr, 1 +experpento.tk, 1 +expert-korovin.ru, 1 +expert-voronezh.tk, 1 +expert.cz, 1 +expert96.cf, 1 +expertclub.tk, 1 +experteasy.com.au, 1 +expertestate.org, 1 +expertisematrix.com, 1 +expertly.com, 1 +expertmarktrg.com, 1 +expertofficefitouts.com.au, 1 +expertpaintersvt.com, 0 +expertpanel.gc.ca, 1 +expertplumbingandsolarservicesbathurst.com.au, 1 +expertsverts.com, 1 +expertvagabond.com, 1 +expertviolinteacher.com, 1 +expii.com, 1 +expireddomains.net, 1 +expis.tk, 1 +expiscor.solutions, 1 +explicate.org, 1 +explodie.org, 1 +explodingcamera.com, 1 +explodingearths.com, 1 +exploflex.com.br, 1 +exploit-db.com, 1 +exploit.cz, 0 +exploit.party, 1 +exploit.ph, 1 +exploited.cz, 1 +exploithe.net, 1 +exploitit.com.au, 1 +exploodo.rocks, 1 +exploravacations.in, 1 +explore-malaysia.ga, 1 +explore-visions.com, 1 +explorea1a.com, 1 +explorebigideas.com, 1 +explorecams.com, 1 +exploregulf.ga, 1 +exploretsp.gov, 1 +exploring-memory.org, 1 +exploringmorocco.tours, 1 +explorium.tk, 1 +explosionstereo.tk, 1 +expo-larionov.org, 1 +expo58.tk, 1 +expobeds.com, 1 +expody.com, 1 +expoexports.tk, 1 +expoline.ua, 1 +exponentialnews.net, 1 +exponentialsoft.gq, 1 +exponline.ga, 1 +exponline.tk, 1 +expoort.co.uk, 1 +expoort.com, 1 +expoort.com.br, 1 +expoort.es, 1 +expoort.fr, 1 +expoort.it, 1 +expopodium.com, 1 +expoprime.tk, 1 +expopro24.ru, 1 +exporta.cz, 1 +exposurecompensation.co.uk, 1 +expouniverse.cf, 1 +expouniverse.tk, 1 +expovivienda.com.mx, 1 +express-hosting.org, 1 +express-shina.ru, 1 +express-shop.tk, 1 +express-vyvoz.ru, 1 +express1040.com, 1 +expressemotion.net, 1 +expresshosting.org, 1 +expressinfo.cz, 1 +expressinfo.sk, 1 +expressmarket.ru, 1 +expressrepair.ca, 1 +expressstore.ga, 1 +expresstinte.de, 1 +expressvpn.com, 1 +expresvpn-private-analytics.net, 1 +exprimo.tk, 1 +expromo.eu, 1 +expxkcd.com, 1 +exquisique.tk, 1 +exquisito.tk, 1 +exs.lv, 1 +exsanio.de, 1 +exside.com, 1 +exsora.com, 1 +extantsoft.biz, 1 +extendet.tk, 1 +extendwings.com, 1 +extensia.it, 1 +extensibility.biz.tr, 1 +extensiblewebmanifesto.org, 1 +extensiblewebreportcard.org, 1 +extensiblewebsummit.org, 1 +extensionciglia.roma.it, 1 +extensionschallenge.com, 1 +extensiontree.com, 1 +exteriorlightingagoura.com, 1 +exteriorlightingagourahills.com, 1 +exteriorlightingcalabasas.com, 1 +exteriorlightingcamarillo.com, 1 +exteriorlightingconejovalley.com, 1 +exteriorlightingdosvientos.com, 1 +exteriorlightinghiddenhills.com, 1 +exteriorlightinglakesherwood.com, 1 +exteriorlightingmalibu.com, 1 +exteriorlightingmoorpark.com, 1 +exteriorlightingnewburypark.com, 1 +exteriorlightingoakpark.com, 1 +exteriorlightingsimivalley.com, 1 +exteriorlightingthousandoaks.com, 1 +exteriorlightingwestlakevillage.com, 1 +exteriorroofwindowguttercleaning.com, 1 +exteriorservices.io, 1 +externalapps.com, 1 +externer-datenschutzbeauftragter-bochum.de, 1 +extienso.com, 1 +extinctionrebellion.de, 1 +extintormadrid.com, 1 +extirosli.ga, 1 +extmatrix.com, 0 +extrabits.pt, 1 +extracting.tk, 1 +extradesktops.com, 0 +extradiely.sk, 1 +extradivers-worldwide.com, 1 +extraeasycash.com, 1 +extraefficiency.tk, 1 +extraefficient.tk, 1 +extrafrei.at, 1 +extrapagetab.com, 1 +extraspaces.co.uk, 1 +extraupdate.com, 1 +extrawdw.net, 1 +extreemhost.nl, 1 +extreme-addicts.tk, 1 +extreme-gaming.de, 1 +extreme-gaming.us, 1 +extreme-stock.com, 1 +extreme.co.th, 1 +extremebros.com, 1 +extremecleaning.com, 1 +extrememanual.net, 1 +extrememusclepump.com, 1 +extremeservicesandrestoration.com, 1 +extremesports.tk, 1 +extremfrank.tk, 1 +extrolife.ml, 1 +extromail.de, 1 +exum.tk, 1 +exvisits.tk, 1 +exvs.org, 1 +exxelmedia.de, 1 +exxoncannabis.com, 1 +exxpozed-image.de, 1 +exxpozed.ch, 1 +exxpozed.co.uk, 1 +exxpozed.com, 1 +exxpozed.de, 1 +exxpozed.eu, 1 +exxvip.com, 1 +eyal-dvorkin.com, 1 +eyasc.nl, 1 +eye-encounters.com, 1 +eye-vet.co.uk, 1 +eyeandfire.com, 1 +eyeball.ml, 1 +eyebrowsmicroblading.co.uk, 1 +eyecandy.gr, 1 +eyedea.ga, 1 +eyedesignuniversity.com, 1 +eyeglasses.com, 0 +eyejobs.com.au, 0 +eyelash-mc.com, 1 +eyelash-navi.com, 1 +eyelash.tk, 1 +eyelashconcept.com, 1 +eyelashextensions.tk, 1 +eyemagic.net, 1 +eyenote.gov, 1 +eyeonid.com, 1 +eyep.me, 1 +eyes-berg.com, 0 +eyesandearsrescue.org, 1 +eyescratch.tk, 1 +eyesee.fr, 1 +eyeshield-informatique.tech, 0 +eyespecialistsofla.com, 1 +eyestrainexplained.com, 1 +eyesurgery.tk, 1 +eyetooth.ga, 1 +eyfari.com, 1 +eyfconsultores.com, 1 +eyktasarim.tk, 1 +eynio.com, 1 +eyona.com, 1 +eyps.net, 1 +eyrid.com, 1 +eytosh.net, 1 +eyy.co, 1 +eyyit.com, 0 +eyyubyilmaz.com, 1 +ez3d.eu, 1 +ezakazivanje.rs, 1 +ezcourseonline.com, 1 +ezdog.press, 1 +ezelukwu-chambers.org, 1 +ezequiel-garzon.net, 1 +ezesec.com, 1 +ezftrs.com, 1 +ezgamble.com, 1 +ezgif.com, 1 +ezguamal.com, 1 +ezhub.de, 1 +ezifin.com, 1 +ezifund.com, 1 +ezik-ido.tk, 1 +ezinternet.com.au, 1 +ezmoddingz.tk, 1 +eznetworks.com.br, 1 +ezorgportaal.nl, 1 +ezpzdelivery.com, 1 +ezrent.tk, 1 +ezrohi.ru, 1 +ezshopper.co.uk, 1 +eztvtorrent.com, 1 +ezwritingservice.com, 1 +ezytrade.africa, 1 +ezzhole.net, 1 +f-401.com, 1 +f-bbs.net, 1 +f-csc.org, 1 +f-droid.org, 1 +f-hd.net, 1 +f-mebel-na-zakaz.ru, 1 +f-thie.de, 1 +f-u-c-k.wien, 1 +f00.fr, 1 +f00228.com, 1 +f00f.org, 1 +f0x.es, 1 +f1318.com, 1 +f1318.net, 1 +f13cybertech.cz, 1 +f1bigpicture.com, 1 +f1classement.com, 0 +f1distribution.com, 1 +f1fever.co.uk, 1 +f1fever.net, 1 +f1grandprix.tk, 1 +f1iran.com, 1 +f1minute.com, 1 +f1nal-lap.be, 1 +f1simulator.tk, 1 +f1sport.tk, 1 +f1tv-streams.live, 1 +f1worldwide.tk, 1 +f2h.io, 1 +f30365.com, 1 +f36533.com, 1 +f3b.de, 1 +f3nws.com, 1 +f3r.xyz, 1 +f42.net, 1 +f43.me, 1 +f4bkv.net, 1 +f51365.com, 1 +f5197.co, 1 +f6729.co, 1 +f6729.com, 1 +f6957.co, 1 +f6queer.org, 1 +f8003.com, 1 +f8007.com, 1 +f8036.com, 1 +f81365.com, 1 +f82365.com, 1 +f88-line.com, 1 +f88-line.net, 1 +f88288.com, 1 +f8842.com, 1 +f88da.com, 1 +f88fine.com, 1 +f88good.com, 1 +f88line.com, 1 +f88line.net, 1 +f88ll.com, 1 +f88qin.com, 1 +f88vip1.com, 1 +f88vip10.com, 1 +f88vip101.com, 1 +f88vip102.com, 1 +f88vip103.com, 1 +f88vip104.com, 1 +f88vip105.com, 1 +f88vip106.com, 1 +f88vip107.com, 1 +f88vip108.com, 1 +f88vip109.com, 1 +f88vip11.com, 1 +f88vip110.com, 1 +f88vip111.com, 1 +f88vip112.com, 1 +f88vip113.com, 1 +f88vip114.com, 1 +f88vip115.com, 1 +f88vip116.com, 1 +f88vip117.com, 1 +f88vip118.com, 1 +f88vip12.com, 1 +f88vip13.com, 1 +f88vip14.com, 1 +f88vip16.com, 1 +f88vip17.com, 1 +f88vip18.com, 1 +f88vip19.com, 1 +f88vip2.com, 1 +f88vip20.com, 1 +f88vip21.com, 1 +f88vip22.com, 1 +f88vip23.com, 1 +f88vip29.com, 1 +f88vip3.com, 1 +f88vip30.com, 1 +f88vip31.com, 1 +f88vip32.com, 1 +f88vip33.com, 1 +f88vip34.com, 1 +f88vip4.com, 1 +f88vip5.com, 1 +f88vip6.com, 1 +f88vip7.com, 1 +f88vip8.com, 1 +f88vip9.com, 1 +f88yule111.com, 1 +f88yule122.com, 1 +f88yule3.com, 1 +f88yule5.com, 1 +f88yule6.com, 1 +f88yule7.com, 1 +f88yule8.com, 1 +f88yule9.com, 1 +f8906.com, 1 +f8908.com, 1 +f8921.com, 1 +f899365.com, 1 +f8cp1.com, 0 +f8cp2.com, 0 +f8cp3.com, 0 +f8cp5.com, 0 +f8cp6.com, 0 +f8cp7.com, 0 +f8cp8.com, 0 +f8s.co, 1 +f9297.co, 1 +f9297.com, 1 +f9397.com, 1 +f9721.com, 1 +f9728.co, 1 +f9852.com, 1 +f9881.com, 1 +f9882.com, 1 +f9883.com, 1 +f9884.com, 1 +f9885.com, 1 +fa-fa.tk, 1 +fa-works.com, 1 +faapart107certifiedpilot.com, 1 +faazmusic.com, 1 +fabbro-roma.org, 1 +fabbro.roma.it, 1 +fabdiz.com, 1 +fabelturen.tk, 1 +faber.org.ru, 0 +faberoclub.tk, 1 +fabfrugals.com, 1 +fabian-fingerle.de, 1 +fabian-klose.com, 1 +fabian-klose.de, 1 +fabian-klose.net, 1 +fabian-kluge.de, 1 +fabian-zoske.de, 1 +fabian.gq, 1 +fabianackle.ch, 1 +fabianasantiago.com, 1 +fabianbeiner.com, 0 +fabianbeiner.de, 0 +fabianegli.ch, 1 +fabianfranke.de, 1 +fabiankaindl.de, 1 +fabiankoeppen.com, 1 +fabianni.tk, 1 +fabien-bousquet.com, 1 +fabien-hebuterne.fr, 1 +fabienbaker.com, 1 +fabienne-roux.org, 1 +fabiobarros.com, 1 +fabiobier.com, 1 +fabiocicerchia.it, 1 +fableforge.nl, 1 +fableheartmedia.com, 1 +faboolus.com, 1 +fabricadeobsequiosimpresores.com, 1 +fabriceleroux.com, 0 +fabriciomoreira.ga, 1 +fabrikafilmes.com.br, 1 +fabrilec.tk, 1 +fabriziofaniello.tk, 1 +fabriziorocca.it, 1 +fabse.net, 1 +fabservicos.com.br, 1 +fabslabour.uk, 1 +fabulosa.com.br, 1 +fabulouslyyouthfulskin.com, 1 +fabulouslyyouthfulskineyeserum.com, 1 +faburocks.com, 1 +fac.fi, 1 +faca.gov, 1 +facan-godollo.hu, 1 +facanabota.com, 1 +facanabota.com.br, 1 +facaobemquevcpode.org.br, 1 +facarospauls.com, 1 +facchinaggio.milano.it, 1 +facchinaggio.roma.it, 1 +facchino.it, 1 +facciadastile.it, 1 +face-fashion.de, 1 +face-mania.com, 1 +face-recognition-cctv.co.uk, 1 +face.yoga, 1 +face2faith-vechta.de, 1 +facebeautyhq.com, 1 +facebook-atom.appspot.com, 1 +facebook-program.com, 1 +facebook.ax, 1 +facebook.com, 0 +facebookmail.com, 1 +facebookrecruiting.com, 1 +facebydrh.com, 1 +facebylouise.co.uk, 1 +facedack.com, 1 +faceegypt.tk, 1 +facekungfu.com, 0 +faceling.net, 1 +facemaze.io, 1 +facepainting.gr, 1 +facepalmsecurity.com, 1 +facepunch.org, 1 +facerepo.com, 1 +faceresources.org, 1 +facesdr.com, 1 +facesnf.com, 1 +faceyogaforyou.com, 1 +facfox.com, 1 +fach-journalist.de, 1 +fachfusspflege-exner.de, 1 +fachim.tk, 1 +fachiri.tk, 1 +fachmann-umzuege.de, 1 +fachowisko.pl, 1 +fachschaftslisten.at, 1 +fachschaftslisten.org, 1 +fachversand-hennes.de, 1 +facialcare.tk, 1 +facialexercising.com, 1 +facialparalysisnetwork.ga, 1 +facialplasticsurgeryofaustin.com, 1 +facil.services, 0 +facilecommebonjour.com, 1 +faciledireto.com.br, 1 +facileway.com, 1 +facilit-info.fr, 1 +facilities.fr, 1 +facilitiessurvey.org, 1 +facilitobet.com, 1 +facilitrak.com, 1 +facility-service-muenchen.de, 1 +facingbipolar.com, 0 +fackovcova.cz, 1 +fackovcova.eu, 1 +fackovcova.fun, 1 +fackovcova.online, 1 +fackovcova.sk, 1 +fackovec.cz, 1 +fackovec.eu, 1 +fackovec.fun, 1 +fackovec.online, 1 +fackovec.sk, 1 +factbytefactbox.com, 1 +factis.com, 1 +factor.cc, 0 +factoriadifacil.com, 1 +factoringsolutions.co.uk, 1 +factorio.tools, 1 +factoriotools.com, 1 +factoriotools.net, 1 +factoriotools.org, 1 +factorit.fr, 1 +factorway.com, 1 +factoryalimentos.com.br, 1 +factorypartsdirect.com, 1 +factozia.tk, 1 +facts-about-bees.ml, 1 +factslider.tk, 1 +factsvision.sr, 1 +factum-info.net, 1 +facturama.pt, 1 +factureenlinea.com, 0 +factuur.pro, 1 +factuursturen.be, 1 +factuursturen.nl, 1 +facty.com, 1 +factys.do, 1 +factys.es, 1 +facua.org, 1 +facucosta.com.ar, 1 +fadednet.com, 0 +fademusic.tk, 1 +fadenmeer.net, 1 +fadergs.edu.br, 1 +faderweb.de, 1 +fads-center.online, 1 +fadusongs.com, 1 +fady.vn, 1 +fae.watch, 1 +faehler.de, 1 +faelix.net, 1 +faerb.it, 1 +faeriebabe.com, 1 +faeriecakes.be, 1 +faeservice.eu, 1 +faeton.tk, 1 +fafa018.com, 1 +fafa106.com, 1 +fafarishoptrading.com, 1 +fafatiger.com, 1 +fafscloud.com, 0 +fag.wtf, 1 +fagdag.dk, 1 +faggut.gg, 1 +fagus.hopto.org, 1 +fahadbook.com, 1 +fahnamporn.com, 1 +fahrenwal.de, 1 +fahrenwalde.de, 1 +fahrschule-laux.de, 1 +fahrwerk.io, 1 +fahrzeug-talk.de, 1 +fai.gov, 1 +faidanoi.it, 1 +faidatefacile.it, 1 +faieurope.it, 1 +fail.cf, 1 +fail4free.de, 0 +failforward.tech, 1 +failover.de, 1 +failover.eu, 1 +failoverplan.it, 1 +fairbairnrealty.com, 1 +fairbill.com, 1 +fairbot.cf, 1 +fairbot.gq, 1 +fairbot.ml, 1 +fairbot.tk, 1 +fairdata.ga, 1 +fairedeseconomies.info, 1 +fairelements.net, 1 +fairfieldschool.tk, 1 +fairgolfteams.com, 1 +fairgreenlimited.com, 1 +fairleighcrafty.com, 1 +fairmarketing.com, 1 +fairouzacademy.org, 1 +fairplay.im, 1 +fairr.de, 1 +fairr.online, 1 +fairssl.dk, 1 +fairssl.se, 1 +fairtradegemeentegent.be, 1 +fairviewfarmacy.com, 1 +fairviewmotel-simcoe.com, 1 +fairyballet.ga, 1 +fairydust.space, 1 +fairyth.tk, 1 +faisia.tk, 1 +faithbulletin.tk, 1 +faithcentercogop.net, 1 +faithfuladvisor.com, 1 +faithfulroad.org, 1 +faithleaks.org, 0 +faithwatch.org, 1 +faixaazul.com, 1 +faizan.net, 1 +faizan.xyz, 1 +faizanullah.com, 1 +fajarafriansh.cf, 1 +fajita.party, 1 +fajode.net, 1 +fake-show.ga, 1 +fakeapple.nl, 1 +fakeboost.com, 1 +fakebusters.club, 1 +faked.org, 1 +fakedisk.com, 1 +fakeemergency.com, 1 +fakel.ga, 1 +fakemoney.ga, 1 +fakerli.com, 1 +fakes-ru.tk, 1 +fakinga.tk, 1 +fakt.tk, 1 +fakti.bg, 0 +faktotum.tech, 0 +fakturar.com, 1 +fakturi.com, 1 +faktury.co, 1 +falaeapp.org, 1 +falaowang.com, 1 +falasteenjobs.com, 1 +falbros.com, 1 +falce.in, 1 +falcema.com, 1 +falcibiosystems.org, 1 +falcom.co.jp, 1 +falcon-forex.com, 1 +falcona.io, 1 +falconfrag.com, 1 +falconventures.ca, 1 +falconvintners.com, 1 +falcoz.co, 1 +faldoria.de, 1 +fale.io, 1 +falegname-roma.it, 1 +falegname.roma.it, 1 +falegnameria.milano.it, 1 +falkus.net, 1 +fall.es, 1 +fall.ga, 1 +falldennismarketing.com, 1 +fallenangeldrinks.co.uk, 1 +fallenangeldrinks.com, 1 +fallenangeldrinks.eu, 1 +fallenangelspirits.co.uk, 1 +fallenangelspirits.com, 1 +fallenmoons.nl, 1 +fallenspirits.co.uk, 1 +fallin.space, 1 +falling.se, 1 +fallofthecitadel.com, 1 +fallonarrocho.tk, 1 +fallout-craft.ru, 1 +fallriverbiblechapel.tk, 1 +fallvegermdfharder.gq, 1 +false.in.net, 1 +falsesecurity.org, 1 +falsterhus.de, 1 +falsterhus.dk, 1 +falsum.net, 1 +fam-borsch.de, 1 +fam-kreibich.de, 1 +fam-roos.com, 1 +fam-stemmer.de, 0 +famcloud.de, 1 +famdouma.nl, 1 +fameng.nl, 1 +famep.gov, 1 +famer.me, 1 +fameslook.tk, 1 +famestube.de, 1 +fameus.fr, 1 +fameuxhosting.co.uk, 1 +famfi.co, 1 +famgdigital.com, 1 +familiaconfort.com.ar, 1 +familialchercher.tk, 1 +familiaperez.net, 0 +familie-keil.de, 1 +familie-kruithof.nl, 1 +familie-kupschke.de, 1 +familie-leu.ch, 1 +familie-mischak.de, 1 +familie-monka.de, 1 +familie-mueller.com.de, 1 +familie-poeppinghaus.de, 1 +familie-remke.de, 1 +familie-sprink.de, 0 +familie-witzik.eu, 1 +familiearchivaris.nl, 1 +familiebies.nl, 1 +familieholme.de, 1 +familiekiekjes.nl, 1 +familienoase-koenigstein.de, 1 +familienportal.de, 1 +familiereimann.com, 1 +familievisscher.tk, 1 +familjenm.se, 1 +familledessaint.fr, 1 +familleseux.net, 1 +familleshilton.com, 1 +familychiropracticcolumbus.com, 1 +familyclinicstl.com, 1 +familyframeworks.com, 1 +familylawhotline.org, 1 +familyparties.co.uk, 1 +familyrecipe.co.uk, 1 +familytreehq.com, 1 +familytrees.net, 1 +familytron.com, 1 +familyworld.gr, 1 +familyzone.ga, 1 +famion.eu, 1 +famlefeber.nl, 1 +fammamtl.com, 1 +famonitor.com, 1 +famosas.cf, 1 +famous-models.tk, 1 +famousbirthdays.com, 1 +famouscelebsurgery.net, 1 +famouschilirecipes.com, 1 +famoushostels.com, 1 +famousit.nl, 1 +famouspdf.gq, 1 +famvsomeren.nl, 1 +fan.gov, 1 +fan4all.de, 1 +fanactu.com, 1 +fanatical.com, 1 +fanaticamandafans.tk, 1 +fanatik.io, 1 +fanatka.tk, 1 +fanboi.ch, 1 +fanclubblackhills.tk, 1 +fanclubmariaciobanu.tk, 1 +fanclubrbdmaniaromania.tk, 1 +fancy-bridge.com, 1 +fancy.org.uk, 1 +fancygaming.dk, 1 +fancypantsfit.com, 1 +fancypanty.cf, 1 +fandeev.tk, 1 +fander.it, 1 +fandomservices.com, 1 +fanescu.ro, 1 +fanfareunion.ch, 0 +fangbing.me, 1 +fangkehou.eu.org, 1 +fangs.ink, 1 +fanidrakopoulou.tk, 1 +fanjingbo.com, 1 +fanjoe.be, 1 +fannietremblay.com, 1 +fanning.tk, 1 +fannyips.tk, 1 +fanohus.de, 1 +fanohus.dk, 1 +fans-lily-allen.tk, 1 +fansale.de, 1 +fanschic.com, 1 +fansided.com, 1 +fanstuff.ru, 1 +fantacast.it, 1 +fantasiapainter.com, 1 +fantasiasaitian.com, 1 +fantasiatravel.hr, 1 +fantasmesexuel.info, 1 +fantasmma.tk, 1 +fantasticcleaners.com.au, 1 +fantastichandymanmelbourne.com.au, 1 +fantastici.de, 1 +fantasticservices.com, 1 +fantasticservicesgroup.com, 1 +fantasticservicesgroup.com.au, 1 +fantasy-judo.com, 1 +fantasyadventures.tk, 1 +fantasybet.co, 1 +fantasycastles.co.uk, 1 +fantasycdn.com, 1 +fantasydesign.no, 1 +fantasyempires.net, 1 +fantasyempires.nl, 1 +fantasyescortsbirmingham.co.uk, 1 +fantasyfoot.tk, 1 +fantasymina.de, 1 +fantasypartyhire.com.au, 1 +fantasyprojections.com, 1 +fantasyspectrum.com, 1 +fantasysportsnews.org, 1 +fantgames.com, 1 +fantinisfantasy.cf, 1 +fantom.foundation, 1 +fantraxhq.com, 1 +fanvoice.com, 1 +fanyina.cn, 1 +fanyina.com, 1 +fanysehy-prof.com, 1 +fanyue123.tk, 1 +fanz.pro, 1 +fanzapers.ga, 1 +fanzlive.com, 1 +fap.link, 1 +fap.no, 1 +fapality.com, 1 +fapcoholic.com, 1 +fapiis.gov, 1 +fapp.tube, 1 +fapplepie.com, 1 +fapplesauce.com, 1 +faq.lookout.com, 0 +faqin-hr.info, 1 +faqiteam.tk, 1 +far-east.tk, 1 +far3link.tk, 1 +fara.gov, 1 +faradji.nu, 1 +faradome.ws, 1 +faradrive.ir, 1 +farallonesrentacar.com, 1 +faraloda.tk, 1 +faramashin.com, 1 +faraonplay5.com, 1 +faraonplay7.com, 1 +faraonplay8.com, 1 +faraslot8.com, 1 +faraslot8.net, 1 +farb-tabelle.de, 1 +farberplasticsurgery.com, 1 +farcecrew.de, 0 +fareast.cf, 1 +fareast.ga, 1 +fareast.gq, 1 +fareast.tk, 1 +fareinternational.com, 1 +faretravel.co.uk, 1 +faretrotter.com, 1 +farfallapets.com.br, 1 +farfor.tk, 1 +fargtorget.se, 1 +farhadexchange.com, 1 +farhanaditya.com, 0 +farhood.org, 1 +farian.tk, 1 +faribanx-porn.com, 1 +farid.is, 1 +farinatorace.es, 1 +farizhan.com, 0 +farizizhan.com, 0 +farleybrass.com.au, 1 +farleymetals.com.au, 1 +farleysworlds.com, 1 +farm-catalog.ga, 1 +farm-dogecoin.tk, 1 +farm-vacations.com, 1 +farm24.co.uk, 1 +farmacia.pt, 1 +farmaciacomunalelacchiarella.it, 1 +farmaciacorvi.it, 1 +farmaciadejaime.es, 1 +farmaciaviva.es, 1 +farmaspeed.it, 1 +farmaweb.be, 1 +farmer-miniaturen.tk, 1 +farmer.dating, 1 +farmers.gov, 1 +farmkazuto.com, 1 +farmmaximizer.com, 1 +farmocracy.in, 1 +farodeluz.ca, 1 +faroes.net, 1 +faroes.org, 1 +faroit.tk, 1 +farol.cz, 1 +farrel-f.cf, 1 +farrel-f.id, 1 +farrel-f.tk, 1 +farrelf.blog, 1 +farsil.eu, 1 +farumbedandbreakfast.dk, 1 +farwat.ru, 1 +fasam.edu.br, 1 +fascat.com, 1 +faschingmd.com, 1 +fascia.fit, 1 +fasea.gov.au, 1 +fashion-buttons.tk, 1 +fashion-family.cf, 1 +fashion-stoff.de, 1 +fashion-swimwear.tk, 1 +fashion-world.tk, 1 +fashion.bg, 1 +fashion.net, 1 +fashionadvice.tk, 1 +fashionandbeautystyle.com, 1 +fashioncatalogues.tk, 1 +fashiondays.bg, 1 +fashiondays.hu, 1 +fashiondays.ro, 1 +fashiondock.de, 0 +fashioneditor.gr, 1 +fashionflavorph.com, 1 +fashionfuture.tk, 1 +fashionlistify.tk, 1 +fashionmasala.tk, 1 +fashionmovie.tk, 1 +fashionplus.ml, 1 +fashionrecovery.co.nz, 1 +fashionsuits.tk, 1 +fashiontrendsetter.com, 1 +fashionunited.be, 0 +fashionunited.cl, 1 +fashionunited.com, 0 +fashionunited.com.ar, 1 +fashionunited.de, 0 +fashionunited.fi, 1 +fashionunited.hk, 1 +fashionunited.hu, 1 +fashionunited.ie, 0 +fashionunited.lu, 1 +fashionunited.mx, 0 +fashionunited.nl, 0 +fashionunited.no, 1 +fashionunited.pl, 1 +fashionunited.se, 1 +fashionusa.gq, 1 +fashionweb.ml, 1 +fashionweek.tk, 1 +fashionweekweb.com, 1 +fashionxmas.gq, 1 +fasmaritime.com, 1 +faspirits.co.uk, 1 +faspirits.com, 1 +fassaden-selleng.de, 1 +fassadenverkleidung24.de, 1 +fassi-sport.it, 1 +fast-cargo.ml, 1 +fast-drops.cf, 1 +fast-events.eu, 1 +fast-mobile.tk, 1 +fast-pro.co.jp, 1 +fast-silver.tk, 1 +fastaim.de, 1 +fastandroid.org, 1 +fastbackmbg.be, 1 +fastbackmbm.be, 1 +fastbizcards.com, 1 +fastblit.com, 1 +fastbob.cf, 1 +fastbob.ga, 1 +fastbob.gq, 1 +fastbob.ml, 1 +fastbob.tk, 1 +fastcash.com.br, 1 +fastcast.ga, 1 +fastcats.tk, 1 +fastcomcorp.net, 1 +fastcommerce.org, 1 +fastconfirm.com, 1 +fastconv.com, 1 +fastcp.top, 1 +fastesp.net, 1 +fastfloorscreed.ie, 1 +fastforwardsociety.nl, 1 +fastforwardthemes.com, 1 +fastfox.tk, 1 +fasthost.com.br, 1 +fastighetsekonomi.com, 0 +fastinviter.com, 1 +fastknighki.ga, 1 +fastknigi.ml, 1 +fastlike.co, 1 +fastmail.com, 0 +fastonline.ro, 1 +fastopen.ml, 1 +fastos.com, 1 +fastos.de, 1 +fastpeoplesearch.com, 1 +fastpresence.com, 1 +fastrack.co.mz, 1 +fastserv.pl, 1 +faststage.ch, 1 +fasturl.ml, 1 +fastvisit.tk, 1 +fastvistorias.com.br, 1 +fastworx.com, 1 +fatal.ga, 1 +fatcat.tk, 1 +fatecdevday.com.br, 1 +fateitalia.it, 1 +fatfueled.com, 1 +fathalla.com, 1 +fathers4equalrights.org, 1 +fati.xyz, 1 +fatidique.com, 1 +fatiguefree.com, 1 +fatiguesyndrome.com, 1 +fatihingemisi.com, 1 +fatimamoldes.com.br, 1 +fatmixx.com, 1 +fator25.com.br, 1 +fatowltees.com, 1 +fattailcall.com, 0 +fattoriabio.jp, 1 +fattorino.it, 1 +fattyink.com, 1 +fatvalley.at, 1 +fau-bremen.tk, 1 +fau8.ml, 1 +faucetbox.com, 0 +fauceton.tk, 1 +faucetslist.tk, 1 +faulkner2020.com, 1 +faultlines.org, 1 +faultyserver.com, 1 +faunahotel.cl, 1 +faunatrek.com, 1 +fauvettes.be, 1 +fauwater.com, 1 +faux.digital, 1 +fauxcams.com, 1 +favalart.com, 1 +fave.ly, 1 +favedog.com, 1 +favorai.com, 1 +favorit-stroy-snab.ru, 1 +favoritestudent.ml, 1 +faw-club.cf, 1 +fawong.com, 1 +fawter.online, 1 +faxitron.com, 1 +faxreader.net, 1 +faxvorlagen-druckvorlagen.de, 1 +fayamovies.tk, 1 +faydali.org, 1 +fayettecountyoh.gov, 1 +fayettevillewv.gov, 1 +fayntic.com, 1 +faysalabdi.fi, 1 +fazal.tv, 1 +fazer.ddns.net, 1 +fazhion.tk, 1 +fazz.id, 1 +fazzfinancial.com, 1 +fb-lab.de, 1 +fb.gg, 1 +fb.me, 1 +fbaun.dk, 1 +fbausch.de, 1 +fbcdn.net, 1 +fbcfairburn.com, 1 +fbcopy.com, 1 +fbe.to, 1 +fbf.gov, 1 +fbfwd.email, 1 +fbhackpass.com, 1 +fbi.gov, 1 +fbigame.com, 1 +fbiic.gov, 1 +fbijobs.gov, 1 +fbo.gov, 0 +fbo.network, 1 +fboerman.nl, 1 +fbrief.org, 1 +fbsbx.com, 1 +fbthirdpartypixel.com, 1 +fbtholdings.com, 1 +fburl.com, 1 +fbwat.ch, 1 +fbwifi.com, 1 +fc-corvinul.tk, 1 +fc8882.net, 1 +fca-tools.com, 1 +fcapartsdb.com, 1 +fcapollo.tk, 1 +fcarrascosa.es, 1 +fcarsenal.tk, 1 +fcat.com.ph, 1 +fcbarcelona.cz, 1 +fcburk.de, 1 +fccarbon.com, 0 +fcforum.net, 1 +fcgmd.gov, 1 +fcic.gov, 1 +fcingolstadt.de, 1 +fcitasc.com, 1 +fcl.guru, 1 +fcosinus.com, 1 +fcpn.org, 1 +fcprovadia.com, 1 +fcsic.gov, 1 +fcts.ml, 1 +fdalawboston.com, 1 +fdaregs.com, 1 +fdereplace.tk, 1 +fdevs.ch, 1 +fdfz.edu.cn, 1 +fdicig.gov, 1 +fdicoig.gov, 1 +fdimmo24.com, 1 +fdis.net.cn, 1 +fdlibre.eu, 1 +fdlpl.org, 1 +fdmg.nl, 1 +fdms.gov, 1 +fdn.one, 1 +fdp-alsdorf.de, 1 +fdpbrig.ch, 1 +fdremodelingatlanta.com, 1 +fdresearch.ca, 1 +fdsl.eu, 1 +fdworlds.com, 1 +fe-data.nl, 1 +feac.us, 1 +feaden.me, 1 +feandc.com, 1 +fearfactory.tk, 1 +fearghus.org, 1 +fearsomegaming.com, 1 +feastofplants.com, 1 +feastr-dev.de, 1 +feastr.de, 1 +feastr.io, 1 +feastshare.com, 1 +feat.agency, 1 +feathersbtq.com, 1 +featherwallet.org, 1 +featherweightlabs.com, 1 +featuredmen.com, 1 +feb.gov, 1 +febeditora.com.br, 1 +fed-shashek.spb.ru, 1 +fed51.com, 1 +fedbizopps.gov, 1 +fedcenter.gov, 1 +federaciocatalanapipaclubs.tk, 1 +federalinvestments.gov, 1 +federaljob.net, 1 +federaljobs.gov, 1 +federalreserve.gov, 1 +federalreserveconsumerhelp.gov, 1 +federasco.ga, 1 +federatedbank.com, 1 +federico.ro, 1 +federicomigliavacca.it, 1 +federize.com, 1 +fedextrackingservices.com, 1 +fedinvest.gov, 1 +fedjobs.gov, 1 +fedn.it, 1 +fedorahosted.org, 1 +fedoralinux.or.kr, 1 +fedorapeople.org, 1 +fedoraproject.org, 1 +fedpartnership.gov, 1 +fedramp.gov, 0 +fedrooms.gov, 1 +fedrtc.org, 1 +fedshat.space, 1 +fedshirevets.gov, 1 +fedux.com.ar, 1 +feecreativity.com, 1 +feedbackproduction.tk, 1 +feedbin.com, 0 +feedclean.co, 1 +feedfall.com, 1 +feedhq.org, 1 +feedinghouse.tk, 1 +feedingmynewbaby.com, 1 +feedkovacs.hu, 1 +feedough.com, 1 +feedstringer.com, 1 +feedthefood.com, 1 +feedthegreek.tk, 1 +feedtube.com, 1 +feeeei.com, 1 +feeg-wage.gc.ca, 1 +feegg.com.br, 1 +feehla.com, 1 +feek.org, 1 +feel-events.com, 1 +feel.aero, 1 +feelerfolg.com, 1 +feelgood-workouts.de, 1 +feelgood.com.tw, 1 +feelingmassage.nl, 0 +feelmingo.com, 1 +feelmom.com, 1 +feelnet.top, 1 +feeltennis.net, 1 +feelya.com, 1 +feen.us, 1 +feepod.com, 1 +feeriedesign-event.com, 1 +feestbierfusten.nl, 1 +feetek.net, 1 +feetpa.ws, 1 +feezmodo.com, 1 +fefacaram.com.br, 1 +fefelovalex.ru, 1 +feg-wge.gc.ca, 1 +fegc-wgec.gc.ca, 1 +fegli.gov, 1 +fehngarten.de, 1 +fehr-online.eu, 1 +feigling.net, 0 +feignandfolly.tk, 1 +feildel.fr, 1 +feilen.de, 1 +feilestrokestown.com, 1 +feines-cbd.at, 1 +feintuchlaw.com, 1 +feirlane.org, 0 +feiromo.com, 1 +feisim.com, 1 +feisim.org, 1 +feistore.com.tw, 1 +feistyduck.com, 1 +feitam.es, 1 +feixiang.eu.org, 1 +feixiang.pp.ua, 1 +feiya.ng, 1 +fejervar.hu, 1 +fekepp.net, 1 +fekir.info, 1 +feld.design, 1 +feld.saarland, 1 +feldbogenclub-hamburg.de, 1 +feldhousen.com, 1 +feldkirchen.tk, 1 +felett.es, 1 +felger-times.fr, 1 +feli.games, 1 +felicifia.org, 1 +feline.ro, 1 +felinepc.com, 1 +felipesuri.com, 1 +feliscatus.tk, 1 +felistirnavia.sk, 1 +felitecn.com, 1 +felix-hirner.de, 1 +felixaufreisen.de, 1 +felixbarta.de, 1 +felixbrand.de, 1 +felixbroekhuizen.tk, 1 +felixc.at, 1 +felixcabrol.com, 1 +felixcrux.com, 1 +felixgerschau.com, 1 +felixharo.es, 1 +felixkauer.de, 1 +felixklenner.de, 1 +felixmendez.com, 1 +felixqu.com, 1 +felixsanchez.tk, 1 +felixsanz.com, 1 +felixseele.de, 1 +felixvelarde.com, 1 +fellas.com.tr, 1 +felsare3.com, 1 +felsenheimer.tk, 1 +felsing.net, 1 +felton.network, 1 +feltons.me, 1 +feluck.de, 1 +female-costumes.tk, 1 +femalefoodie.com, 1 +femalefrag.com, 1 +femarelle.is, 1 +femastudios.com, 1 +femcompany.nl, 1 +femdombbw.com, 1 +femiluna.com, 1 +feminina.eu, 1 +feminina.pt, 1 +feministreview.cf, 1 +feministspectrum.org, 1 +feministwiki.org, 1 +feminity.co, 1 +feminteligencia.com, 1 +femiwiki.com, 1 +femmes-women.gc.ca, 1 +femmes.gc.ca, 1 +femmesaupluriel.com, 1 +femtomind.com, 1 +fena.jp, 1 +fenagav.ga, 1 +fence-stlouis.com, 1 +fencekirkwood.com, 1 +feng-hhcm.com, 1 +feng.si, 1 +fengchuiyudaqu.ml, 1 +fenghuangcheng.tk, 1 +fengyadi.com, 1 +fengyi.tel, 1 +fengying.co, 1 +fenhl.net, 1 +fenichelar.com, 1 +fenitriatnica.tk, 1 +fenix-site.tk, 1 +fenixhost.com.br, 1 +fenixmetal.tk, 1 +fenn.moe, 1 +fennet.rentals, 1 +fennydewit.nl, 1 +fenom.ga, 1 +fenotipo.com, 1 +fenriragic.com, 1 +fenschui.ru, 1 +fenster-bank.at, 1 +fenster-bank.de, 1 +fensterbau-mutscheller.de, 1 +fenus.com.ar, 1 +fenyks.net, 1 +feodosiya.cf, 1 +feodosiya.tk, 1 +fer.pw, 1 +ferad.net, 1 +feras-alhajjaji.com, 1 +feraz.com.mx, 1 +ferc.gov, 1 +ferestre-bucuresti.ro, 1 +ferfer.ga, 1 +fergtm.com, 1 +feridun.tk, 1 +feriehus-danmark.no, 1 +ferien-netzwerk.de, 1 +ferien-zweibruecken.tk, 1 +ferienchalet-wallis.ch, 1 +ferienhaeuser-krummin.de, 1 +ferienhaus-danemark-hund.de, 1 +ferienhaus-danemark-privat.de, 1 +ferienhaus-laesoe.de, 1 +ferienhaus-montenegro.tk, 1 +ferienhaus-polchow-ruegen.de, 0 +ferienhaus-urlaub-danemark.de, 1 +ferienhausprovence.ch, 1 +ferienstpeter.de, 1 +ferienwohnung-becks.de, 1 +ferienwohnung-hafeninsel-stralsund.de, 1 +ferienwohnung-wiesengrund.eu, 1 +ferienwohnungen-lastminute.de, 1 +ferienwohnunglanger.de, 1 +ferieservice.dk, 1 +feriespotter.dk, 1 +ferlc.org, 1 +fermabel.com.br, 1 +fermanacuratampaparts.com, 1 +fermanaghomagh.com, 1 +fermastore.cf, 1 +fermateh.com.ua, 1 +fermier-mag.ro, 1 +fernandes.org, 1 +fernandezvilar.es, 1 +fernandoalonso.tk, 1 +fernandob.com, 1 +fernandobarata.pt, 1 +fernandobarillas.com, 1 +fernandomiguel.net, 1 +fernandosuarez.cf, 1 +fernheim.com.py, 1 +fernland.com.au, 1 +feross.net, 1 +feross.org, 1 +ferozes.com.br, 1 +ferprobolivia.com, 1 +ferrada.org, 0 +ferrariadvisor.it, 1 +ferrarichat.fr, 1 +ferret.zone, 1 +ferreteriaferreiro.com, 1 +ferriswheelofficial.us, 1 +ferrodata.de, 1 +ferrolatino.ch, 1 +ferrousmoon.com, 1 +ferrovial.com, 1 +fersan.pe, 1 +ferticare.pt, 1 +fertila.de, 1 +fertisa.com, 1 +fescuesodsouthernindiana.com, 1 +fespad.org.sv, 1 +fess.ie, 1 +festaprylar.se, 1 +festerculiacan.com, 1 +festesuniversitaries.tk, 1 +festival-tipps.com, 1 +festival-transform.com, 1 +festival365.ml, 1 +festivaldays.tk, 1 +festivaldelumieresgand.be, 1 +festivaldelumieresgand.com, 1 +festivaldimouamaroussiou.gr, 1 +festivalesargentina.com, 1 +festivalfumo.tk, 1 +festivalgourmet.com, 1 +festivaljapon.com, 1 +festivalpopayan.tk, 1 +festivalsalmondeoro.tk, 1 +festivalsrit.tk, 1 +festivitas.tk, 1 +festrentcar.pl, 1 +festx.co.za, 1 +fetawerelddans.tk, 1 +fetch.co.uk, 1 +fetchease.com, 1 +fetchmag.com, 1 +fetclips.se, 1 +fetichedecaramelo.tk, 1 +fetish-x.com, 1 +fetishbazar.cz, 1 +fetishblend.com, 1 +fetishwheels.com, 1 +fetishzone.org, 1 +fetlife.com, 1 +fetlinks.ga, 1 +feudalisten.de, 1 +feudaltactics.com, 1 +feuerhaken.org, 1 +feuerhuhn.de, 1 +feuerloescher-arten.de, 1 +feuerloescher-test.de, 1 +feuerwehr-coesfeld.de, 1 +feuerwehr-dachaufsetzer.de, 1 +feuerwehr-gebirge.de, 1 +feuerwehr-heiligenberg.de, 1 +feuerwehr-mehring.de, 1 +feuerwehr-offenbach-bieber.de, 0 +feuerwehr-vechta.de, 1 +feuerwerksmanufaktur.de, 1 +feuerwolke.spdns.de, 1 +feuetgloire.com, 0 +fever.ch, 1 +fewo-hafeninsel-stralsund.de, 1 +fewo-thueringer-wald.de, 1 +fewo-wildrosenpfad.de, 1 +fewo32.de, 1 +fey-web.tk, 1 +feybiblia.com, 1 +feyiama.de, 1 +ff-bad-hoehenstadt.de, 1 +ff-bg.xyz, 1 +ff-koenigstein-opf.de, 1 +ff-obersunzing-niedersunzing.de, 1 +ff14-mstdn.xyz, 0 +ff18.cc, 1 +ff2k.net, 1 +ff326.com, 1 +ff396.com, 1 +ff5197.co, 1 +ff5g.com, 1 +ff612.com, 1 +ff6729.co, 1 +ff6729.com, 1 +ff675.com, 1 +ff6957.co, 1 +ff9297.co, 1 +ff9397.com, 1 +ff956.com, 1 +ff965.com, 1 +ff9721.com, 1 +ff9728.co, 1 +ff976.com, 1 +ffb.gov, 1 +ffbans.org, 1 +ffbsee.net, 0 +fff-du.de, 1 +ffg.berlin, 1 +ffiec.gov, 1 +ffis.me, 0 +ffkoenigsberg.de, 1 +fflone.com, 1 +ffmradio.de, 1 +ffmv.de, 1 +ffp-survey.com, 1 +ffprofile.com, 1 +ffrev.de, 1 +ffsbgateway.com, 1 +ffsociety.nl, 1 +ffta.eu, 1 +ffty2.com, 1 +ffw-zeven.de, 1 +ffzeven.de, 1 +fgdc.gov, 1 +fgeiger.dnshome.de, 1 +fggpay.com, 1 +fgsv-heureka.de, 1 +fgsv-kongress.de, 1 +fh-x.de, 1 +fh14.com, 1 +fh169.cc, 1 +fh70.com, 1 +fh999.com, 1 +fhappcp.com, 1 +fhar.be, 1 +fharbe.de, 1 +fharbe.net, 1 +fhba.com.au, 1 +fhcdn.xyz, 1 +fhconseil.fr, 0 +fhdhelp.de, 0 +fhdhilft.de, 0 +fheuschen.de, 1 +fhfaoig.gov, 1 +fhinds.co.uk, 1 +fhm.duckdns.org, 1 +fhmkh.cn, 1 +fhservices.com.au, 1 +fhsseniormens.club, 1 +fhv-waldhausen.de, 1 +fhyl789.com, 1 +fhyl888.com, 1 +fi.google.com, 1 +fi.se, 1 +fi.search.yahoo.com, 0 +fiam.me, 1 +fianna.tk, 1 +fiareapp.red, 0 +fiasgo.com, 1 +fiasgo.dk, 1 +fiataldivat.hu, 1 +fibercoverage.com, 1 +fibo-forex.org, 1 +fibra.click, 1 +fibrasynormasdecolombia.com, 1 +fibretv.co.nz, 1 +fibretv.tv, 1 +fibroarrendacaseton.mx, 1 +fibromuebles.com, 1 +fibune.com, 1 +fichajes.com, 1 +fichier-pdf.fr, 0 +fickweiler.nl, 1 +ficlab.com, 1 +ficus.io, 1 +fid-elite.ch, 1 +fid.to, 1 +fidanza.eu, 1 +fiddlesaw.com, 1 +fidelapp.com, 1 +fidelis-it.ch, 1 +fidelis-it.net, 1 +fidelitybank.ng, 1 +fidelitysound.es, 1 +fidesic.com, 1 +fidhouriet.ch, 1 +fidias.com.br, 1 +fidoniagara.ca, 1 +fidoo.com, 1 +fiduciaire-azur.com, 0 +fiduciaire-ratio.ch, 0 +fieggen.eu, 1 +fieggen.net, 1 +fieldexpert.eu, 1 +fieldsgynroboticsurgery.com, 1 +fierce-escarpment-59441.herokuapp.com, 1 +fiercerunning.com, 0 +fierman.eu, 0 +fierman.net, 0 +fierman.us, 0 +fierscleaning.nl, 1 +fiery.me, 1 +fierykitchen.pl, 1 +fietsambassade.be, 1 +fietsambassadegent.be, 1 +fietsherstel.gent, 1 +fietskr.at, 1 +fietsvakman.nl, 1 +fifaaddict.com, 1 +fifacup.ga, 1 +fifastars.tk, 1 +fifaultimatemod.tk, 1 +fifautstore.com, 1 +fifei.de, 1 +fifemedicalgroup.co.uk, 1 +fifieldtech.com, 1 +fifr.nl, 1 +fiftynorth.eu, 1 +fiftyonetielt.be, 1 +fiftyseven.media, 1 +fiftyshadesofgreyfullmovie.ga, 1 +fiftyshadesofluca.ml, 1 +fig.ms, 1 +figbert.com, 0 +fighter-planes.tk, 1 +fighting-turtle.tk, 1 +fightinggobbler.com, 1 +fightingshit.tk, 1 +fightsupplies.co.uk, 0 +figinstitute.org, 1 +figliasons.com, 1 +figmalover.com, 1 +figura.cz, 1 +figuras.tk, 1 +figurasdelinguagem.com.br, 1 +figure.nz, 1 +figuurzagers.nl, 0 +fihatest.ml, 1 +fiilr.com, 1 +fiix.io, 1 +fijnefeestdageneneengelukkignieuwjaar.nl, 1 +fijnewoensdag.nl, 1 +fikavirtual.com, 1 +fiken.no, 1 +fikriwildannugraha.com, 1 +fiksem-it.nl, 1 +fikst.com, 1 +fil-tec-rixen.com, 1 +fil.fi, 0 +filamentia.nl, 1 +filanthropystar.org, 1 +filarakia.eu, 1 +filaretihairlove.gr, 1 +file-cloud.eu, 1 +file-pdf.it, 1 +file24.tk, 1 +filebox.one, 1 +filebox.space, 1 +filecatchers.com, 1 +filecloud.fun, 1 +filecopa.com, 1 +filedesc.com, 1 +filedoom.ml, 1 +filehash.de, 1 +filehippo.com, 1 +filehorsefile.com, 1 +fileio.io, 1 +filejet.io, 1 +filek.ga, 1 +fileon.com, 1 +filequit.xyz, 1 +files.from-me.org, 1 +files.to, 1 +filesense.com, 1 +fileservicios.com.ar, 1 +filestar.io, 1 +filestartest.io, 1 +filestreak.com, 1 +filesuffix.com, 1 +filetransfer.one, 1 +filezilla-project.org, 1 +filhodohomem.com, 1 +filhomes.ph, 1 +fili.com, 1 +filidorwiese.nl, 1 +filiio.com, 1 +filingsmadeeasy.com, 1 +filip-prochazka.com, 0 +filipdima.ro, 1 +filipi.no, 1 +filipinadating.online, 1 +filipinasdailynews.tk, 1 +filipinochinese.tk, 1 +filippo.io, 1 +filipposalvioni.com, 1 +filipstaffa.net, 1 +filleritemsindia.com, 1 +filli-it.ch, 1 +fillmorecountyne.gov, 1 +fillmysuitca.se, 1 +fillo.sk, 1 +fillu.de, 1 +film-colleges.com, 1 +film-op-tv.nl, 1 +film-storyboards.com, 0 +film-tutorial.com, 1 +filmarchiv-sachsen.de, 1 +filmatiporno.xxx, 1 +filmbasar.com, 1 +filmbest.tk, 1 +filmcorner.tk, 1 +filmdates.co.uk, 1 +filmdirectingtips.com, 1 +filme-onlines.com, 1 +filmedonstage.com, 1 +filmero.tk, 1 +filmers.net, 1 +filmisfun.com, 1 +filmisfun.net, 1 +filmitis.com, 1 +filmizleindir.tk, 1 +filmnetz.tk, 1 +filmoffice.pl, 1 +filmphotograph.com, 1 +filmpronet.in, 1 +filmreviewonline.com, 1 +filmsearch.tk, 1 +filmserver.de, 1 +filmsidan.tk, 1 +filmsite-studio.com, 1 +filmtheaternieuwegein.tk, 1 +filmwallpapers.ml, 1 +filobot.xyz, 1 +filokiralama.name.tr, 1 +filosofia.tk, 1 +filstop.com, 1 +filterlists.com, 1 +filtershekanha.com, 1 +filtr.me, 1 +fimfiction.net, 1 +fimozin.ga, 1 +fimp.pt, 1 +fimsquad.com, 1 +fina-foxy.com, 1 +final-expense-quotes.com, 1 +finalfate.tk, 1 +finalfourstream.tk, 1 +finalgambit.band, 1 +finalonline.tk, 1 +finalprice.net, 1 +finalrewind.org, 1 +finalworkdriesstef.tk, 1 +finalx.nl, 1 +finance-colleges.com, 1 +finance-consulting.ga, 1 +finance-equation.co.uk, 1 +finance-news.ga, 1 +financecontrol.tk, 1 +financedepth.com, 1 +financedraft.com, 1 +financeguest.com, 1 +financeinterface.tk, 1 +financejobs.ch, 1 +financeknown.com, 1 +financelong.com, 1 +financemain.com, 1 +financenews.global, 1 +financenews.tk, 1 +financepen.com, 1 +financeplush.com, 1 +financepre.com, 1 +financestead.com, 1 +financethrive.com, 1 +financetwenty.com, 1 +financewhile.com, 1 +financewithcromulent.com, 1 +financial-law.tk, 1 +financialfreedomaus.com, 1 +financialhost.org, 1 +financialnews.today, 1 +financieracademy.com.br, 1 +financniexperti.sk, 1 +finansa.no, 1 +finansinspektionen.se, 1 +finanskredirehberi.com, 0 +finanssaati.com, 1 +finanstilsynet.dk, 1 +finansy.tk, 1 +finanz-planer.net, 1 +finanzasydinero.com, 1 +finanzierung-sofortzusage.de, 1 +finapi.io, 1 +finax.eu, 1 +finbio.cf, 1 +fincaalegranza.com, 1 +fincas-ruiz.com, 1 +finch.am, 1 +finch.ga, 1 +finchi.de, 1 +finchnest.co.uk, 1 +fincitegroup.com, 1 +fincities.tk, 1 +find-job-in.com, 1 +find-mba.com, 1 +finda.ae, 1 +findaffordablehousing.ca, 1 +findapinball.com, 1 +findautoloan.ml, 1 +findcanary.com, 1 +findcarspecs.com, 0 +findcbdoilnearme.com, 1 +findcheap.us, 0 +finde-kleinanzeigen.de, 1 +findelahistoria.com, 1 +findenmed.com.br, 1 +findeth.io, 1 +findheim.at, 1 +findingawesome.com, 1 +findinggenius.com, 1 +findingkorea.com, 0 +findingtheuniverse.com, 1 +finditalldirectory.com, 1 +finditez.com, 1 +findlocalproduce.co.uk, 1 +findmail.ga, 1 +findmentalhealth.co.uk, 1 +findmespot.com, 1 +findmybottleshop.com.au, 1 +findmynudes.com, 1 +findmytricks.com, 1 +findolino.at, 1 +findom.network, 1 +findoon.de, 1 +findrejsepartner.dk, 1 +findsingledating.ml, 1 +findstorenearme.ca, 1 +findstorenearme.co.uk, 1 +findstorenearme.us, 1 +findthatnude.com, 1 +findthere.net, 1 +findtreatment.gov, 1 +findyour.diet, 1 +findyourtrainer.com, 1 +findyourvoice.ca, 1 +fine-services.paris, 1 +finecocoin.io, 1 +finecraft.cc, 1 +finefriends.nl, 1 +finefriends.social, 1 +finefriendsapp.com, 1 +finehealth.ru, 0 +finenet.com.tw, 1 +finesoon.net, 1 +finestinfo.com, 1 +finestrabatalera.tk, 1 +finestreview.cf, 1 +finestrina.net, 1 +finestroom.ru, 1 +finexo.ch, 1 +finext.cz, 1 +finfleet.id, 1 +finform.ch, 1 +fingerscrossed.style, 1 +fingertight.ga, 1 +finhelp.ga, 1 +fini-de-jouer.ch, 0 +finilaviolence.gc.ca, 1 +finion.com, 1 +finisron.in, 1 +finkelstein.fr, 1 +finkrer.wtf, 1 +finlandcook.online, 1 +finlandcook.top, 1 +finlito.tk, 1 +finmarket.tk, 1 +finn-svoboda.cf, 1 +finn.io, 1 +finnclass.cz, 1 +finneas.net, 1 +finnishclothing.tk, 1 +finnkupongkoder.no, 1 +finnwea.com, 0 +finom.co, 1 +finpomosh.gq, 1 +finprison.net, 1 +finpt.com, 0 +fins.money, 1 +finsecurity.eu, 1 +finsprings.org, 1 +finstererlebnis.de, 1 +fintandunleavy.com, 0 +fintechnics.com, 0 +fintry.ca, 1 +finturelife.com, 1 +finvantage.com, 1 +finvantive.com, 1 +finvantive.nl, 1 +finverse.com, 1 +finwe.info, 1 +finzy.com, 1 +fionafuchs.de, 1 +fionamcbride.com, 1 +fiorebjj.com, 1 +fiorenzaperfumhome.com.br, 1 +fioristionline.it, 1 +fioristionline.net, 1 +fiosgenomics.com, 1 +fioulmarket.fr, 1 +fipackaging.com, 1 +fipq.tk, 1 +fir.ch, 1 +fir3net.com, 1 +firatofm.tk, 1 +firc.de, 1 +fire-places.tk, 1 +fire-schools.com, 1 +firebaseio.com, 1 +firebirdrangecookers.com, 1 +firebounty.com, 1 +fireboxfood.com, 1 +firebrandchurch.com, 1 +firecask.com, 1 +firechip.cc, 1 +firechip.srl, 1 +firecore.com, 1 +firecry.org, 1 +firedemons.tk, 1 +firedo.de, 1 +fireeye.tk, 1 +firefart.at, 0 +firefense.com, 1 +firefighters.dating, 1 +firefish.com.au, 1 +fireflywellnesscounseling.com, 1 +firegeisha.com, 1 +fireglow.de, 1 +firegore.com, 1 +fireleadership.gov, 1 +firemist.com, 1 +firemudfm.com, 1 +firenews.cf, 1 +firenza.org, 1 +fireorbit.de, 0 +fireplacesutah.com, 1 +fireplex.co.uk, 1 +fireportal.cz, 1 +fireportal.sk, 1 +fireradio.tk, 1 +firerain.me, 1 +fireshellsecurity.team, 1 +firesofheaven.org, 1 +firestuff.org, 1 +firetotheprisons.org, 1 +fireurboss.tk, 1 +firevap.org, 1 +firewall.net.za, 1 +firewallremoval.cf, 1 +fireware.tk, 1 +fireworksshowvr.com, 1 +firexarxa.de, 1 +firexfly.com, 1 +firexp.tk, 1 +firma-cerny.cz, 1 +firma-offshore.com, 1 +firmador.cloud, 1 +firmador.digital, 1 +firmador.online, 1 +firmale.com, 1 +firmament.space, 1 +firmament.tk, 1 +firmapi.com, 1 +firmen-assekuranz.de, 1 +firmenwerbung-vermarktung.de, 1 +firmground.nl, 1 +firmware.science, 1 +firouz.tk, 1 +first-aid-kit.net, 0 +first-house.no, 1 +first-money.tk, 1 +first-ns.com, 0 +first-time-offender.com, 1 +first.org, 1 +first4it.com, 1 +firstbaptistchurchofchrist.org, 1 +firstbaptistjeff.org, 1 +firstbooks.ml, 1 +firstcentralsavings.com, 1 +firstchoicebouncycastlehire.co.uk, 1 +firstchoicecandy.com, 1 +firstchoicefriseur.at, 1 +firstclass.com.kh, 1 +firstclasscastles.com, 1 +firstclassleisure.co.uk, 1 +firstclassnuisance.tk, 1 +firstclinic.tk, 1 +firstcoastteaco.com, 1 +firstcolonyengraving.com, 1 +firstderm.com, 1 +firstdorsal.eu, 1 +firstdry.com.br, 1 +firstechpayments.com, 1 +firstfinca.de, 1 +firstgov.gov, 1 +firstgradeframeofmind.com, 1 +firstisrael.org.il, 1 +firstlayout.net, 1 +firstlightinspirations.tk, 1 +firstmall.de, 1 +firstmarket.tech, 1 +firstnet.gov, 1 +firstnetwork.cf, 1 +firstnetworksouth.com, 1 +firstphilec.com, 1 +firstplace.ga, 1 +firstq.xyz, 1 +firstresponder.gov, 1 +firstsiteguide.tk, 1 +firsttimer.tk, 1 +firstversionist.com, 1 +firstwebring.tk, 1 +firtreetechnology.co.uk, 1 +fisaplay.com, 1 +fisarmonica.com.br, 1 +fischer-immoteam.de, 1 +fischer-its.com, 0 +fischer-kundendienst.de, 1 +fischer-wasels-medizin.de, 1 +fischerlaender.de, 1 +fischerp.net, 1 +fischers.it, 1 +fischers.srv.br, 1 +fiscoeconti.it, 1 +fise.cz, 1 +fish-hook.ru, 1 +fish-n-chips.uk, 1 +fish2.me, 1 +fishbattle.io, 1 +fishbattle.net, 1 +fishcorp.dk, 1 +fishergo.ml, 1 +fishergo.tk, 1 +fishermailbox.net, 1 +fisherman-union.ml, 1 +fishermansbend.apartments, 1 +fishermansbendcorporation.com.au, 1 +fishermansbendtownhouses.com.au, 1 +fisherscientificsafety2021.com, 1 +fishexport.eu, 1 +fishfish.tk, 1 +fishgen.no, 1 +fishingplaces.net, 1 +fishingworld.tk, 1 +fishlanestudios.com, 1 +fishme.in, 1 +fishoftheday.tv, 1 +fishoilsafety.com, 1 +fishserver.net, 1 +fishtacos.blog, 1 +fishtank.ga, 1 +fishycam.com, 1 +fishygames.ml, 1 +fishyscans.tk, 1 +fishystuff.cf, 1 +fisinfomanagerdr.com, 1 +fisiobox.eu, 1 +fisiodomiciliargoiania.com.br, 1 +fisiolunges.it, 1 +fisioterapista.roma.it, 1 +fisiotohome.com, 1 +fiskalnepretor.pl, 1 +fiskelures.se, 1 +fiskosceyiz.com, 0 +fiskosceyiz.com.tr, 1 +fit-4u.ch, 0 +fit-mit-nina.com, 1 +fit-mit-system.eu, 1 +fit365.jp, 0 +fitandfightrijswijk.nl, 1 +fitbase.fitness, 1 +fitbylo.com, 1 +fitcamp.fitness, 1 +fitchconnect.com, 1 +fitchdesigncompany.com, 1 +fitcoachion.com, 1 +fitcrewhn.com, 1 +fite.family, 0 +fitequilibrio.com.br, 1 +fitflaop.ga, 1 +fitfocusau.com.au, 1 +fitkram.cz, 1 +fitmybike.eu, 0 +fitness-challenge.co.uk, 1 +fitness-world.ga, 1 +fitness.gov, 1 +fitnessexpostores.com, 1 +fitnesshaber.com, 1 +fitnesshire.net, 1 +fitnesskarate.club, 1 +fitnessmaus.com, 1 +fitnessplanet.best, 1 +fitnessunder50.com, 1 +fitnessup.fr, 1 +fitnetion.com, 1 +fitnhot.com, 1 +fito.tk, 1 +fitplus.tk, 1 +fitrecepty.info, 1 +fittelo.cz, 1 +fittingperfetto.it, 1 +fittwon.com.au, 1 +fitzsim.org, 1 +fiusi.net, 1 +fiveboosts.xyz, 1 +fivefortheroad.com, 1 +fiveloaves.life, 1 +fivemnetwork.nl, 1 +fivepedia.tk, 1 +fiveslice.pizza, 1 +fivestartrader.com, 1 +fivetecnologia.com, 1 +fivethirtyeight.com, 1 +fiveyearsahead.com, 1 +fix-ru.ga, 1 +fix-the-timeline.com, 1 +fix-the-timeline.org, 1 +fix.mk, 1 +fixaslowcomputer.com, 1 +fixatelierstore.com.br, 1 +fixatom.com, 1 +fixdiabetesnaturally.com, 1 +fixed.tech, 1 +fixedtoday.com.au, 1 +fixedtodayplumbing.com.au, 1 +fixfix.ch, 1 +fixfm.tk, 1 +fixforce.nl, 1 +fixingcountrybridges.com.au, 1 +fixingscrews.co.uk, 1 +fixlasvegas.com, 1 +fixmyalarmpanel.co.uk, 1 +fixmycomputerdude.com, 1 +fixmyglitch.com, 1 +fixpoint.co.at, 1 +fixpoint.systems, 1 +fixthetimeline.com, 1 +fixthetimeline.org, 1 +fixverkaufen.de, 1 +fixvoltage.ru, 1 +fiyatgrafik.com, 1 +fizadvocaten.nl, 1 +fiziktedavi.name.tr, 1 +fizjoterapia.uk, 1 +fizyoterapi.name.tr, 1 +fizz.buzz, 0 +fizz.cloud, 1 +fizz.space, 1 +fizz.studio, 1 +fizz.systems, 1 +fizz.team, 1 +fizz.technology, 1 +fizz.tools, 1 +fizz.world, 1 +fizz.zone, 1 +fizzcharts.com, 1 +fizzcompetitions.com, 1 +fizzcoronationstreetdied.cf, 1 +fizzcreativemedia.com, 1 +fizzstudio.org, 1 +fj.search.yahoo.com, 0 +fjallconnections.com, 1 +fjco.alsace, 1 +fjharcu.com, 1 +fjordboge.dk, 1 +fjsb.com, 1 +fjugstad.com, 1 +fjzone.org, 1 +fkcdn.de, 1 +fkfev.de, 1 +fklegal.com, 1 +fkosquad.moe, 1 +fkraiem.org, 1 +fktpm.ru, 1 +fl.ru, 1 +fl0w.fr, 1 +flacandmp3.ml, 1 +flacon.tk, 1 +fladby.org, 1 +flaemig42.de, 0 +flag3force.com, 0 +flagburningworld.com, 1 +flagcdn.com, 1 +flagcity.com, 1 +flagfox.net, 1 +flaggorvarlden.se, 1 +flagi-panstw.pl, 1 +flagipanstw.info.pl, 1 +flagipanstw.pl, 1 +flagistrany.ru, 1 +flagma.by, 1 +flagma.pl, 1 +flagma.ru, 1 +flagma.ua, 1 +flagpedia.asia, 1 +flagpedia.net, 1 +flagriculture.gov, 1 +flagspot.net, 0 +flagyl-500-mg.ga, 1 +flairfindr.com, 1 +flam.io, 1 +flam3d.be, 1 +flam3d.nl, 1 +flam3d.org, 1 +flamebot.ru, 1 +flamehaze.tk, 1 +flamencoexplained.com, 0 +flamencoshoes.tk, 1 +flamentecnic.tk, 1 +flamero.fi, 1 +flamet.eu, 1 +flameviper.tk, 1 +flameworked.com, 1 +flamingcow.tv, 1 +flamingkeys.com, 1 +flamingowomenspavilion.com, 1 +flamme-von-anor.de, 1 +flana.com, 1 +flanderslaw.com, 0 +flanga.io, 0 +flapoverspeed.com, 1 +flare.cloud, 1 +flaretechnologies.io, 1 +flarewalker.com, 1 +flarewalker.eu, 1 +flarewalker.net, 1 +flarewalker.org, 1 +flart.tk, 1 +flasaki.gr, 1 +flash-games.tk, 1 +flashback.org, 1 +flashbackband.tk, 1 +flashbaggie.com, 1 +flashcardsmobile.com, 1 +flashcrasher.com, 1 +flashgamedev.tk, 1 +flashgot.net, 1 +flashigra.tk, 1 +flashissue.com, 1 +flashlearners.com, 1 +flashlightchart.com, 1 +flashset.tk, 1 +flashtek-uk.com, 1 +flassetlocators.com, 1 +flat-tire.biz, 1 +flat.io, 1 +flatart.pl, 1 +flatbellyreview.com, 1 +flatbook.one, 1 +flathome.co.jp, 1 +flaticon.com, 1 +flatlandchurch.com, 0 +flatmail.pl, 1 +flatmatehub.com.au, 1 +flatpackmates.co.uk, 1 +flatsomestudio.ir, 1 +flatsurfers.eu, 1 +flattie.cz, 1 +flauschig.net, 1 +flavelappliances.com, 1 +flavinha.tk, 1 +flavinus.fr, 1 +flavio.click, 1 +flaviu.co.uk, 1 +flavo.io, 1 +flawless-gaming.tk, 1 +flawlessbiometrics.com, 1 +flawlesscowboy.xyz, 1 +flawlessly.tk, 1 +flblog.top, 1 +flcatering.com, 1 +flconcretelifting.com, 1 +flealab.it, 1 +fleeb.xyz, 1 +fleep.io, 1 +fleesty.dynv6.net, 1 +fleet-group.com, 1 +fleet-search.com, 1 +fleetcomplete.com, 1 +fleetcor.at, 1 +fleetcor.ch, 1 +fleetcor.cz, 1 +fleetcor.de, 1 +fleetcor.fr, 1 +fleetcor.hu, 1 +fleetcor.lu, 1 +fleetcor.nl, 1 +fleetcor.pl, 1 +fleetcor.sk, 1 +fleetcorcards.be, 1 +fleetpal.io, 1 +fleetsmith.com, 1 +fleetssl.com, 1 +fleetster.es, 1 +fleetster.net, 1 +fleetster.nl, 1 +fleettools.tk, 1 +fleetyards.net, 1 +flehm.de, 1 +fleisch.club, 1 +fleischkaes.de, 1 +flemingmccullagh.com, 1 +flemingtonaudiparts.com, 1 +flens.dance, 1 +flensburg-hilft-flensburg.de, 1 +flers-agglo.fr, 1 +flerstourisme.fr, 1 +fleshwound.tk, 1 +fletcherdigital.com, 1 +fletcherdoescrime.com, 1 +fletchmusic.tk, 1 +fletchto99.com, 1 +fletesymudanzasbaratas.com, 1 +flets-ms.com, 1 +fleurenplume.fr, 1 +fleurette.me, 1 +fleuromance.ga, 1 +fleursdesoleil.fr, 0 +fleursdujour.ph, 1 +fleuryfleury.com, 1 +flexapplications.se, 1 +flexdrukker.nl, 1 +flexfunding.com, 1 +flexiblenetflow.com, 1 +flexibsd.com, 1 +flexicurity.tk, 1 +fleximaal.com, 1 +fleximus.org, 0 +flexinvesting.fi, 1 +flexmedia.tk, 1 +flexport.com, 1 +flexstart.me, 1 +flextribly.xyz, 1 +flexussolucoes.com.br, 1 +flexve.com, 1 +flfl.de, 1 +fliacuello.com.ar, 1 +flibanserina.com, 1 +flicerdowneh.cf, 1 +flickor.tk, 1 +flieger-funk-runde.de, 1 +fliesen-waldschmidt.de, 1 +flight.school, 1 +flightdiary.gq, 1 +flightjackets.tk, 1 +flightmedx.com, 1 +flightscarhire.com, 1 +flightschoolbooking.com, 1 +flightschoolcandidates.gov, 1 +flightschoolusa.com, 1 +flightzero.cf, 1 +fliino.com, 1 +fliino.eu, 1 +fliino.info, 1 +fliino.net, 1 +fliino.org, 1 +fliio.com, 1 +flikmsg.co, 1 +flimnet.tk, 1 +flinch.io, 1 +fling.dating, 1 +flinny.org, 1 +flip.kim, 1 +flip.lease, 1 +flipmusic.tk, 1 +flipneus.net, 1 +flipos.be, 1 +flippery-wynajem.pl, 1 +flipphotography.ga, 1 +flipsidevr.com, 1 +fliptable.org, 1 +fliptracker.io, 1 +flipweb.tk, 1 +flirt-norden.de, 1 +flirtbox.tk, 1 +flirtee.net, 1 +flirtfaces.de, 1 +flirtportalcheck24.de, 1 +flixcheck.com, 1 +flixcheck.de, 1 +flixcost.com, 1 +flixflex.tk, 1 +flixhaven.net, 1 +flixports.com, 1 +flixsave.com, 1 +flixstats.com, 1 +floart.tk, 1 +floaternet.com, 1 +floatifnghotel.cf, 1 +floating-holidays.co.uk, 1 +flockbox.club, 1 +flocktofedora.org, 1 +floersheimer-openair.de, 1 +floffi.media, 1 +flog.nz, 1 +floify.com, 1 +floj.tech, 1 +flokinet.is, 1 +flokkr.com, 1 +floline.fr, 1 +flomax385.tk, 1 +flomedia.pl, 1 +flomeyer.de, 1 +flonharmonymassage.space, 1 +floobits.com, 1 +floodboss.ml, 1 +flooddoctorva.com, 1 +floodheroessaltlakecity.com, 1 +floodsmart.gov, 1 +floogulinc.com, 1 +flooood.tk, 1 +floorballphilippines.tk, 1 +flooringnightmares.com, 1 +flooringsourcetx.com, 1 +floorrestore.co.uk, 0 +floors4lessbay.com, 1 +floort.net, 0 +floppy.tk, 1 +floqast.com, 1 +floraclick.net, 1 +floraexpress.it, 1 +floralin.se, 1 +florausa.net, 1 +floravan.com, 1 +floravino.de, 1 +florenceapp.co.uk, 1 +florenciaextrema.tk, 1 +florenciasabio.com, 1 +florent-tatard.fr, 1 +floresearranjosonline.com.br, 1 +floresvilleedc.org, 0 +floria.online, 1 +florian-bachelet.fr, 1 +florian-knorn.com, 1 +florian-lefevre.fr, 1 +florian-thie.de, 1 +florian2833z.de, 1 +florianbecker.it, 1 +florianbouchet.fr, 1 +florianimdahl.de, 1 +floriankarmen.com, 1 +florianmitrea.uk, 1 +florianschmitt.ca, 1 +florianstroeger.com, 1 +floriantanner.ch, 1 +florida-immigration.com, 1 +florida-online.tk, 1 +florida-prep.org, 1 +floridaagriculture.gov, 1 +floridaconsumerhelp.gov, 1 +floridados.gov, 1 +floridafabrication.net, 1 +floridafieros.org, 1 +floridafx.gov, 1 +floridahealthcareconnections.gov, 1 +floridahomesinvest.com, 1 +floridaimigracao.com, 1 +floridamainmovers.com, 1 +floridaplasticsurgery.com, 1 +floridapowermanagement.com, 1 +floridasexhealth.com, 1 +floridawaterapparel.net, 1 +floridaweightlossdoctors.com, 1 +floriimorii.tk, 1 +florinlungu.it, 1 +floris.tk, 1 +florismouwen.com, 0 +floristics.info, 1 +floristik-online.com, 1 +florisvdk.net, 1 +floriswesterman.nl, 1 +florlola.com, 1 +floryceblanchery.fr, 1 +flosch.at, 0 +floseed.fr, 1 +flossdentallasvegas.com, 1 +flossexanten.de, 1 +floth.at, 1 +flourish.earth, 1 +flourishtogether.com, 1 +flow-serv.com, 1 +flow.su, 1 +flowair24.ru, 1 +flowalizer.com, 1 +flowalyzer.com, 1 +flowanalytics.com, 1 +flowauditor.com, 1 +flowbuk.me, 1 +flowcom.de, 1 +flowcount.xyz, 1 +flowcrypt.com, 1 +flowdise.com, 1 +flowercare.tk, 1 +flowerdelivery.tk, 1 +flowerdesign.tk, 1 +flowersandplantsco.com, 1 +flowersbylegacy.com, 1 +flowersquito.com, 1 +flowfest.com, 1 +flowhopper.com, 1 +flowinformer.com, 1 +flowinity.com, 1 +flowinvoice.com, 1 +flowlytics.host, 1 +flownonfiction.com, 1 +flowpro.info, 1 +flowreader.com, 1 +flowreplicator.com, 1 +flowscale.com, 1 +flowstars.tk, 1 +flowstudios.com, 1 +flox.io, 1 +floy.dk, 1 +flp-pushkar.info, 1 +flra.gov, 1 +flsbanners.com, 1 +flubio.de, 1 +flucky.xyz, 1 +fluconazole.gq, 1 +flucover.com, 1 +fluencytech.com, 1 +fluessiggas.de, 1 +fluff.im, 1 +fluffycat.ga, 1 +fluffycloud.de, 1 +fluffypuff.in, 1 +fluggesellschaft.de, 1 +fluglektuere.com, 1 +flugplatz-edvc.de, 1 +flugplatzmanager.de, 1 +flugrecht.de, 1 +fluidbb.co.uk, 1 +fluidpicturesinc.com, 1 +fluids.ac.uk, 1 +fluig.com, 1 +fluitbeurt.nl, 1 +flukestar.tk, 1 +flumble.nl, 1 +flunschi.goip.de, 1 +fluoxetin.ga, 1 +fluoxetin.tk, 1 +fluoxetine.net, 1 +flurecover.com, 1 +flushlife.com, 1 +flusszs.tk, 1 +fluteandpianoteaching.co.uk, 1 +flutterappdev.com, 1 +flux.healthcare, 1 +fluxforge.com, 1 +fluxoid.com, 1 +flvyingeagle.ga, 1 +flwrightwichita.org, 1 +fly-en-drive.nl, 1 +fly.moe, 1 +flyabe.com, 1 +flyavantar.com, 1 +flyawaybirds.ga, 1 +flybis.net, 1 +flyboyfpv.com, 1 +flycheaps.com, 1 +flydoc.org, 1 +flydrivesicilie.nl, 1 +flyer.tools, 1 +flygon.pink, 1 +flyhealthy.gov, 1 +flying-angels.tk, 1 +flying-dudes.de, 1 +flying-press.com, 1 +flyingangels.cf, 1 +flyingdoggy.net, 1 +flyingdutchman.tk, 1 +flyinghigh.co.jp, 1 +flyinglions.tk, 1 +flyingmonkeys.tk, 1 +flyingpackets.net, 1 +flyingrub.me, 1 +flyingspaghettimonsterdonationsfund.nl, 1 +flylvia.com, 1 +flymns.fr, 1 +flymsy.com, 1 +flyn43.com, 1 +flynn.io, 1 +flynnhub.com, 1 +flyp.me, 1 +flypenge.dk, 1 +flyspace.ga, 1 +flyspace.ml, 1 +flyss.net, 1 +flyssh.net, 1 +flyswoop.com, 1 +flyt.online, 1 +flythecopter.tk, 1 +flytoadventures.com, 1 +flytrap.in, 1 +flyupture.com, 1 +flywind.ml, 1 +flywus.com, 1 +flyxll.com, 1 +flyzoomattzir.com, 1 +fm-digitize.de, 1 +fm-online.tk, 1 +fm.ie, 1 +fmbilder.se, 1 +fmc.gov, 1 +fmcs.gov, 1 +fmdance.cl, 0 +fmi.gov, 1 +fminsight.net, 1 +fmjd64.com, 1 +fmjd64.org, 1 +fmlife.tk, 1 +fmm-creative.com, 1 +fmodoux.biz, 0 +fmorales.com, 1 +fmorales.com.ni, 1 +fmovies.qa, 1 +fmstr.ml, 0 +fmussatmd.com, 1 +fn-0.net, 1 +fnbnokomis.com, 1 +fnbot.shop, 1 +fndout.com, 1 +fneon.eu, 1 +fnerk.org, 1 +fnews.tk, 1 +fnh-expert.net, 1 +fnkr.net, 1 +fnof.ch, 1 +fnordserver.eu, 1 +fnpro.eu, 1 +fnscatania.tk, 1 +foair.me, 1 +foairbus.fr, 0 +foairbussas.fr, 0 +foamfortress.tk, 1 +focalforest.com, 1 +focalpoint.tk, 1 +focalpointvr.com, 1 +focanamoda.com.br, 1 +focanocliente.com.br, 1 +focusmagonline.com.au, 1 +focusmark.jp, 0 +focusministries1.org, 1 +focuspointtechnologies.com, 1 +focusproductions.tk, 1 +focustec.tk, 1 +focustuningclub.tk, 1 +fodder.ga, 1 +foej-aktiv.de, 1 +foej.net, 1 +foerster.gmbh, 1 +fof-clan.tk, 1 +fognini-depablo.eu, 1 +fogu.com, 1 +foguest.com.br, 1 +fogway.net, 1 +foia.gov, 1 +foiaonline.gov, 1 +foiremobile.com, 1 +foixet.com, 1 +fojing.com, 1 +fojt.cz, 1 +fojtova.cz, 1 +fojtovi.cz, 1 +fokan.be, 1 +fokan.ch, 1 +fokep.no, 1 +fokos.de, 1 +fokus.ag, 1 +fol.tf, 1 +folar.ga, 1 +folclore.tk, 1 +folianti.com, 1 +folio.no, 1 +foliumbiosciences.com, 1 +foliumfinance.com, 1 +foljeton.dk, 1 +folk.as, 1 +folkadelic.de, 1 +folkdance.tk, 1 +folkfests.org, 1 +folkofolk.se, 1 +folktalerecords.tk, 1 +follandviolins.com, 1 +follow-the-leader.tk, 1 +followboost.fr, 1 +follower98.ir, 1 +followlearning.com, 1 +followme.com, 1 +followmystaff.com, 1 +followthatpage.com, 1 +foluomeng.net, 1 +fomo.af, 1 +fomo.exposed, 1 +fomo.trading, 1 +fomopop.com, 1 +fonamperu.org.pe, 1 +fonbet-zerkalo.ru, 1 +fondation-machpal.org, 1 +fondationo2.ch, 1 +fondationwiggli.ch, 1 +fondy.ru, 1 +fondy.ua, 1 +foneapk.com, 1 +foneo.com, 1 +fonga.ch, 1 +fonline.tk, 1 +fono.jp, 0 +fonolo.com, 1 +fonseguin.ca, 1 +fontanaseiyo.jp, 1 +fontawesome.com, 1 +fonte-trading.com, 1 +fontein.de, 1 +fontela.es, 1 +fontnegar.ir, 1 +fonts2u.com, 1 +fonts4free.net, 1 +fonzone.it, 1 +foo, 1 +foo.fo, 1 +foo.hamburg, 1 +foochia.com, 1 +food4healthybones.com, 1 +foodattitude.ch, 0 +foodblogger.club, 1 +foodbody.ga, 1 +foodboy.com, 1 +foodbrowser.ga, 1 +foodbuddies.ga, 1 +foodcaster.ga, 1 +foodclient.ga, 1 +foodcollections.ga, 1 +foodcollector.ga, 1 +foodcowgirls.com, 1 +foodcraft.ae, 1 +fooddollar.ga, 1 +foodev.de, 1 +foodfirefriends.com, 1 +foodflower.ga, 1 +foodfriek.nl, 1 +foodieso.com, 1 +foodlast.ga, 1 +foodless.ga, 1 +foodlist.net, 1 +foodloader.net, 1 +foodlustkitchen.com, 1 +foodminer.ga, 1 +foodnachos.com, 1 +foodnight.ga, 1 +foodonbook.com, 1 +foodpart.ga, 1 +foodphotographyblog.com, 1 +foodplantengineering.com, 1 +foodprestige.ga, 1 +foodrates.ga, 1 +foodrex.ga, 1 +foodrips.com, 1 +foodsafety.gov, 1 +foodsafetyjobs.gov, 1 +foodsavers.gent, 1 +foodsaversgent.be, 1 +foodscovery.it, 1 +foodseurope.com, 1 +foodsoul.pro, 1 +foodsreborn.com, 1 +foodsunflower.ga, 1 +foodtable.at, 1 +foodtimeline.org, 1 +foodtrekker.tk, 1 +foodtummy.com, 1 +foodurban.ga, 1 +foodwidget.ga, 1 +foodwise.marketing, 1 +foodwish.ga, 1 +foodylab.it, 1 +foodyshoody.com, 1 +foodzpace.com, 1 +fooishbar.org, 0 +foolip.org, 1 +foolproofcomics.tk, 1 +foolwealth.com, 1 +foonly.fi, 1 +foorack.com, 1 +fooster.io, 1 +foot.fr, 1 +football-news.gq, 1 +football-world.tk, 1 +footballforum.de, 1 +footballrussia.cf, 1 +footballscores.ga, 1 +footballsrit.tk, 1 +footbolka.tk, 1 +footbolki.ml, 1 +footchronique.tk, 1 +footdoctorpodiatristnyc.com, 1 +footmercato.net, 1 +footwear-catalogue.tk, 1 +for-testing.tk, 1 +for.care, 1 +forabrokenrobot.tk, 1 +foray-jero.me, 1 +forbesmarshall.com, 1 +forbidden-mods.de, 1 +forbiddenhistory.info, 1 +forbusiness.ca, 1 +forcamp.ga, 1 +force-unleashed.com, 1 +force-unleashed.de, 1 +force4racing.co.uk, 1 +force4racing.com, 1 +forcebasements.com, 1 +forcelink.eu, 1 +forcelink.nl, 1 +forcelinkamerica.com, 1 +forcelinkamerica.nl, 1 +forcemasonry.net, 1 +forcemasonryinc.com, 1 +forcemat.fr, 1 +forces.army, 1 +forcewaterproofing.com, 1 +forcewave.com, 1 +forchildren.tk, 1 +ford-mustang.tk, 1 +ford-shop.by, 1 +fordeetv.com, 1 +fordlibrarymuseum.gov, 1 +fordshop.by, 0 +fordtrac.com.br, 1 +foreachcode.com, 1 +forecastapp.net, 1 +forecastcity.com, 1 +foreclosureattorneyhouston.com, 1 +forefrontcloud.com, 1 +foreign-language-colleges.com, 1 +foreignpharmacydirectory.com, 1 +foreignxchange.com.au, 1 +forellenpark.com, 1 +foremail.tk, 1 +forensic-system.com, 0 +forensicsciencecentral.tk, 1 +forensicsinfo.ga, 1 +forensicsoftware.biz, 1 +forensischepsychiatrie.tk, 1 +forento.be, 1 +forers.com, 1 +foresdon.jp, 1 +foresightbusinessservices.co.uk, 1 +forestcermegresik.com, 1 +forestparkga.gov, 1 +forestraven.net, 1 +forever.gq, 1 +foreverbreak.com, 1 +forevermuslim.in, 1 +foreverreem.com, 1 +foreverssl.com, 1 +foreversummertime.com, 1 +forevertoday.nl, 1 +foreverydream.com, 1 +forewordreviews.com, 1 +forex-arabia.tk, 1 +forex-giants.com, 1 +forex-opinie.pl, 1 +forex-site.com, 1 +forex-trading-tutorial.tk, 1 +forex-up.cf, 1 +forex.ee, 1 +forexarby.com, 1 +forexchef.de, 1 +forexcity.cf, 1 +forexclubteam.com, 1 +forexcomreview.co, 1 +forexee.com, 1 +forexinthai.com, 0 +forexmarketsm.tk, 1 +forexnew.org, 1 +forexox.com, 1 +forexpattern.tk, 1 +forexplay.com, 1 +forexsignals7.com, 1 +forextickler.com, 1 +forexwine.com, 1 +forexworld.cf, 1 +forfeit.ga, 1 +forfeiture.gov, 1 +forfortcollins.com, 1 +forfunssake.co.uk, 1 +forglemmigej.net, 1 +forgotten-legends.org, 1 +forgottenroles.com, 1 +forhers.com, 1 +forkfeeds.com, 1 +forklift.name.tr, 1 +forkurd.ml, 1 +formacionyestudios.com, 1 +formalgrammar.tk, 1 +formality.one, 1 +forman.store, 1 +formand.ru, 1 +formapi.io, 1 +formar-contract.it, 1 +format-paysage.ch, 0 +formation-assureur.com, 1 +formation-hauteur.com, 1 +formation-mac.ch, 0 +formationseeker.com, 1 +formbetter.com, 1 +formforger.com, 1 +formhub.ru, 1 +formi9.com, 1 +formini.dz, 1 +formio.nl, 1 +formommiesbymommy.com, 1 +forms.gov, 1 +formsbyair.com, 1 +formsmarts.com, 1 +formsmarts.net, 1 +formula-ot.ru, 1 +formula.cf, 1 +formulacionquimica.com, 1 +formulastudent.de, 1 +formulaveevictoria.com.au, 1 +formvibes.com, 1 +fornarisandres.com, 1 +fornwall.net, 0 +foro.io, 0 +foro.red, 1 +foroaranda.com, 1 +forobachiller.com, 1 +forodeespanol.com, 1 +forodieta.com, 0 +foroenguera.tk, 1 +forojovensanfernando.tk, 1 +forologikidilosi.com.gr, 1 +forosdelmisterio.tk, 1 +forowarhammer.tk, 1 +forpreneur.com, 0 +forrestheller.com, 1 +forrestwalkbarbershop.com.au, 1 +forro.berlin, 1 +forro.info, 1 +fors.me, 1 +forsaken.tk, 1 +forsakringsarkivet.se, 1 +forsaleacameras.tk, 1 +forsaleelectronics.tk, 1 +forsaleinedmonton.ca, 1 +forschbach-janssen.de, 1 +forself.me, 1 +forsi.xyz, 1 +forsigo.com, 1 +forskolin.gq, 1 +forstbetrieb-hennecke.de, 1 +forstprodukte.de, 1 +forsure.tk, 1 +forsyththeatre.com, 1 +fortawesome.org, 1 +fortbertholddiabetes.com, 1 +fortcommunity.com, 1 +fortdodgeradio.com, 1 +fortebet.rw, 1 +fortebet.ug, 1 +forteggz.nl, 1 +fortepiano.tk, 1 +fortesanshop.it, 1 +forthenrycustomknives.com, 1 +forthetoys.com, 1 +forthewin.rocks, 1 +forthvalleykeswick.co.uk, 1 +fortifydiy.com, 1 +fortipartner.co.uk, 1 +fortipartner.com, 1 +fortipartner.dk, 1 +fortipartner.net, 1 +fortipartner.nl, 1 +fortipartner.pl, 1 +fortipartner.se, 1 +fortipartner.uk, 1 +fortisadhesives.com.au, 1 +fortmatic.com, 1 +fortnite.ca, 1 +fortoglethorpega.gov, 1 +fortress.no, 1 +fortress.sk, 1 +fortresslinux.com, 1 +fortresslinux.nl, 1 +fortricks.in, 1 +fortsecure.com.br, 1 +fortuna-apotheke-lahnstein.de, 1 +fortuna-loessnitz.de, 1 +fortuna-s.com, 1 +fortuna.co.ua, 1 +fortunabuilders.tk, 1 +fortunacigarettes.tk, 1 +fortunahamburg.tk, 1 +fortuneinvestments.ga, 1 +forty-two.ml, 1 +forty-two.nl, 1 +forty.sh, 1 +forty8creates.com, 1 +fortygordy.com, 1 +fortytwo.cloud, 1 +fortytwo.tk, 1 +forum-4.com, 1 +forum-batteries.com, 1 +forum-egypte.tk, 1 +forum-expert.tk, 1 +forum-gilee.cf, 1 +forum-kinozal-tv.appspot.com, 1 +forum-noginska.tk, 1 +forum-reklamowe.cf, 1 +forum-tutorapide.ml, 1 +forum-tw.tk, 1 +forum-washington.tk, 1 +forum24.ml, 1 +forumcarriocity.tk, 1 +forumdimo.fr, 1 +forumirc.net, 1 +forumistudentore.tk, 1 +forumoff.com, 1 +forumotion.cf, 1 +forumotomobil.com, 1 +forumpakistan.tk, 1 +forumpenaguru.com, 1 +forumrussia.tk, 1 +forums4everyone.tk, 1 +forumsampdoria.tk, 1 +forumsrussia.ga, 1 +forumstandaardisatie.nl, 1 +forumu.net, 1 +forumvardbyggnad.se, 1 +forvisualdesign.com, 0 +forward-fly-fishing.ch, 0 +forward.com, 1 +forwardemail.net, 1 +forwardfever.tk, 1 +forwardtogether.org, 1 +foryourhealthybody.com, 1 +forzamotorsport.net, 1 +fos-apps.org, 1 +fos-games.org, 1 +fosaudit.com, 1 +foscamcanada.com, 1 +fosdem.org, 1 +foselectro.ru, 1 +fosgreece.com, 1 +foshanshequ.com, 0 +fossboxen.com, 1 +fossboxen.net, 1 +fossboxen.org, 1 +fossbytes.com, 1 +fossewayflowers.co.uk, 1 +fossewayflowers.com, 1 +fossildlp.com, 1 +fossilfreeyale.org, 1 +fosterpark.ca, 1 +fotbal-dubina.tk, 1 +fotbalclubcaracal.tk, 1 +fotella.com, 1 +fotikpro.ru, 1 +fotklinikenvarnamo.se, 1 +foto-forum.tk, 1 +foto-gallery.tk, 1 +foto-janvanaefst.nl, 1 +foto-leitner.com, 1 +foto-leitner.de, 1 +foto-robitsch.at, 1 +foto-roma.ru, 1 +foto-znakomstva.ml, 1 +foto.by, 1 +fotoallerlei.com, 1 +fotoars.pl, 1 +fotoblog.nrw, 1 +fotobodyart.nl, 1 +fotoboxvysocina.cz, 1 +fotocopiatrici.roma.it, 1 +fotofaerie.net, 1 +fotoflits.net, 1 +fotofon.tk, 1 +fotograf-mario.de, 1 +fotografechristha.nl, 1 +fotografiadellalucerossa.com, 1 +fotografiamakro.pl, 1 +fotografies.tk, 1 +fotografija.tk, 1 +fotografontes.com.br, 1 +fotohiking.com, 1 +fotohome.dk, 1 +fotohunter.ru, 1 +fotojenico.com, 1 +fotokomorkomania.pl, 1 +fotolectura.tk, 1 +fotoleitner.com, 1 +fotoleitner.de, 1 +fotomodel.cf, 1 +fotomodels.tk, 1 +fotonjan.com, 1 +fotontechnik.pl, 1 +fotonza.ru, 1 +fotopalacedigitalstudio.tk, 1 +fotopremium.cz, 1 +fotorecull.tk, 1 +fotostravestisbr.com, 1 +fotostudio-leitner.com, 1 +fotostudio-leitner.de, 1 +fotostudio-schweiz.ch, 1 +fotostudiobasic.tk, 1 +fotovsibiri.ml, 1 +fotowettbewerb.co, 1 +fotowolfy.com, 1 +fotozakazka.cz, 1 +fotrino.com, 1 +foudufafa.de, 0 +fougner.co, 1 +found.website, 1 +foundationassure.com, 1 +foundationmaintenance.com, 1 +foundationrepairannarbor.com, 1 +foundationrepairasheville.com, 1 +foundationrepairbasementwaterproofingtn.com, 1 +foundationrepairchicagoil.com, 1 +foundationrepairknoxvilletn.com, 1 +foundationrepairnebraska.com, 1 +foundationrepairpro.com, 1 +foundationspecialisteast.com, 1 +foundationspecialistmi.com, 1 +foundchurch.co.uk, 1 +founded.ml, 1 +founderio.net, 1 +foundrehotels.com, 1 +foundsounds.me, 1 +fourashesgolfcentre.co.uk, 1 +fourashesgolfcentre.uk, 1 +fourcask.com, 1 +fourchetteverte.ch, 1 +fourcornerscb.com, 1 +fourdesignstudio.com, 1 +fourfivecbd.co.za, 1 +fourfourcrew.com, 1 +fourfri.es, 1 +fouriemc.com, 1 +fourmaq.com, 1 +fourmies.fr, 1 +fournarisopenday.com, 1 +fournisseur-des-collectivites.com, 1 +fourscore.ga, 1 +fourseasonsgrower.com, 1 +foursight.io, 0 +fourstrategy.de, 1 +fourwaysplumber24-7.co.za, 1 +fousetmoney.tk, 1 +foutrelis.com, 1 +fowlmanor.tk, 1 +fowlsmurf.net, 1 +fowos.de, 1 +fox-zulu.de, 1 +fox.my, 0 +foxbenjaminfox.com, 1 +foxbnc.co.uk, 1 +foxbnc.uk, 1 +foxcloud.tk, 1 +foxcon.tk, 1 +foxdemos.ml, 1 +foxdev.co, 1 +foxdirectory.tk, 1 +foxes.no, 1 +foxesare.sexy, 1 +foxesofleicester.com, 1 +foxghoul.com, 1 +foxing.club, 1 +foxmailer.ml, 1 +foxmay.co.uk, 1 +foxmetrix.com, 1 +foxo.blue, 1 +foxontheinter.net, 1 +foxquill.com, 0 +foxroy.com, 1 +foxscribbler.com, 1 +foxstreetcomms.co.za, 0 +foxstyle.gq, 1 +foxterrier.com.br, 1 +foxtransportables.com.au, 1 +foxtrotfm.tk, 1 +foxycredit.com, 1 +foxyslut.com, 1 +foyale.io, 1 +fozzie.co.uk, 1 +fozzie.space, 1 +fp.systems, 1 +fpaci.org, 1 +fpasca.com, 1 +fpc.gov, 1 +fpersona.com, 1 +fpgamania.com, 1 +fpki.sh, 1 +fpnet.tk, 1 +fppp.fr, 1 +fprinnovaciones.es, 1 +fps73.ru, 1 +fpsclasico.de, 1 +fpsclasico.eu, 1 +fpsv.de, 1 +fpu.sk, 1 +fpy.cz, 1 +fq.mk, 0 +fqxp.de, 1 +fr.search.yahoo.com, 0 +fr33tux.org, 1 +frack.nl, 0 +fracreazioni.it, 1 +fractieplanner.nl, 1 +fractionalciso.com, 1 +fractionclub.com, 1 +fracturedperspective.com, 1 +fragdenstaat.de, 1 +frageboegen-martini-klinik.de, 1 +fragilesolar.cf, 1 +fragmentation.ml, 1 +fragments.ga, 1 +fragmentspuren.de, 1 +fragmentus.tk, 1 +fragstore.net, 1 +fraho.eu, 1 +frahub.com, 1 +frail.gq, 1 +fralippolippi.tk, 1 +frama.link, 1 +frama.site, 1 +frama.wiki, 1 +framabag.org, 1 +framabee.org, 1 +framabin.org, 1 +framablog.org, 1 +framaboard.org, 1 +framabook.org, 1 +framabookin.org, 1 +framacalc.org, 1 +framacarte.org, 1 +framaclic.org, 1 +framacolibri.org, 1 +framadate.org, 1 +framadrive.org, 1 +framadrop.org, 1 +framadvd.org, 1 +framaestro.org, 1 +framaform.org, 1 +framaforms.org, 1 +framagames.org, 1 +framagenda.org, 1 +framagit.org, 1 +framakey.org, 1 +framalab.org, 1 +framalang.org, 1 +framalibre.org, 1 +framalistes.org, 1 +framandroid.org, 1 +framanews.org, 1 +framanotes.org, 1 +framapack.org, 1 +framapad.org, 1 +framapiaf.org, 1 +framapic.org, 1 +framasite.org, 1 +framasites.org, 1 +framaslides.org, 1 +framasoft.org, 1 +framasphere.org, 1 +framastart.org, 1 +framastats.org, 1 +framastory.org, 1 +framatalk.org, 1 +framateam.org, 1 +framavectoriel.org, 1 +framavox.org, 1 +framawiki.org, 1 +framazic.org, 1 +framboise314.fr, 1 +framedpaws.com, 1 +framemo.org, 1 +framer.com, 1 +frames-eyelash.com, 1 +frames-hair-design.com, 1 +framindmap.org, 1 +framinetest.org, 1 +fran.cr, 1 +france-hotellerie-restauration.com, 1 +france-israel-fellows.org, 1 +france-news.cf, 1 +franceactivetravel.cf, 1 +francebattery.com, 1 +francepandi.fr, 0 +francesca-and-lucas.com, 1 +francescopalazzo.com, 1 +francescopandolfibalbi.it, 1 +francescosiciliano.tk, 1 +francescoyatesfansite.com, 1 +francesfluente.cf, 1 +francetraceur.fr, 1 +franchini.email, 1 +franchini.engineer, 1 +franchiseguide.ga, 1 +franchisehive.com, 1 +francinebelanger.network, 1 +francis.ph, 1 +francisbaconnet.com, 1 +franciscadelasllagasvirtual.com, 1 +franciscoalpendre.com.br, 1 +francisli.net, 1 +francisplaza.com, 1 +franckgirard.net, 1 +francocasimirri.tk, 1 +francoexpeditionperu.com, 1 +francois-occasions.be, 0 +francoisbelangerboisclair.com, 1 +francoise-paviot.com, 1 +francoisharvey.ca, 1 +francoislaude.fr, 1 +francoislepage.com, 0 +francoz.me, 1 +frandor.co.uk, 1 +franfoto.com, 1 +franggroup.com, 1 +frank.fyi, 1 +frankbellamy.co.uk, 1 +frankdisplaycabinets.co.uk, 1 +franke-chemie.de, 1 +frankellawfirm.com, 1 +franken-lehrmittel.de, 1 +frankenhost.de, 1 +frankenlehrmittel.de, 1 +frankeurope.com, 1 +frankhaala.com, 1 +frankhaarlem.tk, 1 +frankieburkeactor.tk, 1 +frankierfachmann.de, 1 +frankierprofi.de, 1 +frankierstar.de, 1 +frankieruiz.tk, 1 +frankieylosmatadores.tk, 1 +frankland.tk, 1 +franklincountyflorida.gov, 1 +franklincountyny.gov, 1 +franklinhua.com, 1 +frankopol-sklep.pl, 1 +frankslaughterinsurance.com, 1 +frankthetank.biz, 1 +frankyan.com, 1 +frankydo.com, 1 +franqois.id, 1 +fransallen.com, 1 +franta.biz, 1 +franta.email, 1 +frantic1048.com, 1 +frantorregrosa.me, 1 +franz-vatter.de, 1 +franz.beer, 1 +franzen.tk, 1 +franziska-pascal.de, 1 +franziska-schreck.de, 1 +franziskaherbert.de, 1 +franzknoll.de, 1 +franzt.ovh, 1 +franzters.tk, 1 +fraplaster.com, 1 +frappant.cc, 1 +frappant.net, 1 +fraselab.ru, 1 +fraser-hann.co.uk, 1 +frasermurray.scot, 1 +fraservalleyhotdog.com, 1 +frasesconemocion.com, 1 +frasesdodia.com, 1 +frasesparaface.com.br, 1 +frasestop.com.br, 1 +frasesytarjetas.com, 1 +fratelliscarrone.com, 1 +fraterbolivia.tk, 1 +fratiicazanoi.ro, 1 +frattaroli.org, 1 +frau-pusteblu.me, 1 +frau-sucht-bauer.de, 1 +frau.gq, 1 +fraudmarc.com, 1 +fraudswatch.tk, 1 +frauen-etappenrennen.de, 1 +frauenarzt-niendorf.de, 0 +frauenarzt-zinke.de, 1 +frauenlob.rocks, 1 +fraufries.de, 1 +fraurichter.net, 1 +fravegacatalogo.com, 1 +fraye.net, 1 +frazell.net, 1 +frbg.me, 1 +frbracch.it, 1 +frc.gov, 1 +frccsgo.tk, 1 +frdl.ch, 1 +freak-show.tk, 1 +freakinstream.com, 1 +freaksites.dk, 1 +freaksports.com.au, 1 +freakyawesome.agency, 1 +freakyawesome.art, 1 +freakyawesome.band, 1 +freakyawesome.business, 1 +freakyawesome.ca, 1 +freakyawesome.co, 1 +freakyawesome.co.uk, 1 +freakyawesome.design, 1 +freakyawesome.fm, 1 +freakyawesome.in, 1 +freakyawesome.lgbt, 1 +freakyawesome.net, 1 +freakyawesome.org, 1 +freakyawesome.solutions, 1 +freakyawesome.world, 1 +freakyawesome.yoga, 1 +freakyhappenings.tk, 1 +frebi.org, 1 +frebib.co.uk, 1 +frebib.com, 1 +frebib.me, 1 +frebib.net, 1 +fredbarboo.cf, 1 +freddieleeman.nl, 1 +freddieonfire.tk, 0 +freddo.tk, 1 +freddyhasderyk.tk, 1 +freddythechick.net, 1 +freddyvasquez.com, 1 +fredericcote.com, 1 +frederickearlstein.com, 1 +frederickmd.gov, 1 +frederikshavn.net, 1 +frederikugarte.tk, 1 +fredhook.tk, 1 +fredjanssen.tk, 1 +fredliang.cn, 0 +frednet.tk, 1 +fredriksslaktforskning.se, 1 +fredriksslekt.se, 1 +freds4buildings.com, 1 +fredsmith.net, 1 +fredsmith.org, 1 +fredsmith.us, 1 +fredvoyage.fr, 1 +free-barcode-generator.net, 1 +free-bitco.ml, 1 +free-cms.tk, 1 +free-generate.tk, 1 +free-lancer.ml, 1 +free-obmen.ml, 1 +free-ppp.jp, 1 +free-sex-sites.com, 1 +free-sql-query-tool.com, 1 +free-ss.site, 1 +free-traff.cf, 1 +free-watching.ga, 1 +free-webtv.tk, 1 +free.ac.cn, 1 +free.com.tw, 1 +free6to12yo.gq, 1 +free8.cloud, 1 +free8.xyz, 1 +freeaf.gq, 1 +freeagent.tk, 1 +freeartico.ga, 1 +freeassange.net, 1 +freeauroraoperations.tk, 1 +freebacklinksforyoudirectory.tk, 1 +freebarrettbrown.org, 1 +freebasics.com, 1 +freebcard.com, 1 +freebegames.tk, 1 +freeben666.fr, 1 +freebetoffers.co.uk, 1 +freebitcoinfaucet.org, 1 +freebookdomain.tk, 1 +freebookmakersbetsandbonuses.com.au, 1 +freebookslibrary.gq, 1 +freebornfinancial.ca, 1 +freeboson.org, 1 +freebsdbrasil.com.br, 1 +freebus.org, 1 +freecam-sex.com, 1 +freecam2cam.site, 1 +freecloud.at, 1 +freecn.xyz, 1 +freecookies.nl, 1 +freecoursehunt.in, 1 +freecrypt.ga, 1 +freedatingonline.ml, 1 +freedeals4u.ga, 1 +freedev.cz, 1 +freedgb.com, 1 +freedom-substitute.fr, 1 +freedom.nl, 1 +freedom.press, 1 +freedom35.org, 0 +freedomdujour.com, 1 +freedomfinance.se, 1 +freedomflotilla.org, 1 +freedomfrontier.tk, 1 +freedomhk.info, 1 +freedomhkg.info, 1 +freedomisslavery.tk, 1 +freedomkiaparts.com, 1 +freedomonline.bg, 1 +freedomrahoitus.fi, 1 +freedomtoolkit.com, 1 +freedomtwp-pc.org, 1 +freedomvote.nl, 1 +freedomwill.tk, 1 +freeebooksblog.com, 1 +freeenglishhelp.com, 1 +freeexampapers.com, 1 +freefallproductions.tk, 1 +freefilesync.org, 1 +freefinancialhelp.net, 1 +freefincal.com, 1 +freeflarum.com, 1 +freefonts.ga, 1 +freeform4u.de, 1 +freegame-mugen.jp, 1 +freegamesmac.com, 1 +freegaypornhd.online, 1 +freegovernmentcellphoneguide.com, 1 +freegutters.com, 1 +freehdporn.tv, 1 +freehotline.ru, 1 +freehqporno.com, 1 +freeiconspng.com, 1 +freeinfos.fr, 1 +freeinoutboard.com, 1 +freejeremy.net, 1 +freejidi.com, 1 +freekdevries.nl, 1 +freeks.com.br, 1 +freela.ch, 0 +freelance-webdesign.co.uk, 1 +freelance.boutique, 1 +freelance.guide, 1 +freelance.nl, 1 +freelancecollab.com, 1 +freelanceessaywriters.com, 1 +freelancehunt.com, 1 +freelancejobs.org.uk, 1 +freelancerim.ml, 1 +freelanceunited.co.uk, 1 +freelanceunleashed.com, 0 +freelansir.com, 1 +freelauri.com, 1 +freelifer.jp, 1 +freelyplaygames.com, 1 +freemagi.ga, 1 +freeman-online.tk, 1 +freemania.nl, 1 +freemanlogistics.com, 1 +freemans.com, 1 +freemattandgrace.com, 1 +freeminecraftmaps.tk, 1 +freeministryresources.org, 1 +freemomhugs.org, 1 +freemotion.tk, 1 +freemovieonline.ga, 1 +freemyipod.org, 1 +freend.me, 0 +freenetflow.com, 1 +freenetproject.org, 1 +freenome.net, 1 +freeonlinearticles.tk, 1 +freeonplate.com, 1 +freepastlife.com, 1 +freepatternsarea.com, 1 +freepedia.cf, 1 +freepik.com, 1 +freepnglogos.com, 1 +freepoints.us, 1 +freepornhunt.com, 1 +freepornomovies.info, 1 +freepornovideos.me, 1 +freepornvideos.life, 1 +freepornxxxvids.com, 1 +freepron.xyz, 1 +freepublicprofile.com, 1 +freeradical.zone, 1 +freereal.ml, 1 +freerealincest.com, 1 +freergform.org, 1 +freertomorrow.com, 1 +freerun.cn, 0 +freeschool.cf, 1 +freesexvideo.pro, 1 +freesexvidz.com, 1 +freeshell.de, 1 +freeskateparks.com, 1 +freeslots.guru, 1 +freesmile.tk, 1 +freesms-online.de, 1 +freesnowden.is, 1 +freesoft-board.to, 1 +freesoftlab.com, 1 +freesolitaire.win, 1 +freesoul-deactivate-plugins.com, 1 +freesourcestl.org, 1 +freespace.info, 1 +freespanlift.com, 1 +freesports.ml, 1 +freespot.mobi, 1 +freesquare.net, 1 +freessl.tech, 1 +freestylemartialarts.tk, 1 +freestylesolutions.com, 1 +freetagboards.tk, 1 +freetaxusa.com, 1 +freetelegraph.ga, 1 +freetext.org, 1 +freethehustle.com, 0 +freethetv.ie, 1 +freethinking.co.za, 1 +freeths.co.uk, 1 +freetimefun.tk, 1 +freetrial.tech, 1 +freetrung.tk, 1 +freetsa.org, 1 +freeuseporn.org, 1 +freevisits.tk, 1 +freewarez.org, 1 +freewaypropane.com, 1 +freeweibo.com, 1 +freewerkt.nl, 1 +freewoman.club, 1 +freewoodfactory.com, 1 +freexmovie.com, 1 +freexxxmovies.biz, 1 +freeyourmusic.com, 1 +freezemea.com, 1 +freezerrepairaustin.com, 1 +freezvon.com, 1 +fregona.online, 1 +frei.social, 1 +freibesetzt.tk, 1 +freiboth.ddns.net, 1 +freie-software.net, 1 +freifahrt.de, 1 +freifall.tk, 1 +freifunk-burgaltendorf.de, 1 +freifunk-essen.de, 1 +freifunk-in-solingen.de, 1 +freifunk-lindlar.net, 1 +freifunk-remscheid.de, 1 +freimeldungen.de, 1 +freitasul.com.br, 1 +freitasul.io, 1 +freiwurst.net, 1 +freizeitbad-riff.de, 1 +freizeitpark.tk, 1 +freizeitplaza.de, 1 +frejasdal.dk, 1 +frekat.tk, 1 +fremontcountyia.gov, 1 +frenchbluecottage.com, 1 +frenchcreekcog.org, 1 +frenchmac.com, 1 +frenchmusic.fr, 1 +frenchvandal.com, 0 +frendamos-roleplay.ml, 1 +frenetic.lv, 1 +frente-popular.tk, 1 +frenzel.dk, 1 +frequencebanane.ch, 0 +frequentflyerapp.com, 1 +frequentlyaskedquestions.cf, 1 +fresadora.online, 1 +frescobol.tk, 1 +fresh-hotel.org, 1 +fresh-info.cf, 1 +fresh-info.gq, 1 +fresh-info.tk, 1 +fresh-networks.net, 1 +fresh.co.il, 1 +fresh4.co.uk, 1 +freshbean.club, 1 +freshbooks.com, 0 +freshcode.nl, 1 +freshdesignweb.com, 1 +freshdesk-apps-by-invantive.com, 1 +freshdns.nl, 1 +freshempire.gov, 1 +freshersworld.ml, 1 +fresherwalkins.tk, 1 +freshfishdelivery.com, 1 +freshhosting.tk, 1 +freshinsport.fr, 1 +freshmail.com, 1 +freshman.com.tw, 1 +freshmans-pizza.de, 1 +freshplus62.com, 1 +freshpounds.com, 1 +freshstep.com, 1 +freshtest.tk, 1 +freston.eu, 1 +fretscha.com, 1 +frettboard.com, 1 +frettennet.tk, 1 +frettirnar.is, 1 +fretworksec.com, 1 +freudedurchmachen.de, 1 +freundinnen-ausflug.de, 1 +freundinnen-kurzurlaub.de, 1 +freundinnen-urlaub.de, 1 +freundinnenausflug.de, 1 +frforms.com, 1 +friarsonbase.com, 1 +fribourgviking.net, 1 +fricassea.com, 1 +frickelboxx.de, 1 +frickelmeister.de, 1 +frickenate.com, 1 +frickybeats.com, 1 +fridarestaurantemexicano.com, 1 +fridaybridge.tk, 1 +fridayfoucoud.ma, 1 +fridaypulse.com, 1 +fridaysforfuture-bremen.de, 1 +fridolinka.cz, 1 +fried.tk, 1 +friedberg2020.de, 1 +friedcoffee.com, 1 +friederes.lu, 1 +friederloch.de, 1 +friedhelm-wolf.de, 1 +friedli.info, 1 +friedrich-foto-art.de, 1 +friedsamphotography.com, 1 +friedstechnology.com, 1 +friedstechnology.nl, 1 +friedstechnology.online, 1 +friedzombie.com, 1 +friedzombie.nl, 1 +friedzombie.online, 1 +friendbot.ml, 1 +friendly.pe, 1 +friendlydabs.com, 1 +friendlysiberia.com, 1 +friendofthehoneybee.co.uk, 1 +friendofthehoneybee.org, 1 +friendofthehoneybee.org.uk, 1 +friendowment.us, 1 +friends-online.tk, 1 +friendsforeverrecords.tk, 1 +friendshipismagicsquad.com, 1 +friendsinfilm.com, 0 +friendsnew.com, 1 +friendsofgfwpc.org, 1 +friendsofmagnacarta.tk, 1 +friendsofoldstthomas.org, 1 +friendsofthehoneybee.co.uk, 1 +friendsofthehoneybee.com, 1 +friendsofthehoneybee.org, 1 +friendsofthehoneybee.org.uk, 1 +friendsofthehoneybee.uk, 1 +friendsonline.tk, 1 +friet.org, 1 +frietbesteld.nl, 1 +frietzombie.nl, 1 +friezy.ru, 1 +frightmare.tk, 1 +frigi.ch, 0 +frign.de, 1 +frigochaco.com.py, 1 +frigolit.net, 1 +friherrsindemarit.fi, 1 +frikandellenmoord.nl, 1 +frikandelmoord.nl, 1 +frikipedia.tk, 1 +frikotv.tk, 1 +frilima.com.br, 1 +friller.com.au, 1 +frillip.com, 1 +fringeintravel.com, 1 +frinkiac.com, 1 +frino.de, 1 +friplay.host, 1 +fripper.tk, 1 +frisaga.com, 1 +frisaga.me, 1 +frisaga.net, 1 +frisaga.org, 1 +frisaga.travel, 1 +friseur-foerder.de, 1 +friss.com, 1 +frisuren.tk, 1 +fritteli.ch, 1 +fritz-koehne-schule.de, 1 +fritzbox-forum.tk, 1 +fritzrepair.com, 1 +friv-2018.ga, 1 +frizo.com, 1 +fro.ge, 1 +fro.se, 1 +frob.nl, 1 +frode.win, 1 +frodriguez.xyz, 1 +froehliche-hessen.de, 1 +frog.industries, 1 +frogatto.com, 1 +frogeye.fr, 1 +froggitt.com, 1 +frogsonamission.de, 1 +froh.co.jp, 1 +frokenblomma.se, 1 +frolova.org, 1 +from-the-net.com, 1 +from.ga, 1 +from.network, 1 +fromager.net, 1 +fromages-freres-marchand.fr, 1 +fromix.de, 1 +fromlemaytoz.com, 1 +fromm-projects.de, 1 +fromoldbooks.org, 1 +fromrestaurants.tk, 1 +fromsalttopepper.com, 1 +fromscratch.rocks, 1 +fromtheboxoffice.com, 1 +fromthecountsplace.tk, 1 +fromthemonks.com, 1 +fromthesoutherncross.com, 1 +fromtinythings.com, 0 +frontbaydevices.tk, 1 +fronteers.nl, 0 +fronteimoveis.com.br, 1 +fronterasblog.tk, 1 +frontier-ad.co.jp, 1 +frontier.bet, 1 +frontierbrasil.tk, 1 +frontierdiscount.com, 1 +frontiers.nl, 1 +frontigate.com, 1 +frontline.cloud, 1 +frontlinemessenger.com, 1 +frontrowshoppe.com, 0 +froogo.co.uk, 1 +fropky.com, 1 +frosoku.com, 1 +frostprotection.co.uk, 1 +frostwarning.com, 1 +frosty-gaming.xyz, 1 +frosty.sk, 1 +frosty.style, 1 +frostysummers.com, 1 +frothy.coffee, 0 +frothy285.com, 1 +frowin-stemmer.de, 0 +frown.town, 1 +frownonline.co.uk, 1 +frozen-geek.net, 1 +frozen-solid.net, 1 +frozencuisine.ga, 1 +frozendurian.club, 1 +frozenfutures.com, 1 +frozenjam.com, 1 +frozenpennies.com, 1 +frozentee.com, 1 +frp-roleplay.de, 1 +frpg.gov, 1 +frprn.com, 1 +frprn.es, 1 +frprn.xxx, 1 +frsnpwr.net, 1 +frsra.ml, 1 +frtib.gov, 1 +frtn.com, 1 +frtrains.com, 0 +fruchtikus.net, 1 +fruend-hausgeraeteshop.de, 1 +frugalfamilyhome.com, 1 +frugalmechanic.com, 1 +frugro.be, 1 +fruit-farm.tk, 1 +fruit.ga, 1 +fruit.ml, 1 +fruition.co.jp, 1 +fruitscale.com, 1 +fruityloop.tk, 1 +fruityten.co.uk, 1 +frusky.de, 1 +frutasyvejetales.com, 1 +frutidump.tk, 1 +fruxnux.net, 1 +fruxprivatebank.net, 1 +frydrychit.cz, 1 +fryergroup.com, 1 +fs-fitness.eu, 1 +fs-g.org, 1 +fs-maistadt.de, 1 +fs-rozmarija.tk, 1 +fs-w.org, 1 +fs-world.org, 1 +fs2021asm.com, 1 +fs257.com, 1 +fsalmeron.tk, 1 +fsapubs.gov, 0 +fsavc.org.uk, 1 +fsbn.eu, 1 +fsbnh.bank, 1 +fsbpaintrock.com, 1 +fsbturton.com, 1 +fsch2009.com, 1 +fsck.cz, 1 +fsck.jp, 0 +fscott.de, 1 +fsd.gov, 0 +fsdress.com, 1 +fsfi.is, 1 +fsg.one, 1 +fsgeek.ca, 1 +fsinf.at, 1 +fsinsight.com, 1 +fsk.fo, 1 +fskounoike.com, 1 +fsky.info, 1 +fsm2016.org, 1 +fsps.ch, 1 +fsrs.gov, 1 +fsstyle.com, 1 +fstatic.io, 1 +fsty.uk, 1 +fsub.de, 1 +fsvoboda.cz, 1 +fsvt.ch, 0 +ft.com, 0 +ftang.de, 1 +ftc.gov, 0 +ftcefile.gov, 1 +ftexchange.com, 1 +ftgeufyihreufheriofeuozirgrgd.tk, 1 +ftgho.com, 1 +fthat.link, 1 +ftl-gaming.tk, 1 +ftl13.com, 1 +ftmc.tk, 1 +ftng.se, 1 +ftpmovement.tk, 1 +ftptest.net, 1 +ftrac.com.br, 1 +ftrucks.com.au, 0 +ftv.re, 1 +ftworthhousekeeper.com, 1 +ftx.com, 1 +ftx.digital, 1 +ftx.io, 1 +ftx.tech, 1 +ftx.us, 1 +fu898.top, 1 +fuantaishenhaimuli.net, 1 +fucajz.cz, 1 +fuchsy.com, 1 +fuciam.com.co, 1 +fuck-your-false-positive.de, 1 +fuckar.ch, 1 +fuckav.ru, 1 +fuckcf.cf, 1 +fucknazis.cf, 1 +fucknazis.tk, 1 +fuckobr.com, 1 +fuckobr.net, 1 +fuckobr.org, 1 +fuckobr.su, 1 +fuckssl.com, 1 +fuckup.dk, 1 +fuckwhatyouthink.tk, 1 +fuckxichina.com, 1 +fuckyoupaypal.me, 1 +fuckz.net, 1 +fuddittu.tk, 1 +fudie.net, 1 +fudubank.vn, 1 +fuechschen.org, 1 +fuego.tech, 1 +fuegosalsapower.tk, 1 +fuelfirebrand.com, 1 +fuelingyourdreams.com, 0 +fuembellida.tk, 1 +fuenferrada.tk, 1 +fuentesdeleon.tk, 1 +fuer-gerechte-steuern.at, 1 +fuerzaazul.tk, 1 +fugioninc.com, 0 +fugle.de, 1 +fuglede.dk, 1 +fuite.ch, 0 +fuitedeau.ch, 0 +fuites.ch, 0 +fuiveningent.be, 1 +fujianshipbuilding.com, 1 +fujieb.com, 1 +fujijin.co.jp, 1 +fujikochan.tk, 1 +fujiwarashinzo.com, 1 +fujiyakimono.com, 1 +fukakukeiba.com, 1 +fukase-seed.com, 1 +fukikaeru.com, 1 +fukn.jp, 1 +fukt.ca, 1 +fuku-fashion.nl, 1 +fukuiedu.com, 1 +fukuko.biz, 1 +fukuko.xyz, 1 +fukushima-fun.com, 1 +fukushimacoffee.com, 1 +fulfilmentcrowd.com, 1 +fulgenzis.com, 1 +fulige.top, 0 +fuliwang.info, 1 +fuliwang.us, 1 +full-race.com, 1 +full-stack.ninja, 1 +fullalt.com, 1 +fullautomotivo.com.br, 1 +fullaw.in, 1 +fullbundle.com, 1 +fullcirclestudio.nl, 1 +fullerlife.org.uk, 1 +fullfilez.com, 1 +fullhost.com, 1 +fullhub.ru, 1 +fullmetalconsulting.tk, 1 +fullmoondesignhouse.tk, 1 +fullsize.ml, 1 +fullspace.com.br, 1 +fullstack.love, 1 +fulltextarchive.com, 1 +fulltxt.ml, 1 +fullworks.net.br, 1 +fully-hair.tk, 1 +fumblers.ca, 1 +fumerolles.ch, 0 +fumilink.com, 1 +fumo.reisen, 1 +fun-bounce.co.uk, 1 +fun-club-35.com, 1 +fun-fan.biz, 1 +fun-life.com.tw, 1 +fun-tasia.co.uk, 1 +fun4ubouncycastles.co.uk, 1 +fun888city.com, 1 +fun888city.net, 1 +fun88city.com, 1 +fun9.cc, 1 +fun99.cc, 1 +funadvisor.ca, 1 +funadvisorfrance.com, 1 +funandbounce.com, 1 +funatic.nl, 1 +funatic.tk, 1 +funboat.tk, 1 +funbuynet.com.br, 1 +funcabinrentals.com, 1 +funchal.ga, 1 +functional.cc, 1 +functions-online.com, 1 +fundacioneduser.com, 1 +fundacionfade.org, 1 +fundacionfranciscofiasco.org, 1 +fundacjamatkiewy.pl, 1 +fundaekhaya.co.za, 1 +fundayltd.com, 1 +fundays.nl, 1 +fundchan.com, 1 +fundeego.com, 0 +fundevogel.de, 1 +fundkyapp.com, 1 +fundmyfuture.info, 1 +fundmylegalclaim.co.uk, 1 +fundort.ch, 1 +fundpress.org, 0 +funds.ddns.net, 1 +funeks.com, 1 +funeraire-365.com, 1 +funeral-365.com, 1 +funeral-doom.tk, 1 +funerare-cazacu.com, 1 +funerare24.ro, 1 +funfactorleeds.co.uk, 1 +funfacts.cz, 1 +funfun.com.br, 1 +funfunmstdn.tokyo, 1 +fungalforager.com, 1 +fungame.eu, 1 +fungomoscow.cf, 1 +funhotdate.com, 1 +funhouse-inflatables.co.uk, 1 +funhunt.es, 1 +funideas.org, 1 +funidelia-tr.com, 1 +funidelia.at, 1 +funidelia.be, 1 +funidelia.bg, 1 +funidelia.ca, 1 +funidelia.ch, 1 +funidelia.cl, 1 +funidelia.co, 1 +funidelia.co.il, 1 +funidelia.co.nz, 1 +funidelia.co.uk, 1 +funidelia.com, 1 +funidelia.com.ar, 1 +funidelia.com.au, 1 +funidelia.com.br, 1 +funidelia.com.ua, 1 +funidelia.cz, 1 +funidelia.de, 1 +funidelia.dk, 1 +funidelia.ee, 1 +funidelia.es, 1 +funidelia.fi, 1 +funidelia.fr, 1 +funidelia.gr, 1 +funidelia.hk, 1 +funidelia.hr, 1 +funidelia.hu, 1 +funidelia.id, 1 +funidelia.ie, 1 +funidelia.in, 1 +funidelia.is, 1 +funidelia.it, 1 +funidelia.kr, 1 +funidelia.lt, 1 +funidelia.lu, 1 +funidelia.lv, 1 +funidelia.mx, 1 +funidelia.my, 1 +funidelia.nl, 1 +funidelia.no, 1 +funidelia.ph, 1 +funidelia.pt, 1 +funidelia.ro, 1 +funidelia.rs, 1 +funidelia.ru, 1 +funidelia.se, 1 +funidelia.sg, 1 +funidelia.si, 1 +funidelia.sk, 1 +funinfo.tk, 1 +funkazoid-radio.com, 1 +funken-networks.de, 1 +funkfernbedienung-industrie.de, 1 +funkner.ru, 1 +funknotaus.de, 1 +funkogames.com, 1 +funksteckdosen24.de, 0 +funkstyles.tk, 1 +funktdesign.dk, 1 +funktdesign.eu, 1 +funktionel.co, 1 +funktionevents.co.uk, 1 +funkydealz.no, 1 +funkyflo.tk, 1 +funloaded.org.ng, 1 +funmountaincanyon.com, 1 +funniestclip.com, 1 +funny-boy.tk, 1 +funny-rates.tk, 1 +funny-wedding.ga, 1 +funnyanimalvideos.ml, 1 +funnybikini.com, 1 +funnychristianjokes.tk, 1 +funnycommercials.ga, 1 +funnylinks.cf, 1 +funnymedia.tk, 1 +funnypicz.cf, 1 +funnyprankvideo.ga, 1 +funnytimes.cf, 1 +funoverip.net, 1 +funpakistan.tk, 1 +funphone.tk, 1 +funplaza.tk, 1 +funprode.org, 1 +funprogramming.tk, 1 +funreaktor.com, 1 +funsochi.ru, 1 +funsoup.tk, 1 +funspins.com, 1 +funtastic-basketball.de, 1 +funtastic.ie, 1 +funtime-inflatables.co.uk, 1 +funtime.com.ua, 1 +funtime.kiev.ua, 1 +funtimeentertainment.co.uk, 1 +funtimesailing.com, 1 +funtimesbouncycastles.co.uk, 1 +funtimeusabiloxi.com, 1 +funyirotraktor.hu, 1 +funzack.cf, 1 +fur-shop.tk, 1 +fur.red, 1 +furancheiro.com, 1 +furca.ca, 1 +furcdn.net, 1 +furcity.me, 1 +fureais.com, 1 +furgetmeknot.org, 1 +furgo.love, 1 +furi.ga, 1 +furisode-yamaguchiya.com, 1 +furiya.tk, 1 +furkancaliskan.com, 1 +furkankose.ml, 1 +furkot.com, 1 +furkot.de, 1 +furkot.es, 1 +furkot.fr, 1 +furkot.it, 1 +furkot.pl, 1 +furlan.co, 0 +furlan.tk, 1 +furlog.it, 1 +furnace-zero.tk, 1 +furnfurs.com, 1 +furnishedproperty.com.au, 1 +furnitureconcept.co.uk, 1 +furnitureproduction.tk, 1 +furniturezoneboone.com, 1 +furorcanario.tk, 1 +furosemide-lasix.tk, 1 +furosemide.gq, 1 +furries-united.de, 1 +furry.bot, 1 +furry.cat, 1 +furry.cool, 1 +furry.dk, 1 +furrybbs.com, 1 +furrycraft.ga, 1 +furrytech.network, 1 +fursandfur.tk, 1 +fursuitbutts.com, 1 +furtodo.com, 1 +furworks.de, 1 +furzone.net, 1 +fusacity.tk, 1 +fusacovi.cf, 1 +fusechange.org, 1 +fuselight.nl, 1 +fuseos.net, 1 +fuseyahoken.com, 1 +fushee.com, 1 +fusion-lamps.com, 1 +fusionapps.com, 1 +fusionapps.net, 1 +fusionauth.io, 1 +fusionetics.plus, 1 +fusiongaming.de, 1 +fusionstudios.tk, 1 +fussball-xxl.de, 1 +fussballpiraten.com, 1 +fussballtransfers.com, 1 +fussell.io, 1 +fussy.ee, 1 +fuszara.eu, 1 +futa.agency, 1 +futa.wiki, 1 +futaba-works.com, 1 +futarara.ga, 1 +futb0l.com, 1 +futbito.com, 1 +futbol-tv.tk, 1 +futbolcba.com, 1 +futbomb.com, 1 +futieltextiel.be, 1 +futo.biz, 1 +futos.de, 1 +futrou.com, 0 +futurama-il.tk, 1 +futureaudiographics.com, 1 +futurefire.de, 1 +futurefive.asia, 1 +futurefive.co.nz, 1 +futurefive.com.au, 1 +futurefund.com, 1 +futurefundapp.com, 1 +futuregrowthva.com, 1 +futurehack.io, 1 +futureindia.tech, 1 +futurenda.com, 1 +futureofyoucdc.sg, 1 +futureplanet.tk, 1 +futuresonline.com, 1 +futuressm.com, 1 +futurestyletiling.com.au, 1 +futurezone.at, 1 +futuristacademy.io, 1 +futuristicarchitectures.tk, 1 +fuvelis.com, 1 +fuwafuwa.moe, 1 +fuwashima.moe, 1 +fuxwerk.de, 1 +fuyu.moe, 1 +fuzenet.net, 1 +fuzoku-sodan.com, 1 +fuzoku.jp, 1 +fuzzbucket.tk, 1 +fuzzing-project.org, 1 +fuzzlemann.de, 1 +fuzzylogic.tk, 1 +fvap.gov, 1 +fvdm.com, 1 +fveevaete.com, 1 +fwba.hopto.org, 1 +fwdx.net, 1 +fwest.ovh, 1 +fwest98.nl, 1 +fwest98.ovh, 1 +fwg.sk, 1 +fws.gov, 1 +fwt99.com, 1 +fwt999.com, 1 +fwtapp.com, 1 +fwtewm.com, 1 +fwtpic.com, 1 +fx-rating.com, 1 +fx-rk.com, 1 +fx110.com, 1 +fx5.de, 1 +fxbrokerreview.org, 1 +fxe.pt, 1 +fxeuropa.com, 1 +fxgame.online, 1 +fxislamic.com, 1 +fxmarketing.com.au, 1 +fxmarketing.net.au, 1 +fxnotch.com, 1 +fxopen.co.uk, 1 +fxopen.com, 1 +fxopen.com.au, 1 +fxopen.com.br, 1 +fxopen.com.mx, 1 +fxopen.my, 1 +fxopen.ru, 1 +fxp.at, 1 +fxp.co.il, 1 +fxperk.com, 1 +fxpig-ib.com, 1 +fxpunch.com, 1 +fxrates.com, 1 +fxseo.com.au, 1 +fxstock.eu, 1 +fxstrategics.com, 1 +fxtalk.cn, 1 +fxthai.com, 1 +fxtrade-lab.com, 1 +fxweb.co, 1 +fxwebsites.com.au, 1 +fxwebsites.net.au, 1 +fxwebstudio.net.au, 1 +fydjbsd.cn, 1 +fyfywka.com, 1 +fyllehack.se, 1 +fyn.io, 1 +fyn.nl, 1 +fyn.software, 1 +fynbo.io, 1 +fynchmobility.com, 1 +fyol.pw, 1 +fyphb.com, 1 +fyretrine.com, 1 +fyroeo.fr, 0 +fysio-ict.nl, 1 +fysiotherapie-ict.nl, 1 +fysiotherapie.tk, 1 +fysiotherapieapeldoornzuid.nl, 1 +fysiotherapienieuwveen.nl, 0 +fysiotherapiesimons.nl, 1 +fyss.ga, 1 +fysuite.com, 1 +fytcart.com, 1 +fytorio-pasxalis.gr, 1 +fzbrweb.cz, 1 +fzdm.com, 1 +fzhyzamt.com, 1 +fzoske.de, 1 +fzx750.ru, 1 +g-center.tk, 1 +g-ds.de, 1 +g-fruit.gr, 1 +g-lab.xyz, 1 +g-m-w.eu, 1 +g-p-design.com, 1 +g-projects.herokuapp.com, 1 +g-tea.ml, 1 +g.co, 0 +g00228.com, 1 +g01.in.ua, 1 +g0158.com, 1 +g0881.com, 1 +g0man.com, 1 +g1.ie, 1 +g10e.ch, 1 +g116688.com, 1 +g1jeu.com, 1 +g22-livechat.com, 1 +g2jp.uk, 1 +g2links.com, 0 +g2pla.net, 1 +g2price.com, 1 +g2ship.com, 1 +g2soft.net, 0 +g30365.com, 1 +g36533.com, 1 +g36594.com, 1 +g3circuit.com, 1 +g3d.ro, 1 +g3dev.ch, 0 +g3homefoods.com, 1 +g3rv4.com, 1 +g47.web.id, 1 +g4t5esm2.team, 1 +g4v.in, 1 +g4w.co, 1 +g5.gov, 0 +g51365.com, 1 +g5197.co, 1 +g6666g.tk, 1 +g6729.co, 1 +g6957.co, 1 +g6957.com, 1 +g72020.gov, 1 +g7campdavid.gov, 1 +g7usa.gov, 1 +g81365.com, 1 +g82365.com, 1 +g8energysolutions.co.uk, 1 +g9297.co, 1 +g9397.com, 1 +g9721.com, 1 +g9728.co, 1 +ga-part.ru, 1 +gaasuper6.com, 1 +gaaz.fr, 1 +gabairealestate.com, 1 +gabaldon.eu, 1 +gabaldon.nl, 1 +gabapentin.gq, 1 +gabby-online.tk, 1 +gabbyer.ga, 1 +gabe.cooking, 1 +gabe.download, 1 +gabe.house, 1 +gabe.link, 1 +gabe.pics, 1 +gabe.space, 1 +gabe.watch, 1 +gabe565.com, 1 +gabeb1920.com, 1 +gabecook.com, 1 +gabethebabetv.com, 1 +gabinet-okulistyczny.tk, 1 +gabiocs.com, 1 +gablesportsga.com, 1 +gably.net, 1 +gabnotes.org, 1 +gabriel.to, 1 +gabrielaebruno.cf, 1 +gabrielafriasfanclub.tk, 1 +gabriele-kluge.de, 1 +gabriele.tips, 1 +gabrielemarino.tk, 1 +gabrielg.es, 1 +gabrielgn.com.br, 1 +gabrielgroup.com, 1 +gabrielkoo.com, 0 +gabriella.cf, 1 +gabrielsimonet.ch, 1 +gabrielsteens.nl, 1 +gabrielyin.com, 0 +gabryjeluk.tk, 1 +gabyminneboo.tk, 1 +gabysoft.tk, 1 +gachimuchi.ru, 1 +gachiyase.com, 1 +gachter.name, 0 +gaci88play.com, 1 +gad.co.id, 1 +gadabit.pl, 1 +gadaj.eu, 1 +gadanie.cf, 1 +gadanie.ml, 1 +gadatel.ml, 1 +gaddini.it, 1 +gadecs.com, 1 +gadget-freak.cf, 1 +gadget-tips.com, 1 +gadgetadvisor.net, 1 +gadgetflip.com, 1 +gadgetfreak.cf, 1 +gadgetgi.ga, 1 +gadgethacks.com, 1 +gadgetized.net, 1 +gadgetmaker.tk, 1 +gadgetputeh.com, 1 +gadgets-cars.com.es, 1 +gadgetshome.ml, 1 +gadgetstock.ir, 1 +gadingpromosindo.tk, 1 +gadkiy-farm.tk, 1 +gadse.games, 1 +gadzilla.tk, 1 +gae123.com, 1 +gaea-field.com.vn, 1 +gaecgh.org, 1 +gaelico.tk, 1 +gaengler.com, 1 +gaestehaus-leipzig.de, 1 +gaestehaus-monika.com, 1 +gaetanosonline.com, 1 +gafachi.com, 1 +gafan.cf, 1 +gaff-rig.co.uk, 1 +gaflooring.com, 1 +gaga-debki.pl, 1 +gaganenterprises.in, 1 +gagarin.ga, 1 +gagekroljic.com, 1 +gagesmith.tk, 1 +gagne.tk, 1 +gagnerenfant.tk, 1 +gagnerplusdargent.info, 1 +gagniard.org, 1 +gagor.pl, 0 +gagramore.cf, 1 +gagygnole.ch, 0 +gaiafood.co, 1 +gaiavanderzeyp.com, 0 +gaigai.com, 1 +gaijin.network, 1 +gaijin.systems, 1 +gaijinsystems.com, 1 +gailfellowsphotography.com, 1 +gaines-sodiamex.fr, 1 +gainesvillega.gov, 1 +gainins.com, 1 +gaio-automobiles.fr, 1 +gaireg.de, 1 +gaiserik.com, 0 +gaitandmobility.com, 1 +gaitrehabilitation.com, 1 +gaitresearch.com, 1 +gajas18.com, 1 +gajda.cz, 1 +gajowniczek.eu, 1 +gajqc.gov, 1 +gakdigital.com, 1 +gakkainavi-epsilon.net, 1 +gakki.photos, 1 +gaku-architect.com, 1 +gala.kiev.ua, 0 +galacg.me, 1 +galacticaos.tk, 1 +galacticbusiness.com, 1 +galacticfederation.eu, 1 +galaksidot.tk, 1 +galaktika-znakomstv.tk, 1 +galaltosalento.it, 1 +galanight.cz, 1 +galapagostraveldeals.com, 1 +galavanmoskou.tk, 1 +galax.us, 1 +galaxieblog.com.my, 0 +galaxus.at, 1 +galaxus.ch, 1 +galaxus.com, 1 +galaxus.de, 1 +galaxus.eu, 1 +galaxus.fr, 1 +galaxy.edu.pe, 1 +galaxymedia.tk, 1 +galaxymusicpromo.com, 1 +galaxyplex.tk, 1 +galaxyscientific.com, 1 +galaxysweeper.com, 1 +galefacialplastics.com, 1 +galenguyer.com, 0 +galenreasoner.com, 1 +galeria42.com, 1 +galeriabunkers.tk, 1 +galeriakobylarz.pl, 1 +galeriarr.pl, 1 +galeriart.xyz, 1 +galerias-xamoralarte.cf, 1 +galerie-claudia-walz-nagold.tk, 1 +galeries.photo, 0 +galexlee.com, 1 +galganoboutique.com, 1 +galgoafegao.com.br, 1 +galgoingles.com.br, 1 +galgopersa.com.br, 1 +gali.review, 1 +galiciasensual.tk, 1 +galilahiskye.com, 1 +galileanhome.org, 1 +galileo.io, 1 +galileohealth.com, 1 +galina.ga, 1 +galinas-blog.de, 1 +galinos.gr, 1 +galive.ga, 1 +galizae-sports.tk, 1 +galj.info, 1 +gallant.tk, 1 +galle.cz, 1 +galleonwaymedical.com.au, 1 +galleriacontinua.com, 1 +gallerify.eu, 1 +gallery-kaze.jp, 1 +galleryinfo.ga, 1 +gallest.cf, 1 +gallest.ga, 1 +galleyfoods.com, 1 +gallicrooster.com, 1 +gallifreyan-koala.tech, 1 +gallifreyapp.co.uk, 1 +gallifreypermaculture.com.au, 1 +gallmeyer-consulting.com, 1 +gallolineabagno.it, 1 +gallopingkylin.com, 1 +gallun-shop.com, 1 +galoserver.org, 1 +galpaoap.com.br, 1 +galpsafetytalks-portal-preprod.azurewebsites.net, 1 +galpsafetytalks-portal-production.azurewebsites.net, 1 +galtelligence.com, 1 +galvingao.com, 1 +galvinism.ink, 1 +gamagam.gq, 1 +gamalawadforum.tk, 1 +gamanlu.com, 1 +gamberorosso.menu, 1 +gamberorotto.com, 1 +gambetti.fr, 1 +gambiafishing.tk, 1 +gambiapagina.tk, 1 +gambit.pro, 1 +gambitnash.co.uk, 1 +gambitnash.com, 1 +gambitprint.com, 1 +gamblerhealing.com, 1 +gamblernd.com, 1 +gamblersgaming.eu, 1 +gambling-business.club, 1 +gamboahinestrosa.info, 1 +gamburger.tk, 1 +gamcore.com, 1 +game-club.me, 1 +game-dominion.tk, 1 +game-files.net, 0 +game-gentle.com, 1 +game-graph.com, 1 +game-net.ml, 1 +game-topic.ru, 1 +game4less.com, 1 +game7.de, 1 +game818play.com, 1 +game88city.com, 1 +game88city.net, 1 +game88play.com, 1 +game88yule.com, 1 +gameanalytics.com, 1 +gameapexlegends.com, 1 +gamebase.tk, 1 +gameblabla.nl, 1 +gameboys.xyz, 1 +gamebrott.com, 1 +gamecarddelivery.com, 1 +gamecentercity.fr, 1 +gamechefpummarola.eu, 1 +gamechurch.de, 1 +gameclimax.cf, 1 +gameclimax.tk, 1 +gameclue.jp, 1 +gamecollector.be, 1 +gameconservation.org.uk, 1 +gameconsole.co.nz, 1 +gamecs.tk, 1 +gamedaim.com, 1 +gameexpress.tk, 1 +gamefarm.ru, 1 +gamegainlx.cf, 1 +gamegix.com, 1 +gamegoddess.cf, 1 +gamegoddess.tk, 1 +gamegrad.tk, 1 +gameharbor.duckdns.org, 1 +gameharbor.eu, 1 +gameindustry.eu, 1 +gameisbest.jp, 1 +gamejobs.co, 1 +gamekaitori.jp, 1 +gamekb.gq, 1 +gamekeepers.cz, 1 +gamekeybox.tk, 1 +gamekiller.ga, 1 +gameloft.ga, 1 +gamelok.ga, 1 +gamemakers.tk, 1 +gamemodding.com, 1 +gamenerd.net, 1 +gamenew.tk, 1 +gameofbooks.de, 1 +gameonespirit.tk, 1 +gamepad.com.br, 1 +gameplaysforkids.com, 1 +gamepokies.ml, 1 +gamepower.tk, 1 +gamepreorders.com, 1 +gamepres.org, 1 +gamepunel.cf, 1 +gamepunelita.cf, 1 +gamepunelita.tk, 1 +gamer-portal.com, 1 +gamercredo.com, 1 +gamereactor.asia, 1 +gamereactor.cn, 1 +gamereactor.de, 1 +gamereactor.dk, 1 +gamereactor.es, 1 +gamereactor.eu, 1 +gamereactor.fi, 1 +gamereactor.fr, 1 +gamereactor.it, 1 +gamereactor.no, 1 +gamereactor.pt, 1 +gamereactor.se, 1 +gamereader.de, 1 +gamerepublic.hu, 1 +gameres.com, 1 +gamerezo.com, 1 +gamering.cf, 1 +gamers-community.tk, 1 +gamers-paradise.tk, 1 +gamersheaven.tk, 1 +gamerspawn.net, 1 +gamersplace.tk, 1 +gamerspost.ga, 1 +gamerstudiozinc.tk, 1 +gamersuniverse.tk, 1 +gamersweb.ga, 1 +gamertelligence.com, 1 +gamertrashers.ga, 1 +gamerturk.tk, 1 +gamerwelfare.com, 1 +gamerzdot.com, 1 +games-station.tk, 1 +games2kids.net, 1 +games4theworld.org, 1 +gamesalia.com, 1 +gamesaviour.com, 1 +gamesdepartment.co.uk, 1 +gameserver-admin.ga, 1 +gameserver-sponsor.me, 1 +gamesgate.tk, 1 +gameshack.io, 1 +gameship.ga, 1 +gameshogun.xyz, 1 +gameshopsrbija.com, 1 +gameshowchallenge.ie, 1 +gamesided.com, 1 +gamesmagic.tk, 1 +gamesone.tk, 1 +gamespark.tk, 1 +gamespider.tk, 1 +gamesplanet.com, 1 +gamesputnik.ru, 1 +gamestoplayfree.com, 1 +gameswitchers.uk, 1 +gametium.com, 1 +gametium.es, 1 +gametube.website, 1 +gameview.tk, 1 +gamewayz.online, 1 +gamewinninggoal.com, 1 +gameworldcdr.tk, 1 +gamexperts.ga, 1 +gamezo.co.uk, 1 +gamezon.tk, 1 +gamhealth.net, 1 +gamilab.com, 1 +gamilab.no, 1 +gaming-dice.tk, 1 +gaming-lenkrad-experten.de, 1 +gaming-life.tk, 1 +gaming-news.tk, 1 +gaming-online.tk, 1 +gamingaktier.com, 1 +gamingblogx.com, 1 +gamingerox.com, 1 +gamingexodus.com, 1 +gamingexperts.ga, 1 +gamingmonitortest.com, 1 +gamingph.com, 1 +gamingterritory.com, 1 +gamingtilltheend.cf, 1 +gamingtoday.ga, 1 +gamingtopbox.ga, 1 +gamingwithcromulent.com, 1 +gamingx.tk, 1 +gamingzoneservers.com, 1 +gamisalya.com, 1 +gamishijabsyari.com, 1 +gamishou.fr, 1 +gamivo.com, 1 +gammaphibeta.tk, 1 +gamster.tv, 1 +gan.wtf, 1 +ganapati.fr, 1 +ganardinerotrabajandoporinternet.com, 1 +ganasoku.net, 1 +gancedo.com.es, 1 +gandalfcz.tk, 1 +gandalfservice.com, 1 +gandalfthefeline.com, 1 +gandgliquors.com, 1 +gangbangs.tk, 1 +ganggalbichler.at, 1 +ganglioslinfaticos.com, 1 +gangnam-club.com, 1 +gangnamcool.com, 1 +gangrulz.tk, 1 +gangstaflow.tk, 1 +gangsterz.tk, 1 +ganjinedanesh.com, 1 +ganodermatiendaonline.com, 1 +gantt-chart.com, 1 +ganzgraph.de, 1 +ganztagplus.de, 1 +gao.ci, 1 +gao.rocks, 1 +gaodebo.com, 1 +gaoinnovation.gov, 1 +gaoinnovationlab.gov, 1 +gaoinnovations.gov, 1 +gaojianli.me, 1 +gaojianli.tk, 1 +gaon.network, 1 +gaonadigital.com, 1 +gaos.org, 1 +gaozj.com, 1 +gapdirect.com, 1 +gapfa.org, 0 +gapfa.ro, 1 +gaphag.ddns.net, 1 +gaponov.tk, 1 +garage-leone.com, 0 +garage.click, 1 +garagechief.com, 1 +garagedejan.ch, 1 +garagedoorrepaircedarhilltx.com, 1 +garagedoorrepairingsanjose.com, 1 +garageenginuity.com, 1 +garagegoossens.be, 1 +garagemhermetica.org, 1 +garagenet.com, 1 +garagesmart.com.au, 1 +garagevanhulle-used.be, 0 +garanteasy.com, 1 +garantieabschluss.de, 0 +garazskapuszereles.hu, 1 +garbage-juice.com, 1 +garbarinocatalogo.com, 1 +garbott.co.uk, 1 +garbuz.ga, 1 +garciacleaningsf.com, 1 +garciagerman.com, 1 +garciam.gt, 1 +garciaortiz.com, 1 +garda-see.mobi, 1 +gardarika.tk, 1 +gardedenfantspourtous.fr, 1 +garden-land.ga, 1 +garden-life.org, 1 +garden4less.co.uk, 1 +gardencentreshopping.co.uk, 1 +gardengameshireuk.com, 1 +gardensquaredental.co.uk, 1 +gardikagigih.com, 1 +gardis.ua, 1 +gardonslecap-covid19.ch, 1 +gardtools.com, 1 +garduri-electrice-animale.ro, 1 +garethbowker.com, 1 +garethkirk.com, 1 +garethrhugh.es, 1 +garfieldairlines.tk, 1 +gargantuan.wang, 1 +gargas.ml, 1 +gargazon.net, 1 +gargola.tk, 1 +garmonia.ml, 1 +garmonia.tk, 1 +garnertree.com, 1 +garnuchbau.de, 1 +garo.host, 1 +garo.network, 0 +garo.ninja, 1 +garonna.com.ua, 1 +garotastop10.tk, 1 +garotos.gq, 1 +garotos.tk, 1 +garrettcornwell.tk, 1 +garriganenterprises.com, 1 +garriganenterprises.net, 1 +garriganenterprisesinc.com, 1 +garriganenterprisesinc.net, 1 +garron.net, 1 +garrow.se, 1 +garrowdigitalmedia.com, 1 +garrowmediallc.com, 1 +garrulousgrimoire.com, 1 +garryserver.de, 1 +garsio.com, 1 +gartanien.de, 1 +garten-diy.de, 1 +gartenbau-rostock.de, 1 +gartenbaur.de, 1 +gartenforsenate.com, 1 +gartenplan-saar.de, 1 +gartenplanung-brendes.de, 1 +garwoh.de, 1 +gary.gov, 1 +garycarmell.com, 1 +garyjones.co.uk, 1 +garyrh.com, 1 +garystallman.com, 1 +garywhittington.com, 1 +gas-boilers.tk, 1 +gasbarkenora.com, 1 +gashalot.com, 1 +gasinstallationsjohannesburg.co.za, 1 +gasmar.cl, 1 +gasnews.net, 1 +gasometria.com, 1 +gaspapp.com, 1 +gaspard-ulliel.tk, 1 +gasparesganga.com, 1 +gasscc.id, 1 +gassero.com, 0 +gassouthkenticoqa.azurewebsites.net, 1 +gassyukumenkyoguide.com, 1 +gastonvietto.tk, 1 +gastoudererenda.nl, 1 +gastrobox.com.co, 1 +gastroenterologen.no, 1 +gastrolab.tk, 1 +gastromedicalcenter.com.br, 1 +gastronom.ga, 1 +gastrotiger.at, 1 +gastrotiger.de, 1 +gatapro.net, 0 +gate.sc, 1 +gate2home.com, 1 +gateaucreation.fr, 1 +gatehub.net, 1 +gatekala.ir, 1 +gatemaster.ga, 1 +gatemoves.com, 1 +gatesstlouis.com, 1 +gatewaybridal.com, 1 +gatewayclub.com.au, 1 +gatewaydentalinc.com, 1 +gathegi.ga, 1 +gatherling.com, 1 +gathu.co.ke, 1 +gatilagata.com.br, 1 +gatlink.tk, 1 +gatomix.net, 1 +gatot.id, 1 +gattomatto.tk, 1 +gattschan.tk, 1 +gauche.com, 1 +gaudeamus-folklor.cz, 1 +gaudeamuschoir.tk, 1 +gaudere.co.jp, 1 +gaumenverfuehrer.de, 1 +gauravtiwari.org, 0 +gautam-iiith.tk, 1 +gautam-k.tk, 1 +gautengplumber24-7.co.za, 1 +gauthier.dk, 1 +gauthier.tel, 1 +gavanstore.ir, 1 +gavilanz.ddnsfree.com, 1 +gavin.sh, 1 +gavingreer.com, 1 +gavins.stream, 1 +gavlix.se, 1 +gay-jays.com, 1 +gay-personal-ads.com, 1 +gay.systems, 1 +gayauthors.org, 1 +gaycafe.lt, 1 +gaycc.cc, 1 +gaychatrooms.tk, 1 +gaygeeks.de, 1 +gaymer.network, 1 +gaymerconnect.net, 1 +gaymerx.com, 1 +gaymerx.net, 1 +gaymerx.org, 1 +gaynight.tk, 1 +gaysexpositions.guide, 1 +gaytorrent.ru, 1 +gaytubec.com, 1 +gayubo.com, 1 +gayukai.net, 1 +gayxsite.com, 1 +gazachallenge.org, 1 +gazaryan.tk, 1 +gazellegames.net, 0 +gazete.org, 1 +gazetekarinca.com, 1 +gazette.govt.nz, 1 +gazizov.tk, 1 +gazoakley.com, 1 +gazoz.ga, 1 +gb-repair.com, 1 +gba.ge, 1 +gbcsummercamps.com, 1 +gbet24.com, 1 +gbhem.org, 1 +gbinsta.com, 1 +gbiotech.tk, 1 +gbl.selfip.net, 0 +gbmwolverine.com, 1 +gboys.net, 0 +gbs-uk.com, 0 +gbsapri.it, 1 +gbsvelasco.com, 1 +gbusercontent.com, 1 +gc-hartberg.tk, 1 +gc-mc.de, 1 +gc.de, 1 +gc.gy, 1 +gc.ru.net, 1 +gcb.org.au, 1 +gcbit.dk, 1 +gcfadvisors.com, 1 +gcgeeks.com.au, 1 +gcgroup.io, 1 +gchc.com, 1 +gchp.ie, 0 +gchq.lol, 1 +gchq.wtf, 1 +gcmsnotes.com, 1 +gcode.space, 1 +gcoded.de, 1 +gconcept.tk, 1 +gcs-ventures.com, 1 +gcschool.tk, 1 +gcsepod.com, 1 +gcso.gov, 1 +gcwatx.gov, 1 +gda.fr, 1 +gdax.com, 1 +gdb-tutorial.net, 1 +gde-kupyt.ru, 1 +gdesemena.ru, 1 +gdevpenze.ru, 1 +gdhzcgs.com, 1 +gdiary.net, 1 +gdngs.de, 1 +gdoce.es, 0 +gdpr-pohotovost.cz, 1 +gdpr.fr, 1 +gdraco.com, 1 +gdretrofunk.cf, 1 +gdv.me, 1 +gdz-spishy.com, 1 +gdz.tv, 1 +ge1.me, 0 +ge3k.net, 0 +gealot.com, 1 +gear-acquisition-syndrome.community, 1 +gear4you.shop, 1 +gearallnews.com, 1 +gearbot.rocks, 1 +gearboxhero.com, 1 +gearev.net, 1 +gearfinder.nl, 1 +gearnews.tk, 1 +gearnify.com, 1 +gearset.com, 1 +geartips.club, 1 +gearwise.se, 1 +geaskb.nl, 1 +geass.xyz, 1 +geba-online.de, 1 +gebaeudebilanzierung.de, 1 +geblitzt.de, 1 +gebn.co.uk, 1 +gebn.uk, 1 +geboortestoeltje.com, 1 +geborgen-wachsen.de, 1 +gebruikershandleiding.com, 1 +gec.tn, 1 +gecem.org, 1 +gechr.io, 1 +geckler-ee.de, 0 +geckosurfschool.com, 1 +gedachtekaarsje.nl, 1 +gedankenworks.com, 0 +geddert.systems, 1 +geder.at, 1 +gedlingcastlehire.co.uk, 1 +gedlingtherapy.co.uk, 1 +geecrat.com, 1 +geek-hub.de, 1 +geek-rooms.tk, 1 +geek.ch, 1 +geek1.de, 1 +geekabit.nl, 1 +geekanatomy.com, 1 +geekandi.com, 1 +geekariom.com, 0 +geekashell.tk, 1 +geekbundle.org, 1 +geekclubbooks.com, 1 +geekcreations.co.uk, 1 +geekdama.com.br, 1 +geekedin.ga, 1 +geekeries.org, 1 +geekgao.cn, 1 +geekgear.tk, 1 +geekgirltech.com, 1 +geeklair.net, 1 +geeklan.co.uk, 1 +geekles.net, 1 +geekmagazine.com.br, 1 +geeknik.com, 1 +geekobyte.com, 1 +geekpad.com, 1 +geeks.berlin, 1 +geeks.lgbt, 1 +geeks.one, 0 +geeksforrent.com, 1 +geekshirts.cz, 1 +geeksquadforums.tk, 1 +geekstreet.fr, 1 +geekstuff.tk, 1 +geekstyle.cz, 1 +geektarven.com, 1 +geektechypro.tk, 1 +geektopia.es, 1 +geekurl.cf, 1 +geekwhack.org, 1 +geekwithabudget.com, 1 +geekwu.org, 1 +geekyboi.co.uk, 1 +geekyleisure.com, 1 +geekymansion.com, 1 +geekynutritionist.com, 1 +geekyquiz.com, 1 +geekystudios.us, 1 +geekz.sk, 1 +geekzone.co.nz, 1 +geekzone.fr, 1 +geenoo.net, 1 +geenspam.net, 1 +geentsefeesten.be, 1 +geeq.ch, 1 +geerdsen.net, 1 +geertswei.nl, 1 +geestelijkgezondgent.be, 1 +gefeuert.de, 1 +gefolge.org, 1 +gegeco.ch, 0 +geh.li, 1 +gehas-wein-shop.de, 0 +gehirn.co.jp, 1 +gehirn.jp, 1 +gehirnapis.jp, 1 +gehopft.de, 1 +gehreslaw.com, 1 +gehrke.cloud, 1 +gehrke.in, 1 +gehrke.nrw, 1 +gehsicht.de, 1 +geico.com, 1 +geigenbauer.in, 0 +geigr.de, 1 +geiser-family.ch, 1 +geisser-elektronikdata.de, 1 +geitenijs.com, 1 +gekleurdverleden.be, 1 +gekosoft.eu, 1 +gelaendermanufaktur.de, 1 +gelanc.ml, 1 +gelarehghamari.com, 1 +gelb-computer.de, 1 +geld-im-blick.de, 1 +geld-magazin.info, 1 +geld24.nl, 0 +geldimblick.de, 1 +geldoderleben.tk, 1 +geldteveel.eu, 1 +geleenbeekdal.nl, 1 +geleia-real.com, 1 +geli-graphics.com, 1 +gelijk.cf, 1 +gellis12.com, 1 +gelmostop.tk, 1 +gelog-software.de, 0 +gelonghui.com, 1 +geloofindemocratie.nl, 1 +gelsey.com, 1 +geluidsstudio.com, 1 +gelukkigehonden.nl, 1 +geluleminceur.fr, 1 +gelvetika.cf, 1 +gem-forex.net, 1 +gem-forex.org, 1 +gem-forex.pro, 1 +gem-info.fr, 1 +gemails.eu, 1 +gemax-online.de, 1 +gembet99.com, 1 +gemeinde-steinhoering.de, 1 +gemeinderatswahl2020.de, 1 +gemeinfreie-lieder.de, 1 +gemeinsam-ideen-verwirklichen.de, 1 +gemelen.net, 1 +gemforex.pro, 1 +gemforex.top, 1 +gemgroups.in, 1 +gemini.com, 1 +gemmy.cf, 1 +gemonite.com, 1 +gempak.com, 1 +gemquery.com, 1 +gemsforeveryone.com, 1 +gemstn.com, 1 +gemwire.uk, 1 +gen53.org, 1 +genbars.jp, 1 +genbright.com, 1 +genbrugge.tk, 1 +genchev.io, 0 +gencmedya.com, 1 +gend.moe, 1 +gender-summit.com, 1 +genderidentiteit.nl, 1 +genderreveal.nl, 1 +genderrevealshop.nl, 1 +gendrin.com, 1 +gendundrupa.ch, 0 +gene-drive.com, 1 +gene-drives.com, 1 +genealog.ong.br, 1 +genealogiegazet.nl, 1 +genealogieonline.nl, 1 +genealogiewerkbalk.nl, 1 +genealorand.com, 1 +geneau.net, 1 +geneeskrachtig.com, 1 +genehightower.com, 1 +genehome.com.au, 1 +genemesservwparts.com, 1 +genemon.at, 1 +genen.ga, 1 +generace-id.org, 1 +generacionmoderatto.tk, 1 +generador-electrico.com, 1 +general-anaesthesia.com, 1 +general-anaesthetics.com, 1 +general-anesthesia.com, 1 +general-insurance.tk, 1 +generalautocheck.com, 1 +generalcustomshop.com.br, 1 +generali-worldwide.com, 1 +generalinsuranceagencies.com.au, 1 +generalinsuranceservices.com, 1 +generalpsych.cf, 1 +generalservice.eu, 1 +generaly.ga, 1 +generateur-thot.fr, 1 +generateurdesmiley.tk, 1 +generationgoat.com, 1 +generationnext.pl, 0 +generationsweldom.com, 1 +generator.creditcard, 1 +generatorkodowkreskowych.pl, 1 +generatormag.com, 1 +generatormusic.tk, 1 +generic-noroxin.ml, 1 +generic-plavix.ga, 1 +generic-sildenafil-citrate.cf, 1 +generic-tadalafil.cf, 1 +generic-tenormin.gq, 1 +generic.cx, 1 +genericabana.gq, 1 +genericaccutaneonline.ml, 1 +genericaceon.tk, 1 +genericacomplia.ga, 1 +genericadvaironline.ml, 1 +genericazithromycin.tk, 1 +genericazulfidine.gq, 1 +genericcalan.gq, 1 +genericcelebrex.tk, 1 +genericclaritin.ga, 1 +genericcolchicine.ml, 1 +genericdevelopment.nl, 1 +genericdutasteride.cf, 1 +genericflagyl.ga, 1 +genericforavodartmedication.tk, 1 +genericforflagyl.cf, 1 +genericlevaquin.tk, 1 +genericlexaprocost.cf, 1 +genericlexaprocost.tk, 1 +generico.in, 1 +genericprevacidlansoprazole.tk, 1 +genericrhinocort.ga, 1 +genericuroxatral.gq, 1 +genericvytorin.ml, 1 +generujdata.cz, 1 +geneseecountymi.gov, 1 +genesisblock.com, 1 +genesiseureka.com, 1 +genesisgold.com, 1 +genesisgrade.com, 1 +genesismachina.ca, 1 +genesisplay.tk, 1 +genesistrading.com, 0 +genesysmi.com, 1 +genetargetsolutions.com.au, 1 +geneticvisions.com, 1 +genetidyne.com, 1 +genevachauffeur.com, 1 +genevacountyal.gov, 1 +geneve-naturisme.ch, 0 +geneve.guide, 1 +genevoise-entretien.ch, 0 +genfaerd.dk, 1 +genghan.com, 1 +gengive-smalto-oralb.it, 1 +genhu.com.ar, 1 +genia-life.de, 1 +geninspira.com, 1 +geniofinanciero.org, 1 +genioideal.com, 1 +genious.co, 1 +genious.social, 1 +genious.world, 1 +genioyfigura.tk, 1 +geniusclan.tk, 1 +geniushost.in, 1 +geniusmarketing.ro, 1 +geniusteacher.in, 1 +geniuszone.biz, 1 +genjer.com, 0 +genkihub.com, 1 +genkiwork.com, 1 +genlack.com, 1 +genmab.co.jp, 1 +gennaroabete.duckdns.org, 1 +gennerator.com, 1 +genocidediary.org, 1 +genodeftest.de, 1 +genom.by, 1 +genome.gov, 0 +genomedia.jp, 1 +genomelink.io, 1 +genomequestlive.com, 1 +genometrik.de, 1 +genoog.com, 1 +genophore.com, 1 +genosse-einhorn.de, 1 +genossen.ru, 1 +genossenwiese.ch, 1 +genoveve.de, 1 +gensend.com, 1 +gensenwedding.jp, 1 +genshiken-itb.org, 1 +gensicke.de, 1 +genslerapps.com, 1 +genslerwisp.com, 1 +gensokyo.cafe, 1 +gensokyo.chat, 0 +gensokyo.re, 1 +gensonline.eu, 1 +gentapps.com, 1 +gentbereikbaar.be, 1 +gentblogt.be, 1 +gentbrugsemeersen.be, 1 +gentcityofmusic.be, 1 +gentcongres.be, 1 +gentcongres.com, 1 +gentcongres.eu, 1 +gentcongres.org, 1 +gentcreativecityofmusic.be, 1 +gentechi.com, 1 +gentengarde.be, 1 +gentevenement.be, 1 +gentfietst.be, 1 +gentgezondestad.be, 1 +gentgreenkey.be, 1 +gentianes.ch, 0 +gentinvest.be, 1 +gentklimaatstad.be, 1 +gentlecollies.tk, 1 +gentledance.ch, 1 +gentledance.net, 1 +gentledentalcaregroup.co.uk, 1 +gentleentuit.be, 1 +gentlent.biz, 1 +gentlent.blog, 1 +gentlent.co, 1 +gentlent.com, 1 +gentlent.eu, 1 +gentlent.group, 1 +gentlent.help, 1 +gentlent.info, 1 +gentlent.io, 1 +gentlent.net, 1 +gentlent.org, 1 +gentlent.tech, 1 +gentlent.uk, 1 +gentlent.us, 1 +gentlent.xyz, 1 +gentlentapis.com, 1 +gentlentgroup.com, 1 +gentlentssl.com, 1 +gentlichtfestival.be, 1 +gentlichtfestival.com, 1 +gentlivinglab.be, 1 +gentmuziekstad.be, 1 +gentoo-blog.de, 0 +gentooblog.de, 1 +gentoocn.org, 1 +gentse-ondernemersdagen.be, 1 +gentsefeesten.be, 1 +gentsefeesten.gent, 1 +gentseondernemersdagen.be, 1 +gentsklimaatverbond.be, 1 +gentslimopweg.be, 1 +genttegenarmoede.be, 1 +gentverwent.be, 1 +genunlimited.ga, 1 +genunlimited.tk, 1 +genusbag.com, 1 +genzi.win, 1 +genzia.ga, 1 +geo-industrie.fr, 1 +geo-portale.it, 1 +geoarchive.tk, 1 +geobennett.com, 1 +geocar.com, 1 +geocommunicator.gov, 1 +geocompass.at, 1 +geoconvention.ga, 1 +geocostarica.com, 1 +geodesign.tk, 1 +geoenvironconsult.ga, 1 +geoffanderinmyers.com, 1 +geoffmyers.com, 1 +geoffnussmd.com, 1 +geoffsec.org, 1 +geoforex.ro, 1 +geofox.org, 1 +geografia-peru.tk, 1 +geographique.tk, 1 +geography-schools.com, 1 +geohashing.site, 1 +geoip.fedoraproject.org, 1 +geoip.stg.fedoraproject.org, 1 +geojs.io, 1 +geokeys.cf, 1 +geolex.tk, 1 +geologist.tk, 1 +geology-schools.com, 1 +geomac.gov, 1 +geomadrid.ga, 1 +geoman.tk, 1 +geometra.roma.it, 1 +geometra24.it, 1 +geometri.tk, 1 +geomonkeys.com, 1 +geonice.ga, 1 +geonot.es, 1 +geophysicsjournal.com, 1 +geopixeles.cl, 1 +geoponika.gr, 1 +geoport.al, 1 +georadar-algerie.com, 1 +georg-ledermann.de, 1 +george-brighton.co.uk, 1 +george-orwell.com, 1 +george.com.tw, 1 +georgebeverlysheamemorial.org, 1 +georgebrighton.co.uk, 1 +georgeclaghorn.com, 1 +georgeclooney.tk, 1 +georgecolgrove.com, 1 +georgedesign.ch, 1 +georgekaraoglanis.tk, 1 +georgelucas.tk, 1 +georgemaschke.com, 1 +georgemaschke.net, 1 +georgemudie.com, 1 +georgenad.duckdns.org, 1 +georgepancescu.ro, 1 +georgesand.be, 1 +georgescarryout.com, 1 +georgeshobeika.cf, 1 +georgeslasaucisse.fr, 1 +georgetownohio.gov, 1 +georgewatson.me, 1 +georgewbushlibrary.gov, 1 +georgewilsonvsgatsbyjs.org, 1 +georgiaautoglass.net, 1 +georgiabonepc.com, 1 +georgiadance.com, 1 +georgiaglassrepair.com, 1 +georgiainfo.ga, 1 +georgianews.ml, 1 +georgiangames.gq, 1 +georgianhistory.tk, 1 +georgiaparks.org, 1 +georgiastuartyoga.co.uk, 0 +georgiatransport.com, 1 +georgiaurologist.com, 1 +georgie.cc, 1 +georgiebailey.com, 1 +georginabouzova.tk, 1 +georgioskontaxis.com, 1 +georgioskontaxis.net, 1 +georgioskontaxis.org, 1 +georgiosnetworks.com, 1 +georgiouk.gr, 1 +georgmayer.eu, 1 +geosales.tk, 1 +geoscan.aero, 1 +geoscope.ch, 0 +geotabgov.us, 1 +geotech.tk, 1 +geothermalproducts.info, 1 +geourl.me, 1 +geowest.tk, 1 +geowithmaps.com, 1 +gep.ch, 1 +gep.com, 1 +gepe.ch, 1 +gepgroup.gr, 1 +gepps.de, 1 +geraintwhite.co.uk, 1 +gerald-zojer.com, 1 +geraldoazevedo.com.br, 1 +geraldsonrealty.com, 1 +geraldzavod.ru, 1 +gerardinden.nl, 1 +gerardozamudio.mx, 1 +gerbang-singkolo.ga, 1 +gerber-construction.com, 1 +gerbils.tk, 1 +gerbyte.co.uk, 1 +gerbyte.com, 1 +gerbyte.uk, 1 +gerenciaconsultor.com, 1 +gergoladi.me, 1 +gerinet.pl, 1 +germain.cc, 1 +germaintechnologies.com, 1 +germancoding.com, 1 +germancraft.net, 1 +germandarknes.net, 1 +germanicvs.tk, 1 +germanmasterpainters.nz, 1 +germansoldiers.net, 1 +germanssky.de, 1 +germantrip.tk, 1 +germany-board.tk, 1 +germanytravel.ga, 1 +germanytravelguide.ml, 1 +germfr.ee, 1 +germinalekeren.tk, 1 +germistonrubbleremovals.co.za, 1 +germistry.com, 1 +gernert-server.de, 1 +gero.io, 1 +geroiplavska.tk, 1 +gerritcodereview.com, 1 +gers-authentique.com, 1 +gervais-avocat.fr, 1 +gerwinvanderkamp.nl, 1 +ges-bo.de, 1 +gesamenvat.nl, 1 +gesath.com, 1 +geschenkly.de, 0 +geschichtscheck.de, 1 +geschmacksache.online, 1 +geschmackspiloten.de, 0 +geschwinder.net, 1 +gesditel.es, 1 +geseduc.cl, 1 +gesentorno.tk, 1 +gesevi.com, 1 +gesica.cloud, 1 +gesmav-trier.de, 1 +gesnex.com, 1 +gessettirotti.it, 1 +gestalte-deinen-balkon.de, 1 +gestaoclub.com.br, 1 +gestionadministrativevirtuelle.ca, 1 +gestionadministrativevirtuelle.ch, 1 +gestionadministrativevirtuelle.com, 1 +gestionth.com, 1 +gestorehotel.com, 1 +gestorestecnologicos.com, 1 +gestorimob.com.br, 1 +gestorimobiliaria.com.br, 1 +gestormensajeria.com, 1 +gestsal.com, 1 +gestus.co, 1 +gesundheitmassage.com, 1 +gesundheitswelt24.de, 1 +gesundimmund.de, 1 +get-asterisk.ru, 1 +get-baaam.com, 1 +get-california-real-estate.com, 1 +get-erp.ru, 1 +get-express-vpn.com, 1 +get-it-live.com, 1 +get-it-live.de, 1 +get-maurice.com, 1 +get-my-report.com, 1 +get-on.bid, 1 +get-quick-bits-fast-2018.pw, 1 +get-refer.com, 1 +get-x-web-link2.com, 1 +get-your-business.tk, 1 +get.design, 1 +get.how, 1 +getacrane.co.uk, 1 +getalitools.ru, 1 +getanresources.com, 1 +getanswer.ga, 1 +getapps.review, 1 +getasecondlife.net, 1 +getawayline.com, 1 +getbestbooks.com, 1 +getbookked.com, 1 +getbooks.co.il, 1 +getbootstrap.com, 1 +getboubou.com, 1 +getbox.me, 1 +getbrain.tk, 1 +getbreadcrumbs.com, 1 +getbrowink.com, 1 +getbutterfly.com, 1 +getby.download, 1 +getcloak.com, 0 +getcodelove.com, 1 +getcolq.com, 1 +getcookie.ml, 1 +getcreditscore.com.au, 1 +getdash.io, 1 +getdeclutter.com, 1 +getdinghy.com, 1 +getdishnow.tk, 1 +getdoges.tk, 1 +getdownon.it, 1 +geteducation.tk, 1 +geteduroam.no, 1 +getelectronics.tk, 1 +geterp.ru, 1 +getfedora.org, 1 +getfirstalert.com, 1 +getfithtx.biz, 1 +getflorence.co.uk, 1 +getfreeelectricity.tk, 1 +getfreeltc.ml, 1 +getgeek.dk, 1 +getgeek.ee, 1 +getgeek.es, 1 +getgeek.fi, 1 +getgeek.fr, 1 +getgeek.io, 1 +getgeek.no, 1 +getgeek.nu, 1 +getgeek.pl, 1 +getgeek.se, 1 +gethome.ru, 1 +gethow.org, 1 +gethttpsforfree.com, 1 +gethyas.com, 1 +geti2p.com, 1 +getidmcc.com, 1 +getinfoleads.tk, 1 +getinphase.com, 1 +getintopc.com, 1 +getintra.org, 1 +getitlive.de, 1 +getitpeople.com, 1 +getjadedlocal.com, 1 +getjms.com, 1 +getjobtoday.net, 1 +getlatka.com, 1 +getlawnbuddy.com, 1 +getlawyered.com.au, 1 +getleanflorida.gov, 1 +getlibrary.com, 1 +getlostforever.com, 1 +getmango.com, 1 +getmarksvoice.com, 1 +getmdl.io, 1 +getme.cf, 1 +getmerch.eu, 1 +getmonero.cz, 1 +getmovil.com, 1 +getnetset.com, 1 +getnew.tk, 1 +getnib.com, 1 +getnikola.com, 1 +getonyx.com, 1 +getpagespeed.com, 1 +getpaidclub.tk, 1 +getpaidtocode.com, 1 +getpaidtodesign.com, 1 +getpaidtodev.com, 1 +getpanelapp.com, 1 +getpei.com, 1 +getpet.lt, 1 +getpopspots.com, 1 +getprohealth.com, 1 +getpromo.cf, 1 +getpublii.com, 1 +getrambling.com, 1 +getreadyforever.tk, 1 +getresilience.org, 1 +getsamegoal.com, 1 +getscif.com, 1 +getsecure.nl, 1 +getserum.xyz, 1 +getsetbounce.co.uk, 1 +getshouse.com, 1 +getsilknow.com, 1 +getsmartaboutdrugs.gov, 0 +getsmartlife.in, 1 +getstat.net, 1 +getsubs.net, 1 +getsus.com, 1 +getswadeshi.com, 1 +getteamninja.com, 1 +gettext.tk, 1 +getthefriendsyouwant.com, 1 +getthegoat.com, 1 +getticker.com, 1 +gettodoing.com, 1 +gettopquality.com, 1 +gettravelista.com, 1 +getts.ro, 1 +getts.shop, 1 +gettwo.ml, 1 +getupandbounce.co.uk, 1 +getvalidate.com, 1 +getvdownloader.com, 1 +getveer.io, 1 +getwemap.com, 1 +getwisdom.io, 1 +getwork.tk, 1 +getwsodo.com, 1 +getyeflask.com, 1 +getyou.onl, 0 +getyour.nz, 1 +getyoureuro.tk, 1 +getyourguide.com, 1 +getyourlifestraight.com, 1 +getyournurse.de, 1 +getyourphix.tk, 1 +geulah.org.il, 1 +geus-okna.eu, 1 +gevaulug.fr, 1 +gevelreinigingtiel.nl, 1 +gevme.com, 1 +gewel.io, 1 +geyduschek.be, 1 +gezinnenhilton.com, 1 +gezondetips.nl, 1 +gezondheidszorg-ict.nl, 1 +gezondheidszorg-it.nl, 1 +gf-franken.de, 1 +gf5fcalc.com, 1 +gfac.ru, 1 +gfahnen.de, 1 +gfast.ru, 1 +gfbakers.com, 1 +gfcleisure.co.uk, 1 +gfe.link, 1 +gfedating.com, 1 +gfestival.fo, 1 +gfetechs.com, 1 +gfgmmarketing.com, 1 +gfk-kunststoff-luebben.de, 1 +gflame.de, 1 +gfmomcertified.com, 1 +gfmp.com.pl, 1 +gfms.ru, 1 +gfnetfun.cf, 1 +gforce.ninja, 1 +gforex.biz, 1 +gforex.pro, 1 +gforex.top, 1 +gfoss.eu, 1 +gfoss.gr, 1 +gfourmis.co, 1 +gfournier.ca, 1 +gfronline.tk, 1 +gfw.ro, 1 +gfxbench.com, 1 +gfxload.com, 1 +gfxworld.tk, 1 +gg.ax, 1 +gg5197.co, 1 +gg6729.co, 1 +gg6729.com, 1 +gg6957.co, 1 +gg9297.co, 1 +gg9397.com, 1 +gg9721.com, 1 +gg9728.co, 1 +ggbet.me, 1 +ggdcpt.com, 1 +gggggg.org, 1 +gginin.today, 1 +ggismo.com, 1 +ggiveilig.nl, 1 +ggl-luzern.ch, 0 +ggld.net, 1 +gglks.com, 1 +ggma.co.uk, 1 +ggmmontascale.it, 1 +ggobbo.com, 1 +ggradio.net, 1 +ggs-marschallstrasse.de, 1 +ggs.jp, 1 +ggservers.com, 1 +ggss.cf, 1 +ggworld.ga, 1 +ggx.us, 1 +gh-sandanski.com, 1 +gh16.com.ar, 1 +gha.st, 1 +ghada.blog, 1 +ghanaculture.tk, 1 +gharbala.com, 1 +ghazals.tk, 1 +ghazi.im, 1 +ghbtns.com, 1 +ghcoaching.mx, 1 +ghcpl.in, 1 +ghd.com, 1 +gheestore.in, 1 +ghentcityofmusic.be, 1 +ghentcreativecityofmusic.be, 1 +ghentfilmoffice.be, 1 +ghentholidayland.be, 1 +ghentlichtfestival.be, 1 +ghentlichtfestival.com, 1 +ghentlightfestival.be, 1 +ghentlightfestival.com, 1 +ghentlivinglab.be, 1 +gheorghe-sarcov.ga, 1 +gheorghesarcov.ga, 1 +gheorghesarcov.tk, 1 +ghettonetflix.de, 1 +ghfip.com.au, 1 +ghgkhalsaschool.com, 1 +ghiafeh.com, 0 +ghienlamdep.com, 1 +ghini.com, 1 +ghislainphu.fr, 1 +ghkim.net, 0 +ghobcars.com, 1 +ghobot.ai, 1 +ghobusers.com, 1 +ghostblog.info, 0 +ghostbusters.tk, 1 +ghostbustersuk.tk, 1 +ghostcir.com, 1 +ghostdog.ga, 1 +ghostdragon.tk, 1 +ghostfam.com, 1 +ghostnight.ga, 1 +ghostpin.ga, 1 +ghostridersclan.tk, 1 +ghostruler.com, 1 +ghosts-to-you.tk, 1 +ghostsquad.tk, 1 +ghostutils.tk, 1 +ghostwritershigh.com, 1 +ghou.me, 1 +ghowell.io, 1 +ghprinter.com.br, 1 +ghwconline.org, 1 +ghyvelde.fr, 1 +giac.net, 1 +giac.org, 1 +giacchettaauto.it, 1 +giacomopelagatti.it, 1 +giacomorosaldi.com, 1 +giakki.eu, 0 +giaminh.com, 0 +giancarlomarino.com, 1 +giannademartini.com, 1 +giannifoti.it, 1 +gianproperties.com, 1 +giant-panda.com, 1 +giant-tortoise.com, 1 +giantsquid.tk, 1 +gianttree.de, 1 +giaphaco.com, 1 +giardinaggio.milano.it, 1 +giardinaggio.napoli.it, 1 +giardinaggio.roma.it, 1 +giardiniblog.it, 1 +giardiniere.bologna.it, 1 +giardiniere.milano.it, 1 +giardiniere.roma.it, 1 +giardinoperfetto.com, 1 +giaydantuonghanhphuc.com, 1 +gibberfish.org, 1 +gibbon.tk, 1 +gibraltarwi.gov, 1 +gibranhernandez.tk, 1 +gibreel.tk, 1 +gibsondunn.com, 1 +gichigamigames.com, 1 +gidapgs.cf, 1 +giddyaunt.net, 1 +gidea.nu, 0 +gideonbot.com, 1 +gidive.com, 1 +gidroponica.ml, 1 +giebel.it, 1 +giegler.software, 0 +gielectrical.com.au, 0 +gierds.de, 1 +gieschke.de, 1 +giethoorn.com, 1 +gietvloer-wand.nl, 1 +gietvloergarant.nl, 1 +giff.com.mx, 1 +giftcard.net, 1 +giftcardgranny.com, 1 +giftedconsortium.com, 1 +giftedhealthcare.com, 1 +giftedmodels.com, 1 +giftex.cz, 1 +giftlist.guru, 1 +giftnix.com, 1 +giftofsquare.net, 1 +giftofsquare.org, 1 +gifts.best, 1 +gifts365.co.uk, 1 +giftsera.in, 1 +giftsforaspecialoccasion.com, 1 +giftsholidays.tk, 1 +giftsn.com.sg, 1 +giftsofsquare.com, 1 +giftsofsquare.net, 1 +giftsofsquare.org, 1 +giftya.com, 1 +gifudodo.com, 1 +gifuxuk.tk, 1 +gifzilla.net, 0 +gig-raiffeisen.de, 1 +gig.ru, 0 +gig40.com, 1 +giga.is, 1 +giga.nl, 1 +gigabitz.pw, 1 +gigaclube.com, 1 +gigagroup.cf, 1 +giganet.tk, 1 +gigantar.com, 1 +gigantism.com, 1 +gigaprecos.com.br, 1 +gigasoft.tk, 1 +gigatags.tk, 1 +gigatop.ga, 1 +gigawa.lt, 1 +gigawattz.com, 1 +giggletotz.co.uk, 1 +gigharborwa.gov, 1 +gigiena-ruk.ru, 1 +gigin.eu, 1 +gigin.me, 1 +gigiscloud.servebeer.com, 1 +giglink.club, 1 +gigpam.com, 1 +gigseekr.com, 1 +gijsdeman.nl, 1 +gikovatelojavirtual.com.br, 1 +gil.re, 1 +gilangcp.com, 1 +gilbertosimoni.tk, 1 +gileadpac.com, 1 +gilescountytn.gov, 1 +gilgaz.com, 0 +giliamor.com, 1 +gilion.tk, 1 +gilium.com, 1 +gillesmorelle.com, 0 +gillettechampions.it, 1 +gillettepromociones.com, 1 +gillfamily.de, 1 +gillmanandsoame.co.uk, 1 +gilloteaux.be, 1 +gillyscastles.co.uk, 1 +gilme.net, 1 +gilmourluna.com, 1 +gilnet.be, 0 +gilpincountydronepilot.com, 1 +gilsum-nh.gov, 1 +gim-app.tk, 1 +gimbal.ca, 1 +gimme.money, 1 +gimnazija-skofjaloka.si, 1 +gimnazijapg.me, 1 +gimnazjum-miloslaw.tk, 1 +gimpware.tk, 1 +gina-architektur.design, 1 +ginabaum.com, 1 +ginasiovirtual.com, 1 +ginatony.com, 1 +ginen.xyz, 1 +ginionusedcars.be, 0 +ginitaly.it, 1 +ginn.press, 1 +ginnegappen.nl, 1 +ginniemae.gov, 1 +gino-gelati.de, 1 +gintonic.tk, 1 +ginza-viola.com, 1 +ginzadelunch.jp, 1 +ginzaj.com, 1 +gio-abbigliamento.it, 1 +giochistem.it, 1 +gioielleriamolena.com, 1 +giordano.com, 1 +giovannarossi.tk, 1 +giovannibattistadagnino.eu, 1 +giovannisantini.tk, 1 +giovinco.tk, 1 +gip-carif-idf.net, 1 +gip-carif-idf.org, 1 +gipelpsb.fr, 1 +gipfelbuch.gr, 1 +gipl.tk, 1 +gippert-klein.de, 1 +gipsplitka.ru, 1 +gipuzkoabasket.tk, 1 +giraffeduck.com, 1 +giraffenland.de, 1 +giraffes.org, 1 +giri.co, 1 +girl.click, 1 +girl.science, 1 +girlan.net, 1 +girlfriend.gq, 1 +girlingsdiamond.co.uk, 1 +girlinthetiara.com, 1 +girljacket.com, 1 +girls-heaven.com, 1 +girlsaloudcity.tk, 1 +girlsbar-navi.jp, 1 +girlsforum.com, 1 +girlsgenerationgoods.com, 1 +girlsglimpse.ga, 1 +girlshealth.gov, 1 +girlsky.cn, 1 +girlsnet.work, 1 +girlz.jp, 1 +giroskuter.ga, 1 +girsedesign.de, 1 +girtlak-kanseri.com, 1 +girvas.ru, 1 +gisauto.ru, 1 +gisbornecabs.com.au, 1 +gisellapiano.tk, 1 +gisher.news, 1 +gisher.org, 1 +gisher.video, 1 +gishiko.net, 1 +gisma.tk, 1 +gistportal.com, 1 +gistr.io, 1 +git-stuff.tk, 1 +git.co, 1 +git.market, 1 +git.org.il, 0 +git.sb, 1 +git.tt, 1 +gitar.io, 1 +gitarren-akademie-online.de, 1 +gitch.xyz, 1 +gite-ambleteuse.tk, 1 +gitecolombedesbois.com, 1 +gitedegroupelatruitedor.fr, 1 +gitep.org.uk, 1 +gitesdeshautescourennes.com, 1 +github.blog, 1 +github.com, 1 +githubapp.com, 1 +githubber.com, 1 +githubber.tv, 1 +gitla.in, 1 +gitlab-apps.com, 1 +gitns.com, 1 +gitns.dev, 1 +gitns.io, 1 +gitns.net, 1 +gitns.nl, 1 +gitns.org, 1 +gitstuff.tk, 1 +gittigidiyor.com, 1 +gittr.ch, 1 +giuem.com, 1 +giuliabonati.com, 1 +giuliawylde.com, 1 +giulliamodas.com.br, 1 +giunchi.net, 1 +giuseppemacario.men, 1 +givastar.com, 1 +give.net, 1 +give2charity.co, 1 +give2charityapp.com, 1 +giveamericahope.org, 1 +giveasquare.com, 1 +giveasquare.net, 1 +giveasquare.org, 1 +giveattheoffice.org, 0 +giveme.online, 1 +givemeaverse.com, 1 +givemebeer.tk, 1 +givemeyour.cc, 1 +givemylife.cf, 1 +givemylife.ga, 1 +givemylife.gq, 1 +givemylife.ml, 1 +given2.blog, 1 +given2.com, 1 +given2.me, 1 +given2.us, 1 +given4.it, 1 +giveoneup.org, 1 +givepenny.com, 1 +givesunlight.com, 1 +giveuselife.org, 1 +givingnexus.org, 0 +givingtools.com, 1 +givip.eu, 1 +gix.net.pl, 1 +gixtools.co.uk, 1 +gixtools.com, 1 +gixtools.net, 1 +gixtools.uk, 1 +giyav.org.tr, 1 +gizitalk.com, 1 +gizlilik.org, 1 +gizmo.ovh, 1 +gizmocrazed.com, 1 +gizmodo.com, 1 +gizmodo.es, 1 +gizmodo.in, 1 +gizmolord.com, 1 +gizzo.sk, 0 +gj-bochum.de, 1 +gjan.info, 1 +gjcampbell.co.uk, 1 +gjengset.com, 1 +gjnoonan.co.uk, 1 +gjspunk.de, 0 +gjung.com, 0 +gkasper.de, 1 +gkb2020.ch, 1 +gkconsultancy.tk, 1 +gkepm.com, 1 +gklparis.fr, 1 +gkmusicindia.tk, 1 +gkoenig-innenausbau.de, 1 +gkralik.eu, 1 +gksokol.com, 1 +gkstyle.net, 1 +gku-winterling.de, 1 +gkv-gorinchem.nl, 1 +gkvsc.de, 0 +gl.search.yahoo.com, 0 +glabiatoren-kst.de, 1 +glaciernursery.com, 1 +gladdy.co.uk, 1 +gladdy.uk, 1 +gladdymedia.co.uk, 1 +gladdymedia.com, 1 +gladdymedia.uk, 1 +gladiac.duckdns.org, 1 +gladiators-clan.tk, 1 +gladiatorshop.nl, 1 +gladiium.store, 1 +gladwellentertainments.co.uk, 1 +gladwork.tk, 1 +gladysstrickland.com, 1 +glahcks.com, 1 +glamcosmetic.ch, 1 +glamdaldyreklinikk.no, 1 +glamira.de, 1 +glammybabes.com, 1 +glamour4you.de, 1 +glamourdaze.com, 1 +glamouria.com.br, 1 +glamourmagazine.co.uk, 1 +glamourtime.tk, 1 +glamur-video.com, 1 +glas-systeme.eu, 1 +glasdon.com, 1 +glasen-hardt.de, 1 +glasfaser-im-hanseviertel.de, 1 +glasgeats.co.uk, 1 +glasgestaltung.biz, 1 +glasiko.tk, 1 +glasner.photo, 1 +glaspe.com, 1 +glass.google.com, 1 +glassact.com, 1 +glasschmuck-millefiori.de, 1 +glassemployees.com, 1 +glassexpertswa.com, 1 +glassochchoklad.se, 1 +glassofdirt.tk, 1 +glassofgrape.com, 1 +glassrainbowtrust.org.je, 1 +glassrom.org, 1 +glassrom.pw, 1 +glasstechnics.be, 1 +glassweb.com.mx, 1 +glaswolsite.tk, 1 +glaucoma.uk, 1 +glavfundament.ru, 1 +glavsudexpertiza.ru, 1 +glazedmag.fr, 1 +glazkova.ga, 1 +glcastlekings.co.uk, 1 +gld.re, 1 +gle, 1 +gleam.tk, 1 +gleanview.com, 1 +glebov.tk, 1 +gleich-aluminium-shop.de, 1 +glenavy.tk, 1 +glenbeulahwi.gov, 1 +glencambria.com, 1 +glencarbide.com, 1 +glencoveny.gov, 1 +glendarraghbouncycastles.co.uk, 1 +glenhuntlyapartments.com.au, 1 +glenshere.com, 1 +glenwhitememorial.com, 1 +glevolution.com, 1 +glexia.com, 1 +glgclan.tk, 1 +gliagrumi.it, 1 +glibmarket.in, 1 +glickman-consulting.com, 1 +glidestep.com, 1 +glidingshop.cz, 1 +glidingshop.de, 1 +glidingshop.eu, 1 +gliihc.net, 1 +glimhome.com, 1 +glimpses.tk, 1 +glispecialistidellaprivacy.com, 1 +glit.sh, 1 +glitchcomic.tk, 1 +glitter-graphics.com, 1 +glitterblast.uk, 1 +glittersjabloon.nl, 1 +glitzerstuecke.de, 1 +glixee.com, 1 +glk.academy, 1 +glk.partners, 1 +glloq.org, 0 +glnpo.gov, 1 +gloalerts.com, 1 +global-adult-webcams.com, 1 +global-business-solutions.cf, 1 +global-electronic-music.tk, 1 +global-free-classified-ads.com, 1 +global-monitoring.com, 1 +global-office.com, 0 +global-qanoon.gq, 1 +global-topsecret.tk, 1 +global-village.koeln, 1 +global.my.id, 1 +global1.gg, 1 +globalaccountservice.com, 1 +globalamend.com, 1 +globalautomation.com.co, 1 +globalbridge-japan.com, 1 +globalbusiness.tk, 1 +globalbusinessnews.tk, 1 +globalbusinessrisk.com, 1 +globalcancer.tk, 1 +globalcanineregistry.com, 1 +globalcomix.com, 1 +globalconsulting.ml, 1 +globaldataline.ml, 1 +globalenergyinterconnection.com, 0 +globalentertainment.ga, 1 +globalepsilon.com, 1 +globalexcelsummit.com, 1 +globalformat.de, 1 +globalfuture.eu, 1 +globalgivingtime.com, 1 +globalgovernancewatch.org, 1 +globalhealth.gov, 1 +globalhealthstrategiesnetwork.com, 1 +globalhealthstrategiesnetwork.info, 1 +globalhealthstrategiesnetwork.net, 1 +globalhealthstrategiesnetwork.org, 1 +globalhorses.de, 1 +globalhubb.ro, 1 +globalink.tk, 1 +globalinvestigations.co.uk, 1 +globalipaction.ch, 1 +globalisierung-fakten.de, 1 +globalitac.com, 1 +globalityinvestment.com, 1 +globalizationpedia.com, 1 +globalmaster.com.mx, 1 +globalmed.tk, 1 +globalmoneyapp.com, 1 +globalnewsdaily.cf, 1 +globalnewsnetwork.tk, 1 +globalnewssystems.tk, 1 +globalno.me, 1 +globalnomadvintage.com, 1 +globalobuv.tk, 1 +globalopsgame.tk, 1 +globalpandemictools.com, 1 +globalperspectivescanada.com, 1 +globalpolarbear.com, 1 +globalprojetores.com.br, 1 +globalresearchcouncil.org, 1 +globalresistancecorporation.com, 1 +globalrussia.tk, 1 +globalshares.com, 1 +globalshippinglimited.ga, 1 +globalstar.com, 1 +globaltiendat.com, 1 +globaltix.com, 1 +globaltravel.tk, 1 +globalventil.com, 0 +globalvisions-events.ch, 1 +globalvisions-events.com, 1 +globalvoice.ga, 1 +globalwarmingis.science, 1 +globalwidemedia.com, 1 +globalwitness.org, 0 +globalzone.tk, 1 +globe-brasil.tk, 1 +globeinform.com, 1 +globelink-group.com, 1 +globemusic.es, 1 +globetalent.nl, 1 +globologic.com, 1 +globotech.be, 1 +globotur.de, 1 +globowood.ml, 1 +globuli-info.de, 1 +globus-plus.ml, 1 +globustrust.tk, 1 +glocalworks.jp, 1 +gloeckle-gruppe.de, 1 +glofox.com, 1 +gloning.name, 1 +glont.net, 1 +gloomy.tk, 1 +gloomyspark.com, 1 +glorybee.com, 1 +glorycamrealty.com, 1 +gloryholefucking.com, 1 +glosiko.cn, 1 +glosiko.com, 1 +glosiko.com.cn, 1 +glosiko.net, 1 +glosiko.org, 1 +glosons.com, 1 +glossowiki.ml, 1 +glotech.co.uk, 1 +glotechkitchens.co.uk, 1 +glotechrepairs.co.uk, 1 +glovementor.com, 1 +glow8000.jp, 1 +glowfic.com, 1 +glowstone.net, 1 +glpreparation.com, 1 +glueck-im-norden.de, 1 +gluecksgriff-taschen.de, 1 +glueckskindter.de, 1 +gluecksmomente.boutique, 1 +gluedtomusic.com, 1 +gluhov-ss.ru, 1 +gluit.de, 1 +glutenfreeandtasty.com, 1 +glutenfreehomemaker.com, 1 +glutenfreelife.co.nz, 1 +glutenfreeonashoestring.com, 1 +glutenfreevr.com, 1 +gluto.tk, 1 +glxnet.com, 1 +glyam.nl, 1 +glyburidemetformin.tk, 1 +glyfadacoaststudio.gr, 1 +glykofridis.nl, 1 +glyph.ws, 1 +glyptodon.com, 1 +glytchenergy.com, 1 +glyxins.com, 1 +gm-net.jp, 1 +gm.search.yahoo.com, 0 +gmail, 1 +gmail.com, 0 +gman.bot, 1 +gmanukyan.com, 1 +gmao.com, 1 +gmbh-kiekin.de, 1 +gmc.uy, 1 +gmcbm.net, 1 +gmccar.it, 1 +gmcd.co, 1 +gmcpe.com, 1 +gmdu.net, 1 +gme.one, 1 +gmeet.io, 1 +gmenhq.com, 1 +gmgard.com, 1 +gmind.ovh, 1 +gml4d2.ml, 1 +gmod.de, 1 +gmpark.dk, 1 +gmpartsdb.com, 1 +gmslparking.co.uk, 1 +gmsociety.tk, 1 +gmsurveyingms.com, 1 +gmta.nl, 1 +gmtplus.co.za, 1 +gmuh.fr, 1 +gmw-hannover.de, 1 +gmw-ingenieurbuero.de, 1 +gmx.at, 1 +gmx.ch, 1 +gmx.co.uk, 1 +gmx.com, 1 +gmx.de, 1 +gmx.es, 1 +gmx.fr, 1 +gmx.net, 1 +gn00.com, 1 +gnaptracker.tk, 1 +gnaucke.com, 1 +gnax.jp, 0 +gncsuplementos.com.br, 1 +gndmillwork.com, 1 +gnetion.com, 1 +gnetwork.eu, 1 +gnezdo.tk, 1 +gnfb.be, 1 +gnfrazier.me, 1 +gnhub.org, 1 +gnilebein.de, 1 +gnk.io, 1 +gnmlive.com, 1 +gnom.me, 1 +gnomania.ml, 1 +gnrinfo.tk, 1 +gntfy.us, 1 +gnu.style, 1 +gnuand.me, 1 +gnucashtoqif.us, 1 +gnula2.co, 1 +gnulinux.gq, 1 +gnulinuxforum.tk, 1 +gnuplus.me, 1 +gnuworldorder.ml, 1 +gnwp.eu, 1 +gnylf.com, 1 +go-away.xyz, 1 +go-datasecurity.de, 1 +go-embedded.de, 1 +go-girlonly.shop, 1 +go-go.link, 1 +go-kuwait.tk, 1 +go-life.com.tw, 1 +go-mail.me, 1 +go-propiedades.cl, 1 +go-site.co.uk, 1 +go-srx.tk, 1 +go-wild.co.uk, 1 +go-zh.org, 1 +go.exchange, 1 +go.microsoft.com, 1 +go2archive.nl, 1 +go2people-websites.nl, 1 +go2ubl.nl, 1 +go4golfreizen.nl, 1 +go6.si, 1 +go6lab.si, 0 +go889w.com, 1 +goa8.com, 1 +goa8.xyz, 1 +goabase.com, 1 +goabase.net, 1 +goalbookapp.com, 1 +goalie1998.duckdns.org, 1 +goanalyse.co.uk, 1 +goand.run, 1 +goarmy.eu, 1 +goatbot.xyz, 1 +goatcloud.com, 1 +goatstore.ca, 1 +goaudits.com, 1 +gobarrelroll.com, 1 +gobi.tk, 1 +gobiernousa.gov, 1 +gobiz.com.my, 1 +goblackwood.co.uk, 1 +goblintears.com, 1 +gobouncy.co.uk, 1 +gobouncy.com, 1 +goc4wraps.com, 1 +gocardless.com, 1 +gocdn.com.br, 1 +gocher.me, 1 +gochu.se, 1 +gocleanerslondon.co.uk, 1 +goclix.ml, 1 +gocphongthuy.net, 1 +god-clan.hu, 1 +godalivetpalandet.tk, 1 +godall.tk, 1 +godan.tech, 1 +godating.tk, 1 +godattributes.com, 1 +godaxen.tv, 1 +godbo9.com, 0 +godclan.hu, 1 +goddard.id.au, 1 +goddg.com, 1 +godesigner.ru, 1 +godfilm.tk, 1 +godiscovers.com, 1 +godles.pl, 1 +godmusicapp.com, 1 +godofredo.ninja, 1 +godrealms.com, 1 +godrive.ga, 1 +godruoyi.com, 1 +godsofhell.com, 1 +godsofhell.de, 1 +godstoghosts.com, 1 +goedeke.ml, 1 +goedekortingscodes.be, 1 +goedekortingscodes.nl, 1 +goedkoopstecartridges.nl, 1 +goedkopecartridgeskopen.nl, 1 +goedkopeonesies.nl, 1 +goedkopetaxiservice.nl, 1 +goedkopetonerkopen.nl, 1 +goehler-baumpflege.de, 1 +goeikan.life, 1 +goempyrean.com, 1 +goenea.com, 1 +goerdeler-alumni-club.de, 1 +goerres2014.de, 1 +goetemp.de, 1 +goetic.space, 1 +goettinger-biergarten.de, 1 +goettinger-katzenschutz.de, 1 +goetzinger-web.de, 1 +goffrie.com, 1 +gofigure.fr, 0 +gofile.io, 1 +goflo.net, 1 +gofobo.com, 1 +gofoiayourself.org, 1 +gofoodservice.com, 1 +goforcex.top, 1 +gofriends.cf, 1 +gogem.in, 1 +gogemini.com, 1 +gogetssl.com, 0 +gogle-analytics.com, 1 +gogleapis.com, 1 +gogomail.ga, 1 +gogracego.com, 0 +gogroopie.com, 1 +gogroopie.ie, 1 +gogs.ca, 1 +gogsat.com, 1 +gohanrecords.tk, 1 +gohelixit.com, 1 +gohon.org, 1 +going-dutch.tk, 1 +goingawesomeplaces.com, 1 +goingreen.com.au, 1 +goiymua.com, 1 +goizalde.tk, 1 +gokazakhstan.com, 1 +gokhana.com, 0 +gokhankesici.com, 1 +gokmenguresci.com, 1 +goktoday.com, 1 +gokyrgyzstan.com, 1 +golang.org, 1 +golang.zone, 1 +golayamadam.tk, 1 +gold-bird.tk, 1 +gold-diamondltd.tk, 1 +gold-fm.ml, 1 +gold-iptv.fr, 1 +goldandgopher.com, 1 +goldankauf1875.at, 1 +goldband.tk, 1 +goldbar.com.hk, 1 +goldbug.ga, 1 +goldclubcasino.com, 1 +goldcoast-plumbing.com.au, 1 +goldcoastasian.com, 1 +goldcoasthypnotherapyhypnosis.com.au, 1 +goldcoastphotographycourses.com, 1 +goldcoaststumpbusters.com, 1 +goldcreek.tk, 1 +golden-kamuy.com, 1 +golden-sea.tk, 1 +golden-squad.com, 0 +goldenage.tk, 1 +goldenagefoundation.tk, 1 +goldenbadger.de, 1 +goldenberg.tk, 1 +goldencircle.ga, 1 +goldenclub.ga, 1 +goldencoffee.it, 1 +goldendawnapersonalaffair.com, 1 +goldeneggs.club, 1 +goldengatesports.com, 1 +goldenhillsoftware.com, 1 +goldenhost.ca, 1 +goldenhouse.ga, 1 +goldenowl.ca, 1 +goldenplate.com.sg, 1 +goldenretrieverspets.com, 1 +goldenruleemail.com, 1 +goldenshiny.com, 1 +goldentech.ca, 1 +goldentechelectronics.net, 1 +goldenwolrd.tk, 1 +goldenworldec.com, 1 +goldenyacca.co.uk, 1 +goldenyacca.net, 1 +goldenyacca.org, 1 +goldfelt.com, 1 +goldfingermusic.tk, 1 +goldfm1031.tk, 1 +goldfmromania.ro, 1 +goldhill.ml, 1 +goldminer.ga, 1 +goldnbraces.com, 1 +goldnull.com, 1 +goldpreisfinder.at, 1 +goldsilver.org.ua, 1 +goldskysecurity.com, 1 +goldspace.tk, 1 +goldstandardtrust.tk, 1 +goldstein.rs, 1 +goldstein.tel, 1 +goldsteingloves.com, 1 +goldwater.gov, 1 +goldwaterfoundation.gov, 1 +goldwaterscholarship.gov, 1 +goldytechspecialists.com, 1 +goldzilla.eu, 1 +gole.ms, 1 +golearn.gov, 1 +golestanehali.com, 1 +golestanehali.ir, 1 +golf-supplies.tk, 1 +golf18staging.com, 1 +golfburn.com, 1 +golfhausmallorca.com, 1 +golfmagic.com, 1 +golfrange-ffm.de, 1 +golfscape.com, 1 +golighthouse.com, 1 +golik.net.pl, 0 +golink.co, 1 +golinuxcloud.com, 1 +golnet.hu, 1 +goloaninsurance.tk, 1 +golosok.ml, 1 +golosovanye4you.tk, 1 +golser-schuh.at, 1 +golser.info, 1 +goluggo.com, 1 +golvlyftarna.se, 1 +gomasa.net, 1 +gomasy.jp, 1 +gomasy.net, 1 +gomedium.com, 1 +gomega.vn, 1 +gomel.chat, 1 +gomel.city, 1 +gomelagromashplus.by, 1 +gomelchat.com, 1 +gomelphoto.com, 1 +gomer.tk, 1 +gometa.link, 1 +gomezhvac.com, 1 +gomezites.tk, 1 +gomiblog.com, 1 +gomicrophone.ml, 1 +gommista.roma.it, 1 +gomods.link, 1 +gon45.com, 1 +gonadotropina.com, 1 +goncalves-admredes.cf, 1 +gondawa.com, 1 +gondelvaartdwarsgracht.nl, 1 +gondon.tk, 1 +gonebald.tk, 1 +gonenli.com, 1 +gonepal.com, 1 +gongjianwei.com, 1 +gongjuhao.com, 1 +gonkar.com, 1 +gonumber.ga, 1 +gonx.dk, 0 +gonzalesca.gov, 1 +goo.gl, 1 +gooch.io, 1 +good-cd.ml, 1 +good-course.ga, 1 +good-know.gq, 1 +good-time-to-be.com, 1 +good-wishes-4-u.ga, 1 +goodandsnarky.com, 1 +gooday.life, 1 +goodbot.ru, 1 +gooddayatwork.co.uk, 1 +gooddomainna.me, 1 +goodenglish.ga, 1 +goodfeels.net, 1 +goodgame.lt, 1 +goodgaminggear.com, 1 +goodhealthtv.com, 1 +goodhotel.co, 1 +goodiesnet.ca, 0 +goodiesoft.hu, 1 +goodkitchendesign.com, 1 +goodleads.co.za, 1 +goodlink.ml, 1 +goodmood.co.uk, 1 +goodmood.fr, 1 +goodmoodsocken.de, 1 +goodmorningapril.com, 1 +goodontop.com, 1 +goodopportunity.ga, 1 +goodpeople.tk, 1 +goodryb.top, 1 +goodseed.nl, 1 +goodsex4all.com.br, 1 +goodshepherdmv.com, 1 +goodsite.ga, 1 +goodspeaker.tk, 1 +goodsync.com, 1 +goodth.ink, 1 +goodvibesblog.com, 1 +goodway.tv, 1 +goodwin43.ru, 0 +goodyearsotn.co.uk, 1 +goofy.gr, 1 +google, 1 +google-analytics.com, 1 +google.ax, 1 +googleadvies.nl, 1 +googleandroid.cz, 1 +googlehits.com, 1 +googlemail.com, 0 +googlepinyin.com, 1 +googleplex.com, 1 +googlerecetas.com, 1 +googleshortcuts.org, 1 +googlesource.com, 1 +goole4.com, 1 +goolnk.com, 1 +goombi.fr, 1 +goonersworld.co.uk, 1 +goonfleet.com, 1 +goontopia.com, 0 +goontu.be, 1 +goooo.info, 1 +goop.com, 1 +gooseberries.ch, 1 +goosementor.com, 1 +goosip.tk, 1 +gootax.pro, 0 +gooty.ru, 1 +goover.de, 1 +goow.in, 1 +goozp.com, 1 +goparity.com, 1 +gopass-dev.com, 1 +gopass.health, 1 +gopayz.com.my, 1 +gopet.shop, 1 +gopher.tk, 1 +gophoto.it, 1 +gopkg.link, 1 +gopnikman.cf, 1 +gopostore.com, 1 +gopri.tk, 1 +goproallaccess.com, 1 +gopronow.ga, 1 +goprozone.com, 1 +gopuntaisla.com, 1 +gopwhip.gov, 1 +goquiq.com, 1 +goquiqstatus.com, 1 +gorakhpurclassifieds.tk, 1 +goranrango.ch, 1 +gorbatschow.tk, 1 +gorby.tk, 1 +gordas.cf, 1 +gordeijnsbouw.nl, 1 +gordion.tk, 1 +gordon-reid.com, 1 +gordonbeeming.xyz, 1 +gordonhamilton.com, 1 +gordvorets.tk, 1 +gordyf.com, 1 +gorealya.com, 1 +gorepriest.tk, 1 +gorf.club, 1 +gorgeouslyflawed.com, 1 +gorgias.me, 1 +gorichkata-artplace.com, 1 +goriki.tk, 1 +gorki.tk, 1 +gorky.media, 1 +gorlani.com, 1 +gorlani.net, 1 +gorn.ch, 1 +gornergrat-kulm.ch, 1 +gorod74.ru, 0 +gorodabakan.cf, 1 +gorodabakan.ga, 1 +gorodabakan.gq, 1 +gorodabakan.ml, 1 +gorodabakan.tk, 1 +gorodivanovo.tk, 1 +gorodrabot.ru, 1 +gorodrostov.tk, 1 +gorodruza.tk, 1 +gorodyaroslavl.tk, 1 +goroscop.ml, 1 +goroscope2011.tk, 1 +goroskop-sovmestimosti-znakov.tk, 1 +goroskop-sovmestimosti.ml, 1 +goroskop.gq, 1 +goroskopnew.tk, 1 +gorpg.club, 1 +gorschenin.com, 1 +gorstom.ml, 1 +gosaavd.tk, 1 +gosarh.tk, 1 +goshawkdb.io, 1 +goshin-group.co.jp, 1 +goshow.tv, 1 +gosia-banaszkiewicz.com, 1 +gosiberia.ru, 1 +goskills.com, 1 +gosnipe.com, 1 +gosolockpicks.com, 1 +gospelites.com, 1 +gospellifewc.com, 1 +gospelstreamingsermons.com, 1 +gospelvestcination.de, 1 +gospicers.ca, 1 +gospomedley.com.ng, 1 +gosportweather.co.uk, 1 +gosq.co, 1 +gosq.com, 1 +gossiplolly.com, 1 +gostaffer.com, 1 +gostargazing.co.uk, 1 +gosti-dom.ga, 1 +gostudy.net, 1 +gosu.pro, 1 +goswak.com, 1 +goszakupki.tk, 1 +got-tty.de, 1 +gotajikistan.com, 1 +gotepisodes.tk, 1 +gotgeeks.nl, 1 +gotgenes.com, 0 +gothic.dating, 1 +gothiclandscape.com, 1 +gothicmarketing.tk, 1 +gothicsite.tk, 1 +gothkilts.com, 1 +gotirupati.com, 0 +gotit.com.tw, 1 +gotleanderpi.ddns.net, 1 +goto.archi, 1 +goto.google.com, 1 +goto.msk.ru, 1 +goto.rip, 1 +goto.world, 1 +goto10.se, 1 +gotoals.com, 1 +gotobooks.ml, 1 +gotobrno.cz, 1 +gotoeat-aichi.jp, 1 +gotoexam.tk, 1 +gotolinux.ru, 1 +gotomi.info, 0 +gotorussia.tk, 1 +gotovka.ga, 1 +gotoxy.at, 1 +gotrail.fr, 1 +gotravel.hu, 1 +gotravel.us, 1 +gotrek.com.au, 1 +gotriage.tk, 1 +gotscrapcar.com, 1 +gottcar.com, 1 +gottfridsberg.org, 1 +gottika.com, 1 +goturkmenistan.com, 1 +gotver.tk, 1 +goudenharynck.be, 1 +goudenlaantje.nl, 1 +goudronblanc.com, 1 +goudsbloemonline.nl, 1 +goudt.nl, 1 +gouforit.com, 1 +goug0.com, 1 +goug10.com, 1 +goug11.com, 1 +goug18.com, 1 +goug3.com, 1 +goug4.com, 1 +goug5.com, 1 +goug58.com, 1 +goug6.com, 1 +goug7.com, 1 +goug78.com, 1 +goug8.com, 1 +goug88.com, 1 +goug89.com, 1 +goug99.com, 1 +gougeaway.tk, 1 +gougeul.org, 1 +goukon.ru, 1 +gouldcooksey.com, 1 +gouplinkit.com, 1 +gourgouli.com, 1 +gourmetfestival.de, 1 +gourmetspalencia.com, 1 +gourmetvitamins.ga, 1 +gouthro-goteborg.se, 0 +gov.tc, 1 +gov.uk, 0 +governmentjob.gq, 1 +governmentjobs.gov, 1 +governorhub.com, 1 +goviralnow.ml, 1 +govisitcostarica.co.cr, 1 +govisitcostarica.com, 1 +govloans.gov, 1 +govno-site.tk, 1 +govnohosting.cf, 1 +govnosite.tk, 1 +govorenefekt.com, 1 +govotecolorado.gov, 1 +govotetn.gov, 1 +govtjobs.blog, 1 +govtrack.us, 1 +govype.com, 1 +gow220.ru, 1 +gowancommunications.com, 1 +gowe.wang, 0 +goweraesthetics.co.uk, 1 +gowervets.co.uk, 1 +gowildrodeo.co.uk, 1 +gowithflo.de, 1 +goyumoilexpeller.com, 1 +gozadera.es, 1 +gpalabs.com, 1 +gpastore.com.br, 1 +gpbdev.ru, 1 +gpccp.cc, 1 +gpcp.org, 1 +gpcs.ml, 1 +gpcsolutions.fr, 1 +gpdp.it, 1 +gpfclan.de, 1 +gpfitness.com.br, 1 +gpforum.tk, 1 +gpga.cf, 1 +gpgscoins.com, 1 +gpio.gq, 1 +gpl25.ml, 1 +gplans.us, 1 +gplclubbd.com, 1 +gplintegratedit.com, 1 +gplvilla.com, 1 +gpm.ltd, 1 +gpna.org, 1 +gpolanco.com, 1 +gpony.fr, 1 +gppro.com, 1 +gps-fleettracking.ga, 1 +gps-track-sys.info, 1 +gps.com.br, 1 +gpsarena.ro, 1 +gpsblackbox.com, 1 +gpscamera.nl, 0 +gpsfix.cz, 1 +gpsmith.tech, 1 +gpsnavigator.tk, 1 +gpsolarpanels.com, 0 +gpspolis.nl, 1 +gpsvideocanada.com, 1 +gpswebsoft.ml, 1 +gpu.nu, 0 +gpwmd-portal.org, 1 +gpws.ovh, 0 +gpz500s.tk, 1 +gq-magazine.co.uk, 1 +gqmstore.com.br, 1 +gqyyy.cc, 1 +gr.search.yahoo.com, 0 +gr8engineer2b.com, 1 +gr8ness.com, 1 +gra2.com, 1 +graandco.com, 0 +graasp.net, 0 +grabacabpa.com, 1 +grabadolasermonterrey.com, 1 +grabatt.de, 1 +graberbooks.gq, 1 +grabi.ga, 1 +grabnews.ga, 1 +grabnews.tk, 1 +grace-wan.com, 1 +gracebaking.com, 0 +gracecommunity.school, 1 +gracedays.org, 1 +graceful-project.eu, 1 +gracegensets.com, 1 +graceikahu.com, 1 +graceq.com, 1 +gracethrufaith.com, 1 +gracetini.com, 1 +gracia-club.tk, 1 +graciasmarvin.tk, 1 +gracodesign.eu, 1 +graddient.com, 1 +gradecube.com, 1 +gradedblue.com, 1 +gradenotify.com, 1 +gradienthosting.co.uk, 1 +gradients.com, 1 +gradinacufluturi.ro, 1 +gradle.com, 1 +gradle.org, 1 +grads360.org, 1 +graduados.tk, 1 +gradualgram.com, 1 +graecum.org, 1 +graetgossip.com, 1 +graetintelligence.com, 1 +graetnew.com, 1 +graetnewsnetwork.com, 1 +graetreport.com, 1 +graf-igor.ch, 1 +graf.re, 1 +grafcaps.com, 1 +grafenberg.tk, 1 +graffen.dk, 0 +graffitinetwerk.nl, 1 +graffitiwall.tk, 1 +grafia.ink, 1 +graficasantana.com.br, 1 +graficom.com.ar, 1 +grafik.gq, 1 +grafik.org.ru, 1 +grafimagenpublicidad.com, 1 +grafittikontroll.cf, 1 +grafmag.pl, 1 +grafmurr.de, 1 +grafologia.tk, 1 +grafos.ml, 1 +grafoteka.pl, 1 +grafoterapia.tk, 1 +graft.community, 1 +graft.spb.ru, 1 +graftonglobe.tk, 1 +graftworld.pw, 1 +grahamarthur.com, 1 +grahambaker.ca, 1 +grahamcarruthers.co.za, 1 +grahamcluley.com, 0 +grahamleeonline.com, 1 +grahamsgifts.com, 1 +grahamsmith.tech, 1 +grailify.com, 1 +grain-feature-branch.co, 1 +grain-staging.co, 1 +grain.co, 1 +graingert.co.uk, 1 +gralhaazulcondominio.com.br, 1 +graliv.net, 0 +grallersdegegants.tk, 1 +gram.tips, 0 +gramati.com.br, 1 +grammar.co.id, 1 +grammar.hu, 1 +grammarhouse.co.za, 1 +grammarhouse.me, 1 +grammysgrid.com, 1 +granaturov.mk.ua, 1 +grancellconsulting.com, 1 +grancordobahoy.com.ar, 1 +grand-books.cf, 1 +grand-house.gq, 1 +grand-knighki.gq, 1 +grand-sity.ru, 1 +grandcafeatpark.nl, 1 +grandcafecineac.nl, 1 +grandcafetwist.nl, 1 +grandcapital.cn, 1 +grandcapital.id, 1 +grandcapital.net, 1 +grandcapital.ru, 1 +grandchene.ch, 0 +grandcountydronepilot.com, 1 +grande.coffee, 1 +grandepresion.com, 1 +grandesign.pt, 1 +grandeto.com, 1 +grandi-books.gq, 1 +grandisco.tk, 1 +grandmasfridge.org, 0 +grandmusiccentral.com.au, 1 +grandpad.net, 1 +grandpadusercontent.com, 1 +grandstarcourier.ml, 1 +grandviewheights.gov, 1 +grandwailea.com, 1 +grandworldnghiduong.com, 0 +granfort.es, 0 +granfutbol.com, 1 +granian.pro, 1 +granishe.com, 1 +granit-capital.ga, 1 +graniteind.com, 1 +grannys-stats.com, 1 +grannyshouse.de, 1 +grantashqg.com, 1 +grantcooper.com, 1 +grantdb.ca, 1 +granth.io, 1 +grantmorrison.net, 1 +grantpark.org, 1 +grantsmasters.com, 1 +grantsolutions.gov, 1 +graonatural.com.br, 1 +grapee.jp, 1 +grapeintentions.com, 1 +grapevine.is, 1 +graph.org, 1 +graphcommons.com, 1 +graphe.gq, 1 +graphene.software, 1 +grapheneengine.com, 1 +grapheneos.org, 1 +graphic-schools.com, 1 +graphic-shot.com, 1 +graphicbuffet.co.th, 1 +graphicdesignresources.net, 1 +graphicdream.tk, 1 +graphicspace.tk, 1 +graphicwallet.com, 1 +graphire.io, 1 +graphite.org.uk, 1 +graphobyte.com, 1 +grapholio.net, 1 +graphotism.com, 1 +graphpaper.studio, 1 +graphviewer.tk, 1 +grappes.co, 1 +grappy.net, 1 +grasboom35plus.nl, 1 +grasboomamersfoort.nl, 1 +grasboombinnendoor.nl, 1 +grasboombunschoten.nl, 1 +grasboomclophaemer.nl, 1 +grasboomderoos.nl, 1 +grasboomharmelen.nl, 1 +grasboomleusden.nl, 1 +grasboommax.nl, 1 +grasboommeerbalans.nl, 1 +grasboomveenendaal.nl, 1 +grasboomvondellaan.nl, 1 +grasengroenkunstgras.nl, 1 +grasmark.com, 1 +grasp24.pl, 1 +graspingtech.com, 1 +grasscity.com, 1 +grassenberg.de, 1 +grasshoppervape.com, 1 +grasso.io, 1 +grassreinforcement.com.au, 1 +grast.jp, 1 +gratis-app.com, 1 +gratis-hosting.cf, 1 +gratis.market, 1 +gratisgamecards.nl, 1 +gratishandy.tk, 1 +gratisonlinespel.tk, 1 +gratisparati.tk, 1 +gratisrollenspieltag.de, 1 +gratitudeabundancepassion.com, 1 +gratius.tk, 1 +grattan.co.uk, 1 +gratuitweb.tk, 1 +graumeier.de, 1 +grauwasser-blog.de, 1 +gravedigger.tk, 1 +gravelshooters.com, 1 +gravelshooters.net, 1 +gravelshooters.org, 1 +gravely.com, 1 +gravensteengent.be, 1 +gravescountyky.gov, 1 +gravilink.com, 1 +gravirovshik.ru, 1 +gravitascreative.net, 1 +gravitlauncher.ml, 1 +gravity-inc.net, 1 +gravityfitness-tennis.com, 1 +gravityformspdfextended.com, 1 +gravitypdf.com, 1 +gravityresearchgroup.ga, 1 +grawe-blog.at, 1 +graycat.ml, 1 +grayhatter.com, 1 +grayiron.io, 1 +graylou.com, 1 +grayowlworks.com, 1 +grayrectangle.com, 1 +grayson.sh, 1 +graysonsmith.co.uk, 1 +graz2020.com, 1 +grazetech.com, 1 +grazhdanskij-advokat.tk, 1 +grazitti.com, 1 +grc.com, 0 +grceurope.eu, 1 +grday.com, 1 +great.nagoya, 1 +greatagain.gov, 1 +greataltrock.tk, 1 +greatbarrierisland.nz, 1 +greatepier.tk, 1 +greatergood.com, 0 +greaterreadingyp.org, 1 +greaterswissmountaindogs.com, 1 +greatfire.kr, 1 +greatfire.org, 1 +greatgooglymoogly.tk, 1 +greathairtransplants.com, 1 +greatislandarts.ca, 1 +greatlifeinsurancegroup.com, 1 +greatlms.com, 1 +greatmazes.tk, 1 +greatnetsolutions.com, 1 +greatpages.com.br, 1 +greatplainsaustralia.com.au, 1 +greatrenumbering.tk, 1 +greatscholars.tk, 1 +greatsoftwares.com.br, 1 +greatwebdesign.uk, 1 +greciahora.com, 1 +greditsoft.com, 1 +greek.dating, 1 +greeklish.gr, 1 +greekmusic.academy, 1 +greeknewspapers.tk, 1 +greeks.tk, 1 +greekweb.tk, 1 +green-adn.com, 1 +green-anarchy.tk, 1 +green-attitude.be, 1 +green-aura.ru, 0 +green-care.nl, 1 +green-factory.ml, 1 +green-laser.ga, 1 +green-laser.ml, 1 +green-light.co.nz, 1 +green-light.ml, 1 +green-techno.ru, 1 +greenaddress.it, 1 +greenangels.com.ua, 1 +greenapproach.ca, 1 +greenartistsswiss.ch, 1 +greencapital.gent, 1 +greencircleplantnursery.com.au, 1 +greencircleplantnursery.net.au, 1 +greencocktail.ga, 1 +greencross.cf, 1 +greencyprus.com, 1 +greendotcc.com, 1 +greendotgames.com, 1 +greendragonsearch.tk, 1 +greendrive.tk, 1 +greendvorik.com.ua, 1 +greenearthlawns.com, 1 +greenecountyny.gov, 1 +greenecountyohio.gov, 1 +greenecountytn.gov, 1 +greener.pl, 1 +greenews.ga, 1 +greenforum.tk, 1 +greengarden.tk, 1 +greengates.co.uk, 1 +greengoblindev.com, 1 +greengorych.ru, 1 +greengov.gov, 1 +greengrocery.tk, 1 +greenhats.de, 1 +greenhillhosting.com, 1 +greenhous-technology.tk, 1 +greenkey.gent, 1 +greenland-estate.tk, 1 +greenliquidsystem.com, 1 +greenliv.pl, 1 +greenlungs.net, 1 +greenoutdoor.dk, 0 +greenpal.jp, 1 +greenpanda.de, 1 +greenpark.uz, 1 +greenpartyofnewmilford.org, 1 +greenpaws.ee, 1 +greenpeace.berlin, 1 +greenponik.com, 1 +greenroach.ru, 1 +greenroom.tk, 1 +greenrushdaily.com, 1 +greensad36.ru, 1 +greensborosecuritycameras.com, 1 +greensdictofslang.com, 1 +greensidevetpractice.co.uk, 1 +greensilllatam.com, 1 +greensph.tk, 1 +greensquare.tk, 1 +greenstreethammers.com, 1 +greentea.ml, 1 +greenteamtwente.nl, 1 +greenturtledev.net, 1 +greenway-moskva.ru, 1 +greenway-moving.com, 1 +greenwaylog.net, 1 +greenwiki.ca, 1 +greenwithdecor.com, 1 +greenyflowers.co.uk, 1 +greenytimes.com, 1 +greenyway.com, 1 +greenzved.tk, 1 +greer.ru, 1 +greg.red, 1 +gregbonner.ca, 1 +gregbonner.com, 1 +gregbrimble.com, 1 +greger.me, 1 +gregfoat.co.uk, 1 +greggsfoundation.org.uk, 1 +greghouse.tk, 1 +gregmartyn.com, 1 +gregmarziomedia.com, 1 +gregmc.ru, 1 +gregmilton.com, 1 +gregmilton.org, 1 +gregmote.com, 1 +grego.pt, 1 +gregoirow.be, 0 +gregorians.org, 1 +gregorkofler.com, 1 +gregory-kramer.fr, 1 +gregory-thibault.com, 1 +gregorydorrifourt.fr, 1 +gregorykelleher.com, 1 +gregoryrealestategroup.com, 1 +gregorywiest.com, 1 +gregproffit.com, 1 +greice.de, 1 +greiner-it.de, 1 +greinerj.de, 1 +grekiskagudar.tk, 1 +grenade.ga, 1 +grenadiercorps-kaarst.de, 1 +grenadiere-kaarst.de, 1 +grenadierkorps-kaarst.de, 1 +grenadierkorps.de, 1 +grend.gq, 1 +grendel.no, 1 +grengine.ch, 1 +grenlan.com, 1 +grenlandkiropraktor.no, 1 +grenoblepartners.com, 1 +grepmaste.rs, 0 +grepular.com, 1 +gresak.io, 0 +gresik.info, 1 +gresik.org, 1 +gressnet.id, 1 +greta-birkner.de, 1 +gretathemes.com, 1 +greuel.online, 1 +grevesgarten.de, 1 +grexx.today, 1 +greybazar.com, 1 +greybeards.ca, 1 +greycrane.net, 1 +greyhackcentral.gq, 1 +greyhash.se, 1 +greymattertechs.com, 1 +greypanel.com, 1 +greyrectangle.com, 1 +greysky.me, 1 +greyskymedia.com, 1 +greysolutions.it, 1 +greystonesmovement.com, 1 +greystonesscouts.tk, 1 +greywalker.tk, 1 +greywolf.cz, 1 +grh.am, 1 +grhhosting.com, 1 +griassdi-reseller.de, 1 +gricargo.com, 1 +grickle.org, 1 +gridky.com, 1 +gridly.nl, 1 +gridpack.org, 1 +gridspace.ca, 1 +gridtennis.net, 1 +griechische-pfoetchen.de, 1 +griecopelino.com, 1 +griefheart.com, 1 +grieg-gaarden.no, 1 +grieg.com, 1 +grieg.net, 1 +grieg.no, 0 +grieg.org, 1 +grieglogistics.no, 1 +griegshipbrokers.com, 1 +griegshipbrokers.no, 1 +griendencollege.tk, 1 +grienenberger.eu, 1 +griesser2.de, 1 +griffinli.com, 0 +griffinsrfc.tk, 1 +griffioenconsulting.com, 1 +grifomarchetti.com, 1 +grigorev.tk, 1 +grijpskerk500.tk, 1 +grillen-darf-nicht-gesund-sein.de, 1 +grillfocused.com, 1 +grilllness.com, 1 +grillteller42.de, 1 +grimcalc.com, 1 +grimetoshinecleaners.co.uk, 1 +grimm-gastrobedarf.de, 1 +grimm.cz, 1 +grimmhome.com, 1 +grimms-schuhe.de, 1 +grimstveit.no, 1 +grinday.tk, 1 +grindgore.tk, 1 +grinmore.com, 1 +grinnellplanes.com, 1 +grinnellplans.com, 1 +grinpis.tk, 1 +gripcoat.jp, 1 +gripeh1n1.com, 1 +gripencrossfit.gq, 1 +gripnijmegen.rip, 1 +gripwenab.cf, 1 +grishavirus.cf, 1 +gritte.ch, 1 +grittherapeutic.com, 1 +griyo.online, 1 +grizz.gdn, 1 +grizzlead.com, 1 +grizzlys.com, 1 +grizzlys.tk, 1 +groben-itsolutions.de, 1 +grockradio.ga, 1 +grocock.me.uk, 1 +groenaquasolutions.nl, 1 +groenemoskeeen.nl, 1 +groenlinks.nl, 1 +groentebesteld.nl, 1 +groenteclub.nl, 0 +groentefruitzeep.com, 1 +groentefruitzeep.nl, 1 +groep20.nl, 1 +groepjam-usedcars.be, 0 +grog.pw, 1 +grokker.com, 1 +groklearning.com, 1 +grolimur.ch, 0 +gromovphotography.tk, 1 +gronau-it-cloud-computing.de, 1 +grondius.com, 1 +groningerkustvaart.tk, 1 +groomershop.ru, 0 +groomlake.tk, 1 +groomscroft.co.uk, 1 +groomscroft.com, 1 +grootinadvies.nl, 1 +groots.com, 1 +groots.ngo, 1 +groover.com.br, 1 +groovydisk.com, 1 +groovygoldfish.org, 1 +gropp.org, 1 +gross.business, 1 +grossberger-ge.org, 0 +grossell.ru, 1 +grosser.io, 1 +grossiste-marcassite.com, 1 +grossmisconduct.news, 1 +grossorders.com, 1 +groszek.pl, 1 +grotesk.tk, 1 +groth.im, 1 +groth.xyz, 1 +grothoff.org, 1 +grottalchemica.it, 1 +grottenthaler.eu, 1 +grouchysysadmin.com, 1 +groundengenharia.com, 1 +groundfm.tk, 1 +groundhogg.nl, 1 +groundmc.net, 1 +groundsdirect.com, 1 +groundspan.com, 1 +groundthumpingmotors.com, 1 +groundthumpingmotors.net, 1 +groundthumpinmotors.com, 1 +groundthumpinmotors.net, 1 +group4layers.net, 1 +groupdcc.com, 1 +groupe-erige.com, 1 +groupe-neurologique-nord.lu, 1 +groupeatrium.net, 1 +groupeifams.sn, 1 +groupescr.fr, 1 +groupghistelinck-cars.be, 0 +groupme.com, 1 +groupramirez.com, 1 +groups.google.com, 1 +groupseslogistic.com, 1 +groupx.tk, 1 +grove-archiv.de, 1 +grovecity.ml, 1 +grovesales.co.uk, 1 +growebmarketing.com, 1 +growik.com, 1 +growingallthings.co.uk, 1 +growinghumankindness.com, 1 +growingmetrics.com, 1 +growingsearch.com, 1 +growingsmiles.co.uk, 1 +growme.gq, 1 +growth-rocket.com, 1 +growthagent.com, 1 +growthandrenewal.ca, 1 +growthinbusiness.com, 1 +growthlab.com.my, 1 +growthseedconsulting.com, 1 +growwithdaylight.co.uk, 1 +growy.ch, 0 +grozter.se, 1 +grrmmll.com, 1 +grsecurity.net, 1 +grsstore.it, 1 +grthomes.com, 1 +gruasiturra.cl, 1 +gruaskmsa.cl, 1 +gruasllanos.cl, 1 +gruber-software.com, 0 +gruebebraeu.ch, 1 +grueberstein.de, 1 +gruelang.org, 1 +gruenderlehrstuhl.de, 1 +gruene-im-rvr.de, 1 +gruene-linde-schwimmen.tk, 1 +gruene-wattenscheid.de, 1 +gruener-salon-bochum.de, 1 +gruenes-wp.de, 1 +gruenprint.de, 1 +gruenstreifen-ev.de, 1 +gruhn.email, 1 +grummittgroundworks.co.uk, 1 +grumpy.fr, 1 +grumpygamers.com, 1 +grumpyguy.ga, 1 +grumpyseb.com, 1 +grundig.co.uk, 1 +grundlage.com.ua, 1 +grundlage.fi, 1 +grundschule-mittelbuch.de, 1 +grundskoleboken.tk, 1 +grundycountyiowa.gov, 1 +grunex.com, 0 +grunlab.net, 1 +grunwaldzki.center, 1 +grunwasser.com, 1 +grunwasser.fr, 1 +grupatvogzivota.tk, 1 +grupdedansa.tk, 1 +gruper.mk, 1 +grupo-famia.tk, 1 +grupo-zoom.com, 1 +grupoalpi.com, 1 +grupoauxteclic.com, 1 +grupocata.com, 1 +grupodatco.com, 1 +grupodecoroinhaspnsa.tk, 1 +grupodepasajeros.tk, 1 +grupoellatu.tk, 1 +grupoenelcolombia.com, 1 +grupogabinet.es, 1 +grupoharbour.com, 1 +grupoinassa.com, 1 +grupoiwana.tk, 1 +grupomanquecura.tk, 1 +grupomedlegal.com, 1 +grupoparco.com, 1 +grupoproabienesraices.com.mx, 1 +grupos.cf, 1 +gruposanjose.tk, 1 +gruposiit.com.mx, 1 +gruppa.ml, 1 +gruppa.net, 1 +gruppakolibri.ml, 1 +grurez.com, 1 +gruslic.org.mx, 1 +gruveo.com, 1 +gruver.de, 1 +gruwa.net, 1 +gruzchiki.ml, 1 +gruzchiki74.tk, 1 +gruzinfo.tk, 1 +gruzoperevozki.ml, 1 +grwebdesigns.gr, 1 +gryffin.ga, 1 +gryffin.ml, 1 +gryffin.tk, 1 +gryphonfinancialsolutions.com, 1 +gryphzia.cf, 1 +gryte.tk, 1 +gs-pflege.de, 1 +gs93.de, 0 +gsa-online.de, 1 +gsa.gov, 1 +gsaadvantage.gov, 1 +gsaauctions.gov, 1 +gsaj114.net, 1 +gsaxcess.gov, 1 +gsbolivia.com, 1 +gscgh.com, 1 +gscloud.xyz, 1 +gse.space, 1 +gservera.com, 1 +gsfreak.pt, 1 +gsimagebank.co.uk, 1 +gsiw.be, 1 +gsiw.gent, 1 +gslabnet.org, 1 +gslink.me, 1 +gsm-info.tk, 1 +gsmbrick.com, 1 +gsmkungen.com, 1 +gsmpreview.com, 1 +gsmsale.nl, 1 +gsmsecurity.net, 1 +gsoc.se, 1 +gsoluzioniweb.it, 1 +gsrc.io, 1 +gst.name, 1 +gst.priv.at, 1 +gt-himmel.com, 1 +gta-arabs.com, 1 +gtacty.co, 1 +gtaforum.nl, 1 +gtagames.nl, 1 +gtamoney.net, 1 +gtapg.net, 1 +gtcountymi.gov, 1 +gtcprojects.com, 1 +gtd.cloud, 1 +gtdgo.com, 0 +gti.cx, 1 +gtlaun.ch, 1 +gtlfsonlinepay.com, 1 +gtmetrix.com, 1 +gtmhub.com, 1 +gtn-pravda.ru, 1 +gtoepfer.de, 1 +gtonline.ml, 1 +gtopala.net, 1 +gtour.info, 0 +gtravers-basketmaker.co.uk, 1 +gtrwebdesign.nl, 1 +gtsoftware.gr, 1 +gtupgrade.eu, 1 +gtxbbs.com, 1 +gtxmail.de, 1 +guadagnare.info, 1 +guadalinfoconlaroja.tk, 1 +guadaluperoses.co, 1 +guajars.cl, 1 +guangjiangk.com, 1 +guanyu.ml, 1 +guanzhong.ca, 1 +guaranteedfitdanceshoes.com, 1 +guaranteedfittangoshoes.com, 1 +guaranteedservice.company, 1 +guardando.tk, 1 +guardedbox.com, 1 +guardedbox.es, 1 +guarderiajackson.tk, 1 +guardiabermellon.tk, 1 +guardian-codex.tk, 1 +guardian360.nl, 1 +guardianportal.us, 1 +guardiansoftheearth.org, 1 +guardiapretoriana.tk, 1 +guarrato.tk, 1 +guategmala.ga, 1 +guayaquil-consort.tk, 1 +gubagoo.com, 1 +gubagoo.io, 1 +gubernia37.ml, 1 +guberniya.net, 1 +gubka.ga, 1 +gudangpangan.id, 1 +gudbrand.no, 1 +gudini.net, 1 +gudrun.ml, 1 +gudrunfit.dk, 1 +guegan.de, 1 +guejarsierra.tk, 1 +guelo.ch, 1 +guelphhydropool.com, 1 +guendra.dedyn.io, 1 +guenther-freitag.tk, 1 +guenthereder.at, 1 +guerard.info, 1 +guercioarchitecture.com, 1 +guernica1913.tk, 1 +guernseycounty.gov, 1 +guerra24.net, 1 +guerrasgalacticas.tk, 1 +guerrillaradio.tk, 1 +guessmatch.com, 1 +guestby.tk, 1 +guesthouse-namaste.com, 1 +guesthouse.tk, 1 +guestnetscript.tk, 1 +guestofhonor.tk, 1 +guevener.de, 1 +gueze-ardeche.fr, 1 +gueze-sas.fr, 1 +gufen.ga, 1 +guffr.it, 1 +gugaltika-ipb.org, 0 +gugcstudentguild.com.au, 1 +guge.ch, 1 +gugert.net, 1 +gugs.tk, 1 +gugu-game.tk, 1 +guhei.net, 1 +guhenry3.tk, 1 +guiacg.com, 1 +guiadamassagem.site, 1 +guiadeprofesionales.com.ar, 1 +guiadev.com, 1 +guiaextra.com, 1 +guiaminhasaude.net, 1 +guiascliente.com, 1 +guiasdemexico.tk, 1 +guiasescapate.tk, 1 +guiaswow.com, 1 +guiaturismovallarta.com, 1 +guiaturisticanuevayork.com, 1 +guid2steamid.com, 1 +guid2steamid.pw, 1 +guide-ecole.ch, 1 +guide-peche-cantal.com, 0 +guide-voyage.ga, 1 +guidebook.co.tz, 1 +guidechecking.com, 1 +guidedselling.net, 1 +guidedsteps.com, 1 +guideline.gov, 1 +guidelines.gov, 1 +guideo.ch, 0 +guides-peche64.com, 1 +guidesacademe.com, 1 +guidesetc.com, 1 +guidesorbetiere.com, 1 +guidethailande.tk, 1 +guidetoiceland.is, 1 +guidetourism.tk, 1 +guidopedia.ga, 1 +guilde-dissection.com, 1 +guildgearscore.cf, 1 +guillaume-briand.fr, 1 +guillaumecote.me, 1 +guillaumematheron.fr, 1 +guillaumeperrin.io, 1 +guillaumepommier.com, 1 +guillemagullo.tk, 1 +guillemaud.me, 0 +guillen.tk, 1 +guim.co.uk, 1 +guineapig101.com, 1 +guineapigmustach.es, 1 +guinguetteclovis.com, 1 +guise.tk, 1 +guitar-strings-online.tk, 1 +guitarangel.tk, 1 +guitards.tk, 1 +guitarefacile.tk, 1 +guitarfreak.tk, 1 +guitarraclasica.tk, 1 +guitarreria.tk, 1 +guitarristaluisquintero.com, 1 +gujun-sky.com, 1 +gulabovski.ga, 1 +gulchuk.com, 1 +gulcinulutuna.com, 1 +gulenbase.no, 1 +gulfcoastwaterauthoritytx.gov, 1 +gulfstream.ru, 1 +gulfvestors.com, 1 +gulfwings.com, 1 +gulleyperformancecenter.com, 1 +gulliwer.tk, 1 +gulshankumar.net, 1 +gulsot.tk, 1 +gumbles.tk, 1 +gumbo-millennium.nl, 1 +gumbo.gq, 1 +gumbo.nu, 1 +gumbointro.nl, 1 +gumeyamall.jp, 1 +gumi.ca, 1 +gummibande.noip.me, 0 +gummientchen.net, 1 +gun321.com, 1 +gunarupa.com, 1 +gunauc.net, 1 +gundemguncel.tk, 1 +gunerds.com.br, 1 +gunhunter.com, 1 +gunlaketribe-nsn.gov, 1 +gunlukburc.net, 1 +gunsofshadowvalley.com, 1 +gunstatus.net, 1 +gununsesi.info, 1 +gununsesi.org, 1 +gununsesiaz.info, 1 +gunwatch.co.uk, 1 +gunworld.com.au, 1 +gunz.net, 1 +gunziefolleto.tk, 1 +gunzreplays.com, 1 +guochang.fun, 1 +guochang.xyz, 1 +guogetv.com, 1 +guohuageng.com, 1 +guoke.com, 1 +guolaoban.xyz, 1 +guolaw.ca, 1 +guoliang.me, 1 +guoliangwu.com, 1 +gupfen.ch, 1 +gurkenberry.ddns.net, 0 +gurleyal.gov, 1 +gurmel.ru, 1 +guru-naradi.cz, 1 +guruakuntansi.co.id, 1 +guruarchive.com, 1 +gurucomi.com, 1 +gurueffect.com, 1 +gurugardener.co.nz, 1 +gurumobile.tk, 1 +gurunanakdarvar.tk, 1 +gurunpa.com, 1 +gururi.com, 1 +guruwebseo.com, 1 +guruworld.tk, 1 +gus.host, 1 +gus.moe, 1 +gusli.net, 1 +gusmiller.org, 1 +guso.gq, 1 +gustaff.de, 1 +gustarfsberg.tk, 1 +gustavapp.com, 1 +gustavo-lima.ml, 1 +gustavo.website, 1 +gustavovelasco.ml, 1 +gustavscelmins.tk, 1 +gustiaux.com, 0 +gustom.io, 0 +gustomsc.com, 1 +gusuraman.tk, 1 +gutegutscheine.at, 1 +gutegutscheine.ch, 1 +gutegutscheine.de, 1 +gutendag.ga, 1 +gutetexte.tk, 1 +guthabenkarten-billiger.de, 1 +gutieli.com, 1 +gutools.co.uk, 1 +guts.me, 1 +guts.moe, 1 +gutschein-spezialist.de, 1 +gutscheinemagic.de, 1 +gutscheingeiz.de, 1 +gutterbus.com, 1 +gutterdogs.com, 1 +gutterguardcharlotte.com, 1 +guttershutter.biz, 1 +gutuia.blue, 1 +guus-thijssen.nl, 1 +guvernalternativa.ro, 1 +guyeskens.be, 1 +guyfletcher.com, 1 +guys-reviews.ml, 1 +guysauto.com, 1 +guytarrant.co.uk, 1 +guythomasevans.co.uk, 1 +guyuy.com, 1 +guzdek.co, 1 +guzelforum.tk, 1 +guzelresim.tk, 1 +guzey.me, 1 +guzlewski.pl, 1 +gv-neumann.de, 1 +gv-salto.nl, 1 +gvaa.nl, 1 +gvatas.in, 1 +gvc-it.tk, 1 +gvchannel.xyz, 1 +gveh.de, 1 +gvi-timing.ch, 0 +gviedu.com, 1 +gvirtualclassroom.com, 1 +gvitebsk.cf, 1 +gvitiming.ch, 0 +gvobgyn.ca, 1 +gvoetbaldagenalcides.nl, 1 +gvp.co.in, 1 +gvt2.com, 1 +gvt3.com, 1 +gvwgroup.cloud, 1 +gvwgroup.com, 1 +gvwparts.com, 1 +gw2efficiency.com, 1 +gw2treasures.com, 1 +gw2zone.net, 0 +gw66.cc, 1 +gwandalancobras.com.au, 1 +gwbet99.cc, 1 +gwennyeeckels.com, 1 +gwerder.net, 1 +gwg-march.ch, 1 +gwhois.org, 1 +gwo24.pl, 1 +gworld.cf, 1 +gwrtech.com, 1 +gwsec.co.uk, 1 +gwthub.com, 1 +gwy15.com, 1 +gwynfryncottages.com, 1 +gxgx.org, 1 +gxlrx.net, 1 +gxm5.com, 1 +gxmyqy.net, 1 +gyannews.ga, 1 +gyas.nl, 1 +gybol.com, 1 +gyefund.com, 1 +gyefund.org, 1 +gyengus.hu, 1 +gylly.net, 1 +gyllyngvase.com, 1 +gymagine.ch, 1 +gymbase.ml, 1 +gymbunny.de, 1 +gymhero.me, 1 +gymkirchenfeld.ch, 1 +gymlife.fr, 1 +gymnaserenens.ch, 0 +gymnasium-farmsen.de, 1 +gymnasium-hittfeld.de, 1 +gymnasium56.tk, 1 +gymnastic.ga, 1 +gymnastic.tk, 1 +gymnastikfitness.se, 1 +gymnchod.cz, 1 +gympap.de, 1 +gympass.com, 1 +gynaecology.co, 1 +gynoguide.com, 1 +gyongyosi.ga, 1 +gyoriedes.hu, 1 +gyoza.beer, 1 +gypsyreel.com, 1 +gyre.ch, 0 +gyrenens.ch, 0 +gyroscopicinvesting.com, 1 +gyu-raku.jp, 1 +gyulakerezsi.ro, 1 +gz-architekten.de, 1 +gz-benz.com, 1 +gz-bmw.com, 1 +gza.jp, 1 +gzitech.com, 1 +gzitech.net, 1 +gzitech.org, 1 +gzlivre.org, 1 +gzom.ru, 1 +gzonemu.ga, 1 +h-jo.net, 1 +h-maxton.de, 1 +h-server.myfirewall.org, 1 +h-var.com, 1 +h001.ru, 0 +h09.eu, 1 +h0r.st, 1 +h0u5er.com, 1 +h10l.com, 1 +h10s.net, 1 +h11.io, 1 +h11.moe, 1 +h1ctf.com, 1 +h1z1swap.com, 1 +h2020faros.eu, 1 +h24.org, 1 +h2b.me, 1 +h2cclipboard.com, 1 +h2cdn.cloud, 1 +h2orto.it, 1 +h2ox.io, 1 +h2rul.eu, 1 +h2u.tv, 1 +h30365.com, 1 +h36533.com, 1 +h3artbl33d.nl, 1 +h3b.nl, 1 +h3x.jp, 0 +h3x.net, 1 +h404bi.com, 1 +h51365.com, 1 +h5197.co, 1 +h5q.net, 1 +h6729.co, 1 +h6729.com, 1 +h6852.com, 1 +h6853.com, 1 +h6913.com, 1 +h6957.co, 1 +h6p.de, 1 +h81365.com, 1 +h82365.com, 1 +h8p.de, 1 +h9297.co, 1 +h9397.com, 1 +h9728.co, 1 +ha-blog.tw, 1 +ha-kunamatata.de, 1 +ha.com, 1 +ha3.eu, 1 +ha6.ru, 1 +haakonbecker.de, 1 +haaldesignpro.com, 1 +haancommunity.cf, 1 +haarigerrattenarsch.com, 1 +haarlemsesaxofoonschool.nl, 1 +haarstudiok99.nl, 1 +haasonline.tk, 1 +haavard.me, 1 +hab.dynu.net, 1 +habahaba.tk, 1 +habarimail.com, 1 +habarisoft.com, 1 +habarovsk.ml, 1 +habbig.cc, 1 +habbixed.tk, 1 +habbolibres.tk, 1 +habboz.com.br, 1 +habbstars.org, 1 +habeo.si, 1 +haberer.me, 1 +habernet.tk, 1 +haberton.com, 1 +haberver.me, 1 +habesha.bet, 1 +habeychlab.com, 1 +habibhidayat.com, 1 +habitable.ga, 1 +habitat-domotique.fr, 1 +habitatetbatiment.fr, 1 +habitiss.be, 1 +hablemosclaro.blog, 0 +hablemosdenutricion.com, 1 +habr.com, 1 +habr.ee, 1 +habrastorage.org, 1 +habtium.es, 1 +hac2er.net, 1 +hacc.top, 1 +haccp.bergamo.it, 1 +haccp.milano.it, 1 +haccp.roma.it, 1 +hacerjabon.com, 1 +hacertest.com, 1 +hachette-collections.com, 1 +hachimijiogan.info, 1 +hachre.de, 0 +hacifadilogullari.com.tr, 1 +hack-bang.com, 1 +hack-forum.ml, 1 +hack.club, 1 +hack.fi, 1 +hackade.org, 1 +hackademix.net, 1 +hackadena.com, 1 +hackanders.com, 1 +hackathonbridge.com, 1 +hackathonjr.tw, 1 +hackathontwjr.ml, 1 +hackattack.com, 1 +hackbarth.guru, 1 +hackbeil.name, 1 +hackbubble.me, 1 +hackclubmauritius.nl, 1 +hackcraft.net, 1 +hackdown.tech, 1 +hackeado.tk, 1 +hacked.com, 1 +hackedaf.com, 1 +hackendoz.com, 1 +hackengine.ga, 1 +hackenkunjeleren.nl, 1 +hackenturet.dk, 1 +hacker.club, 1 +hacker.deals, 1 +hacker.holiday, 1 +hacker.im, 1 +hacker.one, 1 +hacker1.com, 1 +hacker101.com, 1 +hacker8.cn, 0 +hackerchai.com, 0 +hackerco.com, 1 +hackercommunity.org, 1 +hackereyes.com, 1 +hackerflare.com, 1 +hackerforums.tk, 1 +hackergateway.com, 1 +hackerinfo.ml, 1 +hackernews.ddns.net, 1 +hackernotice.com, 1 +hackerone-ext-content.com, 1 +hackerone-user-content.com, 1 +hackerone.at, 1 +hackerone.blog, 1 +hackerone.com, 1 +hackerone.events, 1 +hackerone.live, 1 +hackerone.net, 1 +hackerone.org, 1 +hackers-networks.tk, 1 +hackerschat.net, 1 +hackerspace.rocks, 1 +hackersw0rld.tk, 1 +hackerzbug.tk, 1 +hackettrecipes.com, 1 +hackforgood.com, 1 +hackgins.com, 1 +hackhouse.sh, 1 +hackingand.coffee, 0 +hackingdh.com, 1 +hackingfever.tk, 1 +hackingvision.com, 1 +hackintosh.eu, 1 +hackmd.io, 1 +hackmeifyoucan.site, 1 +hackney.tk, 1 +hackops.tk, 1 +hackreone.com, 1 +hackrepreneur.com, 1 +hacksecu.re, 1 +hacksoc.co.uk, 1 +hackthat.tk, 1 +hackthecat.com, 1 +hackthehacker.ml, 1 +hackthissite.org, 1 +hacktic.info, 1 +hacktivis.me, 1 +hacktivitycon.com, 1 +hacktober.dk, 1 +hackworx.com, 0 +hackyourfaceoff.com, 1 +hackzogtum-coburg.de, 0 +hadaly.fr, 1 +hadelandgjestegard.no, 1 +haderecker.me, 1 +hadibut.fr, 1 +hadika.tk, 1 +hadleyluker.com, 1 +hadouk.in, 1 +hadouken.tk, 1 +hadrons.org, 1 +hady.fr, 1 +haeckdesign.com, 1 +haefligermedia.ch, 1 +haehnel.xyz, 0 +haehnlein.at, 1 +haemka.de, 1 +haemmerle.net, 1 +haens.li, 1 +haerwu.biz, 1 +hafer.tech, 1 +haferman.net, 1 +haferman.org, 1 +hafizkadir.tk, 1 +hafniatimes.com, 1 +hag27.com, 1 +hagbergmedia.se, 1 +haggeluring.su, 1 +haggisofnorway.tk, 1 +hagiati.gr, 1 +hagix.tk, 1 +hagoyvivo.com, 1 +hagskold.se, 1 +hagsted.dk, 1 +hagueaustralia.com.au, 1 +haha-raku.com, 1 +haha.nl, 1 +haibara.top, 0 +haiboxu.com, 1 +haidtechnology.com, 1 +haigekassa.ee, 1 +haigure.com, 1 +hails.info, 1 +hailstorm.nl, 1 +haimablog.ooo, 1 +hainanstar.cc, 1 +haindlmuehle.eu, 0 +haineshilton.com, 1 +hainoni.com, 0 +hainstr.de, 1 +hair-care-guide.com, 1 +hair-carekit.tk, 1 +hair-dressing.tk, 1 +hair-extension.tk, 1 +hair-extensions.tk, 1 +hairbrushes.tk, 1 +haircareblog.tk, 1 +haircode.gr, 1 +hairconventioners.ga, 1 +haircrazy.com, 1 +haircutideas.gq, 1 +hairextensionshop.tk, 1 +hairfitwolvega.nl, 1 +hairhardstyle.tk, 1 +hairlossadvice.tk, 1 +hairmitage.pl, 0 +hairphoto.tk, 1 +hairpins.tk, 1 +hairsalon-wish.com, 1 +hairstyles-salon.tk, 1 +haitaka.cc, 1 +haititransfert.com, 1 +haitou.tk, 1 +haiwaiyingyuan.net, 1 +haixingyun.com, 1 +haizrulamrie.com, 1 +haizum.pro, 1 +hajekdavid.cz, 1 +hajekj.com, 1 +hajekj.cz, 1 +hajnzic.at, 0 +haju.fi, 1 +hak-zona.tk, 1 +haka.se, 1 +hakaru.org, 1 +hakase.pw, 1 +hakasia.tk, 1 +hakatabijin-mind.com, 1 +hake.me, 1 +hakerzona.tk, 1 +hakiminvestment.com, 1 +hakimova.tk, 1 +hakkariradyo.tk, 1 +hakkasan.com, 1 +hakkasannightclub.com, 1 +haklappar.nu, 1 +hakon.lol, 1 +hakugin.me, 1 +hakuna.live, 1 +hal-9th.space, 1 +halacs.hu, 1 +halageorgia.com, 1 +halagroup.ml, 1 +halbbit.eu, 1 +halbich.design, 1 +halcraft.tk, 1 +halcyonsbastion.com, 1 +haleluyah-asuubabi.ga, 1 +half-logic.eu.org, 1 +half.ga, 1 +half.host, 1 +half.in.th, 1 +halfco.de, 1 +halfhosting.de, 1 +halfwaythere.eu, 1 +haliava.tk, 1 +halihali.me, 1 +halilweb.tk, 1 +halilyagcioglu.tk, 1 +halkidikitransfers.eu, 1 +halkyon.net, 1 +hallaminternet.com, 1 +hallcopainting.com, 1 +hallcouture.com, 1 +hallelujahsoftware.com, 1 +hallettxn.com, 1 +hallhireforevents.co.uk, 1 +halliday.work, 1 +halligan.tk, 1 +hallighof.de, 1 +halligladen.de, 1 +hallmarkestates.ca, 1 +hallme.com, 1 +hallofoddities.tk, 1 +hallopstyling.com, 1 +hallspumpandwellservice.net, 1 +halltrends.tk, 1 +hallucinogen.com, 1 +hallucinogens.org, 1 +hallways.tk, 1 +halneff.ga, 1 +halo.fr, 1 +halocredit.pl, 1 +halodebki.pl, 1 +halogen.city, 1 +halogen.vip, 1 +halogenos.org, 1 +halongbaybackpackertour.com, 1 +haloobaloo.com, 1 +halospawns.com, 1 +halotours.rs, 1 +halovanic.org, 1 +halsokost4life.se, 1 +haltegame.com, 1 +haluan.co, 1 +halyul.com, 1 +hamacho-kyudo.com, 1 +hamali.bg, 1 +hamamatsu-kotsu.co.jp, 1 +hamarimarriage.tk, 1 +hamartrophy.cf, 1 +hamave.nl, 1 +hamburg40grad.de, 1 +hamburgerbesteld.nl, 1 +hamburgerland.tk, 1 +hamburgobgyn.com, 1 +hamcram.io, 1 +hamelneinfachonline.de, 1 +hamiltonlinen.com, 1 +hamiltonmedical.nl, 1 +hamiltonsalestraining.com, 1 +hamiltonweather.ca, 1 +hamiltonzinelibrary.cf, 1 +hamking.tk, 1 +hamletstudio.tk, 1 +hammed.tk, 1 +hammer-schnaps.com, 1 +hammer-sms.com, 1 +hammeracademy.co.za, 1 +hammercast.fm, 1 +hammered.tk, 1 +hammernews.tk, 1 +hammerofdamnation.tk, 1 +hammerstorm.ga, 1 +hamminga.nl, 1 +hampl.tv, 1 +hampshiretechservices.co.uk, 1 +hamsaranjavan.tk, 1 +hamsternetwork.com, 1 +hamstersenanos.tk, 1 +hamsterworld.tk, 1 +hamsystems.eu, 1 +hamu.blue, 1 +hamwan.nl, 1 +han-nas.com, 1 +hana-groupsac.com, 1 +hana.ondemand.com, 1 +hanakaraku.com, 1 +hanakaru.tk, 1 +hanami-web.tokyo.jp, 1 +hanazono.tokyo, 1 +hanbin.me, 0 +hanbing.it, 1 +hancatemc.com, 1 +hancockcountyia.gov, 1 +hancockcountyohioelections.gov, 1 +hancocklawfl.com, 1 +hand-made-business.com, 1 +hand-made24.de, 1 +hand2h.com, 1 +handbrake.fr, 1 +handcraft.eu.org, 1 +handlecoin.com, 1 +handleidingkwijt.com, 1 +handmade-club.tk, 1 +handmade-workshop.de, 1 +handmadebuy.ru, 1 +handmadehechoamano.com, 1 +handmadetutorials.ro, 1 +handmadeweb.org, 1 +handrollschile.cl, 1 +handsaccounting.com, 1 +handstandstudio.ga, 1 +handwerk-digital-steinfurt.de, 1 +handwerkwebseiten.de, 0 +handy-page.tk, 1 +handy.lc, 1 +handyglas.com, 1 +handymanbypolli.com, 1 +handymanlondonplease.co.uk, 1 +handynummer-info.ch, 1 +handynummer.online, 1 +handyoutdoorgoods.com, 1 +handyquip.com, 1 +handyschaft.de, 1 +handysex.live, 1 +handyticket.de, 1 +hanfox.co.uk, 0 +hanfverband-erfurt.de, 1 +hang333.moe, 1 +hangar.hosting, 1 +hangar4.es, 1 +hangarbox.de, 1 +hangargeek.ml, 1 +hangcapnach.com, 1 +hangout, 1 +hangouts.google.com, 1 +hangryum.com, 1 +hangtenseo.com, 1 +hangw.xyz, 1 +hanikira.com, 1 +hanimat.pl, 1 +hanisirfan.cf, 1 +hanjl.com, 1 +hanjuapp.com, 1 +hanke.se, 1 +hankoreas.com, 1 +hankr.com, 1 +hanksacservice.com, 1 +hanksservice.com, 1 +hannah.link, 1 +hannaljungberg.tk, 1 +hannasecret.de, 1 +hannde.com, 1 +hannehovi.fi, 1 +hannes.paris, 1 +hannit.de, 1 +hannover-96.tk, 1 +hannover-reisen.tk, 1 +hannover.de, 1 +hannywbarek.com, 1 +hanoibuffet.com, 1 +hanoicapital-tanvn.tk, 1 +hanomag-tractors.tk, 1 +hanpenblog.com, 1 +hansa.org.ru, 1 +hansahome.ddns.net, 1 +hansbijster.nl, 1 +hanschventures.com, 1 +hansen-kronshagen.de, 1 +hansen.hn, 1 +hansgoes.it, 1 +hansgoes.nl, 1 +hansgoesit.nl, 1 +hanshosting.nl, 1 +hansminten.com, 1 +hansmund.com, 1 +hansmunt.nl, 1 +hansolrella.com, 1 +hansonian.com, 1 +hansvaneijsden.com, 1 +hansvaneijsden.nl, 1 +hantse.com, 1 +hanu.la, 1 +hanxv.pw, 1 +hanying6.com, 1 +hanyingw.com, 0 +hanys.xyz, 1 +hanzcollection.online, 1 +hanzubon.jp, 1 +hao-zhang.com, 1 +hao.gay, 1 +haocq3.com, 1 +haogoodair.ca, 1 +haorenka.co, 1 +haorenka.me, 1 +haorenka.org, 1 +haosygt.com, 1 +haoyangmao8.com, 1 +haozhang.org, 1 +haozhexie.com, 1 +hapijs.cn, 1 +hapissl.com, 1 +hapivm.com, 1 +haplogroup.org, 1 +happicollective.com, 1 +happiestoutdoors.ca, 1 +happineo.com, 1 +happist.com, 1 +happu-dinero.tk, 1 +happy-end-shukatsu.com, 1 +happy-face.tk, 1 +happy-finance.tk, 1 +happy-herd.com, 1 +happy-space.tk, 1 +happy-wans.com, 1 +happyagain.de, 1 +happyagain.se, 1 +happyandrelaxeddogs.com, 1 +happyandrelaxeddogs.eu, 1 +happyanimalsshop.com, 1 +happybeerdaytome.com, 1 +happybirthdaywisher.com, 1 +happybody.com.tr, 1 +happybounce.co.uk, 1 +happybrush.de, 1 +happycarb.de, 1 +happychat.io, 1 +happychungus.tk, 1 +happycoder.net, 0 +happycoders.eu, 1 +happycolors.us, 1 +happycore.ml, 1 +happydad.tk, 1 +happydietplan.com, 1 +happydoghosting.net, 1 +happydoq.ch, 0 +happydota.ga, 1 +happydreamsz.com, 1 +happyexwife.ga, 1 +happyfeet-dordrecht.nl, 1 +happyfuture.tk, 1 +happygadget.me, 1 +happyglacons.com, 1 +happygreats.tk, 1 +happygutlife.com, 1 +happyhealthytechie.com, 1 +happyheartsabode.com, 1 +happyhumans.com, 1 +happyindia.ml, 1 +happyland.link, 1 +happylearning.com, 1 +happylifestyle.com, 1 +happymondayclub.com, 1 +happymothersday.tk, 1 +happyretail.co, 1 +happyschnapper.com, 1 +happyscubadiving.tk, 1 +happyteamlabs.com, 1 +happytestings.com, 1 +happytiger.eu, 1 +happyukgo.com, 1 +happywater.my, 1 +happyweekend.ga, 1 +happywheels1.online, 1 +hapronailz.tk, 1 +hapsana.nl, 1 +hapsfordmill.co.uk, 1 +haptemic.com, 1 +hapticmedia.com, 1 +hapvm.com, 1 +harabar.ga, 1 +harabar.gq, 1 +harabar.ml, 1 +harabe.ga, 1 +harahanla.gov, 1 +haraj.com.sa, 1 +harakahdaily.net, 1 +harald-d.dyndns.org, 1 +harald-pfeiffer.de, 1 +haramainbd.com, 1 +harambo.cf, 1 +harapecorita.com, 1 +harapjunk.hu, 1 +harbecke.me, 1 +harbecke.net, 1 +harbor-light.net, 1 +harcourt.site, 1 +hard-drive-recovery-blog.tk, 1 +hard.email, 1 +hardcoen.com, 1 +hardcore-bodybuilding.com, 1 +hardcore-bodybuilding.nl, 0 +hardcore-hooligans.tk, 1 +hardeman.nu, 1 +hardenize.com, 1 +hardergayporn.com, 1 +hardertimes.com, 1 +hardesec.com, 1 +hardfalcon.net, 1 +hardfloorcleaninglondon.co.uk, 1 +hardforum.com, 1 +hardh.at, 0 +hardhat.io, 1 +hardhatengineer.com, 1 +hardies.nl, 1 +hardinal.com, 1 +hardmc.ru, 1 +hardnode.org, 1 +hardrain980.com, 1 +hardrock.tk, 1 +hardtec.tk, 1 +hardtfrieden.de, 1 +hardtime.ru, 1 +hardtime.tk, 1 +hardtimeszine.tk, 1 +hardwareforum.ga, 1 +hardwarelog.in, 1 +hardwarelogin.com, 1 +hardwarelogin.rocks, 1 +hardwareschotte.de, 1 +hardweb.it, 1 +hardy.bz, 1 +harelmallac.com, 1 +harelmallacglobal.com, 1 +harery.com, 1 +hargaindo.com, 1 +hargamobilmu.com, 1 +hargrovefirm.com, 1 +hari-katha.tk, 1 +haribilalic.com, 1 +harigovind.org, 1 +hariharnagar.tk, 1 +harimata.co, 1 +harion.fr, 1 +harisht.me, 0 +harititan.com, 1 +haritsa.co.id, 1 +harjitbhogal.com, 1 +harkenzconstruction.com, 1 +harlan.cc, 1 +harleyclassifieds.com, 1 +harlor.de, 1 +harmoney.com, 1 +harmonizely.com, 0 +harmony.ec, 1 +harmonyonline.ir, 1 +harmonyplace.com, 1 +harms.io, 1 +harmsboone.org, 1 +harnov.dk, 1 +haroldkip.nl, 1 +haroldsharpe.com, 1 +harp.gov, 1 +harpersvilleal.gov, 1 +harplingemark.se, 1 +harpoo.jp, 0 +harptechnologies.com, 1 +harrachovskyapartman.cz, 1 +harray.tk, 1 +harrcostl.com, 1 +harriedrecords.tk, 1 +harrietjohnston.tk, 1 +harringtonca.com, 1 +harrisandharris.com.au, 1 +harrisconsulting.ie, 1 +harrisexteriors.com, 1 +harrisonm.com, 1 +harrisonsand.com, 0 +harrisonswebsites.com, 1 +harry-baker.com, 1 +harryagustiana.tk, 1 +harrychristensen.tk, 1 +harrygerritstransport.nl, 1 +harrymclaren.co.uk, 1 +harrypotterclan.tk, 1 +harrypottereditor.com, 1 +harrypottereditor.net, 1 +harrysdiveshop.com, 1 +harrysmallbones.co.uk, 1 +harrysqnc.co.uk, 1 +harryvapoteur.com, 1 +harryxxjohnson.ga, 1 +harshee.ml, 1 +hartfordct.gov, 1 +hartfordschools.org, 1 +hartie95.de, 1 +hartkampforkids.nl, 1 +hartleighclyde.com.au, 1 +hartlep.email, 1 +hartlieb.me, 1 +hartmancpa.com, 1 +hartsfieldrock.tk, 1 +hartvannike.tk, 1 +hartzer.com, 1 +haru-restaurant.tk, 1 +haruhi.org.ua, 1 +harukakikuchi.com, 1 +harukawa.moe, 1 +harumi-cl.jp, 1 +haruue.moe, 1 +harvestapp.com, 1 +harvester.fr, 1 +harvestgospelministries.org, 1 +harveyauzorst.com, 1 +harveyplum.com, 1 +harveysautoservice.net, 1 +harvilldesigns.com, 1 +has-no-email-set.de, 0 +has.report, 1 +has.work, 1 +hasabig.wang, 1 +hasalittle.wang, 1 +hasandeniz.uk, 1 +haschrebellen.de, 1 +hasdf.de, 1 +hasecuritysolutions.com, 1 +haselsteiner.me, 1 +hash-archive.org, 1 +hash.army, 1 +hash.works, 1 +hashcat.net, 1 +hashemian.com, 1 +hashes.org, 1 +hashi.dk, 1 +hashiconf.com, 0 +hashicorp.com, 0 +hashimah.ca, 1 +hashimoto-jimusho.com, 1 +hashinteractive.com, 0 +hashish.net, 1 +hashiura.jp, 1 +hashplex.com, 1 +hashru.nl, 1 +hashworks.net, 1 +hashxp.org, 1 +hasilkeluaransgp.com, 1 +hasilocke.de, 1 +haskovec.com, 1 +hassan-kuordish.tk, 1 +hassclan.tk, 1 +hasselbach-dellwig.de, 1 +hassellunden.ga, 1 +hasseplatslageri.se, 1 +hassiba-abderaouf.tk, 1 +hassmelden.de, 1 +hassra.org.uk, 1 +hastadoktor.com, 1 +hastavem.com, 1 +hastmassage.tk, 1 +hastyllc.com, 1 +hatachan.site, 1 +hataonline.tk, 1 +hatarisecurity.co.ke, 1 +hatcher.cloud, 1 +hate.ga, 1 +hatethe.uk, 1 +hathai.org, 1 +hatierchinois.fr, 1 +hatpakha.com, 1 +hatsuharu.tk, 1 +hatsukoi-seikotsu.com, 1 +hatter.ink, 1 +hatul.info, 1 +haucke.xyz, 1 +haughtonla.gov, 1 +hauller.ch, 1 +haunt-keeper.com, 1 +hauntedfieldsofglory.com, 0 +hauntedhouserecords.co.uk, 1 +hauora.fyi, 1 +hauora.net, 1 +hauora.tech, 1 +haus-garten-test.de, 1 +haus-henne.de, 1 +haus-momo.ch, 1 +hausarzt-stader-str.de, 0 +hausarztpraxis-weilheim.de, 1 +haushaltsaufloesung-vor-ort.de, 1 +haushaltsaufloesung-zentrum.de, 1 +haushaltsaufloesunghannover.de, 1 +haushenne.de, 1 +hausjugo.de, 1 +hauspie.fr, 1 +haustechnik-breu.de, 1 +hausverbrauch.de, 1 +hausverwaltung-motsch.de, 1 +hautarztzentrum.ch, 1 +hauteslatitudes.com, 0 +hautzentrumwien.at, 1 +havarijna-sluzba-bratislava.sk, 1 +havasuinsurance.com, 1 +havasutacohacienda.com, 1 +have-it.tk, 1 +have.jp, 1 +haveabounce.co.uk, 1 +havedicewillsave.com, 1 +haveforeningen-enghaven.dk, 1 +havefunbiking.com, 1 +haveibeenpwned.com, 1 +havellab.de, 1 +havelland-obstler.de, 0 +haven-staging.cloud, 1 +havencyber.com, 1 +havendetoxnow.com, 1 +havenseniorinvestments.com, 1 +havenstrategies.com, 1 +havernbenefits.com, 1 +haverstack.com, 1 +havetherelationshipyouwant.com, 1 +havohravo.com, 1 +havranek-its.at, 1 +hawaar.com, 1 +hawaiiafro.tk, 1 +hawaiianchoice.com, 1 +hawaiiforbernie.com, 1 +hawaiioceanproject.com, 1 +hawat.cz, 1 +hawawa.kr, 1 +hawickvets.co.uk, 1 +hawk-la.com, 1 +hawkargentina.com, 1 +hawkeyeinsight.com, 1 +hawkinsonkiaparts.com, 1 +hawkofgeorgia.com, 1 +hawkon.dk, 1 +hawkrovers.tk, 1 +hawksguild.com, 0 +hawksracing.de, 1 +hax.sc, 1 +hax.to, 1 +haxdroid.com, 1 +haxland.tk, 1 +haxo.nl, 0 +haxx.hu, 1 +hay.email, 1 +hayai.space, 1 +hayashi-rin.net, 1 +hayda-haki.com, 1 +hayden.ru, 1 +haydenbleasel.com, 0 +haydenjames.io, 1 +hayfordoleary.com, 1 +hayl.me.uk, 1 +hayobethlehem.nl, 1 +hayonik.com, 1 +haystackrenovation.com.au, 1 +hayvid.com, 1 +haz.cat, 1 +hazan.eu, 1 +hazana.ovh, 1 +hazara-online.tk, 1 +haze-productions.com, 1 +haze.productions, 1 +hazelglow.com, 1 +hazelhof.nl, 1 +hazelwilks.co.uk, 1 +hazeover.com, 1 +hazit.co.il, 1 +hazloconlapix.com, 1 +hazyhosting.tk, 1 +hb2132.com, 0 +hb5132.com, 0 +hb5197.com, 0 +hb6365.com, 0 +hb6729.com, 1 +hb8522.com, 1 +hb9397.com, 1 +hbaa.ml, 1 +hbbet.com, 1 +hbcm70.fr, 1 +hbcu-colleges.com, 1 +hbeiliny.com, 1 +hbelectricsolutions.com, 1 +hbfisioeesthetic.com.br, 1 +hbgshop.cf, 1 +hboeck.de, 1 +hbomaxaustralia.com, 1 +hbr.link, 1 +hbsslaw.co.uk, 1 +hbsslaw.com, 1 +hbsvzos.nl, 1 +hbudd.com, 1 +hbvip.com, 1 +hbweb.io, 1 +hbxianghang.com, 0 +hby.cx, 1 +hcaz.io, 1 +hcbj.io, 1 +hceu-performance.com, 1 +hcfoodpantry.org, 1 +hcgallia.tk, 1 +hcie.pl, 0 +hclsrilanka.com, 1 +hclu.co, 1 +hco4.com, 1 +hcr2bot.com, 1 +hcs.land, 1 +hcsbk.kz, 1 +hcscrusaders.com, 1 +hcsoffshore.com, 1 +hctegelhandel.tk, 1 +hcv.cz, 1 +hcv.ind.in, 1 +hd-iptv.co, 1 +hd-offensive.at, 0 +hd-only.org, 1 +hd-outillage.com, 1 +hd6729.com, 1 +hd6957.com, 1 +hd9397.com, 1 +hd9721.com, 1 +hdbits.org, 1 +hdc.cz, 1 +hdcenter.cc, 1 +hdcozinha.com.br, 1 +hddrecovery.net.au, 1 +hdeaves.uk, 1 +hdert.com, 1 +hdevent.net, 1 +hdf.world, 1 +hdfgroup.org, 1 +hdguru.com, 1 +hdhoang.space, 1 +hdkandsons.com, 1 +hdlooks.tk, 1 +hdml.kr, 1 +hdnastudio.com, 1 +hdpornose.com, 1 +hdrezka2018.tk, 1 +hdritalyphotos.com, 1 +hdrsource.com, 1 +hdrtranscon.com, 0 +hds-lan.de, 1 +hds-rx.com, 1 +hdsexxx.net, 1 +hdtwinks.com, 1 +hdv.paris, 1 +hdv12.horse, 1 +hdview.co.uk, 1 +hdwallpapers.net, 1 +hdy.nz, 1 +he.kg, 1 +heaaart.com, 1 +head-hunters.tk, 1 +head.org, 1 +head.ru, 1 +heade.cf, 1 +headforcloud.com, 1 +headfullofdynamite.com, 1 +heading2australia.ga, 1 +headjapan.com, 1 +headlinenews.co, 1 +headlinepublishing.be, 1 +headofhair.pl, 1 +headphonesinear.tk, 1 +headwayapp.co, 1 +heal-thybody.nl, 1 +healike.hk, 0 +healingourskin.com, 1 +healingthenaturalway.cf, 1 +healmyhearttoday.ga, 1 +healtbeautyturkey.tk, 1 +health-and-beauty-news.net, 1 +health-balance-plus.com, 1 +health-booster.com, 0 +health-iq.com.au, 1 +health-match.com.au, 1 +health-plan-news.com, 1 +health-road.ga, 1 +health.gd, 1 +health.gov, 1 +health.graphics, 1 +health.inc, 1 +health24.ml, 1 +health24world.ml, 1 +health4food.com, 1 +healthalbuquerque.tk, 1 +healthand-beautynews.net, 1 +healthandglow.tk, 1 +healthandskinbeauty.com, 1 +healtharlington.tk, 1 +healthatlanta.tk, 1 +healthbank.io, 1 +healthboston.tk, 1 +healthbrochures.info, 1 +healthcare.gov, 0 +healthcarereviews.tk, 1 +healthcaresuccess.com, 1 +healthchoice.tk, 1 +healthcise.com, 1 +healthcolumbia.tk, 1 +healthcolumbus.tk, 1 +healthcultureexpo.com, 1 +healthdallas.tk, 1 +healthdata.gov, 1 +healthdenver.tk, 1 +healthdetroit.tk, 1 +healtheals.com, 0 +healtheffectsofasbestos.com, 1 +healthekids.tk, 1 +healthequity.com, 1 +healthfinder.gov, 1 +healthfitapp.com, 1 +healthfoam.com, 1 +healthiercompany.com, 1 +healthiergenerations.co.uk, 1 +healthiraq.ga, 1 +healthit.gov, 1 +healthl.ink, 1 +healthlable.com, 1 +healthlabs.com, 1 +healthlar.com, 1 +healthmanager.ml, 1 +healthmanchester.tk, 1 +healthmatchapp.com, 1 +healthmilwaukee.tk, 1 +healthmilwaukie.tk, 1 +healthpert.com, 1 +healthplansamerica.org, 1 +healthrish.com, 1 +healthsacramento.tk, 1 +healthsanantonio.tk, 1 +healthsanjose.tk, 1 +healthsantaclara.tk, 1 +healthscience.tk, 1 +healthseattle.tk, 1 +healthsone.com, 1 +healthspringfield.tk, 1 +healthstar-dev.io, 1 +healthstar.io, 1 +healthstyletips.ml, 1 +healththoroughfare.com, 1 +healthtoledo.tk, 1 +healthunbox.com, 1 +healthworksmarden.com.au, 1 +healthy-map.com, 1 +healthy-shoko.com, 1 +healthy1lifestyle.com, 1 +healthyaging-digital.com, 1 +healthybeterlife.click, 1 +healthyfitfood.com, 1 +healthyfoodster.com, 1 +healthyhabitswellness.net, 1 +healthyhomeventilation.com.au, 1 +healthykitchen101.com, 1 +healthyliving-healthnetwork.com, 1 +healthymen.ml, 1 +healthynutritionguide.info, 1 +healthyprinciples.co.uk, 1 +healthyrun.tk, 1 +healthyspirituality.org, 1 +healthystyle.tk, 1 +healthysuperhuman.com, 1 +healthyteame.com, 1 +healthyweblife.tk, 1 +heanbian.com, 1 +heap.zone, 1 +heardcountyathletics.com, 1 +hearfool.cc, 1 +hearingshofar.com, 1 +hearkener.com, 1 +heart-cartoons.tk, 1 +heartbeat24.de, 1 +heartbound.wiki, 1 +heartcomms.com.au, 1 +hearted.co, 1 +heartgames.pl, 1 +hearthealing.ca, 1 +hearthstonehungary.hu, 1 +heartlandbiomed.com, 1 +heartmdinstitute.com, 1 +heartofamum.com, 1 +heartsintrueharmony.com, 1 +heartsucker.com, 0 +hearttruth.gov, 1 +heartview.com.br, 1 +heartwoodart.com, 1 +hearty.blog, 1 +hearty.edu.pl, 1 +hearty.eu.org, 1 +hearty.ga, 1 +hearty.gift, 1 +hearty.gq, 1 +hearty.ink, 1 +hearty.me, 1 +hearty.ml, 1 +hearty.ooo, 1 +hearty.org.tw, 1 +hearty.sg, 1 +hearty.taipei, 1 +hearty.tech, 1 +hearty.tw, 1 +heartyapp.com, 1 +heartyapp.tw, 1 +heartycorp.com, 1 +heartycraft.com, 1 +heat-ua.pt, 1 +heatedwater.co.uk, 1 +heatershop.co.uk, 1 +heatherbells.tk, 1 +heatherleysephotography.com, 1 +heathersmithcommercial.com, 1 +heatingandairconditioningdallastx.com, 1 +heatingequipment.tk, 1 +heaven-boutique.de, 1 +heavenlyseals.com, 1 +heavenlysmokenc.com, 1 +heavensattic.co.uk, 1 +heavycaliber.com, 1 +heavyequipments.org, 0 +heavymetalonline.co.uk, 1 +hebamme-cranio.ch, 1 +hebamme-ebersberg.de, 1 +hebamme-sabine.eu, 1 +hebbelabi.tk, 1 +hebbet.de, 1 +heber.tk, 1 +heberut.gov, 1 +hebikhiv.nl, 1 +hebrew.ga, 1 +hec-espace-entreprise.ch, 0 +hec.global, 1 +hecco.io, 1 +hechizosymagianegra.es, 1 +heckelektro.de, 1 +hecking.tk, 1 +heckmann.photos, 1 +hectorfiorini.com.ar, 1 +heddoun.com, 1 +hederaconsulting.com, 1 +hedge.fi, 1 +hedgedoc.org, 1 +hedgehogdigital.co.uk, 1 +hedgeschool.ie, 1 +hedman.tk, 1 +hedonics.org, 1 +hedonism.org, 1 +hedonistic-imperative.com, 1 +hedonistic.org, 1 +hedonium.com, 1 +hedweb.co.uk, 1 +hedweb.com, 1 +hedweb.net, 1 +hedweb.org, 1 +hedys.de, 1 +heeftmijnwebsitehttpsnodig.nl, 1 +heeler.blue, 1 +heeler.red, 1 +heello.es, 1 +heesenyachts.com, 1 +hefengautoparts.com, 1 +heftkaufen.de, 1 +heg.ge, 1 +hegartymaths.com, 1 +hegdahl.tk, 1 +hegen.com.pl, 0 +hegen.cz, 0 +hegenshop.de, 1 +heh.ee, 1 +heha.co, 0 +hehome.xyz, 1 +heiaheia.com, 0 +heic.nz, 1 +heid.ws, 1 +heiden-wir-helfen.de, 1 +heidifuller.com, 1 +heidisheroes.org, 1 +heightselectrical.com.au, 1 +heijdel.nl, 1 +heijenoord.net, 1 +heijmans.blog, 1 +heijmans.email, 1 +heijmans.io, 1 +heijmans.pm, 1 +heijmans.tech, 1 +heikegastmann.com, 1 +heikki-mikkola.tk, 1 +heikkileivonen.fi, 1 +heikohessenkemper.de, 1 +heikorichter.name, 1 +heiland.io, 1 +heiliao.in, 1 +heiliger-gral.info, 1 +heilkraft.online, 1 +heilmandeckandfence.com, 1 +heimansschildersbedrijf.nl, 1 +heimatverein-eitensheim.de, 1 +heimdall-home.com, 1 +heimdallr.nl, 1 +heimnetze.org, 0 +heimonen.eu, 1 +heinenhopman.ro, 1 +heino-peters.de, 1 +heinpost.nl, 0 +heinrich5991.de, 1 +heinzelmann.co, 0 +heinzencastellano.tk, 1 +heiraten-gardasee.de, 1 +heiraten-venedig.de, 1 +heisenberg.co, 1 +heissluft-fritteuse.com, 1 +heist-clan.tk, 1 +heistheguy.com, 1 +heitepriem.info, 1 +heiwa-valve.co.jp, 0 +hejazultra.org, 1 +hejsupport.se, 1 +hekat.sk, 1 +hekate.com.mx, 1 +hekeki.com, 1 +hekimim.tk, 1 +hekoro.ml, 1 +hektenkairez.com, 1 +helagotaland.gq, 1 +helali.me, 1 +helbreath.tk, 1 +helco.xyz, 1 +helden-spielen.de, 1 +heldenhalde.de, 1 +helder.tk, 1 +helderneves.pt, 1 +heldtech.services, 1 +heldundsexgott.de, 1 +heleendebruyne.be, 1 +helenaknowledge.com, 1 +helenapaparizouspainfanclub.tk, 1 +helendoron.fr, 1 +helenekurtz.com, 1 +helenelefauconnier.com, 1 +helenevanwunnik.tk, 1 +helenkellersimulator.org, 1 +helensmithpr.co.uk, 1 +helenssjoholm.cf, 1 +heleus.it, 1 +helfordriversc.co.uk, 1 +helga-fest.tk, 1 +helgaschultz.de, 1 +helichat.de, 1 +heliconservices.com, 1 +helifreak.club, 1 +helijobs.net, 1 +helikopter.ml, 1 +helikopters.tk, 1 +helios4.com, 1 +heliosbot.net, 1 +heliosnet.com, 1 +heliumtech.tk, 1 +helix.am, 1 +helix.social, 1 +helkyn.eu, 1 +helkyn.fr, 1 +helkyn.org, 1 +hell.sh, 1 +hellblast.tk, 1 +hellboundhackers.org, 1 +hellenicagora.co.uk, 1 +hellenicmusicacademy.com, 1 +hellerarko.de, 1 +hellersgas.com, 1 +hellhavens.tk, 1 +hello-design.fr, 1 +helloacm.com, 1 +helloafrica.ga, 1 +helloappservices.com, 1 +hellobee.com, 1 +hellobrian.me, 1 +hellochamath.com, 1 +helloexit.com, 1 +hellofilters.com, 1 +hellofound.co, 1 +hellokashmir.tk, 1 +hellolocalmedia.com.au, 1 +hellolove.sg, 1 +hellomookie.com, 1 +hellomouse.cf, 1 +hellomouse.net, 1 +hellomouse.tk, 1 +hellomyword.tk, 1 +hellonews.cf, 1 +helloo.com.br, 1 +hellopowerserg.com, 1 +hellorussia.ga, 1 +hellosalmon.com, 1 +hellotandem.com, 1 +helloteen.tk, 1 +hellothought.net, 1 +hellovillam.com, 1 +helloworldhost.com, 0 +hellpc.net, 1 +hellsgamers.pw, 1 +hellsh.com, 1 +hellskitsch.com, 1 +hellsoldiers.tk, 1 +hellven.net, 1 +helm-pokale.at, 1 +helm-pokale.de, 1 +helm-trophy.com, 1 +helminger-lrs.at, 1 +help-me.today, 1 +help-step.org, 1 +help207.me, 1 +help207.xyz, 0 +helpantiaging.com, 1 +helpcalculator.tk, 1 +helpcapital.ru, 1 +helpcentral.ng, 1 +helpcomp.tk, 1 +helpconnect.com.au, 1 +helpekwendenihospital.com, 1 +helpfulhealthinsurance.com, 1 +helpkoil.com, 1 +helpmij.cf, 1 +helpnet.ro, 1 +helppc.com.ua, 1 +helprb.ru, 1 +helprf.ru, 1 +helpscoutdocs.com, 1 +helptasker.com, 1 +helptasker.net, 1 +helptasker.ru, 1 +helpwaarbenik.nl, 1 +helpwithadoption.com, 1 +helpwithinsomnia.org, 0 +helpwithmybank.gov, 1 +helsenorge.no, 1 +helseogmassasje.no, 1 +helsingfors.guide, 1 +helsinki.dating, 1 +helvella.de, 1 +hemant.net, 1 +hemaroids.tk, 1 +hematoonkologia.pl, 1 +hemdal.se, 1 +hemdian.com, 1 +hemelgaard.nl, 1 +hementaze.com, 1 +hemingwayfp.co.uk, 1 +hemlibra.co.il, 1 +hemnet.se, 1 +hemorroi.ga, 1 +hemp.com, 1 +hempseedhealth.com, 1 +hems.si, 1 +hen.ee, 1 +hen.ne.ke, 1 +hendersonvalleyautomotive.co.nz, 1 +hendric.us, 0 +hendrickx.be, 1 +hendrik.li, 1 +hendrinortier.nl, 1 +heng555.com, 1 +hengelsportdeal.com, 1 +hengroenet.de, 1 +hengstumone.com, 1 +henkboelman.com, 1 +henke-home.eu, 1 +henker.net, 1 +henkpille.tk, 1 +henkrensing.nl, 1 +henkverlinde.com, 1 +henley-computer-repairs.co.uk, 1 +henleybouncycastles.co.uk, 1 +henlich.de, 1 +hennastories.com, 1 +hennastories.org, 1 +hennecke-forstbetrieb.de, 1 +henneke.me, 1 +hennes-haan.de, 1 +hennes-shop.de, 1 +hennesshop.de, 1 +hennies.org, 1 +henningkerstan.de, 1 +henningkerstan.org, 1 +hennymerkel.com, 1 +henri-feuillade.tk, 1 +henri.moe, 1 +henrieta-nagyova.tk, 1 +henrik-bondtofte.dk, 1 +henrikjuvonen.fi, 1 +henriknoerr.com, 1 +henriksen.is, 1 +henrikwelk.de, 1 +henrilammers.nl, 1 +henry.gg, 1 +henrybelk.com, 1 +henrybrown0.com, 1 +henryclub.tk, 1 +henrycountyohio.gov, 1 +henryishax.com, 1 +henryluker.com, 1 +henrymercado.tk, 1 +henryocallaghan.com, 1 +henryphan.com, 0 +henrysautodetail.com, 1 +hens.ch, 1 +hentai.baby, 1 +hentaigogo.com, 1 +hentaimaster.net, 1 +hentaipornography.com, 1 +hentaiworld.cc, 0 +hentaiz.net, 1 +hentaizm.cf, 1 +hentamanga.tk, 1 +hentavfall.no, 1 +hentschke-bau.de, 1 +hentschke-betonfertigteilwerk.de, 1 +hentschke-invest.de, 1 +henzenhoning.nl, 1 +hepha.ch, 1 +hepla.de, 0 +heppler.net, 1 +heptafrogs.de, 1 +heptner24.de, 1 +heraldik-wiki.de, 1 +heraldmakassar.com, 1 +herba-belgie.be, 1 +herbalifereport.tk, 1 +herbamedicine.com, 1 +herbandpat.org, 1 +herbarex.eu, 1 +herberichfamily.com, 1 +herbers.tk, 1 +herbert.io, 1 +herbertjanvandinther.nl, 1 +herbiez.com, 1 +herbolarigranvida.com, 1 +herbreathonglass.tk, 1 +herbsupplements.co.uk, 1 +herbweb.net, 1 +herbweb.org, 1 +herbymiast.waw.pl, 1 +herculex.fi, 1 +herdingcatshere.com, 1 +herds.eu, 0 +herdserv.de, 1 +herdwilliam.tk, 1 +here.ml, 1 +herecsrymy.cz, 1 +heredapoxetine.gq, 1 +heren.fashion, 1 +heretic-guild.com, 1 +hereticle.com, 1 +hereticmaniacs.tk, 1 +hereticofficial.com, 1 +hereticpreist.tk, 1 +herewomentell.com, 1 +hergeandtintin.tk, 1 +herila.ml, 1 +heritagebaptistchurch.com.ph, 1 +heritagecoffee.co.uk, 0 +heritagemachining.ca, 1 +heritagereformed.tk, 1 +herkam.pl, 1 +herkel.email, 1 +herkel.media, 1 +herkelmedia.com, 1 +herkelmedia.de, 1 +hermanbrouwer.nl, 1 +hermandadblanca.org, 0 +hermann.in, 1 +hermanoscarrera.tk, 1 +hermes-net.de, 1 +hermes-servizi.it, 1 +hermetien.tk, 1 +hermietkreeft.site, 0 +herminghaus24.de, 1 +hermitant.fr, 1 +hermiu.com, 1 +herndl.org, 1 +herni-kupony.cz, 1 +hernn.com, 1 +heroblog.info, 1 +herocentral.de, 1 +heroco.xyz, 1 +heroes3stat.tk, 1 +heroesorchestra.com, 1 +herofil.es, 1 +herogaming.net, 1 +heroiclove.com, 1 +heroicpixel.com, 0 +heroku.com, 1 +herold.me, 1 +herold.space, 1 +heromuster.com, 1 +heroningenieria.com, 1 +heroxin.com, 1 +herpes-no.com, 1 +herr-webdesign.de, 1 +herrald-skeeleren.tk, 1 +herranzramia.com, 0 +herrderzeit.de, 1 +herrenmuehle-wein.de, 1 +herreriamauricio.com.ar, 1 +herreriaorozco.com, 1 +herrfirm.com, 1 +herringadvancemachine.com, 1 +herringboneeats.com, 1 +herringsresidence.be, 1 +herritage.ga, 1 +herrschaftlich-durch-dresden.de, 1 +herrsmith.com, 1 +herrtxbias.net, 0 +herrtxbias.org, 1 +hersdorf-eifel.de, 1 +hersmartchoice.com, 1 +hertsbouncycastles.com, 1 +hertz.fail, 1 +hertz.zone, 1 +herumixer.ga, 1 +herychreality.cz, 1 +herza.id, 1 +herzberg.site, 1 +herzfuersoziales.at, 1 +herzig.cc, 1 +herzogglass.com, 1 +herzwacht.de, 1 +hes.com.cy, 1 +hesabcenter.com, 1 +hesanlang.com, 1 +hesaplama.net, 1 +hesaplat.net, 1 +hesbenergie.be, 1 +hessen-liebe.de, 1 +hessenheim.tk, 1 +hesslag.com, 1 +hestegrovvaren.dk, 1 +hestervanderheijden.nl, 1 +hestia-systeme.be, 1 +hestia-systeme.com, 1 +hestia-systeme.eu, 1 +hestia-systeme.fr, 1 +hesyifei.com, 1 +hetchie.com, 1 +hetdebat.tk, 1 +hetene.nl, 1 +hetfundament.team, 1 +hetgetouw.be, 1 +hethakhout.nl, 1 +hethely.ch, 1 +hetmeisjeachterpauw.nl, 1 +hetmer.cz, 1 +hetmozaiekje.nl, 1 +hetushu.com, 1 +hetwalhalla.nl, 1 +heureka2.com, 1 +heute-kaufen.de, 1 +heute.training, 1 +heutger.net, 1 +hevrishut.cf, 1 +hewavitharanamv.tk, 1 +hex.nl, 1 +hex2rgb.online, 1 +hexacon.io, 1 +hexagon-e.com, 1 +hexagon.io, 1 +hexapt.com, 1 +hexatech.tk, 1 +hexclock.io, 1 +hexcode.in, 1 +hexed.it, 1 +hexg.me, 1 +hexhu.com, 1 +hexhu.net, 1 +hexiaohu.cn, 1 +hexid.me, 0 +hexieshe.com, 1 +hexo.ink, 0 +hexo.io, 0 +hexobind.com, 1 +hexony.com, 1 +hexr.org, 1 +hexsafe.io, 1 +hexstream.net, 1 +hexstream.xyz, 1 +hexstreamsoft.com, 1 +hexxagon.com, 1 +hey.com, 1 +hey.pw, 1 +heyapakabar.com, 1 +heybaker.com.au, 1 +heyboldface.com, 1 +heybritney.tk, 1 +heybyrdie.com, 1 +heyfringe.com, 1 +heyitgirl.com, 1 +heyitsfree.net, 1 +heyjournal.com, 1 +heyplay.eu.org, 1 +heyrockerproductions.com, 1 +heysora.net, 1 +heywise.com, 1 +heywood.cloud, 1 +hf-rpg.ml, 1 +hf51-domeinen.nl, 1 +hf51.nl, 1 +hfbg.nl, 0 +hfi.me, 0 +hflsdev.org, 0 +hfox.org, 1 +hfsctx.gov, 1 +hfx405.de, 1 +hfzlaw.com, 0 +hg.gg, 1 +hg.python.org, 1 +hg0086.la, 1 +hg170.cc, 1 +hg661.cc, 1 +hg71839.com, 1 +hg881.com, 1 +hgbcms.ca, 1 +hgc.solutions, 1 +hgc369.com, 1 +hgfa.fi, 1 +hghanbarimd.com, 1 +hghwebs.com, 1 +hgmaranatha.nl, 1 +hgpowerglue.nl, 1 +hgseo.net, 1 +hguandl.com, 1 +hgvnet.de, 1 +hgyo.me, 1 +hgyoseo.com, 1 +hgzw.com, 1 +hh-host.de, 1 +hh-massage.de, 1 +hh-medic.com, 1 +hh-wolke.dedyn.io, 1 +hh5197.co, 1 +hh6729.co, 1 +hh6729.com, 1 +hh6957.co, 1 +hh9297.co, 1 +hh9397.com, 1 +hh9721.com, 1 +hh9728.co, 1 +hhhdb.com, 1 +hhidr.org, 1 +hhl.de, 1 +hhristov.tk, 1 +hhs.gov, 1 +hhsrocketry.tk, 1 +hhtoners.com.br, 1 +hhxiaozhan.ml, 1 +hi-million.ga, 1 +hi-million.ml, 1 +hi-res.cloud, 1 +hi-res.vip, 1 +hi-science.com, 1 +hi.team, 1 +hialatv.com, 1 +hibanaworld.com, 1 +hibari.moe, 1 +hibiscuscoastfinancialservices.com.au, 1 +hibiscusladigue.com, 1 +hibrid-turf.com, 1 +hiccupsandjuice.co.uk, 1 +hickorywinecellar.com, 1 +hicl.org, 1 +hicoria.com, 1 +hicts.nl, 1 +hiczp.com, 1 +hidbo.de, 1 +hidden.gq, 1 +hiddenhillselectric.com, 1 +hiddenhillselectrical.com, 1 +hiddenhillselectrician.com, 1 +hiddenhillsexteriorlighting.com, 1 +hiddenhillslandscapelighting.com, 1 +hiddenhillslighting.com, 1 +hiddenhillsoutdoorlighting.com, 1 +hiddenimage.ml, 1 +hiddenmalta.net, 1 +hiddenpalms.tk, 1 +hiddenrefuge.eu.org, 1 +hiddout.com, 1 +hide-in.cloud, 1 +hide.me, 1 +hideallip.com, 1 +hidedd.com, 1 +hideouswebsite.com, 1 +hidglobal.com, 1 +hidingin.space, 1 +hidrolimpiadorasprofesionales.org, 1 +hidroshop.com.br, 1 +hidroshoping.com.br, 1 +hieisuki.ga, 1 +hielscher.com, 1 +hien.cf, 1 +hierden-bosch.nl, 1 +hierer.com, 1 +hieu.com.au, 1 +hif88.com, 1 +hifala.de, 1 +hiffo.de, 1 +hifiaudio.sk, 1 +hifiphile.com, 1 +hifly.aero, 1 +hifly.com.tw, 1 +hifumi.us, 1 +hig.gov, 1 +higea.mx, 1 +higgsboson.tk, 1 +higgstools.org, 1 +high-flying.co.uk, 1 +high-heels.se, 1 +high-school-atka.ga, 1 +high-tech.tk, 1 +high-way.me, 1 +highaltitudearchery.com, 1 +highcorkett.com, 1 +highdaseo.ml, 1 +highdesertroboticsurgery.com, 1 +highdeserttinyhomes.com, 1 +highdonate.tk, 1 +higheducation.ml, 1 +highenergy.ro, 1 +higherpress.org, 1 +highgatejoinery.co.uk, 1 +highintegrity.tk, 1 +highinthemid80s.com, 1 +highkick.jp, 1 +highland-webcams.com, 1 +highlandparkcog.org, 1 +highlandpublicschool.co.in, 1 +highlandsfl.gov, 1 +highlandsmode.nl, 1 +highlatitudestravel.com, 0 +highlevelwoodlands.com, 1 +highlightsfootball.net, 1 +highlnk.com, 1 +highnation.ml, 1 +highplainssiding.com, 1 +highqappliance.com, 1 +highriskpay.com, 1 +highspeed-arnsberg.de, 1 +highspenfc.tk, 1 +hightech.construction, 1 +hightechbasementsystems.com, 1 +hightechone.cf, 1 +hightechreviews.ga, 1 +hightimes.com, 1 +highway11north.tk, 1 +highway54.tk, 1 +highwaytohoell.de, 1 +highwayzen.org, 1 +higilopocht.li, 1 +higleyarts.org, 1 +higueras.tk, 1 +hik-cloud.com, 1 +hikagestudios.com, 1 +hikawa.top, 1 +hike.pics, 1 +hikeinrio.com, 1 +hiker.cool, 1 +hikerone.com, 1 +hikikomori-sos.site, 1 +hikka.ru, 1 +hilahdih.cz, 1 +hilalnews.ga, 1 +hilaolu.com, 1 +hilarious.ga, 1 +hilaryhutler.com, 1 +hilde.link, 1 +hilden.ws, 1 +hiledge.com, 1 +hilfe-bei-krebs-vechta.de, 1 +hill.selfip.net, 1 +hillcountryoralsurgery.com, 1 +hillcrestplumber.co.za, 1 +hillcrestswimclub.com, 1 +hillexplorer.com, 1 +hillier-swift.co.uk, 1 +hillner.eu, 1 +hillroadgarage.tk, 1 +hillsandsaunders.co.uk, 1 +hillsandsaunders.com, 1 +hillsboroccpa.org, 1 +hillshandymate.com, 0 +hillsphotosoc.tk, 1 +hillstrak.com.au, 1 +hillstrakwpg.com.au, 1 +hilltopcellar.com, 1 +hilltopsurgicalhospital.ga, 1 +hilnu.com, 1 +hiltonhylandluxurycondos.com, 1 +hiltonsydney.com.au, 1 +hilunetan.tk, 1 +himalaya-masala.at, 1 +himalayanoutback.com, 1 +himalayanyogashram.com, 1 +himarijuana.tk, 1 +himbak.com, 1 +himcy.ga, 1 +himecorazon.com, 1 +himekomi.com, 1 +himg.eu, 1 +himgdz.ru, 1 +himiku.com, 1 +himlamcorp.vn, 1 +himpler.com, 0 +hin10.com, 1 +hinaryazan.com, 1 +hinata-hidetoshi.com, 1 +hindibaba.tk, 1 +hindigalaxy.com, 1 +hindimeinjankari.com, 1 +hindimoviedownload.net, 1 +hindu-temple.tk, 1 +hindustantimes.ml, 1 +hinduworld.tk, 1 +hingehealth.com, 1 +hingle.me, 1 +hinksonlabs.com, 1 +hintergrundbewegung.de, 1 +hinterposemuckel.de, 1 +hintss.pw, 0 +hinyari.net, 1 +hiparish.org, 1 +hipeople.com.br, 1 +hiper-humor.tk, 1 +hiperbusinessblog.hu, 1 +hipercultura.com, 1 +hipermenu.com, 1 +hipersuli.hu, 1 +hiperusera.es, 1 +hiphop.ren, 1 +hiphopfashion.tk, 1 +hipnos.net, 1 +hipo.pt, 1 +hippiekiller.net, 1 +hippies.com.br, 1 +hippomovers.com, 1 +hippopotamuses.org, 1 +hips.com, 1 +hipstercat.fr, 0 +hiq.sh, 1 +hiqhub.co.uk, 0 +hiqonline.co.uk, 1 +hiranosayuri-piano.com, 1 +hiratake.xyz, 1 +hireabouncycastle.net, 1 +hirecities.ml, 1 +hirel.gq, 1 +hireprofs.com, 1 +hiresteve.ca, 1 +hireteen.com, 1 +hirevets.gov, 1 +hirevo.eu, 1 +hirevue.com, 1 +hirezzportal.com, 1 +hirisejanitorial.com, 1 +hirmozaik.com, 1 +hirobbie.com, 1 +hiromuogawa.com, 1 +hirosehp.jp, 1 +hirotaka.org, 1 +hirsch-lawyer.tk, 1 +hirschl.eu, 1 +hirte-digital.de, 0 +hirtz.pm, 1 +hirunet.ml, 1 +hisax.de, 1 +hisbrucker.net, 1 +hiseplast.com.br, 1 +hisgifts.com.au, 1 +hispadent.com.do, 1 +hispalazarus.tk, 1 +hispania-valencia.com, 1 +hispania.ml, 1 +hispanic.dating, 1 +hispasat.es, 1 +hispasys.com, 1 +hisregistries.com, 1 +hisregistries.net, 1 +hisregistries.org, 1 +histhist.ru, 1 +histkult.ml, 1 +histkult.tk, 1 +histogames.com, 1 +histoire-cite.ch, 0 +histoiresdecontenu.com, 0 +histoiresdemotos.fr, 1 +historia-arte.com, 1 +historiadebagua.tk, 1 +historiaeculturaguarani.org, 1 +historiageneral.com, 1 +historiasdepueblo.es, 1 +historiasyrelatos.tk, 1 +historichousesghent.be, 1 +historicizam.tk, 1 +historischehuizengent.be, 1 +historischhout.nl, 1 +history-schools.com, 1 +history-vision.tk, 1 +history.google.com, 1 +history.gov, 1 +history.pe, 1 +historymuseumsb.org, 1 +hitafterhitentertainment.com, 1 +hitandhealth.nl, 1 +hitchpin.com, 1 +hitchunion.org, 1 +hitechgr.eu, 1 +hitechweirdo.com, 0 +hiteshbrahmbhatt.com, 1 +hiteshchandwani.com, 1 +hiteshjoshi.com, 1 +hitflow.fr, 1 +hitflow.net, 1 +hitfm.ml, 1 +hitfm.tk, 1 +hithardnews.com, 1 +hithouse.tk, 1 +hititgunesi-tr.com, 1 +hitleap.com, 1 +hitmaker.ga, 1 +hitmaker.tk, 1 +hitmanstat.us, 1 +hitmyheart.tk, 1 +hitn.at, 1 +hitocom.net.br, 1 +hitokoto-mania.com, 1 +hitokoto.cn, 1 +hitomecha.com, 1 +hitpointer.tk, 1 +hitpt.com, 1 +hitrek.ml, 1 +hitrost.com, 1 +hitrow-move.ga, 1 +hitter-lauzon.com, 1 +hitter.family, 1 +hitterfamily.com, 1 +hittop.tk, 1 +hitvibes.com, 1 +hiv-symptome.de, 1 +hiv.com.tw, 1 +hiv.gov, 1 +hivatal-info.hu, 1 +hivault.cf, 1 +hive101.info, 1 +hivehub.no, 1 +hivekey.eu, 1 +hivekey.io, 1 +hiveopolis.eu, 1 +hiverlune.net, 1 +hivesigner.com, 1 +hiwannz.com, 1 +hiwebsite.tk, 1 +hiwiki.tk, 1 +hiyacar.co.uk, 1 +hiyobi.me, 1 +hizzacked.xxx, 1 +hj-mosaiques.be, 1 +hj.rs, 1 +hj111777.com, 0 +hj2375.com, 0 +hj2565.com, 1 +hj3586.com, 0 +hj3639.com, 0 +hj5386.com, 0 +hj555.cc, 1 +hj556.cc, 1 +hj6298.com, 0 +hj6585.com, 1 +hj6929.com, 0 +hj9379.com, 1 +hj99111.com, 1 +hj99188.com, 1 +hj99333.com, 0 +hjallboscoutkar.se, 1 +hjartasmarta.se, 1 +hjdiaz.com, 1 +hjelmqvist-it.se, 1 +hjelpemiddeldatabasen.no, 1 +hjertingfysioterapi.dk, 1 +hjes.com.ve, 1 +hjkbm.cn, 1 +hjmag.com, 1 +hjort.land, 1 +hjosh.com, 1 +hjphoto.co.uk, 1 +hjstudio.co, 1 +hjtky.cn, 1 +hjw-kunstwerk.de, 1 +hjyl.xn--fiqs8s, 0 +hjyl1999.com, 0 +hjyl2828.com, 0 +hjyl299.com, 0 +hjyl699.com, 0 +hjyl7999.com, 0 +hjyl9898.com, 0 +hk.search.yahoo.com, 0 +hkas.org.hk, 1 +hkl-gruppe.de, 1 +hklbgd.org, 1 +hkmap.co, 1 +hkmap.com, 1 +hkmap.live, 1 +hkmap.net, 1 +hkno.it, 1 +hkoreatv.gq, 1 +hkr.at, 1 +hks.pw, 1 +hktech.com, 1 +hktkl.com, 1 +hktss.pp.ua, 1 +hkustmbajp.com, 1 +hl8id.vip, 1 +hl8th.vip, 1 +hlavacek.us, 1 +hlavi.hu, 1 +hledejlevne.cz, 1 +hledejpravnika.cz, 1 +hlfh.space, 1 +hlg66.cc, 1 +hlg88.cc, 1 +hlidani-tornado.cz, 1 +hlin.cloud, 0 +hloe0xff.ru, 1 +hlpublicidad.com, 1 +hls-tutorial.tk, 1 +hlsblog.com, 1 +hlsjgw.com, 1 +hlsmandarincentre.com, 1 +hltk.fi, 1 +hlucas.de, 1 +hlx66.cc, 1 +hlx86.cc, 1 +hly0928.com, 1 +hlz.mn, 1 +hm-notes.ru, 1 +hm1ch.com, 1 +hm1ch.ovh, 1 +hm773.net, 1 +hm773.org, 1 +hmcdj.cn, 1 +hmeonot.org.il, 0 +hmnd.io, 1 +hmoegirl.com, 1 +hmri.org.au, 1 +hms-waldmann.de, 1 +hmsseahawk.com, 0 +hn.search.yahoo.com, 0 +hn122.cc, 1 +hndmd.com, 1 +hnfertilizermachine.com, 1 +hnn.net.br, 1 +hno-norderstedt.de, 1 +hnonline.sk, 1 +hnrk.io, 1 +hnsseed.com, 1 +hntuin.nl, 1 +hnyp.hu, 1 +ho18.net, 1 +ho188.net, 1 +ho518.net, 1 +ho918.net, 1 +hoaas.no, 1 +hoahau.org, 1 +hoanghaiauto.vn, 1 +hoarding.me, 1 +hoathienthao.com, 1 +hoathienthao.vn, 1 +hob.bi, 1 +hobbiesworld.tk, 1 +hobbslanddevelopment.com, 0 +hobby-drechselei.de, 1 +hobby-freizeit.de, 1 +hoberg.ch, 1 +hobindesign.com, 1 +hobokenrecords.tk, 1 +hocgiai.com, 1 +hochhaus.us, 1 +hochoukikikiraku.com, 1 +hochstift-party.de, 1 +hochuvrotik.cf, 1 +hochyi.com, 1 +hochzeit-dana-laurens.de, 1 +hochzeit-saufzeichnungen.tk, 1 +hochzeitsfotograf-deinfoto.ch, 1 +hochzeitsplaner-rodgau.de, 1 +hochzeitsplanerin-hamburg.de, 1 +hochzeitstypen.de, 1 +hockey.academy, 1 +hockeyapp.ch, 1 +hockeycircles.com, 1 +hockeymotion.ch, 0 +hockeypartner.no, 1 +hocoma.com.mx, 1 +hocoma.eu, 1 +hocoma.net, 1 +hocoma.org, 1 +hocomamedical.com, 1 +hoctienganhgiaotiep.ga, 1 +hoctracnghiem.com, 1 +hocz.net, 1 +hodeis.ga, 1 +hodeys.com, 1 +hodgephotography.com, 1 +hoe.re, 1 +hoeft-autolackierung.de, 1 +hoeheterobenjij.nl, 1 +hoekvanholland.eu, 1 +hoelty.network, 1 +hoeren.club, 1 +hoesnelwasik.nl, 1 +hoest.it, 1 +hoeveiligismijn.nl, 1 +hoevenstein.nl, 0 +hoewler.ch, 0 +hof-imbiss-lieske.de, 1 +hof-mulin.ch, 1 +hofapp.de, 1 +hofauer.de, 1 +hoffmancorporation.com, 1 +hoffmeyer.me, 1 +hoffnungberlin.de, 1 +hoffnungdeutschland.de, 1 +hofiprojekt.cz, 1 +hoflerlawfirm.com, 1 +hofmannenhofmann.nl, 1 +hofstaetter.io, 1 +hogarthdavieslloyd.com, 1 +hoge.se, 1 +hogepad.com, 0 +hogerduinen.tk, 1 +hogl.dk, 1 +hogrebe.de, 1 +hogvorts.tk, 1 +hogwarts.io, 1 +hohenleimbach.de, 1 +hohenpoelz.de, 1 +hohma.tk, 1 +hohnet.com, 0 +hoing.io, 1 +hoiquanadida.com, 1 +hoistfinance.co.uk, 1 +hoistsdirect.com, 1 +hoken-okazaki.com, 1 +hoken-wakaru.jp, 1 +hokenselect.jp, 1 +hokioisecurity.com, 1 +hokkaido.tk, 1 +hokung.xyz, 1 +hokusya.com, 1 +holacannx.com, 1 +holacbdoils.com, 1 +holadinero.es, 1 +holadinero.mx, 1 +holboxwhalesharktours.com, 1 +holdengreene.com, 1 +holdiers.tk, 1 +holdingcelebrations.tk, 1 +holdmybeer.io, 1 +holdport.com, 1 +holebedeljek.hu, 1 +holger-schwarze.de, 1 +holgerlehner.com, 1 +holi-coresdaindia.com.br, 1 +holidayclub.tk, 1 +holidayexcess.com, 1 +holidayincotswolds.co.uk, 1 +holidaylocal.ga, 1 +holidays-info.com, 1 +holidaysportugal.eu, 1 +holidaytable.tk, 1 +holidaytours.tk, 1 +holine.studio, 1 +holini.com, 0 +holisticacupuncture.com.au, 1 +holisticdevelopmentagency.ml, 1 +holistichealer.in, 1 +holisticon.de, 1 +holiy.jp, 1 +hollabanken.cf, 1 +holland-sailing.de, 1 +hollandhouse.info, 1 +hollandsewolken.nl, 1 +hollermann.eu, 1 +hollidays.tk, 1 +hollowpoint.xyz, 1 +hollowrap.com, 1 +hollowwinds.xyz, 1 +hollybanks.net, 1 +hollyforrest.ca, 1 +hollyforrestphotography.ca, 1 +hollywoodstars.tk, 1 +hollyworks.com, 1 +holmesian.org, 1 +holmesworkholding.co.uk, 1 +holmq.dk, 1 +holo.ovh, 1 +holocron.one, 1 +holod-servis777.tk, 1 +holofono.com, 1 +holofox.ru, 1 +holostyak.tk, 1 +holowaty.me, 1 +holoxplor.space, 1 +holstphoto.com, 1 +holtackersleather.be, 1 +holtslander.ca, 1 +holubowski.com, 1 +holundersberg.de, 1 +holvonix.com, 1 +holycrosscatholics.org, 1 +holycrossphl.org, 1 +holycrossrockporttx.org, 1 +holycrossverobeach.org, 1 +holydragoon.jp, 1 +holyfamilyrussell.org, 1 +holyghost-church.org, 1 +holygrail.games, 0 +holygrove.tk, 1 +holyhiphopdatabase.com, 1 +holymartyrschurch.org, 1 +holyriders.cf, 1 +holyscriptur.es, 1 +holyspiritpalmyra.com, 1 +holyspiritweb.org, 1 +holytransaction.com, 1 +holywhite.com, 1 +holywr.it, 1 +holz.nu, 1 +holzed.com, 1 +holzschutz-holzbearbeitung.de, 1 +holzspielzeug-shop.ch, 1 +holzstueckwerk.de, 1 +holzundgarten.de, 1 +homa.website, 0 +homake.cf, 1 +homatism.com, 1 +hombresconestilo.com, 1 +home-cloud.online, 1 +home-insurance-quotes.tk, 1 +home-ncj.com, 1 +home-page.xyz, 1 +home-portal.tk, 1 +home-remedies.tk, 1 +home-style.hu, 1 +home-sud-renovation.com, 0 +home-v.ind.in, 1 +homeable.io, 1 +homeadore.com, 1 +homeadvice.tk, 1 +homeairguides.com, 1 +homeandliving.it, 1 +homeautomated.com, 1 +homebank.kg, 1 +homebasedsalons.com.au, 1 +homebrew.tk, 1 +homebrewshop.be, 1 +homebuilder.tk, 1 +homebutton.tk, 1 +homecareassociatespa.com, 1 +homecaring.com.au, 1 +homecheck.gr, 1 +homecinema-fr.com, 1 +homecoming.city, 1 +homecompost.in, 1 +homecpr.com.au, 1 +homedatacenter.com.br, 0 +homedecorspecialists.com, 1 +homedentist.cl, 1 +homedev.cf, 1 +homedeveloper.gq, 1 +homedeveloper.ml, 1 +homeehome.com, 1 +homefacialpro.com, 0 +homefarmhealesville.com.au, 1 +homeforum.tk, 1 +homegardendecoration.tk, 1 +homegardeningforum.com, 1 +homegardenresort.nl, 1 +homegreenmark.com, 1 +homehunting.pt, 1 +homeimagician.com.au, 1 +homeimprovement.ga, 1 +homeinet.tk, 1 +homeinformation.tk, 1 +homelab.farm, 1 +homelandsecurity.gov, 1 +homeloanprequalify.com, 1 +homem-viril.com, 1 +homemadetips.ga, 1 +homemediadb.org, 1 +homen.in, 1 +homenature.tk, 1 +homeodynamics.com, 1 +homeoesp.org, 1 +homeofjones.net, 1 +homeogenium.com, 0 +homeopathie.tk, 1 +homeostase.pt, 1 +homeownersinsurancenv.com, 1 +homepage.shiga.jp, 1 +homepal.ga, 1 +homeplace.in, 1 +homeporn.stream, 1 +homeportal.cz, 1 +homeprivate.de, 1 +homeprivate.net, 1 +homequipment.com, 1 +homero.tk, 1 +homeschoolinkorea.tk, 1 +homeseeds.nl, 1 +homeseller.com, 1 +homeserver-kp.de, 1 +homeservices.ro, 1 +homesforaustralia.ga, 1 +homeshowoff.com, 1 +homestead-honey.com, 1 +homesteadfarm.org, 1 +hometechmtl.com, 1 +hometeenorgy.com, 1 +hometunnel.de, 0 +homewarrantyreviews.com, 1 +homewatt.co.uk, 1 +homeworkacers.com, 1 +homeworld.ga, 1 +homeyou.com, 1 +homeyx.cf, 1 +homezlog.com, 1 +hommeatoutfaire.be, 0 +homnest.fr, 0 +homo.ga, 1 +homofo.tk, 1 +homoglyph.net, 1 +homoo.social, 1 +homophobia.tk, 1 +homophones.ml, 1 +homophoni.com, 1 +homowank.com, 1 +hompus.nl, 0 +homs.design, 1 +homunyan.com, 1 +homyak.gq, 1 +homyneeds.com, 1 +homyremedies.com, 1 +honda-centrum.cz, 1 +hondart.cz, 1 +hondenoppasfraneker.nl, 1 +honey.beer, 1 +honey.is, 1 +honeybadger.io, 0 +honeybhealthyliving.com, 1 +honeycomb.com.vn, 1 +honeycomb.io, 1 +honeycombcreative.com, 1 +honeycome-recruit.com, 1 +honeycome.net, 1 +honeycreeper.com, 1 +honeymaze.com, 1 +honeypot.net, 1 +honeyspot.de, 1 +honeytracks.com, 1 +hong.com.br, 1 +hong.io, 0 +hongbomiao.com, 1 +hongfumall88.com, 1 +hongki.tk, 1 +hongkongliberate.com, 1 +hongkongwillwin.com, 1 +hongorw.tk, 1 +hongosdemexico.tk, 1 +honguyensy.tk, 1 +hongyun-rent.com, 1 +hongzu.cc, 1 +hongzuwang.com, 1 +hongzuzhibo.com, 1 +honigconte.com, 1 +honigkuchenpferdeher.de, 1 +honkhonk.net, 1 +honkion.net, 1 +honnedechuju.com, 1 +honoka-seitai.jp, 1 +honoka.tech, 1 +honovere.de, 1 +hontoir.eu, 1 +hoodoo.io, 1 +hoodoo.tech, 1 +hoodrivercounty.gov, 1 +hoodtrader.com, 1 +hoofdredacteuren.nl, 1 +hoogelandzorg.nl, 1 +hoogeveen.nl, 0 +hooghiemstrazelf.nl, 1 +hoogstraatseschaakclub.tk, 1 +hoogveen.tk, 1 +hookahfoil.ru, 1 +hookahshop.lt, 1 +hookbin.com, 1 +hookshotdesign.com, 1 +hooliganka.tk, 1 +hooliganz.tk, 1 +hoon.tk, 1 +hoooc.com, 1 +hooowl.com, 1 +hoop.la, 1 +hooperlabs.xyz, 1 +hoopertechnicalsolutions.com, 1 +hooplessinseattle.com, 1 +hoopshabit.com, 1 +hooray.beer, 1 +hoorig.de, 1 +hoosa.de, 1 +hoosierstateofmind.com, 1 +hootworld.net, 0 +hoovism.com, 1 +hopconseils.ch, 0 +hopconseils.com, 0 +hope21.ch, 1 +hopefultexas.com, 1 +hopeland.com.br, 1 +hopemeet.info, 1 +hopemeet.me, 1 +hopeofmyheart.com, 1 +hopesanddreams.org.uk, 1 +hopeworld.pro, 1 +hopglass.eu, 1 +hopglass.net, 1 +hopkinsmediation.com, 1 +hopkintonri.gov, 1 +hoplongtech.com, 1 +hopo.design, 1 +hoponmedia.de, 1 +hopps.me, 1 +hoppyx.com, 1 +hopzone.net, 1 +hor.website, 1 +horaceli.com, 1 +horaciolopez.pro, 1 +horackova.info, 1 +horairetrain.be, 1 +horairetrain.ch, 1 +horairetrain.fr, 1 +horairetrain.lu, 1 +horairetrain.nl, 1 +horcajadadelatorre.tk, 1 +horclan.tk, 1 +hord.ca, 1 +horde-entertainment.tk, 1 +horecaapparatuurkobezuijen.nl, 1 +horecatiger.eu, 1 +horeco.com, 1 +horeizai.net, 1 +horgenberg.com, 1 +horikawa-cement.co.jp, 1 +horizon.ne.jp, 1 +horizonlawncare.tk, 1 +horizonmail.ga, 1 +horizonresourcesinc.com, 1 +horizonshypnosis.ca, 0 +horizontalsystems.io, 1 +horkel.cf, 1 +horn.co, 1 +hornblower.tk, 1 +hornburg.io, 1 +hornertranslations.com, 1 +hornetsecurity.com, 1 +horny-gay-dragons.com, 1 +hornyforhanzo.com, 1 +horo.me, 0 +horoca.net, 1 +horochx.org, 1 +horodance.dk, 1 +horos.es, 1 +horoscopimages.tk, 1 +horoscopos-amor.com, 1 +horozo.com, 1 +horrell.ca, 1 +horrendous-servers.com, 1 +horror-forum.de, 1 +horrormovies.gr, 1 +horrorserv.com, 1 +horrycountysc.gov, 1 +horseboxheaven.uk, 1 +horsebreeding.tk, 1 +horseconsult.com, 1 +horsegateway.com, 1 +horsehead.tk, 1 +horsehunter.co.uk, 1 +horseplanet.tk, 1 +horsky.me, 1 +horstmanshof.eu, 1 +horstmanshof.nl, 1 +horti-it.com, 1 +horton-brasses.com, 1 +horvathd.eu, 1 +horvatia.tk, 1 +horvatnyelvkonyv.hu, 1 +hory.me, 1 +horza.org, 1 +hoshimaq.com.br, 1 +hoshimaquinas.com.br, 1 +hoshinplan.com, 1 +hoshisato.com, 1 +hosiery.tk, 1 +hosmussynergie.nl, 0 +hosoi-tax.com, 1 +hospitalcmq.com, 1 +hospitality-colleges.com, 1 +host-morezar.ml, 1 +host2100.xyz, 1 +host4us.cc, 1 +hostadvice.com, 1 +hostalbarelgato.es, 1 +hostarea51.com, 1 +hostathome.fr, 1 +hostatic.com, 1 +hostcloud.ml, 1 +hostco.nl, 1 +hostcoz.com, 1 +hostdaddyhn.com, 1 +hosteasy.nl, 0 +hosted-power.com, 1 +hostedcomments.com, 1 +hostedghost.eu, 1 +hostedghost.net, 1 +hostedghost.nl, 1 +hostedghost.org, 1 +hostedtalkgadget.google.com, 1 +hostelacion.com, 1 +hostelaciones.com, 1 +hosteleriauno.es, 1 +hostelxaxid.si, 1 +hosteons.com, 1 +hostfact.nl, 1 +hostfission.com, 1 +hostfree12.tk, 1 +hostiberi.com, 0 +hostinecpodlipou.cz, 1 +hosting-rus.tk, 1 +hosting-swiss.ch, 1 +hostingactive.it, 1 +hostingalternative.com, 0 +hostingdiario.com, 1 +hostingdirectory.ga, 1 +hostingelite.tk, 1 +hostingfirst.nl, 1 +hostinghelp.guru, 1 +hostinginnederland.nl, 1 +hostinglogin.net, 1 +hostingphp.ch, 1 +hostingplussize.cloud, 1 +hostingsrv.nl, 1 +hostingsupremo.com, 1 +hostingsvizzera.com, 1 +hostingtg.com, 1 +hostingtipps.eu, 1 +hostinkos.com, 1 +hostinvest.tk, 1 +hostix.de, 1 +hostker.com, 1 +hostma.ma, 1 +hostmijnpagina.nl, 1 +hostmodern.com.au, 1 +hostonssd.ga, 1 +hostpoint-static.ch, 1 +hostpoint.ch, 1 +hostreputation.com, 1 +hostwinds.com, 1 +hosuto.nl, 1 +hot-and-new.gr, 1 +hot-models.tk, 1 +hot-spa.ch, 0 +hot100.ug, 1 +hot101fm.tk, 1 +hotbabe.ml, 1 +hotcandlestick.com, 1 +hotcars.com, 1 +hotchillibox.com, 1 +hotdates18.com.au, 1 +hotdates18.dk, 1 +hotdates18.fi, 1 +hotdoc.com.au, 1 +hotdresses.ga, 1 +hotel-alan.hr, 1 +hotel-bella-muerte.tk, 1 +hotel-du-parc-allevard.fr, 1 +hotel-kontorhaus-stralsund.de, 1 +hotel-kontorhaus.de, 1 +hotel-kronjuwel.de, 1 +hotel-le-vaisseau.ch, 0 +hotel-promyk.pl, 1 +hotel-rosner.at, 1 +hotel-schiller.de, 0 +hotelamgarnmarkt.at, 0 +hotelarevalo.com, 1 +hotelbiz.gq, 1 +hotelbonacabol.com, 1 +hotelbretagne.dk, 1 +hotelcoliber.pl, 1 +hotelconsulado.com.br, 1 +hotelcorporate.codes, 1 +hotelcorporatecodes.com, 1 +hoteldahu.it, 1 +hoteldimorae.it, 1 +hoteldvorik.ml, 1 +hotelelaphusabrac.com, 1 +hoteles4you.com, 1 +hotelevershine.com, 1 +hotelfloresta.tk, 1 +hotelfloridachaco.com, 1 +hotelflow.com.br, 1 +hotelident.de, 1 +hotelitalia.tk, 1 +hotelkaj.hr, 1 +hotello.io, 1 +hotelmadhuwanvihar.com, 1 +hotelmap.com, 1 +hotelmarinaadria.com, 1 +hotelmonal.in, 1 +hotelneptundalmatien.com, 1 +hotelpostaorvieto.it, 1 +hotelpresident.co.in, 1 +hotelpromo.codes, 1 +hotelreis.com.br, 1 +hotels-insolites.com, 1 +hotels3d.com, 1 +hotels4teams.com, 1 +hotelsalzberg.ml, 1 +hotelsantalibera.tk, 1 +hotelsfares.com, 1 +hotelsinformer.com, 1 +hotelsinncoventry.com, 1 +hotelsolinebrela.com, 1 +hotelsonline.tk, 1 +hotelsrit.tk, 1 +hotelstanford.com.co, 1 +hotelsupport.one, 1 +hotelv.ru, 1 +hotelvalena.com, 1 +hotesb.net, 1 +hothbricks.com, 1 +hothiphopmusic.com, 1 +hothub.net, 1 +hotiii.ga, 1 +hotjuice.com, 1 +hotlistproducts.com, 0 +hotlog.tk, 1 +hotmann.de, 1 +hotnewhiphop.com, 1 +hotnewsnl.tk, 1 +hoton.in, 1 +hotornot.com, 1 +hotperiscope.tk, 1 +hotplate.co.nz, 1 +hotpopky.cf, 1 +hotrender.com, 1 +hotroviettel.vn, 1 +hotrowordpress.com, 0 +hotscripting.tk, 1 +hotsexvids.net, 1 +hotsmi.cf, 1 +hotsoft.com.br, 1 +hotsolarsolutions.com, 1 +hottaro.com, 1 +hottestguyoftech.com, 1 +hottestwebcamgirls.org, 1 +hottheme.net, 1 +hotting.nl, 1 +hottoys.tk, 1 +hottubspasnewcastle.co.uk, 1 +hotvideosgalleries.com, 1 +hotwifer.com, 1 +houhuayuan.com, 1 +houlang.ac.cn, 1 +houndsquare.com, 1 +hourai.gg, 1 +houraiteahouse.net, 1 +house-cleaning-howtos.com, 1 +house-sparrow.com, 1 +houseandgarden.co.uk, 1 +housecarty.com, 1 +housedesigninfo.tk, 1 +houseepropiedadraiz.com, 1 +household-appliances.tk, 1 +householdheroes.com.au, 1 +housekeeperlondon.co.uk, 1 +houselocal.co.uk, 1 +housemart.company, 1 +housemates.uk.com, 1 +housemouse.tk, 1 +houseofaceonline.com, 1 +houseofannubis.com, 1 +houseofhouston.com, 1 +houseofpertijs.com, 1 +houser.lu, 1 +houseracko.com, 1 +housese.at, 1 +housingloan.jp, 1 +houstonapartmentinsiders.com, 1 +houstonauthorizedrepair.com, 1 +houstoncreditlaw.com, 1 +houstondiabetesinstitute.org, 1 +houstonendodontics.com, 1 +houstongaragedoorsrepair.com, 1 +houstonhomerevival.com, 1 +houstonlockout.com, 1 +houthandelbunskoek.nl, 1 +houthandeljacobs.nl, 1 +houtinee.com, 1 +hoverboardbarato.com, 1 +hovset.net, 1 +how-old.info, 1 +how-to-blog.xyz, 1 +how-to-build-computer.tk, 1 +how-to-simply.com, 1 +how-to-write-a-book.gq, 1 +how10.com, 1 +how2dev.tools, 1 +how2fsbo.com, 1 +how2recycle.info, 1 +howa-n.net, 0 +howardhannava.com, 1 +howardscholars.org, 1 +howbehealthy.com, 1 +howbigismybuilding.com, 1 +howdybikes.com, 1 +howellaccounts.co.uk, 1 +howesky.com, 1 +howgoodwasmysex.com, 1 +howieisawesome.com, 1 +howinsider.com, 1 +howlers.tk, 1 +howlingbasset.co.uk, 1 +howlinhawk.tk, 1 +howlongtobeatsteam.com, 1 +howmanymilesfrom.com, 1 +howmanypeoplearethereinthe.world, 1 +howmanypeoplearethereintheworld.com, 1 +howmuch.cf, 1 +howmuch.ga, 1 +howonce.cn, 1 +howonce.com, 1 +howonce.com.cn, 1 +howonce.net, 1 +howonce.org, 1 +howsame.com, 0 +howsecureismypassword.net, 1 +howsmyssl.com, 1 +howsmytls.com, 1 +howsyourhealth.org, 1 +howtobehealthy.tk, 1 +howtocurekennelcough.com, 1 +howtodesignwebsite.com, 1 +howtofixwindows.com, 1 +howtofreelance.com, 1 +howtogeek.com, 1 +howtogeekpro.com, 1 +howtogosolar.org, 0 +howtohomepage.tk, 1 +howtolaser.com, 1 +howtomovetheneedle.com, 1 +howtopronounce.com, 1 +howtorunfasterandlonger.com, 1 +howtostopsnoring.tk, 1 +howtoteachviolin.com, 1 +howtotech.de, 1 +howtrainyourdog.ml, 1 +howtutu.click, 1 +howtutu.com, 1 +howtutu.email, 1 +howtutu.eu, 1 +howtutu.info, 1 +howtutu.link, 1 +howtutu.net, 1 +howtutu.org, 1 +howudoin.tk, 1 +howunadeydoam.ng, 1 +hoxo.fr, 1 +hoymedivorcio.com, 1 +hozana.si, 0 +hozinga.de, 1 +hp-67.com, 1 +hp-lexicon.org, 1 +hp-work.net, 0 +hp42.de, 1 +hpac-portal.com, 1 +hpage.com, 1 +hpbn.co, 1 +hpeditor.tk, 1 +hpepub.com, 0 +hpic.net, 1 +hpisavageforum.com, 1 +hpkp-faq.de, 1 +hplace.com.br, 1 +hpneo-conseil.com, 1 +hps.digital, 1 +hps.hu, 1 +hpsdigital.hu, 1 +hpvtimmerwerken.nl, 1 +hq.marketing, 1 +hq77.ru, 1 +hqblog.cn, 0 +hqmovies.club, 1 +hqq.tv, 1 +hqteas.com, 1 +hquest.pro.br, 1 +hqwebhosting.tk, 0 +hqy.moe, 1 +hr-automation.eu, 1 +hr-clan.tk, 1 +hr-praemien-santander.de, 1 +hr-tech.shop, 1 +hr-tech.store, 1 +hr98.tk, 1 +hrabogados.com, 1 +hraesvelg.net, 1 +hrafnkellbaldurs.com, 1 +hranicka.cz, 1 +hrbanen.nl, 1 +hrbatypes.cz, 1 +hrbl.lc, 1 +hrbrt.co, 1 +hrbrt.nl, 1 +hrcrew.com.au, 1 +hrdns.de, 0 +hrebecek.cz, 1 +href.one, 1 +hreflang.info, 1 +hristijanspirovski.tk, 1 +hrjfeedstock.com, 1 +hrjfeedstock.org, 1 +hrjob.ml, 1 +hrka.cc, 1 +hrka.me, 1 +hrkfamilylaw.com, 1 +hrlab.de, 1 +hrlive.ga, 1 +hrmafia.ga, 1 +hrmg.agency, 1 +hrmn.xyz, 1 +hrmny.sh, 1 +hrna.moe, 1 +hrndz.io, 1 +hro.to, 1 +hrobert.hu, 1 +hroling.nl, 1 +hroschyk.cz, 1 +hrpage.ml, 1 +hrpregnancy.com, 1 +hrsa.gov, 1 +hrseoservice.com, 1 +hrstapps-dev.com, 1 +hrtech.shop, 1 +hrumka.net, 1 +hrw66.cc, 1 +hrxkauppa.fi, 1 +hryniewski.net, 1 +hryx.net, 1 +hs-arbeitsschutz.de, 1 +hs-flensburg.de, 1 +hs-group.net, 1 +hs7imports.com.br, 1 +hsappstatic.net, 1 +hschen.top, 0 +hscorp.de, 1 +hse-dev.com, 1 +hse-online.com, 1 +hsex.tv, 0 +hsimrall.com, 1 +hsivonen.com, 1 +hsivonen.fi, 1 +hsivonen.iki.fi, 1 +hsjccconference.ca, 1 +hskernel.com, 1 +hskin.top, 1 +hsmithsmithfield.co.uk, 1 +hsmr.cc, 1 +hsn-tsn.com, 1 +hsn.com, 1 +hsog.tk, 1 +hspinc.ca, 1 +hsr.gov, 0 +hsreformas.es, 1 +hsrm.cz, 1 +hsselite.com, 1 +hst.tc, 1 +hsts-preload-test.xyz, 1 +hsts.eu, 1 +hsts.me, 1 +hsts.ovh, 1 +hstspreload.appspot.com, 1 +hstspreload.com, 1 +hstspreload.de, 1 +hstspreload.me, 1 +hstspreload.org, 1 +hstudio.tk, 1 +hsturan.com, 1 +hszemi.de, 1 +ht.mk, 1 +htaccessbook.com, 1 +htaps.com, 1 +htb-email.co, 1 +htb-email.com, 1 +htb-email.uk.com, 1 +htb.click, 1 +htb.co.uk, 1 +htbemail.co, 1 +htbemail.co.uk, 1 +htbemail.com, 1 +htbemail.net, 1 +htbemail.org, 1 +htc.com, 1 +htcvina.com, 1 +htdcomputer.vn, 1 +hte.ovh, 1 +hti.digital, 1 +htikeagkyaw.com, 1 +htl.wiki, 1 +htlball.at, 1 +htmanager.fr, 1 +htmdom.com, 1 +html-code-generator.com, 1 +html-css.tk, 1 +html5.org, 1 +html5media.info, 1 +htmlacademy.ru, 1 +htmlandcss.tk, 1 +htmlcssphp.ga, 1 +htmlcssphp.gq, 1 +htmlcssphp.ml, 1 +htmlcssphp.tk, 1 +htmlnet.tk, 1 +htmlvalidator.com, 1 +htmlweb.ml, 1 +htmlyse.com, 1 +htmtools.com, 1 +htmue.org, 1 +htp2.top, 1 +htsure.ma, 0 +http-2.com, 1 +http2.pro, 1 +http3-hosting.de, 1 +http3.ch, 1 +http3.pro, 1 +httpd.gq, 1 +https-rulesets.org, 1 +https.dk, 1 +https.jetzt, 1 +https4all.org, 1 +httpsalarm.com, 1 +httpsarnemergan.ml, 1 +httpsecured.net, 1 +httpsecurityreport.com, 1 +httpsiseasy.com, 1 +httpsispisseasy.com, 1 +httpsnow.com, 1 +httpsnow.org, 1 +httpstaak.tk, 1 +httpstest.com, 1 +httpstest.eu, 1 +httpstest.nl, 1 +httpswatch.ca, 1 +httpswatch.eu, 1 +httpswatch.nl, 1 +httptest.net, 1 +htxnet.biz, 1 +hu-a-u.com, 1 +hu.search.yahoo.com, 0 +hu2ty.net, 1 +huabanxs.com, 1 +huagati.com, 1 +huahinpropertylisting.com, 1 +huang.nu, 1 +huangguancq.com, 1 +huanggulin.net, 1 +huangh.com, 1 +huangjia71.com, 1 +huangjia72.com, 1 +huangjia73.com, 1 +huangjia74.com, 1 +huangjia75.com, 1 +huangjia76.com, 1 +huangjia777.com, 1 +huangjia78.com, 1 +huangjia79.com, 1 +huangjiaint.com, 1 +huangjingjing.com, 1 +huangqifu.com, 1 +huangzenghao.cn, 0 +huangzenghao.com, 1 +huanqiu1988.com, 1 +huaqian.art, 1 +huashan.co.uk, 1 +huastecanetwork.com, 1 +huawenyy.com, 1 +huaxingui.com, 1 +huaxueba.com, 1 +hub.org.ua, 1 +hub24.com.au, 1 +hub385.com, 1 +hubanero.cz, 1 +hubapi.com, 1 +hubbroker.com, 1 +hubchain.com, 1 +hubchain.com.br, 1 +hubchain.fr, 1 +hubchain.io, 1 +hubchain.org, 1 +huber-informatik.de, 1 +hubok.net, 1 +hubovra.nl, 1 +hubrecht.at, 1 +hubspot.com, 1 +hubspot.de, 1 +hubspot.es, 1 +hubspot.fr, 1 +hubspot.jp, 1 +huchet.me, 1 +hucklebucks.com, 1 +huckletree.com, 0 +hudebnibazarmixer.cz, 1 +hudeem-vmeste.ml, 1 +hudhaifahgoga.co.za, 1 +hudobniny.net, 1 +hudrydum.cz, 1 +hudsonwi.gov, 1 +huduser.gov, 1 +huelvatrabaja.com, 1 +huemul.studio, 1 +huersch.com, 1 +huertoydesamparados.tk, 1 +hues-in-lee.de, 1 +huesers.de, 1 +huesitos.tk, 1 +hufa.nl, 1 +huffduffer.com, 1 +hugh-dancy.com, 1 +hughfitzgerald.com, 1 +hughtodd.ink, 1 +hugi.is, 1 +huglen.info, 1 +hugo.pro, 1 +hugo6.com, 1 +hugofs.com, 1 +hugolegrand.fr, 1 +hugolynx.fr, 0 +hugomilano.ga, 1 +hugonote.cf, 1 +hugonote.ga, 1 +hugonote.gq, 1 +hugonote.ml, 1 +hugonote.ovh, 1 +hugonote.tk, 1 +huguesblanchard.paris, 1 +huguesditciles.com, 0 +huh.gdn, 1 +huihui.moe, 1 +huininga.com, 1 +huininga.nl, 1 +huininga.org, 1 +huipc.com, 1 +huirongis.me, 1 +huisaandecosta.nl, 1 +huisartsen-ict.nl, 1 +huisartsenpraktijkheemraadssingel.nl, 1 +huisartsenpraktijksonmezer.nl, 1 +huisartsenpraktijkzonnehoed.nl, 1 +huisee.net, 1 +huiser.nl, 1 +huisjeboompje-baby.nl, 1 +huiskopenspanje.nl, 1 +huislaw.com, 1 +huislijn.nl, 1 +huissier-vosges.com, 1 +huit.re, 1 +huitaodang.com, 1 +huizenvlees.nl, 1 +hukkatavara.com, 1 +hulaginswoodworking.com, 1 +hulemaendihabitter.dk, 1 +hulet.tech, 1 +hulldevs.net, 1 +hullscp.co.uk, 1 +hullseals.space, 1 +huloveyou.com, 1 +hulpbijmarketing.nl, 1 +hulpmiddelenshop.nl, 1 +hulpverleningszonecentrum.be, 1 +hulsoft.co.uk, 1 +human-clone.com, 1 +human-parasites.tk, 1 +human-shinri.com, 1 +humanafterall.studio, 1 +humanenrich.com, 1 +humanesdemadrid.tk, 1 +humanewolf.com, 1 +humanexperiments.com, 1 +humanidad.tk, 1 +humanit.com.au, 1 +humanity.com, 1 +humanlocation.net, 1 +humans.io, 0 +humansense.nl, 1 +humanzee.com, 1 +humass.nl, 1 +humblebee.at, 1 +humblebee.be, 1 +humblebee.bg, 1 +humblebee.ch, 1 +humblebee.co.in, 1 +humblebee.co.uk, 1 +humblebee.com.mx, 1 +humblebee.com.ph, 1 +humblebee.cz, 1 +humblebee.dk, 1 +humblebee.es, 1 +humblebee.eu, 1 +humblebee.foundation, 1 +humblebee.fr, 1 +humblebee.gr, 1 +humblebee.hu, 1 +humblebee.ie, 1 +humblebee.it, 1 +humblebee.nz, 1 +humblebee.pl, 1 +humblebee.uk, 1 +humblebee.us, 1 +humblebeeshop.ca, 1 +humblebeeshop.com.au, 1 +humblecraft.tk, 1 +humbledot.com, 0 +humboldtcountynv.gov, 1 +humboldthomeguide.com, 1 +humboldtmfg.com, 1 +humdruma-recordingz.tk, 1 +humexe.com, 1 +humio.com, 1 +hummel.tk, 1 +hummingbird.services, 1 +hummy.tv, 1 +humor-web.tk, 1 +humor.ga, 1 +humorcheck.ga, 1 +humored.gq, 1 +humpchies.com, 1 +humpen.se, 1 +humppakone.com, 1 +humus.tk, 1 +hund.io, 1 +hundeformel.de, 1 +hundeverwaltung.de, 1 +hundhausen.de, 1 +hundimiento.com, 1 +hundter.com, 1 +hundur.tk, 1 +hungarian-united-church.tk, 1 +hungaryz.ml, 1 +hunger.im, 1 +hungryas.tk, 1 +hungryginie.com, 1 +huniverse.co, 1 +hunngard.com, 1 +hunqz.com, 1 +hunstoncanoeclub.co.uk, 1 +hunt.gs, 1 +huntcraft.ru, 1 +hunter-read.com, 1 +hunter.io, 1 +hunterjohnson.io, 1 +hunterkehoe.com, 1 +hunterscrolls.tk, 1 +huntertagog.de, 1 +huntexpired.com, 0 +huntingdonbouncers.co.uk, 1 +huntingdonlifesciences.com, 1 +huntingspirits.tv, 1 +huntingtonestateproperties.com, 1 +huntingtonwv.gov, 1 +huntsvillealtransit.gov, 1 +huntsvillecottage.ca, 1 +huntyourshitaround.com, 1 +huoduan.com, 1 +huohu-sports.com, 1 +huonit.com.au, 1 +huoqibaike.club, 1 +huotuyouxi.com, 1 +huoyankan.com, 1 +hup.hu, 0 +hupsa-kindermode.be, 1 +huracanvillegas.com, 1 +hurbascooter.com, 1 +hurd.is, 1 +hurinkazan2020.com, 1 +hurleyhomestead.com, 1 +huroji.com, 0 +huron.tk, 1 +hurricanecarroll.com, 1 +hurricanelabs.com, 0 +hurtigtinternet.dk, 1 +hus.gay, 1 +husakbau.at, 1 +hushbabysleep.com, 1 +hushfile.it, 1 +husic.net, 0 +husk.house, 1 +huskyeye.de, 1 +huskyinc.us, 0 +husmann.tech, 1 +husqvarnamoped.se, 1 +hussam.eu.org, 1 +hustl.nl, 1 +hustlehope.com, 1 +hustlerstate.tk, 1 +huto.ml, 1 +hutson-foods.com, 1 +huureensite.com, 1 +huurwoordenaar.nl, 1 +huutonauru.net, 1 +huwcbjones.co.uk, 1 +huwcbjones.uk, 1 +huwjones.me, 1 +huxcoconstruction.com, 1 +huxley.net, 1 +huyvu.nl, 1 +huzurmetal.net, 1 +hv-2020.de, 1 +hv-2020.online, 1 +hv-anmeldung.de, 1 +hv-huset.no, 1 +hv-online.net, 1 +hv-portal.de, 1 +hvanmeldung.de, 1 +hvanmeldung.online, 1 +hvdbox.de, 1 +hvenetworks.cf, 1 +hveradistributions.com, 1 +hverdagogkink.no, 1 +hvgg.de, 1 +hvh.no, 1 +hvhercules.tk, 1 +hvorschool.tk, 1 +hvrint.de, 1 +hvsdev.azurewebsites.net, 1 +hvt.com.au, 1 +hvtuananh.com, 1 +hvylya.net, 1 +hw8.eu, 1 +hw923.com, 1 +hwag-pb.de, 1 +hwholdsworth.com.au, 1 +hwjkk.com, 1 +hwlibre.com, 1 +hwsw.io, 1 +hwx8.com, 0 +hx-sun.com, 1 +hx56.cc, 1 +hx678.cc, 1 +hx77.cc, 1 +hxkvm.com, 1 +hxkvm.net, 1 +hxp.io, 1 +hxr404.cf, 1 +hxsf.me, 1 +hxying.com, 1 +hy1.com, 1 +hy88win.com, 1 +hyatt.com, 1 +hyb7.com, 1 +hybridiyhdistys.fi, 1 +hybridklubben.fi, 1 +hybridragon.net, 1 +hybridworld.tk, 1 +hybridworx.com, 1 +hybridworx.de, 1 +hybridworx.eu, 1 +hybridworx.net, 1 +hybridworx.org, 1 +hybrydowe-samochody.pl, 1 +hybula.com, 1 +hycken.com, 1 +hyckenberg.com, 1 +hyderabadonlinegifts.com, 1 +hydrabit.nl, 1 +hydrante.ch, 0 +hydrazin.pw, 1 +hydro17.com, 1 +hydroagro.pl, 1 +hydrochlorothiazide.gq, 1 +hydrochlorothiazide125.ga, 1 +hydrocloud.net, 1 +hydrocontrolsystems-janssenwaterproofing.com, 1 +hydrocontrolsystems.com, 1 +hydrogenplatform.com, 1 +hydrographicsocietybenelux.eu, 1 +hydroid.tk, 1 +hydrolyze.tk, 1 +hydronicheatingaustralia.com.au, 1 +hydronium.cf, 1 +hydronium.ga, 1 +hydronium.ml, 1 +hydronium.tk, 1 +hydroponicglobal.com.au, 1 +hydroturbine.info, 0 +hydroxide.net, 1 +hydrozone.fr, 1 +hyec.jp, 1 +hygh.tech, 1 +hygieneproclean.co.nz, 1 +hygo.com, 1 +hyhy1.com, 1 +hyhy2.com, 1 +hyhy7.com, 1 +hyhy80.com, 1 +hyhy82.com, 1 +hyhy83.com, 1 +hyhy85.com, 1 +hyhy89.com, 1 +hyhy98.com, 1 +hyk.me, 1 +hylians.com, 1 +hyllie.net, 1 +hymnsandverses.com, 1 +hyncice.com, 1 +hyndax.com.ar, 1 +hynek.me, 1 +hynerd.it, 1 +hyodyntamaton.site, 0 +hyparia.fr, 1 +hyparia.org, 1 +hype.tech, 1 +hypelifemagazine.com, 1 +hypemgmt.com, 1 +hyper-matrix.org, 1 +hyper-text.org, 1 +hyper.ai, 1 +hyper.lol, 1 +hyperalgesia.com, 1 +hyperautomotive.com.au, 1 +hyperblast-universe.tk, 1 +hyperbolic-mayonnaise-interceptor.ovh, 1 +hypercdn.de, 1 +hypercompetitions.com, 1 +hyperd.sh, 1 +hyperhidrose.tk, 1 +hyperian.net, 1 +hyperion.io, 1 +hyperjit.com, 1 +hyperlocal.co.za, 1 +hyperloopupv.com, 1 +hyperonline.tk, 1 +hyperreal.biz, 1 +hypershell.tk, 1 +hypersomnia.com, 1 +hyperspace.tk, 1 +hyperstack.org, 1 +hypertensionexplained.com, 1 +hypertesto.me, 1 +hyperthymia.com, 1 +hyperverge.co, 1 +hypevents.net, 1 +hypexstore.tk, 1 +hyphen.co.za, 1 +hyphenpda.co.za, 1 +hypno-thera.fr, 1 +hypnobb.com, 1 +hypnose-hennigsdorf.de, 1 +hypnose-mieux-etre.com, 1 +hypnoseduction.tk, 1 +hypnotic-reviews.com, 1 +hypnotized.org, 1 +hypnotizedgirls.ml, 1 +hypnovir.us, 1 +hypolineweb.de, 1 +hypotheca.ca, 1 +hypothecairelening.net, 1 +hypotheekbond.nl, 1 +hypotheques24.ch, 1 +hypothermia.tk, 1 +hypothes.is, 1 +hypothyroidmom.com, 1 +hypr.ee, 1 +hyr.mn, 0 +hyrius.net, 1 +hysh.jp, 1 +hysolate.com, 1 +hysquad.it, 1 +hystats.net, 1 +hysupchile.cl, 1 +hytale.com, 1 +hytzongxuan.com, 1 +hytzongxuan.top, 1 +hyundai.no, 1 +hyundaisrilanka.lk, 1 +hyvinvointineuvoja.fi, 1 +hyy.ch, 1 +hyy.chat, 1 +hyychat.com, 1 +hyyen.com, 1 +hyyperchat.com, 1 +hzbk.org, 0 +hztgzz.com, 1 +hzwc.nl, 1 +i--b.com, 1 +i-3c.co.jp, 1 +i-aloks.ru, 1 +i-connect.ie, 0 +i-cyber.gov.ua, 1 +i-fastnet.net, 1 +i-forum.ga, 1 +i-geld.de, 1 +i-house.gq, 1 +i-hoz.ru, 1 +i-lab.ml, 1 +i-like-hits.tk, 1 +i-logic.co.jp, 0 +i-make-love.tk, 1 +i-make.com, 1 +i-make.fr, 1 +i-model.org, 1 +i-motor.nl, 1 +i-office.com.vn, 1 +i-on.by, 1 +i-panic.com, 1 +i-pinged-everyone.today, 1 +i-port-voice.com, 1 +i-prince.tk, 1 +i-proswiss.com, 0 +i-r-a.tk, 1 +i-red.info, 1 +i-scream.space, 1 +i-so.ru, 1 +i-sports.cz, 1 +i-stats.net, 1 +i-tm.com.tw, 1 +i-verbi.it, 1 +i-volve.net, 1 +i-voting.pl, 1 +i00.eu, 1 +i00228.com, 1 +i0day.com, 1 +i1314.gdn, 1 +i24.host, 1 +i2capmark.com, 1 +i2gether.org.uk, 1 +i2verify.com, 0 +i30365.com, 1 +i36533.com, 1 +i365365.com, 1 +i36588.com, 1 +i4cu.uk, 1 +i51365.com, 1 +i5197.co, 1 +i5y.co.uk, 1 +i5y.org, 1 +i6729.co, 1 +i6729.com, 1 +i6957.co, 1 +i7.io, 1 +i7sas.tk, 1 +i81365.com, 1 +i82365.com, 1 +i86666.com, 1 +i879.com, 1 +i88i.gq, 1 +i8cp.com, 1 +i9297.co, 1 +i9397.com, 1 +i9721.com, 1 +i9728.co, 1 +i99win.com, 1 +i9elo.com, 1 +i9s.in, 1 +ia.cafe, 1 +ia.net, 1 +ia1000.com, 1 +iabot.tk, 1 +iacitywebdesigner.com, 1 +iaco.li, 1 +iactu.info, 1 +iadttaveras.com, 1 +iaeste.no, 1 +iaeste.or.jp, 1 +iaf.gov, 1 +iahemobile.net, 1 +iain.tech, 1 +iainsimms.co.uk, 1 +iainsimms.com, 1 +iainsimms.me, 1 +iaitouzi.com, 1 +ialis.me, 1 +ialps.cn, 1 +iam.lc, 1 +iam.soy, 1 +iamanewme.com, 1 +iambhatti.tk, 1 +iamconnected.eu, 1 +iamhansen.xyz, 1 +iamhealthystore.com, 1 +iaminashittymood.today, 1 +iamjoshellis.com, 1 +iamlegend.ml, 1 +iamlife.com, 1 +iamlizu.com, 1 +iampersonalized.com, 1 +iamsadmax.ga, 1 +iamsainknight.tk, 1 +iamsamaskom.tk, 1 +iamtheib.me, 1 +iamtonyarthur.com, 1 +iamtrucking.com, 1 +iamusingtheinter.net, 0 +iamwill.io, 1 +iamwoodbeard.com, 1 +ian-barker.co.uk, 1 +ian678.com, 1 +ian678.tk, 1 +ianbrault.com, 1 +iancu.io, 1 +iancu.me, 1 +iandouglasscott.com, 1 +iane-ccs.com, 1 +ianix.com, 1 +ianklug.com, 1 +iankmusic.com, 1 +ianloe.com, 1 +ianloe.rocks, 1 +ianmooreis.me, 1 +ianmoriarty.com.au, 1 +iansyst.co.uk, 1 +ianthompsonbooks.com, 1 +ianwalsh.org, 0 +iap.network, 0 +iapro.com, 1 +iapws.com, 1 +ias-gruppe.net, 1 +ias.ua, 1 +iassess.eu, 1 +iaswc.org, 1 +iatfei.com, 1 +iawx.net, 1 +ib-wedler.de, 0 +ib-zentrale.de, 1 +iba.community, 1 +iba.gov.au, 1 +ibacktraced.it, 1 +ibadboy.net, 1 +iban.com, 1 +ibauruapan.com.mx, 1 +ibavaro.com, 1 +ibb.co, 1 +ibcl.us, 1 +ibcmed.com, 1 +ibcmed.net, 1 +ibcmed.org, 1 +ibe.de, 1 +ibeep.com, 1 +iberiaversicherungen.com, 1 +ibericaderedes.es, 1 +ibericarbenet.es, 1 +ibericarcuzco.es, 1 +ibericarcuzcomini.es, 1 +ibericarformula.es, 1 +ibericargestoso.es, 1 +ibericarmotors.es, 1 +ibericarmotorsmalaga.es, 1 +ibericarmovilcentro.es, 1 +ibericarmovilsur.es, 1 +ibericarreicomsa.es, 1 +ibericartechnik.es, 1 +iberion.pl, 1 +ibestproduct.com, 1 +ibestreview.com, 1 +ibetora.com, 1 +ibexcore.com, 1 +ibexrepair.co.uk, 0 +ibhgospel.com, 1 +ibiki-boushi-makura.net, 1 +ibin.co, 1 +ibinex.news, 1 +ibiz.mk, 1 +iblackfriday.ro, 1 +ibliss.digital, 1 +iblog.pk, 1 +ibloggospel.com, 1 +iblowdry.com, 1 +iblsoft.com, 1 +ibmr.br, 1 +ibodyiq.com, 1 +ibpegasus.tk, 1 +ibps-recruitment.in, 1 +ibpsrecruitment.co.in, 1 +ibq.life, 1 +ibrainmedicine.org, 1 +ibraphotography.com, 1 +ibrom.eu, 1 +ibron.co, 0 +ibsglobal.co.za, 1 +ibstyle.tk, 1 +ibu.ca, 1 +ibug.io, 1 +ibuildings.nl, 1 +ibuki.run, 1 +ibuprofens.gq, 1 +iburgs.com, 1 +ibuzz.tk, 1 +ibwc.gov, 1 +ibykos.com, 1 +ic-lighting.com.au, 1 +ic3.gov, 1 +icafecash.com, 1 +icanhas.report, 1 +icanhasht.ml, 1 +icanhazpass.com, 1 +icap.my, 1 +icarlos.net, 1 +icasnetwork.com, 0 +icasture.top, 1 +icbemp.gov, 0 +icc.kharkov.ua, 1 +iccorporateinteriors.com.au, 1 +icebat.dyndns.org, 1 +iceberg.academy, 0 +iceberg.cyou, 1 +iceberg.ddns.me, 1 +icebook.co.uk, 1 +icebound.cc, 1 +icebound.win, 1 +icecars.net, 1 +icecodenew.tk, 1 +icecontrol.ro, 1 +icecreamandclara.co.uk, 1 +icecreamika.tk, 1 +icecutethings.com, 1 +icedream.tech, 1 +iceflow.tk, 1 +icegate.gov.in, 1 +iceheart.tk, 1 +icehost.cf, 1 +icehousefit.com, 1 +icelandic.cf, 1 +icelandiclamb.is, 1 +iceloch.com, 1 +icemakerrepairaustin.com, 1 +icemedia.com.au, 0 +icemyworld.tk, 1 +icentury.ca, 1 +icepharmaceuticals.com, 1 +icerinkwarehouse.com, 1 +icesemulator.com, 1 +iceshadow.tk, 1 +icetiger.eu, 1 +icetravellers.com, 0 +icetwister.com, 1 +icewoman.net, 1 +ich-hab-die-schnauze-voll-von-der-suche-nach-ner-kurzen-domain.de, 1 +ich-tanke.de, 1 +icharme.fr, 1 +ichasco.com, 1 +ichbinein.org, 1 +ichbinkeinreh.de, 1 +ichglaubesbackt.de, 1 +ichibanfansub.com.br, 1 +ichisound.ml, 1 +ichitaso.com, 1 +ichtushosting.com, 1 +ici-freewares.tk, 1 +icid.com.mx, 1 +icium.org, 1 +ickerseashop.com, 1 +icl82.systems, 1 +iclart.com, 1 +iclb.be, 1 +iclg.com, 1 +iclinic-mrt.ru, 1 +iclinic.ua, 1 +icloud.com, 1 +icloud.st, 1 +icloudlogin.com, 1 +icmhd.ch, 0 +icmp2018.org, 1 +icnc.ga, 1 +icnsoft.org, 1 +ico.wf, 1 +icobench.com, 1 +icodeconnect.com, 1 +icoh.it, 1 +icojapan.tokyo, 1 +icollezionisti.com, 1 +icolorpalette.com, 1 +icon-programming.tk, 1 +iconecoiffure.ca, 1 +iconintegration.com.au, 1 +iconomi.net, 1 +icons4free.tk, 1 +iconworld.ml, 1 +iconx.ml, 1 +icountnm.gov, 1 +icowhitepapers.co, 1 +icpc.pp.ua, 1 +icpc2016.in.th, 1 +icq-project.net, 1 +icq-world.tk, 1 +icruise.com, 1 +ics.edu.hn, 1 +icsfinomornasco.gov.it, 1 +icst.tk, 1 +ict-concept.nl, 1 +ict-crew.nl, 1 +ict-radar.com, 1 +ict-radar.nl, 1 +ict.govt.nz, 1 +ictbaneninnederland.nl, 1 +ictbiz.com.au, 1 +ictcareer.ch, 1 +icterra.com, 1 +ictindia.in, 1 +ictinforensics.org, 1 +ictmjc.com, 1 +ictoniolopisa.it, 1 +ictradar.com, 1 +ictussistemas.com.br, 1 +ictvanafmorgen.nl, 1 +icusignature.com, 1 +icy.aq, 1 +icyapril.com, 1 +icycanada.com, 1 +icynet.eu, 1 +icyrock.com, 1 +iczc.cz, 1 +icze4r.co, 1 +icze4r.com, 1 +icze4r.net, 1 +icze4r.online, 1 +icze4r.org, 1 +iczelion.tk, 1 +iczer.one, 1 +iczer.org, 1 +id-blog.ch, 0 +id.atlassian.com, 0 +id.fedoraproject.org, 0 +id.mayfirst.org, 0 +id.search.yahoo.com, 0 +id0.gr, 1 +id3global.com, 1 +id5-sync.com, 1 +id7.fr, 0 +idaeus.eu, 1 +idahoansforliberty.net, 1 +idahoheating.com, 1 +idanie.cf, 1 +idar-oberstein.de, 0 +idarv.com, 1 +idaspis.com, 1 +idatalabs.com, 0 +idblab.tk, 1 +idc-business.be, 0 +idc.yn.cn, 1 +idc95.com, 1 +idcrane.com, 1 +iddconnect.com, 1 +iddconnect.org, 1 +iddns.net, 1 +ideaassociates.com, 1 +ideadozz.hu, 1 +ideafnd.com, 1 +ideageek.net, 1 +ideagen-ops-sandbox.com, 1 +ideagenpentana.com, 1 +ideagenqpulse.com, 1 +ideahub.tk, 1 +ideal.shop, 1 +idealabs.tk, 1 +idealadvogadosbh.com.br, 1 +idealbody.cf, 1 +idealbody.gq, 1 +idealimplant.com, 1 +idealize.ml, 1 +idealnastrona.pl, 1 +idealog.id, 1 +idealsegurancaeletronica.com.br, 1 +idealtruss.com, 1 +idealtruss.com.tw, 1 +idealwhite.space, 1 +ideamiapublicidad.com, 1 +ideamount.com, 1 +idearumahidaman.com, 1 +ideasenfoto.com, 1 +ideashop.com, 1 +ideaweb.de, 1 +ideaweblab.com, 0 +ideditorial.com, 1 +idee-geschenk.eu, 1 +idee-lq.at, 1 +idee-lq.ch, 1 +idee-lq.com, 1 +idee-lq.de, 1 +idee-lq.net, 1 +ideeaanzee.tv, 1 +ideefactory.de, 1 +idegrafico.com, 1 +ideiasefinancas.com.br, 1 +ideice.gob.do, 1 +idemo.in, 1 +idenamaislami.com, 1 +idensys.nl, 1 +ident-clinic.be, 1 +identa.io, 1 +identassist.com, 1 +identifyme.net, 1 +identifytag.com, 1 +identigraf.center, 1 +identity-hash.online, 1 +identity-inspector.com, 0 +identity.plus, 1 +identityexperts.co.uk, 1 +identitykrisis.com, 1 +identitysandbox.gov, 1 +identitytheft.gov, 1 +ideorealm.tk, 1 +idered.net, 1 +idesoft.cloud, 1 +idesoft.com, 1 +idesoft.eu, 1 +idesoft.net, 1 +idesoft.org, 1 +idesoftinnovacion.com, 1 +idesoftinnovacion.es, 1 +idev-hub.com, 1 +idexxpublicationportal.com, 1 +idf64.com, 1 +idf64.org, 1 +idfc.gov, 1 +idgard.de, 0 +idgateway.co.uk, 1 +idgr.de, 1 +idheastudio.com, 1 +idhosts.co.id, 1 +idid.tk, 1 +idigiskill.com, 1 +idigovs.com, 1 +idinby.dk, 1 +idiomasdelmundo.tk, 1 +idiot.trade, 1 +idioumarou.com, 1 +idkidknow.com, 1 +idleleo.com, 1 +idlemon.net, 1 +idlethoughtsandramblings.com, 1 +idlewildflowers.com, 1 +idmanagement.gov, 1 +idmaster.ml, 1 +idmobile.co.uk, 1 +idn.gov.pt, 0 +idndx.com, 1 +idoc24.com, 1 +idohost.cf, 1 +idohost.tk, 1 +idol-bikes.ru, 1 +idolf.dk, 1 +idolish7.fun, 0 +idontexist.me, 0 +idonthaveawebsite.tk, 1 +idontplaydarts.com, 1 +idoparadoxon.hu, 1 +idouying.com, 1 +idp.onl, 1 +idraetsmusik.dk, 1 +idratherbequilting.com, 1 +idraulico-roma.it, 1 +idraulico.roma.it, 1 +idrissi.eu, 1 +idroserviceweb.com, 1 +idsafe.co.za, 1 +idstudio.tk, 1 +idtechnowizard.com, 1 +idtheft.gov, 1 +idubaj.cz, 1 +idunno.org, 1 +idvl.de, 1 +idweblog.com, 1 +idwebtools.tk, 1 +idxforza.com, 1 +idyl.fr, 1 +idysse.com, 1 +ie-blog.net, 1 +ie.search.yahoo.com, 0 +iea-annex61.org, 1 +iechistore.com, 1 +ieeedeis.org, 1 +ieeesb.nl, 1 +ieeesbe.nl, 1 +ieeespmb.org, 1 +iegat.com, 1 +iegatpracticetest.com, 1 +ieiscccuba.tk, 1 +ieji.de, 0 +iemb.cf, 1 +iemc.pt, 1 +iemsamex.com, 1 +ienakacs.jp, 1 +ienakanote.com, 0 +ienekolife.net, 1 +ienergizer.com, 1 +ieros.eu, 1 +ies-italia.it, 0 +ies911.com, 1 +iesconsultores.com, 1 +iesonline.co.in, 1 +iesucreipi.edu.co, 1 +ieval.ro, 1 +ievgenialehner.com, 1 +iewar.com, 1 +iexpats.com, 1 +iexpert99.com, 1 +if0.ru, 1 +ifacservice.be, 1 +ifadian.club, 1 +ifan.ch, 1 +ifan.ws, 1 +ifangpei.cn, 1 +ifangpei.com.cn, 1 +ifanqiang.net, 1 +ifashionable.info, 1 +ifbagro.in, 1 +ifcfg.jp, 1 +ifcfg.me, 1 +ifconfig.se, 1 +ifederalland.com, 1 +ifelse.io, 1 +ifengge.cn, 1 +ifgcdn.com, 1 +ifibe.com, 1 +ifisher.xyz, 1 +ifleurs.com, 1 +iflyi.me, 1 +ifma.edu.br, 1 +ifnet.fr, 1 +ifoa.it, 1 +ifolder.ga, 1 +iforced.net, 1 +iformbuilder.com, 0 +ifort.fr, 1 +ifosep.fr, 0 +ifoss.me, 1 +ifreetion.cn, 1 +ifreetion.com, 1 +ifsac.org, 1 +ifsh.me, 1 +ifsr.de, 1 +ift.cx, 1 +iftarsaati.org, 1 +iftikharalam.com, 1 +iftrue.de, 0 +ifur.ga, 1 +ifworlddesignguide.com, 1 +ifxd.bid, 1 +ifxnet.com, 1 +ifyou.live, 1 +ig-plastik.tk, 1 +ig.com, 1 +ig.me, 1 +iga-semi.jp, 1 +iganesh.com, 1 +igap.pt, 1 +igarage.nl, 0 +igcb.com, 1 +igdn.de, 1 +igechile.cl, 1 +igeh-immo.at, 1 +igenuinebeauty.co.jp, 1 +igforum.tk, 1 +igfwd.email, 1 +iggies.tk, 1 +igglabs.com, 1 +iggprivate.com, 1 +iggsoft.com, 1 +iggsoftware.com, 1 +ighl.de, 1 +igi-2.com, 1 +igi.codes, 0 +igiftcards.de, 1 +igiftcards.nl, 1 +igimusic.com, 0 +igk.nz, 1 +igkabel.cf, 1 +igkabel.ga, 1 +igkabel.gq, 1 +igkabel.tk, 1 +iglesiabelen.tk, 1 +iglesiadesalvacion.org, 1 +iglesiapentecostal.net, 1 +iglobus.cz, 0 +igloocommunities.com, 1 +igloodigitalworkplace.ca, 1 +igloodigitalworkplace.com, 1 +igloodigitalworkplaces.ca, 1 +igloopartnerportal.com, 1 +igloopreview.ca, 1 +igloosandbox.com, 1 +iglosujemy.pl, 1 +igmus.org, 1 +ignacjanskiednimlodziezy.pl, 1 +ignasiak.pl, 1 +ignat-mag.com, 1 +ignat-torcov.tk, 1 +ignat.by, 1 +ignatij.tk, 1 +ignatovich.by, 1 +ignatovich.me, 1 +ignet.gov, 1 +ignite.cz, 1 +ignitedlocal.com, 1 +ignitedmindz.in, 1 +ignitelocal.com, 1 +ignition.gg, 1 +igorandandre.com, 1 +igorina.com, 1 +igorrealestate.com, 1 +igorw.org, 1 +igotoffer.com, 0 +igra-prestol.tk, 1 +igra3k.tk, 1 +igramfollower.com, 1 +igramming.com, 1 +igranit.md, 1 +igraonicalara.tk, 1 +igrarium.com.ua, 0 +igrivi.com, 1 +igrodrom-kvest.tk, 1 +igrovoi-klub.tk, 1 +igry-onlayn.ru, 1 +igsmgmt.com, 1 +igualdaton.org, 1 +iguru.gr, 1 +igust4u-archive.ga, 1 +igva.or.kr, 1 +ih8sn0w.com, 1 +iha6.com, 1 +ihacker.ai, 1 +ihacklabs.com, 0 +ihakkitekin.com, 1 +ihasco.co.uk, 1 +ihatethissh.it, 1 +ihcprofile.com, 1 +ihearmedical.com, 1 +ihempz.cz, 1 +ihgcontrolbook.com, 1 +ihk-onlinewahl2021.de, 1 +ihkk.net, 1 +ihls.world, 0 +ihmphila.org, 1 +ihoey.com, 1 +ihollaback.org, 1 +ihongchao.com, 1 +ihongzu.com, 1 +ihorizon.jp, 1 +ihorvorotnov.com, 1 +ihost.md, 1 +ihostup.net, 1 +ihouseu.com, 1 +ihrb.com.br, 1 +ihre-pflege-sachsen.de, 1 +ihredls.de, 1 +ihrhost.com, 1 +ihri.ca, 1 +ihsangans.my.id, 1 +ihsolution.in, 1 +ihtdenisjaccard.com, 1 +ihuan.me, 1 +ihydra.net, 1 +ihzys.com, 1 +ii5197.co, 1 +ii6729.co, 1 +ii6729.com, 1 +ii6957.co, 1 +ii74.com, 1 +ii918.com, 1 +ii9297.co, 1 +ii9397.com, 1 +ii9721.com, 1 +ii9728.co, 1 +iiax.net, 1 +iiax.org, 1 +iic.kharkov.ua, 1 +iideaz.org, 1 +iiet.pl, 1 +iii-coalition.us, 1 +iiii.gq, 1 +iiii.ml, 1 +iiij.ml, 1 +iiit.pl, 1 +iimarckus.org, 1 +iinehp.com, 1 +iinf.in, 1 +iinfin.org, 0 +iinix.com, 1 +iiong.com, 1 +iipvapi.com, 1 +iis.net, 1 +iisuss.gq, 1 +iitala.fi, 1 +iitneetprep.com, 1 +iitowns.ir, 1 +iitstartups.org, 1 +iix.se, 1 +ijinus.com, 1 +ijnokmpl.cf, 1 +ijohan.nl, 1 +ijsbaanwitten.nl, 1 +ijsblokjesvormen.nl, 1 +ijsclubdwarsgracht.nl, 1 +ijsclubtilburg.nl, 1 +ijsclubwanneperveen.nl, 1 +ijunohana.jp, 1 +ikachalife.com, 1 +ikarate.ru, 1 +ikari-san.tk, 1 +ikaria.com.gr, 1 +ikaros.tk, 1 +ikasgela.com, 1 +ikeacareers.co.uk, 1 +ikebuku.ro, 1 +ikebukuro-shame.com, 1 +ikedaquotes.org, 1 +ikemedia.xyz, 1 +ikenmeyer.com, 1 +ikenmeyer.eu, 1 +ikerepc.tk, 1 +ikespta.com, 1 +ikeyless.com, 1 +ikfloreer.nu, 1 +ikigaiapp.it, 1 +ikiler.com, 1 +ikinokori-marketing.com, 1 +ikiroutayhtye.fi, 1 +ikisser.de, 1 +ikk.me, 1 +ikkakujuku.work, 0 +ikkatsu-satei.jp, 1 +ikke-coach.nl, 1 +ikkev.de, 0 +ikkoku.de, 1 +iklan-baris.gq, 1 +iklipcollection.my.id, 1 +iklive.org, 0 +ikmx.net, 1 +iknet.top, 1 +iknowd.org, 1 +ikonenmuseumkampen.nl, 1 +ikools.com, 1 +ikootu.com, 1 +ikparis.com, 1 +iks.moe, 1 +iksi.cc, 1 +iksi.me, 1 +ikudo.top, 1 +ikulist.me, 1 +ikumi.us, 1 +ikvts.de, 1 +ikwileendomein.tk, 1 +ikx.me, 1 +ikzoekeengoedkopeauto.nl, 1 +ikzoektim.nl, 1 +ila.fi, 1 +ilab.health, 1 +ilacrehberi.com, 1 +ilamparas.at, 1 +ilamparas.co.uk, 1 +ilamparas.com, 1 +ilamparas.com.co, 1 +ilamparas.com.ve, 1 +ilamparas.mx, 1 +ilanada.com, 1 +ilaphone.com.ua, 1 +ilard.fr, 1 +ilasoft.net, 1 +ilawgix.com, 1 +ilazycat.com, 1 +ilbiscottificiodipamparato.it, 1 +ilctucson.com, 1 +ildomani.it, 1 +ile-kalorii.pl, 1 +ile-sapporo.jp, 1 +ileat.com, 1 +ileci.de, 1 +ilektronika-farmakeia-online.gr, 1 +ilemonrain.com, 1 +ileonidze.tk, 1 +ilericikadinlar.org, 1 +iletisimmakinesi.com, 1 +ilformichiere.com, 1 +ilfumoshop.ru, 1 +ilg.ink, 1 +ilgiornaledelticino.ch, 1 +ilhan.name, 1 +ilhansubasi.com, 1 +iliastsi.net, 1 +iligang.cn, 1 +iligang.com, 1 +iligang.com.cn, 1 +iligang.link, 1 +iligang.net, 1 +iligang.net.cn, 1 +iligang.xin, 1 +ilii.me, 1 +ilikepenguins.tk, 1 +iliny.hu, 1 +iljadr.be, 1 +ilkeakyildiz.com, 0 +illaadventure.com, 1 +illadrodimerendine.it, 1 +illafuture.com, 1 +illambias.ch, 0 +illange.info, 1 +illative.net, 1 +illavobuempliz.ch, 1 +illegalpornography.com, 1 +illegalpornography.me, 1 +illerzell.de, 1 +illi.pro, 1 +illich.cz, 1 +illicitart.ca, 1 +illicitdigital.com, 1 +illinoiscaselaw.com, 1 +illjinx.info, 1 +illogical-gaming.at, 1 +illorenese.fr, 1 +illsley.org, 1 +illubel.com, 1 +illumed.net, 1 +illumepgh.com, 1 +illuminaterecovery.com, 1 +illuminatiofficial.vip, 1 +illuminationis.com, 1 +illuminatisocietyworldwide.org, 1 +illumini.io, 1 +illumis.com, 1 +illusionephemere.com, 0 +illusionsdoptique.com, 1 +illusionunlimited.com, 1 +illustrate.biz, 1 +illuxat.com, 1 +ilmainensanakirja.fi, 1 +ilmataat.ee, 1 +ilmcorp.com, 1 +ilmiobusinessonline.it, 1 +ilmiogiardiniere.it, 1 +ilmuk.org, 0 +ilneminis.com, 1 +iloft.xyz, 1 +iloli.name, 1 +ilona-france.tk, 1 +ilondres.es, 1 +ilonewolfs.com, 1 +ilouis.cn, 1 +ilove.fish, 1 +ilovecomputering.com, 1 +ilovefanyi.win, 1 +ilovefun.tk, 1 +iloveherb.ru, 1 +ilovelwy.com, 1 +iloveporn.ml, 1 +ilovesamara.tk, 1 +ilovesnow.ml, 1 +ilovestickers.gr, 1 +ilovethiscampsite.com, 1 +iloveyoutoo.tk, 1 +ilovias-farm.fr, 1 +ilpl.me, 0 +ilquintoseitu.it, 1 +ilrg.com, 1 +ils-savaient.fr, 1 +ilsedelangeforum.tk, 1 +iltec-prom.ru, 1 +iltec.ru, 1 +iltisim.ch, 0 +iltuogiardino.org, 1 +ilug-ktm.tk, 1 +ilumantio.tk, 1 +ilusionesopticas.net, 1 +ilusionistas.tk, 1 +ilusionphoto.com, 1 +ilusoesopticas.com, 1 +ilya.pp.ua, 1 +im-a.cricket, 1 +im-alter-daheim.ch, 1 +im-c-shop.com, 1 +im-haus-sonnenschein.de, 1 +im-in.space, 1 +im-razmakh.ru, 1 +im2net.com, 1 +im4h.de, 1 +im4h.eu, 1 +im4h.info, 1 +im66.net, 1 +ima-solutions.fr, 1 +ima-tourcoing.fr, 1 +imacs.org, 0 +imadalin.ro, 1 +image-cdn.co.uk, 1 +image-drive.de, 1 +image.hosting, 1 +image.tf, 0 +image2base64.online, 1 +image4arab.tk, 1 +imagealbums.tk, 1 +imagebin.ca, 1 +imagecom.tk, 1 +imagecurl.com, 1 +imagecurl.org, 1 +imageessentialsweightloss.com, 0 +imagefu.com, 1 +imagen891.tk, 1 +imagenesdedibujosalapizfacilesdehacer.com, 1 +imageproductions.ga, 1 +imagerecall.tk, 1 +imagerive.ch, 0 +images99.com, 1 +imageshare.web.id, 1 +imagevillage.ir, 1 +imageworld.tk, 1 +imaginair.es, 1 +imaginarium.tk, 1 +imaginary.ca, 1 +imaginary.stream, 1 +imaginarymakings.me, 1 +imaginationpathway.com, 1 +imagine-cs.com, 1 +imagine-programming.com, 1 +imaginelab.club, 1 +imaginescape.tk, 1 +imagr.io, 1 +imakash.gq, 1 +imamenu.com, 1 +imanageproducts.co.uk, 1 +imanageproducts.com, 1 +imanageproducts.uk, 1 +imanet.cl, 1 +imanolbarba.net, 1 +imap.support, 1 +imap2imap.de, 1 +imaple.net, 1 +imaple.org, 1 +imarkethost.co.uk, 1 +imarketing.pe, 1 +imarukita.ninja, 1 +imasdekor.com, 1 +imask.ml, 1 +imawasn-consulting.com, 1 +imawhale.com, 1 +imbianchino.roma.it, 1 +imboom.tk, 1 +imbrian.org, 1 +imbunatatiri-logan.tk, 1 +imcassociation.com, 1 +imcreative.ro, 1 +imcsi.cn, 1 +imcsx.co, 1 +imdb.com, 1 +imdhd.org, 1 +ime-a-tolerancia-eredmenye.club, 1 +ime.moe, 1 +imed.com.pt, 1 +imed.pt, 1 +imedi.it, 1 +imediafly.com, 1 +imediato.pt, 1 +imedikament.de, 1 +imeds.pl, 1 +imenfarazalvand.com, 1 +imeria.tk, 1 +imerit.net, 1 +imex-dtp.com, 1 +imexmed.com.gt, 1 +imf-online.com, 1 +imfacademy.com, 1 +imforza.com, 1 +img.mg, 1 +img.ovh, 1 +imgaa.com, 1 +imgal.vin, 1 +imgbb.com, 1 +imgbu.com, 1 +imgencrypt.com, 1 +imgg.es, 1 +imgo.ga, 1 +imgo.tk, 1 +imgup.co, 1 +imguploaden.nl, 1 +imgx.eu.org, 1 +imhotx.com, 0 +imhua.com, 1 +imi-rhapsody.eu, 0 +imig.ru, 1 +imiku.cn, 1 +imin.co, 1 +imine.ru, 1 +iminshell.com, 0 +imirhil.fr, 1 +imisa.com.mx, 1 +imisto.net, 1 +imitza.com, 0 +imjo.in, 1 +imjustcreative.com, 1 +imkerverein-moenchswald.de, 1 +imkerverenigingzaanstreek.nl, 1 +imkindofabigdeal.com, 1 +imlec.net, 1 +imlinan.cn, 1 +imlinan.com, 1 +imlinan.info, 1 +imlinan.net, 1 +imlloyd.yt, 1 +imlonghao.com, 1 +immanuellutheranmedia.org, 1 +immarypoppinsyall.tk, 1 +immaterium.de, 1 +immatix.xyz, 1 +immedia.net, 1 +immedicohospitalario.es, 1 +immense.ly, 1 +immersa.co.uk, 1 +immersion-pictures.com, 1 +immersionclub.tk, 1 +immersionwealth.com, 1 +immersivewebportal.com, 1 +immigrantdad.com, 1 +immigrationdirect.com.au, 1 +immigrative.ca, 1 +immijobs.co.uk, 1 +immivest.com, 1 +immo-agentur.com, 0 +immo-ment.eu, 1 +immo-passion.net, 0 +immobilien-badlippspringe.de, 1 +immobilien-in-istanbul.de, 1 +immobilien-wallat.de, 1 +immobilien-zirm.de, 1 +immobiliengutachter-holland.de, 1 +immobilienmakler-berlin-biesdorf.de, 1 +immobilienmakler-berlin-kaulsdorf.de, 1 +immobilienmakler-berlin-mahlsdorf.de, 1 +immobiliensachverstaendiger-waiblingen.de, 1 +immobilier-nice.fr, 0 +immobilier-swiss.ch, 1 +immobilier92.net, 1 +immocompar.com, 1 +immoe.me, 0 +immoe.tech, 1 +immomydesk.fr, 1 +immoraldoctors.tk, 1 +immortal-it.tk, 1 +immortal-pc.info, 1 +immortal.run, 1 +immortalcorporation.tech, 1 +immortol.tech, 1 +immovisual.be, 1 +immune.cf, 1 +imobile3.com, 1 +imoe.ac.cn, 0 +imokuri123.com, 1 +imolights.com, 1 +imolights.net, 1 +imolog.cl, 1 +imoner.com, 1 +imoney.tw, 1 +imouto.my, 0 +imoveisavenda.rio.br, 1 +imovit.ro, 1 +imoxin.net, 1 +impact-fluids.com, 1 +impact.health.nz, 1 +impactartstudy.com, 1 +impacter.eu, 1 +impactingsports.com, 1 +impactparcels.co.uk, 1 +impactparcels.com, 1 +impactpub.ch, 0 +impakho.com, 1 +impaqservices.org, 1 +impartesco.com, 1 +impas.se, 1 +impay.one, 1 +impec-cable.com, 1 +impelup.com, 1 +impendulo.org, 1 +imperdin.com, 1 +imperdintechnologies.com, 1 +imperial-legrand.com, 1 +imperialfenceinc.com, 1 +imperialism.rip, 1 +imperialmiami.com, 1 +imperialteam.tk, 1 +imperiodigital.online, 1 +imperioth.com, 1 +imperiumglass.com.au, 1 +imperiumnova.info, 1 +imperiyashop.tk, 1 +impf.site, 1 +impfung.cf, 1 +impfung.site, 1 +imphotep.net, 1 +impiantistica.org, 1 +implantesdentalestopete.com.mx, 1 +implantologiadentalgt.com, 1 +implude.com, 0 +impns.org, 1 +imponet.com.ar, 1 +import-shopping.de, 1 +importsagt.com, 1 +importsign.com, 1 +imposingoods.com, 1 +impossible.org, 1 +impossiblechoisir.tk, 1 +impossiblehq.com, 1 +impossiblenutrition.com, 1 +impossiblex.com, 1 +impotsimple.ca, 1 +imppac-schmuck.de, 1 +imppac.de, 1 +impra.com.ua, 0 +imprenditore.it, 1 +imprendo.co, 1 +imprendo.pro, 1 +imprensaglobal.com.br, 1 +imprenta-es.com, 1 +impresa-di-pulizie.milano.it, 1 +impresa-di-pulizie.org, 1 +impresa-pulizie.it, 1 +impresadipulizia.milano.it, 1 +impresadipulizia.roma.it, 1 +impresadipulizie.roma.it, 1 +impresadipulizieantonella.com, 1 +impresaedile.roma.it, 1 +impresapulizia.milano.it, 1 +impresapuliziacleanproject.it, 1 +impresapulizie.firenze.it, 1 +impresapulizie.it, 1 +impresapulizie.milano.it, 1 +impresapulizie.roma.it, 1 +impresapuliziebergamo.it, 1 +impressivebison.eu, 1 +impressivetitle.tk, 1 +imprezer.tk, 1 +imprezzor.com, 1 +imprimante-3d-store.fr, 1 +improfestival.ee, 1 +improklinikken.dk, 1 +improv.ee, 1 +improvebusinessonline.info, 1 +improved-madness.de, 1 +improvenerg.com, 1 +improvingwp.com, 1 +improvision.eu, 1 +impudence.tk, 1 +impuls.tk, 1 +impulse-clan.de, 1 +impulsionsa.com, 0 +impulsocristiano.com, 1 +imququ.com, 1 +imqyw.com, 1 +imransarwar.com, 1 +imrbq.com, 1 +imreh.net, 1 +imro.ie, 1 +imrunner.com, 1 +imrunner.ru, 1 +ims-sargans.ch, 1 +imscompany.com, 1 +imstocker.com, 1 +imtikaib.ml, 1 +imwalking.de, 1 +imy.rs, 1 +imychic.com, 1 +imydl.tech, 1 +imyjy.cn, 1 +imyrs.cn, 1 +imyz.tw, 1 +in-books.tk, 1 +in-crypto.tk, 1 +in-depthgame.reviews, 1 +in-depthoutdoors.com, 1 +in-flames.com, 1 +in-love.tk, 1 +in-ua.com, 1 +in.search.yahoo.com, 0 +in.xero.com, 0 +in1000worten.de, 1 +in10tion.com, 0 +inaboutique.it, 1 +inabox.ro, 1 +inakasoftware.com, 1 +inalvittile.cf, 1 +inanaji.ga, 1 +inanam.tk, 1 +inanan.cf, 1 +inanec.gq, 1 +inaned.ga, 1 +inanyevent.london, 1 +inares.org, 0 +inarizona.tk, 1 +inazuma7.jp, 1 +inbitcoin.it, 1 +inblank.tk, 1 +inbound.menu, 1 +inbound.tk, 1 +inbounder.io, 0 +inbox.google.com, 1 +inboxen.org, 1 +inbrand.agency, 1 +inbulgaria.info, 1 +incarceratedwombats.com, 1 +inceneritore.ga, 1 +incentea.com, 1 +incentivi.it, 1 +inceptionband.tk, 1 +incert.cn, 1 +incertint.com, 1 +inchcape-fleet-autobid.co.uk, 1 +inche-ali.com, 1 +inchenaim.com, 1 +inchidi.id, 1 +incidentresponsesolution.com, 1 +incidentresponsesystem.com, 1 +incigma.com, 0 +includesubdomains.preloaded.test, 1 +includesubdomains2.preloaded.test, 1 +inclusion.tn, 1 +inclusiv.nl, 0 +incnjp.com, 1 +incoherent.ch, 1 +incoldext.com, 1 +incometaxbengaluru.org, 1 +incomingfire.com, 1 +incommon.io, 1 +incompliance.de, 1 +inconcerts.de, 1 +incontactmetjezelf.nl, 1 +incore.nl, 1 +incotive.com, 1 +incowrimo.org, 1 +incpak.com, 1 +incparadise.net, 1 +increasetestosteronelevels.org, 1 +incrediblenews.tk, 1 +incrediblez.tk, 1 +incrementation.net, 0 +incrom.com, 0 +incurvy.de, 1 +ind.ie, 1 +indasun.com, 1 +indeika.ml, 1 +indeksonline.tk, 1 +independencerecovery.com, 1 +independent-operators.com, 1 +independentadvicefinancial.ga, 1 +independentfinancial.ga, 1 +independentmoneyadvice.ga, 1 +independentpartyofamerica.tk, 1 +independenttravelcats.com, 1 +independenza.tk, 1 +indevelopment.tk, 1 +index-education.net, 1 +index-games.com, 1 +index-mp3.com, 1 +index-of.ml, 1 +index.law, 1 +indexcesmad.cz, 1 +indexhost.tk, 1 +indexmarket.ml, 1 +indexsalaire.be, 1 +indexyz.me, 1 +india-ennenga.ga, 1 +indiaexamresult.in, 1 +indiaflowermall.com, 1 +indiafm.tk, 1 +indialocaltours.com, 1 +indian-elephant.com, 1 +indianaberry.com, 1 +indianaffairs.gov, 0 +indianafoundationpros.com, 1 +indianamoldrepairpros.com, 1 +indianapolisnews.ml, 1 +indianapolisrestorations.com, 1 +indianareflux.com, 1 +indianawaterdamagerepairpros.com, 1 +indianbridalservices.com, 1 +indiandramasonline.tk, 1 +indianet.tk, 1 +indianhelpline.in, 1 +indianporn2.xxx, 1 +indiantechhunter.tk, 1 +indianwarriors.tk, 1 +indiatechblogger.cf, 1 +indiatrademarkwatch.com, 1 +indiaviral.ga, 1 +indiawise.co.uk, 1 +indiaworlddigital.tk, 1 +indico.tk, 1 +indie.dog, 1 +indiecongdr.it, 1 +indiereview.tk, 1 +indievelopment.nl, 1 +indigartbeading.ca, 1 +indigartbeading.com, 1 +indigestiblesuppuration.tk, 1 +indignes-strasbourg.tk, 1 +indigoblack.com.au, 1 +indigobooks.gq, 1 +indigojewelers.com, 1 +indigopaints.be, 1 +indigosakura.com, 1 +indigostudios.com, 0 +indika.pe, 1 +indilens.com, 1 +indimike.tk, 1 +indio.co.jp, 1 +indir2017.tk, 1 +indirimkuponumarketim.com, 1 +inditip.com, 1 +inditoot.com, 1 +individualizedwellness.net, 1 +indiwebawards.tk, 1 +indiya-kino.gq, 1 +indlish.ga, 1 +indnews.ga, 1 +indo4life.tk, 1 +indobo.com, 1 +indochina.io, 1 +indodax.com, 1 +indoface.ga, 1 +indofountain.tk, 1 +indogermantrade.de, 1 +indoidnews.ga, 1 +indoittraining.com, 0 +indonesiakaya.com, 1 +indonesian-news.tk, 1 +indonesiatrip.tk, 1 +indoor-kletterwald.de, 1 +indoorpaintball.co.uk, 1 +indopress.tk, 1 +indorsie.com, 1 +indospot.tk, 1 +indota.hu, 1 +indotravels.tk, 1 +indovinabank.com.vn, 1 +indramas.tk, 1 +indramdhani.net, 1 +indumar.com, 1 +indusap.com, 1 +indusfastremit-ca.com, 1 +indusfastremit-us.com, 1 +indusfastremit.com, 1 +industreiler.com, 1 +industreiler.com.br, 1 +industriafranchini.com, 1 +industrial-remote-control.com, 1 +industrialalpinism.tk, 1 +industrialcalibration.co.uk, 1 +industrialgassprings.com, 1 +industriascruzcentro.com, 1 +industriemeister.io, 1 +indybay.org, 1 +indyroom.tk, 1 +ineardisplay.com, 0 +inebula.it, 1 +ineedweb.net, 1 +ineffect.net, 1 +inefin.tk, 1 +inertianetworks.com, 1 +inesfinc.es, 1 +inesnutricion.com, 1 +inessoftsec.be, 1 +inesta.nl, 1 +inethost.eu, 1 +inetserver.eu, 1 +inetsoftware.de, 1 +inetuser.tk, 1 +inevitavelbrasil.com.br, 1 +inex.one, 1 +inexlog.fr, 1 +inexpensivecomputers.net, 1 +inextmovies.link, 1 +inextmovies.vip, 1 +ineztheminiatureelephant.com, 1 +inf-fusion.ca, 1 +inf0sec.nl, 1 +infalaw.com, 1 +infans.be, 1 +infantry.org.ua, 1 +infcloud.com, 1 +infectedg.com, 1 +infectedvoice.tk, 1 +infectingthe.world, 1 +infelko.ru, 1 +inference.biz.tr, 1 +infermiere.roma.it, 1 +infernal.rs, 1 +inffin-portal.com, 1 +inffin-portal.de, 1 +inffin-tec.de, 1 +inficom.org, 1 +infidia.tk, 1 +infiernoalgecireno.tk, 1 +infihow.com, 1 +infinether.net, 1 +infinifour.com, 1 +infinipharm.com, 1 +infinita.com.co, 1 +infinite.com, 1 +infinitenews.cf, 1 +infinitescript.com, 1 +infinitiofallentownparts.com, 1 +infinitiofaugustaparts.com, 1 +infinitioflynnwoodparts.com, 1 +infinitiofmarinparts.com, 1 +infinitomaisum.com, 1 +infinity-uitvaartzorg.nl, 1 +infinity3dengine.com, 1 +infinitybas.com, 1 +infinitybc.se, 1 +infinitybooksindia.in, 1 +infinityengine.org, 1 +infinityepos.co.uk, 1 +infinityfaces.tk, 1 +infinityhts.com, 1 +infinityrecruitinggroup.com, 1 +infinitysearch.co, 1 +infinitysportsandfitness.in, 1 +infinityvr.net, 1 +infintechdesigns.com, 1 +infirmiere-canadienne.com, 1 +infirmieredevie.ch, 0 +infirmiers-montpellier.fr, 1 +infivalle.gov.co, 1 +inflammatory.tk, 1 +inflatablehire-scotland.co.uk, 1 +inflatablesny.com, 1 +inflatadays.co.uk, 1 +inflatamania.com, 1 +inflate-a-bubbles.co.uk, 1 +inflated.cloud, 1 +inflatiecalculator.nl, 1 +inflationstation.net, 1 +inflowphysio.com.au, 1 +influo.com, 1 +influxus.com, 0 +info-bay.com, 1 +info-beamer.com, 1 +info-bolivia.tk, 1 +info-club.pro, 1 +info-compusciencetech.tk, 1 +info-days.tk, 1 +info-free.ml, 1 +info-it.tk, 1 +info-kiwi.tk, 1 +info-o-zbozi.cz, 1 +info-obzor.ml, 1 +info-reason.cf, 1 +info-screen.me, 1 +info-screw.com, 1 +info-sell.ml, 1 +info-sys.tk, 1 +info.gov, 1 +infoaboutlawyers.com, 1 +infoamin.com, 1 +infoarenales.com, 1 +infobae.com, 1 +infobasquet.tk, 1 +infobip.com, 1 +infobiznes.ga, 1 +infobot.email, 1 +infobot.eu, 1 +infobot.nl, 1 +infobrain.net, 1 +infobrest.tk, 1 +infocanada.tk, 1 +infocanicatti.tk, 1 +infoclub.club, 1 +infocoin.es, 1 +infocom.bg, 1 +infocommsociety.com, 1 +infocon.org, 1 +infocrypto.pl, 1 +infocus.company, 1 +infocusvr.net, 1 +infodesigners.eu, 1 +infodesk.at, 1 +infofamouspeople.com, 1 +infofp.tk, 1 +infogai.tk, 1 +infogate.ga, 1 +infogram.com, 1 +infographicsmania.com, 1 +infogrfx.com, 1 +infogroups.ml, 1 +infogym.com, 1 +infohas.ma, 1 +infohub.com.ua, 1 +infohunter.education, 1 +infoiinfo.tk, 1 +infoindia.tk, 1 +infoislamharian.tk, 1 +infojeunes.fr, 1 +infojmp.com, 1 +infoland.ml, 1 +infolead.tk, 1 +infolearn.ir, 1 +infoloker.id, 1 +infomail-online.ml, 1 +infomalin.fr, 1 +infomate360.com, 1 +infomax.gr, 1 +infomexico.tk, 1 +infopaperiguatemi.com.br, 1 +infopico.com, 1 +infopier.sg, 1 +infopreneur.blog, 1 +infoprofuse.com, 1 +infopronetwork.com, 1 +infopronetwork.net, 1 +infoprosnetwork.co, 1 +infoprosnetwork.com, 1 +infor-allaitement.be, 1 +inforabota.tk, 1 +inforge.tk, 1 +informace-zbozi.cz, 1 +informaciondeciclismo.com, 1 +informasi-teknologi.com, 1 +informat.ga, 1 +informaticapremium.com, 0 +informaticmousset.tk, 1 +informatiger.net, 1 +informatik-handwerk.de, 1 +informationdoor.ga, 1 +informationrx.org, 1 +informations-echafaudages.com, 1 +informelles.tk, 1 +informhealth.com, 1 +informnapalm.org, 1 +informspb.tk, 1 +inforok.tk, 1 +inforumahgresik.com, 1 +infosactu.com, 1 +infoschool.ml, 1 +infosec-handbook.eu, 1 +infosec.ch, 1 +infosec.exchange, 0 +infosec.mv, 1 +infosec.pizza, 1 +infosec.wiki, 1 +infosecchicago.com, 1 +infosecdecompress.com, 1 +infosecmates.com, 1 +infosecsw.ca, 1 +infosectalks.com, 1 +infosectekniques.com, 1 +infosective.org, 1 +infosenior.ch, 0 +infoserp.net.pe, 1 +infosoph.org, 1 +infosubasta.es, 1 +infosystem.cf, 1 +infotabla.si, 1 +infotainworld.com, 1 +infotectsecurity.com, 1 +infoteka.cf, 1 +infotekno.co.id, 1 +infotelecharge.com, 1 +infotics.es, 0 +infotune.nl, 1 +infotype.ga, 1 +infovb.org, 1 +infovision-france.com, 1 +infoweb.ee, 1 +infowheels.tk, 1 +infoworm.org, 1 +infra-apparel.com, 1 +infra-se.com, 1 +infra.beer, 1 +infra.land, 1 +infra.press, 1 +infraball.com, 1 +infrabeep.com, 1 +infrabeta.com, 1 +infrabind.com, 1 +infrabold.com, 1 +infrabond.com, 1 +infraboom.com, 1 +infraclass.com, 1 +infraclip.com, 1 +infracron.com, 1 +infradart.com, 1 +infradeep.com, 1 +infradio.am, 1 +infradisk.com, 1 +infradive.com, 1 +infradot.com, 1 +infradrop.com, 1 +infraedifice.com, 1 +infrafile.com, 1 +infrafind.com, 1 +infrafire.com, 1 +infraflip.com, 1 +infraflux.com, 1 +infrafuse.com, 1 +infrafusion.com, 1 +infraget.com, 1 +infralicht.nl, 0 +infralira.com, 1 +infralist.com, 1 +infraloon.com, 1 +inframake.com, 1 +inframeet.com, 1 +inframenu.com, 1 +inframetro.com, 1 +inframint.com, 1 +infraname.com, 1 +infranest.com, 1 +infranium.com, 1 +infranium.eu, 1 +infranium.info, 1 +infranium.net, 1 +infranium.org, 1 +infranotes.com, 1 +infranoto.com, 1 +infranox.com, 1 +infrapass.com, 1 +infrapeer.com, 1 +infrapilot.com, 1 +infraping.com, 1 +infrapirtis.lt, 1 +infrapixel.com, 1 +infraplot.com, 1 +infrarank.com, 1 +infrarank.net, 1 +infrarate.com, 1 +infrareader.com, 1 +infraredradiant.com, 1 +infraref.com, 1 +infrarot-thermometer.info, 1 +infras.fr, 1 +infrasend.com, 1 +infraspin.com, 1 +infrastat.com, 1 +infratank.com, 1 +infratask.com, 1 +infrathink.com, 1 +infratrip.com, 1 +infravibe.com, 1 +infravideo.com, 1 +infravoce.com, 1 +infravoice.com, 1 +infrazine.com, 1 +infruction.com, 1 +infstudios.nl, 1 +infuse-mn.gov, 1 +ing-buero-junk.de, 1 +ingadesign.it, 1 +ingalabs.hu, 1 +ingatlanjogaszok.hu, 1 +ingatlanneked.hu, 1 +ingbusiness.pl, 1 +inge-r.nl, 1 +ingebroer.com, 1 +ingeni.ink, 1 +ingenias.es, 1 +ingeniotic.com, 1 +ingenious-development.tk, 1 +ingenium.si, 1 +ingeniumsociety.tk, 1 +ingenius.ws, 1 +ingereck.net, 1 +ingerhy.com, 1 +ingermany.ml, 1 +ingestion.life, 1 +ingfreelancer.com, 1 +ingjobs.ch, 1 +inglebycakes.co.uk, 1 +inglesatutiempo.com, 1 +inglesencanada.cf, 1 +inglesfoco.com.br, 1 +inglesnarede.com.br, 1 +ingo-schlueter.de, 1 +ingolonde.pw, 1 +ingoschlueter.de, 1 +ingresatupedido.com, 1 +ingresomedicina.com, 1 +ingresosautomaticos.tk, 1 +ingresospasivosyafiliados.online, 1 +ingressfs.pl, 1 +ingridbai.me, 1 +ingridvandamme.nl, 1 +ingridvoncken.nl, 1 +ingroxd.com, 1 +ingticos.com, 1 +ingushetia.tk, 1 +ingwaz.org, 1 +inhaltsangabe.de, 1 +inhere.cf, 1 +inhomedesign.ro, 1 +inhouseents.co.uk, 1 +iniby.com, 1 +iniiter.com, 1 +inima.org, 1 +inin.gq, 1 +inishbofin.ie, 1 +init.blog, 0 +init.de, 1 +init3.cn, 1 +initialization.tech, 1 +initiative-3d.org, 1 +initiative-digitalisierung-kmu.de, 1 +initq.net, 1 +initramfs.io, 1 +initrd.net, 1 +injigo.com, 0 +injust.me, 1 +injust.ml, 1 +injust.tk, 1 +inkable.com.au, 1 +inkandtonerni.co.uk, 1 +inkbotdesign.com, 1 +inkbunny.net, 1 +inkeliz.com, 1 +inkerotic.com, 1 +inkhor.se, 1 +inkhub.com.au, 1 +inkjets-inks.tk, 1 +inkliners.tk, 1 +inkognito.cf, 1 +inkognito.ga, 1 +inkognito.gq, 1 +inkognito.ml, 1 +inkomensafhankelijkehuurverhoging.nl, 1 +inkopers.org, 1 +inkor.tk, 1 +inksay.com, 1 +inkteeshop.com, 1 +inkthemes.com, 1 +inkthreadable.co.uk, 1 +inkubatori.tk, 1 +inkurz.de, 1 +inkvisual.tk, 1 +inkwall.co, 1 +inlabo.de, 1 +inline-online.tk, 1 +inline-sport.cz, 1 +inlinea.ch, 1 +inlineskating.ga, 1 +inlink.ee, 1 +inlink.ltd, 1 +inlt.com, 1 +inmaaa.cf, 1 +inmamaskitchen.com, 1 +inmaps.xyz, 1 +inmatefinancial.com, 1 +inmateintake.com, 1 +inmedic.pl, 1 +inmedsm.com, 1 +inmemorium.tk, 1 +inmemoryofdaniella.com, 1 +inmigracion-florida.com, 1 +inmobiliaria-sanpablo.cl, 1 +inmobillium.fr, 1 +inmonteblandinio.be, 1 +inmoodforsex.com, 1 +inmucrom.com, 1 +inmucrom.es, 1 +inmueblescartagena.com.co, 1 +inmusicfestival.com, 1 +innabilawgroup.com, 1 +innatocol.com, 1 +inncoaching.nl, 1 +inner-vision.tk, 1 +innerfence.com, 1 +innerlife.company, 1 +innerlightcrystals.co.uk, 1 +innermostparts.org, 1 +innersafe.com, 1 +innertrip.co.kr, 1 +innico.cf, 1 +innio.com, 1 +inno.ch, 0 +innocence.org.cn, 1 +innocenceseekers.net, 1 +innogames.com, 1 +innogames.de, 1 +innogen.fr, 1 +innohb.com, 1 +innolabfribourg.ch, 1 +innopharmaeducation.com, 1 +innophate-security.com, 1 +innot.net, 1 +innoteil.com, 1 +innoteknology.com, 1 +innotel.com.au, 1 +innova360.com.mx, 1 +innovacoachgroup.com, 1 +innovairservices.ch, 0 +innovamag.com, 1 +innovaptor.at, 1 +innovaptor.com, 1 +innovate-indonesia.com, 1 +innovatech.pe, 1 +innovateohio.gov, 1 +innovation-photography.co.uk, 1 +innovation-workshop.ro, 1 +innovation.gov, 1 +innovationbranding.ga, 1 +innovationgarage.it, 1 +innovationrealtygrp.com, 1 +innovationreno.ca, 1 +innovative-trading.tk, 1 +innovativeactors.com, 1 +innovativebuildingsolutions.co.za, 1 +innovativeideaz.org, 1 +innover.se, 1 +innoviahome.com, 1 +innovomuebles.com, 1 +innovum.cz, 1 +innsalzachsingles.de, 1 +innvisiondesign.net, 1 +innwan.com, 1 +inoa8.com, 1 +inobun.jp, 1 +inodari.com, 1 +inoder.com, 1 +inoio.de, 1 +inondation.ch, 0 +inorder.website, 1 +inoreader.com, 1 +inoruhana.com, 1 +inovasirumahku.tk, 1 +inovatec.com, 1 +inovatecsystems.com, 1 +inovigo.ro, 1 +inoxandco.com, 1 +inoxdesign.fr, 1 +inoxdesign.pro, 1 +inpas.co.uk, 1 +inpdp.tk, 1 +inpector.de, 1 +inphi.com, 1 +inprint.id, 1 +inprosy.com, 1 +inprotec.com.co, 1 +input.club, 1 +input.pt, 0 +input.sh, 1 +inputclub.com, 1 +inputmodes.com, 1 +inqorp.ca, 1 +inquant.de, 1 +inquisicion.tk, 1 +inquisition.is, 1 +inrage.fr, 1 +ins-kreativ.de, 1 +ins1gn1a.com, 1 +insanb.com, 1 +insane.zone, 1 +insanedevs.com, 1 +insanepyro.tk, 1 +insblauehinein.nl, 1 +inschrijfformulier.com, 1 +inscomers.net, 1 +inscribe.ai, 1 +inscribeusercontent.com, 1 +inscripcionessena.com, 1 +insecret.com.ua, 1 +insecret.trade, 1 +insecure.org.je, 1 +insegne.roma.it, 1 +inserta.tk, 1 +insertcoins.net, 1 +insertface.com, 1 +inserzioniticino.ch, 1 +insgesamt.net, 1 +inshapenutrition.com.br, 1 +inshared.nl, 1 +inshop.hu, 1 +insiberia.tk, 1 +inside19.com, 1 +insideastronomy.tk, 1 +insideaudit.com, 1 +insidebeach.com.br, 1 +insidebedroom.com, 0 +insidebitcoins.de, 1 +insideevs.com, 1 +insideevs.com.tr, 1 +insideevs.de, 1 +insideevs.fr, 1 +insideevs.ru, 1 +insidehook.com, 1 +insideofgaming.de, 1 +insideoutfuel.com, 1 +insideperu.tk, 1 +insideprisonbreak.tk, 1 +insider-invest.tk, 1 +insidergazette.com, 1 +insiders.ga, 1 +insidesolutions.nl, 1 +insidethefirewall.tk, 1 +insidetheigloo.com, 1 +insighti.com, 0 +insighti.eu, 1 +insighti.org, 1 +insighti.sk, 1 +insights.is, 1 +insignificant.space, 1 +insinuator.net, 1 +insistel.com, 1 +insity.com, 1 +insolent.ch, 1 +insolved.com, 1 +insomniac.ro, 1 +insomniasec.com, 1 +insotech.eu, 1 +insouciant.org, 1 +inspas.net, 1 +inspiratienodig.nl, 1 +inspiration.gr, 1 +inspirationalstories.tk, 1 +inspiratorysolutions.com, 1 +inspire2rise.com, 1 +inspired-creations.co.za, 1 +inspired-lua.org, 1 +inspiredhousewife.com, 1 +inspiredlife.fun, 1 +inspiredrealtyinc.com, 1 +inspiresurgery.com, 1 +inspireteenhealth.com, 1 +inspirez-vous-sophro.com, 1 +insside.net, 1 +insta-drive.com, 1 +instaart.org, 1 +instachina.ru, 1 +instacredito.pt, 1 +instafind.nl, 1 +instaforex.com.ng, 1 +instafrases.net, 1 +instafuckfriend.com, 1 +instagc.com, 1 +instagfy.com, 1 +instagrabber.ru, 1 +instagram-atom.appspot.com, 1 +instagram.com, 0 +instagrammernews.com, 1 +instagramtweet.com, 1 +instagraph.cn, 1 +instahub.net, 1 +instalamosyreformamos.es, 1 +installgentoo.net, 1 +instamod.io, 1 +instamojo.com, 1 +instances.social, 1 +instanse.nl, 1 +instant-clearance-sale.co.uk, 1 +instant-thinking.de, 0 +instant.io, 1 +instantdomainsearch.com, 1 +instantessay.tk, 1 +instantkhabar.com, 1 +instantluxe.com, 1 +instantluxe.de, 1 +instantmoron.com, 1 +instantpage.tk, 1 +instantphotocamera.com, 1 +instantphotoprinter.com, 1 +instantprint.co.uk, 1 +instantreplay.tk, 1 +instaon.io, 1 +instaquiz.ru, 1 +instava.cz, 1 +instawi.com, 1 +instawierszyki.pl, 1 +instax.pl, 1 +instead.com.au, 1 +insteagle.com, 1 +instelikes.com.br, 1 +instics.com, 1 +institut-coiffureetnature.fr, 1 +institut-confucius-montpellier.org, 1 +institut-uthyl.com, 1 +institutogiuseppe.com, 1 +institutogiuseppe.com.ar, 1 +institutolancaster.com, 1 +institutomaritimocolombiano.com, 1 +institutomarketingdigital.net, 1 +institutosparroquiales.com, 1 +instrukci.tk, 1 +instrumart.ru, 0 +instrumentodepaz.com, 1 +insulations.ga, 1 +insult.es, 1 +insurance, 1 +insurance-companies.tk, 1 +insurance24.online, 1 +insurancebonzer.ga, 1 +insuranceclassic.ga, 1 +insurancecompanylive.tk, 1 +insuranceleep.ga, 1 +insurancenews.gq, 1 +insurancequotes.tk, 1 +insurancesaman.tk, 1 +insuranceweb.ga, 1 +insuredcloud.ga, 1 +insuremycar.ru, 1 +insuremyworkcomp.com, 1 +insureon.com, 1 +insurethebox.tk, 1 +insurrectosdelbosque.tk, 1 +insytesecurity.nl, 1 +inszu.com, 0 +int-ext-design.fr, 1 +int.icu, 1 +int64software.com, 1 +inta-aivn.org, 1 +intafe.co.jp, 1 +intakesync.com, 1 +intal.info, 1 +intalink.org.uk, 1 +intarweb.ca, 1 +intasky.cz, 1 +intasky.sk, 1 +intdemocratic.org, 1 +inteapuestas.com, 1 +intechdaybcp.com, 1 +integ.jp, 1 +integra-belgium.be, 1 +integrahealth.com.mx, 1 +integralblue.com, 1 +integralkk.com, 1 +integralsalud.xyz, 1 +integrata.de, 1 +integratedhealth21.com, 1 +integratedintegrations.xyz, 1 +integratedmedicalonline.com, 1 +integratemyschool.com, 1 +integration-mouvements-oculaires.com, 1 +integrativewellnessny.com, 1 +integritet.com.se, 1 +integritree.ca, 1 +integrity.gov, 1 +integritygeeks.com, 1 +integrityglobal.com, 1 +integrityingovernmentidaho.com, 1 +integritymedicalwaste.com, 1 +integrityokc.com, 1 +integrityoklahoma.com, 1 +integromat.com, 1 +integroof.com, 1 +integsystem.com, 1 +intel.gov, 1 +intel69.cf, 1 +intelalumni.org, 1 +intelhost.cl, 1 +intelhost.com, 1 +intelhost.com.ar, 1 +intelhost.com.br, 1 +intelhost.com.co, 1 +intelhost.com.mx, 1 +intelhost.com.pe, 1 +intellar.com, 1 +intelldynamics.com, 1 +intellectdynamics.com, 1 +intellektuaalomand.ee, 1 +intelliance.eu, 1 +intelligence-explosion.com, 1 +intelligenetics.com, 1 +intelligentcontacts.com, 1 +intelligentrics.com, 1 +intelligentwaves.com, 1 +intelligizedigital.com, 1 +intellihr.io, 1 +intellimatica.se, 1 +intellimax.ir, 1 +intellinetixvibration.com, 1 +intellio.pl, 1 +intelly.nl, 1 +intelly365.nl, 1 +intelrealsense.com, 1 +inteltechniques.com, 1 +intelx.io, 1 +intencje.pl, 1 +intenirphoto.tk, 1 +intensify.pictures, 1 +intensivpflege-sachsen.de, 1 +inter-corporate.com, 1 +inter-news.tk, 1 +interabbit.co, 1 +interacthindu.tk, 1 +interactiveliterature.org, 1 +interaffairs.com, 1 +interaktiva.fi, 1 +interallied.org, 1 +interasistmen.se, 1 +interbec.com, 1 +interc0der.tk, 1 +interchangeillawarra.org, 1 +interchanges.io, 1 +intercom-attachments-1.com, 1 +intercom-attachments-5.com, 1 +intercom-attachments-6.com, 1 +intercom-attachments-9.com, 1 +intercom-sheets.com, 1 +intercom.com, 1 +intercom.io, 1 +intercomp-cbu.ru, 1 +interconlarp.org, 1 +intercrosse.tk, 1 +interdc.com, 1 +interdc.nl, 1 +interesnyimir.com, 1 +interessengemeinschaft-pregelstrasse.tk, 1 +interesting.ac.cn, 1 +interestingfacts.gq, 1 +interferencias.tech, 1 +interfloraservices.co.uk, 1 +interflores.com.br, 1 +interfug.de, 1 +intergenx.co.uk, 1 +intergenx.com, 1 +intergenx.org, 1 +intergenx.org.uk, 1 +intergermania.com, 1 +intergozd.si, 1 +interguard.net, 1 +interiery-waters.cz, 1 +interimages.fr, 1 +interior-design-colleges.com, 1 +interior16.cf, 1 +interiorcheapo.com, 1 +interiorcolors.tk, 1 +interiordesignsconcept.com, 1 +interisaudit.com, 1 +interlecwa.com, 1 +interlijn.nl, 1 +interlingvo.biz, 1 +interlinked.us, 1 +intermax.nl, 1 +intermediapub.com, 1 +intermedinet.nl, 1 +intermezzo-emmerich.de, 1 +interminsk.tk, 1 +intern-base.com, 1 +intern.tax, 1 +internacional.tech, 1 +internacionalista.tk, 1 +internalfb.com, 1 +internalframebackpack.tk, 1 +internalkmc.com, 1 +internally.ga, 1 +international-arbitration-attorney.com, 1 +international-books.org, 1 +international-friends.net, 1 +international-genealogy-services.com, 1 +internationalfashionjobs.com, 1 +internationaljoustingleague.tk, 1 +internationalschool.it, 1 +internationalschoolnewyork.com, 1 +internationalstudentassociation.com, 1 +internationaltalento.it, 1 +internationalweekly.tk, 1 +internect.co.za, 1 +internet-aukcion.info, 1 +internet-drive.tk, 1 +internet-gazeta.ga, 1 +internet-israel.com, 1 +internet-meesters.nl, 0 +internet-pornografie.de, 0 +internet-tv4u.tk, 1 +internet.org, 1 +internet42.tk, 1 +internetaanbieders.eu, 1 +internetauction.tk, 1 +internetbank.swedbank.se, 1 +internetbloger.tk, 1 +internetbugbounty.com, 1 +internetbusiness-howto.com, 1 +internetcom.jp, 1 +internetface.tk, 1 +internetfonden.se, 1 +internetgardener.co.uk, 1 +internetinhetbuitengebied.nl, 1 +internetional.nl, 1 +internetk.tk, 1 +internetline.tk, 1 +internetmagaz.tk, 1 +internetmarketingprofitscenter.com, 1 +internetmarkets.net, 1 +internetmedia.si, 1 +internetmuseum.se, 1 +internetmusicexchange.com, 1 +internetnz.nz, 1 +internetofdon.gs, 1 +internetoffensive.fail, 1 +internetofinsecurethings.com, 1 +internetoskol.tk, 1 +internetovehazardnihry.cz, 1 +internetowykantor.pl, 1 +internetpoem.com, 1 +internetpro.me, 1 +internetprofitspro.com, 1 +internetslapfights.com, 1 +internetstaff.com, 1 +internetstiftelsen.se, 1 +internetstones.com, 1 +internetthreatcenter.com, 1 +internetthreatscenter.com, 1 +internettoday.ga, 1 +internettradie.com.au, 0 +internetwealthresource.com, 1 +internetzaim.tk, 1 +internetzentrale.net, 1 +internewscast.com, 1 +internex.at, 1 +interparcel.com, 1 +interphoto.by, 1 +interpol.gov, 1 +interpretacjawynikowbadan.info.pl, 1 +interracial.dating, 1 +interseller.io, 1 +interset.us, 1 +intersexualite.tk, 1 +interslang.tk, 1 +interspot.nl, 1 +interssl.com, 1 +interstateautomotiveinc.com, 1 +interstateremovalists.sydney, 1 +intersumka.ua, 1 +intertime.services, 1 +intertrans.tk, 1 +interval-training-timer.ru, 1 +interview-suite.com, 0 +interviewme.pl, 1 +interviewpipeline.co.uk, 1 +interways.de, 1 +interwebz-cheats.com, 1 +interwebz.nz, 1 +intestclub.tk, 1 +intheater.de, 1 +intheevent.com, 1 +inthepicture.com, 1 +inthouse.cloud, 1 +intim-24.tk, 1 +intim-ru.tk, 1 +intima-mente.com, 1 +intimastoreatacado.com.br, 1 +intimznakomstvo.tk, 1 +intisar.ru, 1 +intiveo.com, 1 +intl-webs.com, 1 +intmissioncenter.org, 0 +into-the-mountain.com, 1 +intomsk.tk, 1 +inton.biz, 1 +intoparking.com, 1 +intoparking.fi, 1 +intpforum.com, 1 +intr0.cf, 1 +intr0.com, 1 +intr0.tk, 1 +intracdf.net, 1 +intrack.net.au, 1 +intradayseasonals.com, 1 +intranet.dvag, 1 +intranetcrowd.com, 1 +intraobes.com, 1 +intrasac.com, 1 +intrasoft.com.au, 1 +intraxia.com, 1 +intrepy.com, 1 +intrigue3d.com, 1 +intrixgroup.com, 1 +introes.com, 1 +intropickup.ru, 1 +intrp.net, 1 +intsys.fi, 1 +intune.life, 1 +intux.be, 0 +intvonline.com, 1 +intvshop.ru, 1 +intwiff.com, 1 +intxt.net, 1 +inu.nl, 1 +inuevostiempos.es, 1 +inumcoeli.com.br, 1 +inup.jp, 1 +inusasha.de, 1 +inuyasha-petition.tk, 1 +invadecafe.tk, 1 +invaded.ga, 1 +invadelabs.com, 1 +invalida.ru, 1 +invantive-apps-for-dynamics-crm.com, 1 +invantive-apps-for-magento.com, 1 +invantive-apps-for-nmbrs.com, 1 +invantive-apps-for-salesforce.com, 1 +invantive-apps-for-stackoverflow.com, 1 +invantive-apps-voor-exact-online.nl, 1 +invantive-apps-voor-loket.nl, 1 +invantive-apps-voor-xml-auditfiles.nl, 1 +invantive.be, 1 +invantive.co.uk, 1 +invantive.com, 1 +invantive.de, 1 +invantive.es, 1 +invantive.eu, 1 +invantive.net, 1 +invantive.nl, 1 +invantive.org, 1 +invariant.cn, 1 +invariant.me, 1 +invasion.com, 1 +invasivespeciesinfo.gov, 1 +invasmani.com, 1 +invata-ma.ro, 1 +invenio.software, 1 +inventaire.ch, 0 +inventionsteps.com.au, 1 +inventix.nl, 1 +inventoryimages.co.uk, 1 +inventoryimages.com, 1 +inventtatte.com, 0 +inventtheworld.com.au, 1 +inventum.cloud, 1 +inverness.gov, 1 +inversegravity.net, 1 +inverselink-user-content.com, 1 +inverselink.com, 1 +inversion.travel, 1 +inversioneseconomicas.com, 1 +inversionesgalindo.com, 1 +invest-stroj.tk, 1 +investactiv.tk, 1 +investarholding.nl, 1 +investarter.nl, 1 +investasimudah.tk, 1 +investasipasti.tk, 1 +investforum.net, 1 +investgold.ml, 1 +investigatemalware.com, 1 +investigatenj.org, 1 +investigatingmalware.com, 1 +investigatore.it, 1 +investigatore.roma.it, 1 +investigatore.torino.it, 1 +investigazione.milano.it, 1 +investigazione.roma.it, 1 +investinestonia.com, 1 +investingdiary.cn, 1 +investingent.be, 1 +investingent.com, 1 +investinghent.be, 1 +investingindiscovery.com, 1 +investingtrader.net, 1 +investinturkey.com.tr, 1 +investinweed.com, 1 +investion.cf, 1 +investir.ch, 0 +investirenisrael.fr, 1 +investirsolidaire.fr, 1 +investissementimmobilier.be, 1 +investisseur-or-matieres.com, 1 +investlatam.com, 1 +investment-adh.com, 1 +investmonitor.tk, 1 +investnorthernontario.com, 1 +investonline.cf, 1 +investor-academy.jp, 1 +investor.gov, 1 +investoren-beteiligung.de, 1 +investorfare.com, 1 +investorforms.com, 1 +investorloanshub.com, 1 +investors.pl, 1 +investosure.com, 1 +investpay.ru, 1 +investresolve.com, 1 +invetekno.com, 1 +invetep.sk, 1 +invicti.com, 1 +invidio.us, 1 +invinoaustria.com, 1 +invinoaustria.cz, 1 +invisible-college.com, 1 +invisibles.ch, 0 +invisitone.com, 1 +invisiverse.com, 1 +invitation-factory.tk, 1 +invitebiz.tk, 1 +invitescafe.com, 1 +invitescene.com, 1 +invitethemhome.com, 1 +invito.tk, 1 +invkao.com, 1 +invoiced.com, 1 +invokingspirits.tk, 1 +involic.com, 1 +involve.ai, 1 +invuite.com, 1 +invuite.com.au, 1 +inwao.com, 1 +inwerx.com, 1 +inwit.tk, 1 +inwonderofit.com, 1 +inyourcornerinsurance.com, 1 +inyourowntime.info, 1 +inyourowntime.zone, 1 +inyr.hu, 1 +inzdr.com, 1 +inzeitinteractive.tk, 1 +inzelabs.com, 1 +inzernettechnologies.com, 1 +inzestfreunde.de, 1 +inzichtmeditatie.nl, 1 +io.gp, 1 +io.kg, 1 +io9.com, 1 +ioactive.com, 1 +ioanamateas.ro, 1 +iobint.com, 1 +iocheck.com, 1 +iochen.com, 1 +ioconsulting.ee, 1 +iocorp.jp, 1 +iocurrents.com, 0 +iocus.fun, 1 +iodine.com, 1 +iodu.re, 1 +iofort.com, 1 +ioghawaii.com, 1 +ioliver.co.uk, 1 +iomedia.ch, 1 +iompost.com, 1 +iomstamps.com, 1 +ionc.ca, 1 +ioncubedecode.xyz, 1 +iondrey.fr, 1 +ione.net.nz, 1 +ionlabs.kr, 1 +ionline.ml, 1 +ionovia.de, 1 +ionplesalexandru.com, 1 +ionspin.com, 1 +ionstudio.pe, 1 +ionutnechita.ro, 1 +ionutnica.ro, 1 +ionx.co.uk, 1 +iop.intuit.com, 1 +iopool.us, 1 +iorgroup.org, 1 +ios11018.com, 1 +iosartstudios.gr, 1 +iosbankermyanmar.com, 1 +iosecurity.co.za, 1 +iosjailbreakiphone.com, 1 +ioslo.net, 1 +iosme.ga, 1 +iosnoops.com, 1 +iosolutions.cl, 1 +iosprivacy.com, 1 +iossearch.tk, 1 +iossifovlab.com, 1 +iostream.by, 1 +iot-alliances.com, 1 +iotac.xyz, 1 +iotfen.com, 1 +iotmu.com, 1 +iotorq.com, 1 +iotsms.io, 1 +iowacolonytx.gov, 1 +iowaent.com, 1 +iowaschoolofbeauty.com, 1 +iowawx.com, 1 +iowen.cn, 0 +iowxy.com, 1 +iox.is, 1 +ip-addr.es, 1 +ip-address.me, 1 +ip-hahn.de, 1 +ip-life.net, 1 +ip-tanz.com, 1 +ip.dog, 1 +ip.gt, 1 +ip.or.at, 1 +ip.sb, 1 +ip3.world, 1 +ip3office.com, 0 +ip40.com, 1 +ip4unlocked.tk, 1 +ip6.li, 1 +ipaddressreputation.com, 1 +ipadkaitori.jp, 1 +ipadshowroom.com, 1 +ipal.im, 1 +ipal.name, 1 +ipal.tel, 1 +ipanchev.com, 1 +iparduotuves.lt, 1 +iparenda.tk, 1 +iparkki.com, 1 +ipass.live, 1 +ipcareers.net, 1 +ipcfg.me, 1 +ipclabs.tk, 1 +ipcmali.ml, 1 +ipconsulting.se, 1 +ipcuyuni.net, 1 +ipdental.tk, 1 +ipemcomodoro.com.ar, 1 +iperconnessi.it, 1 +iperon.net, 1 +iperon.org, 1 +iperon.ru, 1 +ipfire.org, 1 +ipfirebox.de, 1 +ipfixcalculator.com, 1 +ipfixcollector.com, 1 +ipfixifies.com, 1 +ipfixify.com, 1 +ipfixinator.com, 1 +ipfixreplicator.com, 1 +ipfs.io, 1 +ipgeolocation.io, 1 +ipggroup.com, 1 +iphonekaitori.tokyo, 1 +iphonesoft.fr, 1 +iphostreputation.com, 1 +ipid.me, 1 +ipigri.tk, 1 +ipinfo.tw, 1 +ipioneer.ga, 1 +iplaycraft.ru, 1 +iplayradio.net, 0 +ipleak.net, 1 +ipledgeonline.org, 0 +iplist.cc, 1 +iplog.info, 0 +iplookup.tk, 1 +ipmatic.ga, 1 +ipmotion.ca, 1 +ipmscoutek.com, 1 +ipnetworking.net, 1 +ipo-times.jp, 1 +ipokabu.net, 1 +ipomue.com, 1 +iposm.net, 1 +ippawards.com, 0 +ipplans.com, 1 +ippo-juku.com, 1 +iprash.com, 1 +iprcenter.gov, 1 +iprep.it, 1 +ipresent.com, 1 +iprice.co.id, 1 +iprice.hk, 1 +iprice.my, 1 +iprice.ph, 1 +iprice.sg, 1 +iprice.vn, 1 +ipricethailand.com, 1 +iprim.ru, 1 +ipripojeni.cz, 1 +iproducemusic.com, 1 +iproductrepair.com, 1 +ips-consult.nl, 1 +ips-ihre-pflege-sachsen.de, 0 +ips-sachsen.de, 1 +ipschool.spb.ru, 1 +ipsecurelink.com, 1 +ipsilon-project.org, 1 +ipso.paris, 1 +ipssl.li, 1 +ipsum.dk, 1 +ipswitch.com.tw, 1 +iptechnology.tk, 1 +iptoasn.com, 1 +iptops.com, 1 +iptvmaxx.com, 1 +iptvzoom.xyz, 1 +ipty.de, 1 +ipura.ch, 0 +ipuservicedesign.com, 1 +ipushmail.tk, 1 +ipv4.cf, 1 +ipv4.gr, 1 +ipv4.rip, 1 +ipv6-adresse.dk, 1 +ipv6-handbuch.de, 1 +ipv6.bible, 1 +ipv6.cool, 1 +ipv6.jetzt, 0 +ipv6ioffentligsektor.se, 1 +ipv6vpn.net, 1 +ipv6wallofshame.com, 1 +ipvbook.com, 1 +iqboxy.com, 1 +iqos.com.ua, 1 +iqos.ml, 1 +iqratunisie.com, 1 +iqreview.ru, 1 +iqsecurity.eu, 1 +iqskinclinics.com, 1 +iqsmn.org, 1 +iqtechportal.com, 1 +iqtek.solutions, 1 +iqunit.com, 1 +irajsingh.tk, 1 +iraklisfovakis.com, 1 +iramellor.com, 1 +iran-best.cf, 1 +iran-speedex.tk, 1 +irancenter.tk, 1 +iranconnect.tk, 1 +irandex.ga, 1 +irandm.club, 1 +irando.co.id, 1 +irandroid.ml, 1 +iranfilmcity.tk, 1 +iranfreshfruit.cf, 1 +irangeodesy.tk, 1 +iranian.lgbt, 1 +iranianholiday.com, 1 +iranjeunesse.com, 1 +iranlinks.tk, 1 +iranonline.tk, 1 +iranophiles.com, 1 +iranophiles.net, 1 +iranophiles.org, 1 +iranpay.biz, 1 +iranpedia.tk, 1 +iransculpture.ir, 1 +iranturkey.info, 1 +iranvisa24.com, 1 +iranwiki.ovh, 1 +iraq2u.tk, 1 +iraq4u.tk, 1 +iraqinews.ga, 1 +irayo.net, 1 +irc-results.com, 1 +ircica.org, 0 +ircmett.de, 1 +ircnow.org, 1 +ircoholik.ml, 1 +ircsapiklari.tk, 1 +irdll.com, 1 +ireaco.com, 1 +iready.ro, 1 +ireef.tv, 1 +iregister.al, 1 +ireiguam.org, 1 +ireland.gq, 1 +irelandondemand.ie, 1 +irelandremembers.com, 1 +irelandremembers.ie, 1 +irelandremembers.org, 1 +iren.ch, 1 +irenekauer.com, 1 +irenelove.com, 1 +irenkuhn.ch, 0 +ireps.gov.in, 1 +ireta.net, 1 +irf2.pl, 1 +irfanweb.cf, 1 +irfs.org, 1 +irgendeine.cloud, 0 +irgit.pl, 1 +iridiumbrowser.de, 1 +irina-beauty.de, 1 +irinaf.tk, 1 +iringtone.net, 1 +irioka.be, 1 +iris-design.info, 1 +iris-insa.com, 1 +iris.gotdns.com, 1 +iriscddg.com, 1 +irische-segenswuensche.info, 1 +irisdesideratum.com, 1 +irisdesign.com, 1 +irish.dating, 1 +irish.radio, 1 +irishdenetwork.org, 1 +irishmusic.nu, 0 +irishradioplayer.radio, 1 +irisinclusiva.pt, 0 +irisjieun.com, 1 +irismq.fr, 1 +iritual.ru, 1 +irkfap.com, 1 +irkutsk-studygood.ga, 1 +irkutsk38.tk, 1 +irland-firma.com, 1 +irlfp.com, 1 +irlprable.tk, 1 +irma-gadalka.tk, 1 +irmag.ru, 1 +irmakprefabrik.com, 1 +irmgard-woelfle.de, 1 +irmgardkoch.com, 1 +irmo.hr, 1 +iroise.ch, 1 +ironbarnyc.com, 1 +ironbelly.pro, 1 +ironbow.com, 1 +ironbowhealthcare.com, 1 +ironcarnival.com, 1 +ironcladapp.com, 1 +ironcross.tk, 1 +ironfistdesign.com, 1 +ironfittings.com.br, 1 +ironhide.de, 0 +ironmongery.ga, 1 +ironmountainsolutions.com, 1 +ironpeak.be, 1 +ironraven.ch, 1 +ironraven.ml, 1 +ironscales.com, 1 +ironsidelubricants.com, 1 +ironsidemfg.com, 1 +irontigers.ml, 1 +ironwaytransport.com, 1 +ironwind.ga, 1 +ironycats.net, 1 +irr52.ru, 0 +irr59.ru, 1 +irrewilse.se, 1 +irritant.net, 1 +irstaxforumsonline.com, 1 +iruarts.ch, 1 +iruca.co, 1 +iruniruten.tk, 1 +irwinvalera.com, 1 +iryodatumoguide.com, 1 +is-a-furry.org, 1 +is-for-you.com, 1 +is-in-hyper.space, 1 +is-news.today, 1 +is-rocket.science, 0 +is-socket.tk, 1 +isa357.com, 1 +isa4310.com, 1 +isa5417.com, 1 +isaaccomputerscience.org, 1 +isaaccs.org, 1 +isaacdgoodman.com, 0 +isaacgolding.com, 1 +isaackabel.cf, 1 +isaackabel.ga, 1 +isaackabel.gq, 1 +isaackabel.ml, 1 +isaackabel.tk, 1 +isaackhor.com, 1 +isaacman.tech, 1 +isaacmorneau.com, 1 +isaacpartnership.co.uk, 1 +isaacphysics.org, 1 +isaaczais.com, 1 +isab.top, 1 +isabelaflores.com, 1 +isabelcaviedes.com, 1 +isabellavandijk.nl, 1 +isabelle-delpech.com, 0 +isabellehogarth.co.uk, 1 +isabellzaloof.ga, 1 +isabelmurillo-ordonez.com, 1 +isakow.cf, 1 +isakssons.com, 1 +isamay.es, 1 +isamiok.com, 1 +isaob.com, 1 +isara.com, 1 +isaropiping.fr, 1 +isastylish.com, 1 +isavings.com, 1 +isbaseballstillon.com, 1 +isbengrumpy.com, 1 +isc2chapter-cny.org, 1 +iscert.org, 1 +ischool.co.jp, 1 +iscontrol.com.mx, 1 +iscro.cn, 0 +isdecolaop.nl, 1 +isdn.jp, 1 +isdown.cz, 1 +isecrets.se, 1 +isekaimaid.xyz, 1 +iservicio.com.mx, 1 +iservicio.mx, 1 +iseulde.com, 1 +isex-anal.com, 1 +isf.fi, 1 +isg-tech.com, 1 +isgp-studies.com, 0 +ishangirdhar.com, 1 +isharryworking.today, 1 +ishet.al, 1 +ishhaara.in, 1 +ishigurodo.com, 1 +ishiharaken.com, 1 +ishimen.co.jp, 1 +ishland.com, 1 +ishome.org, 1 +ishopforpowerserg.com, 1 +ishtyl.com, 1 +isidore.uk, 1 +isif-ostewg.org, 1 +isil.fi, 1 +isimonbrown.co.uk, 1 +isimonline.tk, 1 +isincheck.com, 1 +isinolsun.com, 1 +isinthe.uk, 1 +isis.cloud, 1 +isisfighters.info, 1 +isiso.com.tr, 1 +isistomie.com, 1 +isitchristmas.com, 1 +isitcoffeetime.com, 1 +isitdoneyet.gov, 1 +isitef.com, 1 +isitnuclearwaryet.com, 1 +isitpatchtuesday.com, 1 +isitrest.info, 1 +iska.plus, 0 +iskanderbroere.nl, 1 +iskariot.info, 1 +iskaron.de, 1 +iskaz.rs, 1 +iskkk.com, 1 +iskkk.net, 1 +iskogen.nu, 1 +iskorka.tk, 1 +iskurturkiye.gq, 1 +islam-2day.tk, 1 +islam-azeri.tk, 1 +islam-doc.tk, 1 +islam.si, 1 +islam4all.tk, 1 +islam4congo.tk, 1 +islamabadcourt.tk, 1 +islambolivia.tk, 1 +islamdersi.tk, 1 +islamerkantho.com, 1 +islamicacademy.tk, 1 +islamicarchitecturalheritage.com, 1 +islamicmarkets.com, 1 +islamicnews.tk, 1 +islamicsolution.tk, 1 +islaminbremen.de, 0 +islamisgreat.tk, 1 +islamnews.ga, 1 +islamnewss.tk, 1 +islamonline.net, 1 +islampos.com, 1 +islamqa.info, 1 +islamspread.tk, 1 +island.studio, 1 +islandchillfiji.com.my, 1 +islandhosting.com, 1 +islandlakeil.gov, 1 +islandmapstore.com, 1 +islandmenshealth.com, 1 +islandsbanki.is, 1 +isletech.net, 1 +isletmenlikkursuankara.tk, 1 +isleyfarmsupply.com, 1 +isliada.org, 1 +islide-powerpoint.com, 1 +islief.com, 1 +islightdown.today, 1 +islykaithecutest.cf, 1 +islykaithecutest.ml, 1 +ismat.com, 1 +ismena.bg, 1 +ismywebsitepenalized.com, 1 +isn.cz, 1 +iso27032.com, 1 +isocom.eu, 1 +isognattori.com, 1 +isoindonesiacenter.com, 1 +isoip.org, 1 +isolde.com, 1 +isolta.com, 1 +isolta.de, 1 +isolta.ee, 1 +isolta.fi, 1 +isolta.lv, 1 +isolta.se, 1 +isondo.com, 1 +isopres.de, 1 +isoq.vn, 1 +isoroc-nidzica.pl, 1 +isotope.gov, 1 +isotopes.gov, 1 +isovideo.com, 1 +isowosi.com, 1 +ispanika.tk, 1 +ispaniola.ga, 1 +ispfontela.es, 1 +ispmedipv6.se, 1 +ispn.edu.ar, 1 +isportsfab.com, 1 +ispro-ng.com, 1 +ispsoft.pro, 1 +ispymissions.ga, 1 +israel-escorts.com, 1 +israel-in-color.com, 1 +israelbiblicalstudies.com, 1 +israelbizreg.com, 1 +israelil-leumi.co.il, 1 +israelimtovim.co.il, 1 +israelitopbox.ga, 1 +israelnewswire.tk, 1 +israelportalk.ml, 1 +israkurort.com, 1 +isreedyinthe.uk, 1 +isreedyinthe.us, 1 +isreedyintheuk.com, 1 +issa.org.pl, 0 +issaias.net, 0 +issasfrissa.se, 1 +isscouncil.com, 1 +isseenterprises.com, 1 +issforum.org, 1 +issho.jp, 1 +issio.net, 1 +isslshop.com, 1 +issue.watch, 1 +issuerconsulting.com, 1 +issues.email, 1 +ist-intim.de, 1 +istagb.ga, 1 +istanbul.systems, 1 +istdas.lol, 1 +isteinbaby.de, 1 +istekparcam.com, 1 +isterfaslur.com, 1 +isthatarabic.com, 1 +istheapplestoredown.com, 1 +istheapplestoredown.de, 1 +isthedoorlocked.com, 1 +isthefieldcontrolsystemdown.com, 1 +istheinterneton.com, 1 +istheinternetonfire.com, 1 +isthephone.com, 1 +istherrienstillcoach.com, 1 +istheservicedown.co.uk, 1 +istheservicedown.com, 1 +istheservicedowncanada.com, 1 +isthisarabic.com, 1 +isthisus.org, 1 +isthnew.com, 1 +istitutoimballaggio.org, 1 +istitutoricci.it, 1 +istitutovivaldi.it, 1 +istogether.com, 1 +istorija-balkana.tk, 1 +istormsolutions.co.uk, 1 +istorrent.is, 1 +istschonsolangeinrente.de, 1 +istsi.org, 1 +istudentpro.ml, 1 +isuggi.com, 1 +isustain.com.au, 1 +isutils.com, 1 +isv.online, 1 +isvbscriptdead.com, 1 +isvsecwatch.org, 1 +iswag.se, 1 +iswapgh.com, 1 +isyu.xyz, 1 +isz.no, 1 +iszy.cc, 1 +iszy.xyz, 1 +it-academy.sk, 1 +it-actual.ru, 1 +it-blog.cf, 1 +it-boss.ro, 1 +it-com.ga, 1 +it-ebook.ml, 1 +it-enthusiasts.tech, 1 +it-expert.tk, 1 +it-faul.de, 1 +it-inside.ch, 1 +it-jobbank.dk, 1 +it-kron.de, 1 +it-maker.eu, 1 +it-meneer.nl, 0 +it-ottweiler.de, 1 +it-perm.tk, 1 +it-rotter.de, 1 +it-schamans.de, 1 +it-seems-to.work, 1 +it-service24.at, 1 +it-service24.ch, 1 +it-service24.com, 1 +it-shamans.de, 1 +it-shamans.eu, 1 +it-stack.de, 1 +it-support-nu.se, 1 +it-support-stockholm.se, 1 +it-support.one, 1 +it-supportistockholm.se, 1 +it-supportnu.se, 1 +it-swarm.net, 1 +it-tekniker.nu, 1 +it-ti.me, 1 +it-uws.com, 0 +it-volgograd.tk, 1 +it-web-entwicklung.de, 1 +it-xperts.be, 1 +it-zt.at, 1 +it.com.eg, 1 +it.search.yahoo.com, 0 +it1b.com, 1 +it4sure.nl, 1 +it82.com, 1 +itabenar.tk, 1 +itabi.de, 1 +itactiq.com, 1 +itactiq.info, 1 +itad.top, 1 +itaiferber.net, 1 +itajvi.com, 1 +ital-gamma.be, 0 +italbavaro.com, 1 +italentado.ml, 1 +italia-store.com, 1 +italiachegioca.com, 1 +italiamour.com, 1 +italian-shoes.tk, 1 +italian.dating, 1 +italiana-lacrima.tk, 1 +italianshoemanufacturers.com, 1 +italiansrent.com, 1 +italiansrit.tk, 1 +italiaserie.org, 1 +italiataxi.ru, 1 +italiatopnews.tk, 1 +italieflydrive.nl, 1 +italiensk-tolk.dk, 1 +italik.co.uk, 1 +italk.ml, 1 +italserrande.it, 1 +italserver.com, 1 +italyinsider.ru, 1 +italyinspires.com, 1 +itamservices.nl, 1 +itap.gov, 1 +itarc.com.br, 1 +itaro.bot, 1 +itaro.ee, 1 +itaro.eu, 1 +itb-online.co.uk, 1 +itbasic.net, 1 +itbog.org, 1 +itbox.cl, 1 +itbrief.asia, 1 +itbrief.co.nz, 1 +itbrief.com.au, 1 +itbrouwerij.be, 1 +itcbuerobedarf.de, 1 +itchy.nl, 1 +itchybrainscentral.com, 1 +itconsulting-wolfinger.de, 1 +itconvergence.com, 1 +itcoolie.in, 1 +itcreative.ro, 1 +itcs.services, 1 +itdaan.com, 1 +itdashboard.gov, 1 +itdata.ro, 1 +itdoneproperly.com, 1 +itds-consulting.com, 1 +itds-consulting.eu, 1 +itdutchie.com, 1 +ite.st, 1 +itechpros.com.au, 1 +itecor.net, 0 +iteecafe.hu, 1 +iteha.de, 1 +iteke.ml, 1 +iteke.tk, 1 +iteksys.ru, 1 +itemcreator.tk, 1 +itemmc.com, 1 +itemorder.com, 1 +itemstore.ir, 1 +iternalnetworks.com, 0 +itero.eu, 1 +iterror.co, 1 +itezu.ml, 1 +itfall.tk, 1 +itfh.eu, 1 +itfix.cz, 1 +itgeeks.nl, 1 +itgirls.rs, 1 +itgoesup.com, 1 +itgoesupent.com, 1 +itgoesupentertainment.com, 1 +ithakama.com, 1 +ithakama.cz, 1 +ithedgehog.co.uk, 1 +ithenrik.com, 1 +ithinc.net, 1 +ithink.cf, 1 +ithjalpforetag.se, 1 +itidying.com, 1 +itikon.com, 1 +itilo.de, 1 +itis.gov, 1 +itis4u.ch, 1 +itisjustnot.cricket, 1 +itisyourmoney.co.uk, 1 +itiweb.tk, 1 +itjobsineurope.eu, 1 +itkaufmann.at, 1 +itkonsultstockholm.se, 1 +itleaked.gq, 1 +itlitera.com, 1 +itlog.tk, 1 +itlogic.com.au, 1 +itludens.com, 1 +itm-c.de, 1 +itmax.ua, 1 +itmedicinai.lt, 1 +itmindscape.com, 1 +itmustbee.com, 1 +itmx.cc, 1 +itn.co.uk, 1 +itneeds.tech, 1 +itnota.com, 1 +itnow.ng, 1 +itnrd.com, 1 +itochan.jp, 1 +itogoyomi.com, 1 +itoma.tech, 1 +itotalaccess.net, 1 +itouriria.com, 1 +itpanda.pl, 1 +itperm.tk, 1 +itpro-mg.de, 1 +itpro.ua, 1 +itraffic.cf, 1 +itraffic.tk, 1 +itraincalisthenic.com, 1 +itraveille.fr, 1 +itraveller.net, 1 +itreallyaddsup.com, 1 +itreboot.co.nz, 1 +itrendbuzz.com, 1 +itrew.ru, 1 +itrezzo.com, 1 +itring.pl, 0 +itrodeo.com, 1 +itruss.com.tw, 1 +itruth.tk, 1 +its-gutachten.de, 1 +its-schindler.de, 1 +its-truck.net, 1 +its-v.de, 1 +its.gov, 1 +its420somewhere.com, 1 +its4living.com, 1 +itsabouncything.com, 1 +itsakerhetspodden.se, 1 +itsalan.tk, 1 +itsallaboutplumbing.com, 1 +itsallinthedetailsllc.com, 1 +itsallsotireso.me, 1 +itsanicedoor.co.uk, 1 +itsapps.net, 1 +itsatrap.nl, 0 +itsaw.de, 1 +itsayardlife.com, 1 +itsblue.de, 1 +itsburning.nl, 1 +itsch-itsche.com, 1 +itsdcdn.com, 1 +itsec.link, 1 +itsecblog.de, 1 +itseeze.com, 1 +itseovn.com, 1 +itservis.org, 1 +itsevident.com, 1 +itsfitlab.com, 1 +itsgreener.com, 1 +itshealthtea.com, 1 +itshka.rv.ua, 1 +itsig-faq.de, 1 +itsm.tools, 1 +itsmejohn.org, 1 +itsmohitchahal.com, 1 +itsmyparty.ie, 1 +itsnotnot.tk, 1 +itsnotquitethehilton.com, 0 +itsnudi.com.br, 1 +itsoft.ru, 1 +itsok.de, 1 +itsok.link, 1 +itsoluciones.com.co, 1 +itspartytimeonline.co.uk, 1 +itspartytimesweetinflations.com, 1 +itspersonaltraining.nl, 1 +itsquiet.org, 1 +itsryan.com, 1 +itsstefan.eu, 1 +itstatic.tech, 1 +itsuitsyou.co.za, 1 +itsundef.in, 1 +itsupport24.tk, 1 +itsupportnacka.se, 1 +itswincer.com, 1 +itsynergy.co.uk, 1 +ittgame.tk, 1 +ittlloretdemar.com, 1 +itvaatlik.ee, 1 +itvia.email, 1 +itvia.eu, 1 +itvia.net, 1 +itvia.org, 1 +itwebentwicklung.de, 1 +itwell.cz, 1 +itworks.nyc, 1 +itxcjm.top, 1 +itzap.com.au, 1 +itzer.de, 1 +itzine.ru, 1 +itzkavin.tk, 1 +itzlive.tk, 1 +iubuniversity.tk, 1 +iurisnovagestion.es, 1 +iurisnow.com, 1 +iuspenal.com, 1 +iuyos.com, 1 +iv-vr.com, 1 +iv2.com, 1 +ivahbbiz.tk, 1 +ivampiresp.com, 1 +ivan-tadej.tk, 1 +ivan1874.cf, 1 +ivan1874.dynu.net, 1 +ivanaleksandrov.com, 1 +ivanbenito.com, 1 +ivancacic.com, 0 +ivanderevianko.com, 1 +ivanilla.org, 1 +ivankuchin.tk, 1 +ivanmeade.com, 1 +ivanovka.ga, 1 +ivanovocity.tk, 1 +ivanovolive.ru, 1 +ivanpolchenko.com, 1 +ivanwolf.ga, 1 +ivanzorin.cf, 1 +ivaoru.org, 1 +ivelop.me, 1 +ivendi.com, 1 +ivermectin.gq, 1 +ivetazivot.cz, 1 +ivetdata.com, 0 +ivfausland.de, 1 +ivfmeds.com, 1 +ivisa.ga, 1 +ivisitorinsurance.com, 1 +ivixor.space, 1 +ivjose.com, 1 +ivkymppi.fi, 1 +ivnext.org, 1 +ivo.co.za, 1 +ivocopro.com, 1 +ivocopro.de, 1 +ivocotec.com, 1 +ivoid.cf, 1 +ivoorellana.com, 1 +ivopetkov.com, 1 +ivor.io, 1 +ivor.is, 1 +ivorvanhese.com, 1 +ivorvanhese.nl, 1 +ivoryandgrace.com, 1 +ivoryonsunset.com, 1 +ivotemahdi.com, 1 +ivoucher-kuwait.com, 1 +ivpn.net, 1 +ivre.rocks, 1 +ivs-romania.ro, 1 +ivselena.ru, 1 +ivsign.net, 1 +ivvl.ru, 1 +ivx.gallery, 1 +ivxv.ee, 1 +ivy-league-colleges.com, 1 +ivyandrose.co, 1 +ivyhelpers.com, 1 +ivyis.org, 1 +ivyrose.shop, 1 +ivyways.com, 0 +iw.net.sa, 1 +iwader.co.uk, 1 +iwalton.com, 1 +iwantexchange.com, 1 +iwantpayments.com, 1 +iwanttoliveinabunker.com, 1 +iwanttrack.com, 1 +iwascoding.com, 1 +iwascoding.de, 1 +iwashealthy.com, 1 +iwatchcops.com, 1 +iwatchcops.org, 1 +iwatchla.net, 1 +iwatt.sk, 1 +iwch.tk, 1 +iwd.gc.ca, 1 +iwebsolution.tk, 1 +iwex.swiss, 1 +iwizerunek.pl, 1 +iww.me, 1 +iww.mx, 1 +ix8.ru, 0 +ixaris.com, 1 +ixds.org, 1 +ixit.cz, 1 +ixplayer.com, 1 +ixquick-proxy.com, 1 +ixquick.co.uk, 1 +ixquick.com, 1 +ixquick.de, 1 +ixquick.eu, 1 +ixquick.fr, 1 +ixquick.info, 1 +ixquick.nl, 1 +ixtan.ga, 1 +ixuexi.tech, 1 +iyan.es, 1 +iyassu.com, 1 +iyc.web.tr, 1 +iycharter.com, 0 +iyinolaashafa.com, 1 +iymark.com, 1 +iyn.me, 1 +iyouewo.com, 1 +iyoumu.top, 1 +iyume.top, 0 +iz8mbw.net, 1 +izamulhakeem.tk, 1 +izanah.com, 1 +izavel.com, 1 +izdaher.com, 1 +izecubz.me, 1 +izevg.ru, 1 +izipik.gq, 1 +izmir-media.gq, 1 +izmir-organizasyon.tk, 1 +izmirescort.tk, 1 +izmireskortlari.tk, 1 +izmirtemizlik.tk, 1 +izntz.com, 1 +izodiacsigns.com, 1 +izolpoznan.pl, 1 +izolyatsia.org, 1 +izone.ua, 1 +izonemart.com, 1 +izt.tech, 0 +izttech.com, 1 +izuba.info, 0 +izumi-ryokan.com, 1 +izumi.tv, 1 +izzyontour.tk, 1 +izzys.casa, 1 +j-ecolife.com, 1 +j-harrison-media.co.uk, 1 +j-harrison.co.uk, 1 +j-k-fischer-verlag.de, 1 +j-l.pw, 1 +j-maxton.de, 1 +j-navi.com, 1 +j-ph.ovh, 1 +j-robertson.com, 1 +j-sheekey.co.uk, 1 +j00228.com, 1 +j0bs.org, 1 +j0e.com, 1 +j0hn.net, 1 +j0hndball.com, 1 +j0rj.com, 1 +j0s.eu, 1 +j15h.nu, 1 +j1visahealthinsurance.com, 1 +j2ee.cz, 1 +j2h.de, 1 +j30365.com, 1 +j32662.com, 1 +j32663.com, 1 +j32664.com, 1 +j32665.com, 1 +j32771.com, 1 +j32772.com, 1 +j32773.com, 1 +j32774.com, 1 +j32775.com, 1 +j32b.com, 1 +j3349.com, 1 +j36533.com, 1 +j3e.de, 1 +j4e.name, 1 +j4m.xyz, 1 +j5197.co, 1 +j5lx.de, 1 +j5lx.eu, 1 +j5lx.io, 1 +j5y.de, 1 +j605.tk, 1 +j6729.co, 1 +j6729.com, 1 +j6957.co, 1 +j6957.com, 1 +j70111.com, 0 +j70222.com, 0 +j70333.com, 0 +j70444.com, 0 +j70501.com, 1 +j70502.com, 1 +j70503.com, 1 +j70504.com, 1 +j70505.com, 1 +j7051.com, 1 +j7052.com, 1 +j70555.com, 0 +j81365.com, 1 +j82365.com, 1 +j9297.co, 1 +j9297.com, 1 +j9507.com, 1 +j9508.com, 1 +j9511.com, 1 +j9512.com, 1 +j9514.com, 1 +j9515.com, 1 +j9516.com, 1 +j9517.com, 1 +j95app.com, 1 +j95bb.com, 1 +j95cc.com, 1 +j95dd.com, 1 +j95ee.com, 1 +j95ios.com, 1 +j95ss.com, 1 +j95xx.com, 1 +j95zz.com, 1 +j9721.com, 1 +j9728.co, 1 +ja-dyck.de, 1 +ja-gps.com.au, 1 +ja-hypnose.de, 1 +ja-no-me.ru, 1 +ja-sobstvennik.tk, 1 +ja-tay.sr, 1 +ja-zur-gs.de, 1 +ja1deijssel.tk, 1 +jaago-pakistan.tk, 1 +jaakkohannikainen.fi, 1 +jaamaa.com, 1 +jaarvistech.com, 1 +jaaxypro.com, 1 +jaba.hosting, 1 +jababu.cz, 1 +jabagly.com, 1 +jabba.homelinux.org, 1 +jabbari.io, 1 +jabbas.eu, 1 +jabber.at, 1 +jabber.uk, 1 +jabberd.org, 1 +jabberdog.tk, 1 +jabberfr.org, 1 +jabberster.tk, 1 +jabberzac.org, 1 +jabboworld.tk, 1 +jaberg-rutschi.ch, 1 +jabergrutschi.ch, 1 +jabjab.de, 1 +jabsolutions.tk, 1 +jacaranda-deutschland.org, 1 +jaccblog.com, 1 +jacekowski.org, 1 +jachtbouw.eu, 1 +jacik.cz, 1 +jack-p2.cyou, 1 +jack-p2.tech, 1 +jack.fr.eu.org, 1 +jack2celebrities.com, 1 +jackafur.net, 1 +jackal-cogito.tk, 1 +jackandrascals.com, 1 +jackassofalltrades.org, 1 +jackdawphoto.co.uk, 1 +jacket-coat.tk, 1 +jackets-coats.tk, 1 +jackets-coatsplus.tk, 1 +jackets-for-men.tk, 1 +jackf.me, 1 +jackgreenrealty.com, 1 +jackgreiner.ca, 1 +jackhammerinteractive.com, 1 +jackhoodtransportation.com, 1 +jackingramnissanparts.com, 1 +jackingsolutions.com, 1 +jackinmybox.com, 1 +jackjack.ga, 1 +jackmail.tk, 1 +jackmcgregor.uk, 1 +jackops.com, 1 +jackpothappy.com, 1 +jackrussel.tk, 1 +jackrusselterrier.com.br, 1 +jacksanalytics.com, 1 +jacksball.com, 1 +jackson-quon.com, 1 +jackson.jp, 1 +jacksoncountyfl.gov, 1 +jacksonhu.com, 1 +jacksonsykes.com, 1 +jacksorrell.com, 1 +jackspub.net, 1 +jackstone.tk, 1 +jacksutton.info, 1 +jackvaley.com, 1 +jackvalley.com, 1 +jackwarren.info, 1 +jackwilli.com, 1 +jackwozny.com, 1 +jackwu.net, 1 +jackylawless.net, 1 +jackyliao.me, 1 +jackyliao123.tk, 1 +jackyyf.com, 0 +jaco.by, 0 +jacobamunch.com, 1 +jacobey.net, 1 +jacobi-server.de, 1 +jacobian.org, 0 +jacobjangles.com, 1 +jacobphono.com, 1 +jacobs-implantate.at, 1 +jacobsenarquitetura.com, 1 +jacobsmeubels.nl, 1 +jacopomolina.me, 1 +jacquant.be, 1 +jacquesdedixmude.eu, 1 +jacquesfrantz.com, 1 +jaculus.eu, 1 +jacuzziprozone.com, 1 +jadara.info, 1 +jadchaar.me, 1 +jadedmonkey.tk, 1 +jadeforallseasons.com, 1 +jadehotel.nl, 1 +jadesong.cn, 1 +jadesong.net, 1 +jadidgroup.com, 1 +jadox.com, 1 +jaduniv.cf, 1 +jaeger.link, 1 +jaegerlacke.de, 1 +jaepinformatica.com, 1 +jaetech.org, 1 +jafarmehdipor.ga, 1 +jaffewebsites.com.au, 1 +jagad.id, 1 +jagadhatrionline.co.in, 1 +jagan.be, 1 +jagar.com.pl, 1 +jagbouncycastles.co.uk, 1 +jagerkin.tk, 1 +jagerman.com, 1 +jagido.de, 1 +jaguarkuda.com, 1 +jaguarlandrover-asse.be, 0 +jaguarlandrover-occasions.be, 0 +jahanaisamu.com, 1 +jahit.tk, 1 +jahner.xyz, 1 +jahofmann.de, 0 +jaiestate.com, 1 +jailbreakingisnotacrime.org, 1 +jailfood.ga, 1 +jailfooders.ga, 1 +jailstorm.ml, 1 +jaimechanaga.com, 1 +jaingynecology.com, 1 +jainmantras.com, 1 +jaion.ml, 1 +jaion.tech, 1 +jaion.xyz, 1 +jaisa.in, 1 +jaisiam.co.th, 1 +jaisin.com, 1 +jaispirit.com, 1 +jaiyen.com, 1 +jaiyun.tk, 1 +jakarta.dating, 1 +jakdelatseo.cz, 1 +jake.eu.org, 1 +jake.ml, 1 +jake.nom.za, 1 +jakebeardsley.com, 1 +jakecurtis.de, 1 +jakegyllenhaal.ga, 1 +jakejnx.com, 0 +jakemansfield.com, 1 +jakereynolds.co, 1 +jakeslab.tech, 1 +jaketremper.com, 0 +jakewales.com, 1 +jakincode.army, 1 +jako.tk, 1 +jakob-server.tk, 1 +jakobejitblokaci.cz, 1 +jakobkrigovsky.com, 1 +jakobssystems.net, 1 +jakpremyslet.cz, 1 +jakse.fr, 1 +jaksel.id, 1 +jaksi.io, 1 +jakub-boucek.cz, 1 +jakubarbet.eu, 1 +jakubboucek.cz, 1 +jakubklimek.com, 1 +jakubtopic.cz, 1 +jakubvrba.cz, 1 +jala.co.jp, 1 +jaleesa.sa, 1 +jaleo.cn, 1 +jallatte.fr, 1 +jalopnik.com, 1 +jaluzelemoderne.ro, 1 +jamaat.hk, 1 +jamacha.org, 1 +jamaica.gq, 1 +jamalfi.bio, 1 +jamberry.com.mx, 1 +jambihackerlink.tk, 1 +jamcyberinc.com, 1 +jameh.net, 1 +jamelhammoud.com, 1 +jamereviews.com, 1 +james-bell.co.uk, 1 +james-loewen.com, 1 +james-parker.com, 0 +james.guru, 1 +james.je, 1 +jamesaimonetti.com, 1 +jamesbillingham.com, 1 +jameschorlton.co.uk, 1 +jamesconroyfinn.com, 1 +jamesdorf.com, 1 +jamesedition.com, 1 +jamesevans.is, 1 +jamesgreenfield.com, 1 +jamesheald.com, 1 +jameshemmings.co.uk, 1 +jameshost.net, 1 +jameshunt.us, 1 +jamesj.me, 0 +jamesjboyer.com, 1 +jamesknd.uk, 0 +jamesl.tk, 1 +jameslahey.com, 1 +jamesmarsh.net, 1 +jamesmcdonald.com, 0 +jamesmilazzo.com, 1 +jamesmorrison.me, 1 +jamesnowlin.com, 1 +jamesonmelbye.com, 1 +jamesredmond.tk, 1 +jamesrobertson.sh, 1 +jamesross.name, 1 +jamesrtyrrell.com, 1 +jamesrush.com, 1 +jamessmith.me.uk, 1 +jamestmart.in, 1 +jamestmartin.me, 1 +jamestown.de, 0 +jamesturnerstickley.com, 1 +jameswarp.com, 1 +jamesxu.com, 1 +jamhost.org, 1 +jamie-read-photography.com, 1 +jamie.ie, 1 +jamieb.org, 1 +jamiehansonyoga.com, 1 +jamielinux.com, 1 +jamiemagee.co.uk, 1 +jamiemagee.dk, 1 +jamiepleasants.com, 1 +jamieweb.net, 1 +jamieweb.org, 1 +jamiewebb.net, 1 +jamirinyo.tk, 1 +jamjestsimon.pl, 1 +jammucake.com, 1 +jammysplodgers.co.uk, 1 +jamon.ca, 1 +jamstallt.se, 1 +jamstatic.fr, 1 +jamyeprice.com, 0 +jan-and-maaret.de, 1 +jan-bretschneider.de, 1 +jan-bucher.ch, 1 +jan-daniels.de, 1 +jan-graca.tk, 1 +jan-hill.com, 1 +jan-melcher.de, 1 +jan-reiss.de, 1 +jan-rieger.de, 1 +jan-roenspies.de, 1 +jan-von.de, 1 +jan.gl, 1 +jan.su, 1 +janada.cz, 1 +janakifoods.com, 1 +janata.net, 1 +janaundgeorgsagenja.eu, 1 +janavish.tk, 1 +janbilek.cz, 1 +janbretschneider.de, 1 +janbrodda.de, 1 +jandesign.at, 1 +jandev.de, 1 +jandj.yachts, 0 +jandonkers.com, 1 +jands.co.id, 1 +janduchene.ch, 1 +jane.com, 1 +janehamelgardendesign.co.uk, 1 +janelauhomes.com, 1 +janelle-jamer.tk, 1 +janellequintana.tk, 1 +janetandjohns.tk, 1 +janeweeber.com, 1 +janey.cf, 1 +janeymac.com, 1 +jangl.com, 1 +janheidler.dynv6.net, 1 +janhermann.cz, 1 +janhuelsmann.com, 1 +jani.media, 1 +janikrabe.com, 1 +janine-und-johannes.de, 1 +janitorutah.com, 0 +janjoris.nl, 1 +jankamp.com, 1 +janker.me, 0 +jann.is, 1 +jannehonkonen.tk, 1 +jannekekaasjager.nl, 1 +jannes-althoff.de, 1 +jannesmeyer.com, 1 +jannisfink.de, 1 +jannyrijneveld.nl, 1 +janokacer.sk, 1 +janome.club, 1 +janome.com.ua, 1 +janostheil.de, 1 +janschaumann.de, 1 +janservfl.com, 1 +janssen.fm, 1 +janterpstra.eu, 1 +jantinaboelens.nl, 1 +jantyik.com, 1 +janu-todo-list.herokuapp.com, 1 +janv.it, 1 +janvanmechelen.tk, 1 +janvari.com, 1 +janvaribalint.com, 1 +janw.me, 1 +jaot.info, 1 +japanasonic.ru, 1 +japanchiropractic.com.br, 1 +japanduhoc.com, 1 +japanese-cuisine.com, 1 +japanese-imperialism971.tk, 1 +japaneseacupuncture.london, 1 +japanesemotorsports.net, 1 +japanesque.ru, 1 +japangids.nl, 1 +japaniac.de, 1 +japanphilosophy.com, 0 +japanrail.nl, 1 +japanroll.cf, 1 +japansm.com, 1 +japansquared.com, 0 +japantravel.tk, 1 +japanwatches.xyz, 1 +jape.today, 1 +japlin.io, 1 +japlin.tk, 1 +japonyol.net, 1 +jar.cool, 1 +jaramilloconstrucciones.pe, 1 +jarcasting.com, 1 +jarcasting.in, 1 +jarcasting.ru, 1 +jardinderline.ch, 1 +jardineras.online, 1 +jardineriaon.com, 1 +jardinesimperiales.com, 1 +jaredeberle.org, 0 +jaredfernandez.com, 1 +jaredfraser.com, 1 +jaredkunz.com, 1 +jaredonline.tk, 1 +jarett-lee.com, 1 +jarl.ninja, 1 +jarmandental.com, 1 +jarmatys.pl, 1 +jarmix.fi, 1 +jarniashop.se, 1 +jarno.rocks, 1 +jarnob.xyz, 1 +jarnobogaert.com, 0 +jarnobogaert.xyz, 1 +jarods.org, 0 +jarofthread.com, 1 +jaroku.com, 1 +jarondl.net, 1 +jaroslavc.eu, 1 +jarovske-udoli.cz, 1 +jarovskeudoli.cz, 1 +jarquedelaval.tk, 1 +jarrah-alsilawi.com, 1 +jarrettgraham.com, 1 +jarroba.com, 1 +jarrods.tech, 1 +jarsater.com, 0 +jas-team.net, 1 +jasalokal.id, 1 +jasawebbisnis.com, 1 +jashvaidya.com, 1 +jasl.works, 1 +jasmijnwagenaar.nl, 1 +jasminedirectory.com, 1 +jasminefields.net, 1 +jasminka.cz, 1 +jasmyn.tk, 1 +jasnowidzkajowi.pl, 1 +jason.re, 1 +jasonadam.de, 0 +jasonamorrow.com, 1 +jasoncoopermd.com, 1 +jasoncs.eu.org, 1 +jasongerber.ch, 0 +jasonhardin.me, 1 +jasonisclever.com, 1 +jasonmili.online, 1 +jasonrobinson.me, 1 +jasonsansone.com, 1 +jasonsplecoscichlids.com, 1 +jasonwei.nctu.me, 1 +jasonwindholz.com, 1 +jasper.link, 1 +jasper.pt, 1 +jasperhammink.com, 1 +jasperhuttenmedia.com, 1 +jasperpatterson.com, 1 +jasperpatterson.me, 1 +jasperpatterson.net, 1 +jaspersreef.com, 1 +jaspven.net, 1 +jastrow.me, 1 +jaszbereny-vechta.eu, 1 +jateng.press, 1 +jatiwahidfurniture.com, 1 +jatransportadora.com, 1 +jav.st, 1 +jav0x.com, 1 +java-fan.tk, 1 +javabot.ml, 1 +javaexpert.tk, 1 +javafiles.tk, 1 +javamilk.com, 1 +javanguiano.mx, 1 +javanie.com, 1 +javascriptlab.fr, 1 +javaweb.site, 1 +javaxxz.com, 1 +jave.asia, 1 +javedhasrat.com, 1 +javfree.me, 1 +javi-soleil.tk, 1 +javierbalvin.com, 1 +javierburgos.net, 1 +javierflorescastillero.es, 1 +javierguandalini.com, 1 +javierlorente.es, 0 +javiermascherano.tk, 1 +javiersanchez.tk, 1 +javik.net, 1 +javiscoffee.com, 1 +javleech.com, 1 +javmobile.net, 1 +javocean.com, 1 +javorina.tk, 1 +javsod.top, 1 +jawn.ca, 1 +jawo2008.pl, 1 +jawwad.tk, 1 +jaxfstk.com, 1 +jaxxnet.co.uk, 1 +jaxxnet.org, 1 +jayanthreddy.ml, 1 +jaybeez.tk, 1 +jaybrokers.com, 1 +jayceeprints.com, 1 +jaycouture.com, 1 +jaydensar.net, 1 +jayf.de, 1 +jayfreestone.com, 1 +jayharkess.uk, 1 +jayharris.ca, 1 +jayhost.cf, 1 +jayjardine.cf, 1 +jaylee.us, 1 +jaymecd.rocks, 1 +jaynestephenson.com, 1 +jaypandit.me, 1 +jaypark.gq, 1 +jaysaw.me, 1 +jayschulman.com, 1 +jayshao.com, 1 +jaytx.com, 1 +jayveel.nl, 1 +jayxon.com, 1 +jayxu.com, 1 +jazerxx.com, 1 +jazminguaramato.com, 1 +jazz-alliance.com, 1 +jazz-alliance.org, 1 +jazzab-online.tk, 1 +jazzanet.com, 1 +jazzapart.tk, 1 +jazzband.tk, 1 +jazzfeet.co.uk, 1 +jazzy-feet.com, 1 +jazzy.id.au, 1 +jazzy.pro, 1 +jazzysumi.com, 1 +jb-pixel.tk, 1 +jb0.de, 1 +jb138.cc, 1 +jbah.info.vn, 1 +jbbd.fr, 1 +jbc88.cc, 1 +jbdesignfoundations.com, 1 +jbeta.is, 1 +jbfp.dk, 1 +jblackweb.com, 1 +jblan.org, 1 +jbliss.net, 1 +jboho.com, 1 +jbradaric.me, 1 +jbridal.com.au, 1 +jbs-jardins.ch, 0 +jbsinternational.com, 1 +jbt-stl.com, 1 +jcadg.com, 1 +jcai.dk, 1 +jcaicedo.com, 1 +jcaicedo.tk, 1 +jcb.com, 1 +jcbgolfandcountryclub.com, 1 +jccars-occasions.be, 1 +jccrew.org, 1 +jcde.xyz, 1 +jcelectronics.com.au, 1 +jcg.re, 1 +jchn.be, 1 +jci.cc, 1 +jci.me.uk, 1 +jci.name, 1 +jci.org.uk, 1 +jcinet.cc, 1 +jcinet.net, 1 +jcit.xyz, 1 +jclynne.com, 1 +jcontspoord.nl, 1 +jcor.me, 0 +jcphotography.dk, 1 +jcra.net, 1 +jcse.mil, 1 +jcsesecuneta.com, 1 +jcus.co, 1 +jcvignoli.com, 1 +jcwodan.nl, 1 +jd-group.co.uk, 1 +jd1.de, 1 +jd777.vip, 1 +jdara.com, 1 +jdassets.com, 1 +jdc.io, 1 +jdcdirectsales.com, 1 +jdcdirectsales.com.ph, 1 +jdcgroup.com.ph, 1 +jdd888.cc, 1 +jdecommastermind.com, 1 +jdefreitas.com, 1 +jdegbau.com, 1 +jdelgado.fr, 1 +jdheysupplies.co.uk, 1 +jdieselmusic.com, 1 +jdinjury.com, 1 +jdjohnsonmedia.com, 1 +jdjohnsonwaterproofing.com, 1 +jdm.elk.pl, 1 +jdm.pl, 1 +jdmgarage.com.au, 1 +jdncr.com, 1 +jdoi.pw, 1 +jdpleisure.co.uk, 1 +jdproofing.com, 1 +jdscastlehire.co.uk, 1 +jdtangney.com, 1 +jdtic.com, 1 +jdubya.info, 1 +je-vends.fr, 0 +je.net.cn, 1 +je2050.de, 1 +jean-luc.org, 1 +jean-remy.ch, 1 +jeancafe.ddns.net, 1 +jeancampa.com, 1 +jeancardeno.com, 1 +jeancarlos.tk, 1 +jeandanielfaessler.ch, 1 +jeangarcia.tk, 1 +jeankygourmet.com, 1 +jeanmarieayer.ch, 1 +jeanmichelaudet.com, 1 +jeanmusic.tk, 1 +jeannecalment.com, 1 +jeannelucienne.fr, 1 +jeanneret-combustibles.ch, 0 +jeanniegraefe.tk, 1 +jeannotbel.tk, 1 +jeanphilippe.io, 1 +jeans-butik.tk, 1 +jeans-moda.tk, 1 +jeans-shopping.tk, 1 +jeans-stores.tk, 1 +jeansbutik.tk, 1 +jeanslee.tk, 1 +jeansmoda.tk, 1 +jeansstyle.tk, 1 +jec-dekrone.be, 1 +jecho.cn, 1 +jecjacshop.com, 1 +jecnetwork.gq, 1 +jed.site, 1 +jeda.ch, 1 +jeda.im, 1 +jedatw.com, 1 +jedayoshi.com, 1 +jedayoshi.me, 1 +jedayoshi.tk, 1 +jedcg.com, 1 +jeddahlyn.nl, 1 +jedepannetonordi.ch, 1 +jedepannetonordi.com, 1 +jedepannetonordi.fr, 1 +jedi-master.tk, 1 +jedi-online.tk, 1 +jedilukmas.tk, 1 +jedipedia.net, 1 +jedmud.com, 1 +jedwarddurrett.com, 1 +jeec.ist, 1 +jeek.jp, 1 +jeemain.org, 1 +jeep-diagnost.ml, 1 +jeep4ik.com, 1 +jeepeg.com, 1 +jeeptourpocos.com.br, 1 +jeeran.com, 1 +jeeranservices.com, 1 +jef.yt, 1 +jefcorlabs.com, 1 +jeff.forsale, 1 +jeffanderson.me, 1 +jeffcloninger.net, 1 +jeffersonkyattorney.gov, 1 +jeffersonregan.co.uk, 1 +jeffersonregan.com, 1 +jeffersonregan.net, 1 +jeffersonregan.org, 1 +jeffersonvillepdin.gov, 1 +jeffhaferman.com, 1 +jeffhuxley.com, 1 +jeffmcneill.com, 1 +jeffok.com, 1 +jeffpenchoff.com, 1 +jeffreyhaferman.com, 1 +jeffri.me, 1 +jeffsanders.com, 1 +jefrydco.id, 1 +jefsweden.eu, 1 +jehelpdesk.nl, 1 +jehende.fr, 1 +jehovahsays.net, 1 +jej.cz, 1 +jej.sk, 1 +jejakbocah.com, 1 +jekhar.com, 1 +jel-tech.com, 1 +jelena-adeli.com, 1 +jelenkovic.rs, 1 +jell.ie, 1 +jellebo.dk, 1 +jellebuitenhuis.nl, 1 +jelleluteijn.com, 1 +jelleluteijn.eu, 1 +jelleluteijn.nl, 1 +jelleraaijmakers.nl, 1 +jelleschneiders.com, 0 +jelly.cz, 1 +jellybeanbooks.com.au, 1 +jellyfin.spdns.eu, 1 +jellyfishlivewire.co.uk, 1 +jellypepper.com, 1 +jellysquid.me, 1 +jelmer.co.uk, 1 +jelmer.uk, 1 +jelmoli-shop.ch, 1 +jem.gov, 1 +jem.shoes, 1 +jembatankarir.com, 1 +jemefaisdesamis.com, 1 +jemezsprings-nm.gov, 1 +jena.space, 0 +jencor.de, 1 +jencshiny-org.tk, 1 +jendialmeditation.com, 1 +jenelle.ml, 1 +jeneratorkiralama.name.tr, 1 +jenin.ml, 1 +jenkinscountyga.gov, 1 +jenkinsry.fi, 1 +jennethaarfotografie.nl, 1 +jennierobinson.com, 1 +jenniferchan.id.au, 1 +jenniferengerwingaantrouwen.nl, 1 +jenniferlucia.com, 1 +jennifermason.eu, 1 +jennifersauer.nl, 1 +jennifertilly.tk, 1 +jenniwiltz.com, 1 +jennysarl.ch, 0 +jennysource.tk, 1 +jennythebaker.com, 1 +jenolson.net, 1 +jenprace.cz, 1 +jens.hk, 1 +jensdesmeyter.be, 1 +jenslody.de, 1 +jensrex.dk, 1 +jents.ro, 1 +jenyak.com, 1 +jepa.si, 1 +jeparamedia.com, 1 +jeproteste.info, 1 +jeremiahbenes.com, 1 +jeremy-chen.org, 1 +jeremy.codes, 1 +jeremy.hu, 1 +jeremybentham.com, 1 +jeremybloomfield.co.uk, 1 +jeremyc.ca, 0 +jeremycantu.com, 1 +jeremycrews.com, 1 +jeremynally.com, 1 +jeremyness.com, 1 +jeremyrobinlyons.com, 1 +jeremysnotes.com, 1 +jeremytcd.com, 1 +jeremywinn.com, 1 +jeremywinn.xyz, 1 +jericamacmillan.com, 1 +jering.tech, 1 +jerisandoval.tk, 1 +jermann.biz, 1 +jerodslay.com, 1 +jeroendeneef.com, 1 +jeroendev.one, 1 +jeroendj.nl, 1 +jeroenensanne.wedding, 1 +jeroldirvin.com, 1 +jerome-r.tk, 1 +jerome.to, 1 +jerret.de, 1 +jerridoswell.tk, 1 +jerryabrams.com, 1 +jerrybustillo.tk, 1 +jerrysretailstores.com, 1 +jerrytindell.com, 1 +jerryweb.org, 1 +jerryyu.ca, 1 +jerseybikehire.co.uk, 1 +jerseyink.net, 1 +jerseyjumpingbeans.co.uk, 1 +jerseylvi2013.org, 1 +jerseyplantsdirect.com, 0 +jerusalempersonals.ml, 1 +jesec.cn, 1 +jesiensredniowiecza.pl, 1 +jesmh.de, 1 +jesperandersson.tk, 1 +jesseblum.com, 1 +jessecharley.com, 1 +jessecharli.com, 1 +jessecharlie.com, 1 +jessecharlie.net, 1 +jessecharlie.org, 1 +jessecharlienaser.com, 1 +jesseerbach.com, 1 +jessekaufman.com, 1 +jessem.fr, 1 +jessenaser.com, 1 +jessenaser.net, 1 +jessenaser.org, 1 +jesseonline.tk, 1 +jessesjumpingcastles.co.uk, 1 +jessetrebil.com, 1 +jessetrebilfoundationsystems.com, 1 +jessevictors.com, 1 +jessgranger.com, 1 +jessica-weller.de, 1 +jessicabarends.nl, 1 +jessicabenedictus.nl, 0 +jessicaescortsservices.com, 1 +jessicaevrard.com, 1 +jessicahrehor.com, 1 +jessicharlie.com, 1 +jessieabraham.tk, 1 +jessiecharlie.com, 1 +jesslynfietje.com, 1 +jessycharlie.com, 1 +jesters-court.net, 1 +jestyc.com, 1 +jesuisadmin.fr, 1 +jesuisunpapageek.fr, 1 +jesuscapitan.tk, 1 +jesuschrist.com.au, 1 +jesuscnasistente.com, 1 +jesusdenazaret.com, 1 +jesusnazarenobaena.tk, 1 +jesusthegoodshepherd.org, 1 +jesusvasquez.tk, 1 +jet-stream.fr, 1 +jetable.org, 1 +jetapi.org, 1 +jetbbs.com, 1 +jetcost.com, 1 +jetcraft.tk, 1 +jetfirenetworks.com, 1 +jetflex.de, 1 +jetixclub.tk, 1 +jetkittens.co.uk, 1 +jetmirshatri.com, 0 +jetpack.com.ar, 1 +jetsadabetchoke77.com, 1 +jetsieswerda.nl, 1 +jetstudio.ch, 1 +jetswhiteout.com, 1 +jettenbommelaer.nl, 1 +jettenjachtbouw.eu, 1 +jettlarue.com, 1 +jettravel.com.mt, 1 +jettshome.org, 1 +jetular.com, 1 +jetular.net, 1 +jetwhiz.com, 1 +jetzt-elektromobil.de, 1 +jeugdclubjia.tk, 1 +jeugdkans.nl, 1 +jeugdraad.gent, 1 +jeugdwmo.nl, 1 +jeurissen.co, 1 +jeuxerotiques.net, 1 +jeuxetcodes.fr, 1 +jevisite.ca, 1 +jewadvert.ml, 1 +jewaedv.de, 1 +jeweet.net, 1 +jewelcaddesigns.com, 1 +jewellerymarvels.com, 0 +jewelleryrack.com, 1 +jewelry-directories.tk, 1 +jewish.ee, 1 +jewishboyscouts.com, 1 +jewishinseattle.org, 1 +jewishquotations.com, 1 +jexler.net, 1 +jez.nl, 1 +jezebel.com, 1 +jezeravillage.com, 1 +jf-beco.pt, 1 +jf-fotos.de, 1 +jf-igrejanovadosobral.pt, 1 +jf-projects.de, 0 +jf886.cc, 1 +jfbst.net, 1 +jfcare.dk, 1 +jfgselbitztal.tk, 1 +jfhr.de, 1 +jfjtransport.com, 1 +jfklibrary.gov, 1 +jfr.im, 1 +jfreitag.de, 0 +jftw.org, 1 +jfvaccountants.nl, 1 +jfy.jp, 1 +jg-skid.me, 1 +jg078.com, 1 +jgid.de, 1 +jgke.fi, 1 +jgoguen.ca, 1 +jgoldgroup.com, 1 +jgregory.co.uk, 1 +jgwb.de, 1 +jgwb.eu, 1 +jhandke.de, 1 +jhatpatjobs.com, 1 +jhaveri.net, 1 +jhburton.co.uk, 1 +jhcommunitysports.co.uk, 1 +jhe.li, 1 +jhill.de, 1 +jhmrcm.com, 1 +jhof.jp, 1 +jhollandtranslations.com, 1 +jhoncampos.com, 1 +jhonesmarcos.tk, 1 +jhonmurillo.ml, 1 +jhost.gq, 1 +jhuang.me, 1 +jhw3d.com, 1 +jhwestover.com, 1 +jiacl.com, 1 +jiahao.codes, 1 +jialinwu.com, 1 +jian.spb.ru, 1 +jianbin.wang, 1 +jiangmei.ml, 1 +jiangmen.tk, 1 +jiangshiart.com, 1 +jiangwu.eu, 1 +jiangxu.site, 1 +jiangzhuyun.net, 0 +jiangzm.com, 0 +jianji.de, 1 +jianny.me, 1 +jianshu.com, 1 +jianwei.wang, 1 +jianyuan.art, 1 +jianyuan.pro, 1 +jiaqiang.vip, 1 +jiatingtrading.com, 1 +jiaty.com, 1 +jiaxitian.com, 1 +jiayi.eu.org, 1 +jiayi.life, 1 +jiazhao.ga, 1 +jicaivvip.com, 1 +jichi.io, 1 +jichi.nz, 1 +jichi000.win, 1 +jieyang2016.com, 1 +jif.gc.ca, 1 +jigsawplanet.com, 1 +jiheng.tk, 1 +jiid.ga, 1 +jiji.co.ke, 1 +jiji.co.tz, 1 +jiji.com.et, 1 +jiji.com.gh, 1 +jiji.ke, 1 +jiji.ng, 1 +jiji.ug, 1 +jijistatic.com, 1 +jikarentalcar.com, 1 +jikegu.com, 1 +jilworldwide.org, 1 +jimautoservice.pl, 1 +jimbiproducts.com, 1 +jimbutlerkiaparts.com, 1 +jimcoggeshall.com, 1 +jimdorf.com, 1 +jime-hlavou.cz, 1 +jimeaton.com, 1 +jimezdrave.cz, 1 +jimfranke.com, 1 +jimfranke.nl, 1 +jimizhou.xyz, 1 +jimkimmel.com, 1 +jimmiestore.com, 1 +jimmycai.com, 1 +jimmycarterlibrary.gov, 1 +jimmyroura.ch, 0 +jimshaver.net, 1 +jimsheatandcool.com, 1 +jimslop.nl, 1 +jimwoodrealty.com, 1 +jimwoodrealty.help, 1 +jinancy.fr, 1 +jinanshen.com, 1 +jinbijin.nl, 1 +jinbo123.com, 0 +jinbowiki.org, 1 +jinduoduo369.com, 1 +jinduoduo666.com, 1 +jinduoduo888.com, 1 +jing.su, 1 +jingbo.fan, 1 +jingjo.com.au, 1 +jingmakeji.cn, 1 +jinja.ai, 1 +jinkuru.net, 1 +jinliming.ml, 1 +jino-jossy.appspot.com, 1 +jino.gq, 1 +jinshuju.net, 1 +jiogo.com, 1 +jiotvdth.com, 1 +jiretvariedades.com, 1 +jiripik.com, 1 +jisai.net.cn, 1 +jischool.org, 1 +jisnashville.gov, 1 +jitprod.com, 1 +jitterbit.com, 1 +jittruckparts.com, 1 +jiweadventure.com, 1 +jix.im, 1 +jixun.eu, 1 +jixun.moe, 1 +jixun.uk, 1 +jiyue.com, 1 +jiyue.moe, 1 +jiyuu-ni.com, 1 +jiyuu-ni.net, 1 +jj5197.co, 1 +jj6729.co, 1 +jj6729.com, 1 +jj6957.co, 1 +jj9297.co, 1 +jj9397.com, 1 +jj9721.com, 1 +jj9728.co, 1 +jjhampton.com, 1 +jjj.blog, 1 +jjphospitalaria.com, 1 +jjspartyhire.co.uk, 1 +jjsummerboatparty.co.uk, 1 +jjvanoorschot.nl, 1 +jk-entertainment.biz, 1 +jk-rjevka.gq, 1 +jkbfabrics.com, 1 +jkbizsolutions.org, 1 +jkdhn.me, 1 +jkelder.com, 1 +jkest.cc, 1 +jkfindings.com, 1 +jkg.tw, 1 +jki.io, 1 +jkinteriorspa.com, 1 +jklas.cz, 1 +jkloli.tk, 1 +jkng.eu, 1 +jkrcuidadopersonal.com, 1 +jkrippen.com, 1 +jkuu.org, 1 +jkvglobalsourcing.com, 1 +jkvov.com, 1 +jkyuan.tk, 1 +jl-dns.eu, 1 +jl-dns.nl, 1 +jl-exchange.nl, 1 +jl-mail.nl, 1 +jlbleakley.com, 1 +jld.paris, 1 +jldrenergysaver.com, 1 +jlink.nl, 1 +jlkhosting.com, 1 +jlmunn.com, 1 +jloh.co, 1 +jloh.codes, 1 +jlot.org, 1 +jlpn.eu, 1 +jlpn.nl, 1 +jlponsetto.com, 1 +jlr-luxembourg.com, 0 +jltcsecuritygroup.com, 1 +jltctech.com, 1 +jmanalansan.com, 1 +jmap.support, 1 +jmarciniak.it, 1 +jmb.lc, 1 +jmbeautystudio.se, 1 +jmbmexico.com, 1 +jmbproject.ga, 1 +jmcashngold.com.au, 1 +jmcataffo.com, 1 +jmce.eu, 1 +jmcleaning.services, 1 +jmdekker.it, 1 +jmdiesel.com, 1 +jmedesign.tk, 1 +jmedved.com, 1 +jmeno.eu, 1 +jmentertainment.co.uk, 1 +jmg3.dynu.net, 1 +jmisern.com, 1 +jmk.hu, 1 +jmlogistica.com, 1 +jmmanadobitung.co.id, 1 +jmorahan.net, 1 +jmpb.hu, 1 +jms8.net, 1 +jmsjms.cc, 1 +jmsjms.me, 1 +jmsjms.org, 1 +jmsjms.xyz, 1 +jmsmarcelo.tk, 1 +jmsole.cl, 1 +jmsolodesigns.com, 1 +jmssg.jp, 1 +jmstfv.com, 1 +jmsystems.sk, 1 +jmussman.net, 1 +jmwap.com, 1 +jmzo.nl, 1 +jn1.me, 1 +jncie.eu, 1 +jnjdj.com, 1 +jnm-art.com, 1 +jnordell.com, 1 +jnshome.com, 1 +jnssnfotografie.nl, 1 +jnsz.hu, 1 +jo3-w3b-d3v.com, 1 +joa-ebert.com, 1 +joanjensen.net, 1 +joanofarcmtcarmel.org, 1 +joansoy.com, 1 +joaoaugusto.net, 0 +joaobautista.com, 1 +joaojunior.com, 1 +joaosampaio.com.br, 1 +job-chocolat.jp, 1 +job-uber.com, 1 +job.biz.tr, 1 +job2serv.com, 1 +jobalicious.nl, 1 +jobastudio.nl, 1 +jobatus.com.br, 1 +jobatus.es, 1 +jobatus.it, 1 +jobatus.mx, 1 +jobatus.pt, 1 +jobbidag.se, 1 +jobbkk.com, 1 +jobbsafari.no, 1 +jobbsafari.se, 1 +jobcorpsy2y.com, 1 +jobfresh.ga, 1 +jobfrog.com.au, 1 +jobfury.com, 1 +jobgenic.com, 1 +jobhouse.jp, 1 +jobify.in, 1 +jobig.co.il, 1 +jobin.care, 1 +jobinbennykutty.com, 1 +jobindex.dk, 1 +jobit.gr, 1 +jobkaka.com, 0 +joblab.com.ua, 0 +joblife.co.za, 1 +jobmi.com, 1 +jobmiplayground.com, 1 +jobrus.ga, 1 +jobrus.ml, 1 +jobs-in-the-middle-east.tk, 1 +jobs-it.tk, 1 +jobs.at, 1 +jobs.ch, 1 +jobs.schwarz, 1 +jobs.su, 1 +jobs4sales.ch, 1 +jobseekeritalia.it, 1 +jobsindemedia.nl, 1 +jobsisbrown.com, 1 +jobsjj.com, 1 +jobskilled.co.za, 1 +jobsnet.eu, 1 +jobsocity.com, 1 +jobsoid.com, 1 +jobsportalbookmarking.tk, 1 +jobsuchmaschine.ch, 1 +jobtread.com, 1 +jobty.net, 1 +joburgplumbing.co.za, 1 +jobvoyager.com, 1 +jobwinner.ch, 1 +jobynet.tk, 1 +jobzninja.com, 1 +jocata.com, 1 +jocelynjenkins.com, 1 +jochem.pro, 0 +jockbusuttil.co.uk, 1 +jockbusuttil.com, 1 +jockbusuttil.uk, 1 +jocuri-noi.tk, 1 +jocurionline.eu, 1 +jodaniels.photography, 1 +jodbush.com, 1 +jodlajodla.si, 1 +joduska.me, 1 +jodyboucher.com, 0 +jodyshop.com, 1 +joe262.com, 1 +joeainsworth.com, 1 +joearodriguez.com, 1 +joebiden.com, 1 +joecod.es, 1 +joedavison.me, 1 +joedeblasio.com, 1 +joedoyle.us, 1 +joedroll.com, 1 +joefixit.co, 1 +joefixit.co.uk, 1 +joehenry.co.uk, 1 +joejacobs.me, 1 +joel-mayer.de, 1 +joel.coffee, 1 +joeldrapper.com, 1 +joelfries.com, 1 +joelito.tk, 1 +joelj.org, 1 +joelle.me, 1 +joelleandpeter.co.uk, 1 +joellimberg.com, 1 +joellombardo.com, 0 +joelmarkhamphotography.com.au, 1 +joelmunch.com, 1 +joelsolkoff.com, 1 +joelving.dk, 1 +joepitt.co.uk, 0 +joerg-wellpott.de, 1 +joergschneider.com, 1 +joernwendland.de, 1 +joerss.at, 1 +joeseago.com, 0 +joeskup.com, 1 +joesniderman.com, 1 +joespaintingpgh.com, 1 +joestead.codes, 0 +joetsutj.com, 1 +joetyson.io, 1 +joetyson.me, 1 +joeyhoer.com, 1 +joeysmith.com, 1 +joeyvanvenrooij.nl, 1 +joeyvilaro.com, 1 +jofel-kinderkleding.tk, 1 +jogi-server.de, 1 +jogjacar.com, 1 +jogjakarta.tk, 1 +jogorama.com.br, 0 +jogosdeanimais.org, 1 +jogwitz.de, 1 +johan-koffeman.tk, 1 +johanbissemattsson.se, 0 +johand.io, 1 +johanlog.com, 1 +johann.tk, 1 +johanna.gallery, 1 +johannaojanen.com, 1 +johannavarmala.fi, 1 +johannes-bauer.com, 1 +johannes-schaefer.de, 1 +johannes-sprink.de, 0 +johannes-zinke.de, 1 +johannes.io, 1 +johannes.wtf, 1 +johannesen.tv, 1 +johannfritsche.de, 1 +johanpeeters.com, 1 +johansf.tech, 1 +johego.org, 1 +johlmike.com, 1 +johnathanhasty.com, 1 +johnball.co, 1 +johnbeil.com, 1 +johnberan.com, 1 +johnblackbourn.com, 1 +johnblackwell.net, 1 +johnblotsky.tk, 1 +johncam.tk, 1 +johncook.co.uk, 1 +johncook.ltd.uk, 1 +johndball.co, 1 +johndball.com, 1 +johndball.info, 1 +johndball.net, 1 +johndball.org, 1 +johndeisher.com, 1 +johnex.se, 1 +johnfulgenzi.com, 1 +johngallias.com, 0 +johngmchenrymd.com, 1 +johngreatwood.com, 1 +johnguant.com, 1 +johnhgaunt.com, 1 +johninwood.com, 1 +johnjayro.com, 1 +johnkastler.net, 1 +johnkraal.com, 1 +johnmac.cn, 1 +johnmalloneemd.com, 0 +johnmcc.net, 1 +johnmcintosh.pro, 1 +johnmichel.org, 1 +johnmillerdesign.com, 1 +johnno.be, 1 +johnnybegood.tk, 1 +johnnybet.com, 1 +johnnybetstaging.com, 1 +johnnybsecure.com, 1 +johnnydoe.tk, 1 +johnopdenakker.com, 1 +johnroach.io, 1 +johnroberts.me, 1 +johnrockefeller.net, 1 +johnrosen.xyz, 1 +johnrosewicz.com, 1 +johnsegovia.com, 1 +johnsongenealogy.net, 1 +johnsonho.net, 1 +johnsonran.cn, 1 +johnstrad.com, 1 +johnswarbrick.com, 1 +johntomasowa.com, 1 +johnvanhese.nl, 1 +johnwinter.tk, 1 +johny.tv, 1 +johnyytb.be, 1 +johutha.ch, 1 +johyn.me, 1 +joi-dhl.ch, 0 +joifur.com, 1 +joinamericacorps.gov, 1 +joinhonor.com, 1 +joinmobilizon.org, 1 +joinpeertube.org, 1 +jointechforce.org, 1 +jointotem.com, 1 +joinus-outfits.nl, 1 +jojo.sg, 1 +jojosplaycentreandcafeteria.co.uk, 1 +jokedalderup.nl, 1 +jokersro.tk, 1 +jokertv.ovh, 1 +jokesbykids.com, 1 +jokewignand.nl, 1 +joksara.tk, 1 +joky.io, 1 +jolette-hernandez.tk, 1 +joletteperu.tk, 1 +jolfamarket.com, 1 +joliet.gov, 1 +joliettech.com, 1 +jolinebrussel.nl, 1 +jollausers.de, 1 +jolle.io, 1 +jollygoodspudz.ca, 1 +jollyjoker.de, 1 +jollykidswobbleworld.co.uk, 1 +jollytotschildminder.com, 1 +jolo.software, 1 +jolokia.ch, 1 +jomagus.de, 1 +jomo.tv, 1 +jomsolat.tk, 1 +jon8rfc.homeip.net, 1 +jonahburke.com, 1 +jonahperez.com, 1 +jonahtheprophet.tk, 1 +jonale.net, 1 +jonandnoraswedding.com, 1 +jonas-thelemann.de, 1 +jonas.me, 1 +jonasherkel.de, 1 +jonaskarlssonfoto.se, 1 +jonaskjodt.com, 1 +jonaskoeritz.de, 1 +jonaskruckenberg.de, 0 +jonasled.de, 1 +jonasmoeller.de, 1 +jonaswitmer.ch, 1 +jonatan.gq, 1 +jonathan-apps.com, 1 +jonathan.us.com, 1 +jonathancarter.org, 1 +jonathandupree.com, 1 +jonathanisaac.com, 1 +jonathanlara.com, 1 +jonathanmassacand.ch, 1 +jonathanphoto.fr, 1 +jonathanreyes.com, 0 +jonathanrobichaud.ca, 1 +jonathanrobichaud.gq, 1 +jonathansanchez.pro, 1 +jonathansomoza.it, 1 +jonathantaylorthomas.tk, 1 +jonathanwisdom.com, 1 +jonathonkimmel.com, 1 +jonbarron.cf, 1 +jonblankenship.com, 1 +jondarby.com, 1 +jondevin.com, 1 +jondowdle.com, 0 +jonesborostatebank.com, 0 +jonescountyiowa.gov, 1 +jonescountyiowaelections.gov, 1 +jonesfor.men, 1 +jonesopolis.xyz, 1 +jonespayne.com, 0 +jonestrading.com, 1 +jonferwerda.net, 1 +jonfor.net, 1 +jong030.nl, 1 +jongbloed.nl, 1 +jongcaxent.tk, 1 +jongcs.com, 1 +jongenwijs.gent, 1 +jongpay.com, 1 +jongtonghapkido.tk, 1 +jonilar.com, 1 +jonincharacter.com, 1 +jonirrings.com, 1 +jonkermedia.nl, 0 +jonlabelle.com, 1 +jonlu.ca, 1 +jonnasbeauty.com, 1 +jonny5.ru, 1 +jonnybarnes.uk, 1 +jonnygreenwood.tk, 1 +jonoalderson.com, 1 +jonohewitt.com, 1 +jonola.com, 1 +jonpads.com, 1 +jonpavelich.com, 1 +jons.org, 1 +jonscaife.com, 1 +jonsey.co, 1 +jonssheds.direct, 1 +jonstar.tk, 1 +joodari.fi, 1 +jooksuratas.ee, 1 +joomla-leipzig.com, 1 +joomlaclub.ch, 1 +joomladeveloper.ru, 1 +joomlon.com, 0 +joompress.biz, 1 +joona.pw, 1 +joorshin.ir, 1 +joostbovee.nl, 1 +joostmaglev.nl, 1 +joostrijneveld.nl, 1 +joostvanderlaan.nl, 1 +jootshop.ga, 1 +jophson.tk, 1 +joran.org, 1 +jorcus.com, 1 +jordan-jungk.de, 1 +jordandevelopment.com, 1 +jordandirections.com, 1 +jordanhamilton.me, 1 +jordankmportal.com, 1 +jordanp.engineer, 1 +jordanprice.ml, 1 +jordanprogrammer.tk, 1 +jordanrey.net, 1 +jordans.co.uk, 1 +jordanscorporatelaw.com, 1 +jordansfiles.tk, 1 +jordansmovies.tk, 1 +jordansrequests.tk, 1 +jordanstrustcompany.com, 1 +jordhy.com, 1 +jordibelgraver.email, 1 +jordibelgraver.eu, 1 +jordibelgraver.xyz, 1 +jordywijman.nl, 1 +jorexenterprise.com, 1 +jorgelopezorquesta.tk, 1 +jorgemarquez.es, 1 +jorgenegrete.tk, 1 +jorgvandeven.nl, 1 +jorisdalderup.nl, 1 +jornadasciberdefensa2016.es, 1 +jornalalerta.com.br, 1 +jornalaquidf.com.br, 1 +jorritstollman.com, 0 +jorsev.com, 1 +jos-verstappen-fan.tk, 1 +josc.com.au, 1 +joscares.com, 1 +jose-alexand.re, 1 +jose-latino.tk, 1 +jose-lesson.com, 1 +jose-manuel-benito-alvarez.tk, 1 +josealonsodds.com, 1 +joseenriquegonzalez.tk, 1 +joseetesser.nl, 1 +josef-lotz.de, 1 +josefernandomorilloardila.tk, 1 +josefjanosec.com, 1 +josefottosson.se, 1 +josefranca.pt, 0 +josejimenezgonzalez.es, 1 +josemortellaro.com, 1 +josepbel.com, 1 +josephalexander.media, 1 +josephbarela.com, 1 +josephcz.win, 0 +josephcz.xyz, 0 +josephgeorge.com.au, 1 +josephmarino.net, 1 +josephpinder.com, 1 +josephrichard.com, 1 +josephsniderman.com, 1 +josephsniderman.net, 1 +josephsniderman.org, 1 +josephv.website, 1 +josephziegler.com, 1 +josericaurte.com, 1 +joshdiamant.com, 1 +joshfoley.co.uk, 1 +joshgilson.com, 1 +joshgrancell.com, 1 +joshgroban.tk, 1 +joshharkema.com, 1 +joshharmon.me, 1 +joshhoffer.com, 1 +joshimedical.com, 1 +joshjanzen.com, 1 +joshking.com, 1 +joshliba.com, 1 +joshlovephotography.co.uk, 1 +joshmoulin.com, 1 +joshpanter.com, 0 +joshrickert.com, 1 +joshruppe.com, 1 +joshschmelzle.com, 1 +joshtriplett.org, 1 +joshu.am, 1 +joshua-kuepper.de, 1 +joshua.bio, 1 +joshua.mn, 1 +joshuadiamant.com, 1 +joshuahemphill.com, 1 +joshuajohnson.ca, 1 +joshuamccracken.org, 1 +joshuamessick.com, 1 +joshuameunier.com, 1 +joshuaschmitt.us, 1 +josien.fr, 1 +josien.net, 1 +josmith.co.za, 1 +josoansi.de, 1 +jossandmain.com, 1 +jotajotapro.es, 1 +jotbe.io, 1 +jotes-creations.de, 1 +jottenheijm.com, 1 +joubinkhorsandmd.com, 1 +jouetspetitechanson.com, 1 +jouleperformance.ch, 1 +jouleperformance.de, 1 +jouons-aux-echecs.be, 1 +jourbook.cf, 1 +jourdain.pro, 1 +journal84.ch, 1 +journaldufumeur.ch, 1 +journales.com, 1 +journalism-schools.com, 1 +journaliste.tk, 1 +journalof.tech, 1 +journalpmn.com, 1 +journeedesfilles.gc.ca, 1 +journeyfriday.rocks, 1 +journeying.ca, 1 +journeyof1000hops.com, 1 +journeyofmymothersson.com, 1 +journeytoascension.com, 1 +journeytofi.com, 1 +journeytomastery.net, 1 +joustsec.ca, 1 +joustsec.com, 1 +joustsecurity.com, 1 +jouwbuis.nl, 1 +jouwpaardenbak.nl, 1 +jouwtechnischecoach.nl, 1 +jovani.com, 0 +jovenescontraelaburrimiento.tk, 1 +joviam.com, 1 +jovic.hamburg, 1 +jovisa.com.tw, 1 +joworld.net, 0 +joy-ride.yokohama, 1 +joyacorp.com, 1 +joychetry.com, 1 +joydivision.tk, 1 +joyful.house, 1 +joyfulevents.tk, 1 +joyfulexpressions.gallery, 1 +joyfulhealthyeats.com, 1 +joyinverse.com, 1 +joyjohnston.ca, 0 +joymaxiptv.com, 1 +joyofcookingandbaking.com, 1 +joyofhaskell.com, 1 +joyousisle.com, 1 +joyqi.com, 1 +joyreactor.cf, 1 +joysinventingblog.com, 1 +joythroughlaughter.com, 1 +jozefkvasnica.tk, 1 +jp-aic.com, 1 +jp.kg, 1 +jp.md, 1 +jp4f.de, 1 +jparts.su, 1 +jpbe-network.de, 1 +jpbe.de, 1 +jpcorriganlaw.com, 1 +jpcrochetapparel.com, 1 +jpdeharenne.be, 0 +jpdineroasi.com, 1 +jpeg.io, 1 +jpegshare.net, 1 +jperformance.nl, 1 +jpgangbang.com, 1 +jphost.ml, 1 +jpilan.com, 1 +jplennard.com, 1 +jpm-inc.jp, 1 +jpmelos.com, 1 +jpmelos.com.br, 1 +jpmguitarshop.com.br, 1 +jpn-ks.co.jp, 1 +jpod.cc, 1 +jpoirierlavoie.ca, 1 +jppcadvertising.com, 1 +jpph.org, 1 +jpralves.net, 1 +jproxx.com, 1 +jps-selection.co.uk, 1 +jps-selection.com, 1 +jps-selection.eu, 1 +jpshop.ru, 1 +jpsinflatables.co.uk, 1 +jpslconsulting.ca, 1 +jpst.it, 1 +jpvermogensregie.com, 1 +jqlin.com, 1 +jquery.wtf, 1 +jr5devdoug.xyz, 1 +jr5devdouglas.xyz, 1 +jr5proxdoug.xyz, 1 +jrabasco.me, 1 +jrc9.ca, 0 +jrchaseify.xyz, 1 +jreb.nl, 1 +jreiff.de, 1 +jreinert.com, 1 +jrflorian.com, 1 +jrfortune.com, 1 +jrjuristen.nl, 1 +jrlopezoficial.com, 1 +jrock.tk, 1 +jrock.us, 1 +jross.me, 1 +jrstehlik.com, 1 +jrstehlik.cz, 1 +jrt.ovh, 1 +jrtapsell.co.uk, 1 +jrucomsoc.tk, 1 +jrulka.ru, 1 +jrxpress.com, 1 +jrzhong.com, 1 +js-web.eu, 1 +js-webcoding.de, 1 +js0204.com, 1 +js5203344.com, 1 +js6868.cc, 1 +js86.de, 0 +js889.com, 1 +js93029.com, 1 +jsbentertainment.nl, 1 +jsbevents.nl, 1 +jsblights.nl, 1 +jsc.mx, 1 +jschumacher.info, 1 +jscsshtml.com, 1 +jsd-cog.org, 1 +jsdelivr.com, 1 +jsdelivr.net, 1 +jsdesign.mx, 1 +jselby.net, 1 +jsem.fun, 1 +jsfloydlaw.com, 1 +jsg.hk, 1 +jsh918.com, 1 +jsheekeyatlanticbar.co.uk, 1 +jsidefox.de, 1 +jsjfact.com, 1 +jsjohnsononline.com, 1 +jsjs.net, 1 +jsk26.ru, 1 +jskarzin.org, 0 +jskier.com, 0 +jsme.cz, 1 +jsme.fun, 1 +jsnfwlr.com, 1 +jsnfwlr.io, 1 +jsonsinc.com, 1 +jsphys.org.cn, 1 +jsproxy.tk, 0 +jss6868.cc, 1 +jsteward.moe, 1 +jstore.ch, 1 +jsvr.tk, 0 +jswc.de, 1 +jswebbdevelopment.com, 1 +jsxc.ch, 1 +jt-evolution.tk, 1 +jtbservice.se, 1 +jtcat.com, 1 +jtconsultancy.sg, 1 +jtg-inc.com, 1 +jtl-software.com, 1 +jtp.id, 1 +jtrocinski.com, 1 +jtrojanowska.pl, 1 +jts3servermod.com, 1 +jtslay.com, 1 +jttech.se, 1 +juabcounty.gov, 1 +jualjuel.com, 1 +juan23.edu.uy, 1 +juancarlosllaque.com, 1 +juancatalangomez.es, 1 +juanfrancisco.tech, 1 +juanhub.com, 1 +juanitia.com, 1 +juanjovega.com, 1 +juanmaguitar.com, 1 +juanmazzetti.com, 1 +juanmoreno.tk, 1 +juanrodriguezofficial.tk, 1 +juanxt.ddns.net, 1 +jub0bs.com, 1 +jubileum.online, 1 +jubileumfotograaf.nl, 1 +jubodarpan.in, 1 +jucca-nautica.si, 1 +juchheim-methode.de, 1 +juchit.at, 1 +jucktehkeinen.de, 1 +jucocauca.tk, 1 +judc-ge.ch, 1 +judge2020.com, 1 +judgefuszmediation.com, 1 +judgejonesadr.com, 1 +judo2point0.com, 1 +judoprodeti.cz, 1 +judosaintdenis.fr, 1 +judybai.me, 1 +juef.net, 1 +juef.space, 1 +juegosycodigos.mx, 1 +juegosyolimpicos.com, 1 +juek3y.com, 1 +juergen-elbert.de, 1 +juergenklieber.de, 1 +juergenspecht.com, 1 +juergenspecht.de, 1 +juergmeier.ch, 1 +juezz.top, 1 +jugendfeuerwehr-vechta.de, 1 +jugendhackt.org, 1 +jugendsuenden.info, 1 +juggo.me, 1 +jugh.de, 1 +juguetron.com.ec, 0 +jugwallonie.be, 1 +juhakoho.com, 1 +juhanihakala.fi, 1 +juice.codes, 1 +juk.life, 0 +jukkakivi.fi, 1 +jukkakivimaki.fi, 1 +jukovka.tk, 1 +juku-wing.jp, 1 +jule-spil.dk, 1 +julenetxaniz.eus, 1 +julenlanda.com, 0 +julesroovers.nl, 1 +julestern.com, 1 +julia-clarete.tk, 1 +julia-jones.org, 1 +julia-pink.org, 1 +julia.school, 1 +juliaknightly.com, 1 +julian-miller.de, 1 +julian-post.de, 1 +julian-uphoff.de, 1 +julian.tech, 1 +julianaedouglas.ga, 1 +julianbroadway.com, 1 +juliangonggrijp.com, 1 +juliangramajo.tk, 1 +julianickel.de, 1 +julianmeyer.de, 1 +juliannorton.com, 1 +julianporras.com, 1 +juliansimioni.com, 1 +julianskitchen.ch, 0 +julianvmodesto.com, 1 +julianwallmeroth.de, 1 +julianxhokaxhiu.com, 1 +juliaoantiguidades.com.br, 1 +juliawebber.co.za, 1 +juliazeengardendesign.co.uk, 1 +julibear.com, 1 +julibon.com, 1 +julie-and-stevens-wedding.com, 1 +juliebradford.co.uk, 1 +juliedecubber.com, 1 +juliekoubova.com, 1 +juliekoubova.cz, 1 +juliekoubova.name, 1 +juliekoubova.net, 1 +juliekproperties.com, 1 +juliekristin.com, 1 +juliemaurel.fr, 1 +julienc.io, 1 +juliendoco.com, 1 +julienpaterne.com, 0 +julienschmidt.com, 1 +julienstalder.ch, 0 +julientartarin.com, 1 +julienvenesson.fr, 1 +juliet-squad.tk, 1 +julietous.be, 1 +julietta-sanchez.org, 1 +julio.jamil.nom.br, 1 +juliohernandezgt.com, 1 +juliuseskola.org, 1 +julm.de, 1 +julmer.tk, 1 +juls.cloud, 0 +jult.net, 1 +jultube.de, 1 +jumardotaekwondo.tk, 1 +jumbo-air.de, 1 +jumbopan.net, 1 +jumeirashoes.com, 1 +jumelagevezin-vezins.tk, 1 +jumibow.com, 1 +jump-zone.co.uk, 1 +jump.wtf, 1 +jump4funinflatables.co.uk, 1 +jumpandbounce.co.uk, 1 +jumpandjivechildrensparties.co.uk, 1 +jumparoundbouncycastles.co.uk, 1 +jumparty.co.uk, 1 +jumpbuttonnorth.com, 1 +jumpeasy.com.au, 1 +jumperke.be, 1 +jumperoos.co.uk, 1 +jumpin-jax.co.uk, 1 +jumping4all.com, 1 +jumping4all.info, 1 +jumping4all.nl, 1 +jumpingcastlesonline.com.au, 1 +jumpingdeliege-vip.be, 1 +jumpingforall.com, 1 +jumpingforall.nl, 1 +jumpingjacksbouncycastles.co.uk, 1 +jumpinmonkeys.co.uk, 1 +jumpintogreenerpastures.com, 1 +jumpman-iphone-design.de, 1 +jumpnplay.co.uk, 1 +jumpnplay.com.au, 1 +jumprun.com, 1 +jun-e-jay.com, 1 +junbread.win, 1 +junctioncitywisconsin.gov, 1 +jundongwu.com, 1 +junethack.net, 1 +jungesforumkonstanz.de, 1 +junggesellmuc.de, 1 +jungidee.at, 1 +junglaurbana.tk, 1 +jungle-forums.tk, 1 +jungleadventuretours.net, 1 +jungleducks.ca, 0 +junglejackscastles.co.uk, 1 +junglememories.co.uk, 1 +junglevet.fr, 0 +jungleworks.com, 1 +junglist.org, 1 +jungschuetzen.tk, 1 +jungyonghwa.tk, 1 +junias-fenske.de, 1 +juniet.net, 1 +juniorchamber.international, 1 +juniorhandball.com, 1 +juniornasim.cf, 1 +juniorsambo.tk, 1 +juniorsbook.com, 1 +juniperroots.ca, 1 +junjie.pro, 1 +junjun-web.net, 1 +junkcarboys.ca, 1 +junkdrome.org, 1 +junkersparadise.tk, 1 +junkfoodcafe.com, 1 +junkiedownload.tk, 1 +juno.co.uk, 1 +junodownload.com, 1 +junomessenger.cf, 1 +junshinkai.ed.jp, 1 +junte.tk, 1 +juntosfmc.com.br, 1 +juozasveza.lt, 1 +jupiterchiropractic.com, 1 +juppy.tk, 1 +jura-reiseschutz.de, 1 +juraciimoveis.com.br, 1 +juragan.ga, 1 +juraganhp.com, 1 +jurancic.com, 1 +jurassicbarkharrogate.co.uk, 1 +jurassicworldfilmen.cf, 1 +juridischvertalers.nl, 1 +jurislex.tk, 1 +jurisprudentacedo.com, 1 +jurist.gq, 1 +juristech.io, 1 +juristique.fr, 1 +juristique.info, 1 +juristique.org, 1 +juristique.us, 1 +jurnalilmiah.com, 1 +jurojin.net, 1 +jurposluga.tk, 1 +jurquestion.tk, 1 +jurriaan.ninja, 1 +jusfitness.com.au, 1 +juspay.in, 1 +just-a-clanpage.de, 1 +just-bees.de, 1 +just-heberg.fr, 1 +just-keep-swimming.tk, 1 +just-muh.de, 1 +just-pools.co.za, 1 +just-vet-and-drive.fr, 1 +just-webdesign-berlin.de, 1 +just2trade.com, 1 +just3preety.com, 1 +just6f.com, 1 +justacoupleofclarkes.co.uk, 1 +justalilhippie.com, 1 +justanothercompany.name, 1 +justanotherday.tk, 1 +justbelieverecoverypa.com, 1 +justbookexcursions.com, 1 +justbooktransfers.com, 1 +justboom.co, 1 +justcalm.tk, 1 +justchunks.net, 1 +justeducationonline.com, 1 +justfoodfordogs.com, 1 +justforschools.co.uk, 1 +justforsunn.com, 1 +justfresh.com, 1 +justgalak.com, 1 +justgalak.org, 1 +justgamblers.com, 1 +justice.gov, 1 +justice4assange.com, 1 +justiceforjameela.org, 1 +justin-p.me, 1 +justin-tech.com, 1 +justin3d.nl, 1 +justinellingwood.com, 1 +justinfreid.com, 1 +justinharrison.ca, 1 +justinho.com, 1 +justinmanders.nl, 1 +justinsinkula.com, 1 +justinstago.com, 1 +justinstandring.com, 1 +justknigi.gq, 1 +justmade.com.br, 1 +justmensgloves.com, 1 +justmote.me, 1 +justmysocks.xyz, 1 +justmysocks8.com, 1 +justnajoua.tk, 1 +justnaw.co.uk, 1 +justninja.com, 1 +justnu.se, 0 +justor.ru, 1 +justpaste.it, 1 +justpdf.cf, 1 +justpractice.ca, 1 +justquoteme.ga, 1 +justrighthsc.com, 1 +justsellmycar.com, 1 +justsome.info, 1 +justtalk.site, 1 +justthinktwice.gov, 0 +justupdate.me, 1 +justyardsign.com, 1 +justyy.com, 1 +justzz.xyz, 1 +juszczak.io, 1 +juszkiewicz.com.pl, 1 +jutella.de, 0 +jutlander-netbank.dk, 1 +jutlander.dk, 1 +juul.xyz, 0 +juusujanar.eu, 0 +juvenile-studios.de, 1 +juventusmania1897.com, 1 +juweldot.tk, 1 +juwelierstoopman.nl, 1 +juweliervanwillegen.nl, 1 +jvanerp.nl, 1 +jvbouncycastlehire.co.uk, 1 +jvdham.nl, 1 +jvdz.nl, 1 +jvega.me, 1 +jvianes.ddns.net, 1 +jvlandscapingservices.com, 1 +jvlfinance.cz, 1 +jvn.com, 1 +jvphotoboothhire.co.uk, 1 +jvrproductions.com, 1 +jvsticker.com, 1 +jvwdev.nl, 1 +jw.fail, 1 +jw1.ca, 1 +jw66.cc, 1 +jw77.cc, 1 +jwala.diamonds, 1 +jwatt.org, 1 +jwatt.uk, 1 +jwbworks.dk, 1 +jwchords.org, 1 +jwe.nl, 1 +jwhite.network, 1 +jwilsson.com, 0 +jwjwjw.com, 1 +jwmmarketing.com, 1 +jwod.gov, 1 +jwolt-lx.com, 1 +jwplay.ml, 1 +jwpoore.com, 1 +jwr.me, 1 +jwschuepfheim.ch, 1 +jwz.org, 1 +jxcad.com.cn, 1 +jxdsp.com, 1 +jxir.de, 1 +jxltom.com, 1 +jxm.in, 1 +jxs.ch, 1 +jy11.de, 1 +jybrid.com, 1 +jydemarked.dk, 1 +jyk.me, 1 +jyllandsakvariet.dk, 1 +jyoba.co.jp, 1 +jyoti-fairworks.org, 1 +jyrilaitinen.fi, 1 +jyvaskylantykkimies.fi, 1 +jzbk.org, 0 +jzcapital.co, 1 +jzeb.co, 1 +jzgj088.com, 1 +jztkft.hu, 1 +jzwebdesign.ie, 1 +k-bone.com, 1 +k-homes.net, 1 +k-jtan.ca, 1 +k-labs.be, 1 +k-linkcarecenter.com, 1 +k-matsudaclinic.com, 1 +k-netz.de, 1 +k-pan.com, 1 +k-plant.com, 1 +k-pture.com, 0 +k-sails.com, 1 +k-scr.me, 1 +k-system.de, 1 +k.tt, 1 +k0.gg, 1 +k0hs.com, 1 +k1024.org, 1 +k123123.com, 1 +k1chn.com, 1 +k1yoshi.com, 0 +k234234.com, 1 +k258059.net, 1 +k2mts.org, 1 +k30365.com, 1 +k3508.com, 1 +k36533.com, 1 +k38.cc, 1 +k3nny.fr, 1 +k3t.net, 1 +k4law.com, 1 +k4r.ru, 1 +k51365.com, 1 +k5197.co, 1 +k55655.com, 1 +k60d.com, 1 +k66.ag, 1 +k665.vip, 1 +k666.ag, 1 +k6666.ag, 1 +k6729.co, 1 +k6729.com, 1 +k6957.co, 1 +k6957.com, 1 +k7azx.com, 1 +k8.com, 1 +k801.com, 1 +k805.com, 1 +k805.net, 1 +k80608.com, 1 +k8079.com, 1 +k8082.com, 1 +k811.com, 1 +k8111.com, 1 +k81111.com, 1 +k811111.com, 1 +k81365.com, 1 +k8158.com, 1 +k816.com, 1 +k82.org, 1 +k821.net, 1 +k82222.com, 1 +k82222.net, 1 +k82365.com, 1 +k8268.com, 1 +k8268.net, 1 +k829.com, 1 +k83333.com, 1 +k8368.com, 1 +k8368.net, 1 +k846.com, 1 +k85.app, 1 +k8533.com, 1 +k86.app, 1 +k865.net, 1 +k86666.com, 1 +k8668.net, 1 +k86681.com, 1 +k86690.com, 1 +k86813.com, 1 +k86814.com, 1 +k86830.com, 1 +k86833.com, 1 +k86834.com, 1 +k86853.com, 1 +k86855.com, 1 +k86869.com, 1 +k869.co, 1 +k86918.com, 1 +k86921.com, 1 +k86929.com, 1 +k86930.com, 1 +k86966.com, 1 +k86967.com, 1 +k86990.com, 1 +k86991.com, 1 +k87.app, 1 +k87021.com, 1 +k87073.com, 1 +k87100.com, 1 +k87120.com, 1 +k87178.com, 1 +k87210.com, 1 +k873.co, 1 +k873.com, 1 +k875.co, 1 +k87777.com, 1 +k88107.com, 1 +k88110.com, 1 +k88116.com, 1 +k88127.com, 1 +k88133.com, 1 +k88172.com, 1 +k88258.com, 1 +k88269.com, 1 +k88302.com, 1 +k88306.com, 1 +k88312.com, 1 +k88313.com, 1 +k88327.com, 1 +k8861.com, 1 +k88652.com, 1 +k88670.com, 1 +k88671.com, 1 +k88672.com, 1 +k88870.com, 1 +k8892.com, 1 +k89.app, 1 +k89188.com, 1 +k8994.com, 1 +k89999.com, 1 +k8dalao.com, 1 +k8dc13.com, 1 +k8dc17.com, 1 +k8didi.com, 1 +k8gege.com, 1 +k8jiejie.com, 1 +k8laosiji.com, 1 +k8meimei.com, 1 +k8meinv.com, 1 +k8n.de, 1 +k8r.eu, 1 +k8slot.com, 1 +k8v02.com, 1 +k8v03.com, 1 +k8v08.com, 1 +k8v21.com, 1 +k8v27.com, 1 +k8v30.com, 1 +k9297.co, 1 +k9728.co, 1 +k9base.com, 1 +k9lady.ml, 1 +k9life.cf, 1 +k9swx.com, 1 +ka4ka-ru.tk, 1 +ka4ka.cf, 1 +kaagsebc.nl, 1 +kaamoscreations.com, 1 +kaaniche.xyz, 1 +kaany.io, 1 +kaas.wtf, 1 +kaasbesteld.nl, 1 +kaatha-kamrater.se, 1 +kaatsen.tk, 1 +kab-s.de, 1 +kabachok.tk, 1 +kabal-invasion.com, 1 +kabal.tk, 1 +kabardinka.ga, 1 +kabardino-balkariya.ml, 1 +kabarlinux.id, 1 +kabartani.com, 1 +kabat-fans.cz, 1 +kabataanpartylist.com.ph, 1 +kabbac.com, 1 +kabel.cf, 1 +kabel.ml, 1 +kabellegger.nl, 1 +kabeltv.co.nz, 1 +kabeuchi.com, 1 +kabinett.cz, 1 +kabinettindia.in, 1 +kabluchek.tk, 1 +kabluchok.tk, 1 +kabodo.com, 1 +kabos.art, 1 +kabu-abc.com, 1 +kabuki-inc.co.jp, 1 +kabukpsikoloji.com, 1 +kabulpress.org, 1 +kabus.org, 1 +kacgal.com, 1 +kachaem-knigi.gq, 1 +kachelfm.nl, 1 +kachka.cf, 1 +kachlikova2.cz, 1 +kack.website, 1 +kacperchmielowiec.pl, 1 +kadenba.ch, 1 +kadeshfoundation.org, 1 +kadet.net.ru, 1 +kadett-c-club-limburg.tk, 1 +kadhal-kirukkan.tk, 1 +kadhambam.in, 1 +kado-ya.jp, 1 +kadolis.com, 1 +kadro.com.pl, 1 +kadvi.tk, 1 +kadykchanskiy.ml, 1 +kaeme.com, 1 +kaeptns-sechser.de, 1 +kaesehagen.nl, 1 +kafeh-jazan.com, 1 +kafel-ufa.tk, 1 +kaffad.site, 1 +kaffeepflanze-pflege.de, 1 +kaffeeringe.de, 1 +kaffeesud.org, 1 +kaffeklubben.tk, 1 +kafoom.de, 1 +kagawa-net.org, 1 +kagelmacher.ch, 1 +kaggle.com, 1 +kagicomb.org, 1 +kagitreklam.com, 1 +kagomesashi.tk, 1 +kagucho.net, 1 +kagutech.com, 1 +kahane.org, 1 +kahootkings.works, 1 +kai-ratzeburg.de, 1 +kai-ruecker.tk, 1 +kai.cool, 0 +kaibinyang.com, 1 +kaibo.cz, 1 +kaibo.eu, 1 +kaibol.com, 1 +kaidoblogi.eu, 1 +kaifa199.com, 1 +kaigojj.com, 1 +kaijo-physics-club.work, 1 +kaik.io, 1 +kaika-facilitymanagement.de, 1 +kaikei7.com, 1 +kaileymslusser.com, 1 +kaimi.io, 1 +kainetsoft.com, 1 +kainsanders.com, 1 +kainz.be, 1 +kaioken.bar, 1 +kairion.de, 0 +kais08.com, 1 +kaiseraerospace.tk, 1 +kaisev.net, 1 +kaishi009.com, 1 +kaishi05.com, 1 +kaishi06.com, 1 +kaishi22.com, 1 +kaishi55.com, 1 +kaishi555.com, 1 +kaishi77.com, 1 +kaisto.net, 1 +kaitol.click, 1 +kaitori-goods.shop, 1 +kaiusaltd.com, 0 +kaiva.cl, 1 +kaiwu.xyz, 1 +kaizencraft.ga, 1 +kaizenreporting.com, 1 +kaizeronion.com, 1 +kaizoku-dmc.com, 1 +kajak.land, 1 +kajakswaderki.pl, 1 +kajamaakool.ee, 1 +kajirakuda.com, 1 +kajlovo.cz, 1 +kak-pishetsa.ru, 1 +kak-pohudet-legko.ml, 1 +kak-prygotovyt.ru, 1 +kak-sarabotatj.ru, 1 +kak-sdelatj.ru, 1 +kaka.farm, 1 +kakabo.vn, 1 +kakacon.nz, 1 +kakao-karten.de, 1 +kakaravaara.fi, 1 +kakazai.com, 1 +kakdolgonline.cf, 1 +kaketang.com, 1 +kakie-kolesa.ru, 1 +kakofotmitzaim.cf, 1 +kakofotmitzaim.ga, 1 +kakofotmitzaim.gq, 1 +kakofotmitzaim.ml, 1 +kakofotmitzaim.tk, 1 +kakolightingmuseum.or.jp, 1 +kakoo-media.nl, 1 +kakoomedia.nl, 1 +kakpoluchitzaim.cf, 1 +kakpoluchitzaim.ga, 1 +kakpoluchitzaim.gq, 1 +kakpoluchitzaim.ml, 1 +kakpoluchitzaim.tk, 1 +kaktus-tour.cf, 1 +kaktuskola.se, 1 +kakvzyatdolg.ga, 1 +kakvzyatdolg.ml, 1 +kakvzyatzaim.cf, 1 +kakvzyatzaim.gq, 1 +kakvzyatzaim.tk, 1 +kaladarb.com, 1 +kalafard.com, 1 +kalakarclub.com, 1 +kalambur.gq, 1 +kalambur.ml, 1 +kalamos-psychiatrie.be, 1 +kalamos.tk, 1 +kalapatec.id, 1 +kalashcards.com, 1 +kalashnikov.ml, 1 +kalaskvintetten.tk, 1 +kalastus.com, 1 +kaleidomarketing.com, 0 +kaleidoscope.co.uk, 1 +kalek.eu, 1 +kalendarabiturienta.tk, 1 +kalender.com, 1 +kalender.goip.de, 1 +kalevlamps.co.uk, 1 +kalex.nl, 1 +kaleylocks.com, 1 +kalhufvudet.se, 1 +kali.training, 1 +kaliaa.fi, 1 +kalian.cz, 1 +kaliboairport.tk, 1 +kaliforniya.tk, 1 +kalilinux.tech, 1 +kalina.ml, 1 +kaliningrad.gq, 1 +kaliningrad.ml, 1 +kalinka-shop.tk, 1 +kaliocommerce.com, 1 +kalisch.eu, 1 +kalk-shop.nl, 1 +kalkulacka-havarijni.cz, 1 +kalleanka.tk, 1 +kalligo.ga, 1 +kallisto.io, 1 +kalmar.com, 1 +kalmykia.cf, 1 +kalmykia.tk, 1 +kalmykphilly.org, 1 +kaloix.de, 1 +kalolina.com, 1 +kalombo.ru, 1 +kaloni.info, 1 +kalpavriksh.org, 1 +kalprajsolutions.com, 1 +kalsa.ga, 1 +kalsbouncies.com, 1 +kaltenbrunner.it, 1 +kalterersee.ch, 1 +kaltoft.net, 1 +kaluga.cf, 1 +kaluga.gq, 1 +kalugadeti.ru, 1 +kalugin.tk, 1 +kalwak.cr, 1 +kalwestelectric.com, 1 +kalyazin-online.tk, 1 +kam-serwis.pl, 1 +kamalame.co, 1 +kamandula.tk, 1 +kamareddine.tk, 1 +kamasutra-training.gq, 1 +kamata-saisyuusyou.com, 1 +kamata-shinkyu-seikotsu.jp, 1 +kambistories.com, 1 +kamchatkatravel.tk, 1 +kamchatkawinter.tk, 1 +kameari-za.space, 1 +kameliya.tk, 1 +kamen-master.ru, 1 +kamennyj-pisatel.tk, 1 +kameno-news.tk, 1 +kamery.top, 1 +kamikaichimaru.com, 0 +kamikatse.net, 1 +kamildrozd.tk, 1 +kamilla.ml, 1 +kamilmagdziak.pl, 1 +kamin-island.ru, 1 +kaminastudios.com, 1 +kaminbau-laub.de, 1 +kaminoke.info, 1 +kaminoweb.com, 1 +kaminy-msk.ru, 1 +kamisato-ent.com, 1 +kamitech.ch, 1 +kamixa.se, 1 +kamiyo.tk, 1 +kamnob.com, 1 +kamp-kisten.nl, 1 +kampffische.tk, 1 +kamppailusali.fi, 1 +kampunginggris-ue.com, 1 +kamranmirhazar.com, 1 +kamui.co.uk, 1 +kamuniang.org, 1 +kan-ken.fr, 1 +kan3.de, 1 +kana-mono.biz, 1 +kana.me, 1 +kanaete-uranai.com, 1 +kanag.pl, 1 +kanal-schaefer.de, 1 +kanal-tv-haensch.de, 1 +kanapa.gq, 1 +kanar.nl, 1 +kanatsuki.tk, 1 +kancolle.me, 1 +kanctovary.tk, 1 +kandalife.com, 1 +kandelaberi.tk, 1 +kandhamal.org, 1 +kandianshang.com, 1 +kandofu.com, 1 +kandra.com.br, 1 +kandrahechiceravudu.com, 1 +kandwliquor.com, 1 +kanecastles.com, 1 +kanehusky.com, 0 +kanetix.ca, 1 +kanganer.com, 1 +kangaroo-bouncycastle.co.uk, 1 +kangarooislandholidayaccommodation.com.au, 1 +kangaroojacks.co.uk, 1 +kangaroos.org, 1 +kangaroovalleykayaks.com.au, 1 +kangaroovalleymuseum.com, 1 +kangaroovalleyshow.org.au, 1 +kangaroovalleywoodcrafts.com.au, 1 +kangkai.me, 1 +kangkang.net, 1 +kangkang.org, 1 +kangoeroeteam.tk, 1 +kangzaber.com, 1 +kanis.ag, 1 +kanis.me, 1 +kanitha.sk, 1 +kanker.nl, 1 +kankerpannekoek.nl, 1 +kankimaru.com, 1 +kanna.cf, 1 +kannchen.de, 1 +kano.tk, 1 +kanobu.ru, 1 +kanootours.com, 1 +kanotijd.nl, 1 +kanoumokuzai.co.jp, 1 +kanpian369.com, 1 +kanshutan.com, 1 +kantankye.nl, 1 +kantanmt.com, 1 +kantorad.io, 1 +kantorosobisty.pl, 1 +kantube.tk, 1 +kanuvu.de, 1 +kanzashi.com, 1 +kanzlei-gaengler.de, 1 +kanzlei-hhh.de, 1 +kanzlei-oehler.com, 1 +kanzlei-sixt.de, 1 +kanzshop.com, 1 +kaofw.org, 1 +kap-genial.de, 1 +kap-kirche.de, 1 +kap.pe, 1 +kapanlagi.gq, 1 +kapelya.gq, 1 +kapilarya.com, 1 +kapiorr.duckdns.org, 1 +kapital-kredit.cf, 1 +kapitalsprung.com, 1 +kapitany.tk, 1 +kapiteintje.tk, 1 +kaplan.se, 1 +kaplanco.com, 1 +kapler.family, 0 +kapparhokappa.tk, 1 +kappawingman.com, 1 +kappenstein.org, 0 +kappershuis-meppel.nl, 1 +kappharn.com, 1 +kappit.dk, 1 +kapri.dn.ua, 1 +kapsalondigo.nl, 1 +kapsalonlinds.nl, 1 +kapseli.net, 1 +kaptadata.com, 1 +kapulakennel.tk, 1 +kapusta.if.ua, 1 +kaputt.com, 0 +kaputtendorf.tk, 1 +kaputtzich.duckdns.org, 1 +kara-fabian.com, 1 +kara-fabian.de, 1 +karabah.cf, 1 +karabah.tk, 1 +karabas.com, 1 +karabijnhaken.nl, 0 +karabukhaber.tk, 1 +karachay.tk, 1 +karachi.dating, 1 +karalane.com, 1 +karamomo.net, 1 +karanastic.com, 0 +karand.me, 1 +karanjthakkar.com, 1 +karanlyons.com, 1 +karantholdings.ga, 1 +karantyn.pro, 1 +karaoglanis.tk, 1 +karaokerentalcalgary.com, 1 +karaokerentaledmonton.com, 1 +karaokerentalmontreal.com, 1 +karaokerentalottawa.com, 1 +karaokerentaltoronto.com, 1 +karapuzz.tk, 1 +karasevm.ru, 1 +karasik.by, 1 +karateka.org, 1 +karateka.ru, 1 +karatekit.co.uk, 1 +karatepunkslaroca.tk, 1 +karatesamurai.tk, 1 +karawane.tk, 1 +karbox.de, 1 +kardize24.pl, 1 +kardjali.bg, 1 +kareenaworld.tk, 1 +karel-dingeldey.de, 1 +karel-it.be, 1 +karelia.cf, 1 +karelia.ga, 1 +karelia.ml, 1 +karelin.tk, 1 +kareltrans.tk, 1 +karelvanhecke.com, 1 +karen-homestay.tk, 1 +karencatering.com, 1 +karenerdos.com.au, 1 +karenvien.ga, 1 +karewan.ovh, 1 +kargas.cf, 1 +karger.com, 1 +kargl.net, 1 +kargosuben.com, 1 +karguine.in, 1 +karhukamera.com, 1 +karichan.com, 1 +karimova.tk, 1 +karimsaadati.tk, 1 +karimunsejahtera.com, 1 +karina.gd, 1 +karinahh.net, 1 +karinov.co.id, 1 +karinwerner.com, 1 +karit.nz, 1 +karlbowden.com, 1 +karlbrandesmediation.com, 1 +karlic.net, 1 +karlin.run, 1 +karlis-kavacis.id.lv, 1 +karlloch.de, 1 +karloskontana.tk, 1 +karlov.tk, 1 +karlproctor.co.uk, 1 +karlskronajk.tk, 1 +karlsmithmn.org, 1 +karlson.gq, 1 +karlzotter.com, 1 +karmaassurance.ca, 1 +karmaflux.com, 1 +karmaful.de, 1 +karmainsurance.ca, 1 +karmalighting.com, 1 +karmaspa.se, 1 +karmatrend.cf, 1 +karmelava.tk, 1 +karn.nu, 1 +karnage.eu, 1 +karneid.info, 1 +karniz.ml, 1 +karo.pc.pl, 1 +karodos.pl, 1 +karolak.fr, 0 +karolaschinkel.de, 1 +karolinacwik.com, 1 +karopapier.de, 1 +karopc.pl, 1 +karoverwaltung.de, 1 +karpanhellas.com, 0 +karpat.space, 1 +karperpagina.tk, 1 +karpets.gq, 1 +karpo.tk, 1 +karr.ga, 1 +karramba.tk, 1 +karriharju.tk, 1 +karrot.world, 1 +karsofsystems.com, 1 +karsten-voigt.de, 1 +karstjewellery.co.uk, 1 +karstransport.tk, 1 +karta-baikala.ml, 1 +karta-paliwowa.pl, 1 +kartacha.com, 1 +kartatopia.com, 1 +kartbird.com, 1 +kartec.com, 1 +karten-verlag.de, 1 +kartenmarie.de, 1 +kartenplanet.ch, 1 +kartikmohta.com, 1 +karting-normandie.fr, 1 +kartoffel-stampfer.com, 1 +kartoffel-tobi.de, 1 +kartonki.tk, 1 +kartonmodellbau.org, 1 +kartpay.com, 1 +kartpower.tk, 1 +karty.in, 1 +karula.org, 1 +karuneshjohri.com, 1 +karupp-did.net, 1 +kas.ie, 1 +kasasaprotect.com, 1 +kasaysayan.tk, 1 +kaseban.com, 1 +kasei.im, 1 +kasemsantaec.com, 0 +kasettilamerit.fi, 1 +kashadriskill.com, 0 +kashbet.com, 1 +kashbet.net, 1 +kashflowcoupon.co.uk, 1 +kashflowpromocode.co.uk, 1 +kashifshah.tk, 1 +kashinavi.com, 1 +kashis.com.au, 1 +kashousing.tk, 1 +kashrutbaking.com, 1 +kashsports.com, 1 +kasiafricagroup.org, 1 +kasinobonus.com, 1 +kasis.nl, 1 +kasko.io, 1 +kaskocdn.com, 1 +kaskocloud.com, 1 +kaskodev.com, 1 +kaskojs.com, 1 +kaskoqa.com, 1 +kasparovru.tk, 1 +kasper-team.tk, 1 +kasperstad.dk, 1 +kassa.com, 1 +kassa.expert, 1 +kassa.fr, 1 +kastankaoffice.cz, 1 +kastelruth.biz, 1 +kastemperaturen.ga, 1 +kastgroup.com, 1 +kastorsky.ru, 0 +kasual.id, 1 +kasvall.com, 1 +kat.marketing, 1 +kat4at.tk, 1 +kataiszilveszter.hu, 1 +katalog-parfyum.tk, 1 +katalog-serverov.ga, 1 +katalog-tovarov.tk, 1 +katalogbajugamismu.com, 1 +katalogbutikker.dk, 1 +katalogharga.cf, 1 +katalogkapsli.pl, 1 +katan-stroi.tk, 1 +katapult-impuls.com, 1 +katapult.es, 1 +katapult.tk, 1 +katarinasalonzapse.com, 1 +katarsisuib.no, 1 +katazuketai.net, 1 +kate-beckinsale.tk, 1 +katedra.de, 1 +kateduggan.net, 1 +katekligys.com, 1 +katemihalikova.cz, 1 +katenka.tk, 1 +katericke.com, 1 +katerinastudio.com, 1 +katerman.ga, 1 +kateryan.tk, 1 +kateryantv.tk, 1 +katewrightmba.com, 1 +katex.org, 1 +kateysagal.tk, 1 +kathakkachakkar.com, 1 +kathardt.de, 1 +katherineswynford.tk, 1 +kathleendeisher.com, 1 +kathmandupost.com, 1 +kathrin-maren-enders.de, 1 +kathrynbernardo.tk, 1 +kathy.best, 1 +kathy.lgbt, 1 +kathy.link, 1 +kathyforer.com, 1 +kati-raumplaner.de, 1 +kati0.com, 1 +katiebenson.tk, 1 +katiechai.xyz, 1 +katiegunnell.com, 1 +katieriker.com, 1 +katieskandy.co.uk, 1 +katieskastles.co.uk, 1 +katio.net, 1 +kativa.it, 1 +katja-bjoern.de, 1 +katja-nikolic-design.de, 1 +katka.info, 1 +katnunn.co.uk, 1 +kato-yane.com, 1 +katoikos.world, 1 +katom.com, 1 +katrelleonline.tk, 1 +katrinasevilla.com, 1 +katrinjanke.de, 0 +katscastles.co.uk, 1 +katsiavarasorthopedics.gr, 1 +katsunet.com, 1 +kattelans.eu, 1 +katushka.cf, 1 +katushka.ga, 1 +katycomputer.com, 1 +katyl.info, 0 +katyusha.net, 1 +katzei.fr, 1 +katzenbrunnen-test.de, 1 +katzensklave.me, 1 +katzrkool.xyz, 1 +kau-boys.com, 1 +kau-boys.de, 1 +kaufberatung.community, 1 +kaufkraftkiel.de, 1 +kauperwood.ovh, 1 +kausta.me, 1 +kaustubhalandkar.com, 1 +kavalasite.gr, 1 +kavatasygarety.tk, 1 +kaverti.com, 1 +kavik.no, 1 +kavin.rocks, 1 +kavithai.tk, 1 +kavkaz-info.tk, 1 +kavkaz.cf, 1 +kavovary-kava.cz, 1 +kawabeest.tk, 1 +kawaii-dollies.tk, 1 +kawaii.su, 1 +kawaiicon.org, 1 +kawaiii.link, 1 +kawaiiku.com, 1 +kawaiiku.de, 1 +kawamura-inc.jp, 1 +kawuk.com, 1 +kay.la, 1 +kay.moe, 1 +kayakcastro.tk, 1 +kayakpolouniversidades.tk, 1 +kayant-server.space, 1 +kaydan.io, 1 +kayelise.com, 1 +kayit.co.uk, 1 +kayleen.net, 1 +kaylyn.ink, 0 +kayo.digital, 1 +kayon.cf, 1 +kaypasocks.com, 1 +kayscs.com, 1 +kaysis.gov.tr, 1 +kaysvillechurch.com, 1 +kazakov.lt, 1 +kazan-tury.ml, 1 +kazanasolutions.de, 1 +kazancci.com, 1 +kazand.lt, 1 +kazandaemon.ru, 1 +kazangoforums.tk, 1 +kazanusadba.cf, 1 +kazard.co.za, 1 +kazek.com.pl, 1 +kazekprzewozy.pl, 1 +kazino5.tk, 1 +kaznur.tk, 1 +kaztest.tk, 1 +kazu.click, 1 +kazumi-clinic.com, 1 +kazumi.ooo, 1 +kazumi.ro, 1 +kazvel.com, 1 +kazwolfe.io, 1 +kazy111.info, 1 +kb059.com, 1 +kb0606.com, 1 +kb0707.com, 1 +kb096.com, 1 +kb10uy.org, 1 +kb1313.com, 1 +kb1515.com, 1 +kb2121.com, 1 +kb2626.com, 1 +kb283.com, 1 +kb3232.com, 1 +kb35.net, 1 +kb3535.com, 1 +kb3636.com, 1 +kb38.net, 1 +kb4393.com, 1 +kb481.com, 1 +kb486.com, 1 +kb5050.com, 1 +kb5151.com, 1 +kb5757.com, 1 +kb5959.com, 1 +kb65.net, 1 +kb7070.com, 1 +kb7272.com, 1 +kb750.com, 1 +kb82.net, 1 +kb8383.com, 1 +kb8484.com, 1 +kb8585.com, 1 +kb86.net, 1 +kb88.com, 1 +kb886119.com, 1 +kb88818.com, 1 +kb8885.com, 1 +kb88dc05.com, 1 +kb88dc12.com, 1 +kb88dc15.com, 1 +kb88dc16.com, 1 +kb88dc17.com, 1 +kb88dc26.com, 1 +kb88md14.com, 1 +kb88md27.com, 1 +kb9191.com, 1 +kb930.com, 1 +kb957.com, 1 +kb9797.com, 1 +kb9988.com, 1 +kba-online.de, 1 +kbb-ev.de, 1 +kbbouncycastlehire.co.uk, 1 +kbc.be, 1 +kbcequitas.hu, 1 +kbcso.com, 1 +kbit.dk, 1 +kbjorklu.com, 1 +kbk4t.com, 1 +kbleventhire.co.uk, 1 +kbsinflatablekingdom.co.uk, 1 +kbst.se, 1 +kbterapicenter.se, 1 +kbz.fr, 1 +kc-holzfaeller.de, 1 +kc1hbk.com, 1 +kc3.moe, 1 +kc5mpk.com, 1 +kcal4you.se, 1 +kcam91.com, 1 +kccargo.us, 1 +kcire.me, 1 +kcliner.com, 1 +kcmicapital.com, 1 +kcpromi.sk, 1 +kcptun.com, 1 +kcsh.men, 1 +kcshipping.co.uk, 1 +kcsonline.biz, 1 +kcsordparticipation.org, 1 +kcsprayfoam.com, 1 +kd.net.nz, 1 +kdcinfo.com, 1 +kdcp.pw, 1 +kdex.de, 1 +kdistech.nz, 1 +kdramaholic.com, 1 +kdw.cloud, 1 +ke.fo, 1 +ke7tlf.us, 1 +keakon.net, 1 +keane.space, 1 +keaneokelley.com, 1 +kearney.io, 1 +kearnsmotorcar.com, 1 +keaysmillwork.com, 1 +keb.com.au, 1 +keb.net.au, 1 +kebabbesteld.nl, 1 +kebabbruce.com, 0 +kebhanamyanmar.com, 1 +kebidanan.id, 1 +kebo.xyz, 1 +kecht.at, 1 +kedarastudios.com, 1 +kedero.com, 1 +kedi.tk, 1 +kediri.win, 1 +keditor.biz, 1 +kedv.es, 1 +kee.fi, 1 +kee.pm, 1 +keechain.io, 1 +keeckee.ml, 1 +keekmix.nl, 1 +keeley.net, 1 +keeleysam.com, 1 +keelove.net, 1 +keemail.me, 1 +keematdekho.com, 1 +keen.media, 1 +keengamer.com, 1 +keep.id, 1 +keepa.com, 1 +keeperapp.com, 1 +keeperklan.com, 0 +keepersecurity.com, 1 +keepingitheel.com, 1 +keepingitsimpleblog.com, 1 +keepingtheplot.co.uk, 1 +keepiteasy.eu, 1 +keepitsecure24.com, 1 +keepitsimplebitcoin.com, 1 +keepitweedy.com, 1 +keepleft.gr, 1 +keepmesafe.xyz, 1 +keepsight.org.au, 1 +keepwatchprayer.org, 1 +keesmartens.tk, 1 +keesslop.nl, 1 +keestalkstech.com, 1 +keevault.pm, 1 +keeweb.info, 1 +keez.cf, 1 +keezin.ga, 1 +kefu.chat, 1 +kegan.lol, 1 +keganthorrez.com, 1 +kegelschiene.net, 1 +kehlenbach.net, 1 +keian.tk, 1 +keifel.de, 1 +keilycosmetics.com, 1 +kein-design.de, 1 +kein-fidget-spinner-werden.de, 1 +kein-vergessen.tk, 1 +keinanung.nl, 1 +keinefilterblase.de, 1 +keinnerd.net, 1 +keiralewis.co.uk, 1 +keisaku.org, 1 +keisepulveda.com, 1 +keishiando.com, 1 +keisinger.name, 1 +keith.pro, 1 +keithazzopardi.tk, 1 +keithcwood.com, 1 +keithlomax.com, 1 +keithwillcock.com, 1 +keithws.net, 1 +kejadiananeh.com, 1 +kejar.id, 0 +kejpop.pl, 1 +kekarimi.com, 1 +keke-shop.ch, 1 +keke125.idv.tw, 1 +kekku.li, 1 +keksi.io, 1 +kekz.org, 1 +kela.jp, 1 +kelamanproduction.tk, 1 +kelantan.tk, 1 +kelantanmudah.com, 0 +kelastrade.co, 1 +kelax.tk, 1 +keldan.fo, 1 +kelder.tk, 1 +kelgtermans-usedcars.be, 0 +kelheor.space, 1 +kelinda.tk, 1 +kelis.fr, 1 +keller-aarau.ch, 1 +keller-sports.at, 1 +keller-sports.be, 1 +keller-sports.ch, 1 +keller-sports.co.uk, 1 +keller-sports.com, 1 +keller-sports.de, 1 +keller-sports.dk, 1 +keller-sports.es, 1 +keller-sports.fr, 1 +keller-sports.it, 1 +keller-sports.nl, 1 +keller-sports.se, 1 +keller-x.at, 1 +keller-x.ch, 1 +keller-x.com, 1 +keller-x.de, 1 +keller-x.fr, 1 +keller-x.nl, 1 +keller-x.se, 1 +kellerer-ziegel.de, 1 +kellerlan.org, 0 +kelleycurran.com, 1 +kelleylatino.tk, 1 +kelleymcchesney.us, 1 +kellimacconnell.com, 1 +kellyandantony.com, 1 +kellygrenard.com, 1 +kellyskastles.co.uk, 1 +kellyssportsbarandgrill.com, 1 +kellyvoice.tk, 1 +kelm.me, 1 +kelmarsafety.com, 1 +kelsa.io, 0 +kelsall39.com, 1 +kelvinchung.tk, 1 +kelvinfichter.com, 0 +kemerovo.gq, 1 +kemerovo.ml, 1 +kemerovo.tk, 1 +kemerovo42.tk, 1 +kemoiptv.com, 0 +kempkens.io, 1 +kemptechnologies.com, 1 +kemptown.co.uk, 1 +kemptown.com, 1 +kemptown.net, 1 +kemsa.ga, 1 +kemsamnhatban.ml, 1 +ken-electric.com.br, 1 +ken.fm, 1 +kenalsworld.com, 1 +kenbillionsyuan.tk, 1 +kenbonny.net, 1 +kendermore.it, 1 +kendernet.com, 1 +kendle.tk, 1 +kendrick.tk, 1 +kendu.si, 0 +kengilmour.com, 0 +kenia-vakantie.nl, 1 +keniasfamilychildcare.com, 1 +keniff.gq, 1 +kenkou-kitakyusyu.jp, 1 +kennedy.cf, 1 +kennedy.ie, 1 +kennedy.ml, 1 +kennedyinsurancesolutions.com, 1 +kenners.org, 0 +kennethaasan.no, 1 +kennethandersen.com, 1 +kennethlim.me, 1 +kenneths.org, 1 +kennethsentillas.com, 1 +kennewell.tk, 1 +kenny-peck.com, 1 +kennynet.co.uk, 1 +kennyparsons.com, 1 +keno.im, 1 +kenokallinger.at, 1 +kenoschwalb.com, 1 +kenpobolivia.tk, 1 +kenpotalca.tk, 1 +kens.pics, 1 +kensbouncycastles.co.uk, 1 +kenscustomfloors.com, 1 +kensparkesphotography.com, 1 +kentdalevets.co.uk, 1 +kentec.net, 0 +kenterlis.gr, 1 +kentuckianatrucking.com, 1 +kenvix.com, 1 +kenx5.eu.org, 1 +kenyattaachinkle1.com, 1 +kenyons.info, 1 +kenzelmann.name, 1 +keops-spine.fr, 1 +keops-spine.us, 1 +kepak.tk, 1 +kepinski.me, 1 +kepkonyvtar.hu, 1 +keponews.com, 1 +keralit.nl, 1 +keramed.ga, 1 +keramed.gq, 1 +kerameion.com, 1 +keramikaopava.cz, 1 +kerb-grossauheim.de, 1 +kerbin.org, 1 +kerebro.com, 1 +kerijacoby.com, 1 +kerjaremote.online, 1 +kerkdienststream.nl, 1 +kermadec.fr, 1 +kernel-error.de, 1 +kernel-panik.me, 1 +kernel.nz, 1 +kernelpanics.nl, 1 +kernelprogrammer.com, 1 +kerner.xyz, 1 +kernet.com.ar, 1 +kernkompas.nl, 1 +kerocristais.pt, 0 +kerp.se, 0 +kerrnel.com, 1 +kerrydavisguitars.tk, 1 +kersbergen.nl, 0 +kersmexico.com, 1 +kerstkaart.nl, 1 +kersvers.agency, 1 +kertis.tk, 1 +kerus.net, 1 +kescher.at, 1 +kescher.site, 1 +kesef.org.il, 1 +kesen.news, 1 +kesen.wang, 1 +keshankang.com, 1 +keshausconsulting.com, 1 +keskeces.com, 1 +keskikorpimotorsport.fi, 0 +kessawear.com, 1 +kessel-runners.com, 1 +kesselrun.goip.de, 1 +kesslerandsons.com, 1 +kesslerwine.com, 1 +kesteren.org, 1 +ketamine.co.uk, 1 +ketemulagi.com, 1 +ketgioisu.tk, 1 +ketoanvietnam.tk, 1 +ketoconazole.gq, 1 +ketoliv.dk, 1 +ketopower.club, 1 +kett.email, 1 +kettinggeleider.be, 1 +kettlebellkrusher.com, 1 +kettlemetalbbq.com, 1 +kettmail.com, 1 +kettner.com, 1 +ketty-voyance.com, 0 +keutel.net, 1 +keuvelaar.nl, 1 +kevansizemore.com, 1 +kevchia.com, 1 +kevertje.net, 1 +kevhosting.com, 1 +kevin-emo.com, 1 +kevin-ta.com, 1 +kevin.tw, 1 +kevinapease.com, 1 +kevinbauer.ca, 1 +kevinbowers.me, 1 +kevinbusse.de, 1 +kevinchang.me, 1 +kevincox.ca, 1 +kevincoynepage.tk, 1 +kevincramer.net, 1 +kevindienst.blog, 1 +kevindustries.com, 1 +kevinfigueroamusic.tk, 1 +kevinfoley.org, 1 +kevingsky.com, 1 +kevinhill.nl, 1 +kevinhq.com, 1 +kevinkla.es, 1 +kevinlocke.name, 1 +kevinmathiesen.tk, 1 +kevinmeijer.nl, 1 +kevinmo.com, 1 +kevinmoreland.com, 1 +kevinpatel.com, 1 +kevinperrow.com, 1 +kevinpirnie.com, 1 +kevinrandles.com, 0 +kevinrousseeuw.be, 1 +kevintolaw.com, 1 +kevinvanderperren.tk, 1 +kevinwstanton.com, 1 +kevyn.lu, 1 +kexino.com, 1 +key-form.fr, 1 +key-tracker.de, 1 +key.lol, 1 +key2swipe.com, 1 +keybase.io, 1 +keyblock.ga, 1 +keyblock.gq, 1 +keyblock.tk, 1 +keybored.co, 1 +keycdn.com, 1 +keycenter.com.br, 1 +keycontainers.co.za, 1 +keyerror.com, 1 +keyex.com.br, 1 +keygen.sh, 1 +keygens.pro, 1 +keyhani.tk, 1 +keyholdingservices.co.uk, 1 +keyhomechecker.com, 1 +keyihao.cn, 1 +keyinfo.io, 1 +keykong.io, 1 +keylaserinstitute.com, 1 +keylength.com, 1 +keymaster.lookout.com, 0 +keymicrosystems.com, 1 +keynes.id.au, 1 +keyphotojs.cf, 1 +keys.fedoraproject.org, 1 +keyschip.com, 1 +keyserver.sexy, 0 +keysmedspa.com, 1 +keysofart.com, 1 +keyspanish.com, 1 +keysso.net, 1 +keysupport.org, 1 +keywalker.co.jp, 1 +keywaysconsulting.co.uk, 1 +keywebdesign.nl, 1 +keyworth-meadow.tk, 1 +keyyek.com, 0 +kezmanweb.tk, 1 +kf-59.com, 1 +kf-slot.com, 1 +kf005.com, 1 +kf020.com, 1 +kf068.com, 1 +kf099.com, 1 +kf196.com, 1 +kf199.com, 1 +kf2525.com, 1 +kf5656g.com, 1 +kf6628.com, 1 +kf66888.com, 1 +kf688.com, 1 +kf7676.com, 1 +kf7joz.com, 1 +kf846.com, 1 +kf848.com, 1 +kf8686.com, 1 +kf8897.com, 1 +kf8954.com, 1 +kf8955.com, 1 +kf8956.com, 1 +kf8957.com, 1 +kf908.com, 1 +kf909.com, 1 +kfassessment.eu, 1 +kfbl.cc, 1 +kffs.ru, 1 +kfirba.me, 1 +kfispiff.com, 1 +kfkf999.com, 1 +kfm.ink, 1 +kfmhf.ca, 1 +kfo.com.br, 1 +kforesund.se, 1 +kfoundation.org, 1 +kfv-kiel.de, 0 +kfz-hantschel.de, 1 +kfz-sachverstand.de, 1 +kfz-service-wachtmann.de, 1 +kfz.nl, 1 +kfzjeugd.nl, 1 +kg7.pl, 1 +kga-rathaustreptow.de, 1 +kgcarpetandupholsterycleaning.com, 1 +kgky.cc, 1 +kgm-irm.be, 1 +kgnk.ru, 0 +kgt10.ru, 1 +kh.pub.sa, 1 +kha.com, 1 +khachhangvietnam.tk, 1 +khaganat.net, 1 +khakasiya.ml, 1 +khakasiya.tk, 1 +khakassia.cf, 1 +khakassia.ga, 1 +khakassia.gq, 1 +khakassia.tk, 1 +khaki.ga, 1 +khakiblossom.com, 1 +khakim.tk, 1 +khaledgarbaya.net, 0 +khaledkhan.ml, 1 +khalidalnajjar.com, 1 +khalidmail.tk, 1 +khaliinfo.tk, 1 +khalti.com, 1 +khanacademy.org, 1 +khankandi.tk, 1 +khanovaskola.cz, 1 +khaotipthai.se, 1 +kharatinoil.ml, 1 +kharkiv.tk, 1 +kharkov.tk, 1 +khas.co.uk, 1 +khedmatazma.com, 1 +kheshtar.pl, 1 +khetzal.info, 1 +khg-orchester.de, 1 +khimaira.com, 1 +khimno.com, 1 +khipu.com, 1 +khm.v.ua, 1 +khmb.ru, 0 +khmerlive.cf, 1 +khmrynok.com.ua, 1 +khojhealth.com, 1 +khokey.com, 1 +khorne.me, 1 +khoteyev.tk, 1 +khotool.com, 1 +khoury-dulla.ch, 0 +khouryalexandre.com, 0 +khoxuongchothuegiare.vn, 1 +khramtsov.org, 1 +khs1994.com, 1 +khslaw.com, 1 +khudothiswanpark.vn, 1 +khukhrain.tk, 1 +khusal.tk, 1 +khushiandjoel.com, 1 +khwezifinancialservices.co.za, 1 +ki-management.ch, 1 +kiadoapartman.hu, 1 +kiahalchemy.com, 1 +kiahoriane.com, 1 +kiano.net, 0 +kiapps.ovh, 1 +kiarayoga.com, 1 +kiasarnews.tk, 1 +kiasystems.com, 1 +kibea.net, 1 +kibersalon.com, 1 +kibibit.net, 1 +kibickas.lt, 1 +kibizoid.tk, 1 +kibriscicek.net, 1 +kibrisdoktor.com, 1 +kichy.net, 1 +kicirdekorasyon.com, 1 +kick-in.nl, 1 +kickasscanadians.ca, 1 +kickedmycat.com, 1 +kickex.com, 1 +kickitupcoaching.com, 1 +kickscrew.com, 1 +kickshack.tk, 1 +kicou.info, 0 +kiczela.eu, 1 +kidan.ch, 1 +kidaptive.com, 1 +kidbacker.com, 1 +kiddieschristian.academy, 1 +kiddocom.org, 1 +kiddyboom.ua, 1 +kidify.co.uk, 1 +kidneydonation.com, 1 +kido-dc.jp, 1 +kidonng.me, 1 +kids-at-home.ch, 1 +kids-castles.com, 1 +kids-ok.com, 1 +kids-world.dk, 1 +kids.gov, 1 +kids2day.in, 1 +kidsareatrip.com, 1 +kidsclub.photos, 1 +kidsdaysout.co.uk, 1 +kidsdinefree.com, 1 +kidsdj.co.uk, 1 +kidsforsavingearth.org, 1 +kidsinwoods-interfacesouth.org, 1 +kidsmark.net, 1 +kidsneversleep.com, 0 +kidspaper.nl, 1 +kidsphysiotherapy.co.uk, 1 +kidsplay-plymouth.co.uk, 1 +kidsplaybouncycastles.co.uk, 1 +kidswithguns.tk, 1 +kidtoyshop.ru, 1 +kidzpartiesllp.co.uk, 1 +kidzsmile.co.uk, 1 +kiebel.de, 1 +kiedys.net, 1 +kiekin.org, 1 +kiekko.pro, 1 +kiel-kind.de, 1 +kielux.de, 1 +kielwi.gov, 1 +kienlen.org, 1 +kienthucnoithat.vn, 1 +kientrucnamcuong.vn, 1 +kienviethung.com, 1 +kieran.de, 1 +kieran.ie, 1 +kieranjones.uk, 1 +kieranweightman.me, 1 +kierweb.co.uk, 1 +kieskundig.nl, 1 +kiesmedia.com, 1 +kiesuwarbeidsrechtadvocaat.nl, 1 +kiesuwkerstkaart.nl, 1 +kietblog.tk, 1 +kiev-live.tk, 1 +kievkiralikotel.com, 1 +kievlove.tk, 1 +kiffmarks.com, 1 +kifid.nl, 1 +kigurumi-party.ru, 1 +kihi.news, 1 +kiinteistot-lidl.fi, 1 +kiir.net, 1 +kik.ee, 1 +kikbb.com, 1 +kiki-voice.jp, 1 +kikivega.net, 1 +kiknudes.co, 1 +kikoskia.com, 1 +kiku.pw, 1 +kikuzuki.org, 1 +kilbi-reussbuehl.ch, 1 +kilian.gallery, 1 +kilianvalkhof.com, 1 +kiliframework.org, 1 +kilkennyaccountingservices.ie, 1 +kilkimzaibu.tk, 1 +kill.trade, 1 +killaraapartments.com.au, 1 +killborn.tk, 1 +killdeer.com, 0 +killedbynlp.com, 1 +killerkink.net, 1 +killerpixel.me, 1 +killerrobots.com, 1 +killerwebsites.com.au, 1 +killharmonic.tk, 1 +killme.rocks, 1 +killmebaby.ml, 1 +killmenow.tk, 1 +killymoonbouncycastles.com, 1 +kilo-files.tk, 1 +kilobyte22.de, 1 +kilogram.nl, 1 +kilometertje.nl, 1 +kimai.cloud, 1 +kimamass.com, 1 +kimbal.co.uk, 1 +kimberleythomson.tk, 1 +kimbunlar.tk, 1 +kimdotcom.tk, 1 +kimdumaine.com, 1 +kimiadaro.ir, 1 +kimicar.de, 1 +kimino-school.com, 1 +kimiris.com, 1 +kimis.gr, 1 +kimisia.net, 1 +kimitang.com, 1 +kimkuhlmanphoto.com, 1 +kimmel.com, 0 +kimmel.in, 1 +kimochi.info, 1 +kimono-furuya.com, 1 +kimono-hishiya.jp, 1 +kimono-yamaguchiya.com, 1 +kimotodental.com, 1 +kimphattai.vn, 1 +kimtran.kim, 1 +kimtstore.com, 1 +kin.life, 1 +kin.pet, 1 +kinaesthetics-forschung.net, 1 +kinanbudotenero.tk, 1 +kinautas.com, 1 +kindbear.pl, 1 +kinder-garten.tk, 1 +kinderarzt-berlin-zia.de, 1 +kinderbasar-luhe.de, 1 +kinderbuecher-kostenlos.de, 1 +kinderchor-bayreuth.de, 1 +kinderevents-sehnde.de, 1 +kindergarten-neugnadenfeld.tk, 1 +kinderkleding.news, 1 +kinderlachen.ro, 1 +kinderopvang.gent, 1 +kinderopvangthuis.nl, 1 +kinderosteopathie-osteopathie.de, 1 +kinderpneumologie.ch, 1 +kindertagespflege-rasselbande-halle.de, 1 +kindertherapie-wesel.de, 1 +kindesfreude.ch, 1 +kindfotografie.nl, 1 +kindlezs.com, 1 +kindredcode.com, 1 +kindredcode.net, 1 +kindredcode.org, 1 +kine-duthil.fr, 1 +kine.co.il, 1 +kinebamps.be, 1 +kinepolis-studio.ga, 1 +kinesiologie.tk, 1 +kinesiologikerteminde.dk, 1 +kinesiologiodense.dk, 1 +kinesiologiskolen-syd.dk, 1 +kinesiologiuddannelsen.dk, 1 +kinetikos.com.au, 1 +kinetiq.com, 1 +kineto.space, 1 +king-of-the-castles.com, 1 +kingant.net, 1 +kinganywhere.eu, 1 +kingbot.tk, 1 +kingcannabisshop.com, 1 +kingchess.vip, 1 +kingclass.cn, 1 +kingcourriel.fr, 1 +kingdomcoffee.co, 1 +kingdomexperiments.org, 1 +kingdominnergy.com, 1 +kingdoms.gg, 1 +kingfast.cc, 1 +kingfast.eu.org, 1 +kingfin.com, 1 +kingforex.co, 1 +kingiescastles.co.uk, 1 +kingjamesbibleonline.org, 1 +kingjamesgospel.com, 1 +kinglaksa.com, 0 +kinglier.ga, 1 +kingliey.ga, 1 +kingofshooting.com, 1 +kingofthecastlecoventry.co.uk, 1 +kingofthecastlesentertainments.co.uk, 1 +kingofthecastlesouthwales.co.uk, 1 +kingofthecastlesrhyl.co.uk, 1 +kingpincages.com, 1 +kingsaft.net, 1 +kingsandqueensbypalos.com, 1 +kingsblueblue.com, 1 +kingsfoot.com, 1 +kingsgategrease.com, 1 +kingsgateseptic.com, 1 +kingsley.cc, 1 +kingsofkauffman.com, 1 +kingsol.hu, 1 +kingsound.tk, 1 +kingspalacepainting.com, 1 +kingstake.network, 1 +kingstonga.gov, 1 +kingsvilletexas.com, 1 +kingtech8.tk, 1 +kingtreeexperts.com, 1 +kinhtenongthon.vn, 1 +kini24.ru, 1 +kinja.com, 1 +kinkcafe.net, 1 +kinkenonline.com, 1 +kinklist.me, 1 +kinksecrets.ga, 1 +kinkyhookup.com, 1 +kinmeiphoto.jp, 1 +kinmunity.com, 1 +kinnikinnick.com, 0 +kino-boom.tk, 1 +kino-doma.tk, 1 +kino-room.ga, 1 +kino-zavr.tk, 1 +kino.ma, 1 +kinobag.tk, 1 +kinobarashka.ga, 1 +kinodrom.kiev.ua, 1 +kinodrom.tk, 1 +kinofest.tk, 1 +kinofile.tk, 1 +kinofilmionline.tk, 1 +kinogold.tk, 1 +kinograd.tk, 1 +kinohi.tk, 1 +kinohled.cz, 1 +kinokub.tk, 1 +kinolex.ml, 1 +kinology.tk, 1 +kinomagia.cf, 1 +kinomaniac.tk, 1 +kinomoto.ovh, 0 +kinos.nl, 0 +kinoscope.tk, 1 +kinoserver.ml, 1 +kinosha.tk, 1 +kinoshki.ga, 1 +kinothek.at, 1 +kinovsem.ml, 1 +kinozone.tk, 1 +kinschots.eu, 1 +kinsei.jp, 1 +kinshipnd.com, 1 +kinsights.com, 0 +kintawifi.com, 1 +kintone.com, 1 +kintore.tv, 1 +kintsugi-beauty.com, 0 +kinualive.com, 1 +kinvault.com, 1 +kiocloud.com, 1 +kiomara.com, 1 +kiomoda.com, 1 +kiot.eu, 1 +kiousis.me, 1 +kip-ribbetjes-bestellen.be, 1 +kipa.at, 1 +kipcrepair.com, 1 +kipiradio.com, 1 +kiplelive.com, 1 +kippenbart.gq, 1 +kipriakipita.gr, 1 +kiprinform.com, 1 +kipsu.com, 1 +kipwells32.com, 1 +kiraboshi.xyz, 1 +kiragameforum.net, 1 +kirainmoe.com, 1 +kiraku.co, 1 +kirbear.com, 1 +kirby.eu.org, 1 +kirche-sankt-augustin.de, 1 +kirchen-im-web.de, 0 +kirchenchor-olzheim.de, 1 +kirchengemeinde-markt-erlbach.de, 1 +kircp.com, 1 +kirei.se, 1 +kirgistan.tk, 1 +kirie-photos.tk, 1 +kirig.ph, 1 +kirikira.moe, 1 +kirillaristov.com, 1 +kirillpokrovsky.de, 1 +kirina.nl, 1 +kirinas.com, 1 +kirka.ga, 1 +kirkae.com, 1 +kirkforcongress.com, 1 +kirkforillinois.com, 1 +kirkforsenate.com, 1 +kirkify.com, 1 +kirkintillochbc.co.uk, 1 +kirkovsky.com, 1 +kirkwood-smith.com, 1 +kirkwoodfence.com, 1 +kirkwoodfencing.com, 1 +kirkwoodoutdoors.com, 1 +kiro-ku.com, 1 +kiropraktorvard.se, 1 +kirov.ml, 1 +kirovcity.tk, 1 +kirovgrad.tk, 1 +kirrie.pe.kr, 1 +kirsch-gestaltung.de, 1 +kirschbaum.me, 1 +kirscrb.ru, 1 +kirslis.com, 1 +kirstenbos.ca, 1 +kirstin-peters.de, 1 +kirstygreenwoodartist.ga, 1 +kirwandigital.com, 1 +kisaragihayato.com, 1 +kiseimarriage.com, 1 +kiseki.xyz, 1 +kisel.org, 1 +kisiselveri.com, 1 +kiskeedeesailing.com, 1 +kislovodsk-zamok.tk, 1 +kisma.de, 1 +kismy.tk, 1 +kismyder.tk, 1 +kisser.name, 1 +kissesb.net, 1 +kissgyms.com, 1 +kissimmee.gov, 1 +kisskiss.ch, 1 +kissmateszabolcs.hu, 1 +kissmycreative.com, 1 +kissoft.ro, 1 +kisstube.tv, 1 +kisulki.tk, 1 +kisumuterraceapartments.tk, 1 +kisvasut.tk, 1 +kit.watch, 1 +kita-freie-schule.de, 1 +kita-sun.com, 1 +kitabat.com, 1 +kitabmimpi.com, 1 +kitabnamabayi.com, 1 +kitacoffee.com, 1 +kitagawa-internal-medicine-clinic.com, 1 +kitchenlove.tk, 1 +kitchenpad.biz, 1 +kitchenpad.co.uk, 1 +kitchenpad.info, 1 +kitchenpad.net, 1 +kitchenpad.org, 1 +kitchenpad.us, 1 +kitchenpadtimer.com, 1 +kitchenpunx.com, 0 +kitchenware.tk, 1 +kitchenwarestore.xyz, 1 +kite-surf.tk, 1 +kite-surfen.tk, 1 +kiteadventure.nl, 1 +kiteboard-selbstbau.tk, 1 +kitebowl.ru, 1 +kiteschoolamsterdam.nl, 1 +kiteschooledam.nl, 1 +kiteschoolijmuiden.nl, 1 +kiteschoolkatwijk.nl, 1 +kiteschoolnoordwijk.nl, 1 +kiteschoolschellinkhout.nl, 1 +kiteschoolwijkaanzee.nl, 1 +kiteschoolzandvoort.nl, 1 +kitesurfen.tk, 1 +kitevalley.tk, 1 +kitke.de, 1 +kits-graphiques-shop.tk, 1 +kits-graphiques.tk, 1 +kitsapsolutions.com, 1 +kitscan.com, 1 +kitseliit.ee, 1 +kitsquid.de, 1 +kitsuna.eu, 1 +kitten-advice-forum.cf, 1 +kittpress.com, 0 +kittybot.de, 1 +kittyhacker101.tk, 0 +kittymagician.com, 1 +kivitelezesbiztositas.hu, 1 +kiwee.eu, 1 +kiweeagentur.de, 1 +kiwetech.com, 1 +kiwi-bird.xyz, 1 +kiwi.com, 1 +kiwi.digital, 1 +kiwi.global, 1 +kiwibird.tokyo, 1 +kiwicoworking.com, 1 +kiwideo.ro, 1 +kiwiflowershop.com.ua, 1 +kiwing.ddns.net, 1 +kiwipayment.com, 1 +kiwiplace.com, 1 +kiwistreamer.co.nz, 1 +kiwitastic.com, 1 +kix.moe, 1 +kiyotatsu.com, 1 +kizkulesi.tk, 1 +kizomba.info, 1 +kizuki1749.net, 1 +kizzedbykelz.com, 1 +kj-prince.com, 1 +kj1396.net, 1 +kjaer.io, 1 +kjarni.cc, 1 +kjarrval.is, 1 +kjccradio.tk, 1 +kjcdaily.xyz, 1 +kjchernov.info, 1 +kjellner.com, 1 +kjelltitulaer.com, 1 +kjellvn.net, 1 +kjfaudio.com, 1 +kjkmail.de, 1 +kjmedia.dk, 1 +kjnotes.com, 1 +kjs73.com, 1 +kk-gruppe.net, 1 +kk.gt, 1 +kk.in.th, 1 +kk.sb, 1 +kk3773.com, 1 +kk5197.co, 1 +kk575757.com, 1 +kk6729.co, 1 +kk6729.com, 1 +kk6957.co, 1 +kk9297.co, 1 +kk9721.com, 1 +kk9728.co, 1 +kkangeli.tk, 1 +kkaramela.eu, 1 +kkc.com, 1 +kkcinemas.in, 1 +kkcsc.co.jp, 1 +kki.org, 1 +kkicreative.com, 1 +kkk0011.com, 0 +kkk101.com, 0 +kkk102.com, 0 +kkk104.com, 0 +kkk106.com, 0 +kkk109.com, 0 +kkk201.com, 0 +kkk202.com, 0 +kkk203.com, 0 +kkk204.com, 0 +kkk208.com, 0 +kkk209.com, 0 +kknapredak-rubin.tk, 1 +kkovacs.eu, 1 +kkr-bridal.net, 1 +kkren.me, 0 +kks-karlstadt.de, 0 +kks.ch, 1 +kksg.com, 0 +kkull.tv, 1 +kkutu.us, 0 +kkws.co, 1 +kkyy.me, 0 +kkzxak47.com, 1 +kl008888.com, 1 +klabnik.cz, 1 +klabnikova.cz, 1 +klacki.de, 1 +klaim.us, 1 +klamathrestoration.gov, 1 +klanggut.at, 1 +klankenkast.nl, 1 +klapib.ee, 1 +klapty.com, 1 +klares-licht.de, 1 +klarika.com, 1 +klarmobil-empfehlen.de, 1 +klassenlos.tk, 1 +klassiekballet.tk, 1 +klassika.tk, 1 +klatschreime.de, 1 +klaudialeszczynska.pl, 1 +klauke-enterprises.com, 1 +klausbrinch.dk, 0 +klausen.dk, 1 +klausfoerster.tk, 1 +klauswissmann.com, 1 +klautshop.com, 1 +klaver.it, 1 +klaw.xyz, 1 +klaxon.me, 1 +klaxon.ml, 1 +kle.cz, 1 +klea.tk, 1 +kleaning.by, 1 +kleankonshiens.com, 1 +klebeband.eu, 1 +kleberstoff.xyz, 1 +klebetape.de, 1 +kleebauerhof.com, 1 +kleemans.nl, 1 +kleen.tk, 1 +kleidertauschpartys.de, 1 +kleim.fr, 1 +kleinblogje.nl, 0 +kleincliche.nl, 1 +kleine-dingen.nl, 1 +kleine-strandburg-heringsdorf.de, 1 +kleine-strandburg.com, 1 +kleine-strolche-lich.de, 1 +kleine-viecherei.de, 1 +kleineanfragen.de, 1 +kleinestrandburg-heringsdorf.de, 1 +kleinestrandburg-usedom.de, 1 +kleineviecherei.de, 1 +kleinfein.co, 1 +kleinhaneveld.tk, 1 +kleinhelena.dynv6.net, 1 +kleinreich.de, 1 +kleinserienproduktion.com, 1 +kleinsys.com, 1 +kleintransporte.net, 1 +kleki.com, 1 +klementijgerta.tk, 1 +klemkow.net, 1 +klemkow.org, 1 +klempin.co.uk, 1 +klempin.me, 1 +klempin.net, 1 +klempin.network, 1 +klempin.se, 1 +klen.ua, 1 +klenc.eu, 1 +kleor.com, 1 +kleppe.co, 1 +kleteckova.cz, 1 +kleurbkennen.nl, 1 +klev.su, 1 +klever.com.mk, 1 +kleverltd.ru, 1 +kli.is, 1 +klickinvite.com, 1 +klickstdu.com, 1 +kliemann.me, 1 +klikacc.com, 0 +klikarnia.pl, 1 +kliki.tk, 1 +kliklinks.tk, 1 +klikmanga.com, 1 +klikmarket.tk, 1 +klil.co.il, 1 +klimaatgroepstars.nl, 1 +klimaatkids.be, 1 +klimaatstad.gent, 1 +klimaloven.no, 1 +klimapartner.de, 1 +klimapartner.net, 1 +klingeletest.de, 1 +klingenundmesser.com, 1 +klinik-fuer-aesthetische-zahnheilkunde.de, 1 +klinikac.co.id, 0 +klinikasochi.com, 1 +klinikum-oldenburg.de, 1 +klinkenberg.ws, 1 +klinknetz.de, 1 +klinkov.tk, 1 +klinto.nl, 1 +klishyn.com, 1 +klitmoeller.de, 1 +klitmoeller.dk, 1 +kliu.io, 1 +klj-beveren.tk, 1 +klj-walshoutem.tk, 1 +klm-huisjes.nl, 1 +klmgewinnspiel.de, 1 +klmhouses.com, 1 +klocast.com, 1 +klocker-ausserlechner.com, 1 +klocksnack.se, 1 +kloclabs.com, 1 +klogeschichten.net, 1 +kloia.com, 1 +klondike-pool.com, 1 +kloop.kg, 1 +klop.info, 1 +klose.family, 1 +klosko.net, 1 +klpiano.my, 1 +klssn.com, 1 +klu.io, 1 +klub-zajmov.ga, 1 +klub.tk, 1 +klubcajovna.cz, 1 +kluck.me, 1 +klugemedia.de, 1 +klusbedrijfdupau.nl, 1 +klushka.cf, 1 +klusservice-utrecht.nl, 1 +klustermedia.com, 1 +klusweb-merenwijk.nl, 1 +klute.spdns.de, 1 +kluzza.nl, 1 +klva.cz, 1 +kmashworth.co.uk, 1 +kmassociations.com, 1 +kmkz.jp, 1 +kmrgroup.com, 1 +kms60.fr, 1 +kmsk.tk, 1 +kmtechnology.com, 1 +kmzs123.cn, 1 +kn007.net, 1 +kn40la.com, 1 +kn4ivj.com, 1 +kn4ola.com, 1 +knab-networks.com, 1 +knabden.co.za, 1 +knabstrup-autoophug.dk, 1 +knallfrosch.ddnss.de, 1 +knapp.noip.me, 1 +knapp.pro, 1 +knapp.servehttp.com, 1 +knarcraft.net, 1 +knarkkorven.tk, 1 +knautiluz.net, 0 +kncg.pw, 1 +kndrd.io, 1 +knechtology.com, 1 +kneerux.de, 1 +knegten-agilis.com, 1 +kneli.co.il, 1 +knep.me, 0 +kneppe.me, 1 +kngk-group.ru, 0 +kngk-transavto.ru, 1 +kngk.org, 0 +kniga-ru.tk, 1 +kniga.market, 0 +knigareceptov.cf, 1 +knighki-knighki.ml, 1 +knighkidoma.tk, 1 +knightpowerelectrical.com.au, 1 +knightsblog.de, 1 +knightsbr1dge.red, 0 +knightsbridge.net, 1 +knightsbridgewine.com, 1 +knightsofcolumbus867.com, 1 +knightsweep.com, 1 +knighulki.cf, 1 +knigi-free.cf, 1 +knigi-na-dom.cf, 1 +knigi-zdes.gq, 1 +knigifast.ga, 1 +knihovnajablonne.cz, 1 +knip.ch, 1 +knispel-online.de, 1 +knitfarious.com, 1 +knitted-hats.tk, 1 +knitting.cz, 1 +kniwweler.com, 1 +knize.tech, 1 +knjazevac.tk, 1 +knjizevic.at, 1 +knmv.nl, 1 +knnet.ch, 1 +knobboutheftrucks.nl, 1 +knoji.com, 1 +knop.info, 0 +knorrnet.de, 1 +knovator.com, 1 +know.cf, 1 +knowarth.com, 1 +knowit-now.com, 1 +knowledge-base.info, 1 +knowledgeforce.com, 0 +knowledgehook.com, 1 +knowledze.com, 1 +knowlevillagecc.co.uk, 1 +knownsec.cf, 1 +knowpanamatours.com, 1 +knowthebus.cf, 1 +knowuproxy.com, 1 +knowyour.place, 1 +knowyourday.ai, 1 +knoxcountytn.gov, 1 +knoxvilleimplants.com, 1 +knrt.de, 1 +knrt.eu, 1 +knthost.com, 1 +knuckles.tk, 1 +knulla.me, 1 +knulle.me, 1 +knurps.de, 1 +knuterikskare.no, 1 +knuthildebrandt.de, 0 +knuwiki.tk, 1 +knxstore.cz, 1 +knygos.lt, 1 +koala.one, 0 +koalapress.fr, 0 +koalarong.com, 0 +koalas.org, 1 +kob-one.com, 1 +koba.jp, 1 +kobar.id, 1 +kobejet.com, 1 +kobezda.net, 1 +kobieta.guru, 1 +kobietydokodu.pl, 1 +kobofarm.com, 1 +koboldcraft.ch, 1 +koboldmalade.fr, 1 +kobolya.hu, 1 +kobovec.tk, 1 +kobudo49.fr, 1 +koch-wro.pl, 1 +kochadaiyaan.tk, 1 +kochbar.de, 1 +kochcommunity.com, 1 +kocherev.org, 1 +kochereva.com, 1 +kocheshkov.cf, 1 +kochhar.net, 1 +kochi-death.ml, 1 +kochinke.com, 1 +kochinke.us, 1 +kochura.tk, 1 +kocka.cf, 1 +kocka.tech, 1 +kockanakocko.si, 1 +kocovi.cz, 0 +kod13.com, 1 +kodak-ism.com, 1 +kodama-dorayaki.co.jp, 1 +kodamail.com, 1 +kodden.com.br, 1 +koddsson.com, 1 +kode-it.de, 1 +kode.ch, 0 +kodexplorer.ml, 1 +kodifirestick.info, 1 +kodify.net, 1 +kodikom.de, 1 +kodineuerleben.eu, 1 +kodioso.com, 1 +kodkollen.com, 1 +kodkollen.se, 1 +kodomo.live, 1 +koe.dk, 1 +koe.hn, 1 +koe.kr, 0 +koebbes.de, 1 +koecollege.com, 1 +koeeusa.org, 1 +koef.nl, 1 +koehlhoff.de, 1 +koehn.com, 1 +koelbli.ch, 1 +koelcel-onderdelen.com, 1 +koeldezomerdoor.nl, 1 +koelingmonitor.com, 1 +koelnmafia.de, 1 +koenberkhout.nl, 1 +koenigsbrunner-tafel.de, 1 +koenleemans.nl, 1 +koenmartens.nl, 1 +koenrh.com, 1 +koenrh.net, 1 +koenrh.nl, 1 +koenrouwhorst.com, 1 +koenrouwhorst.nl, 1 +koenzk.nl, 1 +koerperkult.ch, 1 +koertner-muth.com, 1 +koertner-muth.de, 1 +koethen-markt.de, 1 +koetjesenkanker.nl, 1 +koez-mangal.ch, 1 +koffie-enzo.com, 1 +koffiekoeken.tk, 1 +kofler.info, 1 +kogak.ninja, 1 +kogax.com, 0 +kogi.fr, 1 +kogotok.gq, 1 +kogotok.ml, 1 +kogro.de, 1 +kogudesi.com, 1 +kohaku.love, 1 +kohlchan.net, 1 +kohlistkool.tk, 1 +kohoutsautomotive.com, 1 +kohparadise.com, 1 +kohsandra.com, 0 +koi-lexikon.de, 1 +koicenter-thuine.de, 1 +koifish.org, 1 +koineuno.com, 1 +koing.de, 1 +koirala.email, 1 +koiro.fi, 1 +koishi.pro, 1 +koizumidesign.com, 1 +koj.co, 1 +koji-tsujitani.net, 1 +kojiishikawa.com, 1 +kojip.com, 1 +kojipkgs.fedoraproject.org, 1 +kojy.fr, 1 +koka-shop.de, 1 +kokankart.com, 1 +kokensupport.com, 1 +koketteriet.se, 1 +kokica.si, 1 +kokily.com, 1 +koko.news, 1 +kokoiroworks.com, 1 +kokomo.cloud, 1 +kokomo.xyz, 1 +kokomu.com, 1 +kokona.ch, 1 +kokoro-singsong.com, 1 +kokotaru.com, 1 +kokteili.tk, 1 +koktelparty.tk, 1 +kokumoto.com, 1 +kokyu-caba.com, 1 +kolaci.tech, 1 +kolaczek.cz, 1 +koladeogunleye.com, 1 +kolakweb.com, 1 +kolania.com, 1 +kolania.de, 1 +kolania.net, 1 +kolaprestaurant.com, 1 +kolas.in, 1 +kolbeck.tk, 1 +kolbeinsson.se, 1 +kolcsey.eu, 1 +koldanews.com, 0 +kolhozik.ml, 1 +kolibrikapp.com, 1 +kolibrisolutions.nl, 1 +kolin.org, 1 +kolizaskrap.bg, 1 +kolja-engelmann.de, 1 +kolkataflowermall.com, 1 +kolkatanight.com, 1 +kolkinn.no, 1 +kollawat.me, 1 +kollega.it, 1 +kollegamenti.it, 1 +kollner.com, 1 +kollross.io, 1 +kolmann.at, 1 +kolmann.eu, 1 +kolodec-pod-kluch.ru, 1 +kolonie-am-stadtpark.de, 1 +koloradskij-zhuk.tk, 1 +kolorwell.tk, 1 +kolpingsfamilie-vechta-maria-frieden.de, 1 +kolrami.com, 1 +koltsov.email, 1 +koluke.co, 1 +koluke.com, 1 +kolyapetrov.tk, 1 +kom.pe, 1 +komall.net, 1 +komarex.pl, 1 +komarh.tk, 1 +komehyo.co.jp, 1 +komelin.com, 0 +komenamanda.de, 1 +kometia.com, 1 +komfort.kh.ua, 1 +komget.net, 0 +komicloud.com, 1 +komidoc.com, 1 +komiksbaza.pl, 1 +kominfo.go.id, 1 +kominfo.net, 0 +kominki-sauny.pl, 1 +komintek.ru, 1 +komintern43.tk, 1 +komischkeszeug.de, 1 +komisjon.ee, 1 +komitur.tk, 1 +komlangs.nl, 1 +kommaer.dk, 1 +komment.ml, 1 +kommotiv.nl, 0 +kommunermeddnssec.se, 1 +kommunermedipv6.se, 1 +kommunikation-czw.de, 1 +kommunistienliitto.tk, 1 +kommx.de, 1 +komodolabs.com, 1 +komoju.com, 1 +komok.co.uk, 1 +komp-plus.tk, 1 +komp247.pl, 1 +kompaniya-vasya.tk, 1 +kompetenzkurs.de, 1 +komplekt.gq, 1 +komplektmarket.ru, 1 +komplet.sk, 1 +komplexlysimple.com, 1 +komputer-net.tk, 1 +komputersat.pl, 1 +komun.me, 1 +kon-sil.de, 1 +konaqua.com, 1 +konarentals.net, 1 +konata.tech, 1 +konbantsan.com.tr, 1 +koncertbooking.com, 1 +kondi.net, 1 +kondou-butsudan.com, 1 +konducars.nl, 1 +konf.ga, 1 +konfekcjonowanie.com, 1 +konflikte-als-chance.de, 1 +konflikthaus.de, 1 +konfliktklaerer.de, 1 +kong.ink, 1 +kongar.org, 1 +kongress-hostessen.de, 1 +konicaprinterdriver.com, 0 +koniecfica.sk, 0 +konijnen-knaagdieren.tk, 1 +konijntjes.nl, 1 +konings.it, 0 +koningslust.tk, 1 +koninkrijk.net, 1 +konjunktion.tk, 1 +konkai.store, 1 +konklone.com, 1 +konkurs.ba, 1 +konkursita.ru, 1 +konnai.jp, 1 +konnitanaka.com, 1 +konoe.studio, 0 +kononenko.ml, 1 +konosuke.jp, 1 +konpyuta.nl, 1 +konsertoversikt.no, 1 +konservy.tk, 1 +konst.se, 1 +konstanz.tk, 1 +konstructdigital.com, 1 +konsul.ga, 1 +konsul.tk, 1 +konsultacii-buhgaltera.ga, 1 +konsultaciya-astrologa.cf, 1 +konsultaciya-astrologa.ga, 1 +konsultaciya-astrologa.gq, 1 +konsultaciya-astrologa.ml, 1 +konsultaciya-astrologa.tk, 1 +kontabilitet.tk, 1 +kontantfinans.se, 1 +kontaxis.org, 1 +kontenido.net, 1 +kontikiindustries.tk, 1 +kontist.com, 1 +kontorhaus-schlachte.de, 1 +kontorhaus-stralsund.de, 1 +kontracovid.ph, 1 +kontracrew.tk, 1 +kontrapolis.info, 1 +kontrastonline.tk, 1 +kontrolapovinnosti.cz, 1 +kontum.in, 1 +kontur-buhta.ru, 1 +kontur-extern.ru, 1 +kontur.tk, 1 +konturconference.ru, 1 +konuhaber.com, 0 +konut-projeleri.com, 1 +konventa.net, 1 +konyahaber.tk, 1 +konyalian.com, 1 +konyvbazar.ro, 1 +konzepttreu.de, 1 +konzertheld.de, 1 +koobin.cat, 1 +koobin.com, 1 +koobin.es, 1 +kood13.com, 1 +koodaklife.com, 1 +koode.mx, 1 +koodimasin.ee, 1 +koodimasin.eu, 1 +kooer.org, 1 +koof.win, 1 +kooibeds.com, 1 +kooky.org, 1 +koolauwomenshealthcare.com, 1 +kooli.ee, 1 +koolikatsed.ee, 1 +koolisw.cf, 1 +koolisw.tk, 1 +koolitee.ee, 1 +kooliveeb.ee, 1 +koolkool.tk, 1 +koomaldreaming.com.au, 1 +koood13.com, 1 +koop-bremen.de, 1 +kooplokaal.gent, 1 +kooponline.eu, 1 +kooratalk.ga, 1 +koot.nl, 1 +kooxdiving.com, 1 +koozal.de, 1 +kopany.tk, 1 +kopb.tk, 1 +kopeechka.ml, 1 +koperek.pl, 1 +kopeyka.cf, 1 +kopfgeld.tk, 1 +kopfkrieg.org, 1 +kopfootdoctor.com, 0 +kopfsalat.eu, 0 +kopfschaschlik.de, 1 +kopfundseele.de, 1 +kopieid.be, 1 +kopjethee.nl, 1 +kopker.hu, 1 +koplancpa.com, 1 +koplax-online.com, 1 +koponyab.com, 1 +kopplin.family, 1 +koptev.ru, 1 +kopteva.ru, 1 +kopular.com, 1 +kopykatz.org, 0 +kor.ovh, 1 +kora-pluss.com, 0 +korablino.tk, 1 +korancode.tk, 1 +koranseruya.com, 1 +korbel-loziska.cz, 1 +korben.info, 1 +kordamed.ee, 1 +korea-dpr.org, 1 +korea.dating, 1 +korea.de, 1 +koreabestood.ga, 1 +koreaboo.com, 1 +koreanfashion.tk, 1 +koreanhouse.tk, 1 +koreaninhd.com, 1 +koreanpearls.tk, 1 +koreanrandom.com, 1 +koreanure.tk, 1 +koredia.com, 1 +korespondent.tk, 1 +koretech.nl, 1 +korfbalinformatie.nl, 1 +korkortonline.se, 1 +kormmi.ru, 1 +korn-klan.tk, 1 +kornmesser-goldankauf.at, 1 +korob-ok.com.ua, 1 +korobkovsky.ru, 0 +korofilms.com, 1 +koroknaimedical.hu, 1 +koroleva.ml, 1 +korolevstvo-movie.ml, 1 +koroli.tk, 1 +korp.fr, 1 +korrelzout.nl, 1 +kortarsmagyarfesto.tk, 1 +kortgebyr.dk, 1 +korund.tk, 1 +korusautos.com, 1 +koryfi.com, 1 +kos4all.com, 1 +kos9078.com, 1 +kosaki.moe, 1 +koscielniak-nieruchomosci.pl, 1 +koshakovo.ga, 1 +koshechka.tk, 1 +koshereducationers.ga, 1 +kosherjava.com, 1 +kosinc.org, 1 +kosmetykifm.pl, 1 +kosmonavt.tk, 1 +kosmos.org.tw, 1 +kosmosfestival.tk, 1 +kosovo.gq, 1 +kost-magazin.de, 1 +kostecki.com, 1 +kostecki.org, 1 +kostecki.tel, 1 +kostenlosepornos.online, 1 +kostenloses-forum.tk, 1 +kosterenpartners.com, 1 +kostroma-city.tk, 1 +kostroma.cf, 1 +kostroma.gq, 1 +kostroma.ml, 1 +kostroma.tk, 1 +kosturanov.com, 1 +kostya.ws, 1 +kostyumi.tk, 1 +kosuzu.moe, 1 +kotaartsklan.com, 1 +kotaev.tk, 1 +kotak.us, 1 +kotakoo.id, 1 +kotaku.com, 1 +kotaraanglican.org.au, 1 +kotatgent.be, 1 +kotausaha.com, 1 +koten-bu.com, 1 +kother.org, 1 +kotilinkki.fi, 1 +kotitesti.fi, 1 +kotka.ml, 1 +kotke.ru, 1 +kotly-marten.com.ua, 1 +kotmale.com, 1 +kotobox.net, 1 +kotois.com, 1 +kotomei.moe, 1 +kotonoha.cafe, 1 +kotonozaka.xyz, 1 +kotoopros.tk, 1 +kotori.love, 1 +kotori.style, 1 +kotorimusic.ga, 1 +kottbulle.net, 1 +kottur.is, 1 +kotuwa.tk, 1 +koubova.net, 1 +koujo-soukohonpo.com, 1 +kouki-food.com, 1 +koumakan.cc, 1 +koumuwin.com, 1 +koupons.nl, 1 +kouroshnet.com, 0 +koushinjo.org, 1 +kouten-jp.com, 1 +koutkod.com, 1 +kouwenhoven.xyz, 1 +kov.space, 1 +kovachica.tk, 1 +kovehitus.ee, 1 +kovered.net, 1 +kovnsk.net, 1 +kovspace.com, 1 +kovu.es, 1 +kovuthehusky.com, 1 +kowalmik.tk, 1 +kowalski7cc.xyz, 1 +kowalstwo.com.pl, 1 +kowarschick.de, 1 +kowshiksundararajan.com, 1 +koyaanis.com, 0 +koyaanisqatsi.tk, 1 +koyo.kr, 1 +kozackibazar.pl, 1 +kozak.cloud, 1 +kozansa.net, 1 +kozentic.com, 1 +kozlekedes.info, 1 +kozlov.cf, 1 +kozuch.biz, 1 +kp-walsh.com, 1 +kp0808.cc, 1 +kp0809.com, 1 +kpforme.org, 1 +kpinvest.eu, 1 +kplastics.in, 1 +kplasticsurgery.com, 1 +kplnet.net, 1 +kpmgclientcollab.co.nz, 1 +kpntdolive.nl, 1 +kpop.events, 1 +kpop.re, 1 +kpopsource.com, 1 +kprem.com, 1 +kprf-school74.tk, 1 +kpumuk.info, 1 +kpvpn.com, 1 +kpx1.de, 1 +kr.search.yahoo.com, 0 +kr0n.dk, 1 +kra2laiz.eu, 1 +krabathor.tk, 1 +krachtinverbinding.nl, 1 +kradalby.no, 1 +kraft.blog, 1 +kraft.im, 1 +kraftek.cf, 1 +kraftpc.com, 1 +kraftzeiten.de, 1 +krag.be, 1 +kraga.sk, 1 +kraiwan.com, 1 +kraiwon.com, 1 +krajzlinsky.info, 1 +kraken-ttt.com, 1 +kraken.io, 1 +kraken.site, 1 +krakenrobotik.de, 1 +krakozyabra.ga, 1 +krakozyabra.gq, 1 +krakozyabra.tk, 1 +kralchat.net, 1 +kralenparadijs.tk, 1 +kralik.io, 1 +kralovskapradelna.cz, 1 +kralovstvimap.cz, 1 +kram.nz, 1 +krambeutel.de, 1 +kramersworld.tk, 1 +kramsj.uk, 1 +kran.ga, 1 +krang.org.uk, 1 +kranjnakolo.ml, 1 +krankenpflege-haushaltshilfe.de, 1 +krankenpflege.ch, 1 +kranservice-alzey.tk, 1 +krasa.tk, 1 +krasavchik.by, 1 +krasivye-foto.ru, 1 +kraski.tk, 1 +krasnaya-nit.ga, 1 +krasnodar-pravoved.ru, 1 +krasnodar.one, 1 +krasnodar24.tk, 1 +krasnodarkrai.tk, 1 +krasnoyarsk-24.tk, 1 +krasnoyarsk24.tk, 1 +krasotkafirm.tk, 1 +krasotki.ml, 1 +krasovsky.me, 1 +kratochvilovi.net, 1 +kratom-k.com, 1 +krauseent.com, 0 +krauskopf-it.de, 1 +krautomat.com, 1 +kravmagaangers.fr, 1 +kraynik.com, 1 +krazy.net.au, 1 +krazykastles.co.uk, 1 +krazykoolkastles.com, 1 +krazyphotobooths.co.uk, 1 +krc.link, 1 +kreasiwarna.com, 1 +kreationnext.com, 0 +kreativbande.com, 1 +kreativelabs.ch, 0 +kreativenerds.com.ng, 1 +kreativklinik.at, 1 +kreativoweb.tk, 1 +kreativstrecke.de, 1 +kreatywni.co, 1 +krechka.ru, 1 +kredigram.com, 1 +kredit-abzocke.com, 1 +kredit-galerie.de, 1 +kredit-kenntnis.de, 1 +kredit-mit-negativer-schufa.com, 1 +kredit-negative-schufa.de, 1 +kredit-ohne-schufa.at, 1 +kredit-online.ru, 1 +kredit-schule.de, 1 +kredit-zeit.de, 1 +kredit24.de, 1 +kredita.dk, 1 +kredite-ohne-schufa.at, 1 +kreditkarten-forum.de, 1 +kreditkoll.nu, 1 +kreditonline.ml, 1 +kreditor.gq, 1 +kreditovnet.tk, 1 +kreditvergleich.org, 1 +kreditzirkus.de, 1 +kreditzone.ml, 1 +kredobank.com.ua, 1 +kredytzen.pl, 1 +kreen.org, 1 +kreftprzewieda.pl, 1 +krehak.com, 1 +kreidl.org, 1 +kreidlernet.tk, 1 +kremalicious.com, 1 +kreno.tech, 1 +krenstetter.at, 1 +kresimir-blazevic.tk, 1 +kreslorotang.com.ua, 1 +krestanskydarek.cz, 1 +kretaforum.dk, 1 +kretschmann.consulting, 1 +kreuzbergflieger.de, 1 +kreuzpfadfinder.de, 1 +kreuzwortraetsellosungen.com, 1 +kreweofneptune.org, 1 +krey.is, 1 +kreyolgym.fr, 1 +kreza.de, 1 +krezimizik.com, 1 +kridtvejsplanter.dk, 1 +kriechel.de, 1 +kriegskindernothilfe.de, 1 +krikorianconstruction.com, 1 +krillz.se, 1 +krilotek.com, 1 +krilov.tk, 1 +krimikiosk.de, 1 +krimzeta.com, 1 +krinetzki.de, 0 +kringloopwinkelsteenwijk.nl, 1 +krings.nl, 1 +krinnovations.ie, 1 +kripa.tk, 1 +kriptodede.com, 1 +kriptokereso.com, 1 +kriptopodgon.tk, 1 +kriptosec.com, 1 +kriptoworld.hu, 1 +krise-chance.ch, 1 +krisenintervention-deutschland.de, 1 +kriseninterventiondeutschland.de, 1 +krisftp.fr, 1 +krishin.tk, 1 +krishnakalisaha.com, 1 +krishnendu.com, 1 +krishnenduayur.org, 1 +krishofer.com, 1 +krishouse.fr, 1 +kriskonaturopathic.com, 1 +kriskras99.nl, 1 +krismurray.co.uk, 1 +krisp.ai, 1 +krispeinture.be, 1 +krisstarkey.co.uk, 1 +kristall-energie.at, 1 +kristall.xyz, 1 +kristenpaigejohnson.com, 1 +kristiehill.com, 1 +kristikala.nl, 1 +kristina-lari.ru, 1 +kristinbailey.com, 1 +kristineskitchenblog.com, 1 +kristjanrang.eu, 0 +kristofba.ch, 1 +kristofdv.be, 1 +kristoffer.is, 1 +kriston.tk, 1 +kriswauters.tk, 1 +kritical.es, 1 +kritikahotels.com, 1 +kritikawebu.cz, 1 +kritikos.io, 1 +kriyayoga.fr, 1 +krizevci.info, 1 +krmela.com, 1 +krmeni.cz, 0 +kroell.net, 1 +krok.gq, 1 +krokedil.se, 1 +kroliczki.tk, 1 +kroll.tk, 1 +kromamoveis.com.br, 1 +kromax.it, 1 +kromciri.gq, 1 +krome.sg, 1 +kromonos.net, 1 +kromozottrud.hu, 1 +kroneaustralia.com.au, 1 +kronopolo.com, 1 +kronos-crm.com, 1 +kronos-web.com, 1 +kronosproject.tk, 1 +kronych.cz, 1 +kroon.email, 1 +kropkait.pl, 1 +krosovki-nike.tk, 1 +krossakorven.tk, 1 +krouzkyliduska.cz, 0 +krovatka.tk, 1 +krozilla.tk, 1 +krsaustralia.com.au, 1 +krsn.de, 1 +krsvrs.nl, 1 +krti.com.ua, 1 +krubik.tk, 1 +kruemels-kleine-kinderwuensche.de, 1 +krug-munroe.wedding, 1 +krugermillions.org, 1 +krugernationalpark.org.za, 1 +krugersdorpplumber24-7.co.za, 1 +kruin.net, 1 +kruk.co, 1 +krumpf.de, 1 +kruno.ooo, 1 +krup.com.ua, 1 +krupa.net.pl, 0 +kruselegal.com.au, 1 +krusesec.com, 1 +krusic22.com, 1 +krutilka.ga, 1 +krutka.cz, 1 +kruu.de, 1 +kry.no, 1 +kry.se, 1 +krypmonet.com, 1 +krypsys.com, 1 +krypt.com, 1 +kryptera.se, 1 +kryptix.eu, 1 +kryptix.net, 1 +kryptlock.com, 1 +krypto-geld.eu, 1 +kryptoforce.com, 1 +kryptologie.tk, 1 +kryptomech.com, 1 +kryptomodkingz.com, 1 +kryptux.xyz, 1 +kryshodel.ml, 1 +krystal-framework.ml, 1 +krystalrsimpson.com, 1 +krytykawszystkiego.com, 1 +krytykawszystkiego.pl, 1 +kryx.de, 1 +ks-19.com, 1 +ks-29.com, 1 +ks-39.com, 1 +ks-59.com, 1 +ks-79.com, 1 +ks-89.com, 1 +ks-watch.de, 1 +ks009.com, 1 +ks0098.com, 1 +ks015.com, 1 +ks016.com, 1 +ks017.com, 1 +ks02.cc, 1 +ks0318.com, 1 +ks038.com, 1 +ks05.cc, 1 +ks05.net, 1 +ks0550.com, 1 +ks058.com, 1 +ks0588.com, 1 +ks0599.com, 1 +ks06.cc, 1 +ks0618.com, 1 +ks0660.com, 1 +ks068.com, 1 +ks0788.com, 1 +ks08.cc, 1 +ks080.com, 1 +ks081.com, 1 +ks0858.com, 1 +ks086.com, 1 +ks0866.com, 1 +ks0877.com, 1 +ks0886.com, 1 +ks0888.com, 1 +ks0977.com, 1 +ks0990.com, 1 +ks1519.com, 1 +ks16.net, 1 +ks168158.net, 1 +ks17.net, 1 +ks18.cc, 1 +ks181.com, 1 +ks182.com, 1 +ks19.net, 1 +ks191.com, 1 +ks1athome.co.uk, 1 +ks202.com, 1 +ks2020.vip, 1 +ks206.com, 1 +ks208.com, 1 +ks2099.com, 1 +ks2235.com, 1 +ks2251.com, 1 +ks2375.com, 1 +ks2500.com, 1 +ks257.com, 1 +ks288.net, 1 +ks2888.com, 1 +ks298.com, 1 +ks299.com, 1 +ks299.net, 1 +ks330.com, 1 +ks335.com, 1 +ks335.net, 1 +ks337.com, 1 +ks337.net, 1 +ks339.com, 1 +ks339.net, 1 +ks35.cc, 1 +ks3533.com, 1 +ks3536.com, 1 +ks3636.com, 1 +ks3737.com, 1 +ks380.com, 1 +ks381.com, 1 +ks382.com, 1 +ks386.com, 1 +ks3888.com, 1 +ks410.com, 1 +ks5000.com, 1 +ks515.com, 1 +ks516.com, 1 +ks549.com, 1 +ks5525.com, 1 +ks5528.com, 1 +ks5529.com, 1 +ks5531.com, 1 +ks5532.com, 1 +ks56.cc, 1 +ks5660.com, 1 +ks571.com, 1 +ks5822.com, 1 +ks5888.com, 1 +ks5888.net, 1 +ks597.com, 1 +ks6225.com, 1 +ks626.com, 1 +ks628.com, 1 +ks637.com, 1 +ks641.com, 1 +ks6522.com, 1 +ks6535.com, 1 +ks657.com, 1 +ks6600.com, 1 +ks6665.com, 1 +ks668.com, 1 +ks6687.com, 1 +ks680.com, 1 +ks6808.com, 1 +ks6875.com, 1 +ks6887.com, 1 +ks79.app, 1 +ks8.net, 1 +ks8112.com, 1 +ks8113.com, 1 +ks8115.com, 1 +ks8128.com, 1 +ks8129.com, 1 +ks8135.com, 1 +ks8152.com, 1 +ks8176.com, 1 +ks8177.com, 1 +ks82.net, 1 +ks8211.com, 1 +ks8218.com, 1 +ks8225.com, 1 +ks8233.com, 1 +ks8265.com, 1 +ks8266.com, 1 +ks8278.com, 1 +ks88.com, 1 +ks8802.com, 1 +ks8805.com, 1 +ks8815.com, 1 +ks8825.com, 1 +ks883.com, 1 +ks8831.com, 1 +ks8836.com, 1 +ks8851.com, 1 +ks8862.com, 1 +ks8883.com, 1 +ks8886.com, 1 +ks89.net, 1 +ks8915.com, 1 +ks9.app, 1 +ks902.com, 1 +ks907.com, 1 +ks912.com, 1 +ks9122.com, 1 +ks920.com, 1 +ks921.com, 1 +ks96.cc, 1 +ks960.com, 1 +ks9696.com, 1 +ks9888.com, 1 +ks99.app, 1 +ksauhs-med.com, 1 +kscarlett.com, 1 +kschv-rdeck.de, 1 +kselenia.ee, 1 +ksem.tk, 1 +kseniya.tk, 1 +kseniyakoroleva.tk, 1 +ksenomorf.tk, 1 +ksero.center, 1 +ksero.wroclaw.pl, 1 +kserownia.eu, 1 +ksham.net, 1 +ksk-raduga.tk, 1 +ksm.co.in, 1 +ksoc.com, 1 +ksoftware.tk, 1 +ksopp.si, 1 +ksp-spb.com, 1 +ksradio.it, 1 +kssk.de, 1 +kst-dlvr.tk, 1 +kst-service.tk, 1 +ksu.kz, 1 +ksukelife.com, 1 +ksv-friesland.nl, 1 +ksvip02.com, 1 +ksvip09.com, 1 +kswcosmetics.com, 1 +kswork.life, 1 +kt-events.de, 1 +kt-motors.com, 1 +kt-studio.com.ua, 1 +kt-zoe.com, 1 +kt3i.com, 1 +ktbnetbank.com, 1 +ktd-design.com, 1 +kteatras.tk, 1 +kthnxbai.xyz, 1 +ktk-pc.de, 1 +ktm-troxler.de, 1 +ktmclubitalia.it, 1 +kts-thueringen.de, 1 +ktsee.eu.org, 1 +ktstreams.live, 1 +ktube.yt, 1 +ktuluweb.tk, 1 +ktw.lv, 0 +ku-7.club, 1 +ku.ag, 1 +ku.io, 0 +kuaishou.cf, 1 +kuaitiyu.org, 1 +kuaiyaojing.com, 1 +kualiti.net, 1 +kualo.co.uk, 1 +kualo.com, 1 +kualo.in, 1 +kuaza.com, 1 +kub.hr, 1 +kuba-orlik.name, 1 +kubabrussel.be, 1 +kubalok.de, 1 +kubanitoscali.com, 1 +kubeico.com, 1 +kubica.ch, 1 +kubierecki.pl, 1 +kubik-rubik.de, 1 +kubkprf.ru, 1 +kublis.ch, 1 +kubota.com.au, 1 +kubotagear.com.au, 1 +kubotapower.com.au, 1 +kubrick.tk, 1 +kubusadvocaten.nl, 1 +kuchen-am-stiel.de, 1 +kucingmania.net, 1 +kucloud.win, 1 +kucnibudzet.com, 1 +kucukayvaz.com, 0 +kucukkaymakli.tk, 1 +kuda-poexatj.ru, 1 +kudinilam.tk, 1 +kuditel.net, 1 +kudoran.tk, 1 +kuechenserver.de, 1 +kuechenserver.org, 1 +kuechler.info, 1 +kuehndel.org, 1 +kuehnel-bs.de, 0 +kuehnel-online.eu, 1 +kuemmerlin.eu, 1 +kuemmling.eu, 1 +kuepper.nrw, 1 +kuepper.tk, 1 +kuestensiegel.de, 1 +kugelblitz.co, 1 +kuhlecloud.co.za, 0 +kuhn-elektrotechnik.de, 1 +kuhne-electronic.de, 1 +kuhnerts.eu, 1 +kuisus.com, 1 +kukal.cz, 1 +kukeri-karlovo.tk, 1 +kuketz-blog.de, 1 +kuketz-security.de, 1 +kuklavrost.ru, 1 +kuko-crews.org, 1 +kukoon.de, 0 +kukutza.tk, 1 +kulde.net, 1 +kuliahbahasainggris.com, 1 +kuliahpendidikan.com, 1 +kulinarika.net, 1 +kulinaristi.fi, 1 +kulinariya.tk, 1 +kulivps.com, 1 +kulopo.com, 1 +kulp.is, 1 +kulthist.tk, 1 +kultmobil.se, 1 +kultur-werkstatt-wulfen.tk, 1 +kultur1.se, 1 +kulturistika.tk, 1 +kulturmel.ch, 1 +kumachan.biz, 1 +kumalog.com, 1 +kumaraguruparan.tk, 1 +kumasanda.jp, 1 +kumilasvegas.com, 1 +kumpulannamabayi.com, 1 +kumuwiki.de, 1 +kunaldesai.blog, 1 +kunashir.tk, 1 +kunden-webseite.de, 1 +kundenerreichen.com, 1 +kundenerreichen.de, 1 +kundenvertrag.de, 1 +kundo.se, 1 +kunra.de, 1 +kunstcentraal.nl, 1 +kunstdrucke-textildruck.de, 1 +kunsthandel-augustus-rex.de, 1 +kunstundunrat.de, 1 +kunvarji.com, 1 +kunze-medien.de, 1 +kuoruan.com, 1 +kuotiva.com, 1 +kup-sluzbu.cz, 1 +kupaa.ink, 1 +kupferschmids.ch, 1 +kupferstichshop.com, 1 +kupibilet.ru, 1 +kupid.com, 1 +kupidom2.com, 0 +kupiewszystkieauta.pl, 1 +kupil.ru, 1 +kupimlot.ru, 1 +kupinska.pl, 1 +kupipled.cf, 1 +kupislivki.tk, 1 +kupitnedorogo.com, 1 +kupleno.com, 1 +kuponmail.tk, 1 +kuponydoher.cz, 1 +kupriy-coach.ru, 1 +kupschke.net, 1 +kupsluzbu.cz, 1 +kupu.maori.nz, 1 +kuraga.org, 1 +kurashino-mall.com, 1 +kurashinohinto.com, 1 +kurd-online.tk, 1 +kurd-yogurt.tk, 1 +kurdigrafya.com, 1 +kurdishphotography.tk, 1 +kurenivka.tk, 1 +kuretru.com, 1 +kurgan-city.tk, 1 +kurgan.cf, 1 +kurgancity.cf, 1 +kurgancity.tk, 1 +kurido-anime.tk, 1 +kurierwilenski.lt, 1 +kurirplus.tk, 1 +kurition.eu, 1 +kuritsa.tk, 1 +kurniadwin.to, 1 +kurniasihmandiri.com, 1 +kurofuku.me, 1 +kuroha.co.uk, 1 +kuroinu.jp, 1 +kuroisalva.xyz, 0 +kurona.ga, 1 +kuronekogaro.com, 1 +kuropatina.tk, 1 +kurrende.nrw, 0 +kurschies.de, 1 +kurserne.dk, 1 +kursk.cf, 1 +kurspmr.ru, 1 +kurssertifikasi.com, 1 +kurswahl-online.de, 1 +kursyjezykowelublin.pl, 1 +kursypolska.pl, 1 +kurszielnull.de, 1 +kurtschlatzer.com, 0 +kurungkurawal.id, 1 +kuruppa.xyz, 1 +kurz.pw, 1 +kusasa.biz, 1 +kuscheln.com, 1 +kuschku.de, 1 +kuscu.de, 1 +kusdaryanto.web.id, 1 +kushfest.com, 1 +kushfest.net, 1 +kushner-cpa.co.il, 0 +kushtikidsparties.co.uk, 1 +kushwanthreddy.com, 1 +kuslink.tk, 1 +kusochi.eu, 1 +kustarnik.tk, 1 +kustod.io, 1 +kustom-kitchens.com, 1 +kustosija.tk, 1 +kustvissen.tk, 1 +kutaisi.it, 1 +kutalek.cz, 1 +kutamo.com, 1 +kutekeiki.com, 1 +kutinsoft.com, 1 +kutsankaplan.com, 1 +kutus.ee, 1 +kutvonen.net, 1 +kuvera.in, 1 +kuwago.io, 1 +kuwichitagastro.com, 1 +kuwichitaim.com, 1 +kuzbass-pwl.ru, 1 +kuzelky-cb.cz, 1 +kuzik.tk, 1 +kuzinea.tk, 1 +kuzmik.net, 1 +kuzmik.org, 1 +kuzmiks.com, 1 +kuznica.tk, 1 +kuzov-plus.tk, 1 +kv-genebos.tk, 1 +kvadratnimeter.si, 1 +kvadru.cz, 1 +kvalitetsaktiepodden.se, 1 +kvalitnitesneni.cz, 1 +kvarta.tk, 1 +kvartira-grad.tk, 1 +kvartiragrad.tk, 1 +kvcc.com.au, 1 +kvdekolk.tk, 1 +kvest-v-moskve.ga, 1 +kvestiks.ru, 1 +kvetinymilt.cz, 1 +kvetinyumarkety.cz, 1 +kvhile.com, 1 +kvhv-brussel.be, 1 +kvhv.brussels, 1 +kvilt.dk, 1 +kviskoteka.tk, 1 +kvmcloud.net, 0 +kvn.tf, 1 +kvnsport.ru, 1 +kvpc.com.au, 1 +kvsrot.cz, 1 +kvt.berlin, 0 +kw.gt, 1 +kwadraadtevredenheid.nl, 1 +kwat.chat, 1 +kwbresidential.com, 1 +kwcolville.com, 1 +kweb.ml, 1 +kwedo.com, 1 +kwench.com, 1 +kwieben.com, 1 +kwik.cx, 1 +kwikkargreenville.com, 1 +kwikkarkave.com, 1 +kwikkarofmesquite.com, 1 +kwikkarrichardson.com, 1 +kwikmed.eu, 0 +kwoll.de, 1 +kwonghei.net, 1 +kwork-garand.tk, 1 +kwx.gg, 1 +kwyxz.org, 1 +kx197.com, 1 +kxah35.com, 1 +kxnrl.com, 1 +ky.rs, 1 +kyberna.xyz, 1 +kybi.sk, 1 +kycisrael.com, 1 +kydara.com, 1 +kyj22.com, 1 +kyj250.com, 1 +kyj322.com, 1 +kyj33.com, 1 +kyj35.com, 1 +kyj36.com, 1 +kyj369.com, 1 +kyj4.com, 1 +kyj44.com, 1 +kyj511.com, 1 +kyj522.com, 1 +kyj544.com, 1 +kyj55.com, 1 +kyj56.com, 1 +kyj566.com, 1 +kyj57.com, 1 +kyj577.com, 1 +kyj59.com, 1 +kyj599.com, 1 +kyj622.com, 1 +kyj633.com, 1 +kyj644.com, 1 +kyj65.com, 1 +kyj655.com, 1 +kyj67.com, 1 +kyj677.com, 1 +kyj76.com, 1 +kylby.com, 1 +kyle-s.com, 1 +kyle.place, 1 +kylebaldw.in, 0 +kyledrake.net, 1 +kylefennell.blog, 1 +kylegutschow.com, 1 +kylehaka.la, 1 +kylehakala.com, 1 +kylejohnson.io, 1 +kylepet.co, 1 +kylese.com, 1 +kylianvermeulen.com, 1 +kylianvermeulen.nl, 1 +kylie-pomada.tk, 1 +kylinj.com, 0 +kyn.be, 1 +kynaston.org.uk, 1 +kynastonwedding.co.uk, 1 +kynd.com.au, 1 +kyobostory-events.com, 1 +kyochon.fr, 1 +kyoko.org, 1 +kyosaku.org, 1 +kyosyo-jungle.com, 1 +kyoto-sake.net, 1 +kyoto-tomoshibi.jp, 1 +kyprexxo.com, 1 +kypride.com, 1 +kyras-castles.co.uk, 1 +kyrgizion.tk, 1 +kyriakidisship.gr, 1 +kyrylych.tk, 1 +kys.host, 1 +kysil.org, 1 +kysounds.com, 1 +kysseo.fr, 1 +kyujin-office.net, 1 +kyunyuki.com, 1 +kyusyu.org, 1 +kyy.me, 0 +kyzyl-senir.ml, 1 +kz.search.yahoo.com, 0 +kzar.co.uk, 1 +kzmhk.cz, 1 +kzsdabas.hu, 1 +l-atelier-c.com, 1 +l-lab.org, 1 +l-poya.ch, 1 +l0re.com, 1 +l10n.site, 1 +l17r.eu, 1 +l18.io, 1 +l2.ai, 1 +l214.com, 1 +l2guru.ru, 1 +l2l.vn, 1 +l2p.lol, 1 +l2relax.ml, 1 +l3.ee, 1 +l30365.com, 1 +l33te.net, 1 +l36533.com, 1 +l4s.me, 1 +l51365.com, 1 +l5197.co, 1 +l66.io, 1 +l6729.co, 1 +l6729.com, 1 +l6957.co, 1 +l7plumbing.com.au, 1 +l7world.com, 1 +l81365.com, 1 +l82365.com, 1 +l9297.co, 1 +l9297.com, 1 +l9397.com, 1 +l9721.com, 1 +l9728.co, 1 +la-baldosa.fr, 0 +la-bolle.fr, 0 +la-buns.com, 1 +la-clairiere-arlon.be, 1 +la-compagnie-des-elfes.fr, 1 +la-fenice-neheim.de, 1 +la-kaz-a-velo.fr, 1 +la-laitonnerie.com, 1 +la-maison.ch, 0 +la-maison.eu, 1 +la-manufacture-du-nettoyage.com, 1 +la-paco.tk, 1 +la-tourmaline.ch, 1 +la-verite.tk, 1 +la-ville-aux-dames-auto-ecole.com, 1 +la-vraie-histoire.fr, 1 +laab.gv.at, 1 +laac.io, 1 +laanius.dk, 1 +laarroceriacolombiana.com, 1 +laassari.me, 0 +laatikko.io, 1 +laatjeniethackmaken.nl, 1 +lab-advancedservicesportal.com, 1 +labacanisima.tk, 1 +labadusa.com, 1 +labambi.pl, 1 +labandadelamente.tk, 1 +labandadelexpreso.tk, 1 +labande-annonce.fr, 1 +labanochjonas.se, 1 +labanote.com, 1 +labanskoller.se, 1 +labanskollermark.se, 1 +labassist.lt, 1 +labastidedesaromes.com, 0 +labavn.com, 1 +labavn.org, 1 +labcenter.com, 1 +labcoat.jp, 1 +label-octopus.org, 1 +labeled.vn, 1 +labelfactory.nl, 1 +labequipvn.com, 1 +labiblioafronebrulepas.com, 0 +labirint.cf, 1 +lablic-beta.work, 1 +lablnet.tk, 1 +labmarket-eg.com, 0 +labms.com.au, 1 +labobooks.com, 1 +laboiteanem.fr, 1 +laboiteasous.com, 1 +laboratoriodemarketingb3.com, 1 +laboratoriomolina.tk, 1 +laborriquita.tk, 1 +labortogether.com, 1 +labouncycastlehire.co.uk, 1 +labourreedevergheas.fr, 1 +laboutiquedejuliette.com, 1 +laboutiquemarocaineduconvoyeur.com, 1 +laboutiquemarocaineduconvoyeur.ma, 1 +laboxfaitsoncinema.com, 1 +labrat.mobi, 0 +labroma.tk, 1 +labs-is.com, 1 +labs.ro, 1 +labsender.com, 1 +labsitserviss.lv, 1 +labsys.xyz, 1 +labtalleraudiovisual.tk, 1 +labtest.ltd, 1 +labussola.site, 1 +labworks.com, 0 +labworks.org, 1 +laby.link, 1 +laby.me, 1 +labyrinth-technologies.com, 1 +lacaey.se, 1 +lacalderera.tk, 1 +lacallas.tk, 1 +lacantine.xyz, 1 +lacarniceria.tk, 1 +lacasa.fr, 1 +lacasadelmaniqui.net, 1 +lacasadelours.fr, 1 +lacaserita.org, 1 +lacasseroy.com, 1 +lacatta.com, 1 +lacatta.es, 1 +lacaveducinquantenaire.com, 1 +lacazadora.tk, 1 +laceleste.it, 1 +lacentral.com, 0 +lacetsfun.com, 1 +lacetsroses.ch, 1 +laceysfarm.ie, 1 +lachainedesentrepreneurs.fr, 1 +lachlan-harris.com, 1 +lachlan.com, 1 +lachlanallison.com, 0 +lachyoga-schwieberdingen.de, 1 +laciana.tk, 1 +lacicloud.net, 1 +lacigognedelily.com, 1 +lackan.tk, 1 +lackierereischmitt.de, 1 +laclaque.ch, 0 +lacledelareussite.com, 0 +lacledeslan.com, 1 +lacledeslan.org, 1 +lacledor.ch, 0 +laclefdor.ch, 0 +lacnesidlo.sk, 1 +lacoast.gov, 1 +lacoccinelle.net, 1 +lacochinacounselor.com, 1 +lacocina.nl, 1 +lacocinadelila.com, 1 +lacoquette.gr, 1 +lacoste.net, 1 +lacuerba.com, 1 +lacuna-vermoegen.de, 1 +lacyc3.eu, 1 +lad-china.com, 0 +lada-event.com.ua, 1 +lada-granta.tk, 1 +lada-plus.tk, 1 +ladadate.com, 1 +ladakhtrip.tours, 1 +ladanivabelgium.tk, 1 +ladanmokhtari.tk, 1 +ladbroke.net, 0 +ladedu.com, 1 +ladelicateparenthese.com, 1 +ladenzeile.at, 1 +ladenzeile.de, 1 +ladies-shoes.tk, 1 +ladiescode.tk, 1 +ladiesofvietnam.net, 1 +ladiesrapide.tk, 1 +ladige.it, 1 +ladisko.tk, 1 +ladislavbrezovnik.com, 1 +lado.ltd, 1 +lado.site, 1 +ladocdn.com, 1 +ladocs.tk, 1 +ladocu.cf, 1 +ladotech.cn, 1 +ladotech.com, 1 +ladraiglaan.com, 1 +ladrilleraeldiamante.co, 1 +ladrones.tk, 1 +lady-blog.ga, 1 +lady-len.com, 1 +lady-wishlist.my.id, 1 +ladyanna.de, 1 +ladybirdeducation.co.uk, 1 +ladybugjam.com, 1 +ladyjanitor.com, 1 +ladyklub.ru, 1 +ladyleeshome.com, 1 +ladylikeit.com, 1 +ladymakeup.com.ua, 1 +ladymakeup.eu, 1 +ladymakeup.ru, 1 +ladymayonline.tk, 1 +ladyofhopeparish.org, 1 +ladyofsongstv.com, 1 +ladysecrets.cf, 1 +ladysecrets.ga, 1 +ladytron.tk, 1 +ladywishlist.my.id, 1 +laembajadamexico.com, 1 +laemen.com, 0 +laemen.nl, 0 +laemiliafutbol.tk, 1 +laencina.tk, 1 +laermschmiede.de, 1 +laesisvefurinn.is, 1 +laextra.mx, 1 +lafamiliallc.com, 1 +lafansite.tk, 1 +lafayette-rushford.com, 1 +lafayetteco.gov, 1 +lafeemam.fr, 1 +lafema.de, 1 +lafermegourmande.fr, 1 +lafillepolyvalente.ca, 1 +lafillepolyvalente.com, 1 +lafka.org, 1 +laflanelle.fr, 1 +laflash.com, 1 +lafr4nc3.xyz, 1 +lafsc.co.uk, 1 +lafyne.eu, 1 +lag-fan.tk, 1 +lag-gbr.gq, 1 +lagaia.com.br, 1 +lagaleria-ag.com, 1 +lagavach.com, 1 +lagazzettadigitale.it, 1 +lagendijk.org, 1 +lagerauftrag.info, 1 +lagier.xyz, 1 +lagin.cz, 1 +laginghanda.gov.ph, 1 +lagit.in, 1 +laglab.org, 0 +lagloriadehuampani.com, 1 +lagodny.eu, 1 +lagoonrealty.com, 1 +lagout.org, 1 +lagracia.com.br, 1 +lagrange.cloud, 1 +lagranmasade.info, 0 +lagriffeduservice.fr, 1 +lagriot.com, 1 +lagrotta.pizza, 1 +lagsoftware.com, 1 +laguiadelocioenuruguay.com, 1 +laguiadelpapa.com, 1 +laguinguette.fr, 1 +lagunakitchenandbath.com, 1 +lagunaklub.tk, 1 +laguterbaru.gq, 1 +lahacker.net, 1 +laharilais.fr, 1 +lahipotesisgaia.com, 1 +lahirusblog.tk, 1 +lahmer.ma, 1 +lahora.com.ec, 1 +lai.is, 1 +lai.zone, 1 +laibcoms.com, 1 +lailabanx.org, 1 +lain.at, 1 +lain.wiki, 1 +laindonleisure.co.uk, 1 +laity.gq, 1 +laizhongliuxue.com, 1 +lajarana.tk, 1 +lajas.com.ve, 1 +lajauria.tk, 1 +lajessica.com, 1 +lajijonencadebarbera.com, 1 +lajme-shqip.gq, 1 +lajornadafilipina.com, 1 +lak-berlin.de, 1 +lakatrop.com, 1 +lake-baikal.ml, 1 +lake-bonavista.ca, 1 +lakeandriverrestoration.com, 1 +lakeclerkfl.gov, 1 +lakecountyclerkfl.gov, 1 +lakedavid.com.au, 1 +lakeee.com, 1 +lakehavasucitynews.com, 1 +lakehavasuhouserentals.com, 1 +lakehavasuwebsites.com, 1 +lakelandbank.com, 1 +lakemacquariecashforcars.com.au, 1 +lakeoswegotowncar.com, 1 +lakersview.com, 1 +lakesherwoodelectric.com, 1 +lakesherwoodelectrical.com, 1 +lakesherwoodelectrician.com, 1 +lakesherwoodexteriorlighting.com, 1 +lakesherwoodlandscapelighting.com, 1 +lakesherwoodlighting.com, 1 +lakesherwoodoutdoorlighting.com, 1 +lakeshorepoolsandtubs.com, 1 +lakeshowlife.com, 1 +lakestreetministorage.com, 1 +lakeview.photography, 1 +lakevotes.gov, 1 +lakewinnipegdatastream.ca, 1 +lakewoodcityglass.com, 1 +lakewoodcomputerservices.com, 1 +lakewylietax.com, 1 +lakichat.fi, 1 +lakiernictwo.auto.pl, 1 +lakkt.de, 1 +lakonia.com.br, 1 +lakorona.tk, 1 +lakspuiterijmosman.nl, 1 +lalagunachalate.tk, 1 +lalalab.com, 1 +lalaloe.be, 1 +lalaserniagara.ca, 1 +lalaya.fr, 1 +laled.ch, 0 +lalegria.tk, 1 +laleli.biz, 1 +lallybroch.com.au, 1 +lalucepulsata.it, 1 +lalucioledigitale.com, 1 +lalyre-corcelles.ch, 0 +lamafioso.com, 1 +lamai-crochets.fr, 1 +lamaisonfantastique.fr, 1 +lamakat.de, 1 +lamalapalabra.tk, 1 +lamaletarural.es, 1 +lamaline.tk, 1 +lamalleauxsaveurs-aubigny.com, 1 +lamanufacturedebaches.fr, 1 +lamargheritalruoto.it, 1 +lamarieealhonneur.com, 0 +lamasacre.tk, 1 +lamaturitadidaniele.ml, 1 +lambauer.com, 1 +lambda.dance, 1 +lambda.sx, 1 +lambdaof.xyz, 1 +lambertshealthcare.co.uk, 1 +lambertz.xyz, 1 +lamboo.be, 1 +lamchannang.com, 1 +lamconnect.com, 1 +lamdav.com, 1 +lamei-group.com, 1 +lamergameryt.xyz, 1 +lamet-kher.tk, 1 +lamikvah.org, 1 +laminine.info, 1 +laminsaho.tk, 1 +lamiradaacr.com, 1 +lamisionband.tk, 1 +lammersmarketing.com, 1 +lammertbies.com, 1 +lammertbies.nl, 1 +lamnea.se, 1 +lamnhom.com.vn, 1 +lamontre.ru, 1 +lamorralla.tk, 1 +lamp.re, 0 +lamp24.se, 1 +lampade.it, 1 +lampara.es, 1 +lampbooks.gq, 1 +lampco.com, 1 +lampegiganten.dk, 1 +lampegiganten.no, 1 +lampen24.be, 1 +lampen24.nl, 1 +lampenwelt.at, 1 +lampenwelt.ch, 1 +lampenwelt.de, 1 +lamper-design.nl, 1 +lampl.info, 0 +lampposthomeschool.com, 1 +lamppostpublishing.com, 1 +lampsh.ml, 1 +lampy.pl, 1 +lamujerquesoy.com, 0 +lan-der.de, 1 +lan-der.net, 1 +lan-divy.com, 1 +lan-divy.fr, 1 +lan.biz.tr, 1 +lan4.life, 1 +lana.swedbank.se, 1 +lanabello.com.br, 1 +lanaengel.com, 1 +lanahallen.com, 1 +lanasomething.com, 1 +lanaturedaure.com, 1 +lanbroa.eu, 1 +lancashirecca.org.uk, 1 +lancea.pl, 1 +lancejames.com, 1 +lancelafontaine.com, 1 +lancelhoff.com, 1 +lancemanion.com, 1 +lancers.jp, 1 +lanceyip.com, 1 +lanchong.tk, 1 +lancyvbc.ch, 0 +land.nrw, 0 +landassessmentservices.com, 1 +landbetweenthelakes.us, 1 +landchecker.com.au, 1 +landell.ml, 1 +landflair-magazin.de, 1 +landforsale.co.il, 1 +landinfo.no, 1 +landing-phillipferreira.herokuapp.com, 1 +landingear.com, 1 +landloperfm.tk, 1 +landlordy.com, 1 +landofelves.net, 0 +landofmerlin.tk, 1 +landofoz.dynu.net, 1 +landoftherisingson.com, 1 +landoncreekapartments.com, 1 +landoverhillsmd.gov, 1 +landsbref.is, 1 +landscape-photography.org, 1 +landscapelightingagoura.com, 1 +landscapelightingagourahills.com, 1 +landscapelightingcalabasas.com, 1 +landscapelightingcamarillo.com, 1 +landscapelightingconejovalley.com, 1 +landscapelightingdosvientos.com, 1 +landscapelightinghiddenhills.com, 1 +landscapelightinglakesherwood.com, 1 +landscapelightingmalibu.com, 1 +landscapelightingmoorpark.com, 1 +landscapelightingnewburypark.com, 1 +landscapelightingoakpark.com, 1 +landscapelightingpacificpalisades.com, 1 +landscapelightingsimivalley.com, 1 +landscapelightingthousandoaks.com, 1 +landscapelightingwestlakevillage.com, 1 +landscapephotography.org.au, 1 +landscaping-montreal.com, 1 +landscaping.gq, 1 +landsforsale.co.il, 1 +landslide.tk, 1 +landtrack.com.au, 1 +landware.cf, 1 +landyhome-register.com, 1 +landyparts.nl, 1 +lanekoll.se, 1 +lanetix.com, 1 +lanforalla.se, 1 +lang-php.com, 1 +langadeduero.tk, 1 +langages-programmation.tk, 1 +langapi.com, 1 +langatang.com, 1 +langbein.org, 1 +langduytinh.com, 1 +langgasse-baar.ch, 1 +langhof-immobilien.de, 1 +langhun.me, 1 +langjp.com, 0 +langleyporter.com, 1 +langly.fr, 1 +langotie.com.br, 1 +langrock.info, 1 +langsam-dator.se, 1 +langstreckensaufen.de, 1 +languageatplay.de, 1 +languagecourse.net, 1 +languageterminal.com, 1 +langworth.com, 1 +langzijn.nl, 1 +lanhhuyet510.tk, 1 +lankana.tk, 1 +lankarkivet.tk, 1 +lanna.io, 1 +lannainnovation.com, 1 +lannamontessori.com, 1 +lannatefl.com, 1 +lanny.ga, 1 +lanodan.eu, 1 +lanostrasalute.it, 1 +lanoticia.com, 1 +lanparty.si, 1 +lanre.org, 1 +lanroamer.de, 1 +lansechensilu.com, 1 +lanselot.com, 1 +lansewu.com, 0 +lansilesia.tf, 1 +lansing.ninja, 1 +lansink.it, 1 +lansoft.site, 1 +lansoftware.eu, 1 +lantern.digital, 1 +lanternalauth.com, 1 +lanternhealth.org, 1 +lanthanum.me, 1 +lantian.pub, 1 +lanturtle.com, 1 +lanuovariviera.it, 1 +lanyang.tk, 1 +lanyards.com.au, 1 +lanzalex.com, 1 +lanzamientovirtual.es, 1 +lanziego.com, 1 +laobayy.com, 1 +laodongkynghi.info, 1 +laolaweb.tk, 1 +laoliang.ml, 1 +laoriginalfm.com, 1 +laos.dating, 1 +laospage.com, 1 +laoudit.com, 1 +laozhu.me, 1 +lapageamelkor.org, 1 +lapaksulawesi.tk, 1 +lapakus.com, 1 +laparoscopyhospital.com, 1 +lapassiondutrading.com, 0 +lapatio.dk, 1 +lapazsheriff.org, 1 +lapcameradongnai.com, 1 +lapcamerahochiminh.com, 1 +lapdance.tk, 1 +laperfumista.es, 1 +laperla-chemnitz.de, 1 +laperladelduero.tk, 1 +lapetition.be, 1 +lapicena.eu, 1 +lapidge.net, 1 +lapinator.net, 1 +lapismagico.com, 1 +laplacesicherheit.de, 1 +laplanetebleue.com, 1 +lapluma.tk, 1 +lapnest.in, 1 +lapolla.com, 1 +lapolvora.ga, 1 +laportedufutur.org, 1 +lapotagere.ch, 0 +lapparente-aise.ch, 0 +lappari.com, 0 +lappersfort.tk, 1 +lapps.es, 1 +laprensadelasagradafamilia.org, 1 +lapseofsanity.net, 1 +lapshore.com, 1 +laptopcloseout.ca, 1 +laptopdropoff.com, 1 +laptopnewbie.eu.org, 1 +lapulgaflamenco.com, 1 +laqueuedevache.be, 1 +lara.photography, 1 +larabergmann.de, 1 +laracode.eu, 1 +laracumkitten.org, 1 +laradiorespuestas.tk, 1 +laraeph.com, 1 +laramewa.tk, 1 +laranara.se, 1 +laranjada.org, 1 +larasm.tk, 1 +laravelcommunity.asia, 1 +laraveldirectory.com, 1 +larawoodarts.com, 1 +larbertbaptist.org, 1 +larch.gq, 1 +larch.me, 1 +lareclame.fr, 1 +lareduction.be, 1 +lareduction.ch, 1 +lareduction.fr, 1 +lareginetta.com, 1 +larenas.com, 1 +larepublicacultural.es, 1 +laresistencia.xyz, 0 +larete.ch, 1 +largeandhighquality.com, 1 +largescaleforums.com, 1 +largest-soldiers.cf, 1 +largeviewer.com, 1 +larifari.ch, 1 +larimarhomes.ca, 1 +larimercolorado.gq, 1 +lariscus.eu, 1 +lark.pw, 1 +larmenta.tk, 1 +larobba.ddns.net, 1 +laromlab.tk, 1 +larondenet.tk, 1 +larondinedisinfestazione.com, 1 +larosadelosvientos.tk, 1 +larousse-edu.fr, 1 +larpkalender.ch, 1 +larplibrary.org, 1 +larptreff.de, 1 +larraz.es, 1 +larrutan.shop, 1 +larry.buzz, 1 +larryandprisca.it, 1 +larryklug.com, 1 +larryli.cn, 1 +larrysalibra.com, 1 +lars-kusch.de, 1 +lars-mense.de, 1 +lars-mielke.de, 1 +lars-minecraft.de, 1 +lars.cloud, 1 +lars.moi, 1 +larsentransfer.com, 1 +larser.tk, 1 +larseriksson.es, 1 +larsi.org, 1 +larsklene.nl, 1 +larsklint.com, 1 +larsmerke.de, 1 +larsnittve.tk, 1 +lartduportrait.fr, 1 +larvps.com, 1 +las.so, 1 +lasabina.it, 1 +lasabubillas.es, 1 +lasalle.wa.edu.au, 1 +lasandwicheriamedellin.com, 1 +lasarmas.com, 1 +lasavonnerieducroisic.fr, 1 +lascana.co.uk, 1 +lascandalistas.org, 1 +lasdelgadas.tk, 1 +lasept.com.ua, 1 +laser-jeux.com, 1 +laser-toners.tk, 1 +lasercareestetica.com.br, 1 +lasercloud.ml, 1 +laserena.tk, 1 +lasereyess.net, 1 +laserhealthsolutions.com, 1 +laserpc.net, 1 +laserplaza.de, 1 +laserplaza.net, 1 +lasersandbacon.com, 1 +lasersolutions.tk, 1 +lasertechsolutions.com, 1 +lasittellecosmetiques.com, 1 +lasix-medication.cf, 1 +lask.in, 1 +laskas.pl, 1 +lasmesas.tk, 1 +lasmoarquitectos.com, 1 +lasmorfianapoletana.com, 1 +lasourisglobe-trotteuse.tk, 1 +laspeligrosas.tk, 1 +laspeludas.tk, 1 +laspequenassemillas.com, 1 +lasranas.es, 1 +lasrecetascocina.com, 1 +lasrecetasdeguada.com, 1 +lasse-it.dk, 0 +lasseaktiv.es, 1 +lasseleegaard.com, 1 +lasseleegaard.dk, 1 +lasseleegaard.net, 1 +lasseleegaard.org, 1 +lassemakela.fi, 1 +lassesworld.com, 1 +lassesworld.se, 1 +lassovideos.com, 1 +lasst-uns-beten.de, 1 +last-strike.org, 1 +lastbooks.gq, 1 +lastingsmiles.org, 1 +lastmile.ml, 1 +lastmohicans.tk, 1 +lastorder.icu, 1 +lastpass.com, 0 +lastrik.ch, 1 +lastrourbanismo.com.br, 1 +lastsunset.tk, 1 +lasuzefc.fr, 1 +lasvegascasinonews.com, 1 +lasvegasgfegirls.com, 1 +lat.sk, 1 +lat46.ch, 0 +latabaccheria.net, 1 +latabledebry.be, 1 +latabledemontebello.com, 1 +latanadelpolpo.it, 1 +latardeurbana.cf, 1 +latardeurbana.ga, 1 +latardeurbana.gq, 1 +latardeurbana.ml, 1 +latardeurbana.tk, 1 +latchplus.com, 1 +latdor.com, 1 +late.am, 0 +latecnosfera.com, 1 +latedeals.co.uk, 1 +lateliercantaldeco.fr, 1 +laten.tk, 1 +latenitefilms.com, 0 +lateral.dog, 1 +lateralsecurity.com, 1 +laterremotodealcorcon.tk, 1 +latestairfaredeals.com, 1 +latestbitcoinnews.io, 1 +latestcoin.tk, 1 +latestdeals.co.uk, 1 +latestimmigrationnews.today, 1 +latestmata.com, 1 +latestmyanmarnews.com, 1 +latetrain.cn, 1 +lathamlabs.com, 1 +lathamlabs.net, 1 +lathamlabs.org, 1 +latia.tk, 1 +latiamona.com, 1 +latiendauno.com, 0 +latiendawapa.com, 1 +latinmusiccollection.tk, 1 +latino.dating, 1 +latinphone.com, 1 +latinred.com, 1 +latitudesign.com, 0 +latka.tk, 1 +latour-managedcare.ch, 1 +latremebunda.com, 1 +latrynchera.tk, 1 +lattyware.co.uk, 1 +lattyware.com, 1 +latviaonline.tk, 1 +latvijashipoteka.lv, 1 +laubacher.io, 1 +laube-school.com, 1 +laubo.tk, 1 +lauchundei.at, 1 +laud.io, 1 +laudableapps.com, 1 +laudablesites.com, 1 +laudlab.de, 1 +laudon.nl, 1 +laudwein.fr, 1 +laudworks.de, 1 +lauensteiner.de, 0 +laufpix.de, 1 +lauftreff-himmelgeist.de, 0 +laughinggrapepublishing.com, 1 +laughingloon.com, 1 +laukstein.com, 1 +launch-subtitle.com, 1 +launcher-minecraft.com, 1 +launchgroup.com.au, 1 +launchingsuccess.com, 1 +launchmylifend.com, 1 +launchpad-app2.com, 1 +launchpadder2.com, 1 +launchyourcareer.com, 1 +laundrydidi.com, 1 +laura.network, 1 +lauraandwill.wedding, 0 +laurabailo.com, 1 +laurable.com, 1 +lauraenvoyage.fr, 1 +laurahausmann.de, 1 +laurainnes.tk, 1 +laurakashiwase.com, 1 +lauralinde.de, 1 +lauraofrank.com, 1 +lauraohagan.com, 1 +laurasplacefamilysupport.org.au, 1 +lauravaindumentaria.com, 1 +laureaty.tk, 1 +laurelblack.com, 1 +laurelcountycorrectionsky.gov, 1 +laurenball.com, 1 +laurencball.com, 1 +laurenceplouffe.com, 1 +laurenlobue.com, 1 +laurensvanderblom.nl, 1 +lauresta.lt, 1 +lauresta.lv, 1 +lauriemilne.com, 1 +laurineprice.com, 1 +lauriuc.sk, 1 +lausannedentiste.ch, 0 +lausannelovers.ch, 0 +laussat.de, 1 +laut.digital, 1 +lautremode.com, 1 +lauxzahnheilkunde.de, 1 +lauzon-hitter.com, 1 +lavabit.com, 1 +lavabit.no, 1 +lavaccount.ru, 1 +lavaggista.it, 1 +lavalon.tk, 1 +lavamine.tk, 1 +lavamob.com, 1 +lavanderia.roma.it, 1 +lavarex.co.jp, 1 +lavasing.eu.org, 1 +lavaux.lv, 0 +lavenderx.org, 1 +laventura.tk, 1 +laveriebyk.com, 1 +lavhire.tk, 1 +laviedalex.ovh, 1 +lavinaec.com, 1 +lavinde.com, 1 +lavinya.net, 1 +laviro.tk, 1 +lavita.de, 1 +lavitagarden.tk, 1 +lavka.cf, 1 +lavki.tk, 1 +lavocedelviolino.it, 1 +lavochka.tk, 1 +lavoieducoeur.be, 1 +lavoiepharmd.com, 1 +lavolte.net, 0 +lavoniaga.gov, 1 +lavozdelamusicachilena.tk, 1 +lavril.fr, 1 +lavval.com, 0 +law-colleges.com, 1 +law-iku.pro, 1 +law-peters.de, 1 +law-profile.com, 1 +law-zur.co.il, 1 +law.co.il, 1 +law22.com, 1 +lawabidingcactus.com, 1 +lawcer.com, 1 +lawda.ml, 1 +lawebnobasta.tk, 1 +lawhery.com, 1 +lawlessenglish.com, 1 +lawlessfrench.com, 1 +lawlessitalian.com, 1 +lawlessrepublic.com, 1 +lawlessspanish.com, 1 +lawluxury.com, 1 +lawn-seeds.com, 1 +lawncorner.com, 1 +lawnuk.com, 1 +lawportal.com.ua, 1 +lawrad.com, 1 +lawrenca.com, 1 +lawrence-institute.com, 1 +lawrenceberg.nl, 1 +lawrenceclarkemd.com, 1 +lawrencecountyboe-ohio.gov, 1 +lawrenceklepinger.com, 1 +lawrencemurgatroyd.com, 1 +lawrencewhiteside.com, 1 +lawsoner.tk, 1 +lawtap.com, 1 +lawtreeclub.com, 1 +lawvize.com, 1 +lawyer.cf, 1 +lawyerboksburg.co.za, 1 +lawyerdigital.co.bw, 1 +lawyermidrand.co.za, 1 +lawyersofmissouri.com, 1 +lawzakon.tk, 1 +lawzana.com, 1 +lawzava.com, 1 +laxaf.com, 1 +laxxl.com, 1 +layan-luxurylighting.com, 1 +layazc.com, 1 +layermesh.net, 1 +layermesh.se, 1 +layers.media, 1 +layflamso.tk, 1 +laylo.io, 1 +laymans911.info, 1 +layordesign.co.uk, 1 +layoutsatzunddruck.de, 1 +laythetable.com, 1 +lazell.de, 1 +lazer.cf, 1 +lazerengravingpros.com, 1 +lazerus.net, 1 +lazerus.pw, 1 +lazibeach.tk, 1 +lazistance.com, 1 +laziz24.com, 0 +lazo.futbol, 1 +lazonacartagena.tk, 1 +lazosamericaunida.org, 1 +lazoscollection.com, 1 +lazowik.pl, 1 +lazownik.pl, 1 +lazudi.com, 1 +lazulu.com, 1 +lazurit.com, 1 +lazyboston.com, 1 +lazyframe.com, 1 +lazyhelp.com, 1 +lazysoftware.fr, 1 +lazytux.org, 1 +lazywaves.tk, 1 +lazzzy.com, 1 +lb-music.tk, 1 +lb-toner.de, 1 +lb366.cc, 1 +lb369.cc, 1 +lbarrios.es, 1 +lbayer.com, 1 +lbc-podcast.tk, 1 +lbc.gr, 1 +lbda.net, 1 +lbet365.com, 1 +lbihrhelpdesk.com, 1 +lbjlibrary.gov, 1 +lbls.me, 0 +lbph.org, 1 +lbphacker.pw, 1 +lbrlh.tk, 1 +lbrli.tk, 1 +lbrls.tk, 1 +lbs-logics.com, 1 +lbsgroup.co.uk, 1 +lbt-russia.ru, 1 +lbux.org, 1 +lc-8.com, 1 +lc-cs.com, 0 +lc-promiss.de, 1 +lc-suites.gr, 1 +lc08080.com, 1 +lc10086.com, 1 +lc1588.com, 1 +lc18.vip, 1 +lc1818.com, 1 +lc1818.net, 1 +lc3708.com, 1 +lc3710.com, 1 +lc3711.com, 1 +lc3714.com, 1 +lc3715.com, 1 +lc3716.com, 1 +lc3717.com, 1 +lc3720.com, 1 +lc3723.com, 1 +lc3726.com, 1 +lc3729.com, 1 +lc3731.com, 1 +lc3732.com, 1 +lc3733.com, 1 +lc3736.com, 1 +lc3738.com, 1 +lc3739.com, 1 +lc3741.com, 1 +lc3742.com, 1 +lc3743.com, 1 +lc3744.com, 1 +lc3745.com, 1 +lc3751.com, 1 +lc3757.com, 1 +lc3759.com, 1 +lc3760.com, 1 +lc3763.com, 1 +lc3772.com, 1 +lc3776.com, 1 +lc3778.com, 1 +lc3779.com, 1 +lc3780.com, 1 +lc3781.com, 1 +lc3782.com, 1 +lc3783.com, 1 +lc3793.com, 1 +lc3794.com, 1 +lc3795.com, 1 +lc3798.com, 1 +lc3799.com, 1 +lc3801.com, 1 +lc3802.com, 1 +lc460.com, 1 +lc50000.com, 1 +lc5188.net, 1 +lc530.com, 1 +lc555.net, 1 +lc58588.com, 1 +lc5998.com, 1 +lc6.fun, 1 +lc60000.com, 1 +lc6686.com, 1 +lc6698.com, 1 +lc68.net, 1 +lc68693.com, 1 +lc68694.com, 1 +lc68696.com, 1 +lc68699.com, 1 +lc68884.com, 1 +lc7.fun, 1 +lc8.com, 1 +lc8.fun, 1 +lc8.life, 1 +lc80000.com, 1 +lc80801.com, 1 +lc80802.com, 1 +lc80803.com, 1 +lc80804.com, 1 +lc80805.com, 1 +lc80806.com, 1 +lc80807.com, 1 +lc80808.com, 1 +lc80809.com, 1 +lc80810.com, 1 +lc80811.com, 1 +lc80812.com, 1 +lc80813.com, 1 +lc80814.com, 1 +lc80815.com, 1 +lc80816.com, 1 +lc80817.com, 1 +lc80818.com, 1 +lc80819.com, 1 +lc80820.com, 1 +lc818.net, 1 +lc859.com, 1 +lc861.com, 1 +lc862.com, 1 +lc863.com, 1 +lc865.com, 1 +lc869.com, 1 +lc871.com, 1 +lc873.com, 1 +lc875.com, 1 +lc876.com, 1 +lc879.com, 1 +lc88.fun, 1 +lc8812.com, 1 +lc8820.com, 1 +lc8838.com, 1 +lc8839.com, 1 +lc8866.com, 1 +lc8868.net, 1 +lc8881.com, 1 +lc8885.com, 1 +lc8887.com, 1 +lc8898.net, 1 +lc891.com, 1 +lc8912.com, 1 +lc892.com, 1 +lc8924.com, 1 +lc8925.com, 1 +lc8926.com, 1 +lc8928.com, 1 +lc8929.com, 1 +lc893.com, 1 +lc8930.com, 1 +lc8931.com, 1 +lc8936.com, 1 +lc895.com, 1 +lc8950.com, 1 +lc897.com, 1 +lc8a.com, 1 +lc8guidance.com, 1 +lc9158.com, 1 +lc9256.com, 1 +lc98.net, 1 +lc9852.com, 1 +lc9862.com, 1 +lc9899.com, 1 +lc9900.com, 1 +lc9910.com, 1 +lc9920.com, 1 +lc9930.com, 1 +lc9940.com, 1 +lc9950.com, 1 +lca-pv.de, 1 +lca.gov, 1 +lcacommons.gov, 1 +lcars-sv.info, 1 +lcdf.education, 1 +lce-events.com, 1 +lcgabogados.com, 1 +lcgaj.com, 1 +lcht.ch, 0 +lclarkpdx.com, 1 +lclarkuhl.com, 1 +lcrmscp.gov, 1 +lcs.wiki, 1 +lcsoftware.tk, 1 +lcti.biz, 1 +lcv.psc.br, 1 +lcvip3.com, 1 +lcvip5.com, 1 +lcvip6.com, 1 +lcvip8.com, 1 +lcvip9.com, 1 +lcwater.com.tw, 1 +lcwebsite.cn, 1 +lcx.cc, 1 +lcy.cat, 1 +lcy.im, 0 +lcy.moe, 1 +ld-begunjscica.si, 1 +ld66999.com, 1 +ld699.com, 0 +ld6999.com, 1 +ldarby.me.uk, 0 +ldcraft.pw, 1 +ldesignweb.com, 1 +ldiesel.ca, 1 +ldjb.jp, 1 +ldm2468.com, 1 +ldsun.com, 1 +ldtborovina.cz, 1 +ldts.es, 1 +ldvsoft.net, 0 +ldx.design, 1 +le-bar.org, 1 +le-caprice.co.uk, 1 +le-club.co, 1 +le-controle-parental.fr, 1 +le-creux-du-van.ch, 0 +le-drive-de-just-vet.fr, 1 +le-forum.tk, 1 +le-fumoir.com, 1 +le-h.de, 0 +le-marais.be, 1 +le-page.info, 0 +le-palantir.com, 1 +le-stroke-of-genius.com, 1 +le-traiteur-parisien.fr, 0 +le-upfitter.com, 1 +le0.me, 1 +le052.com, 1 +le056.com, 1 +le0yn.ml, 1 +le10sport.com, 1 +le130rb.com, 1 +le133cannes.com, 1 +le23.fr, 1 +le42mars.fr, 1 +le802.com, 1 +leabharbreac.com, 1 +leadbook.ru, 1 +leadbox.cz, 1 +leadercreative.ga, 1 +leaderfreight.tk, 1 +leaderinnetflow.com, 1 +leaderoftheresistance.com, 0 +leaderoftheresistance.net, 0 +leadersaudit.ga, 1 +leadership-conference.net, 1 +leadership9.com, 1 +leadgem.co.uk, 1 +leadgenie.me, 1 +leadinfo.com, 1 +leadplan.ru, 0 +leadquest.nl, 1 +leadsformoney.tk, 1 +leadsguru.ru, 1 +leaf-nail.com, 1 +leaf.ninja, 1 +leafandseed.co.uk, 1 +leafans.tk, 0 +leafinote.com, 1 +leafinote.net, 1 +leafland.co.nz, 1 +leafletdistributionmanchester.com, 1 +leak.media, 1 +leakedminecraft.net, 1 +leakforums.net, 1 +leales.org, 1 +leamsigc.com, 0 +lean-consulting.cf, 1 +leanclub.org, 1 +leandre.cn, 1 +leandrebergeron.com, 1 +leandri-campana-avocat.fr, 1 +leandromarcolino.tk, 1 +leandromoreno.co, 1 +leanplando.com, 1 +leaodarodesia.com.br, 1 +leap-it.be, 0 +leapa.co, 1 +leapandjump.co.uk, 1 +leapday.us, 1 +leapworks.io, 1 +leardev.de, 1 +learn-smart.uk, 1 +learn-this.tk, 1 +learncrypto.live, 1 +learncrypto.show, 1 +learncrypto.vip, 1 +learnedhacker.com, 1 +learnerdriving.com, 1 +learnflakes.net, 1 +learnforestry.com, 1 +learnhowtoplayguitar.tk, 1 +learning-id.com, 1 +learningaboutcarinsurance.com, 1 +learningis1.st, 1 +learningladderacademy.net, 1 +learninglaw.com, 1 +learningman.top, 1 +learnk12.org, 1 +learnlux.com, 1 +learnpianogreece.com, 1 +learnpine.com, 1 +learnplayground.com, 1 +learnspace.co.za, 1 +learnthetruth.tk, 1 +learntobeonline.com, 1 +learntosurfcaparica.com, 1 +learntosurflisbon.com, 1 +learntradingforexnow.com, 1 +leasecar.uk, 1 +leaseit24.com, 1 +leaseourthings.com, 1 +leasit.de, 1 +leastsignificantbit.de, 1 +leatam.fr, 1 +leatherfurnitureexpo.com, 1 +leathergoods.tk, 1 +leathership.co, 1 +leathersofacleaning.co.uk, 1 +leatherstreet.tk, 1 +leatherwill.com.ua, 1 +leatherwood.nl, 1 +leavenworthcounty.gov, 1 +leaving.africa, 1 +lebal.se, 1 +lebalcondesraspes.com, 1 +lebanesearmy.gov.lb, 1 +lebanonbitcoin.com, 1 +lebanonoregon.gov, 1 +lebarbatruc.com, 1 +lebarmy.gov.lb, 1 +lebc-group.com, 1 +lebeachvillage.com, 1 +lebendige-heilkunst.de, 1 +lebens-fluss.at, 1 +lebensinselparaguay.tk, 1 +lebensraum-fitness-toenisvorst.de, 1 +lebensraum-kurse.ch, 1 +lebesis.tk, 1 +lebihan.pl, 1 +leblanc.io, 1 +leblancq.ca, 1 +lebourgeo.is, 1 +lebozec.org, 1 +lecafedugeek.fr, 1 +lecannabis.at, 1 +lecannabis.com, 1 +lecannabiste.com, 1 +lecannabiste.fr, 1 +lecannabiste.it, 1 +lecannabiste.uk, 1 +lecatal.ca, 1 +leccamilafi.ga, 1 +lecercleguimard.fr, 1 +lechaudrondupertuis.ch, 1 +lecheng.in, 1 +lecheng08.com, 1 +lecheng3.com, 1 +lecheng5288.com, 1 +lecheng7.com, 1 +lecheng8.net, 1 +lecheng88.com, 1 +lecheng88.net, 1 +lecheng888.com, 1 +lecheng98.com, 1 +lecheng988.com, 1 +lechenietravami.cf, 1 +lechiennoir.net, 1 +lechite.ga, 1 +lechompenchaine.fr, 1 +lechucero.com, 1 +leclubnestleantillesguyane.fr, 1 +leclubnestlereunion.re, 1 +lecoinchocolat.com, 1 +leconnecteur-biarritz.fr, 1 +lecoquelicot.info, 1 +lecreative.tk, 1 +lectricecorrectrice.com, 1 +lecul.site, 1 +led-jihlava.cz, 1 +led.xyz, 0 +ledburyvets.co.uk, 1 +leddeluxe.ml, 1 +leddingplasticsurgery.com, 1 +ledebergleeft.be, 1 +ledecologie.com.br, 1 +ledeguisement.com, 1 +ledensite.com, 1 +lederer-it.com, 1 +ledgy.com, 1 +ledlampor365.se, 1 +ledlight.com, 1 +ledlights.ca, 1 +lednavi.de, 1 +ledscontato.com.br, 1 +ledshop.mx, 1 +ledspadova.eu, 1 +ledspalluto.de, 1 +leeaaronsrealestate.com, 1 +leeannescreations.com, 1 +leebiblestudycenter.co.uk, 1 +leebiblestudycenter.com, 1 +leebiblestudycentre.co.uk, 1 +leebiblestudycentre.com, 1 +leebiblestudycentre.net, 1 +leebiblestudycentre.org, 1 +leech.ga, 1 +leech.tk, 1 +leeclemens.net, 0 +leefindlow.com, 1 +leekspin.ml, 1 +leelaylay.com, 1 +leelou.wedding, 1 +leeman.nl, 1 +leemankuiper.nl, 1 +leenaluhtanen.net, 1 +leendebroekertfonds.nl, 1 +leere.me, 1 +leerkotte.eu, 1 +leerliga.de, 1 +leertipp.de, 1 +leeryan.tk, 1 +leesilvey.com, 0 +leet2.com, 1 +leetbunny.tk, 1 +leetcode.com, 1 +leetcode.net, 1 +leetgamers.asia, 1 +leetsaber.com, 1 +leevealdc.com, 1 +leeyoungaeph.tk, 1 +lefarsankids.com.br, 1 +lefcoaching.nl, 1 +lefebvristes.com, 1 +lefebvristes.fr, 1 +lefilradio.fr, 1 +leflibustier.ru, 1 +leflox.cf, 1 +lefonddeloeil.com, 0 +lefroyee.com, 1 +left-baggage.co.uk, 1 +leftbankdesign.net, 1 +leftbrainsolutions.com.au, 1 +leftclick.be, 1 +leftclick.cloud, 1 +leftclick.es, 1 +leftclick.eu, 1 +leftclick.fr, 1 +leftclick.nl, 1 +leftoye.com, 1 +lega-dental.com, 1 +legacygame.ga, 1 +legacygame.gq, 1 +legacyiohs.org, 1 +legadental.com, 1 +legaillart.fr, 1 +legal-aid.tk, 1 +legal.farm, 1 +legal.today, 1 +legalagenda.ga, 1 +legalatlanta.com, 1 +legalcalculator.ga, 1 +legalcanal.ga, 1 +legalcircus.ga, 1 +legalclearance.ga, 1 +legalcorporation.ga, 1 +legaleus.co.uk, 1 +legalinmotion.es, 1 +legalintergrity.ga, 1 +legalisierung.tk, 1 +legaliz.ml, 1 +legalnews.ml, 1 +legalplace.fr, 1 +legalrobot-uat.com, 1 +legalrobot.com, 1 +legalsearch.nl, 1 +legalservicespanel.gov.au, 1 +legalsoftware.net, 1 +legalsrit.tk, 1 +legalsteroid.co, 1 +legaltechnology.pro, 1 +legaltip.eu, 1 +legaltity.com, 1 +legato.marketing, 1 +legatofmrc.fr, 1 +legba.in, 1 +legeaz.net, 1 +legen.sk, 1 +legend-of-pirates.tk, 1 +legend-v.life, 1 +legendary-royale.net, 1 +legendcatz.com, 1 +legendesdechine.ch, 0 +legendgrafix.tk, 1 +legendofkrystal.com, 1 +legends-game.ru, 0 +legendwiki.com, 1 +leggyeggy.ga, 1 +legiaphu.com, 1 +legible.es, 1 +legilimens.de, 1 +legion.ge, 1 +legionisci.com, 1 +legioniv.org, 1 +legionminecraft.com, 1 +legiscontabilidade.com.br, 1 +legit.nz, 1 +legjobblogo.hu, 1 +legkie-recepty.tk, 1 +legko-pohudet.cf, 1 +legko-pohudet.ml, 1 +legland.fr, 1 +legna.roma.it, 1 +legnami24.it, 1 +legoktm.com, 1 +legoutdesplantes.be, 1 +legowerewolf.net, 1 +legrandvtc.fr, 1 +legterm.cz, 1 +legumeinfo.org, 1 +legyenkianegykereked.hu, 1 +lehighmathcircle.org, 1 +lehighvalleypeds.com, 1 +lehmitz-weinstuben.de, 1 +lehnen.xyz, 1 +lehokolo.eu, 1 +lehti-tarjous.net, 1 +lehvyn.org, 1 +leibniz-gymnasium-altdorf.de, 1 +leideninternationalreview.com, 1 +leighneithardt.com, 1 +leignier.org, 1 +leilautourdumon.de, 1 +leilonorte.com, 1 +leiming.co, 1 +leipzig.photo, 1 +leipziger-triathlon.de, 1 +leisure-blog.com, 1 +leisure-supplies-show.co.uk, 1 +leisure.cf, 1 +leisurecooker.co.uk, 1 +leisurecooker.ie, 1 +leivadi.com, 1 +leiyinan.com, 1 +lejade.fr, 1 +lejardindesmesanges.fr, 1 +lekkergoings.nl, 1 +lekkerleben.de, 1 +leko.tk, 1 +lekota.co.uk, 1 +lelac-capfrance.com, 0 +leladesign.it, 1 +lele13.cn, 1 +lelehei.com, 1 +leleimports.store, 1 +leliekerk.nl, 1 +leliveld.nl, 1 +leliveld.org, 1 +lellek.at, 1 +lelo.com.pl, 1 +lelocaldrive.com, 1 +lelubre.info, 1 +lelux.fi, 1 +lelux.net, 1 +lelux.site, 1 +lemagauto.fr, 1 +lemans.com.gt, 1 +lemarcheelagrandeguerra.it, 1 +lemat.de, 1 +lemazol.fr, 1 +lemcarni.shop, 1 +lemco.dk, 1 +lemfam.ru, 1 +lemilane.it, 1 +leminhduong.com, 1 +lemmi.no, 1 +lemmy.ca, 1 +lemni.top, 1 +lemoine.at, 1 +lemonardo.ga, 1 +lemoncarlawyer.com, 1 +lemondrops.xyz, 1 +lemonop.com, 1 +lemonparty.co, 1 +lemonrockbiketours.com, 1 +lemonrotools.com, 1 +lena-klein.de, 1 +lena-klein.eu, 1 +lena-nitro.org, 1 +lenafonster.se, 1 +lenagroben.de, 1 +lenalio.fr, 1 +lenamorino.net, 1 +lenaneva.ru, 0 +lenardoips.tk, 1 +lence.net, 1 +lencia.ga, 1 +lenczewski.ddns.net, 1 +lendahandmissionteams.org, 1 +lendingclub.com, 1 +lendingmate.ca, 1 +lenemes.tk, 1 +lenergietoutcompris.fr, 1 +lengow.com, 1 +lengua-alemana.tk, 1 +lenguajecoloquial.com, 1 +lenguajecoloquial.es, 1 +lenguajedeprogramacion.com, 1 +lenguasgermanicas.tk, 1 +lengyelnyelvoktatas.hu, 1 +lengyelul.hu, 1 +lenidh.de, 1 +lenii.com, 1 +lenina72.tk, 1 +leninalbertop.com.ve, 1 +lenit.nl, 1 +lenkeran.tk, 1 +lenkunz.me, 1 +lenn-blaschke.com, 1 +lennar.com, 1 +lennard-indlekofer.de, 1 +lennard.tk, 1 +lennard0711.eu, 1 +lennartoldenburg.de, 1 +lennertvh.xyz, 1 +lennox.cf, 1 +lennyendewespen.tk, 1 +lennyobez.be, 1 +lenoblpech.ru, 1 +lenoirnc.gov, 1 +lenorefan.tk, 1 +lenostech.gr, 1 +lenou.nl, 1 +lenovovietnam.net, 1 +lenqiue.com, 1 +lenr-forum.com, 1 +lensdoctor.com, 1 +lenseshop.tk, 1 +lenspirations.com, 1 +lensual.space, 1 +lenta-ru.tk, 1 +lentanews.ml, 1 +lentivo.com, 1 +lenuagebauche.org, 1 +lenyip.com, 1 +lenyip.works, 1 +leo-music.tk, 1 +leoandpeto.com, 1 +leochedibracchio.com, 1 +leodraxler.at, 1 +leoji.codes, 0 +leola.cz, 1 +leola.sk, 1 +leolepirate.com, 1 +leominstercu.com, 0 +leon-tec.co.jp, 1 +leon-tech.com, 1 +leon.wtf, 1 +leonalonso.com, 0 +leonard.io, 0 +leonardcamacho.me, 1 +leonardlorenz.de, 1 +leonardocremonesi.it, 1 +leonardofavio.tk, 1 +leonardoneiva.com.br, 1 +leonauto.de, 1 +leonbuitendam.nl, 1 +leondenard.com, 1 +leongalin.tk, 1 +leonhooijer.nl, 0 +leonidas-dovido.tk, 1 +leoniepur-porn.com, 1 +leonklingele.de, 1 +leonplast.tk, 1 +leontic.es, 1 +leontiekoetter.de, 1 +leontworzy.pl, 1 +leontyev.tk, 1 +leonvermunt.com, 1 +leonvermunt.nl, 1 +leonvotes.gov, 1 +leonyork.com, 1 +leoservicosetc.com, 1 +leoservicosetc.com.br, 1 +leoservicosetc.email, 1 +leoservicosetc.live, 1 +leoservicosetc.net, 1 +leoservicosetc.online, 1 +leoservicosetc.org, 1 +leoservicosetc.rio.br, 1 +leoservicosetc.store, 1 +leoservicosetc.world, 1 +leosty.com, 1 +leovanna.co.uk, 1 +leowkahman.com, 1 +lep.gov, 1 +lepalierjuridique.com, 1 +lepallec.tv, 1 +lepartiecomemoracoes.com.br, 1 +lepenetapeti.com, 1 +lepenis.fr, 1 +leper.ga, 1 +lepetitkids.com.br, 1 +lepetitsavoyardbio.fr, 1 +lephilnet.tk, 1 +lepidum.jp, 1 +lepkov.ru, 1 +leporem.com.br, 1 +leppis-it.de, 1 +leprado.com, 1 +leprekon.tk, 1 +leps.fr, 1 +lepsos.com, 0 +lequerceagriturismo.com, 1 +lequest.dk, 1 +lequocthai.com, 1 +lerasenglish.com, 1 +lereporter.ma, 1 +leretour.ch, 0 +lerika.tk, 1 +lerku.com, 1 +lerlivros.online, 1 +lermer.nl, 1 +lernenamsee.ch, 1 +lernerspersonalinjury.ca, 1 +lernorteuropa.com, 1 +lernorteuropa.de, 1 +lernorteuropa.eu, 1 +lernplattform-akademie.de, 1 +lertsiritravel.net, 1 +leruevintage.com, 1 +les-ateliers-de-melineo.be, 0 +les-explos.com, 1 +les-formations.fr, 1 +les-inoxydables.com, 1 +les-pipelettes-de-narbonne.com, 1 +les-pyrenees.tk, 1 +lesa.boutique, 1 +lesacredescouleurs.fr, 1 +lesaffre.es, 1 +lesalpinistes.com, 1 +lesamisdelaroumanie.com, 1 +lesamoureuxdangelique.ovh, 1 +lesancheslibres.fr, 1 +lesargentinas.tk, 1 +lesatelierskosto.com, 1 +lesberger.ch, 0 +lesbi-porno-video.ru, 1 +lesbianfacesitting.com, 1 +lesbianlovers.tk, 1 +lesbiansslaves.com, 1 +lesblogueuses.fr, 1 +lesbonzoms.alwaysdata.net, 1 +lesborgestv.cat, 1 +lesbrillantsdaristide.com, 1 +lescommunes.com, 1 +lescomptoirsdepierrot.com, 1 +lesconcours.tk, 1 +lescrapdesfilles.fr, 1 +lesdouceursdeliyana.com, 1 +leseditionsbraquage.com, 1 +lesfouines.com, 1 +lesgitesdusapey.fr, 0 +lesgoodnews.fr, 1 +lesh.eu, 1 +lesharris.com, 0 +leshe.us, 1 +leshervelines.com, 1 +leshetu.com, 1 +leshok.tk, 1 +lesin.tk, 1 +lesjardinsdemathieu.net, 0 +lesjardinsdubanchet.fr, 1 +leskoalasenvoyage.com, 1 +lesley.xyz, 1 +leslie.horse, 1 +leslyandyana.com, 1 +lesmamy.ch, 0 +lesmontagne.net, 1 +lesnet.co.uk, 1 +lespagesweb.ch, 0 +lespatriotes.tk, 1 +lespecialiste-pradelexcellence.com, 1 +lesplatanes.ch, 0 +lesportmusic.tk, 1 +lespret.nl, 1 +lesprofsplacotent.com, 1 +lesptitspasdelyne.fr, 1 +lesptitstutos.fr, 1 +lesquerda.cat, 0 +lesscloud.com, 1 +lessentieldanthony.fr, 1 +lessets-graphiques.com, 1 +lessis.moe, 1 +lesspass.com, 1 +lestanzedelgattopardo.it, 1 +lesterchan.net, 1 +lesterrassesdusoleil.ch, 0 +lestrokeofgenius.com, 1 +lesummeira.is, 1 +lesy.eu, 1 +lesy.online, 1 +lesyndicat.info, 0 +leszonderstress.nl, 1 +letableaunoir.fr, 1 +letaman.tk, 1 +letao18.com, 0 +letchikleha.tk, 1 +letdownloads.tk, 1 +letechgranby.com, 1 +leteckedarky.cz, 1 +letemps.ch, 1 +letempsdujasmin.fr, 1 +letempsdunefleur.be, 1 +letertrefleuri.com, 1 +letgodbetrue.com, 1 +lethosdesigns.co.uk, 1 +lethosdesigns.com, 1 +leticia.com.tw, 1 +leticia.ml, 1 +letitfly.me, 1 +letni-kurzy.cz, 1 +leto12.xyz, 1 +letote.com, 0 +letraba.com, 1 +letranif.net, 1 +letrissimas.com, 1 +lets-bounce.com, 1 +lets-go-acoustic.de, 0 +lets-ktai.jp, 1 +lets.ninja, 1 +lets.nu, 1 +letsagree.online, 1 +letsbounceuk.com, 1 +letsbrand.com, 1 +letsbrandholding.com, 1 +letscrackit.ml, 1 +letsdebug.net, 1 +letsdevelop.com.br, 1 +letsdocode.com, 1 +letsdoeit.com, 1 +letsencrypt-for-cpanel.com, 1 +letsfame.com, 1 +letsflyinto.space, 1 +letsgame.nl, 1 +letsgetchecked.com, 1 +letsgetintouch.com, 1 +letsgo.icu, 1 +letsgowhilewereyoung.com, 1 +letsmakeiteasy.tech, 1 +letsnet.org, 1 +letson.me, 1 +letsorganise.uk, 1 +letspartyrugby.co.uk, 1 +letstalkcounseling.com, 1 +letterbox-online.de, 1 +letterdance.de, 1 +letteringinstitute.com, 1 +lettersblogatory.com, 1 +lettersvertalingen.nl, 1 +letterzaken.nl, 1 +lettings101.org, 0 +lettori.club, 1 +lettres-motivation.net, 1 +letturaveloce.tk, 1 +letustravel.tk, 1 +letweedoo.com, 1 +letzi-immobilien.ch, 1 +leu.to, 0 +leuchtmann.ch, 1 +leuenhagen.com, 1 +leukert.org, 1 +leulu.com, 1 +leumi-how-to.co.il, 1 +leutgeb.xyz, 1 +leuthardtfamily.com, 1 +leuvensefilmclub.tk, 1 +lev103.com, 1 +levabilligt.com, 1 +levans.fr, 0 +levante.com.au, 1 +levante.net.nz, 1 +levapsych.com, 1 +levaquin750.ga, 1 +level-10.de, 1 +level5-drywall.com, 1 +level6.me, 1 +level9hvac.com, 1 +levelaccordingly.com, 1 +levelia.eu, 1 +levellock.com.ua, 1 +levelninehvac.com, 1 +levels.one, 1 +levels3d.com, 1 +levelsoft.ml, 1 +leveluplv.com, 1 +leveluprankings.com, 1 +levendwater.be, 1 +levendwater.org, 1 +levensbron.nl, 1 +leventismotors.com.ng, 1 +leveragedtokens.com, 1 +leveredge.net, 1 +leverj.io, 1 +levermann.eu, 1 +leviaan.nl, 1 +leviathan-studio.com, 1 +leviathanfan.tk, 1 +levico.tk, 1 +levidromelist.com, 1 +levineteamestates.com, 1 +levinus.de, 1 +leviobery.com, 1 +levis.fun, 1 +levis.name, 1 +levisenlaw.com, 1 +levittasaude.com.br, 0 +levothyroxineonline.gq, 1 +levs.tk, 1 +levshamaster.org, 1 +lew.im, 1 +lewdawson.com, 1 +lewdgamer.com, 1 +leweslivingstreets.tk, 1 +lewiatan.opole.pl, 1 +lewis-sharp.com, 1 +lewiscollard.com, 1 +lewisdatasecurity.com, 1 +lewisjuggins.co.uk, 1 +lewisllewellyn.me, 1 +lewismcyoutube.uk, 1 +lewt.me, 1 +lexapro-price.ga, 1 +lexautoservice.nl, 1 +lexblog.com, 1 +lexdigital.pl, 1 +lexe.club, 1 +lexic.co, 1 +lexico.pt, 1 +lexicography.online, 1 +lexicore.ga, 1 +lexifax.ga, 1 +lexikon24.tk, 1 +lexis.ml, 1 +lexitravels.com, 1 +lexjunkie.xyz, 1 +lexpartsofac.com, 1 +lexreception.com, 1 +lexway.pk, 1 +leybelsgarden.cf, 1 +leybold.co.id, 1 +leyendaluzrenacer.com, 1 +leylalewis.com, 1 +leymaritima.com, 1 +leytron.tk, 1 +lez.gent, 1 +lez2020.be, 1 +lez2020.gent, 1 +lezdomsm.com, 1 +lezwatchtv.com, 1 +lf112.net, 1 +lfashion.eu, 1 +lfaz.org, 1 +lfcnsv.de, 1 +lffweb.ga, 1 +lfgss.com, 1 +lfnaturopathie.com, 1 +lforum.tk, 1 +lfrconseil.com, 1 +lfyhokk.tk, 1 +lg-obchod.cz, 1 +lg-store.sk, 1 +lg-waps.go.jp, 1 +lg-world.cz, 1 +lg.com.br, 1 +lg.gz.cn, 1 +lg0.site, 1 +lg2.com, 1 +lgam.com, 1 +lgbt-colleges.com, 1 +lgbt.io, 1 +lgbt.ventures, 1 +lgbtventures.com, 1 +lgbusiness.es, 0 +lgerman.de, 1 +lgesteticaautomotiva.com.br, 1 +lghfinancialstrategy.ch, 0 +lgiswa.com.au, 1 +lgnsh.fr, 1 +lgobchod.cz, 1 +lgpecasoriginais.com.br, 1 +lgrs.com.au, 1 +lgscripts.com.br, 1 +lgsg.us, 1 +lgshop.cz, 1 +lgshop.sk, 1 +lgstore.cz, 1 +lgstore.sk, 1 +lgworld.cz, 1 +lhajn.cz, 1 +lhakustik.se, 1 +lhalbert.xyz, 1 +lhamaths.online, 1 +lhasaapso.com.br, 1 +lhconsult.tk, 0 +lheinrich.org, 1 +lhero.org, 1 +lhgavarain.com, 1 +lhost.su, 1 +lhp-creation.com, 1 +lhp-creation.fr, 1 +lhr.wiki, 1 +lhsj28.com, 1 +lhsj68.com, 1 +lhsj78.com, 1 +li-de.tk, 1 +li-ke.co.jp, 1 +li-n.net, 1 +li.gz.cn, 1 +li.search.yahoo.com, 0 +lia-fox.org, 1 +liaengel.com, 1 +lialion.de, 1 +liam-is-a-nig.ga, 1 +liam-w.io, 1 +liamelliott.me, 1 +liamlin.me, 1 +lian-in.net, 1 +liandongyoupin.com, 1 +lianglongcredit.com, 1 +liangxingai.com, 1 +lianhe.art, 1 +lianwen.kim, 1 +lianye1.cc, 1 +liaozheqi.cn, 1 +liaronce.com, 1 +liaronce.win, 1 +liautard.fr, 1 +lib64.net, 1 +libbitcoin.org, 1 +libble.eu, 1 +libbywinberginteriors.com.au, 1 +libcip.org, 1 +libcmodbus.org, 1 +libcrc.org, 1 +liberalis.tk, 1 +liberapay.com, 1 +liberation2020.com, 1 +liberationschool.org, 1 +liberdademg.com.br, 1 +liberecstehovani.cz, 1 +liberta-me.org, 1 +libertacao.tk, 1 +libertarian-party.com, 1 +libertas-tech.com, 1 +libertas.co.jp, 1 +liberte-toujours.tk, 1 +libertis.ga, 1 +liberty-city.tk, 1 +liberty-host.tk, 1 +libertyachts.com, 0 +libertyland.tk, 1 +libertytereconoce.com, 1 +libertyvault.us, 1 +libertywines.co.uk, 1 +libertywines.ie, 1 +libertyxpress.tk, 1 +libfins.org, 1 +libgame.com, 1 +libget.com, 1 +libhttp.org, 1 +libmpq.org, 1 +libnull.com, 1 +libpdf.org, 1 +libportal.cf, 1 +libr.ee, 1 +libra.com, 1 +libractes.tk, 1 +librairieducontretemps.com, 1 +librairiezbookstore.com, 1 +libraries.vic.gov.au, 1 +librarium.tk, 1 +library-quest.com, 1 +libraryofcode.org, 1 +libraryofcode.us, 1 +librarytools.com, 0 +libravatar.org, 1 +librazy.org, 1 +libre-innovation.org, 1 +libre-service.de, 1 +libre.cr, 1 +libre.university, 1 +libreboot.org, 1 +librebox.de, 1 +libredns.eu, 1 +libreduca.com, 1 +libreho.st, 1 +librelamp.com, 1 +libremail.nl, 1 +libremedia.info, 1 +librends.org, 1 +libreoffice-from-collabora.com, 1 +libreofficefromcollabora.com, 1 +libreria-ouroboros.tk, 1 +librervac.org, 1 +libresoft.ml, 1 +libressobooks.sk, 1 +libricks.fr, 1 +librisulibri.it, 1 +libroautomotriz.com, 1 +librofilia.com, 1 +librosdescargas.club, 1 +librosgratisnet.tk, 1 +libscpi.org, 1 +libskia.so, 1 +libsodium.org, 1 +libstdc.com, 1 +libstock.si, 1 +libuni.eu, 1 +liburanjogja.co.id, 1 +libyanexpert.ml, 1 +licence-registry.com, 1 +licenciasconstrucciondiamante.com, 1 +licensediscovery.io, 1 +licenzacalcio.tk, 1 +liceo.cn, 1 +lichess.org, 1 +lichform.com, 1 +lichnyj-astrolog.cf, 1 +lichnyj-astrolog.ga, 1 +lichnyj-astrolog.gq, 1 +lichnyj-astrolog.ml, 1 +lichnyj-astrolog.tk, 1 +lichtcam.ddns.net, 0 +lichtfestival.be, 1 +lichtfestival.gent, 1 +lichtfestivalgent.be, 1 +lichtfestivalgent.com, 1 +lichtfestivalgent.tv, 1 +lichtfestivalghent.be, 1 +lichtfestivalghent.com, 1 +lichtmetzger.de, 0 +lichtspot.de, 1 +lichtsturm.net, 1 +lichttechnik-tumler.com, 1 +lichttraeumer.de, 1 +lick.link, 1 +lickingcounty.gov, 1 +lickthesalt.com, 1 +licloud.homeip.net, 1 +licx.cf, 1 +licx.ml, 1 +licx.ru, 1 +lida-vets.co.uk, 1 +lidavidm.me, 1 +lidel.org, 1 +lidernaturascarlettbados.com, 1 +liderok.tk, 1 +liderwalut.pl, 0 +lidl-foto.it, 1 +lidl-fotos.at, 1 +lidl-fotos.de, 1 +lidl-gewinnspiel.de, 1 +lidl-holidays.com, 1 +lidl-immobilien.de, 1 +lidl-kochen.de, 1 +lidl-shop.be, 1 +lidl-shop.cz, 1 +lidl-shop.nl, 1 +lidl-shop.sk, 1 +lidl-sklep.pl, 1 +lidl-stikeez.si, 1 +lidl-tour.ro, 1 +lidl.at, 1 +lidl.be, 1 +lidl.de, 1 +lidlonline.es, 1 +lidlovajogurteka.si, 1 +lidodecor.com, 1 +lidogr.com, 1 +lidong.me, 1 +lidosparesort.com, 1 +lidow.eu, 1 +lidtkemotors.com, 1 +liduan.com, 0 +liduan.net, 0 +liebel.org, 1 +lieben.tk, 1 +lieberwirth.biz, 1 +lied8.eu, 1 +liemen.net, 1 +liendar-silver.com, 1 +lienhuyghebaert.tk, 1 +lier.tk, 1 +lieren4x4.nl, 1 +lierohell.tk, 1 +lieuu.com, 0 +lifanov.com, 1 +lifars.com, 1 +life-emotions.pt, 1 +life-experiment.com, 1 +life-in-hell.tk, 1 +life-is-riddle.tk, 1 +life-style.tk, 1 +life-tec.tk, 1 +life29.com, 1 +life4net.tk, 1 +lifeandhealthtips.tk, 1 +lifeartstudios.net, 1 +lifeasgame.tk, 1 +lifebetweenlives.com.au, 1 +lifeboxhealthcare.co.uk, 1 +lifebun.com, 1 +lifebymargot.co.uk, 1 +lifecism.com, 1 +lifecoachkatrien.be, 1 +lifeconnections.ro, 1 +lifecounselingorlando.com, 1 +lifecraft.cf, 1 +lifeeducationqld.org.au, 1 +lifefoto.de, 1 +lifeguatemala.com, 1 +lifehacker.com, 1 +lifehouseliving.com, 0 +lifeinhellfansite.tk, 1 +lifeinhex.com, 1 +lifeinsurancepro.org, 1 +lifeisabug.com, 1 +lifeismmo.com, 1 +lifeisqi.nl, 1 +lifekirov.tk, 1 +lifekiss.ru, 1 +lifelinesupport.org, 1 +lifematenutrition.com, 1 +lifemcserver.com, 1 +lifemstyle.com, 1 +lifenews24.tk, 1 +lifenexto.com, 1 +lifeqa.net, 1 +lifereset.it, 1 +lifesafety.com.br, 1 +lifesaver.tk, 1 +lifesaverhindi.tk, 1 +lifesavvy.com, 1 +lifesavvymedia.com, 1 +lifeset.pp.ua, 1 +lifesettlements.com, 1 +lifesharing.gr, 1 +lifesignals.com, 1 +lifeskills-education.co.uk, 0 +lifeslice.online, 1 +lifeslonglist.com, 1 +lifestorage.com, 1 +lifestrongacademy.org, 1 +lifestyle7788.com, 1 +lifestylecent.com, 1 +lifestylediet.space, 1 +lifestylefinancial.ca, 1 +lifestylefoto.cz, 1 +lifestyler.me, 1 +lifestylexplocial.tk, 1 +lifesuccessandpersonalgrowth.com, 1 +lifetimefitness.tk, 1 +lifetimestack.com, 1 +lifetoolscdc.com, 1 +lifetree.network, 1 +lifeupgame.fr, 1 +lifewaysvillage.com, 1 +lifewithdyna.com, 1 +lifexpert.tk, 1 +lifi.digital, 1 +lifi.is, 1 +liftagacademy.com, 1 +liftie.info, 1 +liftmastercloud.com, 1 +liftoff.rocks, 1 +liftyourgame.com, 1 +lig.ink, 0 +liga.ng, 1 +liga99.tk, 1 +ligadelconsorcista.org, 1 +ligadosgames.com, 1 +ligare-fp.com, 1 +light.mail.ru, 1 +lightanddarkgame.com, 1 +lightbluelearning.com, 1 +lightbox.co, 1 +lightcraftmc.tk, 1 +lightdark.xyz, 1 +lightfestivalghent.be, 1 +lightfestivalghent.com, 1 +lightfoot.co.uk, 1 +lighthouseglobal.com, 1 +lighthouseinstruments.com, 1 +lightingagoura.com, 1 +lightingagourahills.com, 1 +lightingcalabasas.com, 1 +lightingconejovalley.com, 1 +lightingdosvientos.com, 1 +lightinghiddenhills.com, 1 +lightinglakesherwood.com, 1 +lightingmalibu.com, 1 +lightingmoorpark.com, 1 +lightingnewburypark.com, 1 +lightingoakpark.com, 1 +lightingpacificpalisades.com, 1 +lightingsimivalley.com, 1 +lightingthousandoaks.com, 1 +lightingwestlakevillage.com, 1 +lightme.us, 1 +lightmere.com, 1 +lightning-wallet.com, 1 +lightning.community, 1 +lightning.engineering, 1 +lightnings.tk, 1 +lightningseed.net, 1 +lightningwirelabs.com, 1 +lightnovel.info, 1 +lightography.com, 1 +lightquantum.me, 0 +lights.co.uk, 1 +lights0123.com, 1 +lightscale.com, 1 +lightsheep.no, 0 +lightspeed.com, 0 +lightspeedta.co, 1 +lightstep.com, 0 +lightupcollective.co.uk, 1 +lightweighthr.com, 1 +lightwitch.org, 0 +lightyear.no, 1 +ligmadrive.com, 1 +ligne-roset.com, 1 +ligneclaire.tk, 1 +lignemalin.com, 1 +lignite.com, 1 +lignoma.com, 1 +ligonier.com, 1 +lihaul.dnsalias.net, 1 +lihj.me, 1 +lihuenjardin.com, 1 +liisauusitaloarola.fi, 1 +lijana.rs, 1 +lije-creative.com, 1 +lijero.co, 1 +lijncoaching.nl, 1 +lijstje.be, 1 +lijstje.nl, 1 +like-boss.ga, 1 +like-rabota.tk, 1 +like.lgbt, 1 +likeablehub.com, 1 +likeabox.de, 1 +likeany.com, 1 +likebee.gr, 1 +likefast.tk, 1 +likefluence.com, 1 +likegeeks.com, 1 +likehifi.de, 1 +likemovies.de, 1 +likenewhearing.com.au, 1 +likenosis.com, 1 +likeometer.co, 1 +likere.com, 1 +likestudio.com.ua, 1 +likewatercs.com, 1 +likui.me, 1 +lil88.com, 1 +lilaccakeboutique.com, 1 +lilai107.com, 1 +lilai116.com, 1 +lilai18.ph, 1 +lilai2211.com, 1 +lilai3366.com, 1 +lilai520.com, 1 +lilai5566.com, 1 +lilai634.com, 1 +lilai6616.com, 1 +lilai6677.com, 1 +lilai6688.com, 1 +lilai777.com, 1 +lilai838.com, 1 +lilai8866.com, 1 +lilai9898.com, 1 +lilai99.com, 1 +lilai9966.com, 1 +lilaiw66.com, 1 +lilianejuchli.ch, 1 +liliang.moe, 1 +liliang13.com, 1 +lilidarcek.sk, 1 +lilie.fr, 1 +lilievabien.fr, 1 +lilimusic.tk, 1 +lilisg.tk, 1 +lilith-magic.com, 1 +liliweb.tk, 1 +liljohnsanitary.net, 1 +lillbrothers.com, 1 +lille.ml, 1 +lillieprivat.org, 1 +lilliputpreschool.co.nz, 1 +lilly-lil.org, 1 +lillyfox.de, 1 +lilomatrixcorner.fr, 1 +lilosaludable.com, 1 +lilou-sportswear.com, 1 +lilousportswear.com, 1 +lilpwny.com, 1 +liltv.media, 1 +lily-bearing.com, 1 +lily-inn.com, 1 +lily.flowers, 1 +lilylango.net, 1 +lilylasvegas.com, 1 +lilypadwikisecret.tk, 1 +lilysbouncycastles.com, 1 +lilysgrill.com, 1 +lilyvet.com, 1 +lim-light.com, 1 +limap.ch, 1 +limawi.io, 1 +limbaido.tk, 1 +limberg.me, 1 +limbo-online.tk, 1 +limc.cloud, 1 +lime-host.cf, 1 +lime-host.tk, 1 +lime.rocks, 1 +limecho.net, 1 +limehost.com, 1 +limehotel.tk, 1 +limit.xyz, 1 +limitededitioncomputers.com, 1 +limitededitionsolutions.com, 1 +limitlessinteractive.com, 1 +limiturls.ga, 1 +limitxyz.com, 1 +limnt.cn, 1 +limo.pl, 1 +limoairporttoronto.net, 1 +limoforsale.com, 1 +limoshka.ru, 1 +limouzines.cf, 1 +limpiadordeporos.online, 1 +limpid.nl, 1 +limportemps.fr, 1 +limsia.co, 1 +limsia.com, 1 +limstash.com, 1 +limstash.me, 1 +limules.ch, 0 +limx.win, 1 +lin.fi, 1 +linafernandez.com.co, 1 +linaklein.de, 1 +linalynn.com, 1 +linan.info, 1 +linan.site, 1 +linaproclinic.com, 1 +linarite.net, 1 +lincasonline.tk, 1 +lincdavis.com, 1 +lince-bonares.tk, 1 +lincnaarzorg.nl, 1 +lincolnbrokerage.com, 1 +lincolncountymoclerk.gov, 1 +lincolncountysheriffok.gov, 1 +lincolncountytn.gov, 1 +lincolnfinewines.com, 1 +lincolnil.gov, 1 +lincolnpedsgroup.com, 1 +lincolnspringsgc.com, 1 +lincore.ru, 1 +lindajahn.de, 1 +lindalap.fi, 1 +lindaolsson.com, 1 +lindaquerida.com.br, 1 +lindazi.com, 1 +lindbladcruises.com, 1 +linden-nj.gov, 1 +linden.me, 0 +lindependant.ml, 1 +lindeskar.se, 1 +lindgrenracing.tk, 1 +lindnerhof-taktik.de, 1 +lindnerhof.info, 1 +lindnerova.cz, 1 +lindo.ru, 1 +lindogdahl.dk, 1 +lindon.pw, 1 +lindquistnet.us, 1 +lindsayanderson.com, 1 +lindsaygorski.com, 1 +lindseyfansite.tk, 1 +lindskogen.se, 1 +line-magazine.com, 1 +line.biz, 1 +line.co.nz, 0 +lineaesse5.it, 1 +linearaudio.net, 1 +linearmap.com, 1 +linebooks.cf, 1 +linernotekids.com, 1 +lineshop.ml, 1 +linespots.com, 1 +linestep.jp, 1 +linfadenopatia.com, 1 +linfamilygc.com, 1 +linge-ma.ro, 1 +lingerie.com.br, 1 +lingeriecollect.ga, 1 +lingeries.boutique, 1 +lingeriesilhouette.com, 1 +lingolia.com, 0 +lingotaxi.com, 1 +lingroove.com, 1 +lingros-test.tk, 1 +lingualeo.com, 1 +linguamilla.com, 1 +linguaromanica.tk, 1 +linguatrip.com, 1 +lingvist.com, 1 +linherest.tk, 1 +linhua.org, 1 +link-group.tk, 1 +link-knighki.cf, 1 +link-list.tk, 1 +link-man.net, 1 +link-medital.com, 1 +link-net.ga, 1 +link-sanitizer.com, 1 +link.sb, 1 +link2link.tk, 1 +link2serve.com, 1 +link9.net, 1 +linkagemag.com, 1 +linkages.org, 1 +linkat4.cz, 1 +linkbooks.ga, 1 +linkcat.tk, 1 +linkdecode.com, 1 +linkdolar.tk, 1 +linkdr.uk, 1 +linkedin500.com, 1 +linkedpipes.com, 1 +linkenheil.org, 1 +linkie.vn, 1 +linkinbooks.gq, 1 +linkinparkoutpost.tk, 1 +linkinsta.com, 1 +linklocker.co, 1 +linkmauve.fr, 1 +linknaarlinux.tk, 1 +linko-pomoika.tk, 1 +linkonaut.net, 1 +linkopia.com, 1 +linkportal.tk, 1 +linkposts.tk, 1 +linkroll.cf, 1 +linksafe.ga, 1 +linksanitizer.com, 1 +linksbridge.com, 1 +linkscloud.org, 1 +linksextremist.at, 1 +linksgruenejugend.de, 1 +linksite.tk, 1 +linksmatrix.tk, 1 +linkspace.tk, 1 +linksphotograph.com, 1 +linkst.co, 1 +linkstagr.am, 1 +linkthis.me, 1 +linkthis.ml, 1 +linktio.com, 1 +linkto.cf, 1 +linku.com, 1 +linkuva.tk, 1 +linkview.tk, 1 +linkwater.org, 1 +linkwheel.tk, 1 +linky.tk, 1 +linkycat.com, 1 +linkyou.top, 0 +linley.de, 1 +linmago.com, 1 +linmi.cc, 1 +linnaeusgroup.co.uk, 1 +linncounty-ia.gov, 1 +linnetinfotech.in, 1 +linocolombo.tk, 1 +linocomm.com, 1 +linocomm.net, 1 +linocomm.nl, 1 +linomass.com, 1 +linomass.nl, 1 +linonin.tk, 1 +linoplan.be, 1 +linoplan.com, 1 +linoplan.de, 1 +linoplan.dk, 1 +linoplan.eu, 1 +linoplan.fr, 1 +linoplan.info, 1 +linoplan.net, 1 +linoplan.nl, 1 +linoscan.com, 1 +linoscan.nl, 1 +linoskin.com, 1 +linoskin.nl, 1 +linosky.ch, 1 +linostor.com, 1 +linostor.nl, 1 +linotrac.com, 1 +linotrac.nl, 1 +linotype.tk, 1 +linovelib.com, 1 +linpx.com, 1 +linqhost.nl, 1 +linss.com, 1 +lintmx.com, 1 +linuq.org, 1 +linusdrop.tips, 1 +linux-admin-california.com, 1 +linux-admin.tk, 1 +linux-audit.com, 1 +linux-florida.com, 1 +linux-help.org, 1 +linux-mint-czech.cz, 1 +linux-pc.ml, 1 +linux-share.tk, 1 +linux-taganrog.tk, 1 +linux-vme.org, 1 +linux.cn, 0 +linux.conf.au, 1 +linux.farm, 1 +linux.fi, 1 +linux.im, 1 +linux.monster, 1 +linux.sb, 1 +linux.study, 1 +linux3.org, 1 +linux4tw.de, 1 +linuxadictos.com, 1 +linuxarequipa.tk, 1 +linuxbabe.com, 1 +linuxbg.eu, 1 +linuxbierwanderung.com, 1 +linuxcbt.com, 1 +linuxchick.se, 1 +linuxcommand.ru, 1 +linuxdashboard.com, 1 +linuxdays.cz, 1 +linuxforum.ch, 1 +linuxforwindows.com, 1 +linuxge.com, 1 +linuxgiggle.com, 1 +linuxhilux.com, 1 +linuxhostsupport.com, 1 +linuxhub.ro, 0 +linuxincluded.com, 1 +linuxiuvat.de, 1 +linuxkompis.se, 1 +linuxlounge.net, 1 +linuxnetflow.com, 1 +linuxonline.tk, 1 +linuxos.org, 1 +linuxproperties.com, 1 +linuxsecurity.expert, 1 +linuxwerkstatt.net, 1 +linuz.it, 1 +linx.net, 1 +linxmind.eu, 1 +linzyjx.com, 1 +lion7.de, 1 +lionchita.tk, 1 +lionelsfarm.com, 1 +lionhosting.nl, 1 +lionland.tk, 1 +lionlyrics.com, 1 +lioprog.com, 1 +lioraaja.com, 1 +liorggi.ga, 1 +lipacom.ga, 1 +lipartydepot.com, 1 +lipaslovanska.cz, 1 +lipeck.ga, 1 +lipeck.tk, 1 +lipetsk-centralniy.cf, 1 +lipetsk48.tk, 1 +lipex.com, 1 +lipighor.com, 1 +lipighor.xyz, 1 +lipo.lol, 1 +lipoabaltimore.org, 1 +lipovka.tk, 1 +lippu1.fi, 1 +lipsumtech.com, 1 +lipthink.com, 1 +lipturess.tk, 1 +liqd.net, 1 +liqueur.wiki, 1 +liquid.cz, 1 +liquidation.tk, 1 +liquidationyt.com, 1 +liquidcomm.net, 1 +liquidflash.ml, 1 +liquidhost.co, 1 +liquidinternet.co, 1 +liquidplus.com, 1 +liquidradio.pro, 1 +liquidwarp.net, 1 +liquidweb.tk, 1 +liquipedia.net, 1 +liquiritia.tk, 1 +liquor.my, 1 +lirapogrebnicentar.hr, 1 +lirelesgens.com, 1 +liress.gq, 1 +lirico.ca, 1 +lirion.de, 1 +lirlandais.ch, 0 +lirnberger.com, 1 +lis-na-plasty.cz, 1 +lis.koeln, 1 +lisa-mainz.tk, 1 +lisadelbo.tk, 1 +lisahh-jayne.com, 0 +lisahutson.co.uk, 1 +lisamaffia.tk, 1 +lisamccorrie.com, 1 +lisanzauomo.com, 1 +lisapo.info, 1 +lisas.ml, 1 +lisasack.net, 1 +lisasc.gq, 1 +lisasworkshop.co.uk, 1 +lisavrobinson.tk, 1 +lisbon-pre-1755-earthquake.org, 1 +lisburnhottubnbounce.co.uk, 1 +liscieperfetti.com, 1 +lishayut-prav.cf, 1 +lishayut-prav.ga, 1 +lishayut-prav.gq, 1 +lishayut-prav.ml, 1 +lishayut-prav.tk, 1 +lishup.com, 1 +lisieuxarquitetura.com.br, 1 +lisinphotography.com, 1 +lisius.ga, 1 +liskgdt.net, 1 +lislan.org.uk, 1 +lisowski-development.com, 0 +lisowski-photography.com, 1 +lissabon.guide, 0 +lissabonsite.tk, 1 +lissajouss.tk, 1 +lissauer.com, 1 +list-gymnasium.de, 1 +listach.tk, 1 +listahu.org, 1 +listapp.uz, 1 +listekdo.fr, 1 +listen.dk, 1 +listener.ga, 1 +lister-kirchweg.de, 1 +listim.com, 1 +listing-here.com, 1 +listing.gq, 1 +listisima.com, 1 +listiu.com, 1 +listminut.be, 1 +lists.fedoraproject.org, 1 +lists.mayfirst.org, 0 +lists.stg.fedoraproject.org, 1 +listsothebysrealtyhk.com, 1 +listyourinfo.com, 1 +lit.foundation, 0 +litarvan.com, 1 +litcc.com, 1 +litchidova.nl, 1 +litcomphonors.com, 1 +litebit.de, 1 +litebit.eu, 1 +litebit.nl, 1 +litebitcdn.eu, 1 +litebits.com, 1 +litebooks.gq, 1 +litecache.de, 1 +litecloud.ml, 1 +litecoinnews.info, 1 +litehost24.tk, 1 +litemere.com, 1 +litemind.com, 0 +liteminer.cf, 1 +litepanels-parts.com, 1 +litepay.ch, 1 +litepost.com, 1 +literacychannel.ga, 1 +literarymachin.es, 1 +literatura-portal.cf, 1 +literature-schools.com, 1 +literaturka.ga, 1 +literie06.com, 1 +litespeed-webserver.de, 1 +litespeedwebserver.com, 1 +litespeedwebserver.de, 1 +litfin.name, 1 +litfl.com, 1 +lithan.com, 1 +lithesalar.se, 1 +lithianissaneugeneparts.com, 1 +litiab.tk, 1 +litlscholars.com, 1 +litportal.gq, 1 +litsovet.com, 1 +little-brother.eu, 1 +little-cake.com, 1 +little-news.gq, 1 +little.recipes, 1 +littlebar.tk, 1 +littlebearcare.com, 1 +littlebestfriend.de, 1 +littlebirds.cf, 1 +littlebites.co.nz, 1 +littleblackfish.se, 1 +littlebootshonduras.tk, 1 +littleboutiqueshop.co.uk, 1 +littleboutiqueshop.com, 1 +littleboutiqueshop.uk, 1 +littledev.nl, 1 +littlefamilyadventure.com, 1 +littlefingersindia.com, 1 +littlegiants.edu.au, 1 +littlehide.gq, 1 +littlelife.co.uk, 1 +littlelucifercafe.tk, 1 +littlemaster.tk, 1 +littlenina.nz, 0 +littlenlargeevents.co.uk, 1 +littleorangecookbook.com, 1 +littlepigcreek.com.au, 1 +littlepincha.fr, 0 +littleqiu.net, 1 +littleredsbakeshop.com, 1 +littlericket.me, 1 +littlerose.ml, 1 +littlerphotographie.fr, 1 +littles.moe, 1 +littlescallywagsplay.co.uk, 1 +littleservice.cn, 1 +littlesk.in, 1 +littleskin.cn, 1 +littleswitch.co.jp, 1 +littlewatcher.com, 1 +littleyokohamakennel.tk, 1 +liturgical.net, 1 +liturkey.tk, 1 +litvideoserver.de, 1 +litz.ca, 1 +litzenberger.ca, 1 +liu0hy.cn, 1 +liubliu.co.uk, 1 +liud.im, 1 +liudon.org, 1 +liujr.tk, 1 +liukang.tech, 1 +liul.in, 1 +liuliuya.com.tw, 1 +liulo.cf, 1 +liuq.org, 1 +liuqiao.best, 1 +liuqiao.cf, 1 +liuqiao.eu.org, 1 +liuqiao.ga, 1 +liuqiao.gq, 1 +liuqiao.ml, 1 +liuqiao.pp.ua, 1 +liuqiao.tk, 1 +liuqiaolovecaonali.ml, 1 +liushuyu.tk, 1 +liuwenxuan.com, 1 +livada.fr, 1 +livadm.ml, 1 +live-knigi.cf, 1 +live-news.gq, 1 +live-z-rejstejna.cz, 1 +live2play.ml, 1 +live4k.media, 0 +live8811.com, 1 +live8899.cn, 1 +live8899.co, 1 +live8899.net, 1 +live9922.com, 1 +liveandinvestoverseas.com, 1 +liveanimations.org, 1 +livebandphotos.com, 1 +livebestbooks.gq, 1 +livebetterwith.com, 1 +livebythesun.de, 1 +livecards.co.uk, 1 +livecards.es, 1 +livecards.eu, 1 +livecards.it, 1 +livecchi.cloud, 1 +liveciv.top, 1 +livecommande.fr, 1 +liveconcertvideo.tk, 1 +livedemo.pw, 1 +livedesign.at, 1 +livedesign24.de, 1 +liveflightapp.com, 1 +liveforspeed.se, 1 +livehelpindia.com, 1 +livehomecams.co.uk, 1 +liveint.org, 1 +liveita.com, 1 +liveitlogical.in, 1 +liveitmerck.ca, 1 +livejasmin-online.com, 1 +livejasmin.dk, 1 +livejh.tk, 1 +livekaarten.be, 1 +livekaarten.nl, 1 +livekarten.at, 1 +livekarten.de, 1 +livekey.tk, 1 +livekort.com, 1 +livekort.dk, 1 +livekort.no, 1 +livekort.se, 1 +livekortti.com, 1 +livekortti.fi, 1 +livela.jp, 1 +livelexi.com, 1 +livelifewithintent.com, 1 +livelink.tk, 1 +livelondon.fr, 1 +livelonglife.tk, 1 +livelovelaughlg.com, 1 +livelyapps.com, 1 +livemomentum.ml, 1 +livenewsrussia.tk, 1 +liveomadic.com, 1 +liveperformersmeeting.net, 1 +livepl.eu, 1 +liverano.com, 1 +liveregistratie.nl, 1 +liverider.co.jp, 1 +liverobot8.com, 1 +liverobot888.com, 1 +livesexcalls.co.uk, 1 +livesheep.com, 1 +liveskype.com, 1 +liveslides.com, 1 +livestone.tk, 1 +livestrana.tk, 1 +livesure.com, 1 +liveteachers.in, 1 +livetopknigi.gq, 1 +livetoride.co.za, 1 +livezrejstejna.cz, 1 +livfcshop.com, 1 +livhao.com, 1 +livi.co, 1 +livi.co.uk, 1 +livi.fr, 1 +living-space.co.nz, 1 +living-with-outlook-2010.com, 1 +living.digital, 1 +living.video, 1 +living2000.com, 1 +livingafrugallife.com, 1 +livingforreal.com, 1 +livinginhimalone.com, 1 +livinglab.be, 1 +livinglifesecurely.com, 1 +livinglink.be, 1 +livingorganicnews.com, 1 +livingthegreenlife.com, 1 +livingtired.org, 1 +livingtohearsix.com, 1 +livingworduk.org, 1 +livinkitchen.tk, 1 +livive.com, 1 +livnev.me, 1 +livnev.xyz, 1 +livogeva.dk, 1 +livornonellarete.tk, 1 +livrariacoad.com.br, 1 +livrariause.com, 1 +livresetmanuscrits.com, 1 +livroseuniformes.com.br, 1 +livv168.com, 1 +livv88.com, 1 +liwaoases.com, 1 +lixiaoyu.live, 1 +lixtick.com, 1 +liyin.date, 1 +liypoi.top, 0 +liz-fry.com, 1 +liz.ee, 1 +lizagalore.tk, 1 +lizaminnelli.tk, 1 +lizardsystems.com, 1 +lizardtech.top, 1 +lizbonbet.net, 1 +lizheng.de, 1 +lizhi.io, 1 +lizhi123.net, 1 +lizhuogui.ga, 1 +lizmccaughey.com, 1 +lizmooredestinationweddings.com, 1 +liznewton.com.au, 1 +liztattoo.se, 1 +lizteacher.com, 1 +lizzaran.io, 1 +lizzian.uk, 1 +lizzwood.com, 1 +lizzythepooch.com, 1 +lj-creation.com, 1 +ljason.cn, 1 +ljc.ro, 1 +ljoonal.xyz, 1 +ljs.io, 1 +ljskatt.no, 1 +ljw.me, 1 +lk-hardware.cz, 1 +lk1.bid, 1 +lkbk.uk, 1 +lkellar.org, 1 +lklyrics.com, 1 +lknw.de, 1 +lkotlarenko.xyz, 1 +lkp111138.me, 1 +lkqpickyourpart.com, 1 +lkummer.cz, 1 +lkw-servis.sk, 1 +ll-t.com, 1 +ll.gr, 1 +ll5197.co, 1 +ll6729.co, 1 +ll6729.com, 1 +ll6957.co, 1 +ll8819.com, 1 +ll9297.co, 1 +ll9397.com, 1 +ll9728.co, 1 +llamadordeangeles.online, 1 +llamerapido.com, 1 +llandudnochristmasfayre.co.uk, 1 +llanelli-radio-club.tk, 1 +llanowar.tk, 1 +llantasysuspensiones.shop, 1 +llbcpa.com, 1 +llccd.eu.org, 1 +lldy88.com, 1 +lleidanoticies.com, 1 +llemoz.com, 1 +llgj888.com, 1 +llgw8.com, 1 +lligwy.co.uk, 1 +llinternational.tk, 1 +llm-guide.com, 1 +lloyd-day.me, 1 +lloydrogerspencer.com, 1 +llredac.fr, 1 +llvm.us, 1 +llyq8866.com, 1 +llyq9988.com, 1 +lm-landscapes.co.uk, 1 +lm1628.com, 1 +lm228.cn, 1 +lm228.com, 1 +lm338.cn, 1 +lm338.com, 1 +lmasqueen.com, 1 +lmbyrne.co.uk, 1 +lmbyrne.com, 1 +lmddgtfy.net, 1 +lmdev.com.br, 1 +lmh-style.com, 1 +lmintlcx.com, 1 +lmmi.nl, 1 +lmmks.com, 1 +lmmtfy.io, 1 +lmrcouncil.gov, 1 +lms-luch.ru, 1 +lmsptfy.com, 1 +lmsuitespagna.it, 1 +lmtls.me, 1 +lmtravis.com, 1 +lmvsci.gov, 1 +ln.io, 1 +lndrive.space, 1 +lnhydy.cn, 1 +lnk.bio, 1 +lnk.dk, 1 +lnoldan.com, 1 +lnx.li, 1 +lnyltx.cn, 1 +lo-li.icu, 1 +lo-mio.com, 1 +lo-zuromin.tk, 1 +loa.land, 1 +loackerbusiness.it, 1 +load-ev.de, 1 +load.pm, 0 +loaded.se, 1 +loader.to, 1 +loader.us.com, 1 +loading.express, 1 +loadlow.me, 1 +loadme.ml, 1 +loadtime.de, 1 +loadwallet.com, 1 +loafhead.me, 1 +loan-lenders.co.za, 1 +loancompare.co.za, 1 +loanfreeze.ga, 1 +loanmatch.sg, 1 +loanreadycredit.com, 1 +loansharkpro.com, 1 +loanstreet.nl, 1 +loantillpaydaydelaware.com, 1 +loavies.com, 1 +lob-assets-staging.com, 1 +lob-assets.com, 1 +lob-staging.com, 1 +lobbes.nl, 1 +lobevert.com, 1 +lobin21.com, 1 +lobivia.de, 1 +lobocapoeira.tk, 1 +lobosdomain.ddns.net, 1 +lobosdomain.hopto.org, 1 +lobosdomain.no-ip.info, 1 +lobsangstudio.com, 1 +lobste.rs, 1 +lobstr.co, 1 +loca-voiture.fr, 1 +locabir.cf, 1 +locais.org, 1 +local360.net, 1 +localassocier.tk, 1 +localbandz.com, 1 +localbiketrader.com, 1 +localbitcoins.com, 1 +localblitz.com, 0 +localblock.co.za, 1 +localbouncycastle.com, 1 +localbusinessimprovement.com, 1 +localcryptopremium.com, 1 +localcryptos.com, 1 +locald.at, 1 +localegroup.com, 0 +localexpert.realestate, 1 +localhorst.duckdns.org, 1 +localhorst.xyz, 1 +localhost.cat, 1 +localized.tk, 1 +localizejs.com, 1 +localizestaging.com, 1 +locall.cf, 1 +locallhost.me, 1 +localmonero.co, 1 +localnet.site, 1 +localnetwork.nz, 1 +localpov.com, 1 +localprideart.com, 1 +localrvs.com, 1 +localsearch.homes, 1 +localseo.ltd, 1 +localseo.repair, 1 +localseorepair.co, 1 +localseorepair.design, 1 +localseorepair.ltd, 1 +localseorepair.network, 1 +localseorepair.rocks, 1 +localseorepair.services, 1 +localseorepair.world, 1 +localserver.ca, 1 +localspot.pl, 1 +localstartupfest.id, 1 +localtownhouses.ga, 1 +localwebsuccess.com, 1 +locamation.com, 1 +locapos.com, 1 +location-appartement-dakar.com, 1 +location-fichier-email.com, 1 +location-groix.com, 1 +location-vacances-croatie.tk, 1 +locationkaraokemontreal.com, 1 +locationkaraokeottawa.com, 1 +locationkaraokequebec.com, 1 +locationvoitureallemagne.com, 1 +locationvoitureangleterre.com, 1 +locationvoitureaustralie.com, 1 +locationvoitureautriche.com, 1 +locationvoiturebelgique.com, 1 +locationvoiturecorse.net, 1 +locationvoitureespagne.com, 1 +locationvoiturefinlande.com, 1 +locationvoitureislande.com, 1 +locationvoitureitalie.com, 1 +locationvoiturenorvege.com, 1 +locationvoiturepaysbas.com, 1 +locationvoitureportugal.com, 1 +locationvoituresuede.com, 1 +locatornet.ga, 1 +locatorplus.gov, 1 +locauxrama.fr, 1 +locchat.com, 1 +lock-expert.de, 1 +lock.me, 1 +lock23.ca, 1 +lockaby.org, 1 +locker.email, 1 +locker.plus, 1 +locker3.com, 1 +lockerroomstories.com, 1 +lockify.com, 1 +lockless.tk, 1 +locklock.com.br, 1 +locklockbrasil.com.br, 1 +lockme.at, 1 +lockme.ch, 1 +lockme.de, 1 +lockme.pl, 1 +locknlock.com.br, 1 +locknlockbrasil.com.br, 1 +lockoutgroup.com, 1 +lockpick.nl, 1 +lockr.jp, 1 +locksmith--richmond.com, 1 +locksmith--sanantoniotx.com, 1 +locksmith-durbannorth.co.za, 1 +locksmith-pasadenatx.com, 1 +locksmith-sanantonio-tx.com, 1 +locksmith-springtx.com, 1 +locksmithbalchsprings.com, 1 +locksmithballito.com, 1 +locksmithbluff.co.za, 1 +locksmithboksburg.co.za, 1 +locksmithdearborn.com, 1 +locksmithdickinson-tx.com, 1 +locksmithdriftwood.com, 1 +locksmithedenvale24-7.co.za, 1 +locksmithedmonds.com, 1 +locksmithforcarshoustontx.com, 1 +locksmithfourways24-7.co.za, 1 +locksmithgarland-tx.com, 1 +locksmithgermiston24-7.co.za, 1 +locksmithgrapevinetx.com, 1 +locksmithhillcrest.co.za, 1 +locksmithindurban.co.za, 1 +locksmithlakewaytx.com, 1 +locksmithlivoniami.com, 1 +locksmithmadisonheights.com, 1 +locksmithmesquitetexas.com, 1 +locksmithmesquitetx.com, 1 +locksmithmidrand24-7.co.za, 1 +locksmithmissouricity.com, 1 +locksmithopen.com, 1 +locksmithresidentialspringtx.com, 1 +locksmithsammamishwa.com, 1 +locksmithsbluff.com, 1 +locksmithsbuda.com, 1 +locksmithscottsdaleaz.com, 1 +locksmithseattleco.com, 1 +locksmithservice-cypress.com, 1 +locksmithservice-humble.com, 1 +locksmithsinsanantoniotx.com, 1 +locksmithspring.com, 1 +locksmithspringtx.com, 1 +locksmithssanmarcostx.com, 1 +locksmithstaffordtx.com, 1 +locksmithswestville.com, 1 +locksmiththewoodlands.com, 1 +locksmithunit.cat, 1 +locksmithunit.com, 1 +locksmithunit.es, 1 +locksport.org.nz, 1 +locktonportal.com, 1 +lockwoodchristmastreefarm.com, 1 +locomore.com, 1 +locomotionds.com, 1 +locomotiv.tk, 1 +locomotive.ca, 1 +locoserver.net, 1 +locurimunca.co, 1 +locus-dashboard.com, 1 +locus.tk, 1 +locusmap.eu, 1 +lodash.com, 0 +loddeke.eu, 1 +lode.li, 1 +lode.tk, 1 +lodela.ru, 1 +lodewijkict.nl, 1 +lodewillems.com, 1 +lodger.cf, 1 +lodki-pvh.com, 1 +lodni.site, 1 +lodosswar.tk, 1 +lodus.io, 1 +loeklommers.nl, 1 +loenshotel.de, 1 +loew.de, 1 +lofficinadelweb.com, 1 +loforo.com, 1 +lofttravel.com, 1 +loftyideas.ml, 1 +loftymedia.ca, 1 +lofw.tk, 1 +logactiond.org, 1 +logal.media, 1 +logalot.com, 1 +logancooper.jp, 1 +logancountyky.gov, 1 +loganmarchione.com, 1 +loganparkneighborhood.org, 1 +logart.tk, 1 +logay.com.br, 1 +logbook.ch, 1 +logbot.info, 1 +logcat.info, 1 +logdoc.tk, 1 +logement-saisonnier.com, 1 +logement.com, 1 +logentries.com, 0 +logevou-immobilier.tk, 1 +logexplorer.net, 1 +logfile.at, 1 +logfile.ch, 1 +logger-phillipferreira.herokuapp.com, 1 +logibow.com, 1 +logic8.ml, 1 +logical-invest.com, 1 +logicchen.com, 1 +logicdream.tk, 1 +logiciel-entreprise-seurann.fr, 1 +logicio.ch, 0 +logicio.de, 0 +logicio.net, 0 +logicne-hise.si, 1 +logicnets.com, 1 +logico.ar, 1 +logicz.top, 1 +logimap.cz, 1 +login.corp.google.com, 1 +login.gov, 1 +login.launchpad.net, 1 +login.ooo, 1 +login.raiffeisen.ch, 1 +login.sapo.pt, 1 +login.ubuntu.com, 1 +login.yahoo.com, 0 +logingate.hu, 1 +logitel.de, 1 +logitheque.tk, 1 +logitrack.tk, 1 +loglineargroup.com, 1 +logo-vogtland.de, 1 +logobravo.com, 1 +logoenvue.fr, 1 +logoesun.com, 1 +logoglo.com, 1 +logolabben.cf, 1 +logolando.tk, 1 +logomarket.jp, 1 +logon-int.com, 1 +logopaedie-sandkrug.de, 1 +logopedistalanni.it, 1 +logophiliapress.com, 1 +logopoeia.com, 1 +logostock.jp, 1 +lograr.me, 1 +logtalk.org, 1 +logtenberg.eu, 1 +logue.be, 1 +logwise.com, 1 +lohanaflores.com.br, 1 +loheprobado.com, 1 +lohkoketju.fi, 1 +lohmeyer.cc, 1 +lohnsteuerhilfe-essen.de, 1 +lohr.net, 1 +loichot.ch, 0 +loiit.ga, 1 +loire-en-bateau.fr, 1 +loisirsdouville.com, 1 +lojaapoio.com.br, 1 +lojacorbuccieats.com.br, 1 +lojadafloresta.pt, 1 +lojadamimo.com.br, 1 +lojadanidrea.com.br, 1 +lojadarenda.com.br, 1 +lojadelicatojatai.com.br, 1 +lojadewhisky.com.br, 1 +lojadoanime.com, 1 +lojadoarcomprimido.com.br, 1 +lojadoprazer.com.br, 1 +lojadosirmaos.com.br, 1 +lojadosomautomotivo.com.br, 1 +lojafazendoarte.com.br, 1 +lojahaus.com.br, 1 +lojahunamarcenaria.com.br, 1 +lojak2.com.br, 1 +lojal19.com.br, 1 +lojamagicalx.com, 1 +lojamascate.com.br, 1 +lojamoleco.com.br, 1 +lojamultplick.com.br, 1 +lojaodo9.com.br, 1 +lojapos.eu, 1 +lojaprojetoagua.com.br, 1 +lojas25online.com.br, 1 +lojasmary.com.br, 1 +lojastec.com.br, 1 +lojasti.com.br, 1 +lojasvictoria.com.br, 1 +lojatema.com.br, 1 +lojaterrazul.com.br, 1 +lojavirtualdopsicopedagogo.com.br, 1 +lojavirtualinfopaper.com.br, 1 +lojavisamed.com.br, 1 +lojaxo.com.br, 1 +lojix.com, 0 +lojj.pt, 1 +lok.space, 1 +lokaal.org, 1 +lokal-speisen.de, 1 +loker.id, 1 +lokjagruktafoundation.com, 1 +lola.by, 1 +lolas-vip.com, 1 +lolaseuropeancafe.com, 1 +lolcats.tk, 1 +lolcloud.ru, 1 +lolcorp.pl, 1 +lolcosplay.ga, 1 +lolcow.farm, 1 +lolfunny.tk, 1 +loli.com, 1 +loli.edu.kg, 1 +loli.gallery, 1 +loli.net, 1 +loli.pet, 1 +loli.tube, 1 +loli.world, 1 +loliblogs.cf, 1 +loliblogs.ga, 1 +loliblogs.gq, 1 +loliblogs.ml, 1 +lolibrary.org, 1 +lolic.xyz, 1 +lolicon.eu, 1 +lolicon.info, 1 +loliel.tk, 1 +lolifamily.cf, 1 +lolifamily.ga, 1 +lolifamily.gq, 1 +lolifamily.js.org, 1 +lolifamily.ml, 1 +lolifamily.tk, 1 +lolio.tw, 1 +lolipops.ga, 1 +lolis.stream, 1 +lolitalechat.com, 1 +lolivpn.com, 1 +lolkot.ru, 1 +lollipopo69.net, 1 +lolly.cc, 1 +lollybrown.com, 1 +lollypop.tk, 1 +lollyteam.tk, 1 +lolmania.tk, 1 +loma.ml, 1 +lomaster.tk, 1 +lomayko.ml, 1 +lombri-agro.com, 1 +lomerhouse.com, 1 +lomex.tk, 1 +lommeregneren.dk, 1 +lommyfleet.com, 1 +lomza.tk, 1 +lon-so.com, 1 +lona.io, 1 +lonavla.tk, 1 +lonay.me, 0 +london-mafia.tk, 1 +london-transfers.com, 1 +london.dating, 1 +londonbridge.pl, 1 +londoncalling.co, 0 +londongallery.net, 1 +londongynaecologist.co, 1 +londonhealthcare.tk, 1 +londonhouseshare.co.uk, 1 +londonindustry.it, 1 +londonkan.jp, 1 +londonkeyholdingcompany.co.uk, 1 +londonlegaltranslation.ae, 1 +londonpods.co.uk, 1 +londonpropertymatch.com, 1 +londonseedcentre.co.uk, 1 +londontrivia.gq, 1 +londresdecouverte.fr, 1 +londynelliot.com, 1 +lone-gunman.be, 1 +lonelyhaoss.com, 1 +lonelyion.com, 0 +lonelypawn.com, 1 +lonelystoner.design, 0 +lonelytweets.com, 1 +lonelyworld.co.uk, 1 +loneronin.tk, 1 +lonerwolf.com, 0 +lonesomecosmonaut.com, 1 +lonestarlandandcommercial.com, 1 +long-6.com, 1 +long-8.com, 1 +long-9.com, 1 +long-journey.com, 1 +long008.com, 1 +long0310.com, 1 +long0311.com, 1 +long0316.com, 1 +long0317.com, 1 +long0318.com, 1 +long0355.com, 1 +long0356.com, 1 +long0376.com, 1 +long0377.com, 1 +long0398.com, 1 +long0536.com, 1 +long0538.com, 1 +long0539.com, 1 +long0555.com, 1 +long0556.com, 1 +long0728.com, 1 +long0735.com, 1 +long0736.com, 1 +long0776.com, 1 +long0777.com, 1 +long08.com, 1 +long0818.com, 1 +long0855.com, 0 +long0877.com, 1 +long0878.com, 1 +long0897.com, 1 +long0898.com, 1 +long0976.com, 1 +long0996.com, 1 +long0997.com, 1 +long0999.com, 1 +long100.vip, 1 +long113.com, 1 +long139.com, 1 +long18.cc, 1 +long186.com, 1 +long226.com, 1 +long228.com, 1 +long266.com, 1 +long288.com, 1 +long388.com, 1 +long510.com, 1 +long566.com, 1 +long566.net, 1 +long68.net, 1 +long688.com, 1 +long788.com, 1 +long8.com, 1 +long8021.com, 1 +long8026.com, 1 +long8032.com, 1 +long8039.com, 1 +long918.com, 1 +long988.com, 1 +longboat.io, 1 +longfordlodge.tk, 1 +longhaircareforum.com, 1 +longhorn-imports.com, 1 +longhorn.id.au, 1 +longislandbusiness.info, 1 +longlink.tk, 1 +longlivehongkong.com, 1 +longma.pw, 1 +longma168.cn, 1 +longma168.com, 1 +longstride.net, 1 +longtermrentalsportugal.com, 1 +lonleymoon.tk, 1 +lonlomba.com, 1 +lonniec.com, 1 +lonniemason.net, 1 +lonny.ee, 1 +look-books.tk, 1 +look-info.tk, 1 +look.co.il, 1 +lookae.com, 1 +lookagain.co.uk, 1 +lookasik.eu, 1 +lookatmysco.re, 1 +lookbetweenthelines.com, 0 +looker.com, 1 +looker.wang, 0 +lookgadgets.com, 1 +lookingstores.fr, 0 +lookup-dns.net, 1 +loomis.center, 1 +loonbedrijfdenboer.nl, 1 +looneymooney.com, 1 +loony.info, 0 +loonylatke.com, 1 +loopback.kr, 1 +loopcore.de, 1 +loopool.tk, 1 +loopower.com, 1 +looseleafsecurity.com, 1 +loothole.com, 1 +loots.eu, 1 +lop12.com, 1 +lopendvuurtje.tk, 1 +lopezmanzano.com, 1 +loposchokk.com, 1 +lopp.net, 1 +loqu8.com, 1 +loquo.com, 1 +loqyu.co, 1 +loqyu.com, 1 +lor.kharkov.ua, 1 +loratadine10mg.gq, 1 +lorbooks.tk, 1 +lord-design.tk, 1 +lord-of-forex.tk, 1 +lord.sh, 1 +lordbyron.tk, 1 +lorddominion.tk, 1 +lordgrant.tk, 1 +lordjevington.co.uk, 1 +lordofthebrick.com, 0 +lordsesshoumaru.tk, 1 +lordtracking.com, 1 +lordusa.com, 1 +lordusers.com, 1 +lore-seeker.cards, 1 +lore.azurewebsites.net, 1 +loremipsum.info, 1 +lorena-salido.tk, 1 +lorenadumitrascu.ro, 1 +lorengraff.net, 1 +lorenz-cloud.eu, 1 +lorenz-hundler.co, 1 +lorenzocampagna.myqnapcloud.com, 1 +lorenzocompeticion.com, 0 +lorenzodeangelis.tk, 1 +loreofthenorth.com, 1 +loreofthenorth.net, 1 +loricozengeller.com, 1 +lorimullins.com, 1 +lorisfnotary.com, 1 +loritaboegl.de, 1 +lorn.tk, 1 +lornabenes.com, 1 +lorqui.tk, 1 +lorrainestreatmentroom.co.uk, 1 +lorucreative.fi, 1 +los-diablos.tk, 1 +losangelesescorts.net, 1 +losangelestown.com, 1 +losaucas.tk, 1 +loschilums.tk, 1 +losdisidentes.tk, 1 +lose-weight-now.ml, 1 +losebellyfat.pro, 1 +losemperadores.tk, 1 +loser.wtf, 1 +loseweightbaby.tk, 1 +loseweightin5days.tk, 1 +losflamers.tk, 1 +losfogueteros.com, 1 +losgringos.tk, 1 +loshogares.mx, 1 +losinterrogantes.com, 1 +losjuegosdemesa.online, 1 +loslegendarios.tk, 1 +losless.fr, 1 +losmedicamentos.net, 0 +losmiserables.tk, 1 +losmolinos.tk, 1 +lospozuelos.tk, 1 +losreyesdeldescanso.com.ar, 1 +loss.no, 1 +lossaicos.tk, 1 +lost-bit.tk, 1 +lost-illusions.tk, 1 +lost-in-place.com, 1 +lost.report, 1 +lostandfound.mu, 1 +lostarq.com, 1 +lostinfood.co.uk, 1 +lostinweb.eu, 0 +lostkeys.co.uk, 1 +lostproperty.org, 1 +lostprophetschile.tk, 1 +lostsandal.com, 1 +lostsandal.io, 1 +lostserial.cf, 1 +lostserver.com, 1 +lostwithdan.com, 1 +loszucoz.tk, 1 +loteamentoabertocapivari.com.br, 1 +lotekk.gq, 1 +lotereiki.tk, 1 +lothai.re, 1 +lothlorien.ca, 0 +lotl.ru, 1 +lotn.mobi, 1 +lotnonline.com, 1 +lotnonline.net, 1 +loto-tele.com, 1 +lotos-ag.ch, 1 +lotposh.com, 1 +lotro-wiki.com, 1 +lotto.com, 1 +lottodatabase.com, 1 +lottoland.pt, 1 +lottosonline.com, 1 +lottospielen24.org, 0 +lottothaipro.com, 1 +lotuselise.tk, 1 +lotusweb.tk, 1 +lotuswebsolutions.tk, 1 +lotw.de, 1 +lou-castelet.com, 0 +lou.ist, 1 +lou.lt, 1 +louange-reconvilier.ch, 0 +louboutin.tk, 1 +louboutinshoessale.tk, 1 +loucanfixit.com, 1 +loudhills.pl, 1 +louerunhacker.fr, 1 +louhomeworkouts.com, 1 +louisa.tk, 1 +louisacountyia.gov, 1 +louisapolicefoundation.com, 1 +louisapolicefoundation.org, 1 +louiscap.co, 1 +louisdefunes.tk, 1 +louiselaliberte.ca, 1 +louisemisellinteriors.co.uk, 1 +louiserutkowski.tk, 1 +louisville.gov, 1 +louisvillecarguys.com, 1 +louisvilleconnections.ga, 1 +louisvillefibroids.com, 1 +louisvillefilmfestival.org, 1 +louisvillene.gov, 1 +louiza.tk, 1 +loukas-stoltz.fr, 1 +loukkos.ma, 1 +loulifestyle.net, 1 +louloulovestreats.com, 1 +loune.net, 1 +loungecafe.net, 1 +loungecafe.org, 1 +loungepapillon.com, 1 +lourencolar.com, 1 +loutro.tk, 1 +louwlemmer.com, 1 +love-and-hate.cf, 1 +love-books.ga, 1 +love-navigator.tk, 1 +love-planeta.tk, 1 +love-sent.com, 1 +love-spells-tarot.com, 1 +love4musik.com, 1 +love4taylor.com, 1 +love4taylor.eu.org, 1 +love4taylor.me, 0 +love4taylor.xyz, 1 +loveai.org, 0 +loveamber.me, 1 +loveandloyalty.se, 1 +lovebeingsexy.co.uk, 1 +lovebigisland.com, 1 +lovebirdhut.tk, 1 +lovebo9.com, 1 +lovebo9.net, 1 +lovechester.com, 1 +lovecode.net, 1 +lovecrystal.co.uk, 1 +lovedaleschool.tk, 1 +lovedonesofprisoners.com, 1 +lovedutch.tk, 1 +lovegpl.com, 1 +loveismore.de, 0 +loveismore.es, 0 +loveismore.eu, 0 +loveismore.fr, 0 +loveismore.it, 0 +loveismore.org, 0 +loveismore.pl, 0 +loveismore.ru, 0 +loveismore.sk, 0 +loveismystyle.tk, 1 +loveisourweapon.com, 1 +lovejms.com, 1 +lovelee.tk, 1 +lovelens.li, 0 +loveless.ml, 1 +lovelive-anime.tk, 1 +lovelive.us, 1 +lovelivewiki.com, 1 +lovelovenavi.jp, 1 +lovelybook4u.gq, 1 +lovelyfamilymm.com, 1 +lovelyflavor.com, 1 +lovelylanguedoc.com, 1 +lovelytimes.net, 1 +lovemanagementaccounts.co.uk, 1 +lovemasjid.com, 1 +lovememories.cf, 1 +lovemen.cc, 1 +lovemesomegadgets.com, 1 +lovemiku.info, 1 +lovemoon.tk, 1 +lovemoon.xyz, 1 +lovemybubbles.com, 1 +lovenet.tk, 1 +loveni.me, 1 +lovenwishes.com, 1 +loveph.one, 1 +loveplanets.tk, 1 +lover-bg.com, 1 +loverepublic.ru, 1 +loverngifts.com, 1 +loverussiangirls.tk, 1 +lovesmagical.com, 0 +lovesquirting.com.br, 1 +lovessentials.com, 1 +lovestar.wang, 1 +lovetowork.tk, 1 +loveweddingphotosandfilm.co.uk, 1 +loveysa.ch, 0 +lovg.ren, 1 +lovingthermo.com, 1 +lovink.net, 1 +lovizaim.ru, 1 +lovlyhorses.tk, 1 +lovlyluna.net, 1 +low-battery.tk, 1 +low-diets.com, 1 +lowbidders.com, 1 +lowcarbdietmealsmsk.ga, 1 +lowcarbspark.com, 1 +lowcosthost.cf, 1 +lowcostivf.net, 1 +lowcostwire.com.au, 1 +lowerpricefinder.com, 1 +lowerthetone.com, 1 +lowmagnitude.com, 1 +lowsec.space, 1 +lowsidetna.com, 1 +lowson.ca, 1 +lowt.us, 1 +loxdonmarkets.com, 1 +loyaleco.it, 1 +loyaltech.ch, 1 +loyd.co, 1 +loyisa.cn, 0 +loyverse.com, 1 +loyverse.town, 1 +lozhka-mernaya.tk, 1 +lp-support.nl, 0 +lp177.fr, 1 +lpacademy.com.br, 1 +lpasteur.info, 1 +lpbk-bethel.de, 0 +lpcd-lafla.gov, 1 +lpcdops-lafla.gov, 1 +lpchemicalsolution.tk, 1 +lpcom.de, 1 +lpdp.photo, 1 +lpfan.tk, 1 +lpgaclub.jp, 1 +lph.saarland, 1 +lphispano.tk, 1 +lpid.org, 1 +lpkosovo.tk, 1 +lpmkonji.cf, 1 +lprr.fr, 1 +lpt-nebreziny.eu, 1 +lq.hr, 1 +lqshu.net, 1 +lra-cloud.de, 1 +lrdo.net, 1 +lriese.ch, 1 +lrs.lt, 1 +lrssystems.com, 1 +lrumeq.com, 1 +ls-alarm.de, 1 +ls-mapping-team.de, 1 +ls-modcompany.com, 1 +lsal.me, 1 +lsbricks.com, 1 +lsc-dillingen.de, 1 +lsc.ee, 1 +lsc.moe, 1 +lscache.com, 1 +lscache.de, 1 +lsesteticaavancada.com.br, 1 +lsg2021acm.com, 1 +lshiy.com, 1 +lsj.world, 1 +lsl.eu, 1 +lsmentor.com, 1 +lspdonline.gq, 1 +lsquo.com, 1 +lsscreens.de, 1 +lstlx.com, 1 +lstma.com, 1 +lstu.tk, 1 +lsv-tech.com, 1 +lsy.cn, 1 +lsys.ac, 1 +lszj.com, 1 +lt.search.yahoo.com, 0 +ltaake.com, 1 +ltailshort.tk, 1 +ltba.org, 1 +ltcwaterwijk.nl, 1 +ltdev.im, 1 +ltecode.com, 1 +ltheinrich.de, 1 +ltib.com.au, 1 +ltime.ml, 1 +ltlec.cn, 1 +ltlec.com, 0 +ltlec.net, 1 +ltlec.org, 0 +ltlec.services, 1 +ltls.org, 1 +ltmw.xyz, 1 +ltn-tom-morel.fr, 1 +ltonlinestore.in, 0 +ltprtz.co.uk, 1 +ltransferts.com, 1 +lts-tec.de, 1 +ltservers.net, 1 +lty.space, 1 +lu-rp.es, 1 +lu.search.yahoo.com, 0 +lu2343.com, 1 +luabiquinis.com.br, 1 +lual.tk, 1 +luan.ma, 1 +luanvancaohoc.com, 1 +luanxt.tk, 1 +lubar.me, 1 +lubbockyounglawyers.org, 1 +lubersacr.com, 1 +lubot.net, 1 +luc-nutrition.tk, 1 +luc-oberson.ch, 0 +luca-steeb.com, 1 +lucacastelnuovo.nl, 1 +lucade.ddns.net, 1 +lucafontana.net, 1 +lucafrancesca.me, 1 +lucakrebs.de, 1 +lucaplus.com, 1 +lucarautti.com, 1 +lucarelli.fr, 1 +lucasartsclassics.com, 1 +lucasbergen.ca, 1 +lucascantor.com, 1 +lucascodes.com, 1 +lucascountyohiovotes.gov, 1 +lucasdamasceno.com, 1 +lucasem.com, 1 +lucasferraz.com.br, 1 +lucasfrinktbe.com, 1 +lucasgymnastics.com, 1 +lucasit.com, 1 +lucaslarson.net, 1 +lucasrl.fr, 1 +lucassoler.com.ar, 0 +lucasuwadi.com, 1 +lucciolachile.com, 1 +lucdethier.be, 1 +luce.life, 1 +lucentioluo.space, 1 +lucerin.ga, 1 +lucesledsbaratas.shop, 1 +luchalibre.tk, 1 +luchscheider.de, 0 +luchshie-experty.top, 1 +luchthavenmaastricht.nl, 1 +lucia-art.cf, 1 +lucia-riemer.de, 1 +lucid-light.de, 1 +lucid-reality.ch, 1 +lucidframeworks.com, 1 +lucidlight.de, 1 +lucidlink.com, 1 +lucidlogs.com, 1 +lucidoccult.com, 1 +lucie-parizkova.cz, 1 +lucie.jp, 1 +lucielavickova.com, 1 +luciferblog.tk, 1 +luciferianism.tk, 1 +lucille-thomas.fr, 1 +lucillewillemsen.tk, 1 +luciobarcellona.it, 1 +luciogelsi.com, 1 +lucklesslovelocks.com, 1 +lucky-bul.tk, 1 +lucky-frog.co.uk, 1 +lucky-time.tk, 1 +luckyabonent.ml, 1 +luckycasino.se, 1 +luckycastles.co.uk, 1 +luckyemail.ml, 1 +luckyfrog.hk, 1 +luckymice.ml, 1 +luckyrent.tk, 1 +luckystorevn.com, 1 +luckyxf.com, 1 +luclu7.fr, 1 +lucorautopartes.com, 1 +lucschiltz.com, 1 +luctam.com, 1 +lucy.science, 1 +lucybles.com, 1 +lucychan.tk, 1 +lucyhancock.tech, 1 +lucymontebello-arte.com, 1 +lucyparsonslabs.com, 1 +lucysan.net, 1 +lucz.co, 1 +lud.la, 1 +luda.me, 1 +ludejo.eu, 1 +ludek.biz, 1 +luden.tk, 1 +ludikovsky.name, 1 +ludivine-viguie.com, 1 +ludmilla.tk, 1 +ludmillaewagner.ga, 1 +ludo-giuly.tk, 1 +ludofantasy.fr, 1 +ludogue.net, 1 +ludolust.tk, 1 +ludomo.de, 1 +ludotech.tk, 1 +ludothek-burgdorf.ch, 1 +ludovic-muller.fr, 1 +ludum-polus.xyz, 1 +ludum.pl, 1 +ludwig.im, 1 +ludwiggrill.de, 1 +ludwigjohnson.se, 1 +ludwigpro.net, 1 +luedeke-bremen.eu, 1 +lueersen.homedns.org, 1 +luehne.de, 1 +luelistan.net, 0 +luematecidos.com.br, 1 +luenwarneke.com, 1 +lueurexterne-audiovisuel.com, 0 +lueurexterne.com, 0 +luffarn.com, 1 +luffyhair.com, 1 +luftbild-siegerland.de, 1 +luftreiniger.biz, 1 +lufu.io, 1 +lugaresturisticosdeguatemala.ga, 1 +luggagecare.com, 1 +luggagechoices.com, 0 +luggagehero.com, 1 +lugimax.com, 1 +luginbuehl.be, 1 +luginbuehl.eu, 1 +lugobama.tk, 1 +lugros.tk, 1 +lugui.in, 1 +luhn.be, 1 +lui.pink, 1 +lui.vn, 1 +luigialtieri.com, 1 +luisa-birkner.de, 1 +luisanalopilatogrecia.tk, 1 +luisaviles.tk, 1 +luisbustamante.mx, 1 +luisfariasgrupo.com, 1 +luismaier.de, 1 +luisnavarrosl.tk, 1 +luissotodesign.com, 1 +luisv.me, 1 +luisyr.com, 1 +luiza.ga, 1 +luizkowalski.net, 1 +luje.net, 1 +luje.nl, 1 +luk.earth, 1 +luk.photo, 1 +lukas-gorr.de, 1 +lukas-meixner.com, 1 +lukas-schauer.de, 1 +lukas.im, 1 +lukas2511.de, 1 +lukasberan.com, 1 +lukasberan.cz, 1 +lukasbures.com, 1 +lukasfelder.tk, 1 +lukasfunk.com, 1 +lukaskollmer.de, 1 +lukasldc.com, 1 +lukasmatuska.cz, 1 +lukasrod.cz, 1 +lukasschauer.de, 1 +lukasunger.cz, 1 +lukasunger.net, 1 +lukasw.tk, 1 +lukaswiden.com, 1 +lukasztkacz.com, 1 +lukaszuk.net, 1 +lukaszwojcik.net, 1 +luke-hacks.com, 1 +luke.ch, 1 +luke6887.me, 1 +lukeistschuld.de, 1 +lukekuza.com, 1 +lukekuza.me, 1 +lukem.net, 1 +lukeng.net, 1 +luker.org, 1 +lukersallamericanstorage.com, 1 +lukersstorage.com, 1 +lukerstorage.com, 1 +lukertech.net, 1 +lukesbouncycastlehire.com, 1 +lukestebbing.com, 1 +lukesutton.info, 1 +lukezweb.tk, 1 +lukin.ga, 1 +lukka.tk, 1 +lukloveswhisky.pl, 1 +lukmanulhakim.id, 1 +lukonet.com, 1 +luksusy.pl, 1 +lukull-pizza.de, 1 +lule-kendo.tk, 1 +luls.tk, 1 +lumacurve.com, 1 +lumbercartel.ca, 1 +lumberjackman.tk, 1 +lumbre-encendedores.com, 1 +lumchan.tk, 1 +lumen.sh, 1 +lumenapp.com, 1 +lumenbrowser.com, 1 +lumentell.us, 1 +lumer.tech, 1 +lumi.com, 1 +lumi.pw, 1 +lumien.net, 1 +lumierewithinspirato.com, 1 +luminaire-mobilier-design.be, 1 +luminaire.fr, 1 +luminaproject.ml, 1 +luminary.pl, 1 +lumindigital.com, 1 +lumitop.com, 1 +lumizor.com.ua, 1 +lummi-nsn.gov, 1 +lumminary.com, 1 +lumomongoose.com, 1 +lumoria.eu, 1 +lumos.gallery, 1 +lumpenrock.tk, 1 +lumpov.com, 1 +lumpy.ga, 1 +lums.se, 1 +luna-corazon.net, 1 +luna-love.net, 1 +luna-zen.fr, 1 +lunaballoonclub.com.au, 1 +lunademiel.org, 1 +lunafag.ru, 1 +lunai.re, 1 +lunakit.org, 1 +lunalove.de, 1 +lunapps.com, 1 +lunar6.ch, 0 +lunares.pl, 1 +lunaretna.com, 1 +lunarflake.com, 1 +lunarhost.cf, 1 +lunaribes.ch, 0 +lunarlog.com, 1 +lunarshark.com, 1 +lunarsoft.net, 1 +lunartail.nl, 1 +lunasqu.ee, 1 +lunchbunch.me, 1 +lundberghealthadvocates.com, 1 +lundlist.net, 1 +lune-indigo.ch, 0 +lunepieters.co.za, 1 +lunextd.com, 1 +lungcancerchallenge.ca, 1 +lungta.pro, 1 +lunidea.ch, 0 +lunight.ml, 1 +lunis.net, 1 +lunite.net, 1 +lunivertdelyne.fr, 1 +lunix.io, 1 +lunk.it, 1 +lunulanails.nl, 1 +luochunhui.com, 1 +luody.info, 1 +luoe.me, 1 +luoh.cc, 1 +luoh.me, 1 +luohua.im, 1 +luoli.one, 1 +luom.net, 1 +luongvu.com, 1 +luoshifeng.com, 1 +luosonghao.com, 1 +luotbike.vn, 1 +luowu.cc, 1 +luoxingyu.ml, 1 +lupa.cz, 1 +luparacoes.com.br, 1 +lupecode.com, 1 +lupinencyclopedia.com, 1 +lupinenorthamerica.com, 1 +luqsus.pl, 1 +luripump.se, 1 +lurishop.com.br, 1 +lurkmirror.ml, 1 +lushersolutions.com, 1 +lushnikov-alex.ru, 1 +lushnja.tk, 1 +lusis.fr, 1 +lusitec.pt, 1 +lusitom.com, 1 +luska.cz, 1 +lust.works, 1 +lusteniny.cz, 1 +lustin.fr, 1 +lustro.com.sa, 1 +lustrum.ch, 1 +lusynth.com, 1 +lut.im, 1 +luteijn.biz, 1 +lutesite.tk, 1 +lutherus.tk, 1 +lutify.me, 1 +lutizi.com, 0 +lutoma.org, 1 +lutricia.tk, 1 +luukdebruincv.nl, 0 +luukklene.nl, 1 +luukuton.fi, 1 +luuppi.fi, 1 +luv-scent.com, 1 +luv.asn.au, 1 +luv2watchmycam.com, 1 +luvare.com, 1 +luvbridal.com.au, 1 +luvhacks.com, 1 +luvitpatna.com, 1 +luvscent.com, 1 +lux-house.tk, 1 +lux.com.de, 1 +luxanos.com, 1 +luxarchive.tk, 1 +luxcraft.eng.br, 1 +luxden.com, 1 +luxebadkameraccessoires.nl, 1 +luxeblades.com, 1 +luxedentalfl.com, 1 +luxegram.co, 1 +luxegram.co.za, 1 +luxembourgapartment.lu, 1 +luxemburgsite.tk, 1 +luxeturf.com.au, 1 +luxeunderlay.com, 0 +luxfosdecoenterprise.com, 1 +luxhome.tk, 1 +luxmare.hr, 1 +luxosemimos.com.br, 1 +luxplay.com.tw, 1 +luxsci.com, 1 +luxstil.ga, 1 +luxstyleproductions.com, 1 +luxur.is, 1 +luxury-inside.vn, 1 +luxurydistribution.cz, 1 +luxurygifts.tk, 1 +luxuryhome.co.id, 1 +luxuryislandtrips.com, 1 +luxuryitaly.co.id, 1 +luxurynsight.net, 0 +luxuryspeed.tk, 1 +luxurystays.in, 1 +luxuryweddingsindonesia.com, 1 +luxusnivoucher.cz, 1 +luxusnyvoucher.sk, 1 +luxvacuos.net, 1 +luxwatch.com, 1 +luyckx.net, 1 +luzat.com, 1 +luzfaltex.com, 1 +luzi-type.ch, 1 +luzica.tk, 1 +lv.search.yahoo.com, 0 +lv0.it, 1 +lv5.top, 1 +lvcshu.com, 1 +lvee.org, 1 +lvfc.co, 1 +lvftw.com, 1 +lvguitars.com, 1 +lvmoo.com, 1 +lvna.capital, 1 +lvnacapital.com, 1 +lvrsystems.com, 1 +lvtrafficticketguy.com, 1 +lw-addons.net, 1 +lw1.at, 1 +lwis.me, 1 +lwisa.ma, 1 +lwl-foej-bewerbung.de, 1 +lwnlh.com, 1 +lwsl.ink, 1 +lx-blog.cn, 1 +lxai.net, 1 +lxd.cc, 1 +lxd.pm, 1 +lxiii.eu, 1 +lxiv.eu, 1 +lxx4380.com, 1 +lxx77.com, 1 +lyam.fr, 1 +lyap-lyandiya.ga, 1 +lyax.be, 1 +lychankiet.name.vn, 0 +lyclub.vn, 1 +lycly.me, 1 +lydiawebfans.tk, 1 +lydudlejning.net, 1 +lyfbits.com, 1 +lyfstylorganix.com, 1 +lyftrideestimate.com, 1 +lykope.com, 1 +lyla-pressing.com, 1 +lyme-regis-accommodation.co.uk, 1 +lymia.moe, 1 +lyna.ml, 1 +lynamhomeloans.com.au, 1 +lynero.dk, 1 +lyness.io, 1 +lyness.uk, 1 +lyngvaer.no, 1 +lynho.com.br, 1 +lynkmi.com, 1 +lynndye.com, 1 +lynnejeancleaning.com, 1 +lynnellneri.com, 1 +lynnesbian.space, 1 +lynnlaytonnissanparts.com, 1 +lynnmosher.com, 1 +lynsec.com, 1 +lynth.io, 1 +lynthium.com, 1 +lynx.nl, 1 +lynxbroker.cz, 1 +lynxbroker.de, 1 +lynxbroker.pl, 1 +lynxbroker.sk, 1 +lynxpro.nl, 1 +lynxriskmanager.com, 1 +lyon-interactive.com, 1 +lyon-synergie.com, 1 +lyonelkaufmann.ch, 0 +lyoness.digital, 1 +lyonl.com, 1 +lyonslawlink.com, 1 +lyrenhex.com, 1 +lyrical-nonsense.com, 1 +lyricfind.com, 1 +lyricfm.com, 1 +lyricfm.ie, 1 +lyricsupdater.tk, 1 +lyriksidan.ga, 1 +lys.ch, 0 +lysbed.com, 1 +lyscnd.com, 1 +lysdeau.be, 1 +lysel.net, 1 +lysergion.com, 1 +lyst.co.uk, 1 +lyteclinic.com, 0 +lyubov-sovmestimost.cf, 1 +lyuda.tk, 1 +lyukaacom.ru, 1 +lyuks-parfyum.tk, 1 +lyuly.com, 1 +lyx.dk, 1 +lz.sb, 1 +lz898.com, 1 +lzcreation.com, 1 +lzh.one, 1 +lzqii.cn, 1 +lzwc.nl, 1 +lzzr.me, 1 +m-16.ml, 1 +m-22.com, 1 +m-ast.de, 1 +m-beshr.tk, 1 +m-ch.ml, 1 +m-chemical.com.hk, 1 +m-epigrafes.gr, 1 +m-exchange.ml, 1 +m-foda.com, 1 +m-gaming.tk, 1 +m-generator.com, 1 +m-h-b.fr, 1 +m-hydravlika.com.ua, 1 +m-idea.jp, 1 +m-kleinert.de, 1 +m-mail.fr, 1 +m-monitor.pl, 1 +m-net.de, 1 +m-office.pl, 1 +m-team.cc, 1 +m-warrior.tk, 1 +m.directory, 1 +m.facebook.com, 1 +m.mail.ru, 1 +m.me, 1 +m0t0k1ch1.com, 1 +m0v0.com, 1 +m132.eu, 1 +m134.eu, 1 +m1gun.tk, 1 +m1hax.uk, 1 +m23cal.eu, 1 +m271809.vip, 1 +m2epro.com, 1 +m2h-fiscaliste.fr, 1 +m2il.co, 1 +m2international.com, 1 +m2os.com, 1 +m2tm.fr, 1 +m3-gmbh.de, 1 +m30365.com, 1 +m365.co, 1 +m36533.com, 1 +m42-gmbh.de, 1 +m4all.gr, 1 +m4g.ru, 1 +m4rcus.de, 1 +m5197.co, 1 +m6729.co, 1 +m6729.com, 1 +m6957.co, 1 +m6pub.fr, 0 +m7rxx.com, 1 +m81365.com, 1 +m82365.com, 1 +m8593.com, 1 +m9297.co, 1 +m9297.com, 1 +m9397.com, 1 +m9721.com, 1 +m9728.co, 1 +ma-eir.nl, 1 +ma-maison-container.fr, 1 +ma-ze-linux.tk, 1 +ma2t.com, 1 +maagdesigns.com.uy, 1 +maahchepen.tk, 1 +maailm.tk, 1 +maaldrift.tk, 1 +maalexi.com, 1 +maaret.de, 1 +maarivpn.com, 1 +maartenderaedemaeker.be, 1 +maartenvandekamp.nl, 1 +maasstaddinerexpres.nl, 1 +maatwerkopruimcoaching.nl, 1 +maatwerkzorgcoaching.nl, 1 +maavicorp.com, 0 +maaya.jp, 1 +mabankonline.com, 1 +mabulledu.net, 1 +mabusalah.tk, 1 +mac-i-tea.ch, 0 +mac-service-stockholm.se, 1 +mac-servicen.se, 1 +mac-support.nu, 1 +mac-support.se, 1 +mac-world.pl, 1 +mac.biz.tr, 1 +mac.osaka.jp, 1 +macabacus.com, 1 +macangus-wainwright.com, 1 +macaos.com, 1 +macapflag.com, 1 +macappstudio.com, 1 +macappstudiobridge.com, 1 +macaque.io, 0 +macarenagomezfan.tk, 1 +macaroons.tk, 1 +macaroonshindig.tk, 1 +macautocouture.ga, 1 +macautocouture.gq, 1 +macawos.com, 1 +macaws.org, 1 +macbook.es, 1 +macc.org.my, 1 +maccabi-dent.com, 1 +macdj.tk, 1 +macedonian-hotels.com.mk, 1 +macedonian-hotels.mk, 1 +macehead.tk, 1 +maceinturecuir.com, 1 +maces-net.de, 1 +macgeneral.de, 1 +macgenius.com, 1 +mach-politik.ch, 1 +macha.cloud, 1 +machbach.com, 1 +machbach.net, 0 +machetewp.com, 1 +machiavelli.tk, 1 +machikka.com, 0 +machin.email, 1 +machinatio.ga, 1 +machine.email, 1 +machineaecrire.fr, 1 +machinebazar.com, 1 +machineidle.com, 1 +machinetransport.com, 1 +machissenefre.ga, 1 +macho-i-botan.tk, 1 +machon.biz, 1 +machtweb.de, 1 +machu-picchu.nl, 1 +machupicchu.tk, 1 +maciej.ml, 1 +macil.tech, 1 +macinyasha.net, 1 +macioszektv.eu, 1 +macji-raj.si, 1 +mack.space, 1 +mackanz.tk, 1 +mackenziedatastream.ca, 1 +macker.io, 1 +mackeysack.com, 1 +mackinawil.gov, 1 +macksproductions.in, 1 +mackungfu.org, 1 +maclafferty.be, 1 +maclemon.at, 1 +macleod.io, 1 +macnemo.de, 1 +macnetwork.eu, 0 +macnetwork.fr, 0 +macnetwork.net, 0 +macnews.me, 1 +macnugget.org, 1 +maco.org.uk, 1 +macon.de, 1 +maconcountymo.gov, 1 +maconnerie-dcs.ch, 1 +macosx86.ml, 1 +macosxfilerecovery.com, 1 +macpress.com.br, 1 +macramos.co.za, 1 +macreosolutions.com, 1 +macreports.com, 1 +macros.co.jp, 1 +macroseo.tk, 1 +macslure.com, 1 +macsupportnacka.se, 1 +macsupportstockholm.se, 1 +macupdate.com, 1 +macvcure.com, 1 +macx.cc, 1 +mad-fabrikken.dk, 1 +mad.ninja, 1 +madadmin.com, 1 +madae.nl, 1 +madamasr.com, 1 +madamcougar.com, 1 +madameblueimages.com, 1 +madamecolette.fr, 1 +madamegarage.nl, 1 +madampastry.com, 1 +madars.org, 0 +madbicicletas.com, 1 +madbin.com, 1 +madbouncycastles.co.uk, 1 +madcs.nl, 1 +maddi.biz, 1 +maddin.ga, 1 +maddistonevangelical.co.uk, 1 +maddreefer.com, 1 +made-dwell.com, 1 +made-in-auto.com, 1 +made-in-earth.co.jp, 1 +made-to-usb.com, 1 +made.md, 1 +madebydusk.com, 0 +madebyhand.art, 1 +madebyshore.com, 1 +madebythijmen.nl, 1 +madebyvasilis.site, 1 +madecenter.com.br, 1 +madeconsultingsrl.it, 1 +madedwell.com, 1 +madeglobal.com, 1 +madeinbarcelona.com, 1 +madeincana.com, 1 +madeinolive.com, 0 +madeinrussia.com, 1 +madeinstudio3.com, 1 +madeintucson.org, 1 +madeira.link, 1 +mademoe.com, 1 +maden.com, 1 +madepalestine.com, 1 +mader.jp, 1 +maderasbrown.com, 1 +madewellwoodworks.com, 1 +madewithopendata.org, 1 +madhawaweb.tk, 1 +madhyrecords.com, 1 +madian.tk, 1 +madin.ru, 1 +madinina.tk, 1 +madirc.net, 1 +madisoncountyhelps.com, 1 +madisonent-facialplasticsurgery.com, 1 +madisonivy.space, 1 +madisonprocaccini.tk, 1 +madisonsjewelersorlando.com, 1 +madisonsquarerealestate.com, 1 +madkids.ga, 1 +madlandezboard.tk, 1 +madler.com.ua, 1 +madluging.tk, 1 +madmar.ee, 1 +madmax-store.gr, 1 +madmenmedia.cz, 1 +madnetwork.org, 1 +madoka.nu, 1 +madokami.net, 1 +madokami.pw, 1 +madonnadellafibra.gq, 1 +madprod.tk, 1 +madpsy.uk, 1 +madrants.net, 1 +madrasareforms.cf, 1 +madreacqua.org, 1 +madreluna.it, 1 +madreshoy.com, 1 +madridagency.com, 1 +madridartcollection.com, 1 +madscientistwebdesign.com, 1 +madsgencydemo.com, 1 +madskauts.tk, 1 +madskills.tk, 1 +madsstorm.dk, 1 +madteam.tk, 1 +madtec.de, 1 +madtown.tk, 1 +maduracion.com, 1 +maduradas.info, 1 +maduradas.net, 1 +madurasfollando.online, 1 +madviewer.tk, 1 +madwarlock.com, 1 +mae-berlinistanbul.com, 1 +maedchenflohmarkt.at, 1 +maedchenflohmarkt.de, 1 +maeln.com, 1 +maelstrom-fury.eu, 1 +maelstrom.ninja, 1 +maeplasticsurgery.com, 1 +maeprototipi.it, 1 +maerzpa.de, 1 +maesinox.be, 1 +maeterlinck100.be, 1 +maev.si, 1 +maevelyfotografia.com, 1 +maewongaming.tk, 1 +maff.co.uk, 1 +maff.scot, 1 +mafia-penguin.club, 1 +mafia-web.tk, 1 +mafia.network, 1 +mafiaclan.tk, 1 +mafiaclub.ml, 1 +mafiaforum.de, 1 +mafiamohaa.tk, 1 +mafiapenguin.club, 1 +mafiasi.de, 1 +mafondue.ch, 0 +mafy.fi, 1 +mag-led.com, 1 +maga.host, 1 +magaconnection.com, 1 +magadan.gq, 1 +magadan.ml, 1 +magaliff.net, 1 +magaria.ml, 1 +magasindejouets.com, 1 +magasinsalledebain.be, 1 +magasinsalledebain.fr, 1 +magasinsalledebains.be, 1 +magasinsalledebains.fr, 1 +magasinsenfrance.com, 1 +magaso.tk, 1 +magazilla.ga, 1 +magazin3513.com, 1 +magazin4ik.ga, 1 +magazinecards.ga, 1 +magazinedabeleza.net, 1 +magazinedotreino.com.br, 1 +magazone.ml, 1 +magbt.net, 1 +magdafornal.pl, 1 +magdalena-pulawska.pl, 1 +magdalenabus.tk, 1 +magdalenatransa.tk, 1 +magdeburg.directory, 1 +magdic.eu, 1 +magebit.com, 1 +magebrawl.com, 1 +magel.io, 1 +magellan-met.ru, 1 +magenbrot.net, 0 +magenda.sk, 1 +magenta-health.com, 1 +magentaize.net, 1 +magentoeesti.eu, 1 +magepro.fr, 1 +magescobd.com, 1 +magewell.nl, 1 +maggie-shaw.co.uk, 0 +maggie.com, 1 +maggiemcgee.tk, 1 +maggot.cf, 1 +magi-cake.com, 1 +magiamgiatot.tk, 1 +magic-cards.info, 1 +magic-cheerleading.tk, 1 +magic-photo-events.fr, 1 +magical-secrets.com, 1 +magical.rocks, 1 +magicalminkies.com, 1 +magicalwishes.tk, 1 +magicamulet.me, 1 +magicball.co, 1 +magicball.ga, 1 +magicbar.tk, 1 +magicbeanschool.com, 1 +magicbroccoli.de, 1 +magicbullets.com, 1 +magiccards.info, 1 +magicdaysomagh.co.uk, 1 +magicdlp.com, 1 +magiciansofchaos.tk, 1 +magicitaca.com, 1 +magicjudges.org, 1 +magiclen.org, 1 +magicline.com, 1 +magiclogix.com, 1 +magicnatura.ro, 1 +magicnethosting.com, 1 +magicomotor.com, 1 +magicorama.com, 1 +magicskillet.com, 1 +magicspaceninjapirates.de, 1 +magicstay.com, 1 +magictable.com, 1 +magicvaporizers.at, 1 +magicvaporizers.be, 1 +magicvaporizers.co.uk, 1 +magicvaporizers.com, 1 +magicvaporizers.cz, 1 +magicvaporizers.de, 1 +magicvaporizers.dk, 1 +magicvaporizers.ee, 1 +magicvaporizers.es, 1 +magicvaporizers.fi, 1 +magicvaporizers.fr, 1 +magicvaporizers.gr, 1 +magicvaporizers.hr, 1 +magicvaporizers.hu, 1 +magicvaporizers.ie, 1 +magicvaporizers.it, 1 +magicvaporizers.lu, 1 +magicvaporizers.nl, 1 +magicvaporizers.pl, 1 +magicvaporizers.pt, 1 +magicvaporizers.se, 1 +magicvaporizers.si, 1 +magicvaporizers.sk, 1 +magicvodi.at, 1 +magikbyte.com, 1 +magilio.com, 1 +magiskmanager.com, 1 +magisterjuris.com, 1 +magisternegi.tk, 1 +magliner.com, 1 +magnacarebroker.com, 1 +magnacumlaude.co, 1 +magnamus.it, 1 +magnate.co, 1 +magnatronic.com.br, 1 +magnes.priv.pl, 1 +magnesium-biomed.ch, 1 +magnesy-neodymowe.com.pl, 1 +magnesy-neodymowe.pl, 1 +magnesy-tanio.net, 1 +magnesy.de, 1 +magnesy.net.pl, 1 +magnesy.priv.pl, 1 +magnetgaming.com, 1 +magnetic.su, 1 +magneticanvil.com, 1 +magneticarrow.com, 1 +magneticarrowdev.com, 1 +magneticattraction.com.au, 1 +magneticmoney.de, 1 +magnetoscopio.tk, 1 +magnetoterapiapertutti.com, 1 +magnetpass.uk, 1 +magnets.jp, 1 +magnetto.ga, 1 +magnettracker.com, 1 +magnewsblog.com, 1 +magnewspress.com, 1 +magniezetassocies.fr, 1 +magnificentdata.com, 1 +magniflood.com, 1 +magnitola.ml, 1 +magnoliadoulas.com, 1 +magnoliastrong.com, 1 +magnunbaterias.com.br, 1 +magnusonhomes.com, 1 +magodasredes.com.br, 1 +magonote-nk.com, 1 +magosmedellin.com, 1 +magraebela.com, 1 +magravsitalia.com, 1 +magsdata.com, 1 +magu.kz, 1 +mague.org, 1 +maguire.email, 1 +maguire.tk, 1 +magwin.co.uk, 1 +magyarepitok.hu, 1 +mah-nig.ga, 1 +mahabharat.tk, 1 +mahadihasan.cf, 1 +mahadsunnah.com, 1 +mahadulmuneer.org, 1 +mahalaraibanda.ro, 1 +mahalux.com, 1 +mahalux.cz, 1 +mahanpt.com, 1 +mahaskacountyia.gov, 1 +mahatmayoga.org, 1 +mahawi.sk, 1 +mahayana.tk, 1 +mahealthsurveys.gov, 1 +mahgu.com, 1 +mahjong-navi.com, 1 +mahjong.org, 1 +mahjonggames.tk, 1 +mahjongrush.com, 1 +mahler.io, 1 +mahmalci.net, 1 +mahmoudeeb.com, 1 +mahrer.net, 1 +mahurivaishya.co.in, 1 +mahurivaishya.com, 1 +maiaimobiliare.ro, 1 +maichun.info, 1 +maid.tk, 1 +maidenliput.fi, 1 +maidenworld.tk, 1 +maidoty.net, 1 +maiebanatulfruncea.com, 1 +maiet.net, 1 +maigesellschaft-lammersdorf.de, 1 +maijia800.com, 1 +maik-mahlow.de, 1 +maikhuong.tk, 1 +maikolfish.it, 1 +maikoloc.com, 1 +mail-de.jp, 1 +mail-delivery.ga, 1 +mail-ink.com, 1 +mail-rotter.de, 1 +mail-settings.google.com, 1 +mail.ac, 1 +mail.com, 1 +mail.de, 1 +mail.google.com, 1 +mail.storage, 1 +mail.tm, 1 +mail.yahoo.com, 0 +mail180.com, 1 +mail4you.in, 1 +mailanyzer.com, 1 +mailbase.cf, 1 +mailbox.mg, 1 +mailbox.org, 1 +mailboy.ml, 1 +mailcubexs.tk, 1 +maildrops.tk, 1 +mailer.me, 1 +mailex.cf, 1 +mailexpresso.tk, 1 +mailexx.ga, 1 +mailexx.gq, 1 +mailexx.ml, 1 +mailfence.com, 1 +mailflank.com, 0 +mailgun.com, 1 +mailhardener.com, 1 +mailinabox.email, 1 +mailinabox.ml, 1 +mailinaitor.tk, 1 +mailingproduct.tk, 1 +mailinizer.com, 1 +mailinyzer.com, 1 +mailjunkey.tk, 1 +maillady-susume.com, 1 +mailmaid.de, 1 +mailman.ml, 1 +mailmaster.tk, 1 +mailmerc.com, 1 +mailmum.io, 1 +mailnara.co.kr, 1 +mailon.ga, 1 +mailpenny.com, 1 +mailsend.ml, 1 +mailstart.ga, 1 +mailsupport.cz, 1 +mailtelligent.com, 1 +mailto.space, 1 +mailtobiz.tk, 1 +mailtracker.ml, 1 +mailtrap.io, 1 +mailum.org, 0 +mailwala.tk, 1 +mailway.io, 1 +mailxpress.ga, 1 +main1.host, 1 +mainblades.com, 1 +mainechiro.com, 1 +mainelosap.gov, 1 +mainframeserver.space, 1 +mainhattan-handwerker.de, 1 +mainlined.org, 1 +mainquest.org, 1 +mainstreetartisans.com, 1 +maintainyourwebsite.help, 1 +maintenance-traceur-hp.fr, 1 +maintenancemtp.fr, 1 +mainzelmaennchen.net, 1 +maioresemelhores.com, 1 +mairie-landry.com, 1 +mairie-sornay.fr, 1 +mairiedemoncelsurseille.com, 1 +mairimcosmetics.com, 1 +maisallianz.com, 1 +maisapanama.com, 1 +maiscelular.com.br, 1 +maiscuidar.com, 1 +maisecom.com.br, 1 +maisempregonet.com, 1 +maisgasolina.com, 1 +maisie.nl, 1 +maison-coutin.com, 1 +maison-du-savon-de-marseille.fr, 1 +maison-haimard.fr, 1 +maisonanimale.com.br, 1 +maisondoree.be, 1 +maisondureau.fr, 1 +maisonmere.group, 1 +maisonpaulmier.fr, 1 +maisretorno.com, 1 +maisvitaminas.com.br, 1 +maitemerino.net, 1 +maitheme.com, 1 +maiti.info, 1 +maitlandcashforcars.com.au, 1 +maitrise-orthopedique.com, 1 +maitriser-son-stress.com, 1 +maizuru-ongaku-kan.com, 1 +majahoidja.ee, 1 +majalmirasol.com, 1 +majameer.com, 1 +majaweb.cz, 1 +majemedia.com, 1 +majesnix.org, 1 +majesticsailing.com, 1 +majestio.tk, 1 +majid.info, 1 +majisign.co.uk, 1 +majkassab.com, 1 +majkassab.net, 1 +majkassab.org, 1 +majkl.me, 1 +majkl.xyz, 1 +majkl578.cz, 1 +majkyto.cz, 1 +majlovesreg.one, 1 +majolka.com, 1 +majorpaintingco.com, 1 +majorpussycum.com, 1 +makaleci.com, 1 +makalu.me, 1 +makangratis.id, 1 +makani.be, 1 +makariza.com.co, 1 +makasetesan.com, 1 +make-your-own-song.com, 1 +make.org, 1 +makeagif.com, 1 +makechanges.com.au, 1 +makecharcoal.com, 1 +makedin.net, 1 +makedonija.net.mk, 1 +makefoodrecipes.com, 1 +makeh2o.com, 1 +makeit-so.de, 0 +makeitshort.ml, 1 +makelovenotporn.tv, 1 +makemejob.com, 1 +makemillion.tk, 1 +makemoney-plan.tk, 1 +makemusic-asia.com, 1 +makenaiyo-fx.com, 1 +makephpsites.com, 1 +makepro.net, 1 +makera.ga, 1 +makerdao.com, 1 +makermiles.com, 1 +makermiles.net, 1 +makermiles.org, 1 +makesenseofdata.co.uk, 1 +maketheneighborsjealous.com, 1 +makeupevelinua.ga, 1 +makeupillusion.com, 1 +makeuplove.nl, 1 +makeurbiz.com, 1 +makeurl.ml, 1 +makewebbetter.com, 1 +makfra.com, 1 +makhmudov.net, 1 +maki-chan.de, 1 +makinen.ru, 1 +makingmemoney.ml, 1 +makingmoneyathome.tk, 1 +makingmoves.gq, 1 +makkiyaz.tk, 1 +makkusu.photo, 1 +makkyon.com, 1 +maklerinfo.biz, 1 +makmasks.com, 1 +makocontrols.com, 1 +makohu.tk, 1 +makonet.com.au, 1 +makos.jp, 1 +makowitz.cz, 1 +maksa.ga, 1 +maksatmoda.com, 1 +maksimmrvica.tk, 1 +maksimyugai.com, 1 +maksmedia.tk, 1 +maksonshop.ga, 1 +maksoud-karim.net, 1 +maksport.ml, 1 +maksutov.tk, 1 +maktoob.search.yahoo.com, 0 +makuonline.tk, 1 +makura.fun, 1 +malabarismo.tk, 1 +malachiteauth.com, 1 +maladie-autoimmune.fr, 1 +malahov.tk, 1 +malamutedoalasca.com.br, 1 +malangartchannel.com, 1 +malardalenvvs.se, 1 +malariaadvice.gq, 1 +malariabehaviorsurvey.org, 1 +malash.me, 0 +malasuk.com, 1 +malawi-portal.de, 1 +malaysia.cf, 1 +malaysia.search.yahoo.com, 0 +malaysiabrands.com.my, 1 +malaysiainternship.my, 1 +malaysian.dating, 1 +malaysianews.ml, 1 +malaysiasentral.com, 1 +malcathatochen.co.il, 1 +malcolmellis.com, 1 +maldenvotes.com, 1 +maldives-showing.cf, 1 +maldives.cx, 1 +male-cats-spray.ml, 1 +malecondemusique.fr, 1 +maleevcues.com, 1 +malek3d.com.br, 1 +malenaamatomd.com, 1 +malenyflorist.com.au, 1 +maleperformancepills.com, 1 +malermeister-haussmann.de, 1 +malermeister-tichnau.de, 1 +malesoowki.blog, 1 +maleylabapplications.org, 1 +malezan.com, 1 +malgraph.net, 1 +malhasgusmao.com.br, 1 +maliar.fr, 1 +malibaby.ga, 1 +malibu-electric.com, 1 +malibuelectrical.com, 1 +malibuexteriorlighting.com, 1 +malibulingerie.com, 1 +malibumodas.com.br, 1 +maliciousdeath.tk, 1 +malie.it, 1 +malik.holdings, 1 +malik.id, 1 +malikdeenarislamicacademy.tk, 1 +malikussa.id, 1 +malikussaid.com, 1 +malimusavirler.tk, 1 +malinaclub.com, 1 +malinheadview.ie, 1 +malisheva-blog.cf, 1 +malisheva-blog.ga, 1 +maliskovik.si, 1 +malkaso.com.ua, 1 +malkoun.com, 1 +mall.cz, 1 +mall.hr, 1 +mall.hu, 1 +mall.pl, 1 +mall.sk, 1 +mallach.net, 1 +mallasvita.com, 1 +mallgastronomico.com.ar, 1 +mallner.me, 1 +mallonline.com.br, 1 +mallpass.ga, 1 +malmyzh.tk, 1 +malond.com, 1 +malphisruul.de, 1 +malrox.com, 1 +malscan.com, 0 +malsignature.com, 1 +malsoftware.com, 1 +malta-firma.com, 1 +maltasite.tk, 1 +maltaultrastifo.tk, 1 +maltegegner.de, 0 +malu.style, 1 +malufs.com.br, 1 +malvertise.xyz, 1 +malvinas-falklands.tk, 1 +malvy.kiev.ua, 1 +malwar.ee, 1 +malwar.eu, 1 +malware.watch, 1 +malwaredevil.com, 1 +malwareincidentresponse.com, 1 +malwareinvestigator.gov, 1 +malwarekillers.com, 1 +malwaretips.com, 1 +malwarewise.com, 1 +malworld.me, 1 +malwr.ee, 1 +malypiesekzuzi.pl, 1 +malysvet.net, 0 +mamabali-spa.com, 1 +mamabatataya.com, 1 +mamabepo.com, 1 +mamadoma.com.ua, 1 +mamaisonsherby.ca, 1 +mamaliefde.nl, 1 +mamamoet.ru, 1 +mamanakormit.tk, 1 +mamanecesitaungintonic.com, 1 +mamanura.tk, 1 +mamasorganizedchaos.com, 1 +mamaxi.org, 1 +mamaznaet.ml, 1 +mambas.cn, 1 +mambos.tk, 1 +mamburao.tk, 1 +mame.cl, 1 +mamijaclean.tk, 1 +mammabelly.com.br, 1 +mammaklader.tk, 1 +mammal-taxonomy.tk, 1 +mammals.net, 1 +mammaw.com, 1 +mammooc.org, 1 +mammothlakesmls.net, 1 +mamochka.org.ua, 0 +mamodsteam.tk, 1 +mamohe.de, 1 +mamoni.co, 1 +mamospienas.lt, 1 +mamradost.sk, 1 +mamsds.com, 1 +mamtapark.tk, 1 +mamuko.nl, 1 +mamunlyric.tk, 1 +man-stuff.co.uk, 1 +man-trailer.com, 1 +man3s.jp, 0 +mana.ee, 1 +manach.net, 1 +manage.cm, 1 +manageathome.co.uk, 1 +managedhosting.de, 1 +managedserver.it, 1 +managedservicesraleighnc.com, 1 +management-companie.ro, 1 +managementboek.nl, 1 +managementfeedback.com, 1 +managementforstartups.com, 0 +manageprefs.com, 1 +manageprojects.com, 0 +manager.linode.com, 0 +managment.io, 1 +managr.net, 1 +manalu.cz, 1 +manaonetrading.com, 1 +manasakcijas.lv, 1 +manaspaul.tk, 1 +manatees.com.au, 1 +manatees.net, 1 +manav-it.de, 1 +manavgabhawala.com, 1 +manawill.jp, 1 +manawithtea.com, 1 +manbetx1998.live, 1 +manboy.tk, 1 +manchestertechservices.co.uk, 1 +mancrates.com, 1 +mandai-f.jp, 1 +mandai-i.jp, 1 +mandai-s.jp, 1 +mandai-sf.jp, 1 +mandai-st.jp, 1 +mandai-t.jp, 1 +mandala-book.tk, 1 +mandalatantra.com.br, 1 +mandanudes.ae, 1 +mandarinpediatrics.com, 1 +mandarinplay.tk, 1 +mandcbouncycastlehire.co.uk, 1 +mandediary.com, 1 +mandefender.tk, 1 +mandela-effect-wiki.tk, 1 +mandelaeffect.tk, 1 +mandiblackburnphoto.com, 1 +mandilabeachhotel.com, 1 +mandor.id, 1 +mandospersonalizados.com, 1 +mandrill.fr, 1 +manducoshop.com, 1 +mandynamic.gr, 1 +mandzak.com, 1 +manegehenriet.tk, 1 +maneggio.milano.it, 1 +manelli.fr, 1 +maneql.co.jp, 1 +maneql.info, 1 +manero.de, 1 +manesht.ir, 1 +manforums.com, 1 +manfredgruber.net, 1 +manfredi.io, 1 +manfredimatteo.com, 1 +manfredschafer.ch, 1 +mangabank.net, 1 +mangabank.org, 1 +mangabond.tk, 1 +mangaboxes.ml, 1 +mangacat.ga, 1 +mangafreak.tk, 1 +mangagaga.tk, 1 +mangahigh.com, 1 +mangapoi.com, 1 +mangareactor.tk, 1 +mangarosa.pt, 1 +mangaworld.gq, 1 +mangeur-de-cigogne.tk, 1 +mangga.cloud, 1 +mangnhuapvc.com.vn, 1 +mango-zajm.gq, 1 +mangomercado.com, 1 +mangoservers.tk, 1 +mangotwoke.co.uk, 1 +manguyen.de, 1 +manhassetparkdistrictny.gov, 1 +manhattan-college.com, 1 +manhattanchoralensemble.org, 1 +manhattandermatologistsnyc.com, 1 +manhattangastroenterology.com, 1 +manhattanprimarycaredoctorsnyc.com, 1 +manhole.club, 1 +manhuagui.com, 1 +mani.tw, 1 +maniacoland.com, 1 +maniadicane.com.br, 0 +maniaiti.nz, 1 +maniazul.tk, 1 +manicbouncycastles.co.uk, 1 +manicminers.tk, 1 +manicode.com, 1 +manicur-salon.tk, 1 +manicuradegel.com, 1 +manicuradegel.es, 1 +manikinuk.tk, 1 +manilacrawl.com, 1 +manilaprinciples.org, 1 +maniorpedi.com, 1 +maniosglass.gr, 1 +manipil.ch, 0 +manipurmatka.net, 1 +manito.kr, 1 +manitouspringsco.gov, 1 +manja-und-martin.de, 1 +manjaro.ru, 1 +mankans.com, 0 +mankier.com, 1 +mankomarketing.com, 1 +mann-und-maeuse.de, 1 +manneguiden.no, 1 +mannenzang.tk, 1 +mannhaarkunst.com, 1 +mannheimbloggt.tk, 1 +manns-solutions.co.uk, 1 +manoek.dynu.net, 1 +manoha-proservices.fr, 1 +manoirdecontres.com, 1 +manojsharan.me, 1 +manolitodarts.tk, 1 +manonandre-avocat.fr, 1 +manopause.com, 1 +manoro.de, 1 +manova.cz, 1 +manowarus.com, 1 +mansdell.net, 1 +mansell-law.com, 1 +mansfeld.pl, 1 +mansform.com, 1 +manshatech.com, 1 +mansionflip.com, 1 +manski.net, 1 +mansora.co, 1 +mansora.io, 1 +mansora.net, 1 +mansour.io, 1 +mansurov.tk, 1 +mansys.io, 1 +mantabiofuel.com, 1 +mantachiepharmacy.com, 1 +mantalak.com, 1 +mantaoilco.com, 1 +manteligencia.com, 1 +mantelligence.com, 1 +mantenimiento-zaragoza.com, 1 +mantenimientoimpresoras.com, 1 +mantenimientosenjardineriaypiscinasveracruz.com, 1 +manti.by, 1 +mantor.org, 0 +mantra.pictures, 1 +mantul.top, 1 +manualidadeson.com, 1 +manualidadespararegalar.online, 1 +manuall.ae, 1 +manuall.co.uk, 1 +manuall.cz, 1 +manuall.de, 1 +manuall.dk, 1 +manuall.es, 1 +manuall.fi, 1 +manuall.fr, 1 +manuall.hu, 1 +manuall.info.tr, 1 +manuall.it, 1 +manuall.jp, 1 +manuall.kr, 1 +manuall.no, 1 +manuall.pl, 1 +manuall.pt, 1 +manuall.ro, 1 +manuall.se, 1 +manuall.sk, 1 +manualscollection.com, 1 +manuel-herrmann.de, 1 +manuel-schefczyk.de, 1 +manuel7espejo.com, 1 +manuelahidalgo.org, 1 +manuelboelstler.tk, 1 +manuelcancelas.com, 1 +manuelefysiotherapeut.nl, 1 +manuelguerra.pt, 1 +manueli.de, 1 +manuelpinto.in, 1 +manuelraimo.cf, 1 +manuelrueger.de, 0 +manufacturedhomemoving.com, 1 +manufacturing.gov, 1 +manufacturinginmexico.org, 1 +manufacturingsupportgroup.co.uk, 1 +manufacturingusa.com, 1 +manulife.ca, 1 +manuscripteditorial.com, 1 +manuscriptlink.com, 1 +manusiasosial.tk, 1 +manutd.org.np, 1 +manuth.life, 1 +manwork.tk, 1 +manyetikboya.com, 1 +manyhotfiesta.ml, 1 +manylots.ru, 1 +manyproservices.com, 1 +manytubes.ga, 1 +maocular.org, 1 +maomao.blog, 1 +maomihz.com, 1 +maone.net, 1 +maorx.cn, 1 +maosensanguentadasdejesus.net, 1 +maowtm.org, 1 +maozedong.red, 1 +map4erfurt.de, 1 +map4jena.de, 1 +mapado.ru, 1 +mapasmundi.com.br, 1 +mapausenaturelle.fr, 1 +mapblender.com, 1 +mapchange.org, 1 +mapgues.net, 1 +maplebgm.cc, 1 +maplegate.info, 1 +maplehome.tk, 1 +mapletime.com, 1 +maplewood.tk, 1 +mappingfutures.org, 1 +mappingspaceperu.com, 1 +mapresidentielle.fr, 1 +mapstack.org, 1 +mapuut.net, 1 +maquena.org, 1 +maquetting.com, 1 +maquinariaspesadas.org, 0 +maquinasdecoserplus.com, 1 +maquinasperfectas.tk, 1 +maquinasquepiensan.tk, 1 +mar-eco.no, 1 +mar.pt, 1 +marabumadrid.com, 0 +marabunta.io, 1 +maracarlinicourses.com, 1 +maracit.tk, 1 +marakovits.net, 1 +maransurology.com, 1 +marasma.tk, 1 +marauderos.tk, 1 +marble.com, 1 +marbledentalcentre.ca, 1 +marblemosaics.ga, 1 +marblenexus.de, 1 +marbogardenlidkoping.se, 1 +marbree.eu, 1 +marbrerie-segur.fr, 1 +marc-beninca.fr, 1 +marc-hammer.de, 1 +marc-hoffrichter.de, 1 +marc-schlagenhauf.de, 0 +marc.info, 1 +marcaixala.me, 1 +marcanhoury.com, 1 +marcannmentalhealth.com, 1 +marcbeije.com, 1 +marcberndtgen.de, 1 +marcceleiro.cat, 1 +marcceleiro.com, 1 +marceau.ovh, 1 +marcel-preuss.de, 1 +marcel-veronetzki.de, 1 +marcel-waldvogel.ch, 1 +marcelabarrozo.tk, 1 +marcelino.cf, 1 +marcelinofranchini.com, 1 +marcelinofranchini.eu, 1 +marcelinofranchini.info, 1 +marcelinofranchini.net, 1 +marcelinofranchini.org, 1 +marceljeannin.com, 1 +marcelkooiman.com, 1 +marcell-jansen.tk, 1 +marcelmarnitz.com, 1 +marcelofernandez.tk, 1 +marcelpreuss.de, 1 +marcelsiegert.com, 1 +marcelwaldvogel.ch, 1 +marcelwiedemeier.com, 1 +marcelwolf.coach, 1 +marcenariaembh.com.br, 1 +marcgoertz.de, 1 +marche-contre-monsanto.ch, 0 +marche-nordic-jorat.ch, 0 +marchellenevers.tk, 1 +marcheslep.org.uk, 1 +marchhappy.tech, 0 +marchinghatters.tk, 1 +marchukov.com, 1 +marcianoandtopazio.com, 1 +marcillacetfils.fr, 1 +marclange.net, 1 +marco-burmeister.de, 1 +marco-goltz.de, 1 +marco-hegenberg.net, 1 +marco-reitmeier.de, 1 +marco-s.net, 1 +marcocasoni.com, 1 +marcoececilia.it, 1 +marcohager.de, 1 +marcoherten.com, 1 +marcoklomp.nl, 1 +marcomooij.net, 1 +marcopierrard.fr, 1 +marcopolo-restaurant.com, 1 +marcoreitmeier.de, 1 +marcositaliandeli.co.uk, 1 +marcosocio.com, 0 +marcosteixeira.tk, 1 +marcus-scheffler.com, 1 +marcus.pw, 0 +marcusburghardt.tk, 1 +marcusds.ca, 1 +marcusporter.tk, 1 +marcusstafford.com, 1 +marcyacademiademusica.com.ar, 1 +mardelcupon.com, 1 +mardigrasnapkins.com, 1 +mare-sylt.de, 1 +mare92.cz, 1 +marechal-company.com, 1 +marei.ad, 1 +marek.su, 1 +marekherel.cz, 1 +marekkorlak.com, 1 +marelijah.org, 1 +maresencial.com, 1 +marex.host, 1 +marga-marga.tk, 1 +marga.tech, 1 +margagriesser.de, 1 +margan.ch, 1 +margaret.land, 1 +margaridamendessilva.com, 1 +margatroid.com, 1 +margatroid.net, 1 +margaux-perrin.com, 1 +margays.de, 1 +margherita.cl, 1 +marglotfabadi.com, 1 +margo-co.ch, 0 +margo.ml, 1 +margolis.gq, 1 +margots.biz, 1 +margots.life, 1 +margots.tech, 1 +marguerite-maison.fr, 1 +marhobateren.tk, 1 +maria-blanco.tk, 1 +maria-galland.cz, 1 +maria-kirilenko.tk, 1 +mariaelisaejunior.ga, 1 +mariafernanda.com.br, 1 +mariage-protestant.ch, 1 +mariagealamontagne.com, 1 +mariages.net, 1 +mariagiovannaluini.it, 1 +mariahandnasty.com, 1 +mariaisabel.tk, 1 +marialopez.tk, 1 +marianatherapy.com, 1 +marianelaisashi.com, 1 +mariannenan.nl, 1 +mariannethijssen.nl, 1 +marianrivera.tk, 1 +mariapietropola.com, 1 +mariasavchenko.com, 1 +mariasemarias.com.br, 1 +mariasilverbutterfly.com, 1 +mariaterbildt.tk, 1 +maridonlaw.com, 1 +marie-pettenbeck-schule.de, 1 +marie.club, 1 +mariecurie.tk, 1 +mariedanielle.it, 1 +mariehane.com, 1 +mariejulien.com, 1 +marielinepitre.com, 1 +marielouise-oliwkiewicz.nl, 1 +marielouise.tk, 1 +mariemiramont.fr, 1 +mariereichl.cz, 1 +mariescountymo.gov, 1 +marietrap.ch, 1 +marijnfidder.nl, 1 +marijuanajobscannabiscareers.com, 1 +marijuanamed420.com, 1 +marikafranke.de, 1 +mariliaveiga.com.br, 1 +marilsnijders.nl, 1 +marilynhartman.com, 1 +marilynmartin.com.au, 1 +marilynstreats.com, 1 +marin-business-center.ch, 0 +marin-dom.ru, 0 +marin-tullet.com, 0 +marina-group.tk, 1 +marina-tsvetaeva.ml, 1 +marinamontana.net, 1 +marinapetruzio.it, 1 +marinapozzoli.tk, 1 +marinarinaldi.ml, 1 +marinasmad.com, 1 +marinat.de, 1 +marinat2012.de, 1 +marinazarza.es, 1 +marinbusinesscenter.ch, 0 +marine.gov, 1 +marinecadastre.gov, 1 +marinekaplama.com, 1 +marinelausa.com, 0 +marinelife.store, 1 +marinella.tk, 1 +marinershousecalstock.com, 1 +marinettecountywi.gov, 1 +maringalazer.com.br, 1 +mario-ancic.tk, 1 +marioabela.com, 1 +marioberluchi.by, 0 +mariogarcia.tk, 1 +mariogb.com, 1 +mariogeckler.de, 0 +marioncountyohio.gov, 1 +marioserver.ml, 1 +mariouniversalis.fr, 1 +mariowiki.com, 1 +mariposah.ch, 1 +marisamorby.com, 0 +marisasitaliankitchen.com, 1 +mariskavankasbergen.nl, 1 +marisolcu.org, 1 +maritime-mea.com, 1 +maritlarsen.ml, 1 +maritlarsen.tk, 1 +marivalemotions.com, 1 +mariviolin.com, 1 +marix.ro, 1 +marjeta-gurtner.ch, 1 +marjoleindens.be, 1 +marjon.photography, 1 +marjonruns.nl, 1 +marjoriebarretto.tk, 1 +marjoriecarvalho.com.br, 1 +mark-armstrong-gaming.com, 1 +mark-dietzer.de, 1 +mark-goeder-tarant.com, 1 +mark-semmler.de, 1 +mark1998.com, 1 +markaconnor.com, 1 +markacutt.com, 1 +markandrosalind.co.uk, 1 +markantalyamasajsalonu-bayanmasoz-cim.cf, 1 +markantoffice.com, 1 +markdain.net, 1 +markdaine.com, 1 +markdaine.net, 1 +markdixon.name, 1 +markdown.help, 1 +markecubanos.com, 1 +markellos-olive.gr, 1 +markenet.co, 1 +markentier.tech, 1 +markepps.com, 1 +market-vanna.ru, 1 +market.android.com, 1 +marketbasket.tk, 1 +marketcavalli.it, 1 +marketespace.fr, 0 +marketfeed.news, 1 +marketgarden.tk, 1 +marketgrid.ml, 1 +marketgrid.tk, 1 +marketia.ml, 1 +marketing-2.de, 1 +marketing-advertising.eu, 1 +marketing1-0-1.com, 1 +marketing4trends.com, 1 +marketing91.com, 1 +marketingautomationplan.nl, 1 +marketingbab.com, 1 +marketingbrandingnews.com, 1 +marketingbrandingnews.net, 1 +marketingco.nl, 1 +marketingconcafe.com, 1 +marketingdesignu.cz, 1 +marketingdigitalefisiente.com, 1 +marketingforfood.com, 1 +marketinghaters.com, 1 +marketingmd.com, 1 +marketingmind.in, 1 +marketingpalace.tk, 1 +marketingproducts.review, 1 +marketingprofesszorok.hu, 1 +marketingseo.fr, 1 +marketingstrategy.gq, 1 +marketingsuite.tk, 1 +marketingtrendnews.com, 1 +marketingvirtuales.com, 1 +marketingypublicidaddigital.com.mx, 1 +marketio.ai, 1 +marketizare.ro, 1 +marketking.ga, 1 +marketplace.org, 1 +marketplace.tf, 1 +marketplacestrategy.com, 1 +marketsearch.ga, 1 +marketvalue.gq, 1 +markf.io, 1 +markfietje.eu, 1 +markfisher.photo, 1 +markfordelegate.com, 1 +markhaehnel.de, 1 +markhamfair.ca, 1 +markholden.guru, 1 +markhoodphoto.com, 1 +markhoodwrites.com, 1 +markhornsby.co.uk, 1 +markhornsby.uk, 1 +markido.com, 1 +markisa.ninja, 1 +markitanova-anna.tk, 1 +markitzeroday.com, 1 +markjansen.tk, 1 +markkirkforillinois.com, 1 +markkirkforsenate.com, 1 +markkusilvennoinen.fi, 1 +marklauman.ca, 1 +marklehane.com, 1 +markllego.com, 1 +markocloud.com, 1 +markoglou.com.gr, 1 +markoh.co.uk, 1 +markprof.ru, 1 +markri.nl, 1 +markridgwell.co.uk, 1 +markridgwell.com, 1 +markrobin.de, 1 +markshroyer.com, 1 +marksm.it, 1 +marksmit.co, 1 +marksouthall.com, 1 +markstevenkirk.com, 1 +markstickley.co.uk, 1 +markt-heiligenstadt.de, 0 +marktcontact.com, 1 +marktgorman.com, 1 +marktguru.at, 1 +marktguru.de, 1 +markup-ua.com, 1 +markus-blog.de, 1 +markus-dev.com, 1 +markus-keppeler.de, 1 +markus-musiker.de, 1 +markus-ullmann.de, 1 +markus289.com, 1 +markusehrlicher.de, 1 +markusgran.de, 1 +markusjanzen.de, 1 +markusjochim.de, 1 +markuskeppeler.de, 1 +markuskeppeler.no-ip.biz, 1 +markuslintula.fi, 1 +markusribs.com, 1 +markusritzmann.ch, 1 +markusueberallassetmanagement.de, 1 +markusueberallconsulting.de, 1 +markusweimar.de, 1 +markxpdesign.ga, 1 +marl.fr, 1 +marleenjacobi.de, 0 +marlenefavela.tk, 1 +marliesfens.nl, 1 +marliesslomp.nl, 1 +marloncommunications.com, 1 +marlonlosurdopictures.com, 1 +marlosoft.net, 1 +marmaluot.com, 1 +marmista.roma.it, 1 +marmo.tk, 1 +marmotte.love, 1 +marmuif.fr, 1 +marny.eu, 1 +marocmail.ma, 1 +marocweb.tk, 1 +marokkaansearganolie.nl, 1 +marolu.one, 1 +maroquineriepirlot.be, 0 +maroshionline.tk, 1 +maroussia.tk, 1 +marpa-wohnen.de, 1 +marqperso.ch, 1 +marquepersonnelle.ch, 1 +marqueswines.co.uk, 1 +marquisepools.com, 1 +marrai.de, 1 +marriage-shrine.jp, 1 +marriageinchrist.com, 1 +marrickvilleapartments.com.au, 1 +marropax.com, 1 +marry-fox.com, 1 +mars.army, 1 +mars.navy, 1 +marsafc.tk, 1 +marsatapp.com, 1 +marseillekiteclub.com, 1 +marshaiargentina.com, 1 +marshall-allman.tk, 1 +marshallscastles.com, 1 +marshallwilson.com, 1 +marshmallow.co, 1 +marshmallow.com, 1 +marshop.tk, 1 +marsikelektro.cz, 1 +marsilioblack.tk, 1 +marsmediavideo.com, 1 +marsoftyazilim.com, 1 +marta-chat.ga, 1 +marta.uz, 0 +martasibaja.com, 1 +martel-innovate.com, 0 +martelange.ovh, 1 +martellosecurity.com, 1 +martelus.com, 1 +martemeo-wetterau.de, 1 +marten-buer.de, 1 +martensmxservice.nl, 1 +martensson.io, 1 +marthakenney.com, 1 +marthasvillemo.gov, 1 +marthus.com.br, 1 +marti201.ga, 1 +martialarts-wels.at, 1 +martialartsbrownsplains.ga, 1 +martian.community, 1 +martian.tk, 1 +martide.com, 1 +martijnschreuders.tk, 1 +martijnvanderzande.nl, 1 +martijnvdputten.tk, 1 +martin-burger.net, 1 +martin-loewer.de, 1 +martin-mattel.com, 1 +martin-prell.de, 1 +martin-renze.de, 0 +martin-smith.info, 1 +martin-weil.de, 1 +martin.vet, 1 +martinassurfdepot.tk, 1 +martinbaileyphotography.com, 0 +martinboerhof.nl, 1 +martincernac.cz, 1 +martindales.ltd.uk, 1 +martindano.com, 1 +martine.nu, 1 +martinebot.com, 1 +martinelias.cz, 1 +martineweitweg.de, 1 +martinhal.pl, 1 +martinhalresidences.com, 1 +martinhaunschmid.com, 1 +martinho.tk, 1 +martinishotpodcast.com, 1 +martinkunc.tk, 1 +martinkus.eu, 1 +martinmuc.de, 1 +martinreed.net, 1 +martins.im, 1 +martinschulze.org, 1 +martinsfamilyappliance.com, 1 +martinsferryoh.gov, 1 +martinus.cafe, 1 +martinverkerkonline.tk, 1 +martinvillalba.com, 1 +martinvillalba.com.ar, 1 +martinvillalba.info, 1 +martinvillalba.net, 1 +martinvillalba.org, 1 +martonmihaly.hu, 1 +martonveronika.tk, 1 +martstroy.ru, 1 +marturet.com, 0 +martvila.com, 1 +marufmusic.tk, 1 +maruhoi.com, 1 +maruja.tk, 1 +marulaweb.com, 1 +marustat.ru, 1 +marvaco.ga, 1 +marvelmoviemarathon.com, 1 +marvelo.cf, 1 +marvelweed.ru, 1 +marvin.is, 1 +marvin.rocks, 1 +marvingazibaric.io, 1 +marvinkeller.de, 0 +marvinschopf.com, 1 +marvinxyz.de, 1 +marvnet.design, 1 +marvnet.ga, 1 +marvnet.gq, 1 +marvnet.ml, 1 +marvnet.tk, 1 +marvnetdigital.cf, 1 +marvnetdigital.gq, 1 +marvnetdigital.tk, 1 +marvnetforum.ga, 1 +marvnetforum.gq, 1 +marvnetforum.ml, 1 +marvnetforum.tk, 1 +marw.org, 1 +marxist.party, 1 +marxists.org, 1 +marxmyths.org, 1 +marxpark.tk, 1 +mary-e-kay.tk, 1 +marycliffpress.com, 1 +marycowanceramics.com, 1 +maryeclark.com, 1 +maryeileen90.party, 1 +maryhaze.net, 1 +marykatrinaphotography.com, 1 +marylandbasementandcrawlspacewaterproofing.com, 1 +marylandtraditions.org, 1 +maryluzturismo.co, 1 +marymaloney.tk, 1 +marypatriotnews.com, 1 +marywet.net, 1 +marzio.co.za, 1 +masajeadorespremium.com, 1 +masakanibu.ga, 1 +masakigarden.com, 1 +masalaband.tk, 1 +masaloku.com.tr, 1 +masanunciosimpresos.com, 1 +masarik.sh, 1 +masaze-hanka.cz, 1 +mascarablond.tk, 1 +mascarbo.tk, 1 +mascarillas.blog, 1 +maschine.email, 1 +maschinen.email, 1 +mascorazon.com, 1 +mascosolutions.com, 1 +mascotarios.org, 1 +masdemariette.com, 1 +masdemexico.com, 1 +masduta.co, 1 +masdzub.com, 1 +maservant.net, 1 +mashairi.co.ke, 1 +mashandco.it, 1 +mashandco.tv, 1 +mashcape.com, 1 +mashek.net, 1 +mashina.world, 1 +mashonkavortu.tk, 1 +mashoom.co.uk, 1 +masiniunelte.store.ro, 1 +masiul.is, 1 +mask-skin.tk, 1 +maskerking.com, 1 +maskim.fr, 1 +maskinkultur.com, 1 +maskova.net, 1 +maskssouthafrica.co.za, 1 +maslenka.tk, 1 +maslife365.com, 1 +maslin.io, 1 +masmusica.tk, 1 +masmusicaradio.tk, 1 +masonicangelfund.org, 1 +masquerade.site, 0 +masqueradecostumes.tk, 1 +masrilanguage.tk, 1 +mass.pt, 1 +massaboutique.com, 1 +massage-colleges.com, 1 +massage-technique.tk, 1 +massage-vitalite.fr, 1 +massage-well.ch, 1 +massageandwellbeing.com, 1 +massagecoolangatta.com.au, 1 +massagecupping.com, 1 +massagegunadvice.com, 1 +massagekartan.ga, 1 +massagetainha-hanoi.com, 1 +massar.family, 1 +massazh.cf, 1 +massconsultores.com, 1 +massdesigners.net, 1 +masse.org, 1 +massflix.com, 1 +massfone.com, 1 +masshost.tk, 1 +massive.tk, 1 +massotherapeutique.com, 1 +masstercurssos.com, 1 +massvow.com, 1 +masta.ch, 0 +masta.me, 1 +mastah.fr, 1 +mastd.fr, 1 +mastd.me, 0 +mastd.onl, 1 +mastdi.eu, 1 +mastellone.us, 1 +master-net.org, 1 +master-tmb.ru, 1 +mastercardpac.com, 1 +mastercareplus-demo.com, 1 +mastercareplus-staging.com, 1 +mastercareplus-uat.com, 1 +mastercareplus.com, 1 +mastercheat.net, 1 +masterdemolitioninc.com, 1 +masterdesingweb.tk, 1 +masterdigitale.com, 1 +masterdrilling.com, 1 +masterhelenaroma.com, 1 +masterhoteis.com.br, 1 +masterin.it, 1 +masterminer.tk, 1 +masternetix.ga, 1 +masterofallscience.com, 1 +masterofbytes.ch, 1 +masterpassword.org, 1 +masterpieceitaly.co.id, 1 +masterplc.com, 1 +masterplumber.coach, 1 +masterpro1.ru, 1 +masterquest.tk, 1 +masters-burrell.co.uk, 1 +masters.black, 1 +mastersadistancia.com, 1 +mastersofmedia.nl, 1 +mastersthesiswriting.com, 1 +masterstruckingacademy.com, 1 +masterstuff.de, 1 +mastersystem.ro, 1 +mastervision.tk, 1 +masterwank.com, 1 +masterwayhealth.com, 1 +mastiffingles.com.br, 1 +mastodon.at, 1 +mastodon.blue, 0 +mastodon.co.nz, 0 +mastodon.expert, 1 +mastodon.fun, 0 +mastodon.my, 1 +mastodon.rocks, 1 +mastodon.top, 1 +mastodon.uno, 1 +mastpartners.com, 1 +maswali.com, 1 +maszdobro.pl, 1 +mat-berenbostel.de, 1 +mat-ras.com, 1 +mat.com.vn, 1 +mat.tt, 1 +mat99.dk, 1 +matanz.de, 1 +matarrosabierzo.com, 1 +matatabimix.com, 1 +matatall.com, 1 +match.audio, 1 +matcha-iga.jp, 1 +matchatea24.com, 1 +matchboxdesigngroup.com, 1 +matchday.cz, 1 +matchmadeinstubton.com, 1 +matchpointusa.com, 1 +matchupmagic.com, 1 +matdesign-prod.com, 1 +matebalazs.hu, 1 +mateball.io, 0 +matega.hu, 1 +mateidibu.org, 0 +mateiko.by, 1 +matejgroma.com, 1 +matejkosiarcik.com, 1 +matel.org, 1 +matematikkulubu.tk, 1 +matematyka.wiki, 1 +materasocial.live, 1 +materassi.roma.it, 1 +materi.co.id, 1 +materiaischiquinho.com.br, 1 +material-ui.com, 1 +material-world-fuyouhin.com, 1 +materialflow.com, 1 +materialism.com, 1 +materialyinzynierskie.pl, 1 +materiel-grand-format.fr, 1 +maternum.com, 1 +mateu.us, 1 +mateuszchyla.pl, 1 +mateuszkopytko.pl, 1 +mateuszmajewski.com, 1 +mateuszpilszek.pl, 1 +matex-tokyo.co.jp, 1 +matgauthanky.com, 1 +matglobal.tech, 1 +matgodt.no, 1 +math-coaching.com, 1 +math-colleges.com, 1 +math.hamburg, 1 +mathalexservice.info, 1 +mathavuzteknolojileri.com.tr, 1 +mathchall.net, 1 +matheball.de, 1 +mathebau.de, 1 +mathematik.rocks, 1 +matheo-schefczyk.de, 1 +mathers.ovh, 1 +mathes.berlin, 1 +matheusmacedo.ddns.net, 1 +mathewlane.com, 1 +mathfinder.org, 0 +mathhire.org, 1 +mathias.is, 1 +mathias.re, 0 +mathiasbynens.be, 1 +mathiasgarbe.de, 1 +mathiasheise.de, 1 +mathiaswagner.org, 1 +mathieuguimond.com, 1 +mathieui.net, 1 +mathijskingma.nl, 1 +mathilderegis.fr, 1 +mathis.com.tr, 1 +mathiteia.com, 1 +mathiveri.tk, 1 +mathleaks.com, 1 +mathleaks.se, 1 +maths.network, 1 +mathsai.com, 1 +mathschool.lt, 1 +mathsource.ga, 1 +mathspace.co, 1 +mathys.io, 1 +mati.gq, 1 +matiaskorhonen.fi, 0 +matijakolaric.com, 1 +matildajaneclothing.com, 1 +matildeferreira.co.uk, 1 +matinataskincare.com, 1 +matipl.pl, 1 +matjaz.it, 1 +matkuling.no, 1 +matli.com.tr, 1 +matlss.com, 1 +matocmedia.com, 1 +matok.me.uk, 1 +matome-surume.com, 1 +matopu.tk, 1 +matoutepetiteboutique.com, 1 +matov.tk, 1 +matovaya-pomada.ml, 1 +matozone.com, 1 +matpools.com, 1 +matras.ru, 1 +matratzentester.com, 1 +matrichelp.co.za, 1 +matridiana.com, 1 +matrieux.dk, 1 +matrimoni.uk, 1 +matrimonio.com, 1 +matrimonio.com.co, 1 +matrimonio.com.pe, 1 +matrimonios.cl, 1 +matrimonybest.com, 1 +matriterie-sdv.ro, 1 +matrix.org, 1 +matrixbricks.com, 1 +matrixfm.tk, 1 +matrixglobalsms.com, 1 +matrixmedia.ro, 1 +matrixread.com, 1 +matrixreq.com, 1 +matronal.ru, 0 +matsu-semi.com, 1 +matsushima-kosodate.com, 1 +matt-brooks.com, 1 +matt-royal.com.cy, 1 +matt-royal.gr, 1 +matt.ag, 1 +matt.gd, 1 +matt.re, 1 +matt.wiki, 1 +mattadams.info, 1 +mattaki.tk, 1 +mattandreko.com, 1 +mattandyana.com, 1 +mattari-app.com, 1 +mattatoio.eu, 1 +mattberryman.org, 1 +mattbiscay.com, 1 +mattcoles.io, 1 +mattconstruction.com, 1 +mattcorp.com, 1 +mattcronin.co.uk, 1 +mattdbarton.com, 1 +mattdrew.org, 1 +mattentaart.tk, 1 +matteobrenci.com, 1 +matteomarescotti.it, 1 +matterhorn-test.com, 1 +mattersource.com, 1 +mattessons.co.uk, 1 +mattferderer.com, 1 +mattforster.ca, 1 +matthecat.com, 1 +matthew-carson.info, 1 +matthew-cash.com, 1 +matthewbenchimol.com, 1 +matthewberry.co.za, 1 +matthewburket.com, 1 +matthewchapman.co.uk, 1 +matthewcollins.me, 1 +matthewfells.com, 1 +matthewgallagher.co.uk, 1 +matthewgrow.com, 1 +matthewimaniphotography.ga, 1 +matthewj.ca, 1 +matthewkenny.co.uk, 1 +matthewkerley.com, 1 +matthewljiang.com, 1 +matthewohare.com, 1 +matthewoshea.tk, 1 +matthewprenger.com, 1 +matthewsaeger.com, 1 +matthewselby.com, 1 +matthewsetter.com, 1 +matthewsfuneralhome.com, 1 +matthewthode.com, 1 +matthewthode.net, 1 +matthewthode.org, 1 +matthey.nl, 1 +matthi.coffee, 1 +matthi3u.xyz, 1 +matthias-muenzner.de, 1 +matthias-wimmer.de, 1 +matthiasadler.info, 1 +matthiasbeck.com, 1 +matthiasheil.de, 1 +matthiasmueller.me, 1 +matthiasott.com, 1 +matthiasschwab.de, 1 +matthiasweiler.de, 0 +matthieuchedidweb.tk, 1 +matthieuschlosser.fr, 1 +matthijssen.info, 1 +matti01.com, 1 +mattiascibien.net, 0 +mattisclever.com, 1 +mattknight.io, 1 +mattlaks.com, 1 +mattmccutchen.net, 1 +mattmcshane.com, 1 +mattmoorcroft.com, 1 +mattmorrissound.co.uk, 1 +mattnetwork83.com, 1 +matton-ict.nl, 1 +mattonline.me, 1 +mattprice.eu, 1 +mattprojects.com, 1 +mattrude.com, 1 +matts.wiki, 1 +matts.world, 1 +mattwservices.co.uk, 1 +matucloud.de, 1 +matuslab.net, 1 +matway.com, 1 +matway.net, 1 +matyldamost.cz, 1 +matze.org, 0 +mau.chat, 1 +mau.fi, 1 +mau.life, 1 +mau.lu, 1 +mau.photos, 1 +maubot.xyz, 1 +mauditeboisson.tk, 1 +mauerwerkstag.info, 1 +mauhalito.tk, 1 +mauldincookfence.com, 1 +mauletsmallorca.tk, 1 +maumovie.ml, 1 +maunium.net, 1 +mauracher.cc, 1 +mauran.me, 0 +maurice-walker.com, 0 +mauricechavez.tk, 1 +mauricedb.nl, 1 +mauriceje.ga, 1 +mauricio-ochmann.tk, 1 +mauriciog.com.ar, 0 +mauricioghiorzi.com.ar, 0 +mauricioquadradoconsultor.com.br, 1 +mauricioquadradocontador.com.br, 1 +mauriciosilva.tk, 1 +mauroalejandro.co, 1 +maurovacca.com, 1 +maury-moteurs.com, 1 +mausmani.tk, 1 +mausoleum.ga, 1 +maveeranpasupathi.tk, 1 +maven.ng, 1 +mavenclinic.com, 1 +mavensecurity.com, 1 +mavenvets.co.uk, 1 +mavibrasil.com.br, 1 +mavro.cf, 1 +mavro.ga, 1 +mavro.gq, 1 +mawai.com.tw, 1 +mawidabp.com, 1 +mawo.olkusz.pl, 1 +mawrex.tech, 1 +mawulihotel.com, 1 +max-apk.com, 0 +max-it.fr, 1 +max-moeglich.de, 1 +max-phone.com, 0 +max-went.pl, 1 +max.gov, 1 +max00365.com, 1 +max0365.com, 0 +max11365.com, 0 +max1365.com, 0 +max22365.com, 0 +max2365.com, 0 +max33365.com, 0 +max3365.com, 0 +max4365.com, 0 +max44365.com, 0 +max5365.com, 0 +max55365.com, 0 +max6365.com, 0 +max66365.com, 0 +max77365.com, 0 +max8365.com, 0 +max88365.com, 0 +max9365.com, 0 +maxb.fm, 1 +maxbeenen.de, 1 +maxbruckner.de, 1 +maxbruckner.org, 1 +maxbuelk.de, 1 +maxbytes.nl, 0 +maxchan.info, 1 +maxclean.ml, 1 +maxcleaning.be, 1 +maxclers.com, 1 +maxdargent.com, 1 +maxedgymequipment.com, 1 +maxgamez.tk, 1 +maxh.me.uk, 1 +maxhamon.ovh, 1 +maxhoechtl.at, 1 +maxhorvath.com, 1 +maxibanki.ovh, 1 +maxico.tk, 1 +maxiglobal.net, 1 +maxiglobal.pt, 1 +maxihide.tk, 1 +maximarket.info, 1 +maximbaz.com, 1 +maximdeboiserie.be, 1 +maximdens.be, 1 +maximeferon.fr, 1 +maximegagnon.io, 1 +maximemalfoy.com, 1 +maximemichaud.me, 1 +maximilian-graf.de, 1 +maximilian-greger.com, 1 +maximilian-staedtler.de, 1 +maximiliankrieg.de, 1 +maximoguk.com, 1 +maximov.space, 0 +maxims-travel.com, 1 +maximum-rent.com, 1 +maximumphysiotherapy.com, 1 +maxinesbydennees.com, 1 +maxipcalls.com, 0 +maxiservak.ml, 1 +maxisito.it, 1 +maxiutov.ru, 1 +maxivisor.ga, 1 +maxkaul.de, 1 +maxlaumeister.com, 1 +maxley.yachts, 1 +maxmanus.ga, 1 +maxmarket.bg, 1 +maxmatthe.ws, 1 +maxmilton.com, 1 +maxmind.com, 1 +maxmoda.eu, 1 +maxmuen.de, 1 +maxopen.cf, 1 +maxopolyworldnews.com, 1 +maxp.info, 0 +maxpl0it.com, 1 +maxr1998.de, 1 +maxrandolph.com, 1 +maxratmeyer.com, 1 +maxrider.tk, 1 +maxscripts.com, 1 +maxtruxa.com, 1 +maxundlara.at, 1 +maxundlara.com, 1 +maxundlara.eu, 1 +maxundlara.org, 1 +maxus.tk, 1 +maxverboom.nl, 1 +maxwaellenergie.de, 1 +maxwell-english.co.jp, 0 +maxwellcity.cf, 1 +maxwellcity.ga, 1 +maxwellcody.com, 1 +maxwellmoore.co.uk, 1 +maxwittfeld.tech, 1 +mayaimplant.com, 1 +mayamushrooms.co.uk, 1 +mayarocabletv.com, 1 +mayaroconstituency.org, 1 +mayavi.co.in, 1 +mayaxelstore.com, 1 +maybeonline.de, 1 +maybeshewill.xyz, 1 +maybeul.com, 1 +mayblossom.net, 1 +maycarivero.com, 1 +maydex.info, 1 +mayerbrownllz.com, 1 +mayesoley.co, 1 +mayflowerbocawina.tk, 1 +mayflowercreative.com, 1 +mayflowerfairytales.com, 1 +mayhutmuibep.com, 1 +mayito.tk, 1 +mayki.ga, 1 +maykitut.tk, 1 +maynails.com.br, 1 +maynardnetworks.com, 0 +maynesoftware.co.uk, 1 +mayomarquees.com, 1 +mayopartyhire.com, 1 +mayorcahill.com, 1 +mayorscouncil.ca, 1 +mayre-idol.tk, 1 +mayrhofer.eu.org, 0 +maysambotros.tk, 1 +maytalkhao.com, 1 +maythai.eu, 1 +maythai.pl, 1 +maytinh.io, 1 +mazartdesign.tk, 1 +mazavto.ml, 1 +mazayaashop.com, 1 +mazda-mps.de, 1 +mazda-thermote.com, 0 +mazda626.net, 1 +mazdaofgermantown.com, 1 +maze.fr, 0 +mazenjobs.com, 1 +mazepa.ml, 1 +mazloum.adv.br, 1 +mazternet.ru, 1 +mazurlabs.tk, 1 +mazury-invest.pl, 1 +mazzettigroup.com, 1 +mazzotta.me, 1 +mb-demo.net, 1 +mb-is.info, 1 +mb-msk.ru, 1 +mb-server.de, 1 +mb300sd.com, 1 +mb300sd.net, 1 +mbaasy.com, 1 +mbaestlein.de, 1 +mbainflatables.co.uk, 1 +mbanq.com, 1 +mbar.us, 1 +mbardot.com, 1 +mbasic.facebook.com, 0 +mbc.asn.au, 1 +mbcars.be, 0 +mbclegal.org, 1 +mbd2021cm.com, 1 +mbda.gov, 1 +mbdrogenbos-usedcars.be, 1 +mbed.com, 1 +mbedcloud.com, 1 +mbedcloudintegration.net, 1 +mbeo.ch, 0 +mbetb33.com, 1 +mbfiles.tk, 1 +mbinf.de, 0 +mbinformatik.de, 0 +mbk.net.pl, 1 +mblankhorst.nl, 1 +mble.mg, 1 +mbmc.gov.in, 1 +mbosna.eu, 1 +mbr-net.de, 1 +mbr.pw, 1 +mbrd.de, 1 +mbrjun.cn, 1 +mbrooks.info, 1 +mbs-journey.com, 1 +mbsec.net, 1 +mbski.se, 1 +mbsr-barmstedt.de, 1 +mbsync4supply.com, 1 +mburaks.com, 1 +mburns.duckdns.org, 1 +mbwemmel-usedcars.be, 1 +mc-auth.com, 1 +mc-dos.ru, 1 +mc-jobs.net, 1 +mc-pub.org, 0 +mc-teemocraft.tk, 1 +mc-web.se, 1 +mc.ax, 1 +mc007.xyz, 1 +mc4free.cc, 1 +mc5zvezd.ru, 0 +mc81.com, 1 +mcadmin.net, 1 +mcagon.tk, 1 +mcatnnlo.org, 1 +mcblain.ca, 1 +mcblain.com, 1 +mcbooks.vn, 1 +mccn.pp.ua, 1 +mccommando.tk, 1 +mcconciergerie.com, 1 +mccoolesredlioninn.com, 1 +mccordscvs.com, 1 +mccordsvillelocksmith.com, 1 +mccrackon.com, 1 +mcculloughjchris.com, 1 +mcculloughsgolf.com, 1 +mccurtainems.gov, 1 +mcdanieldevelopmentservices.com, 1 +mcdeed.net, 1 +mcdermottautomotive.com, 1 +mcdona1d.me, 1 +mcdonalds.be, 1 +mcdonaldwhsl.com, 0 +mcdsg.net, 1 +mcduff.ga, 1 +mce.eu, 1 +mce.nyc, 1 +mce55.eu, 1 +mcea-hld.jp, 1 +mceconferencecentre.eu, 1 +mcfallout.ru, 1 +mcfarlow.sk, 1 +mcfi.mu, 1 +mcfipvt.com, 1 +mcfx.us, 1 +mcg4loans.com, 1 +mcgaccountancy.co.uk, 1 +mcgavocknissanwichitaparts.com, 1 +mcgifreestore.com, 1 +mcgovernance.com, 1 +mcgrp.ru, 1 +mchaelkordomain.tk, 1 +mchan.us, 1 +mchaves.com, 1 +mchel.net, 1 +mchollet.eu, 1 +mchopkins.net, 1 +mchost.no, 1 +mchristopher.com, 1 +mchuiji.com, 0 +mcideas.tk, 1 +mcivor.me, 1 +mcjackk77.me, 1 +mcjars.com, 1 +mckay-bednar.net, 1 +mckendry.com, 1 +mckendry.consulting, 1 +mckenna.academy, 1 +mckeownshvac.com, 1 +mckernan.in, 0 +mckinley1.com, 1 +mckinleytk.com, 1 +mckycraft.xyz, 1 +mcl.de, 0 +mcl.gg, 1 +mclanedirect.com, 1 +mclanexpress.com, 1 +mclinflatables.co.uk, 1 +mclmotors.co.uk, 1 +mcmillanskiclub.com.au, 1 +mcmk.in, 1 +mcnb.top, 1 +mcneill.io, 1 +mcnet.care, 1 +mcnext.net, 1 +mcnoobs.pro, 1 +mcon.se, 1 +mcoutinho.pt, 0 +mcpa.top, 1 +mcpaoffice.com, 1 +mcpart.land, 1 +mcpat.com, 1 +mcpebox.com, 1 +mcpgnz.tech, 1 +mcplat.ru, 1 +mcplayman.de, 1 +mcprocdn.com, 1 +mcrn.jp, 1 +mcsa-usa.org, 1 +mcsdatum.co.uk, 1 +mcseboard.de, 1 +mcsidan.tk, 1 +mcsinflatables.co.uk, 1 +mcsmart.ru, 1 +mcsnovatamabayan.com, 1 +mcsoneca.tk, 1 +mcsports.es, 1 +mcsrvstat.us, 1 +mcstaralliance.com, 1 +mctherealm.net, 1 +mctitan.net, 1 +mctools.org, 1 +mctwcloud.tk, 1 +mcuexchange.com, 1 +mcukhost.co.uk, 1 +mcuong.tk, 0 +mcuuid.net, 1 +mcversions.net, 1 +mcvs.net, 1 +mcwrapper.com, 1 +mcyukon.com, 1 +md-clinica.com.ua, 1 +md-progressistes.fr, 1 +md-service.net, 1 +md19lc8.com, 1 +md21lc8.com, 1 +md24lc8.com, 1 +md5file.com, 1 +md5hashing.net, 1 +mdaemon.de, 1 +mdazo.net, 1 +mdbug.de, 1 +mdcallianceparty.org, 1 +mdcghana.org, 1 +mdcloudps.com, 1 +mdconnect.asia, 1 +mddistributorsstore.com, 1 +mdewendt.de, 1 +mdf-bis.com, 0 +mdihi.com, 1 +mdinstituteplasticsurgery.com, 1 +mdinvest.nz, 1 +mdir.tk, 1 +mditsa.de, 1 +mdiv.pl, 1 +mdlayher.com, 1 +mdleom.com, 1 +mdma.net, 1 +mdmed.clinic, 1 +mdns.eu, 1 +mdosch.de, 1 +mdpp.com.br, 1 +mdpparish.com, 1 +mdpraha.cz, 1 +mdrp.be, 1 +mdrsp.de, 1 +mdrthmcs.io, 1 +mds-paris.com, 1 +mds.cool, 1 +mdsave.com, 1 +mdscomp.net, 1 +mdsconcept.fr, 1 +mdsglobal.com, 1 +mdtorelli.it, 1 +mdwftw.com, 1 +mdx.no, 1 +mdxdave.de, 1 +mdxn.org, 1 +mdzservers.com, 1 +me-center.com, 1 +me-dc.com, 0 +me-groups.com, 1 +me-news.tk, 1 +me-soft.nl, 1 +me.com.br, 1 +me.net.nz, 1 +me.tc, 1 +me.vu, 1 +me7878.com, 1 +meadowfen.farm, 1 +meadowfenfarm.com, 1 +meadowviewfarms.org, 1 +meadstats.com, 1 +mealcast.ml, 1 +mealpedant.com, 1 +mealsnmemories.in, 1 +mealz.com, 1 +meamod.com, 0 +meandb.net, 1 +meanevo.com, 1 +meangirl.club, 1 +meaningfulaction.org, 1 +meany.xyz, 1 +meap.xyz, 1 +meapbot.com, 1 +meapbot.net, 1 +meapbot.org, 1 +meapbot.pro, 1 +meaqua.love, 1 +measureyourpenis.today, 1 +meat.org.uk, 1 +meat.tk, 1 +meatfoods.com.br, 1 +meatfreecarnivore.com, 1 +meayne.ddns.net, 1 +mebaneattorney.com, 1 +mebanesteakhouse.com, 1 +mebel-voronezh.cf, 1 +mebelconcept.tk, 1 +mebelisk.com.br, 1 +mebelshik.tk, 1 +mec010.com, 1 +mec020.com, 1 +mec021.com, 1 +mec022.com, 1 +mec023.com, 1 +mec024.com, 1 +mec025.com, 1 +mec027.com, 1 +mec028.com, 1 +mec029.com, 1 +mec0310.com, 1 +mec0311.com, 1 +mec0312.com, 1 +mec0313.com, 1 +mec0314.com, 1 +mec0315.com, 1 +mec0316.com, 1 +mec0317.com, 1 +mec0318.com, 1 +mec0319.com, 1 +mec0335.com, 1 +mec0350.com, 1 +mec0351.com, 1 +mec0352.com, 1 +mec0353.com, 1 +mec0354.com, 1 +mec0355.com, 1 +mec0356.com, 1 +mec0357.com, 1 +mec0358.com, 1 +mec0359.com, 1 +mec0370.com, 1 +mec0371.com, 1 +mec0372.com, 1 +mec0373.com, 1 +mec0374.com, 1 +mec0375.com, 1 +mec0376.com, 1 +mec0377.com, 1 +mec0378.com, 1 +mec0379.com, 1 +mec0391.com, 1 +mec0392.com, 1 +mec0393.com, 1 +mec0394.com, 1 +mec0395.com, 1 +mec0396.com, 1 +mec0398.com, 1 +mec0410.com, 1 +mec0411.com, 1 +mec0412.com, 1 +mec0413.com, 1 +mec0414.com, 1 +mec0415.com, 1 +mec0416.com, 1 +mec0419.com, 1 +mec0421.com, 1 +mec0429.com, 1 +mec0431.com, 1 +mec0432.com, 1 +mec0433.com, 1 +mec0434.com, 1 +mec0435.com, 1 +mec0436.com, 1 +mec0437.com, 1 +mec0438.com, 1 +mec0439.com, 1 +mec0440.com, 1 +mec0450.com, 1 +mec0451.com, 1 +mec0452.com, 1 +mec0453.com, 1 +mec0454.com, 1 +mec0455.com, 1 +mec0456.com, 1 +mec0457.com, 1 +mec0458.com, 1 +mec0459.com, 1 +mec0470.com, 1 +mec0471.com, 1 +mec0472.com, 1 +mec0473.com, 1 +mec0474.com, 1 +mec0475.com, 1 +mec0476.com, 1 +mec0477.com, 1 +mec0478.com, 1 +mec0479.com, 1 +mec0482.com, 1 +mec0483.com, 1 +mec0510.com, 1 +mec0511.com, 1 +mec0512.com, 1 +mec0513.com, 1 +mec0514.com, 1 +mec0515.com, 1 +mec0516.com, 1 +mec0517.com, 1 +mec0518.com, 1 +mec0519.com, 1 +mec0523.com, 1 +mec0530.com, 1 +mec0531.com, 1 +mec0532.com, 1 +mec0533.com, 1 +mec0534.com, 1 +mec0535.com, 1 +mec0536.com, 1 +mec0537.com, 1 +mec0538.com, 1 +mec0539.com, 1 +mec0550.com, 1 +mec0551.com, 1 +mec0552.com, 1 +mec0553.com, 1 +mec0554.com, 1 +mec0555.com, 1 +mec0556.com, 1 +mec0557.com, 1 +mec0558.com, 1 +mec0559.com, 1 +mec0561.com, 1 +mec0562.com, 1 +mec0563.com, 1 +mec0564.com, 1 +mec0565.com, 1 +mec0566.com, 1 +mec0570.com, 1 +mec0571.com, 1 +mec0572.com, 1 +mec0573.com, 1 +mec0574.com, 1 +mec0575.com, 1 +mec0576.com, 1 +mec0577.com, 1 +mec0578.com, 1 +mec0579.com, 1 +mec0580.com, 1 +mec0591.com, 1 +mec0592.com, 1 +mec0593.com, 1 +mec0594.com, 1 +mec0595.com, 1 +mec0596.com, 1 +mec0597.com, 1 +mec0598.com, 1 +mec0599.com, 1 +mec0660.com, 1 +mec0661.com, 1 +mec0662.com, 1 +mec0663.com, 1 +mec0691.com, 1 +mec0692.com, 1 +mec0701.com, 1 +mec0710.com, 1 +mec0711.com, 1 +mec0712.com, 1 +mec0713.com, 1 +mec0714.com, 1 +mec0715.com, 1 +mec0716.com, 1 +mec0717.com, 1 +mec0718.com, 1 +mec0719.com, 1 +mec0722.com, 1 +mec0724.com, 1 +mec0728.com, 1 +mec0730.com, 1 +mec0731.com, 1 +mec0732.com, 1 +mec0733.com, 1 +mec0734.com, 1 +mec0735.com, 1 +mec0736.com, 1 +mec0737.com, 1 +mec0738.com, 1 +mec0739.com, 1 +mec0743.com, 1 +mec0744.com, 1 +mec0745.com, 1 +mec0746.com, 1 +mec0751.com, 1 +mec0752.com, 1 +mec0753.com, 1 +mec0754.com, 1 +mec0755.com, 1 +mec0756.com, 1 +mec0757.com, 1 +mec0758.com, 1 +mec0759.com, 1 +mec0760.com, 1 +mec0762.com, 1 +mec0763.com, 1 +mec0765.com, 1 +mec0766.com, 1 +mec0768.com, 1 +mec0769.com, 1 +mec0770.com, 1 +mec0771.com, 1 +mec0772.com, 1 +mec0773.com, 1 +mec0774.com, 1 +mec0775.com, 1 +mec0776.com, 1 +mec0777.com, 1 +mec0778.com, 1 +mec0779.com, 1 +mec0790.com, 1 +mec0791.com, 1 +mec0792.com, 1 +mec0793.com, 1 +mec0794.com, 1 +mec0795.com, 1 +mec0796.com, 1 +mec0797.com, 1 +mec0798.com, 1 +mec0799.com, 1 +mec0810.com, 1 +mec0811.com, 1 +mec0812.com, 1 +mec0813.com, 1 +mec0814.com, 1 +mec0816.com, 1 +mec0817.com, 1 +mec0818.com, 1 +mec0819.com, 1 +mec0826.com, 1 +mec0827.com, 1 +mec0830.com, 1 +mec0831.com, 1 +mec0832.com, 1 +mec0833.com, 1 +mec0834.com, 1 +mec0835.com, 1 +mec0836.com, 1 +mec0837.com, 1 +mec0838.com, 1 +mec0839.com, 1 +mec0840.com, 1 +mec0851.com, 1 +mec0852.com, 1 +mec0853.com, 1 +mec0854.com, 1 +mec0855.com, 1 +mec0856.com, 1 +mec0857.com, 1 +mec0858.com, 1 +mec0859.com, 1 +mec0870.com, 1 +mec0871.com, 1 +mec0872.com, 1 +mec0873.com, 1 +mec0874.com, 1 +mec0875.com, 1 +mec0876.com, 1 +mec0877.com, 1 +mec0878.com, 1 +mec0879.com, 1 +mec0881.com, 1 +mec0883.com, 1 +mec0886.com, 1 +mec0887.com, 1 +mec0888.com, 1 +mec0890.com, 1 +mec0891.com, 1 +mec0898.com, 1 +mec0899.com, 1 +mec0910.com, 1 +mec0911.com, 1 +mec0912.com, 1 +mec0913.com, 1 +mec0914.com, 1 +mec0915.com, 1 +mec0916.com, 1 +mec0917.com, 1 +mec0919.com, 1 +mec0930.com, 1 +mec0931.com, 1 +mec0932.com, 1 +mec0933.com, 1 +mec0934.com, 1 +mec0935.com, 1 +mec0936.com, 1 +mec0937.com, 1 +mec0938.com, 1 +mec0941.com, 1 +mec0943.com, 1 +mec0951.com, 1 +mec0952.com, 1 +mec0953.com, 1 +mec0954.com, 1 +mec0971.com, 1 +mec0972.com, 1 +mec0973.com, 1 +mec0974.com, 1 +mec0975.com, 1 +mec0976.com, 1 +mec0977.com, 1 +mec0991.com, 1 +mec111.net, 1 +mec222.com, 1 +mec222.net, 1 +mec333.net, 1 +mec444.com, 1 +mec555.com, 1 +mec555.net, 1 +mec666.net, 1 +mec777.net, 1 +mec825.com, 1 +mec888.com, 1 +mec888.net, 1 +mec999.com, 1 +mec999.net, 1 +mecanicoautomotriz.org, 0 +mecaniquemondor.com, 1 +meccano.srl, 1 +mechanics-schools.com, 1 +mechanicweb.com, 1 +mechanixdirect.co.uk, 0 +mechanus.io, 1 +mechaspartans6648.com, 1 +mechbattlegrounds.com, 1 +mechmk1.me, 1 +mechok.ru, 1 +mechta.gq, 1 +mechtateli.eu, 1 +mecp.de, 1 +med-colleges.com, 1 +med-line.cf, 1 +med-otzyv.ru, 1 +med-post.biz, 1 +med-post.co, 1 +med-post.com, 1 +med-post.net, 1 +med-post.org, 1 +med-postclinic.com, 1 +med-postdoctor.com, 1 +med-postdoctors.com, 1 +med-postemergency.com, 1 +med-posthealth.com, 1 +med-postmedical.com, 1 +med-postphysicians.com, 1 +med-postwellness.com, 1 +med.tips, 1 +med360.at, 1 +medaboutme.ru, 1 +medaliturki.tk, 1 +medalofvalor.gov, 1 +medart-media.de, 1 +medasset.gr, 1 +medbiocompany.com, 1 +medbreaker-friends.at, 1 +medbreaker.one, 0 +medcartoon.com, 1 +medcenter.online, 1 +medcentr.online, 1 +medcentrnadezhda.ru, 1 +medcir.com.br, 1 +medcorfu.gr, 1 +medcrowd.com, 1 +meddatix.com, 1 +meddigital.com, 0 +meddin.com, 1 +mede-handover.azurewebsites.net, 1 +medebridge.com.au, 1 +medecinchinois.be, 1 +medecinsdumonde.lu, 1 +medeinos.lt, 0 +medellinapartamentos.com, 1 +medexpress.co.uk, 1 +medfinancial.com, 1 +medguide-bg.com, 1 +medhiwa.com, 1 +medi.com.br, 1 +media-credit.eu, 1 +media-instance.ru, 1 +media-library.co.uk, 1 +media-serwis.com, 1 +media-start.tk, 1 +media-store.ir, 1 +media-valko.hu, 1 +media4u.tk, 1 +mediaarea.net, 1 +mediaareplural.ca, 1 +mediabackoffice.co.jp, 1 +mediablaster.com, 1 +mediabogen.net, 1 +mediabola.net, 1 +mediabookdb.de, 1 +mediabooks.ml, 1 +mediabrandgroup.com, 1 +mediaburst.co.uk, 1 +mediacenter.dynv6.net, 1 +mediacloud.me, 1 +mediacluster.de, 1 +mediacritik.com, 1 +mediadex.be, 1 +mediafart.fr, 1 +mediafly.com, 1 +mediafocus.biz, 1 +mediaforkids.org, 1 +mediafresco.com, 1 +mediagenic.ch, 0 +mediagetnews.tk, 1 +mediagold.it, 1 +mediagrand.net, 1 +mediajurnal.com, 1 +medialab.nrw, 1 +medialinkz.ga, 1 +medialys.ca, 1 +mediamarket42.tk, 1 +mediamonitors.net, 1 +medianbases.ga, 1 +mediapart.fr, 1 +mediapath.gr, 1 +mediaplaytv.com.br, 1 +mediapuller.com, 1 +mediarithmics.com, 1 +mediarithmics.io, 1 +mediaselection.eu, 1 +mediasst.com, 1 +mediastorm.us, 1 +mediastroke.com, 1 +mediathekview.de, 1 +mediation-mv.de, 1 +mediationculturelleclp.ch, 0 +mediatorzy.waw.pl, 1 +mediaukkies.nl, 1 +mediaweb.com.ve, 1 +mediawijsheid.nl, 1 +mediawijzer.net, 1 +mediawiki.com, 1 +mediawiki.org, 1 +mediawin.pl, 1 +mediawizards.co, 1 +mediayourway.ie, 1 +medibasket.co.in, 1 +medic-world.com, 1 +medicairsolutions.com, 1 +medical-assistant-colleges.com, 1 +medical-centr.tk, 1 +medical-safety-system.com, 1 +medicalabroad.org, 0 +medicalassistantadvice.com, 1 +medicalauction.ga, 1 +medicalcountermeasures.gov, 1 +medicallicensing.com, 1 +medicalonliner.tk, 1 +medicalpeople.tk, 1 +medicalphysicistservices.com, 1 +medicals-i.com, 1 +medicalsite.tk, 1 +medicalsland.com, 1 +medicaltools.de, 1 +medicano.site, 0 +medicardlimited.com, 1 +medicare-providers.net, 1 +medicarecoveragefinder.com, 1 +medicareful.com, 1 +medicareinfo.org, 1 +medicenteritalia.it, 1 +medichat.ml, 1 +medicina-antiage.com, 1 +medicina-news.tk, 1 +medicinae.solutions, 1 +medicinaesolutions.com, 1 +medicinaesolutions.com.br, 1 +medicinalflora.com.br, 1 +medicine-consultant.com, 1 +medicine.com, 1 +medicinesfast.com, 0 +medicinia.com.br, 1 +medicinskavranje.edu.rs, 1 +mediciventures.com, 1 +mediclinik.tk, 1 +medicm.jp, 1 +medicocompetente.it, 1 +medicoleads.com, 1 +medicompany.tk, 1 +medicoresponde.com.br, 1 +medicosrecomendados.com, 1 +medicoway.ru, 1 +medictools.de, 1 +medidordecampo.online, 1 +medidordehumedad.online, 1 +medientechnik.wien, 1 +medienweite.de, 1 +medifirst.de, 1 +medifit.si, 1 +medifoto.tk, 1 +medigap-quote.net, 1 +medik8.com.cy, 1 +medikalakademi.com.tr, 1 +medikuma.com, 1 +medimush.co.uk, 1 +medinacountyohio.gov, 1 +medinc.tk, 1 +medino.com, 1 +medinorte.es, 1 +medinside.ch, 1 +medinside.li, 1 +medinsider.ch, 1 +medinsider.li, 1 +medirota.com, 1 +medisense.tk, 1 +mediskin.ro, 1 +meditadvisors.com, 1 +meditarenargentina.org, 1 +meditateinolympia.org, 1 +meditation-rennes.org, 1 +meditel.nl, 1 +meditez.ca, 1 +meditrak.ml, 1 +medium.com, 1 +mediums.cf, 1 +medivox.tk, 1 +mediweed.tk, 1 +medja.net, 1 +medklee.com, 1 +medlineplus.gov, 1 +mednew.site, 1 +medo64.com, 1 +medonline.co.nz, 1 +medosedu.in, 1 +medovea.ru, 1 +medovoe.ml, 1 +medpeer.co.jp, 1 +medpeer.jp, 1 +medpost.biz, 1 +medpost.co, 1 +medpost.info, 1 +medpost.me, 1 +medpost.mobi, 1 +medpost.tv, 1 +medpost.us, 1 +medpostcare.com, 1 +medpostclinic.com, 1 +medpostdoctor.com, 1 +medpostdoctors.com, 1 +medpostemergency.com, 1 +medpostexpresscare.com, 1 +medposthealth.com, 1 +medposthealthcare.com, 1 +medpostimmediatecare.com, 1 +medpostmedical.com, 1 +medpostphysicians.com, 1 +medposturgentcare.biz, 1 +medposturgentcare.co, 1 +medposturgentcare.com, 1 +medposturgentcare.info, 1 +medposturgentcare.net, 1 +medposturgentcare.org, 1 +medpostwalkincare.com, 1 +medpostwellness.com, 1 +medprozone.com, 1 +medrol.cf, 1 +medsanuk.co.uk, 1 +medsblalabs.com, 1 +medschat.com, 1 +medschrome.com, 1 +medscope.tk, 1 +medservis.online, 1 +medsister.tk, 1 +medsourcelabs.com, 1 +medspecial.tk, 1 +medstatix-dev.com, 1 +medstatix.co, 1 +medstreaming.com, 0 +medtalents.ch, 1 +medtehnika.ua, 1 +medtip.de, 0 +medunovi.com, 1 +medusa.wtf, 1 +meduza.io, 1 +medvedikorenka.cz, 1 +medvedivka.tk, 1 +medvedka-nasekomoe.tk, 1 +medvedkovo-hovrino.ru, 1 +medvesajt.hu, 1 +medvet.com.es, 1 +medwaybouncycastlehire.co.uk, 1 +medy-me.com, 1 +medyascope.tv, 1 +medyotan.ga, 1 +medzinenews.com, 0 +meedoenhartvanwestbrabant.nl, 0 +meedoennoordkop.nl, 0 +meekhak.com, 1 +meeko.cc, 1 +meekru.com, 1 +meepbot.net, 1 +meepbot.org, 1 +meepbot.pro, 1 +meer-der-ideen.de, 0 +meeras.ga, 1 +meereskunst.de, 1 +meerman.nl, 1 +meermantechnischburo.nl, 1 +meerutcake.com, 1 +meesteresmisty.nl, 1 +meet, 1 +meet.google.com, 1 +meetanshi.com, 1 +meetbot.fedoraproject.org, 1 +meetfranz.com, 1 +meeting-server.ml, 1 +meetingapplication.com, 1 +meetingmanage.nl, 1 +meetingmanager.ovh, 1 +meetjeslandsetriathlon.tk, 1 +meetmibaby.co.uk, 1 +meetmygoods.com, 1 +meetmyown.ga, 1 +meetpoint.education, 1 +meetsummer.org, 1 +meeusen-usedcars.be, 0 +meevo.ca, 1 +meewan.fr, 1 +meeztertom.nl, 1 +meg-a-bounce.co.uk, 1 +mega-aukcion.ru, 1 +mega-byte.nl, 1 +mega-feeling.de, 1 +mega.co.nz, 1 +mega.nz, 1 +megabook.ml, 1 +megabounce.co.uk, 1 +megabouncingcastles.com, 1 +megacity.com.ng, 1 +megadrol.com, 1 +megaelettrostimolatore.com, 1 +megafide.com.br, 1 +megaflix.nl, 1 +megaflowers.ru, 1 +megagifs.de, 1 +megaherz.tk, 1 +megahostingbr.tk, 1 +megaimpressao3d.com.br, 1 +megainflatables.co.uk, 1 +megainformatyk.pl, 1 +megakoncert90.cz, 1 +megalibportal.ga, 1 +megalogi.ma, 1 +megam.host, 1 +megamilftube.com, 0 +megamillions.tk, 1 +megamisja.pl, 1 +megamov.eu, 1 +megamov.fr, 1 +megamov.pro, 1 +megamp3.eu, 1 +meganandmarc.us, 1 +meganmarston.cf, 1 +meganreel.com, 1 +meganruggiero.com, 0 +megaparadise.ml, 1 +megapixel.cz, 1 +megapl.ru, 1 +megaplan.cz, 1 +megaplan.ru, 1 +megaportal.ga, 1 +megaron.at, 1 +megasslstore.com, 1 +megateam.tk, 1 +megatravel.com.mx, 1 +megatyumen.ru, 1 +megauction.tk, 1 +megavasoc.com.ar, 1 +megaviews.tk, 1 +megawarez.org, 1 +megawebsite.tk, 1 +megawhat.energy, 1 +megaxchange.cash, 1 +megayachts.world, 1 +megazigzag.com, 1 +megazine3.de, 1 +meggidesign.com, 1 +meggiehome.com, 1 +megh.tv, 1 +meginajums1.space, 1 +mego.cloud, 1 +megumico.net, 1 +megztosidejos.lt, 1 +meh.is, 1 +mehalick.com, 1 +meharossii.ru, 1 +mehdavia.tk, 1 +mehdibouchema.be, 1 +mehdimassage.com, 1 +meherbaba.sk, 1 +meherpurnews.com, 1 +mehhh.xyz, 1 +mehibo.tk, 1 +mehmetince.net, 1 +mehode.com, 1 +mehostdd.com, 0 +mehrgarh.tk, 1 +mehrleben.at, 1 +mehrnevesht.com, 1 +mehrwert.de, 1 +meideas108.com, 1 +meidev.co, 1 +meier-stracke.de, 1 +meierhofer.net, 1 +meiersmarkus.de, 1 +meigetsuen1980.com, 1 +meijburg.com, 1 +meijwebdesign.nl, 1 +meikampf.de, 1 +meikan.moe, 1 +meiksbar.de, 1 +meiler.cf, 1 +meillard-auto-ecole.ch, 1 +meilleur.info, 1 +meilleursavis.fr, 1 +meilleursjeuxporno.fr, 1 +meilleurstrucs.com, 1 +meimeistartup.com, 1 +mein-domizil.at, 1 +mein-gehalt.at, 1 +mein-kuechenhelfer.de, 1 +mein-muehlhausen.bayern, 1 +mein-neuer-garten.de, 1 +mein-webportal.de, 0 +meinbetriebsrat24.de, 1 +meincenter-meinemeinung.de, 1 +meincoach.at, 1 +meine-cloud-online.de, 1 +meine-email-im.net, 1 +meine-finanzanalyse.de, 1 +meine-immofinanzierung.de, 1 +meine-stirnlampe.de, 1 +meineit.dvag, 1 +meinevorlagen.com, 1 +meinewolke.pw, 1 +meineziege.de, 1 +meinezwangsversteigerung.de, 1 +meinforum.net, 1 +meinheizstrom.de, 1 +meinstartinsleben.com, 1 +meinstartinsleben.de, 1 +meintragebaby.de, 1 +meinv.asia, 1 +meiqia.cn, 1 +meiqia.com, 1 +meisterlabs.com, 1 +meistertask.com, 1 +meitan.gz.cn, 1 +meitianyixiaobu.com, 1 +meiyi.ga, 1 +mejitravelcr.com, 1 +mejofi.com, 1 +mejofi.eu, 1 +mejofi.net, 1 +mejofi.nl, 1 +mejofi.org, 1 +mejorator.com, 1 +mejorator.es, 1 +mejorator.net, 1 +mejorator.org, 1 +mejorespatineteselectricos.es, 1 +mejorwork.com, 1 +mejovonakowogov.gq, 1 +mekajen.com, 1 +mekaleskirit.tk, 1 +mekanagadde.com, 1 +mekanika.com.my, 1 +mekanismo.tk, 1 +mekanova.art, 1 +mekatro.tech, 1 +mekatronika.tk, 1 +mekatrotekno.com, 1 +mekegi.com, 1 +mekesh.com, 1 +mekesh.net, 1 +mekesh.ru, 1 +meklon.net, 1 +mekongmontessori.com, 1 +melagenina.tk, 1 +melanfengshui.com, 1 +melania-voyance.fr, 0 +melanie-guy.fr, 1 +melanie-schwarze.de, 1 +melaniebernhardt.com, 1 +melaniec-thebest.tk, 1 +melaniegruber.de, 1 +melanieschweiger.com, 1 +melanin.cf, 1 +melatonin.fun, 1 +melbar.com.au, 1 +melbet.com, 1 +melbet.ru, 1 +melbourne.dating, 1 +melbourneapartments.website, 1 +melbournefunctionalmedicine.com.au, 1 +melcher.it, 1 +melchizedek-forum.de, 1 +melda-agustin.tk, 1 +melda.ru, 1 +meldcode-assistent.nl, 1 +meldjeaan.be, 1 +meldpuntemma.nl, 1 +meldsluikstort.gent, 1 +meldwekker.nl, 1 +mele.ro, 1 +meledia.com, 0 +melenchatsmelenchiens.fr, 1 +melhoresdominios.com, 1 +melhoresmarcasdenotebook.com.br, 1 +melhorproduto.com.br, 1 +melideluxe.org, 1 +melihacar.com.tr, 1 +melikoff.es, 1 +melina-may.com, 1 +melina-schefczyk.de, 1 +meliowebweer.nl, 1 +melissaadkins.com, 1 +melissaauclaire.com, 1 +melissadeluxe.com, 1 +melissageorge.tk, 1 +melissalb.tk, 1 +melissameuwszen.nl, 0 +melissaofficial.tk, 1 +meliyb.ga, 1 +melkiran.tk, 1 +mellika.ch, 1 +mellitus.org, 1 +mellmon.com, 1 +mellonne.com, 1 +melnessgroup.com, 1 +melodict.com, 1 +melodiouscode.co.uk, 1 +melodiouscode.com, 1 +melodiouscode.net, 1 +melodiouscode.uk, 1 +melody-lyrics.com, 1 +melodycenter.de, 1 +melonhub.com, 1 +melonstudios.net, 1 +melopie.com, 1 +melosyne.com, 1 +melosyne.de, 1 +melosyne.net, 1 +melosyne.org, 1 +melted.me, 1 +meltzow.net, 1 +melvinsfrance.tk, 1 +mema.recipes, 1 +members-arbourlake.com, 1 +members-only-shopping.com, 1 +members.nearlyfreespeech.net, 0 +membershipservices.org.uk, 1 +memberstweets.com, 1 +membrive.net, 0 +memdoc.org, 1 +meme.fi, 1 +meme.institute, 1 +memed.xyz, 1 +memememememememe.me, 1 +memento-mori.cf, 1 +memepasmal.org, 1 +memes.nz, 1 +memesbee.com, 1 +memetrash.co.uk, 1 +memind.net, 1 +memiux.com, 1 +memo-linux.com, 1 +memo.ee, 1 +memo2ch.com, 1 +memoire-resistance-ariege.fr, 1 +memoirmedie.dk, 1 +memola.net, 1 +memorablewords.org, 1 +memoriadeunaciudadzccm2019.com, 1 +memorind.com, 1 +memorycards.ie, 1 +memoryex.net, 1 +memorylines.ml, 1 +memoryofyou.eu, 1 +mempool.de, 1 +mempool.ninja, 1 +mempool.space, 1 +memrise.com, 1 +memurvadisi.tk, 1 +men-costumes.tk, 1 +menanam.net, 1 +menanwc.org, 1 +menaraannonces.com, 1 +menchez.me, 1 +menddie.com, 1 +mendel.tk, 1 +mendelsphotography.tk, 1 +menden.com, 1 +mendipbouncycastles.co.uk, 1 +mendix-apps.com, 1 +mendosuits.com, 1 +mendozagenevieve.com, 1 +mendrala.eu, 1 +mendrala.io, 1 +mendrala.net, 1 +menfis.es, 1 +menfis.info, 1 +menfis.net, 1 +menfisnet.com, 1 +menfisnet.es, 1 +menfisnet.net, 1 +menfisonline.com, 1 +menfisonline.es, 1 +mengliangyun.xyz, 1 +menglong.me, 1 +mengma.pub, 1 +mengqingzhong.cn, 1 +mengqingzhong.com, 1 +mengqingzhong.com.cn, 1 +mengxin.life, 1 +menh.vn, 1 +menhera.org, 0 +menielias.com, 1 +menlosecurity.com, 1 +menn.tk, 1 +mennace.com, 1 +menno.me, 1 +menole.com, 1 +menole.de, 1 +menole.net, 1 +menomineemi.gov, 1 +menotag.com, 1 +mens-health.com.my, 0 +mens-qzin.jp, 1 +mens-v.com, 1 +mens-watch.tk, 1 +mensagemaniversario.com.br, 1 +mensagemdaluz.com, 1 +mensagensaniversario.com.br, 1 +mensagensdeconforto.com.br, 1 +mensajitos.tk, 1 +mensarena.gr, 1 +mensch-peter.me, 1 +menselijkembryo.tk, 1 +menshealthinsurance.com, 1 +menspeak.ga, 1 +menswear.tk, 1 +mental-check.jp, 1 +mentalcalculations.tk, 1 +mentalcraft.tk, 1 +mentalhealthmn.org, 1 +mentalproblems.tk, 1 +mentaltraining-fuer-musiker.ch, 1 +mentecuriosa.net, 1 +mentesinquietas.tk, 1 +menthiere.fr, 1 +mentiq.az, 1 +mentita.de, 1 +mentorbizlist.com, 1 +mentoringauchan.es, 1 +mentors4stem.org, 1 +mentup.com.br, 1 +menu.fyi, 1 +menuel.me, 1 +menufree.org, 1 +menuiserie-deumer.be, 1 +menupay.com, 1 +menureader.ml, 1 +menurutparaahli.com, 1 +menzel4you.tk, 1 +meodihoang.com, 1 +meow-games.com, 1 +meow.plus, 1 +mepambalaj.com, 1 +mepassport.com, 1 +mepc.jp, 1 +meperidina.com, 1 +mephedrone.org, 1 +meps.net, 1 +merafsolutions.com, 1 +meralda.eu, 1 +meralda.net, 1 +meralda.org, 1 +meraldamulder.com, 1 +meraldamulder.eu, 1 +meraldamulder.net, 1 +meraldamulder.org, 1 +meran.in, 1 +meransuedtirol.com, 1 +meraseo.com, 1 +mercadohype.tk, 1 +mercadoleal.com.br, 1 +mercadolibre.cl, 1 +mercadolibre.co.cr, 1 +mercadolibre.com.ar, 1 +mercadolibre.com.bo, 1 +mercadolibre.com.co, 1 +mercadolibre.com.do, 1 +mercadolibre.com.ec, 1 +mercadolibre.com.gt, 1 +mercadolibre.com.hn, 1 +mercadolibre.com.mx, 1 +mercadolibre.com.ni, 1 +mercadolibre.com.pa, 1 +mercadolibre.com.pe, 1 +mercadolibre.com.py, 1 +mercadolibre.com.sv, 1 +mercadolibre.com.uy, 1 +mercadolibre.com.ve, 1 +mercadolibrefz.tk, 1 +mercadolivre.com.br, 1 +mercadopago.cl, 1 +mercadopago.com, 1 +mercadopago.com.ar, 1 +mercadopago.com.br, 1 +mercadopago.com.co, 1 +mercadopago.com.mx, 1 +mercadopago.com.pe, 1 +mercadopago.com.uy, 1 +mercadopago.com.ve, 1 +mercamaris.es, 1 +mercanix.co.uk, 1 +mercatinomusicale.com, 1 +mercatoitticosbt.it, 1 +mercedes-anciennes.fr, 1 +mercedes-benz-arena-stuttgart.de, 1 +mercedes-benz-kiev.com, 1 +mercedes-ig.de, 1 +mercelo.com, 1 +mercercountyohio.gov, 1 +mercerisland.gov, 1 +merchant.agency, 1 +merchantcardadvisors.com, 1 +merchcity.com, 1 +mercici.com, 1 +mercredifiction.io, 1 +mercury.foundation, 0 +mercury.photo, 1 +mercuryamericas.com, 0 +mercurycards.com, 1 +mercyseverity.tk, 1 +merdacz.pl, 1 +mereni.cz, 1 +merenita.com, 1 +mergellina.tk, 1 +meric-graphisme.info, 1 +meridanas.me, 1 +meridianenvironmental.com, 1 +meridiangroup.ml, 1 +meridianmetals.com, 1 +meridianoshop.com.br, 1 +merikserver.tk, 1 +merimatka.fi, 1 +merkattumaa.tk, 1 +merkchest.tk, 1 +merke.tk, 1 +merkel.li, 1 +merkel.me, 1 +merkleforest.xyz, 1 +merlet.eu, 1 +merlin-memorial.de, 1 +merlin.dk, 1 +merlinsoap.com, 1 +merloaded.rocks, 1 +mermaidboattrips.com, 1 +mermakov.info, 1 +mero.co, 0 +merojob.com, 1 +meronberry.jp, 1 +merpay.com, 1 +merry.news, 1 +merryvic.com, 1 +merson.org, 1 +merson.tv, 1 +mertak.cz, 1 +mertarauh.com, 1 +mertcangokgoz.com, 1 +meruri.com, 1 +merza.is, 1 +merzai.co.uk, 1 +mes-bouquins.fr, 1 +mes-courriers.fr, 1 +mes-finances.be, 1 +mes-vacances.tk, 1 +mes10doigts.ovh, 1 +mesabi.ga, 1 +mesamoving.com, 1 +mesappros.com, 1 +mesareal.com.br, 1 +mesasysillas.site, 1 +mescaline.com, 1 +mescaline.org, 1 +mesec.cz, 1 +mesh.gov, 1 +mesh.org.ua, 1 +meshekard.co.il, 1 +meshintranet.com, 1 +meshok.info, 1 +meshok.ru, 1 +meskdeals.com, 1 +meskimonos.fr, 1 +meskiukas.tk, 1 +meslekifikir.com, 1 +meslekkursu.com, 1 +mesomeds.com, 1 +mesotheliomacentre.tk, 1 +messageclient.gq, 1 +messagescelestes-archives.ca, 1 +messagevortex.com, 1 +messagevortex.net, 1 +messcoutsandguides.tk, 1 +messcustom.com, 1 +messdorferfeld.de, 1 +messenger.co.tz, 1 +messenger.com, 0 +messenger.md, 1 +messengerupdate.com, 1 +messengerwebbrands.com, 1 +messengerwebdesign.com, 1 +messer24.ch, 1 +messifan.tk, 1 +messymom.com, 1 +mestazitrka.cz, 1 +mesvision.com, 1 +mesvt.com, 1 +meszlenyiattila.tk, 1 +meta-db.com, 1 +meta-word.com, 1 +meta4.be, 1 +metablog.xyz, 1 +metabox.io, 1 +metachris.com, 1 +metacoda.com, 1 +metacode.biz, 1 +metacompliance.com, 1 +metacortex.cf, 1 +metadata.be, 1 +metadedi.net, 1 +metaether.net, 1 +metafiz.ml, 1 +metafurquest.net, 1 +metagaming.tk, 1 +metaglyphics.com, 1 +metahumanvpn.network, 1 +metait.de, 1 +metakari.one, 1 +metal-madness.tk, 1 +metal-news.tk, 1 +metal-rock.tk, 1 +metalcorenews.ga, 1 +metalempire.tk, 1 +metaljournal.tk, 1 +metaljunkiez.com, 1 +metall.market, 1 +metallibrarian.com, 1 +metalliran.tk, 1 +metallobaza.ml, 1 +metallomania.it, 1 +metalloprokat.market, 1 +metallosajding.ru, 1 +metalmaniac.tk, 1 +metalsoviet.tk, 1 +metalu.ch, 0 +metalunion.tk, 1 +metamorfosis.cf, 1 +metanic.services, 1 +metanumbers.com, 1 +metapeen.nl, 1 +metaphilic.tk, 1 +metapsychie.com, 1 +metasearch.nl, 1 +metasolutions.se, 1 +metasquare.com.au, 1 +metasquare.nyc, 1 +metasurfforecast.com, 1 +metasyntactic.xyz, 1 +metasysteminfo.com, 1 +metaurl.io, 1 +metavr.ru, 1 +metaword.com, 1 +metaword.net, 1 +metaword.org, 1 +metayou.gq, 1 +metebalci.com, 0 +meteenonline.nl, 1 +meteo-parc.com, 1 +meteobox.co, 1 +meteobox.cz, 1 +meteobox.de, 1 +meteobox.es, 1 +meteobox.fr, 1 +meteobox.mx, 1 +meteobox.pl, 1 +meteobox.sk, 1 +meteobox.tk, 1 +meteocat.net, 1 +meteocuenca.tk, 1 +meteohuertamur.tk, 1 +meteonederbetuwe.nl, 1 +meteoradar.ch, 1 +meteorapp.space, 1 +meteorites-for-sale.com, 1 +meteorologiaenred.com, 1 +meteosmit.it, 1 +meteosolutions.com, 1 +meter.md, 1 +meterhost.com, 1 +meterinsight.com, 1 +metformin365.tk, 1 +methamphetamine.co.uk, 1 +method.com, 1 +methodfactory.com, 1 +methotrexatee.gq, 1 +methotrexates.gq, 1 +methusalem.tk, 1 +methylone.com, 1 +metin2blog.de, 1 +metin2sepeti.com, 1 +metinarslanturk.com, 1 +metkos.pl, 1 +metod.photo, 1 +metop.de, 1 +metric.ai, 1 +metricmutt.com, 1 +metrika.ml, 1 +metrix-money-ptc.com, 1 +metrix.design, 0 +metro-detroit.com, 1 +metro-lawn-care.com, 1 +metro-vet.co.uk, 1 +metro-web.net, 1 +metroairvirtual.com, 1 +metrobriefs.com, 0 +metrocarremovals.com, 1 +metrocraft2033.tk, 1 +metrodemaracaibo.tk, 1 +metrolaut.de, 1 +metroline.ml, 1 +metrolush.com, 1 +metron-eging.com, 1 +metron-networks.com, 1 +metron-online.com, 1 +metron.mv, 1 +metronaut.de, 1 +metronidazolee.gq, 1 +metronome.ga, 1 +metropole.com.au, 1 +metropolis.ga, 1 +metropolis5000.tk, 1 +metropolisil.gov, 1 +metropop.ch, 0 +metrorealestatepros.com, 1 +metrothessalonikis.tk, 1 +metroval.tk, 1 +metsasta.com, 1 +mettelenejohansson.dk, 1 +mettin.org, 1 +mettle.co.uk, 1 +metube.icu, 1 +metyweb.ga, 0 +metz-metropolitain.fr, 1 +metzgermark.com, 1 +meuautotrac.com.br, 1 +meubanco7.com.br, 1 +meugamer.com, 1 +meuhfolle.com, 1 +meulenerkes.tk, 1 +meulk.co.uk, 1 +meulocal.ml, 1 +meupatrocinio.com, 1 +meupedido.online, 1 +meurisse.org, 1 +meusigno.com, 1 +mevanshop.com, 0 +mevo.xyz, 1 +mevrouwtjepeper.nl, 1 +mevs.cz, 1 +mevsim.com, 1 +mew.build, 1 +mewtea.org, 1 +mexby.com, 1 +mexican.dating, 1 +mexicanjokes.net, 1 +mexico.rs, 1 +mexico.sh, 1 +mexicodental.co, 1 +mexicom.org, 1 +mexicosrit.tk, 1 +mexior.nl, 1 +meyafloors.com, 1 +meyateks.com, 1 +meydan.tv, 1 +meyer-horn.de, 1 +meyeraviation.com, 1 +meys.io, 1 +mezedokamomata.tk, 1 +mezemeze.de, 1 +meziblog.cz, 1 +mezinfo.tk, 1 +mezquetillas.tk, 1 +mf-fischer.de, 1 +mf-natuurfotografie.nl, 1 +mf58.de, 1 +mfatravaux.fr, 1 +mfedderke.com, 1 +mfen.de, 1 +mfg-forex.com, 1 +mfg-fx.com, 1 +mfgo.link, 1 +mfgusa.com, 1 +mfiles.pl, 1 +mfin.services, 1 +mfischer-it.de, 1 +mfits.co.uk, 1 +mflodin.se, 1 +mfoda-eg.com, 1 +mfpccprod.com, 1 +mfrepair.com, 1 +mfsquad.com, 1 +mft.global, 1 +mftn.eu, 1 +mfxbe.de, 1 +mfxer.com, 1 +mfzkl.com, 0 +mgae.com, 1 +mgcraft.net, 1 +mgdigitalmarketing.com.au, 1 +mgfashion.ae, 1 +mgfashion.store, 1 +mghiorzi.com.ar, 0 +mghturismo.com.ar, 1 +mghw.ch, 1 +mgi.gov, 1 +mgientertainment.com, 1 +mgiljum.com, 1 +mgmd.org, 1 +mgmeet.com, 1 +mgmpic.com, 0 +mgmultiservicessrl.it, 1 +mgonline.tk, 1 +mgriff.id.au, 1 +mgrossklaus.de, 0 +mgrt.net, 1 +mgsdb.com, 1 +mgsisk.com, 1 +mgtbaas.eu, 1 +mgvideo.com.au, 1 +mh.com.fj, 1 +mh2.at, 1 +mhabdullah.tk, 1 +mhadot.com, 1 +mhalfter.de, 1 +mhand.org, 1 +mhatero.com, 1 +mhatlaw.com, 1 +mhcdesignstudio.com, 1 +mheistermann.de, 1 +mhermans.nl, 1 +mhf.gc.ca, 1 +mhh.de, 1 +mhi.web.id, 1 +mhjuma.com, 1 +mhmfoundationrepair.com, 1 +mhonline.fr, 1 +mhtdesign.net, 1 +mhurologytriad.org, 1 +mi-beratung.de, 1 +mi-so-ji.com, 1 +mi1k.cn, 1 +mi80.com, 1 +mi92.ru, 0 +mia-manager.dk, 1 +mia.ac, 1 +mia.gent, 1 +mia.tw, 1 +miablow.net, 1 +miacordeonstereo.com, 1 +miacuario.cl, 1 +miadennees.com, 1 +miagexport.com, 1 +miah.top, 1 +mialma.live, 1 +mialquilerdecoches.com, 1 +miamibeachcommunitychurch.com, 1 +miamifl.casa, 1 +miamifl.homes, 1 +miamimosque.org, 1 +miamiobgyndreams.com, 1 +mianbao.ga, 1 +miaoft.com, 1 +miaomiao.eu.org, 1 +miaowo.org, 1 +miap.eu, 1 +miasarafina.de, 1 +miasonne.com, 1 +miatfactory.be, 1 +miatgent.be, 1 +miavierra.org, 1 +mibaso.com, 1 +mibeneficio.cl, 1 +mibh.de, 1 +miboulot.com, 1 +mibuiin.com, 1 +mica.ml, 1 +micaballo.org, 1 +micado-software.com, 1 +micah.soy, 1 +micalodeal.ch, 0 +micamisetaestampada.com, 1 +micasayestilo.com, 1 +micase.info, 1 +micbase.com, 1 +michadenheijer.com, 1 +michael-glaser.de, 1 +michael-r.ddns.net, 1 +michael-r.dynv6.net, 1 +michael-rigart.be, 1 +michael-schefczyk.de, 1 +michael-simon.de, 1 +michael-steinhauer.eu, 1 +michael.band, 1 +michaelabbas.tk, 1 +michaelamead.com, 1 +michaelasawyer.com, 1 +michaelband.co, 1 +michaelband.com, 1 +michaelbeer.co.uk, 1 +michaelbondar.tk, 1 +michaelcullen.name, 1 +michaelglaser.de, 1 +michaelgroves.tk, 1 +michaelgwynn.tk, 1 +michaelhayes.tk, 1 +michaelhrehor.com, 1 +michaeliannetta.tk, 1 +michaelismold.com, 1 +michaelizquierdo.com, 1 +michaeljdennis.com, 0 +michaeljohnsrestaurant.com, 1 +michaelklos.nl, 1 +michaelkorsgill.tk, 1 +michaelkosiba.com, 1 +michaelkuchta.me, 1 +michaelkuehn.tk, 1 +michaell.io, 1 +michaell.xyz, 1 +michaelleibundgut.com, 1 +michaelloveys.com, 1 +michaelmckenney.com, 1 +michaeln.net, 1 +michaelpelletterie.it, 1 +michaelpfrommer.de, 1 +michaelpfrommer.pub, 1 +michaelpmullally.com, 1 +michaelrigart.be, 1 +michaelschmidt.ch, 1 +michaelschubert.com, 1 +michaelstenberg.com, 1 +michaelstoffer.com, 1 +michaelsweater.com, 1 +michaeltaboada.me, 1 +michaeltjeuw.com.au, 1 +michaeltroger.com, 1 +michaeltruskowski.com, 1 +michaelvician.me, 0 +michaelwermeester.com, 1 +michaelwmckinney.com, 1 +michal-klabnik.com, 1 +michal-klabnik.cz, 1 +michal-s.net, 1 +michal-spacek.com, 1 +michal-spacek.cz, 1 +michaldudek.it, 1 +michalinastrzyz.xyz, 1 +michalis.xyz, 1 +michalklabnik.com, 1 +michalklabnik.cz, 1 +michalkozak.cz, 1 +michalkral.tk, 1 +michalp.pl, 0 +michalpodraza.pl, 1 +michalspacek.com, 1 +michalspacek.cz, 1 +michalwiglasz.cz, 1 +michaonline.de, 1 +michasfahrschule.com, 1 +michel-kratochvil.tk, 1 +michel-wein.de, 1 +micheladisavino.tk, 1 +michelangelofoundation.org, 1 +michele.ga, 1 +michele.ml, 1 +micheleandkeith.com, 1 +michelgolfier.ml, 1 +michellavat.com, 1 +michellelowery.com, 1 +michelletmc.com, 1 +michelletrachtenberg.tk, 1 +michelskovbo.dk, 1 +michelwolf.ch, 1 +michey.tk, 1 +michibeck.eu, 1 +michielbijland.nl, 1 +michielvanfastenhout.nl, 1 +michig.tk, 1 +michiganstateuniversityonline.com, 1 +michiganunionoptout.com, 1 +michilaw.com, 1 +michmexguides.com.mx, 1 +michu.pl, 1 +mickel.tk, 1 +mickelvaessen.com, 1 +mickybottenberg.com, 1 +mickyfanclub.tk, 1 +micluz.shop, 1 +mico.world, 1 +micoff.tk, 1 +micomi.co, 1 +micopal.com, 1 +micospa.gq, 1 +micr0lab.org, 1 +micra.org.uk, 1 +micredito-ok.com, 1 +micro-credit.tk, 1 +microbiologist.tk, 1 +microbiote-insectes-vecteurs.group, 1 +microbird.club, 1 +microblading.pe, 1 +microcert.cn, 1 +microco.sm, 1 +microcomploja.com.br, 1 +microdesic.com, 1 +microdots.de, 1 +microfinance-crimea.ru, 1 +microfusion.tw, 1 +microgreensworld.com, 1 +microjournal.xyz, 1 +microjovem.pt, 1 +microl.ink, 1 +microlog.org, 1 +micromaid.cf, 1 +micromata.de, 1 +micromegas.com.ua, 1 +micromind.io, 1 +microneedlingstudio.se, 1 +micropigmentadordesucesso.com, 1 +microsoftedgeinsider.com, 1 +microtel2notch.tk, 1 +microtube.tk, 1 +microvb.com, 1 +microwesen.de, 1 +microzubr.com, 1 +micsell.com, 1 +micsoft.gq, 1 +miculturaservicios.gob.do, 1 +midair.io, 1 +midamericapiering.com, 1 +midasauctions.com, 1 +midasjewellery.com.au, 1 +midcarolinaregionalairport.com, 1 +midcarolinaregionalairport.org, 1 +middle.io, 1 +middlesexwoodpigeonclub.co.uk, 1 +middletonshoppingcentre.co.uk, 1 +middletowndelcopa.gov, 1 +mide.gob.do, 1 +mideo.tk, 1 +midgawash.com, 1 +midi-coquillages.com, 1 +midi-ctes.fr, 1 +midia.tk, 1 +midiaid.de, 1 +midial.cz, 1 +midislandrealty.com, 0 +midkam.ca, 1 +midl.me, 1 +midlandgate.de, 1 +midlandsfundays.co.uk, 1 +midlandslotus.co.uk, 1 +midlandsphotobooths.co.uk, 1 +midnight-gaming-community.tk, 1 +midnightmango.co.uk, 1 +midnightmango.de, 1 +midnightmechanism.com, 1 +mido.ga, 1 +midrandplumber24-7.co.za, 1 +midress.club, 1 +midriversmotorsllc.com, 0 +midstatebasement.com, 1 +midterm.us, 1 +midtnorskvask.com, 1 +midwayrecovery.com, 1 +midwestbloggers.org, 1 +midweststructuralrepair.com, 1 +midyatotantik.tk, 0 +miegl.com, 1 +miegl.cz, 1 +mieldemexico.us, 1 +mielelpinsapar.com, 1 +miembarcacion.com, 1 +miemus.eu, 1 +mieresabadus.ro, 1 +mierloiu.ro, 1 +mieszkania-wroclaw.tk, 1 +mieterschutzkartei.de, 1 +mietwohnungen-vermietung.com, 1 +mieuxgrandir.ch, 0 +miffy.me, 1 +miftahulteknik.com, 1 +mig5.net, 1 +miggy.org, 1 +mightful-noobs.de, 1 +mightytext-ios.tk, 1 +mightytips.com, 1 +migliorisitiincontri.it, 1 +migraine-en-werk.nl, 1 +migrainereliefplan.com, 1 +migrantskillsregister.org.uk, 1 +migrations.tk, 1 +miguel-platteel.fr, 1 +miguel.pw, 1 +miguelcolmenares.com, 1 +migueldemoura.com, 1 +migueldominguez.ch, 0 +miguelgaton.es, 1 +miguelito.tk, 1 +miguelkertsman.com, 1 +miguelmartinez.ch, 0 +miguelmenendez.pro, 1 +miguelmoura.com, 1 +migueloblitas.tk, 1 +miguelpallardo.tk, 1 +miguia.tv, 1 +mihalgrameno.ml, 1 +mihalicka.com, 1 +mihanwebtest.tk, 1 +mihealth.link, 1 +mihealthl.ink, 1 +mihgroup.eu.org, 1 +mihgroup.net, 1 +mihnea.net, 1 +mihu233.com.cn, 1 +miisy.com, 1 +miisy.eu, 1 +miisy.me, 1 +mijam.xyz, 1 +mijcorijneveld.nl, 1 +mijn.computer, 0 +mijnadviseur.shop, 1 +mijncloud.space, 1 +mijngeldcoach.nl, 1 +mijngent.be, 1 +mijnkantoor.net, 1 +mijnkerstkaarten.be, 1 +mijnkinderkleding.com, 1 +mijnkwadraad.nl, 1 +mijnnaamdag.nl, 1 +mijnreisoverzicht.nl, 1 +mijnsite.ovh, 1 +mijnstembureau.nl, 1 +mijntelefoonboek.com, 1 +mijntransacties.nl, 0 +mijnwefact.nl, 1 +mika.cat, 1 +mika.moe, 1 +mikadoe.nl, 1 +mikaelf.com, 1 +mikaeljansson.net, 1 +mikaelk.tk, 1 +mikaelvesavuori.se, 1 +mikaila.tk, 1 +mikakalathil.ca, 1 +mikakalevi.com, 1 +mikaknuutila.fi, 1 +mikalikes.men, 1 +mike-bland.com, 1 +mike-burns.com, 1 +mike-et-pascale-sanger.com, 1 +mikeandemily.duckdns.org, 1 +mikeandersondj.com, 1 +mikebelanger.ca, 1 +mikeblog.site, 1 +mikebutcher.ca, 1 +mikecameronyyc.com, 1 +mikecapson.com, 1 +mikecb.org, 1 +mikechasejr.tk, 1 +mikegao.net, 0 +mikegao.org, 1 +mikegerwitz.com, 1 +mikeguy.co.uk, 1 +mikehamburg.com, 1 +mikeklidjian.com, 1 +mikekreuzer.com, 1 +mikelpradera.tk, 1 +mikemcgeephotography.com, 1 +mikemooresales.com, 1 +mikeowens.us, 1 +mikeprocopio.com, 1 +mikerichards.gallery, 1 +mikerichards.photography, 1 +mikerichards.photos, 1 +mikerichards.pictures, 1 +mikerichardsphotography.com, 1 +mikesplumbingswfl.com, 1 +mikesystems.tk, 1 +miketabor.com, 1 +miketheuer.com, 1 +mikethiessen.net, 1 +mikevesch.com, 1 +mikewillia.ms, 1 +mikewrites.online, 1 +mikewritesstuff.com, 1 +mikeybot.com, 1 +mikeylab.com, 1 +mikeyroxtravels.com, 1 +mikhailkolesnikov.tk, 1 +mikhirev.ru, 1 +mikhlevich.ru, 1 +miki-boras.de, 1 +miki.it, 1 +mikino.cf, 1 +mikino.ga, 1 +mikino.gq, 1 +mikino.ml, 1 +mikkei.space, 1 +mikkel.cc, 1 +mikkelladegaard.dk, 0 +mikkelscheike.com, 1 +mikkelvej.dk, 1 +mikkonen.bio, 1 +miklagard.dk, 1 +miklcct.com, 1 +mikmik.co.il, 1 +miknight.com, 1 +mikonmaa.fi, 1 +mikori.sk, 1 +mikrokolektyw.com, 1 +mikrom.cz, 0 +mikropixel.de, 1 +mikrotech.co.za, 1 +mikrozajmy-na-kartu.cf, 1 +miku.bar, 1 +miku.cloud, 1 +miku.party, 1 +miku.ro, 1 +mikumiku.stream, 1 +mikupic.com, 1 +mikusa.xyz, 1 +mil-spec.ch, 0 +mil0.com, 1 +milacronindia.com, 1 +milaelaine.net, 1 +milahendri.com, 1 +milakirschner.de, 1 +milan-news.ml, 1 +milania.de, 1 +milanoclownfestival.tk, 1 +milanow67.ml, 1 +milanpala.cz, 0 +milanstephan.de, 0 +milanvit.net, 1 +milavica.tk, 1 +milbournequine.co.uk, 1 +milcahsmusings.com, 1 +milcarteles.com, 1 +milchweg.com, 1 +mildridesua.com, 1 +milehighmaniac.com, 1 +mileme.com, 1 +milenaria.es, 1 +milenkojovanov.com, 0 +milesaddict.com, 1 +milesapart.dating, 1 +milesdewitt.com, 1 +mileyweasel.de, 1 +milfpornograph.com, 1 +milhistwiki.tk, 1 +milhoazul.com.br, 1 +milieuland.com, 1 +military-equipment.tk, 1 +militaryaviationsafety.gov, 1 +militaryconsumer.gov, 1 +militaryfetish.tk, 1 +militaryonesource.mil, 1 +militarysrit.tk, 1 +miljotankar.se, 1 +milkaalpesiutazas.hu, 1 +milkagyengedseg.hu, 1 +milkaholic.ml, 1 +milkameglepetes.hu, 1 +milkingit.co.uk, 1 +milkingit.net, 1 +milkmoovement.io, 1 +milktea.info, 0 +milkypond.org, 1 +mill.ml, 1 +millbrookbedandbreakfast.co.uk, 1 +millefleurs.eu, 1 +millennium-thisiswhoweare.net, 1 +millenniumfalcon.org, 1 +millenniumstem.org, 1 +millenniumweb.com, 0 +miller-shop.cf, 1 +millerandzois.com, 1 +milleron.net, 1 +milleron.xyz, 1 +millerpaving.com, 1 +millersminibarns.com, 1 +millersprolandscape.com, 0 +millerwalker.com, 1 +millesime-communication.fr, 1 +millettable.com, 1 +milliarden-liste.de, 1 +millibitcoin.jp, 1 +milliegrace.org, 1 +millikart.az, 1 +millionairessecrets.com, 1 +millioncombolist.tk, 1 +millionen-von-sonnen.de, 1 +millistream.com, 1 +millonario.tk, 1 +millscountyiowa.gov, 1 +millsidecentre.org, 1 +millwoodwa.gov, 1 +milmiedos.tk, 1 +milon-apps.com, 0 +milr.dk, 1 +miltau.de, 1 +miltor.by, 1 +miltor.com.ua, 1 +miltor.ru, 1 +milwaukee-webdesigner.com, 1 +milwaukeecreative.com, 1 +mim.am, 1 +mim.properties, 1 +mimavision.ddns.net, 1 +mimemo.io, 1 +mimemoriadepez.com, 1 +mimeo.digital, 1 +mimgnj.com, 1 +mimisi.ru, 1 +mimithedog.com, 1 +mimm.gov, 1 +mimmog.it, 1 +mimocad.io, 1 +mimonia.cf, 1 +mimonia.ga, 1 +mimonia.gq, 1 +mimovrste.com, 1 +mimumimu.net, 1 +mimundodxn.com, 1 +mimusic.cf, 1 +min-datorsupport.se, 1 +min-sky.no, 1 +min.kiwi, 0 +minacssas.com, 1 +minaio.tk, 1 +minakov.pro, 1 +minakova.pro, 1 +minami.xyz, 1 +minamo.io, 1 +minandolacorrupcion.mx, 1 +minantavla.se, 0 +minapan.ro, 1 +minapin.com, 1 +minaprine.com, 1 +minbrew.com, 1 +minced.cf, 1 +mincom.ga, 1 +mind-books.gq, 1 +mind-box.ch, 0 +mind-farma.com, 1 +mind-hochschul-netzwerk.de, 1 +mind-moves.es, 1 +mindandfull.ga, 1 +mindask.tk, 1 +mindatasupport.nu, 1 +mindatasupport.se, 1 +mindatorsupport.se, 1 +mindbounce.com, 1 +mindbuild.com, 1 +mindcms.nl, 1 +mindcoding.ro, 1 +mindcraft.ga, 1 +minddistortion.tk, 1 +minddrive.cf, 1 +mindera.com, 1 +mindercasso.nl, 1 +mindfactory.de, 1 +mindfulnessjourney.ca, 1 +mindhunter.info, 1 +mindjee.tk, 1 +mindleaking.org, 1 +mindlush.com, 1 +mindmax.fi, 1 +mindmeister.com, 1 +mindmusic.online, 1 +mindofmedia.dk, 1 +mindoktor.se, 0 +mindomo.com, 1 +mindonmymoney.nl, 1 +mindorbs.com, 1 +mindox.com.br, 1 +mindresti.tk, 1 +mindthe5.com, 1 +mindthe5.org, 1 +mindvsmind.tk, 1 +mindwork.space, 1 +mine-craftlife.com, 1 +mine-pixl.de, 1 +mine260309.me, 0 +minebier.dk, 1 +minebitcoin.tk, 1 +minecraft-forum.eu, 1 +minecraft-reviews.com, 1 +minecraft-server.eu, 1 +minecraft.gen.tr, 1 +minecraftbestroyale.gq, 1 +minecraftdolarcube.gq, 1 +minecrafteasy.gq, 1 +minecraftforum.de, 1 +minecraftforum.ovh, 1 +minecraftgoldwar.tk, 1 +minecraftjson.com, 0 +minecraftjustone.ga, 1 +minecraftonlinesfull.tk, 1 +minecraftrealgold.gq, 1 +minecraftrealgold.ml, 1 +minecraftruns.ml, 1 +minecrafts.gq, 1 +minecraftstal.com, 1 +minecraftwin.gq, 1 +minecraftworlds.info, 1 +minecraftx.ml, 1 +minefields.tk, 1 +minehash.tk, 1 +minehattan.de, 1 +minehub.de, 1 +minei.me, 1 +minelands.ml, 1 +minelight.ml, 1 +minepack.net, 1 +minepic.org, 0 +mineralky.com, 1 +mineralnibani.bg, 1 +minered.org, 1 +minermonitoring.com, 1 +minerstat.com, 1 +minerva2015.it, 1 +minervacars.com, 1 +minesouls.fr, 1 +minestory.cf, 1 +minetrack.de, 1 +minetrack.no, 1 +minetracker.dk, 1 +mineturtle.de, 1 +minez-nightswatch.com, 0 +minf3-games.de, 1 +minfin.gov.ua, 1 +mingky.net, 1 +mingkyaa.com, 1 +mingming.info, 1 +mingram.net, 1 +mingwah.ch, 0 +mingy.ddns.net, 1 +minh.at, 0 +minhanossasenhora.com.br, 1 +minhanwindow.vn, 1 +minhng99.cloud, 1 +minhng99.eu, 1 +minhyukpark.com, 1 +mini-igra.tk, 1 +mini-piraten.de, 1 +mini2.fi, 1 +minialbums.ga, 1 +miniatomium.tk, 1 +miniaturepets.net, 1 +minibaggerverleih-aulendorf.de, 1 +minibikini.cf, 1 +minibrewery.cf, 1 +minibus-service.ru, 1 +minicampingshalom.nl, 1 +minican.net, 1 +miniclip.com, 1 +minigames.com, 1 +minigermanauto.com, 1 +minigolf-reisinger.com, 1 +minigolfandgames.co.uk, 1 +minikidz.es, 1 +minikin.tk, 1 +minikneet.com, 1 +minikumbaradergisi.com, 0 +minilions.fr, 1 +minilov.fr, 0 +minimal-apps.de, 1 +minimal-nothing.ml, 1 +minimal-website.ch, 0 +minimalistbaker.com, 1 +minimalistmenu.com, 1 +minimaliston.com, 1 +minimalmx.io, 1 +minimayhemsoftplay.co.uk, 1 +minimbah.com.au, 1 +minimonies.tk, 1 +minimvc.com, 1 +mining-club.tk, 1 +mining.diamonds, 1 +miningtronics.com, 0 +minintendo.tk, 1 +minipc.de, 1 +minipigscare.com, 1 +minir.ru, 1 +minirizhi.com, 1 +miniskipper.at, 1 +miniso.me, 1 +minisoft4u.ir, 1 +ministeriumfuerinternet.de, 1 +ministory.tk, 1 +ministranten-sankt-ge.org, 1 +ministryofinternet.eu, 1 +minitruckin.net, 1 +minitrucktalk.com, 1 +minivaro.de, 1 +minivehicle.tk, 1 +miniverse.social, 1 +minivideoadapterssales.tk, 1 +miniwallaby.com, 1 +miniwaplus.com, 1 +minix.jp, 1 +minjusticia.gob.cl, 1 +mink-coat.tk, 1 +minka.net.bo, 1 +minkymoon.jp, 1 +minload.com, 1 +minmaxgame.com, 1 +minna.tk, 1 +minndak.net, 1 +minnesotakinkyyouth.org, 1 +minnesotareadingcorps.org, 1 +minnit.chat, 1 +minobar.com, 1 +minocyclinee.gq, 1 +minocyclinehere.gq, 1 +minocyclines.gq, 1 +minor.news, 1 +minorisa.tk, 1 +minoritywhip.gov, 1 +minorshadows.net, 1 +minotauro.com.ar, 1 +minoxbahia.com.br, 1 +minpex.nl, 1 +minpingvin.dk, 1 +minschuns.ch, 1 +minsk-city.tk, 1 +minsk-cops.tk, 1 +minsk-music.tk, 1 +mintclass.com, 1 +mintea-noua.ro, 1 +mintecc.com, 1 +minternals.com, 1 +mintert.net, 1 +minto.cc, 1 +minton.systems, 1 +mintosherbs.com, 1 +mintrak2.com, 1 +mintse.com, 0 +minttang.cn, 0 +minu.link, 1 +minube.co.cr, 1 +minucaelena.com, 1 +minutashop.ru, 1 +minuteflightdeals.com, 1 +minuto30.com, 0 +minux.info, 1 +mio-ip.ch, 1 +miodziki.pl, 1 +mionerve.com, 1 +mionerve.org, 1 +mipapo.de, 1 +mipasevip.com, 1 +mipnet.cl, 1 +miproximopaso.org, 1 +miprudelafi.ga, 1 +mips.co.in, 1 +mipymesenlinea.com, 1 +mir-faktov.tk, 1 +mir-koji.tk, 1 +mir-multimedia.tk, 1 +mir-pressy.ga, 1 +mir-tiktak.tk, 1 +mir-torgovli.tk, 1 +mir.do, 1 +mir.pe, 1 +mir24.tk, 1 +miraclesformya.org, 1 +mirador.co.uk, 1 +miragenews.com, 1 +miragg.cf, 1 +miraggiostudio.com, 1 +miraheze.org, 1 +mirai-coupon.com, 1 +miraidenshi.com, 1 +miraiex.com, 0 +miramar-obgyn.com, 1 +miramar.ca, 1 +miramaraddictionandrehabcenters.com, 1 +mirasmun.tk, 1 +miratechgroup.com, 1 +miraxe.cf, 1 +miraxe.ga, 1 +mirazonline.tk, 1 +mirazperu.com, 1 +mirazperu.tk, 1 +mircarfinder.ru, 1 +mirdetaley.tk, 1 +mirdon.com, 1 +mireiaseuba.com, 1 +mireillewendling.com.br, 1 +mirepublic.co.nz, 1 +mireservaonline.es, 1 +mirfire.com, 0 +miriamgamburd.com, 1 +mirinfonews.tk, 1 +mirjamderijk.nl, 1 +mirkino.tk, 1 +mirknighechek.tk, 1 +mirknighek.cf, 1 +mirknighek.gq, 1 +mirkofranz.de, 1 +mirkvartir.tk, 1 +mirnesnet.tk, 1 +mirnews.ml, 1 +mirobuvi.com.ua, 1 +mirokon.tk, 1 +mironet.cz, 1 +mironi.ml, 1 +mironov.tk, 1 +miroslavbaka.cz, 1 +mirrordream.net, 1 +mirrormirror.tk, 1 +mirrorsedgearchive.de, 1 +mirrorsedgearchive.ga, 1 +mirrorwood.com, 1 +mirs.ky, 1 +mirshak.com, 0 +mirstroy.su, 1 +mirtazapine.gq, 1 +mirtes.cz, 1 +mirtouf.fr, 1 +mirumhongkong.com, 1 +mirvent.site, 1 +mirvolgograda.ml, 1 +mirwild.cf, 1 +mirwild.gq, 1 +mirzetonline.tk, 1 +misakacloud.net, 1 +misakaloli.com, 1 +misakastudio.com, 1 +misakiya.co.jp, 1 +misclick.net, 1 +misclick.nl, 1 +misclick.xyz, 1 +misconfigured.io, 1 +miscuadros.tk, 1 +miscursosdebelleza.com, 1 +misfit-media.com, 1 +mishavayner.com, 1 +mishkan-israel.net, 1 +mishkinn.ru, 1 +mishkovskyi.net, 1 +misiepluszowe.com, 1 +misini.fr, 1 +misinstrumentos.com, 1 +miskatonic.org, 1 +misoji-resist.com, 1 +misol.kr, 1 +misp-project.org, 1 +mispromo.com, 1 +miss-inventory.co.uk, 1 +miss-platinum.net, 1 +miss.com.tw, 1 +missakari.com, 1 +missaocadastrobv.com.br, 1 +missapk.com, 1 +missbitcoin.nl, 1 +missblisshair.com.au, 1 +missdoertie.net, 1 +missdream.org, 1 +misseguf.dk, 1 +missevent.pl, 1 +missguidedus.com, 1 +missilovely.tk, 1 +missinglinknyc.com, 1 +missinicial.com, 1 +mission-gesundheit.online, 1 +mission-orange.de, 1 +missionflare.com, 1 +missionpuppy.nl, 1 +missionsgemeinde.de, 1 +mississippigenealogy.com, 1 +misskey.site, 0 +missmaid.co.uk, 1 +missmaid.com, 1 +misson.ovh, 1 +missouri-sky.tk, 1 +missouriheatingcoolingadvice.com, 1 +missoy.me, 1 +misspoliticsaustralia.cf, 1 +missthetoro.tk, 1 +misstika-bijoux.com, 1 +misstress.cf, 1 +missualready.com, 1 +missuniverse.tk, 1 +missworldinfo.tk, 1 +missycosmeticos.com.br, 1 +missycraindance.com, 1 +missyjay.tk, 1 +missyou.link, 1 +missyou.ro, 1 +mist79.ru, 1 +mistacms.com, 1 +mister-matthew.de, 1 +misterandersson.com, 1 +misterboddy.com, 1 +misterd.ml, 1 +mistergermany.tk, 1 +mistergout.com, 1 +misterkeltic.com, 1 +misterl.net, 1 +misterorion.com, 1 +misterseguros.com.br, 1 +mistlake.net, 1 +mistreaded.com, 1 +mistressofbeads.tk, 1 +mistybox.com, 1 +misumasu.com, 1 +misupport.dk, 1 +misura.re, 1 +mit-dem-rad-zur-arbeit.de, 1 +mit-dem-rad-zur-uni.de, 1 +mit-uns.org, 1 +mit.gg, 1 +mita.me, 1 +mitaines.ch, 0 +mitarbeitermotivation-anleitungen.de, 1 +mitchell.id, 1 +mitchellhandymanservices.co.uk, 1 +mitchelmore.ca, 1 +mitchkalf.nl, 1 +mitchkiah.com, 1 +mitdip-mit-group-ch.azurewebsites.net, 1 +mite3.nl, 1 +mitegra.herokuapp.com, 1 +mitevi.com, 1 +mitfx.com, 1 +mithgol.tk, 1 +mitiad.gq, 1 +miticobikes.com, 1 +mitigationcommission.gov, 1 +mitior.net, 1 +mitnetz-gas.de, 1 +mitnetz-strom.de, 1 +mitratech.com.br, 1 +mitrax.com.br, 1 +mitre10.com.au, 0 +mitrecaasd.org, 1 +mitremai.org, 1 +mitrostudios.com, 1 +mitsign.com, 1 +mitsonnenbrillen.de, 1 +mitstek.com, 1 +mitsubishielectric-rce.eu, 1 +mitsuvictory.com, 1 +mittagonggardencentre.com.au, 1 +mittagonghomestead.com.au, 1 +mittelalter-lexikon.de, 1 +mittelunsachlich.de, 1 +mittendorff.tk, 1 +mittenofficesystems.com, 1 +mittid.dk, 1 +mittikimonos.com.br, 1 +mittwoch-nacht.net, 1 +mitzpettel.com, 1 +miui-germany.de, 1 +miukimodafeminina.com, 1 +mivestuariolaboral.com, 1 +mividasecreta.tk, 1 +mivm.cn, 1 +mivne.co.il, 1 +mivzak.im, 1 +mivzakim.biz, 1 +mivzakim.cf, 1 +mivzakim.info, 1 +mivzakim.ml, 1 +mivzakim.mobi, 1 +mivzakim.net, 1 +mivzakim.org, 1 +mivzakim.tk, 1 +mivzakim.tv, 1 +miweb.cr, 0 +mix-books.ga, 1 +mix-channel.ml, 1 +mix-recruit.jp, 1 +mix.my, 1 +mixedmenus.com, 1 +mixedreality.football, 1 +mixedrecipe.com, 1 +mixes.cloud, 1 +mixinglight.com, 1 +mixmastermitch.com, 1 +mixmister.com, 1 +mixmix.tk, 1 +mixpanel.com, 1 +mixposure.com, 1 +mixtafrica.com, 1 +mixtape.moe, 1 +mixx.com.hk, 1 +miya.io, 1 +miyagi-ctr.com, 1 +miyagi-r.com, 1 +miyako-kyoto.jp, 1 +miyanaga.tech, 1 +miyatakaikei.com, 1 +miyatore.com, 1 +miyoshi-kikaku.co.jp, 1 +miyoshi-kikaku.com, 0 +miyugirls.com, 1 +mizar.im, 0 +mizik.cz, 1 +mizoey.se, 1 +mizque.ch, 1 +mizrahi-tefahot.co.il, 1 +mizternational.com, 1 +mizu.coffee, 1 +mizuasobi.work, 1 +mizucoffee.net, 1 +mizuhobank.co.id, 1 +mizukoshika.jp, 1 +mizumax.me, 1 +mj420.com, 1 +mjacobson.net, 1 +mjanja.ch, 1 +mjasm.org, 1 +mjforan.com, 1 +mjgroup.io, 1 +mjish.com, 1 +mjjlab.com, 1 +mjmedia.co.za, 1 +mjniessen.com, 1 +mjpak.com.au, 1 +mjrlegends.com, 1 +mjs-domy.pl, 1 +mjsacco-dwi.com, 1 +mjsacco.com, 1 +mjscustomcreations.com.au, 1 +mjstudios.tk, 1 +mjt.me.uk, 1 +mk-dizajn.com, 1 +mk.gov.tr, 1 +mk89.de, 1 +mkacg.com, 1 +mkaciuba.com, 0 +mkakh.com, 1 +mkakh.xyz, 1 +mkalisch.de, 1 +mkbd.ru, 1 +mkbet.tk, 1 +mkbouncycastles.co.uk, 1 +mkbouncyhire.co.uk, 1 +mkboynton.org, 1 +mkcert.org, 1 +mkchandler.com, 1 +mkfs.fr, 1 +mkg-wiebelskirchen.de, 1 +mkhsoft.eu, 1 +mkie.cf, 1 +mkimage.com, 0 +mkinteriores.com.br, 1 +mkjl.ml, 0 +mkk.de, 1 +mkkkrc.ru, 1 +mklenterprises.com, 1 +mklenterprisesacademy.com, 1 +mklenterprisescoaching.com, 1 +mklpedia.de, 1 +mkm.ee, 1 +mkm.szczecin.pl, 1 +mkmedien.tk, 1 +mknclab.info, 1 +mkoppmann.at, 1 +mkpdeepclean.com, 1 +mkplay.io, 1 +mksac.co.uk, 1 +mksdarchitects.com, 1 +mkse.com, 1 +mkset.ru, 0 +mksport.ru, 1 +mkt.com, 1 +mkt7.de, 1 +mktdigital.info, 1 +mktemp.org, 1 +mktenlared.com, 1 +mkuznets.com, 1 +mkw.st, 1 +mkws.sh, 1 +ml-academy.org, 1 +mlada-moda.cz, 1 +mladamoda.sk, 1 +mladenovac.tk, 1 +mlarte.com, 1 +mlathrom.com, 1 +mlcfinvest.in, 1 +mlcnfriends.com, 1 +mlcreaciones.com, 1 +mlcrosoftonlline.cz, 1 +mlcrosoftonlline.ml, 1 +mlfaw.com, 1 +mlii.net, 1 +mlirb.com, 1 +mllz.com, 1 +mlmjam.com, 1 +mlmjunction.tk, 1 +mlnews.ml, 1 +mlo.no, 1 +mlohr.com, 1 +mlonline.com.mx, 1 +mloska.tk, 1 +mlpvcdn.top, 1 +mlpvector.club, 1 +mlsrv.de, 1 +mlstav.sk, 1 +mlsvallarta.com, 1 +mlum.net, 1 +mlundberg.se, 1 +mlv.me, 1 +mlwr.ee, 1 +mlytics.com, 1 +mm13.at, 1 +mm404.com, 1 +mm5197.co, 1 +mm6729.co, 1 +mm6729.com, 1 +mm6957.co, 1 +mm88game.com, 1 +mm9297.co, 1 +mm9397.com, 1 +mm9721.com, 1 +mm9728.co, 1 +mma-records.de, 1 +mmafactory.com.au, 1 +mmalisz.com, 1 +mmaps.ddns.net, 1 +mmaps.org, 1 +mmarnitz.de, 1 +mmassemblyline.de, 1 +mmbb.org, 0 +mmcafe.com.br, 1 +mmcalc.jp, 1 +mmcase.ml, 1 +mmcwholesale.com, 1 +mmgal.com, 1 +mmgtx.com, 1 +mmhome.fr, 1 +mmichaelb.pw, 1 +mmilog.hu, 1 +mminsco.com, 1 +mmkstudio-digital.com, 1 +mml.cx, 0 +mmlebanon.com, 1 +mmm.lu, 1 +mmmarco.com, 1 +mmmaximaliselmeny.hu, 1 +mmmm.mn, 1 +mmmonk.net, 1 +mmogah.com, 1 +mmoneko.com, 1 +mmonit.com, 1 +mmot.sk, 1 +mmoveisplanejados.com.br, 1 +mmpaymentsystem.com, 1 +mmphub.com, 1 +mmprojects.nl, 0 +mms.is, 1 +mmscy.com, 0 +mmsmotor.com.hk, 1 +mmstick.tk, 1 +mmucha.de, 1 +mmuclassifieds.tk, 1 +mmwb.nl, 1 +mmxblog.com, 1 +mmzztt.com, 1 +mnatechnologies.com.au, 0 +mnbg.tk, 1 +mnciitbhu.me, 1 +mncloud.de, 1 +mncr.nl, 1 +mnd.sc, 1 +mne.moe, 1 +mnec.io, 1 +mneeb.de, 1 +mnemonic.ninja, 1 +mnemonicninja.com, 1 +mneti.ru, 1 +mngfam.ddns.net, 1 +mnguyen.io, 1 +mnienamel.com, 1 +mnitro.com, 1 +mnium.de, 1 +mnjg123.de, 1 +mnkt.site, 1 +mnlfnet.com, 1 +mnml.art, 1 +mnml.blog, 1 +mnml.top, 1 +mnn.tw, 1 +mnnknz.de, 1 +mnogodetey.ru, 1 +mnogoknighek.gq, 1 +mnogoknighek.ml, 1 +mnogoknighek.tk, 1 +mnogosofta.tk, 1 +mnogoznai.tk, 1 +mnotrioesdp.ml, 1 +mnrloroli.tk, 1 +mnrv.trade, 1 +mns.co.jp, 1 +mns.jp, 0 +mns.llc, 1 +mnsure.org, 1 +mnt-tech.fr, 1 +mnt9.com, 1 +mnt9.de, 1 +mo-en-karim.tk, 1 +mo-journal.com, 1 +mo-mochizuki.com, 1 +mo-vvs.dk, 1 +mo.nl, 1 +mo2021.de, 1 +mo3.club, 1 +moa.moe, 1 +moabit.de, 1 +moabpapier.de, 1 +moabygg.se, 1 +moahmo.com, 1 +moarcookies.com, 1 +moas.design, 1 +moas.photos, 1 +mobal.com, 1 +mobeforlife.com, 0 +mobi-katalog.tk, 1 +mobi2go.com, 1 +mobi4.tk, 1 +mobidesigns.org, 1 +mobijo.tk, 1 +mobil-bei-uns.de, 1 +mobila-chisinau.md, 1 +mobilcom-debitel-empfehlen.de, 1 +mobildeal.id, 1 +mobile-holzofenpizza.de, 1 +mobile-ivr.tk, 1 +mobile-news.tk, 1 +mobile.eti.br, 1 +mobile.united.com, 0 +mobile.usaa.com, 0 +mobile360.ph, 1 +mobileague.ml, 1 +mobilebingoclub.co.uk, 1 +mobilebooster.tk, 1 +mobilecasinoclub.co.uk, 1 +mobilecontractcomparison.com, 1 +mobilecraftingco.com, 1 +mobilegoldcoastelectrical.ga, 1 +mobileinternetbanking.com, 1 +mobilelooper.com, 1 +mobilemedics.com, 1 +mobilenerve.com, 1 +mobilepartner.tk, 1 +mobiler-handel.de, 1 +mobileread.com, 1 +mobilerhandwerker.de, 1 +mobileritelushi.com, 1 +mobilesector.de, 1 +mobilesnewsworld.ga, 1 +mobilespectrum.org, 1 +mobilestuff.tk, 1 +mobiletirer.tk, 1 +mobiletraff.co, 1 +mobiletry.com, 1 +mobilewikiserver.com, 1 +mobilhaber.ga, 1 +mobilhondatangsel.com, 1 +mobilinnov.it, 1 +mobilisation-generale.org, 0 +mobiliteit.gent, 1 +mobiliteitgent.be, 1 +mobiliteitsbedrijf-gent.be, 1 +mobiliteitsbedrijf.be, 1 +mobiliteitsbedrijfgent.be, 1 +mobiliteitsbedrijfstadgent.be, 1 +mobiliteitstadgent.be, 1 +mobility-events.ch, 1 +mobilize.us, 1 +mobilizon.fr, 1 +mobilizon.org, 1 +mobilki.tk, 1 +mobilni.site, 1 +mobilux.lv, 1 +mobilyaderyasi.com, 1 +mobimsua.com, 1 +mobincube.com, 1 +mobincube.es, 1 +mobincube.mobi, 1 +mobincube.net, 1 +mobinst.ml, 1 +mobinstore.com, 0 +mobio.net, 1 +mobiproj.com, 1 +mobisaar-cloud.de, 1 +mobistartv.ml, 1 +mobisuper.com.au, 1 +mobitracker.co, 1 +mobius.network, 1 +mobizat.com, 1 +mobizma.com, 1 +mobl.io, 1 +moblkar.com, 1 +mobmp4.com, 1 +mobmp4.info, 1 +mobobe.com, 1 +mobolight.ml, 1 +mobsitin.tk, 1 +mobtop.ml, 1 +moburst.com, 1 +mobycoders.com, 1 +mobydog.net, 1 +mobylette.tk, 1 +moc.ac, 1 +moca-2080.com, 1 +moca-2081.com, 1 +moca-2082.com, 1 +moca-2083.com, 1 +moca-kinder.de, 1 +mochasoft.jp, 1 +mochilerostailandia.com, 1 +mochiyuki.net, 1 +mochizuki.moe, 1 +mochoko.com, 1 +mockerel.com, 1 +mocking-bird.org, 1 +mocking.top, 1 +mocknen.net, 1 +mockups.com.co, 1 +mocloud.eu, 1 +mococo.co.uk, 1 +mod.af, 1 +moda-donna.cf, 1 +moda-line.ml, 1 +modacruz.com, 1 +modaexecutiva.com.br, 1 +modafinilici.com, 1 +modafo.com, 1 +modahouse.co, 1 +modalogi.com, 1 +modalrakyat.com, 1 +modamoom.com.br, 1 +modanacrho.tk, 1 +modanese.net, 1 +modav.org, 1 +modax.ua, 1 +modbom.com.tw, 1 +modcover.com, 1 +modded-minecraft-server-list.com, 1 +modded.club, 1 +moddedphones.com, 1 +modderday.com, 0 +modding-forum.com, 1 +modding-welt.com, 1 +moddiy.com, 1 +mode-hautnah.de, 1 +mode-individuell.de, 1 +mode-musthaves.com, 1 +mode-tabita.be, 1 +modecaso.com, 1 +model-school.tk, 1 +model.earth, 1 +modelbase.org, 1 +modelclub-draveil.eu, 1 +modelcube.com, 1 +modeldimension.com, 1 +modeldoll.tk, 1 +modelflight.com, 1 +modeli.tk, 1 +modelisme-rc.net, 1 +modelisme-voiture-rc.fr, 1 +modell-lq.net, 1 +modellbahnshop.de, 1 +modellismo.roma.it, 1 +modelpac.com.ua, 1 +modelservis.cz, 1 +modelspoor-projecten.nl, 1 +modelspoorprojecten.nl, 1 +modem.cf, 1 +modem7.com, 1 +modemaille.com, 0 +modemchild.net, 1 +modenuit.fr, 1 +moderatoren.org, 1 +modern-family.tv, 1 +modern-gaming.ga, 1 +modernagritec.com, 1 +modernapprenticeships.org, 1 +modernautorepairs.com, 1 +moderncommercialrealestate.com, 1 +moderndeck.org, 1 +moderndukes.tk, 1 +moderniknihovna.cz, 1 +modernliferoleplay.cf, 1 +moderntld.net, 1 +moderntrailers.com.au, 1 +moderntrainer.co.za, 1 +modernworkplacelearning.co.za, 1 +modesalination.com, 1 +modestoca.gov, 1 +modetalente.com, 1 +modicollege.com, 1 +modifiedmind.com, 1 +modineaviation.com, 1 +modistryusercontent.com, 1 +modmountain.com, 1 +modnitsa.info, 1 +mods-community.de, 1 +modscrew.com, 1 +modsrigs.com, 1 +modul-metal-habitat.fr, 1 +modul21.eu, 1 +modul8infinity.co, 1 +modul8r.com, 1 +module.market, 1 +modulebaan.tk, 1 +modulex-gmbh.de, 1 +modulkuhni.by, 1 +moduloseltaladro.com, 1 +modusawperandi.com, 1 +modxvm.com, 1 +moe-max.jp, 1 +moe.pe, 1 +moe.social, 1 +moe4sale.in, 1 +moeali.com, 1 +moebelschreinerei-engelhardt.de, 1 +moeblog.cn, 1 +moec.top, 1 +moechel.com, 1 +moecraft.net, 1 +moefactory.com, 1 +moefi.xyz, 1 +moegi.ml, 1 +moego.me, 1 +moehrke.cc, 1 +moekes.amsterdam, 1 +moeking.me, 1 +moeli.org, 1 +moeloli.ac.cn, 1 +moenew.top, 1 +moenew.us, 1 +moens.tech, 1 +moepass.com, 1 +moeqing.net, 1 +moer.tel, 1 +moescat.xyz, 0 +moesif.com, 1 +moetrack.com, 1 +moeyi.xyz, 0 +mof.gov.ws, 1 +mofohome.dyndns.org, 1 +mogamugi.com, 1 +mogica.tk, 1 +mogilev-forum.tk, 1 +mogomix.cf, 1 +moha-swiss.com, 0 +mohaabobclan.tk, 1 +mohabatein1.tk, 1 +mohamedalibenammarmaba.tk, 1 +mohamedhamuda.com, 1 +mohamedhosting.tk, 1 +mohamedsherif.ml, 1 +mohammad-yarahmadi.tk, 1 +mohammadreza-bakhtiari.tk, 1 +mohammedalrifai.tk, 1 +mohave.gov, 1 +moheatingcoolinghvac.com, 1 +mohela.com, 1 +moheyuddin.tk, 1 +mohitchahal.com, 1 +mohot.com, 1 +mohot.fit, 1 +mohr-maschinenservice.de, 1 +mohsen-pashootan.vercel.app, 1 +moi-sait.tk, 1 +moikolhoz.ml, 1 +moikolhoz.tk, 1 +moipourtoit.ch, 0 +moipourtoit.com, 0 +moipourtoit.org, 0 +moisesbarrio.es, 1 +mojaapteka.pl, 1 +mojaczarnastrona.pl, 1 +mojaknjiznica.com, 0 +mojama3dz.com, 1 +mojartech.ml, 1 +mojavenissanofbarstowparts.com, 1 +mojdom.ba, 1 +mojeco2.cz, 1 +mojefedora.cz, 1 +mojefilmy.xyz, 1 +mojekonsultacje.pl, 1 +mojezegarki.pl, 1 +mojilitygroup.com, 1 +mojitoparty-articlespara.website, 1 +mojkragujevac.net, 1 +mojleksikon.com, 1 +mojnet.eu, 1 +mojnet.net, 1 +mojo.az, 1 +mojoco.co.za, 1 +mojome.co.za, 1 +mojt.net, 1 +mojzis.com, 1 +mojzis.cz, 1 +mojzisova.com, 1 +mokamelhaa.ir, 1 +mokeedev.com, 1 +mokeedev.review, 1 +mokhan.ca, 1 +mokhtarmial.com, 1 +moki.org.pl, 1 +mokujinken.tokyo, 1 +mokum-organics.com, 0 +mokuroh.club, 1 +mokutovo.tk, 1 +molb.org, 1 +moldova-online.ml, 1 +moldovanka.tk, 1 +moldovawall.tk, 1 +molecularbiosystems.org, 1 +molekula.hr, 1 +molenaagtekerke.tk, 1 +molenaar-ricardo.tk, 1 +moleskinestudio.com, 1 +molidaytravel.com, 1 +molinero.xyz, 1 +molinillo.tk, 1 +moliporex.pt, 1 +mollaretsmeningitis.org, 1 +molleron.net, 1 +molletjesveer.tk, 1 +mollie.com, 1 +mollyringworm.tk, 1 +molodost.ga, 1 +molokai.org, 1 +molokov.tk, 1 +molot-tora.ml, 1 +molot-tora24.ga, 1 +molpek.com, 1 +moltapor.tk, 1 +molti.hu, 1 +molun.net, 0 +molunerfinn.com, 1 +molusk.ml, 1 +molwick.com, 1 +moment-terroir.ch, 1 +momentalno.tk, 1 +momentsofimpact.info, 1 +momentum.photos, 1 +momentumcoach.se, 1 +momentumdash.com, 1 +momentumdesign.website, 1 +momi-chura.com, 1 +momit.eu, 1 +momjoyas.com, 1 +mommydigest.ga, 1 +momo0v0.club, 1 +momobako.com, 1 +momochrome.online, 1 +momocogames.com, 1 +momocrats.com, 1 +momove.nl, 1 +moms.com, 1 +momsagainstcooties.com, 1 +momsays.co.za, 1 +momstableonline.com, 1 +momtazz.net, 1 +momut.org, 1 +momy-genealogie.info, 1 +mon-a-lisa.com, 1 +mon-agenda.org, 0 +mon-agora.com, 1 +mon-butin.fr, 1 +mon-dolibarr.fr, 1 +mon-lab-digital.com, 1 +mon-partage.fr, 1 +mon-trafic.com, 0 +mon22.ch, 0 +mona-dress.com, 1 +monachatdeco.com, 0 +monaco-automaten.de, 1 +monaco-info.tk, 1 +monacoexpress.tk, 1 +monad.io, 1 +monakasatmasr.com, 1 +monakinolandscape.com, 1 +monalisa.wtf, 1 +monalyse.com, 1 +monamurlite.ru, 1 +monarch.security, 1 +monarchelectric.com, 1 +monarchisc.com, 1 +monarchpartnersgroup.com, 1 +monarcjuexpo.ch, 1 +monays.ga, 1 +monbudget.org, 0 +moncarnetdesante.fr, 1 +moncoach.ch, 0 +monconcoursdgfip.fr, 1 +monctonhomeinspections.com, 1 +monde-oriental.tk, 1 +mondechenoafrance.tk, 1 +mondedie.fr, 1 +mondial-movers.nl, 1 +mondo-it.ch, 1 +mondocellulari.tk, 1 +mondonet.org, 0 +mondpo.pro, 1 +mondsee-psychotherapie.at, 1 +mondzorgaanzee.nl, 1 +monelephantapois.com, 1 +moneoci.com.br, 1 +monerogamez.com, 1 +monetki.net, 1 +monetus.com.br, 1 +money-book.jp, 1 +money-earning.tk, 1 +money-fast.ga, 1 +money-finder.ml, 1 +money-quick.cf, 1 +money-spell.com, 1 +money-transfers.tk, 1 +moneybill.us, 1 +moneybird.com, 1 +moneybird.de, 1 +moneybird.nl, 1 +moneybirdstorage.com, 1 +moneyblo.com, 1 +moneychill.biz, 1 +moneycredit.eu, 1 +moneyfactory.gov, 1 +moneyformybeer.com, 1 +moneyfortitude.com, 1 +moneygo.se, 1 +moneygrup.tk, 1 +moneymania.tk, 1 +moneypark.ch, 1 +moneyreal.tk, 1 +moneysavingpro.com, 1 +moneysmart.gov.au, 1 +moneytamer.com, 1 +moneytoday.se, 1 +monfilm.tk, 1 +monforte.tk, 1 +mongla168.net, 1 +mongla88.net, 1 +mongolbox.tk, 1 +mongolie.net, 1 +mongolito.tk, 1 +mongooselock.com.ua, 1 +mongrossisteauto.com, 1 +monicahq.com, 1 +monicajean.photography, 1 +monicanaranjo.tk, 1 +monicapotter.tk, 1 +monicz.pl, 1 +monidenum.fr, 1 +monika.tk, 1 +moninformaticien.ovh, 0 +moninformaticien.shop, 0 +monique.io, 1 +monirtalk.ml, 1 +monitman.com, 1 +monitman.solutions, 1 +monitorbandwidth.net, 1 +monitorbox.jp, 1 +monitord.at, 1 +monitori.ng, 1 +monitoring-servers.tk, 1 +monitoring.kalisz.pl, 1 +monitoringanetwork.com, 1 +monitoringd.de, 1 +monix.io, 1 +monjardin.tk, 1 +monjo.io, 1 +monjob.tk, 1 +monkeybusiness.agency, 1 +monkeyfaqs.com, 1 +monkeyhill.us, 1 +monkeymills.ga, 1 +monkeysorce.tk, 1 +monkeytek.ca, 1 +monlissagebresilien.com, 1 +monloyer.quebec, 1 +monnaiecourante.tk, 1 +monnyonle.hu, 1 +mono.cafe, 1 +mono0x.net, 1 +monoblu.com, 1 +monobunt.at, 1 +monochrometoys.com, 1 +monocl.com, 1 +monodejuegos.shop, 1 +monohost.ml, 1 +monokli.tk, 1 +monolithapps.com, 1 +monolithic.tk, 1 +monolithindustries.com, 1 +monopoly-one.com, 1 +monorail.ga, 1 +monorthopedagogue.ca, 1 +monospazzole.roma.it, 1 +monothesis.com, 1 +monoworks.co.jp, 1 +monpc-pro.fr, 0 +monpetitmobile.com, 1 +monplay.host, 1 +monroe27.com, 1 +monshoppingcestcalais.fr, 1 +monsieurbureau.com, 1 +monsieurdecapage.com, 1 +monsieursavon.ch, 0 +monsitemoncommerce.com, 1 +monsterandfox.co.uk, 1 +monstermashentertainments.co.uk, 1 +monsterminigames.de, 1 +monsterminus.tk, 1 +monstermoney.tk, 1 +mont-thabor.fr, 1 +montack.de, 1 +montanabiack.de, 1 +montanasky.tv, 1 +montanatrouthunters.com, 1 +montanteaesthetics.com, 1 +montanwerk.de, 1 +montarfotoaki.com, 1 +montarosa.tk, 1 +montas.io, 1 +montazer.net, 1 +montco.today, 1 +montehermoso.tk, 1 +montenativo.de, 1 +montenegro-yacht.com, 1 +montessori-oberhaching.de, 1 +montessori.edu.vn, 1 +monteurzimmerfrei.de, 1 +montgomerycountyia.gov, 1 +montgomeryfirm.com, 1 +montgomerysoccer.net, 1 +monticelloky.gov, 1 +montillafarm.com, 1 +montoan.com, 1 +montoneros.tk, 1 +montpreveyres.ch, 0 +montrain.com, 1 +montrain.fr, 1 +montrealcatadoptions.com, 1 +montredeal.fr, 1 +montsaintaignan.fr, 1 +montserrat.ind.br, 1 +montserratoptics.com, 1 +montychristie.com, 1 +monveilleuretmoi.com, 1 +monweb.tk, 1 +monzaradio.tk, 1 +monzo.com, 1 +monzo.me, 1 +monzo.tk, 1 +moo.la, 1 +moobl.io, 1 +moodfoods.com, 1 +moodforsex.com, 1 +moodytattoo.com, 1 +moofin.ml, 1 +mooglms.com, 1 +moojp.co.jp, 1 +moolah.rocks, 1 +moom20101234567890.tk, 1 +moon.fish, 1 +moon.lc, 0 +moonagic.com, 1 +moonagic.io, 1 +moonbench.xyz, 1 +moonbooth.com, 1 +moonbot.io, 1 +moonboys.de, 1 +moonbyte.at, 1 +mooncharmshop.com, 1 +moonchart.co.uk, 1 +moondrop.org, 1 +moonfist.eu, 1 +moonkin.eu, 1 +moonlabs.nl, 1 +moonlightcapital.ml, 1 +moonlightdesign.org, 1 +moonlightpicnic.tk, 1 +moonlights.tk, 1 +moonlighttheatre.tk, 1 +moonlit.cloud, 1 +moonmelo.com, 1 +moonpay.com, 1 +moonpay.io, 1 +moonracer.ga, 1 +moonraptor.co.uk, 0 +moonraptor.com, 0 +moonrhythm.info, 0 +moonrhythm.io, 0 +moonsault.de, 1 +moonshyne.org, 1 +moontaj.com, 0 +moonvpn.org, 1 +moonwolfwiccanschool.tk, 1 +moonzerotwo.tk, 1 +mooregreen.nl, 1 +moorelawfirmaz.com, 1 +mooremoney.co, 1 +mooretownrancheria-nsn.gov, 1 +moorewelliver.com, 1 +moorfunevents.co.uk, 1 +moormiles.com, 1 +moorparkelectrical.com, 1 +moorparkelectrician.com, 1 +moorparkexteriorlighting.com, 1 +moorparklandscapelighting.com, 1 +moorparklighting.com, 1 +moorparkoutdoorlighting.com, 1 +moort.be, 1 +moosikapp.ml, 1 +moosikapp.tk, 1 +moosmann-moehrle.de, 1 +moot-info.co.za, 0 +moovablestorage.com, 1 +moove-it.com, 1 +mooveo.co, 1 +moovhl.com, 1 +moparcraft.com, 1 +moparcraft.net, 1 +moparcraft.org, 1 +moparinsiders.com, 1 +moparisthe.best, 1 +moparisthebest.com, 1 +moparisthebest.net, 1 +moparisthebest.org, 1 +moparscape.net, 1 +mopedpress.com, 1 +mopedreifen.de, 0 +mopie.de, 1 +mople71.cz, 1 +mopliangxing.com, 1 +moppeleinhorn.de, 1 +moppenfactory.tk, 1 +moppy.org, 1 +mopxing.com, 1 +moqo.de, 1 +moqtmatrak.com, 1 +mora.pl, 1 +moraffpritchard.com, 1 +moralcenter.cf, 1 +moralcompass.ga, 1 +moraldehornuez.tk, 1 +moranyachts.com, 1 +moratilla.ml, 1 +morbatex.com, 1 +morbiceramicindustry.com, 1 +morbitiles.org, 1 +morbitzer.de, 1 +morbius.cz, 1 +morbotron.com, 1 +morc.me, 1 +morchino.ch, 0 +morchstore.com, 1 +mord-ost.de, 1 +mordamla.com, 1 +mordovia.cf, 1 +mordovia.ga, 1 +mordovia.gq, 1 +mordovia.tk, 1 +mordoviya.tk, 1 +more-hikkoshi.com, 1 +more-terrain.de, 1 +moreal.co, 1 +moreapp.co.uk, 1 +morecreativelife.com, 1 +morediets.net, 1 +moreeducation.tk, 1 +moremindsbetter.com, 1 +morenadacentral.tk, 1 +morenci.ch, 1 +moreniche.com, 1 +moreno820.com, 1 +morepablo.com, 1 +morepay.cn, 1 +moreserviceleads.com, 0 +moreshop.pl, 1 +moresw.com, 1 +moretesting.tk, 1 +morethanautodealers.com, 1 +morethancode.be, 1 +morethandigital.info, 1 +moretti.camp, 1 +morevesi.cf, 1 +morgan-insurance.com, 1 +morgan.solutions, 1 +morgancounty-al.gov, 1 +morgancountysheriffal.gov, 1 +morgandesort.com, 1 +morganhome.co.id, 1 +morgansleisure.co.uk, 1 +morganwilder.com, 1 +morgen.news, 1 +morgner.com, 1 +morhys.com, 1 +mori-cdc.com, 1 +morifuji.me, 1 +morikami.org, 1 +morisakimikiya.com, 1 +moritoworks.com, 1 +moritz-baestlein.de, 1 +moritz-poldrack.de, 1 +moritz.sh, 1 +moritzkornher.de, 1 +moritztremmel.de, 1 +moriz.de, 1 +moriz.net, 1 +mormon-colleges.com, 1 +mormonleaks.io, 1 +morningbhai.com, 1 +morningbird.eu, 1 +morningchew.com, 1 +morningcurve.com, 0 +morningtime.cloud, 1 +moroccanews.tk, 1 +moroccomiami.com, 1 +moroccotodaynews.ga, 1 +moromsmile.com, 1 +morooi.cn, 1 +morox.top, 1 +morozko.gq, 1 +morozyaka.tk, 1 +morrellllc.com, 0 +morris.computer, 1 +morritosfelices.com, 1 +morrowind-finland.tk, 1 +morsang.net, 1 +morse-ti.net, 1 +mortengamstpedersen.tk, 1 +mortgagecalculator.biz, 1 +mortgagetranslations.gov, 1 +mortgagewebinars.com, 1 +mortis.eu, 1 +morus.tk, 1 +morvo.mx, 1 +morwynna.com, 1 +morz.org, 1 +mos-camin.ru, 1 +mosaic-design.ru, 1 +mosaicmarble.com, 1 +mosaicot.com, 1 +mosaique-lachenaie.fr, 1 +mosboutique.it, 1 +moscow-moscow.tk, 1 +moscow-new.cf, 1 +moscow-xiaomi.ru, 1 +moscow.dating, 1 +moscow.tk, 1 +moscowartdesign.com, 1 +moscowlombard.ru, 1 +moscowlove.tk, 1 +moscownews.ml, 1 +moscownights.org, 1 +moscowsex.tk, 1 +moscowtimes.tk, 1 +mosdosug.ml, 1 +moseleyelectronics.com, 1 +moseracctg.com, 1 +mosfet.cz, 1 +mosfetkiller.de, 1 +moshiach.ru, 1 +moshiachtime.com, 1 +moshop.com.vn, 1 +moshwire.com, 1 +mosin.org, 1 +moskas.tk, 1 +moskeedieren.nl, 1 +moskva-city.cf, 1 +moskvagruz.tk, 1 +mosnews.tk, 1 +moso.io, 1 +mosobl.tk, 1 +mosquitojoe.com, 1 +mosquitoshop.co.za, 1 +mossan.net, 1 +mosscade.com, 1 +mosshi.be, 1 +mossipanama.com, 1 +most.tk, 1 +mostafabanaei.cf, 1 +mostazaketchup.com, 1 +mosternaut.com, 1 +mostertadmin.nl, 1 +mostfamousbirthdays.com, 1 +mostlyharmless.at, 1 +mostlyoverhead.com, 1 +mostmost.tk, 1 +mostqbalwatanalqahirah.com, 1 +mosttaza.com, 1 +mosurist.tk, 1 +motastore.com.br, 1 +motchirotchi.com, 1 +motd.ch, 0 +motekforce.link, 1 +motekforcelink.com, 1 +motekforcelink.eu, 1 +motekforcelink.net, 1 +motekforcelink.nl, 1 +motekmedical.com, 1 +motekmedical.eu, 1 +motekmedical.nl, 1 +motekrysen.com, 0 +moteksystems.com, 1 +moteksystems.net, 1 +motezazer.fr, 1 +motherboard.services, 1 +motherbrain.tk, 1 +motherearth.cf, 1 +mothereff.in, 0 +motherguru.ca, 1 +motherhoodinblack.com, 1 +motherofsorrows.net, 1 +mothership.de, 1 +motichi.cf, 1 +motifstudio.com.ua, 1 +motionless.nl, 1 +motiv-rechts.tk, 1 +motivational-babes.com, 1 +motivationshastra.com, 1 +motivness.com, 1 +motiweb.fr, 1 +motlife.net, 0 +motmplus.com, 1 +moto-station.com, 1 +moto-texnika.tk, 1 +motoactionimola.it, 1 +motoblogism.com, 1 +motoclubentresemana.tk, 1 +motoclubrker.tk, 1 +motodb.co.uk, 1 +motodb.net, 1 +motodb.uk, 1 +motoforce.lt, 1 +motofoto.tk, 1 +motogb.net, 1 +motogeelshop.be, 1 +motohell.com, 1 +motojato.com.br, 1 +motokados.tk, 1 +motoland.ml, 1 +motolife.tk, 1 +motolinesupply.com, 1 +motomorgen.com, 1 +motopoland.com.ua, 1 +motor-agro.com, 1 +motor-agro.com.ua, 1 +motor-agro.kz, 1 +motor-agro.ru, 1 +motor-cycles.tk, 1 +motor-forum.nl, 0 +motor1.com, 1 +motorbiketourhanoi.com, 1 +motorcyclesafer.com, 1 +motorialab.com, 0 +motoridiricerca.tk, 1 +motornaolja.com, 1 +motorpointarenacardiff.co.uk, 1 +motorrijschoolgul.nl, 1 +motorring.ru, 1 +motorsplus.com, 0 +motortecbrasil.com.br, 1 +motortrend.com, 1 +motoryachtclub-radolfzell.de, 1 +motorzone.od.ua, 1 +motoscascos.com, 1 +motospaya.com, 1 +motostorie.blog, 1 +mototax.ch, 1 +mototeam.com.ua, 1 +motovated.co.nz, 0 +motovio.de, 1 +motowilliams.com, 1 +motoworld.biz, 1 +motransportinfo.com, 1 +motringeneric.tk, 1 +motshop.tk, 1 +motstats.co.uk, 1 +mott.pe, 1 +motto-iikoto.com, 1 +motun.ga, 1 +mou-pmr.tk, 1 +moube.fr, 1 +mouche.fr, 1 +moucloud.cn, 1 +moumaobuchiyu.com, 1 +mound.ga, 1 +mouniresidences.com, 1 +mountain-retreat-center.com, 1 +mountain-rock.ru, 1 +mountainactivitysection.org.uk, 1 +mountainairandheating.com, 1 +mountainbatchers.de, 1 +mountainbell.net, 1 +mountaincastle.store, 1 +mountainchalet.blue, 1 +mountainspringsrentals.ca, 1 +mountaintree.eu, 1 +mountainutilities.eu, 1 +mountairymd.gov, 1 +mountbatten.cz, 1 +mountbrowneguestcottage.ga, 1 +mountknowledge.nl, 1 +mountpost.tk, 1 +mourabaha-dz.com, 1 +mouracloset.com.br, 1 +mousepotato.uk, 1 +mousetravelmatters.com, 1 +moushed.tk, 1 +moustream.com.br, 1 +moutiezhaller.com, 1 +mova.club, 1 +movacare.de, 1 +movaci.com, 1 +movahoteis.com.br, 1 +move-out-cleaning.co.uk, 1 +move.mil, 1 +movedigital.com.au, 1 +moveltix.net, 1 +movember.com, 0 +movementdanceacademy.it, 1 +movepin.com, 1 +movestorm.com, 1 +movewellnesslab.com, 1 +movewithfiness.com, 1 +movfun.ga, 1 +movie-forum.co, 1 +movie-infos.net, 1 +movie-sounds.org, 1 +movie1000.com, 1 +movieboost.nl, 1 +moviefreeze.com, 1 +movieguys.org, 1 +moviejack.org, 0 +movieking.bz, 1 +movies-fan.tk, 1 +moviesetc.net, 1 +movietradition.tk, 1 +moviewatchin.tk, 1 +movihut.com, 1 +moviko.nz, 1 +movil.uno, 1 +movilcelular.es, 1 +moviles.com, 1 +moviltronix.com, 1 +movimento-terra.it, 1 +moving-pixtures.de, 1 +moving-target.info, 1 +movinglogistics.nl, 0 +movingoklahoma.org, 1 +movingtohttps.com, 1 +movio.ga, 1 +moviro.net, 1 +movlib.org, 1 +mow.pw, 1 +mowalls.net, 1 +mowing-the-lawn.com, 1 +mox.link, 1 +moxiegirlz.id, 1 +moy-biznes.tk, 1 +moy-gorod.od.ua, 0 +moy.cat, 1 +moybiznes.tk, 1 +moyideal.tk, 1 +moylen.eu, 1 +moyminsk.tk, 1 +moyoo.net, 1 +moyufangge.com, 1 +mozartgroup.hu, 1 +mozektevidi.net, 1 +mozgb.ru, 1 +mozgovoy.tk, 1 +mozilla-hispano.org, 1 +mozilla.cz, 1 +mozzak.tk, 1 +mozzez.de, 1 +mozzi.online, 1 +mozzilla.cz, 1 +mp3gratuiti.com, 1 +mp3noi.com, 1 +mp3skull.cf, 1 +mpa-pro.fr, 1 +mpath.health, 1 +mpc-hc.org, 1 +mpcdn.ch, 1 +mpdu.tk, 1 +mpebrasil.tk, 1 +mpetroff.net, 1 +mpg.ovh, 1 +mpgaming.pro, 1 +mpgu.tk, 1 +mphold.ru, 1 +mphwinkel.nl, 1 +mpintaamalabanna.it, 1 +mpk-chayka.org.ua, 1 +mpkrachtig.nl, 1 +mplanetphl.fr, 0 +mplant.io, 1 +mpms.nl, 1 +mpodraza.eu, 1 +mpodraza.pl, 1 +mpoonamchandpearls.com, 1 +mpornoindir.tk, 1 +mpowr.com, 1 +mprsco.eu, 1 +mpserver12.org, 1 +mpsoundcraft.com, 1 +mpu-beratungsstellen.com, 1 +mpu-giessen.com, 1 +mpu-ibbi.de, 1 +mpu-vorbereitung.com.de, 1 +mpublicidad.com, 1 +mpy.ovh, 1 +mqacg.com, 1 +mqas.net, 1 +mqbeauty.com.tw, 1 +mqbx.nl, 1 +mr-a.de, 1 +mr-anderson.org, 1 +mr-bills.com, 1 +mr-coffee.net, 1 +mr-labo.jp, 1 +mr-nachhilfe.de, 1 +mr-wolf.nl, 0 +mr3.io, 1 +mraag.xyz, 1 +mrafrohead.com, 1 +mrak.blog, 1 +mralonas.cf, 1 +mrandmrsparrot.gr, 1 +mrandyyp.com, 1 +mranimal.tk, 1 +mrautomazioni.it, 1 +mrazek.biz, 1 +mrbounce.com, 1 +mrbouncescrazycastles.co.uk, 1 +mrbouncycastle.com, 1 +mrc-productivity.com, 1 +mrca-sharp.com, 0 +mrcelulares.co, 1 +mrcog.tk, 1 +mrcomer.tk, 1 +mrcool.store, 1 +mrcoolevents.com, 1 +mrcyberpixel.tk, 1 +mrd-rc.com, 1 +mrd.ninja, 1 +mrdatenschutz.de, 1 +mrdayman.com, 1 +mrevolution.eu, 1 +mrfd.nl, 1 +mrfinka.ml, 1 +mrfreshtruck.com, 1 +mrguider.org, 1 +mrhc.ru, 1 +mrhookupsd.com, 1 +mrichard333.com, 1 +mricspatial.com, 1 +mrinalpurohit.in, 1 +mrizzio.com, 1 +mrjbanksy.com, 1 +mrjhnsn.com, 1 +mrjo.sh, 1 +mrjooz.com, 0 +mrjunior.ga, 1 +mrkapowski.com, 0 +mrknee.gr, 1 +mrkrabat.de, 1 +mrliu.me, 1 +mrlove.tk, 1 +mrmad.com.tw, 1 +mrmanson.tk, 1 +mrmemory.co.uk, 1 +mrmn.nl, 1 +mrmoregame.de, 1 +mrmosier.tk, 1 +mrmostafaacademy.tk, 1 +mrnathanpowell.com, 1 +mrnh.de, 1 +mrnh.tk, 1 +mrnice.ml, 1 +mrning.com, 1 +mrnonz.com, 1 +mrpanipiales.com, 1 +mrprintables.com, 1 +mrprintglobal.com, 1 +mrs-labo.jp, 1 +mrs-shop.com, 1 +mrsbairds.com, 0 +mrschristine.com, 1 +mrshahin.cf, 1 +mrsheep.win, 1 +mrsiding.net, 1 +mrsjinthelibrary.com, 1 +mrsk.me, 1 +mrsourabh.me, 1 +mrssclaus.ca, 1 +mrstat.co.uk, 1 +mrston.ml, 1 +mrstuudio.ee, 1 +mrtg.com, 1 +mrtprioritet.ru, 1 +mrtskidkispb.ru, 1 +mrtunnel.club, 1 +mruczek.ga, 1 +mruganiepodspacja.pl, 1 +mrupert.com, 1 +mrupp.eu, 1 +mrv.li, 1 +mrvl.net, 1 +mrvnt.co, 1 +mrwacky.com, 1 +mrx.one, 0 +mrxn.net, 1 +mrzauto.com, 1 +ms-australia.de, 1 +ms-ch.ch, 1 +ms0s.com, 1 +ms295.com, 1 +msa-aesch.ch, 1 +msa.bank, 1 +msafiri.co, 1 +msahebhonar.com, 1 +msaludasuhogar.com, 1 +msar.eu, 1 +msc-corps.de, 1 +mscc.mu, 1 +mscc.org, 1 +mscenter.cf, 1 +msch.pw, 1 +msdprojectclearmo.gov, 1 +msebera.cz, 1 +mselectronique.tk, 1 +mserve.ddns.net, 1 +mservers.cz, 1 +msfishingcharter.com, 1 +msgallery.tk, 1 +msgmon.com, 1 +msgspoof.com, 1 +msh100.uk, 1 +msha.gov, 1 +mshemailmarketer.com.au, 1 +mshgame.ga, 1 +msi-zlin.cz, 1 +msiegmund.com, 1 +msieursvp.fr, 1 +msize48.ch, 1 +msl.org, 1 +mslivros.com.br, 1 +msm-data.com, 1 +msmails.de, 1 +msnarzedzia.pl, 1 +msngr.com, 1 +msnhdd.info, 1 +msnr.net, 1 +msoffice-inc.net, 1 +msoida.me, 1 +msoll.de, 1 +msoll.eu, 1 +msp66.de, 0 +mspatexas.com, 1 +msphotographics.de, 1 +mspnocsupport.com, 1 +mspsocial.net, 1 +msquadrat.de, 1 +msrohkwrstock.com, 1 +msroot.de, 1 +mssa.jp, 1 +mssm-portal.com, 1 +mssora.com, 1 +mstazakka.com, 1 +mstdn.blue, 1 +mstdn.fm, 1 +mstdn.fr, 0 +mstdn.io, 1 +mstdn.onl, 0 +mstr-f-dstrctn.de, 1 +mstudio.tk, 1 +msuess.me, 1 +msuna.net, 1 +msv-limpezas.pt, 1 +mswdtemplate.com, 1 +msx.org, 1 +msz-fotografie.de, 1 +mszavodumiru.cz, 1 +mt-bank.jp, 1 +mt-caza.com, 1 +mt-tech.fi, 1 +mt-west.org, 1 +mt.run, 0 +mt.search.yahoo.com, 0 +mt1016.com, 1 +mt2414.com, 1 +mt4professional.com, 1 +mta-sts.email, 1 +mta-sts.eu, 1 +mta-sts.nl, 1 +mta.fail, 1 +mta.org.ua, 1 +mtabriz.de, 1 +mtaman.com, 1 +mtane0412.com, 0 +mtasa.com, 1 +mtasa.hu, 1 +mtasts.xyz, 1 +mtauburnassociates.com, 1 +mtb.wtf, 1 +mtcq.jp, 1 +mtd.org, 1 +mtd.ovh, 1 +mte.sk, 1 +mtechprecisioninc.com, 1 +mteleport.net, 1 +mtfgnettoyage.fr, 1 +mtgeni.us, 1 +mtgenius.com, 1 +mtgsuomi.fi, 1 +mthode.org, 1 +mthrbrd.com, 1 +mthrbrd.net, 1 +mths.be, 0 +mticareportal.com, 1 +mtinz.com, 1 +mtirc.co, 1 +mtiryaki.com, 1 +mtjholding.ee, 1 +mtlconcerts.com, 1 +mtltransport.com, 1 +mtludlow.co.uk, 1 +mtmedia.org, 1 +mtouch.facebook.com, 0 +mtp-services.fr, 1 +mtpleasant-tn.gov, 1 +mtr-croatia.tk, 1 +mtr.md, 1 +mtr123.cn, 0 +mtran.co, 1 +mtravelers.net, 1 +mtrock.ru, 1 +mtrx.tech, 1 +mts-energia.eu, 1 +mtservicescorp.com, 1 +mtsn3padang.sch.id, 1 +mtsoftware.com.au, 1 +mtsolar.es, 1 +mtthwbrd.com, 1 +mtv.re, 1 +mtvroadies.tk, 1 +mu-thunder.online, 1 +mu.search.yahoo.com, 0 +mu105.cc, 1 +mu3on.com, 1 +muabannhanh.com, 0 +muafakatmalaysia.ga, 1 +muarstabyggmarknad.tk, 1 +mub-tomsk.ru, 1 +mubase.dk, 1 +mubiflex.nl, 1 +mubo.com.mx, 1 +muceniece.tk, 1 +muchbetterthancash.com, 1 +muchohentai.com, 1 +muchotrolley.tk, 1 +muckingabout.eu, 1 +muckrack.com, 1 +mucmail.de, 1 +mudanzasacuna.com.co, 1 +mudanzasjuniorh.com, 1 +mudanzasuiza.com.ec, 1 +mudanzasytransportesbh.com, 1 +mudaomundo.org, 1 +mudareganhar.pt, 0 +mudasobwa.tk, 1 +mudbenesov.cz, 1 +mudcomplex.ga, 1 +mudcrab.us, 0 +mudgezero.one, 1 +mudit.xyz, 0 +mudramagik.com, 1 +mudrc.net, 1 +mueblescuerolorca.cl, 1 +muel.io, 1 +muelhau.pt, 1 +muell-weg.de, 1 +muellapp.com, 0 +muellerurology.com, 1 +muenchberger.com, 0 +muennich-coll.de, 1 +muffs.ru, 1 +mufibot.net, 1 +mufid.tk, 1 +muflon-linux.org, 1 +muga.space, 1 +muganworld.com, 1 +mugawe.com, 1 +mugen.technology, 1 +mugrabyhostel.tk, 1 +muguayuan.com, 1 +muh.io, 1 +muhabarishaji.com, 0 +muhafazakarkiralikvilla.com, 1 +muhcow.dk, 1 +muhelheim.com, 1 +muhibbulislam.tk, 1 +muhlenbergtwppa.gov, 1 +muhrielle.org, 1 +mui.fitness, 1 +mui.kitchen, 1 +mui.pet, 1 +mui.today, 1 +muii.com.br, 1 +muii.in, 1 +muilties.com, 1 +muir.eu.org, 1 +muir.fun, 1 +muir.pp.ua, 1 +muisoft.fi, 1 +mujeresfemeninas.com, 1 +mujlinux.cz, 1 +muk-kobetsu.com, 1 +mukilteodentalarts.com, 1 +mukilteoeuropeanautorepair.com, 1 +muku-flooring.com, 1 +mulaccosmetics.com, 1 +mulail.com, 1 +mulaisehat.com, 1 +mulej.net, 1 +mulheres18.com, 1 +muling.lu, 1 +mulk.hopto.org, 1 +mullen.net.au, 1 +mullens-usedcars.be, 0 +mullerkappers.nl, 1 +mullinsfarms.com, 1 +muloft.com, 1 +multi-fruit.tk, 1 +multi-soudures.fr, 1 +multi-tool.ml, 1 +multibomasm.com.br, 1 +multichange.net, 1 +multiclinicacardio.com.br, 1 +multicomhost.com, 1 +multicore.cl, 1 +multicorpbra.com, 1 +multievidence.es, 1 +multifruttisystems.gr, 1 +multigamecard.com, 1 +multigamers-net.tk, 1 +multigeist.de, 1 +multikalender.de, 0 +multilevelmarketing.cf, 1 +multilogik.com, 1 +multimatte.com, 1 +multimed-solutions.com, 1 +multimedia-pool.com, 1 +multimediapc.de, 1 +multimediaworld.tk, 1 +multimediosmonti.com, 1 +multinationalforce.com, 1 +multipassword.com, 1 +multipleservers.com, 1 +multiplex.tk, 1 +multiplexcy.com, 1 +multiplexenterprises.com, 1 +multiplies.tk, 1 +multipuntos.ml, 1 +multirep.ch, 0 +multiroom-streaming.de, 1 +multischool.tk, 1 +multisite.ovh, 1 +multistas.tk, 1 +multitec.nl, 1 +multitek.no, 1 +multitenantlaravel.com, 1 +multiterm.org, 1 +multitheftauto.com, 1 +multitool.cf, 1 +multitraf.ga, 1 +multivideo.tk, 1 +multivpn.cn.com, 1 +multivpn.com.de, 1 +multivpn.com.ua, 1 +multivpn.fr, 1 +multizone.games, 1 +mum.ceo, 1 +muma.gq, 1 +muma.ml, 1 +mumablue.com, 1 +mumakil.fi, 0 +mumbaionlinegifts.com, 1 +mumbairoleplay.tk, 1 +muminkoykiran.com, 1 +mummyandmephotography.com, 1 +mumolabs.com, 1 +mums.cz, 1 +mumusofa.com.tw, 1 +muna.de, 1 +munakata-cl.jp, 1 +munch.me, 1 +munchcorp.com, 1 +mundismart.com, 1 +mundo-otaku.tk, 1 +mundoamatista.online, 1 +mundoarabe.com.br, 1 +mundoconejos.com, 1 +mundodapoesia.com, 1 +mundodasfechaduras.com.br, 1 +mundodasmensagens.com, 1 +mundodosagapornis.tk, 1 +mundofoto.tk, 1 +mundogamers.top, 1 +mundokinderland.com.br, 1 +mundolarraz.es, 1 +mundolettering.com, 1 +mundomagicotv.com, 1 +mundopatchwork.online, 1 +mundoperfecto.net, 1 +mundoperros.es, 1 +mundosai.online, 1 +mundoscrapbooking.online, 1 +mundosteampunk.club, 1 +mundosuiri.ml, 1 +mundotortugas.com, 1 +mundschenk.at, 1 +mundtec.com.br, 1 +munduch.cz, 1 +munduch.eu, 1 +muneni.co.za, 1 +munera.ca, 1 +munfordtn.gov, 1 +munich-eventlocations.de, 1 +municipaldroguerias.com, 1 +munirajiwa.com, 1 +munki.org, 1 +munkibuilds.org, 1 +munndialarts.com, 1 +muntajati-om.com, 0 +muntproever.nl, 1 +muntuit.be, 1 +munwr.com, 1 +munzlocal10.org.nz, 1 +muoivancauhoivisao.com, 1 +muon.marketing, 1 +mup-republicanos.tk, 1 +muqu.co, 1 +mur-vegetal-interieur.fr, 1 +murakami-sah.com, 1 +mural.co, 1 +mural.com, 1 +muralart.ga, 1 +muralswallpaper.co.uk, 1 +muralswallpaper.com, 1 +muraltown.com, 1 +murashun.jp, 1 +muratatifsayar.com.tr, 1 +muratcileli.tk, 1 +muratore-roma.it, 1 +murciaprocuradores.tk, 1 +murdercube.com, 1 +murfy.kiwi, 1 +murfy.nz, 1 +murgi.de, 1 +murksbreider.tk, 1 +murmansk.cf, 1 +murmanskforum24x7.tk, 1 +murmashi.ru, 1 +murof.com.br, 1 +murphy-law.net.ru, 1 +murray.xyz, 1 +murraya.cn, 1 +murraycoin.org, 1 +mursa.tk, 1 +mursatov.tk, 1 +murster.tw, 1 +mursu.directory, 1 +murtazamustafahirani.tk, 1 +murz.tv, 1 +murzik.space, 1 +musa.gallery, 1 +musaccostore.com, 1 +musamwaky.com, 0 +musaslush.com, 1 +muscatinecountyiowa.gov, 1 +muscle-tg.com, 1 +musclecarresearch.com, 1 +musclecarsillustrated.com, 1 +muscolinomusic.com, 1 +muscularbabes.net, 1 +muscuolisq.cf, 1 +musearchengine.com, 1 +museclef.com, 1 +musecomunicazione.it, 1 +musedash.moe, 1 +musehelix.com, 1 +museloveurania.com, 1 +museodefutbol.online, 1 +museodelistmo.tk, 1 +muserver.io, 1 +muses-success.info, 1 +musettishop.com, 1 +museumnachtgent.be, 1 +museumofautism.net, 1 +museumwaalsdorp.nl, 1 +mush-room.co.jp, 1 +mushel.ddns.net, 1 +mushikabu.net, 1 +mushino.com, 1 +mushka.ga, 1 +mushman.tk, 1 +music-is-my-life.de, 1 +music-privilege.fr, 1 +music-project.eu, 1 +music-store-download.com, 1 +music.amazon.com, 1 +musica.com, 1 +musicalive.nl, 1 +musicall.com, 1 +musicalschwarzenburg.ch, 1 +musicapara.net, 1 +musicaporbolivia.tk, 1 +musicasbr.com.br, 1 +musicbow.com, 1 +musicbox.party, 1 +musicchris.de, 1 +musiccitycats.com, 1 +musicfactory.ml, 1 +musicfor.us, 1 +musicfromgod.com, 1 +musicgamegalaxy.de, 1 +musicgeek.ga, 1 +musicgivesmelife.com, 1 +musichiphop.ga, 1 +musician.dating, 1 +musicindustrydb.org, 1 +musicinsiderdigest.com, 1 +musickhouseleveling.com, 1 +musiclenta.tk, 1 +musicnotesroom.com, 1 +musicompare.com, 1 +musicradar.co.il, 1 +musicradio.ga, 1 +musicrainbow.tk, 1 +musicschoolonline.com, 1 +musicsense.cf, 1 +musicstudio.pro, 1 +musicupdate.de, 1 +musicvideo.club, 1 +musicvietnam.tk, 1 +musicwear.cz, 1 +musicworkout.de, 1 +musigama.tk, 1 +musik-mentaltraining.ch, 1 +musiker.tk, 1 +musikerkontakt.dk, 1 +musikhaus-korn.de, 1 +musikidersi.tk, 1 +musiktag2020.ch, 1 +musikverein-elten.de, 1 +musikzentrale.net, 0 +musings.tech, 1 +musingsatmidnight.com, 1 +musique2nuit.com, 1 +musiques-traditionnelles.ga, 1 +musketfire.com, 1 +musketiers.tk, 1 +musketonhaken.nl, 0 +muskokadanceconnection.com, 1 +muskokavoltz.ca, 1 +muskuratimorning.tk, 1 +muslim.singles, 1 +muslimah.boutique, 1 +muslimbanter.co.za, 1 +muslimmarriage.cf, 1 +muslimsoul.cf, 1 +musmann.io, 1 +muspla.com.br, 1 +mussalains.com, 1 +musselsblog.com, 1 +musta.ch, 1 +mustard.co.uk, 1 +mustardwallet.com, 1 +mustasj.no, 1 +mustat.com, 1 +muster-folien.de, 1 +muster-schablonen.de, 1 +mustertexte-musterbewerbung.de, 1 +mustexist.tk, 1 +musthavesforreal.com, 1 +musthinsider.com, 1 +mustika.cf, 1 +mustketing.com, 1 +musttest.com, 1 +musttest.email, 1 +musttest.eu, 1 +musttest.net, 1 +musttest.org, 1 +mutahar.me, 1 +mutantletterpress.com, 1 +mutantmonkey.in, 1 +mutantmonkey.info, 1 +mutantmonkey.sexy, 1 +mutek.com, 1 +mutex.tech, 1 +mutext.com, 1 +mutfakyolu.com, 1 +muthai.in.th, 1 +mutual.ga, 1 +mutualmoney.ml, 1 +mutuals.cool, 1 +mutuelle.fr, 1 +mutuocasafacile.it, 1 +muuglu.es, 1 +muunnin.net, 1 +muusika.fun, 1 +muwa-consulting.com, 1 +muwatenraqamy.org, 1 +muy.ooo, 1 +muydelgada.com, 1 +muz2u.ru, 1 +muzeumkomiksu.eu, 1 +muzi-tips.tk, 1 +muzi.cz, 1 +muzicamp3.org, 1 +muzicari.tk, 1 +muziekcentrumdebijloke.gent, 1 +muziektermen.tk, 1 +muzikanews.tk, 1 +muzikantine.nl, 1 +muzike.tk, 1 +muzprosvet.tk, 1 +muzykanawesele.info, 1 +muzzmusic.com, 1 +mv-schnuppertage.de, 1 +mv-wohnen.de, 1 +mvandek.nl, 1 +mvarsamis.com, 1 +mvbits.com, 1 +mvbug.com, 1 +mvccp.co.za, 1 +mvisioncorp.com, 1 +mvistatic.com, 1 +mvmm.fr, 1 +mvno.io, 1 +mvorisek.com, 1 +mvorisek.cz, 1 +mvpinfo.ga, 1 +mvpower.pt, 1 +mvwoensei.com, 1 +mvwoensei.xyz, 1 +mvwoensel.com, 1 +mvwr.co.uk, 1 +mvzstartpagina.tk, 1 +mw.search.yahoo.com, 0 +mwainc.org, 1 +mwalz.com, 1 +mwamitours.com, 1 +mware-staging.azurewebsites.net, 1 +mwavuli.co.ke, 1 +mwba.org, 1 +mwcwallet.com, 1 +mwd.world, 1 +mwe.st, 1 +mwinds.tk, 1 +mwine.sk, 1 +mwlcouriers.com, 1 +mwms.nl, 1 +mwnonline.net, 1 +mwork.tech, 1 +mwr.team, 1 +mwstrategicservices.com, 1 +mwtdev.se, 1 +mwteh.ru, 1 +mwtj.com, 1 +mww.moe, 1 +mx-quad.fr, 1 +mx.org.ua, 1 +mx.search.yahoo.com, 0 +mx5international.com, 1 +mxawei.cn, 1 +mxbids.com, 1 +mxdanggui.org, 1 +mxdvl.com, 1 +mxes.net, 1 +mxihan.xyz, 1 +mxii.eu.org, 1 +mxin.ltd, 1 +mxn8.com, 1 +my-aftershave-store.co.uk, 1 +my-best-wishes.com, 1 +my-bratsk.tk, 1 +my-calend.ru, 0 +my-cars.tk, 1 +my-contract.ch, 0 +my-contract.info, 0 +my-contract.net, 0 +my-demo.co, 1 +my-dns.co.il, 1 +my-ebook.es, 1 +my-education.tk, 1 +my-finance.tk, 1 +my-floor.com, 1 +my-gode.fr, 1 +my-goldfinger.com, 1 +my-health-homes.com, 1 +my-host.ovh, 1 +my-hps.de, 1 +my-ifms.com, 1 +my-ip.work, 1 +my-mobile-apps.com, 1 +my-montenegro.tk, 1 +my-new-bikini.de, 1 +my-nextcloud.at, 1 +my-pawnshop.com.ua, 0 +my-photo.me, 1 +my-profile.org, 1 +my-sex-cam.com, 1 +my-static-demo-808795.c.cdn77.org, 1 +my-static-live-808795.c.cdn77.org, 1 +my-story.ml, 1 +my-stuff-online.com, 1 +my-town.tk, 1 +my-tunisia.tk, 1 +my-web.xyz, 1 +my-webcloud.at, 1 +my.onlime.ch, 0 +my.urown.cloud, 1 +my.usa.gov, 1 +my4g.net, 1 +my4thtelco.com.sg, 1 +my4thtelco.sg, 1 +myabcm.com, 1 +myaccount.google.com, 1 +myactivity.google.com, 1 +myadpost.com, 1 +myaggic.com, 1 +myalliancechurch.com, 1 +myamend.com, 1 +myamihealth.com, 1 +myamity.info, 1 +myammo.com, 1 +myammo.ru, 1 +myandroidfriend.ml, 1 +myanimelist.net, 1 +myapexcard.com, 1 +myartsjournal.com, 1 +myathena.ai, 1 +myauto.ml, 1 +mybakkupakku.com, 1 +mybarcelona.tk, 1 +mybasementdoctor.com, 1 +mybathroom.tk, 1 +mybauingenieur24.de, 1 +mybb.com, 1 +mybb.de, 1 +mybbcode.tk, 1 +mybeancloud.co.za, 1 +mybeautyjobs.de, 1 +mybestbook.tk, 1 +mybestbooks.gq, 1 +mybestmattress.com, 1 +mybestwebsitebuilder.com, 1 +mybetternormal.org, 1 +mybicc.org, 1 +mybillie.com, 1 +mybirds.tk, 1 +mybisnis.tk, 1 +mybizzmail.com, 1 +myblockchain.cloud, 1 +mybloggedlife.com, 1 +myblogwire.org, 1 +myblogworld.com.au, 1 +mybokx.co, 1 +mybon.at, 0 +mybon.online, 1 +mybookbee.com, 1 +mybookkeeper-perth.com.au, 1 +myboothang.com, 1 +myborder.ru, 1 +mybottle.ch, 1 +myboxing.tk, 1 +myboxofficetickets.com, 1 +mybpstar.com, 1 +mybritney.tk, 1 +mybrokenheart.tk, 1 +mybsms.gr, 1 +mybuddycare.com, 1 +mybuddytheplumber.com, 1 +mybuildingcertifier.com.au, 1 +mycaelis.fr, 1 +mycam.gq, 1 +mycamshowhub.com, 1 +mycamshowhub.to, 1 +mycard.moe, 1 +mycardplace.com, 1 +mycarinsurance123.com, 0 +mycarwashers.com, 1 +mycbils.uk, 1 +mycc.be, 1 +mychamberlain.co.nz, 1 +mychamberlain.com, 1 +mychamberlain.com.au, 1 +mychamberlain.eu, 1 +mychawinda.cf, 1 +mychemromance.tk, 1 +mychicken.info, 1 +mychicken.nl, 1 +mychildatschool.com, 1 +mychunky.design, 1 +mychurchisalive.org, 1 +mycinema.pro, 1 +mycircleworks.com, 1 +myclimate.com, 1 +myclinicalstudybuddy.com, 1 +myclon.tk, 1 +mycloud-system.com, 1 +mycloudbits.me, 1 +mycloudhome.site, 1 +mycloudhome.top, 1 +mycloudhome.xyz, 1 +mycloudkey.net, 1 +mycloudsaas.com, 1 +mycodes.com.au, 1 +mycofairtrade.com, 0 +mycoins.gallery, 1 +mycoldjet.com, 1 +mycolorado.gov, 1 +mycommerce.tk, 1 +mycompanion.cz, 1 +mycompanysite.host, 1 +myconan.net, 1 +myconan.tk, 1 +myconcorde.fr, 1 +myconf.com, 1 +myconf.es, 1 +myconf.uk, 1 +myconferencion.tk, 1 +myconnection.ie, 1 +myconsultation.be, 1 +myconsulting.ch, 0 +mycontactacuvue.fr, 1 +mycontactopticien.fr, 1 +mycontrolmonitor.com, 1 +mycookrecetas.com, 1 +mycoordinates.xyz, 1 +mycounterstrike.ru, 1 +mycoupons.com, 1 +mycr.eu, 1 +mycreativeartsconsulting.com, 1 +mycreativenook.com, 1 +mycreditcardcenter.com, 1 +mycreditcardclub.com, 1 +mycreditunion.gov, 1 +mycritify.com, 1 +mycrm.coach, 1 +mycrowdstack.com, 1 +mycrypnet.io, 1 +mycustomwriting.com, 1 +mycutebee.com, 1 +mydais.org, 1 +mydarkness.cf, 1 +mydarksite.tk, 1 +mydarkstar.net, 1 +mydatadoneright.eu, 1 +mydataprotected.com, 1 +mydaxio.com, 1 +mydaymark.com, 1 +mydaywebapp.com, 1 +mydeardreams.com, 1 +mydebian.in.ua, 1 +mydentalplan.gr, 1 +mydenverhomesource.com, 1 +mydevolo.com, 1 +mydevolo.de, 1 +mydevops.cloud, 1 +mydigicard.biz, 1 +mydigicard.host, 1 +mydigitalweek.com, 1 +mydistance.tk, 1 +mydna.bio, 1 +mydnshost.co.uk, 1 +mydoc.fr, 1 +mydocserve.com, 1 +mydogtrainingcollar.com, 1 +mydolls.ml, 1 +mydomaindesk.com, 1 +mydomen.ml, 1 +mydoxod.tk, 1 +mydreamlifelab.com, 1 +mydreamshaadi.in, 1 +mydroneservices.ca, 1 +mydroneservices.com, 1 +mydslwebstats.co.uk, 1 +mydsomanager.com, 1 +myduffyfamily.com, 1 +myeasybooking.de, 1 +myeberspaecher.com, 1 +myebony.cam, 1 +myecms.com, 1 +myecopanda.com, 1 +myedcreview.cf, 1 +myediblefood.com, 1 +myeditclub.ml, 1 +myedu.ga, 1 +myedu.gq, 1 +myeducationhub.tk, 1 +myedumundo.com, 1 +myeisenbahn.de, 1 +myekon.com, 1 +myelka.tk, 1 +myemailsender.tk, 1 +myeml.net, 0 +myempire.com.au, 1 +myenemy.tk, 1 +myepass.bg, 1 +myepass.de, 1 +myeriri.com, 1 +myers.house, 1 +myerscreekcascades.com.au, 1 +myersking.com, 1 +myesk.rs, 1 +myessaygeek.com, 1 +myetherwallet.com, 1 +myethvault.com, 1 +myeventstation.com, 1 +myevive.com, 1 +myexams.nl, 1 +myf.cloud, 1 +myfae.eu, 1 +myfamilyancestry.tk, 1 +myfancyurl.tk, 1 +myfantasysportstalk.com, 1 +myfavmessage.cf, 1 +myfavorite.com.tw, 1 +myfdic.gov, 1 +myfedloan.org, 1 +myfile.gq, 1 +myfinverse.com, 1 +myfirenet.com, 0 +myfishpalace.at, 1 +myflightsonline.com, 1 +myfloridacfo.gov, 1 +myforfaitmobile.com, 1 +myformatconverter.com, 0 +myfortdodge.com, 1 +myforum.community, 1 +myfreemp3.click, 1 +myfrenchtattoo.fr, 1 +myfsb.bank, 1 +myfunworld.de, 1 +myfursona.com, 1 +myfutureself.com.au, 1 +myg21.com, 1 +mygadgetguardian.lookout.com, 0 +mygallery.homelinux.net, 1 +mygameconsole.tk, 1 +mygate.at, 0 +mygaysitges.com, 1 +mygear.live, 1 +mygedit.com, 1 +mygedit.info, 1 +mygedit.net, 1 +mygedit.org, 1 +mygeneral.org, 1 +mygeorgia.org, 1 +mygeotrip.com, 1 +mygermanexpert.com, 1 +mygest.me, 1 +mygh.online, 1 +mygigabitnation.com, 1 +mygignation.com, 1 +mygimp.tk, 1 +mygirlfriendshouse.com, 1 +mygizmolife.tech, 1 +mygnmr.com, 1 +mygoldennetwork.com, 1 +mygomel.tk, 1 +mygov.scot, 1 +mygreatjob.eu, 1 +mygreatjobs.de, 0 +mygreatlakes.org, 1 +mygreatwebsite.co.uk, 1 +mygreeley.com, 1 +mygreenrecipes.com, 1 +mygretchen.de, 1 +mygrodno.tk, 1 +mygymer.ch, 1 +myhair.asia, 1 +myhappiness.tk, 1 +myhatsuden.jp, 1 +myhealthcheckup.ca, 1 +myhealthcheckup.com, 1 +myhealthyday.com, 1 +myheartlaundry.com, 1 +myhell-anonim.tk, 1 +myhfstar.com, 1 +myhkweb.tk, 1 +myhmz.bid, 1 +myhollywoodnews.com, 1 +myhome-24.pl, 1 +myhomeworkpapers.com, 1 +myhoor.ga, 1 +myhostname.net, 1 +myhotgirls.ml, 1 +myhuthwaite.com, 1 +myibidder.com, 1 +myicare.org, 1 +myid.be, 1 +myimds.com, 1 +myimmitracker.com, 1 +myinjuryattorney.com, 1 +myinsiderplus.com, 1 +myinstapy.ru, 0 +myinsurancesource.com, 1 +myinternist.com, 1 +myintimtoys.com, 1 +myitworks.co.za, 0 +myjarofhope.com, 1 +myjourney.id, 1 +myjudo.net, 1 +myjumparoo.co.uk, 1 +myjumpsuit.de, 1 +myjustice.org, 1 +myjuvelirika.ru, 1 +mykarelia.ga, 1 +mykarelia.tk, 1 +myke.website, 1 +myki.co, 1 +mykolhoz.tk, 1 +mykonos-island.tk, 1 +mykontool.de, 1 +mykumedir.com, 1 +mykurgan.tk, 1 +mykursumlija.tk, 1 +mylahcollection.com.br, 1 +mylatestnews.org, 1 +mylawer.ga, 1 +mylawyer.be, 1 +mylearners.vic.gov.au, 1 +myled.ml, 1 +mylegacyvip.com, 1 +mylene-chandelier.me, 1 +myles.digital, 1 +mylever.com, 1 +mylfca.com, 1 +mylife360mag.com, 1 +mylifeabundant.com, 1 +mylifesphotograph.com, 1 +myliftmaster.com, 1 +myliftmaster.eu, 1 +mylight.tk, 1 +mylittlechat.ru, 1 +mylittlegrocer.co.uk, 1 +mylittlegrocer.com, 1 +myliveupdates.com, 1 +mylms.nl, 1 +myload.ch, 1 +myloan.hk, 1 +myloanmanager.com, 1 +mylocalfoodtrucks.com, 1 +myloneworkers.com, 1 +mylookout.com, 0 +mylotto.co.nz, 1 +mylover.be, 1 +mylrd.xyz, 1 +mylstrom.com, 1 +myltivarka.ml, 1 +mylucknursinghome.com, 1 +mymagic.ml, 1 +mymailboxpro.cf, 1 +mymailspace.ml, 1 +mymanagement.ml, 1 +mymartinbeckeropenhab.de, 1 +mymartinbeckeropenhab.eu, 1 +mymb.pm, 1 +mymed.de, 1 +mymed.eu, 1 +mymedia.gotdns.com, 1 +mymedz.nl, 1 +mymerlin.co.nz, 1 +mymerlin.com.au, 1 +mymixtapez.com, 1 +mymkphotography.com, 1 +mymommyworld.com, 1 +mymonture.com, 1 +mymoretrip.com, 1 +mymotherlandstuffs.cn, 1 +mymotor.nl, 1 +mymsr.de, 0 +mymun.com, 1 +mymun.net, 1 +mymusiclist.alwaysdata.net, 1 +mymusique.tk, 1 +mymx.lu, 0 +myna.go.jp, 1 +mynak.se, 1 +mynameistavis.com, 1 +mynas.ovh, 1 +mynaturalhairstyles.com, 1 +mynaturalmood.es, 1 +mynavi-kaigo.jp, 1 +myndcoin.com, 1 +myndcoins.com, 1 +myndcommunication.com, 1 +myndighetermeddnssec.se, 1 +myndighetermedipv6.se, 1 +mynerva.io, 1 +mynetflow.com, 1 +mynetpay.be, 1 +mynetworkingbuddy.com, 1 +mynewsspot.com, 1 +mynext.events, 1 +mynextmove.org, 1 +mynic.my, 1 +mynimo.com, 1 +mynn.io, 0 +mynook.info, 1 +mynoveltyshop.com, 1 +mynovus.de, 1 +mynutrientcloud.com, 1 +myoddlittleworld.com, 1 +myodysi.com, 1 +myofficeconnect.co.uk, 1 +myofficerenovation.com, 1 +myonline.hu, 1 +myonline.store, 1 +myonlinedating.club, 1 +myonlinemovies.ga, 1 +myonlinevehicleinsurance.com, 1 +myopd.in, 1 +myoptimalbrain.com, 1 +myoptumhealthcomplexmedical.com, 1 +myoregon.gov, 1 +myotopie.de, 0 +myoueb.fr, 1 +myoukochou.com, 1 +myowncloud.ovh, 1 +myowncloud.pl, 1 +myownconference.com, 1 +myownconference.com.ua, 1 +myownconference.pl, 1 +myownconference.ru, 1 +myowndisk.com, 1 +myowndisk.net, 1 +mypaperdone.com, 1 +mypaperpress.com, 1 +mypaperwriter.com, 1 +myparadigm.com, 1 +myparfumerie.at, 0 +mypartnernews.com, 1 +mypartybynoelia.es, 1 +mypathologos.gr, 1 +mypay.fr, 1 +mypcb.tk, 1 +mypdns.com, 1 +mypdns.org, 1 +mypehas.com, 1 +mypenza.tk, 1 +myperfecthome.ca, 1 +myperks.in, 1 +mypersonalpage.tk, 1 +mypet24.ch, 1 +mypfp.co.uk, 1 +myphamaplus.org, 1 +mypharmjar.com, 1 +myphotographytips.com, 1 +myphotonics.ml, 1 +myphotos.ga, 1 +myphotoshopbrushes.com, 1 +mypillcard.com, 1 +mypiloteis.com, 1 +mypinasale.com, 0 +mypivcard.com, 1 +mypizza-bremen.de, 1 +myplaceonline.com, 1 +myplaystation.nl, 0 +mypnu.net, 1 +mypogljad.tk, 1 +mypornsnap.top, 1 +myportal.ga, 1 +mypower91.com, 1 +mypress.mx, 1 +myprintcard.de, 1 +myproblog.com, 1 +mypromocode.com, 1 +myproof.me, 1 +mypropertal.com, 1 +myprotime.eu, 1 +myproxy.eu.org, 1 +mypskov.tk, 1 +mypsychicreadings.tk, 1 +mypvhc.com, 1 +myqbusiness.com, 1 +myqservices.com, 1 +myraboats.tk, 1 +myradnetconnect.com, 1 +myrandomtips.com, 1 +myrasp.eu, 1 +myraytech.net, 0 +myrealestateautomation.com, 1 +myrealestatemate.com.au, 1 +myred.net, 1 +myref.net, 1 +myrekber.co.id, 1 +myremont.tk, 1 +myremotelogin.ddns.net, 1 +myrent.quebec, 1 +myrepubic.net, 1 +myrepubiic.net, 1 +myrepublc.net, 1 +myrepublic.asia, 1 +myrepublic.cf, 1 +myrepublic.cloud, 1 +myrepublic.com.cn, 1 +myrepublic.com.hk, 1 +myrepublic.com.kh, 1 +myrepublic.com.lk, 1 +myrepublic.com.my, 1 +myrepublic.com.ph, 1 +myrepublic.com.tw, 1 +myrepublic.eu.com, 1 +myrepublic.ga, 1 +myrepublic.gq, 1 +myrepublic.icu, 1 +myrepublic.id, 1 +myrepublic.in, 1 +myrepublic.limited, 1 +myrepublic.lk, 1 +myrepublic.ml, 1 +myrepublic.mobi, 1 +myrepublic.my, 1 +myrepublic.net, 1 +myrepublic.net.au, 1 +myrepublic.nz, 1 +myrepublic.ph, 1 +myrepublic.rocks, 1 +myrepublic.run, 1 +myrepublic.tk, 1 +myrepublic.tv, 1 +myrepublic.tw, 1 +myrepublic.us.com, 1 +myrepublic.xyz, 1 +myrepublicau.com, 1 +myrepublicaus.com, 1 +myrepublicbroadband.com.au, 1 +myrepublicfibre.com.au, 1 +myrepublicgroup.com, 1 +myrepublicinternet.com.au, 1 +myrepublicltd.com, 1 +myrepublicmy.com, 1 +myrepublicnz.com, 1 +myrepublicsg.com, 1 +myrepublictelecom.com, 1 +myrepubllc.net, 1 +myresearchapp.com, 1 +myresearchtoolbox.net, 1 +myresidence.de, 1 +myrevery.com, 1 +myreviews.ga, 1 +myrevolution.in, 1 +myrewardspoints.com, 1 +myriadlex.com.tw, 1 +myriadof.com, 1 +myrig.com, 1 +myrig.net, 1 +myrnabiondo.com.br, 1 +myrom.tk, 1 +myrotvorets.center, 1 +myrotvorets.news, 1 +myrp.co, 1 +myruststats.com, 1 +myrvog.net, 1 +myrvogna.net, 1 +mysad.de, 1 +mysafetygear.co.za, 1 +mysaldo.info, 1 +mysasiedzi.bialystok.pl, 1 +mysaymk.tk, 1 +mysbaccoach.com, 1 +myschoolphoto.org, 1 +mysciencecloset.com, 1 +myscottishpath.com, 1 +myseatime.com, 1 +mysecretstylist.ga, 1 +myself5.de, 1 +myseo.ga, 1 +myservicearl.com, 1 +myservik.ml, 1 +myseu.cn, 1 +mysexvids.net, 1 +mysexycard.com, 1 +mysexydate24.com, 1 +myshikarpur.tk, 1 +myshopdisplay.com, 1 +mysidekick.io, 1 +mysignal.com, 1 +mysites.guru, 1 +mysmelly.com, 1 +mysmg.in, 1 +mysocialporn.com, 1 +mysociety.ml, 1 +mysockfactory.ch, 1 +mysockfactory.com, 1 +mysocrat.com, 1 +mysoundtalks.com, 0 +mysouschef.herokuapp.com, 1 +myspicer.com, 1 +mysports.com, 1 +mysql-real-escape-string.xyz, 1 +mysqldump-secure.org, 1 +myssl.com, 1 +mystaffonline.com, 1 +mystagic.cloud, 1 +mysteriesandmargaritasblogspot.com, 1 +mysteriousbeans.com, 1 +mysteriouscode.io, 1 +mystery-box.cf, 1 +mysterydata.com, 1 +mysterymind.ch, 0 +mysterysear.ch, 1 +mysteryshow.site, 1 +mystgames.tk, 1 +mystia.org, 1 +mystic-falls.tk, 1 +mystic-welten.de, 1 +mysticconsult.com, 1 +mystickphysick.com, 1 +mysticmedia.net, 1 +mystorage.work, 1 +mystore24.eu, 1 +mystore24.us, 1 +mystorymonster.com, 1 +mystown.org, 1 +mystreet.ga, 1 +mystudy.me, 1 +mystudycart.com, 1 +mystudymap.tk, 1 +mystylion.com, 1 +mysupplements.ga, 1 +myswimmingclub.uk, 1 +myswissmailaddress.com, 0 +myswitchelectric.com, 1 +mytc.fr, 1 +myte.ch, 1 +mytefl.com, 1 +mytests.tk, 1 +mytfg.de, 1 +mythemeshop.com, 0 +mythen-fonds.ch, 1 +mythenfonds.ch, 1 +mythesis.academy, 1 +mythicdelirium.com, 1 +mytime.fr, 1 +mytime.gl, 1 +myting.net, 1 +mytntware.com, 1 +mytodo.cloud, 1 +mytraiteurs.com, 1 +mytraning.cf, 1 +mytransmissionexperts.com, 1 +mytravelblog.de, 1 +mytravelguide.tk, 1 +mytrendiya.com, 1 +mytribes.ru, 1 +mytribus.com, 1 +mytrinity.com.ua, 1 +mytripcar.co.uk, 1 +mytripcar.com, 1 +mytripcar.de, 1 +mytripcar.es, 1 +mytripcar.fr, 1 +mytruecare.org, 1 +mytrustadviser.com, 1 +mytty.net, 1 +mytuleap.com, 1 +mytun.com, 1 +mytuzla.tk, 1 +mytweeps.com, 1 +myupbeat.com, 1 +myupdatestar.com, 0 +myupdatestudio.com, 1 +myupdatesystems.com, 1 +myupdateweb.com, 1 +myusagepayments.com, 1 +myvacompany.com, 1 +myvalleymarketing.com, 1 +myvegasadvisor.com, 1 +myviewboard.com, 1 +myvoipnews.com, 0 +myvologda.tk, 1 +myvotect.gov, 1 +myvpl.com, 1 +mywalletcrypto.cf, 1 +mywapforum.ga, 1 +mywari.com, 1 +myweatherbuzz.com, 1 +myweb360.de, 1 +mywebexperience.gq, 1 +mywebinar.io, 1 +mywebmanager.co.uk, 1 +mywebpanel.eu, 1 +mywebpharmacy.tk, 1 +mywebserver.ml, 1 +myweddingreceptionideas.com, 1 +myweightlosstips.tk, 1 +mywestondental.com, 1 +mywetpussycams.com, 1 +mywindscreen.my, 1 +mywiwe.com.au, 1 +mywoodbridgedentist.com, 1 +myworkinfo.com, 0 +myworth.com.au, 1 +mywrecklawyer.com, 1 +myxnr.com, 1 +myxxxsite.tk, 1 +myyubikey.net, 1 +myyubikey.org, 1 +myzarabot.tk, 1 +myzina.cz, 0 +mz-mz.net, 1 +mza.com, 1 +mzademiryolu.com, 1 +mzb.company, 0 +mzcsgo.top, 1 +mzitu.com, 1 +mziulu.me, 0 +mzlive.eu, 1 +mzlog.win, 1 +mzmtech.com, 1 +mzorn.photography, 1 +mzr.jp, 1 +mzrme.com, 1 +mzrme.top, 1 +mzstatic.cc, 1 +n-a-railways.com, 1 +n-cis.ru, 1 +n-design-service.de, 1 +n-design.de, 1 +n-doc.com, 1 +n-doc.de, 1 +n-gram.it, 1 +n-laboratory.jp, 1 +n-linear.org, 1 +n-m.lu, 1 +n-man.info, 1 +n-metz.de, 1 +n-pix.com, 0 +n-un.de, 0 +n.tt, 1 +n0paste.tk, 0 +n0psled.nl, 1 +n16.co, 1 +n26.com, 1 +n29.co, 0 +n2diving.net, 1 +n2o.io, 1 +n2ray.xyz, 1 +n30365.com, 1 +n36533.com, 1 +n37.co, 1 +n3oxid.fr, 1 +n3rd0rama.tk, 1 +n4mullingartolongford.ie, 1 +n4zm.com, 1 +n5118.com, 1 +n5197.co, 1 +n61roscommon.ie, 1 +n6729.co, 1 +n6729.com, 1 +n6957.co, 1 +n6a.net, 1 +n7.education, 1 +n81365.com, 1 +n82365.com, 1 +n888-qieji.com, 1 +n888151.com, 1 +n888161.com, 1 +n888388.com, 1 +n888599.com, 1 +n888677.com, 1 +n888699.com, 1 +n88890.com, 1 +n888duchang.com, 1 +n888go.com, 1 +n888ok.com, 1 +n8ch.net, 1 +n8mgt.com, 1 +n8nvi.com, 1 +n8s.jp, 1 +n8solutions.biz, 1 +n8solutions.com, 1 +n8solutions.host, 1 +n8solutions.net, 1 +n8solutions.us, 1 +n9297.co, 1 +n9397.com, 1 +n95.news, 1 +n95s.icu, 1 +n95s.tech, 1 +n9721.com, 1 +n9728.co, 1 +na-kipre.tk, 1 +na-n.xyz, 1 +na-school.nl, 1 +naahgluck.de, 1 +naam.me, 1 +naamlint.nl, 1 +naano.org, 1 +naarakah.fr, 1 +nab-services.ml, 1 +nabaleka.com, 1 +nabeer.ga, 1 +nabeez.cf, 1 +nabidkydnes.cz, 1 +nabiev.tk, 1 +nabitrix.tk, 1 +nabokov.tk, 1 +nabosoft.tk, 1 +nabytek-valmo.cz, 1 +nabytokalva.sk, 1 +nacfit.com, 1 +nachalniku.tk, 1 +nachalosbog.bg, 1 +nachalova.tk, 1 +nachbar.chat, 1 +nachovni.org, 1 +nachsendeauftrag.net, 1 +nachsenden.info, 1 +nachtmuziek.info, 1 +nacin.com, 1 +nacktetatsachen.at, 0 +nacktwanderfreunde.de, 1 +nacnkabiltrim.cf, 1 +nacocu.cf, 1 +nacoree.ga, 1 +nacyklo.cz, 1 +nad-r.com, 1 +nadacnifondacr.cz, 1 +nadaquenosepas.com, 1 +naddi.org, 1 +nadejeproninu.cz, 1 +nadelholzkulturen.de, 1 +nadex.com, 1 +nadezhda.ml, 1 +nadiafourcade-photographie.fr, 1 +nadine-birkner.de, 1 +nadine-chaudier.net, 1 +nadinecays.com, 1 +nadjabenaissa.tk, 1 +nadji.ga, 1 +nadlerdentistry.com, 1 +nadomna-rabota.tk, 1 +nadoske.info, 1 +nadsandgams.com, 1 +nadyaolcer.fr, 1 +naemnuk.tk, 1 +nafod.net, 1 +naga-semi.com, 1 +naga-wedding.tk, 1 +naga.gq, 1 +naganoziotech.com, 1 +nagara.fr, 1 +nagashi.ma, 0 +nagato.tk, 1 +nagaya.biz, 1 +nagb.gov, 1 +nagb.org, 1 +nagel-dentaltechnik.de, 1 +nageler.org, 1 +nagelfam.com, 1 +nagelideeen.ml, 1 +naggie.net, 1 +nagoonline.com, 1 +nagoya.tk, 1 +nagrad.tk, 1 +nah.nz, 1 +nah.re, 1 +nahman.tk, 1 +nahouw.net, 1 +nahtanoj.tk, 1 +nahttps.tk, 1 +nahura.com, 1 +nai-job.jp, 1 +naia.me, 1 +naiaokami.me, 1 +naide.ee, 1 +naif.cz, 1 +naifcare.cz, 1 +naifix.com, 1 +naijaretro.com, 1 +naijatechweb.tech, 0 +naijaxnet.com.ng, 1 +nailattitude.ch, 0 +nailchiodo.com, 1 +nailclub.tk, 1 +nails-n-more.be, 1 +nailsalon-aztplus.com, 1 +nailsart.roma.it, 1 +nailsforyoustouffville.ca, 1 +nailshop.gq, 1 +nailsmania.ua, 1 +nairobibusinessreview.com, 1 +nais0ne.com, 1 +naivetube.com, 0 +najafpour-stone.com, 1 +najany.de, 1 +najany.dk, 1 +najany.nl, 1 +najany.se, 1 +najarkadeh.com, 1 +najdou.cz, 1 +naji-astier.com, 1 +najiflix.fr, 1 +najmacademy.com, 1 +najprzepis.pl, 1 +najrecept.sk, 1 +naka.io, 1 +nakada4610.com, 1 +nakagawa-d.co.jp, 1 +nakagawa-s.jp, 1 +nakajims.net, 1 +nakalabo.jp, 1 +nakama.tv, 1 +nakamastudios.com, 1 +nakanishi-paint.com, 1 +nakarkhana.com, 1 +nakayama.industries, 1 +nakayama.systems, 1 +nakayamaresearch.com, 1 +nakazanie.ga, 1 +nakazato-shika.com, 1 +nakedalarmclock.me, 1 +nakedfacts.co.uk, 0 +nakedinkas.com, 1 +nakedtruthbeauty.com, 1 +nakenmodell.tk, 1 +nakhtalla.ir, 1 +nakim.cf, 1 +nakin.tk, 1 +nakka.ch, 1 +nakliyat.name.tr, 1 +nakliyatsirketi.biz.tr, 1 +nakliye.name.tr, 1 +nakluky.cz, 1 +nako.kr, 1 +nako.no, 1 +nakupi.online, 1 +nakvartiru.com, 1 +nale-hosting.tk, 1 +nalenders.com, 1 +nalepky-na-zed.cz, 1 +nalepte.cz, 1 +nalexandru.xyz, 1 +nalresearch.com, 1 +naltrexon.gq, 1 +nalukfitness.com.br, 1 +namaanak.net, 1 +namaanakperempuan.net, 1 +namacindia.com, 1 +namalelaki.com, 1 +namaperempuan.com, 1 +namazon.org, 1 +namdak.com, 1 +namedaemon.com, 1 +namegrep.com, 1 +nameid.org, 1 +namepros.com, 1 +nameproscdn.com, 1 +namereel.com, 1 +nameshield.com, 1 +nameshield.net, 1 +namesnack.com, 1 +namethatporn.com, 1 +namethissymbol.com, 1 +nametiles.co, 1 +nami.bo, 1 +nami.exchange, 1 +nami.trade, 1 +namikawatetsuji.jp, 1 +naminam.de, 1 +namrs.net, 1 +namsbaekur.is, 1 +namskra.is, 1 +namu.games, 1 +namu.la, 1 +namu.live, 1 +namu.moe, 1 +namu.news, 1 +namu.wiki, 1 +namus.gov, 1 +nan.ge, 0 +nan0.cloud, 1 +nanaimo.ca, 1 +nanaimoneighbourhoods.ca, 1 +nanaka.love, 1 +nanamovies.com, 1 +nanarose.ch, 0 +nanch.com, 1 +nanco.co.jp, 1 +nanco.jp, 1 +nancytelford.com, 1 +nancytutors.com, 1 +nancyzone.tk, 1 +nandapanithota.xyz, 1 +nandedbazar.tk, 1 +nandemo.tk, 1 +nanderson.me, 1 +nandito.tk, 1 +nanfangstone.com, 1 +nange.cn, 1 +nangluongxanhbinhphuoc.com, 1 +naninossoftware.tk, 1 +nanisiyou.com, 1 +nanji123.com, 1 +nanjiys.com, 1 +nanjiyy.com, 1 +nankiseamansclub.com, 1 +nanmu.me, 1 +nannan.online, 1 +nannytax.ca, 1 +nano.voting, 1 +nanodynelabs.com, 1 +nanofy.org, 1 +nanogi.ga, 1 +nanogramme.fr, 0 +nanohatsolution.tk, 1 +nanohostsolution.cf, 1 +nanolet.ga, 1 +nanollet.org, 1 +nanopixel.ch, 1 +nanoport.jp, 1 +nanosealcreto.com, 1 +nanoshop.ml, 1 +nanotechnologist.com, 1 +nanotechnologysolutions.com.au, 1 +nanotechtorsion.com, 1 +nanotipbot.tk, 1 +nanovolt.nl, 1 +nanowallet.io, 1 +nanpuyue.com, 1 +nansa.ch, 1 +nanshy.com, 0 +nanubo.com, 1 +nanubo.de, 1 +nanwan.info, 1 +nanxin.live, 1 +nanxin.wtf, 1 +nanxin.xyz, 1 +nao.sh, 1 +napcae.de, 1 +naphex.rocks, 1 +napikuponok.hu, 1 +napisdata.us, 1 +napitok.tk, 1 +napkins-wholesale.co.za, 1 +napkins-wholesale.com, 1 +napkins-wholesale.in, 1 +napkins-wholesale.nz, 1 +napkins-wholesale.uk, 1 +naplata.mk, 1 +naples.tk, 1 +naplestotalgarage.com, 1 +napoleonoutlawed.tk, 1 +napolinissanctparts.com, 1 +napominanie.ml, 1 +napoveda.online, 1 +nappylaundry.ga, 1 +nappywashing.ga, 1 +napych.com, 1 +naql.om, 1 +naquebec.tk, 1 +naraboty.ga, 1 +narada.com.ua, 1 +naradiebosch.sk, 1 +naradiehusqvarna.sk, 1 +naradiemakita.sk, 1 +narakenkoland.net, 1 +naralogics.com, 1 +naranonsantabarbara.org, 1 +narardetval.se, 1 +narazaka.net, 1 +narcisqeshm.com, 1 +narcologic.ru, 1 +narda-sts.com, 1 +nardamiteq.com, 1 +nardpedro.tk, 1 +nareb.com, 1 +narec.org, 1 +narela.com.mx, 1 +narenderchopra.com, 1 +narfation.org, 1 +nargele.eu, 1 +nargileh.nl, 1 +naric.com, 1 +narindal.ch, 1 +narko-stop.org, 1 +narmos.ch, 0 +naro.se, 1 +narodnaya-medizina.tk, 1 +narodniki.com, 1 +narodowyspispowszechny.pl, 1 +narodserial.cf, 1 +naroska.name, 1 +narrabeenlakesbikehire.com, 1 +narrativasdigitais.pt, 1 +narrative.network, 1 +narrative.org, 1 +narrenverein-wolkenschieber.de, 1 +narsq.com, 1 +narthollis.net, 0 +narushil-pdd.cf, 1 +narushil-pdd.ga, 1 +narushil-pdd.gq, 1 +narushil-pdd.ml, 1 +narushil-pdd.tk, 1 +naruto-best.tk, 1 +narutoshippuden.tk, 1 +narutouzumaki.tk, 1 +narzedziownia.top, 1 +nasa.co.nz, 1 +nasaacronyms-beta.com, 1 +nasaacronyms.com, 1 +nasalucx.org, 1 +nasarawanewsonline.com, 1 +nasavelkaceskoslovenskasvadba.eu, 1 +nasbi.pl, 1 +naschenweng.info, 1 +naschenweng.me, 1 +nascher.org, 0 +nasdarq.com, 1 +naseehah.ga, 1 +nasehyar.ir, 1 +nash-dom.tk, 1 +nash-megagid.tk, 1 +nash-server.tk, 1 +nash-shishtavec.tk, 1 +nasha-kahovka.tk, 1 +nashareklama.tk, 1 +nashdistribution.com, 1 +nashfutbol.tk, 1 +nashikmatka.com, 1 +nashira.cz, 1 +nashjurist.tk, 1 +nashkrai.ga, 1 +nashuaradiology.com, 1 +nashvillebasements.com, 1 +nashvillelidsurgery.com, 1 +nashvillesheriff.gov, 1 +nashzhou.me, 1 +nasimblog.tk, 1 +naslovi.net, 1 +nasospromsnab.ru, 1 +nasosvdom.com, 1 +nasosvdom.com.ua, 1 +nasr.mobi, 1 +nasrabady.tk, 1 +nasrsolar.com, 1 +nassconorfolk.com, 1 +nasserver-test.de, 0 +nassi.me, 1 +nast.tk, 1 +nastrojka-pianino.spb.ru, 1 +nastunya.tk, 1 +nastycomics.eu, 1 +nastysclaw.com, 1 +naszymzdaniem.pl, 1 +nat-neocron.tk, 1 +nataez.tk, 1 +nataldigital.com, 1 +natalia-in-quebec.tk, 1 +natalia-shablo.ru, 1 +natalia-venezuela.tk, 1 +nataliedawnhanson.com, 1 +nataliehershlag.tk, 1 +natalsentido.com, 1 +natanaelys.com, 0 +nataniel-perissier.fr, 1 +natarius.tk, 1 +natariusadvokat.ga, 1 +natasa-theodoridou.tk, 1 +natasabekvalac.tk, 1 +natasajanvirant.com, 1 +natasasavija.tk, 1 +nataschaskraamzorg.nl, 1 +natashki.tk, 1 +natasjaversantvoort.nl, 1 +natation-nsh.com, 0 +natchmatch.com, 1 +nate.sh, 1 +nateandxtina.wedding, 1 +nategreen.org, 0 +natehobi.com, 1 +natenom.com, 1 +natenom.de, 1 +natenom.name, 1 +nates.tk, 1 +natevolker.com, 1 +natextruck.com, 1 +nathaliedijkxhoorn.com, 1 +nathaliedijkxhoorn.nl, 1 +nathaliesadventure.eu, 1 +nathalyb.com, 1 +nathan.ovh, 1 +nathanaeldawe.com, 1 +nathanbarry.com, 1 +nathancrank.com, 1 +nathanielparker.com, 0 +nathanielparker.de, 0 +nathanielparker.info, 0 +nathanielparker.org, 0 +nathankonopinski.com, 1 +nathanmfarrugia.com, 1 +nathanphoenix.com, 1 +nathansmetana.com, 1 +nathenmaxwell.tk, 1 +nathumarket.com.br, 1 +nation-contracting.com.hk, 1 +nationalaustriabank.com, 1 +nationalbank.gov, 1 +nationalbanknet.gov, 1 +nationalcashoffer.com, 1 +nationalcrimecheck.com.au, 1 +nationalcybersecuritysociety.org, 1 +nationalfleetparts.com, 1 +nationalhomeimprovements.co.uk, 1 +nationalhomequotes.com, 1 +nationalmall.gov, 1 +nationalmap.gov, 1 +nationalopera.ml, 1 +nationalpriorities.org, 1 +nationalservice.gov, 1 +nationaltrails.ru, 1 +nationandfreedom.tk, 1 +nationsecurity.com, 1 +nationslending.com, 1 +nationx.tk, 1 +native2ascii.net, 1 +nativeindonesia.com, 1 +nativemusicrecords.cf, 1 +nativeonestop.gov, 1 +nativereach.tv, 1 +natives-team.ch, 0 +nativetitle.org.au, 1 +nativitynj.org, 1 +nativs.ch, 0 +natlec.ch, 1 +natlec.com, 1 +natmal.net, 1 +nato-stamps.tk, 1 +natropie.pl, 1 +natsar.com, 1 +nattiam.com, 1 +natuerlichabnehmen.ch, 1 +natunion.ga, 1 +natur-care.com, 1 +natur-plus.tk, 1 +natur-udvar.hu, 1 +natur.com, 1 +natura-sense.com, 1 +natura2000.tk, 1 +naturalbeautyhacks.com, 1 +naturalbijou.com, 1 +naturalbladdercontrol.tk, 1 +naturalcosmetics.cf, 1 +naturaldisasters.tk, 1 +naturalezafengshui.com, 1 +naturalfit.co.uk, 1 +naturalflowerpower.com, 1 +naturalkitchen.co.uk, 1 +naturallyvegan.de, 1 +naturalspacesdomes.com, 1 +nature-et-bio.fr, 1 +natureclaim.com, 1 +naturecoaster.com, 1 +natureflo.net, 1 +naturelk.org, 1 +naturesbest.co.uk, 1 +natureshive.org, 1 +naturesorganichaven.com, 1 +naturesportcentral.com, 1 +natureword.com, 0 +naturheilpraxis-grauer.de, 1 +naturheilpraxis-oida.de, 1 +naturheilpraxis-p-grote.de, 1 +naturliga.tk, 1 +naturopatiasiddharta.com, 1 +naturtint.co.uk, 1 +natusvita.com, 1 +natusvita.com.br, 1 +natuurlijk.tk, 1 +natverkstekniker.se, 1 +natwest.com, 1 +nau.edu.pt, 1 +naude.co, 1 +naufalpanjwani.com, 1 +naughty.audio, 1 +naughtytoy.co.uk, 0 +nauris.fi, 1 +nausicaahotel.it, 1 +naut.ca, 1 +nautiljon.com, 1 +nautsch.de, 1 +nauz-art.com, 1 +navadebejar.tk, 1 +navalarchitect.tk, 1 +navalkejigo.tk, 1 +navaneethnagesh.com, 1 +navarralanparty.org, 1 +navdeep.ca, 1 +naveengranites.com, 1 +navegarea.tk, 1 +naveka.ga, 1 +navenlle.com, 1 +naviaddress.io, 1 +navidarian.tk, 1 +navienna.com, 1 +navient.com, 1 +navigator.ca, 1 +navigo-inc.com, 1 +navigo.cc, 1 +navigo.global, 1 +navinka.com, 1 +naviteq.eu, 1 +navkor.tk, 1 +navlnachekg.cz, 1 +navnet.ml, 1 +navot.co.il, 1 +navroopsahdev.in, 1 +navstevnik.sk, 1 +navycs.com, 1 +nawaf-blog.com, 1 +nawarasa.com, 1 +nawdar.tk, 1 +nawir.de, 1 +nawroth.info, 1 +nawt.pl, 1 +nax.io, 0 +naxoprojects.com, 1 +nay.sk, 1 +nayami64.xyz, 1 +nayanaas.com, 1 +nayapakistan.tk, 1 +nayapixel.com, 1 +nayefalebrahim.com, 1 +nayr.us, 1 +nazarenohuelva.tk, 1 +nazarenoviso.tk, 1 +nazbol.tk, 1 +nazevfirmy.cz, 1 +nazimogluinsaat.com, 1 +nazmulislam.cf, 1 +nazukebanashi.com, 1 +nazuna.blue, 1 +nb.zone, 1 +nb01.com, 1 +nb6.de, 1 +nba-2k.com, 1 +nba-croatia.com, 1 +nba-pcszerviz.hu, 1 +nba.christmas, 1 +nba.com.de, 1 +nba.de.com, 1 +nba.download, 1 +nba.gd, 1 +nba.gs, 1 +nba.gy, 1 +nba.hosting, 1 +nba.im, 1 +nba.live, 1 +nba.lu, 1 +nba.moe, 1 +nba.trade, 1 +nba.vc, 1 +nba.vg, 1 +nba2.com, 1 +nba2k.blog, 1 +nba2k.cc, 1 +nba2k.co, 1 +nba2k.download, 1 +nba2k.live, 1 +nba2k.net, 1 +nba2k.tw, 1 +nba2kcn.com, 1 +nba2kcontest.com, 1 +nba2kmods.com, 1 +nba2kmt.com, 1 +nba2kmy.team, 1 +nba2kol.com, 1 +nba2konline.com, 1 +nba2konlinex.com, 1 +nba2kqq.com, 1 +nba2kx.com, 1 +nbad.al, 1 +nbadancers.com, 1 +nbade.com, 1 +nbafile.com, 1 +nbagirls.com, 1 +nbaim.com, 1 +nbaimg.com, 1 +nbalivecn.com, 1 +nbalivex.com, 1 +nbari.com, 1 +nbask.com, 1 +nbasky.com, 1 +nbaspot.com, 1 +nbavc.com, 1 +nbavg.com, 1 +nbayouxi.com, 1 +nbclinic.co.uk, 1 +nbhorsetraining.com, 1 +nbib.gov, 1 +nbis.gov, 1 +nbl.org.tw, 1 +nbm.gov, 1 +nbotvinnik.com, 1 +nbrain.de, 1 +nbrii.com, 1 +nbriresearch.com, 1 +nbrown.us, 1 +nbsgames.at, 1 +nbwp.uk, 1 +nc-beautypro.fr, 1 +nc-formation.fr, 1 +nc-network.io, 1 +nc2c.com, 1 +nca.ink, 1 +ncamarquee.co.uk, 1 +ncands.net, 1 +ncarmine.com, 1 +ncc-efm.com, 1 +ncc-efm.org, 1 +ncc-qualityandsafety.org, 1 +nccemail.net, 1 +nccfa.org, 1 +nccoe.org, 1 +ncdc.pt, 1 +ncea.net.au, 1 +ncegs.sk, 1 +nchangfong.com, 0 +nchponline.org, 1 +ncic.gg, 1 +ncjrs.gov, 1 +ncksrv.com, 1 +ncksrv.email, 1 +ncksrv.eu, 1 +ncksrv.net, 1 +ncksrv.nl, 1 +ncksrv.org, 1 +nclf.net, 0 +ncli-design.com, 1 +ncloud.freeddns.org, 1 +ncloud.nl, 1 +ncmedicaidplan.gov, 1 +ncmedicaidplans.gov, 1 +ncommenuptial.tk, 1 +ncpimd001.spdns.de, 1 +ncpublichealth.info, 1 +ncrypt.ai, 1 +ncrypt.at, 1 +ncs-cleaning.dk, 1 +ncsadministraties.nl, 1 +ncsc.gov.uk, 1 +ncsccs.com, 1 +nctx.co.uk, 1 +ncua.gov, 1 +nd.fyi, 1 +ndaal.eu, 1 +ndarville.com, 1 +ndbt.com, 1 +ndcpolipak.com, 1 +nder.be, 1 +ndev.tk, 1 +ndfirefighter.com, 1 +ndhlink.com, 1 +ndibba.com, 1 +ndmath.club, 1 +ndmibiza.com, 1 +ndns.ga, 1 +ndpbrn-research.org, 1 +ndphp.org, 1 +ndpigskin.com, 1 +ndrew.me, 1 +nds-helicopter.de, 1 +nds-online.ru, 1 +ndtblog.com, 1 +ndum.ch, 1 +nduna.dk, 1 +ndvr.com, 1 +ndx.ee, 1 +ndy.sex, 1 +ne-on.org, 1 +nea.gov, 1 +nealvorusphd.com, 1 +neanderthalia.tk, 1 +neapi.com, 0 +near.sh, 1 +nearbi.com.mx, 1 +nearby.in.th, 1 +nearbyprinter.com, 1 +neartothesky.com, 1 +neasahourigan.com, 0 +neat-patch.de, 1 +neatlife.co.uk, 1 +neatnestsdesign.com, 1 +neatnestsorganizing.com, 1 +neatous.cz, 1 +neatous.net, 1 +neave.tv, 1 +neaz.tk, 1 +neba.io, 1 +nebelhauch.de, 1 +nebelheim.de, 1 +nebenbeiblog.ch, 1 +nebogame.com, 1 +nebohost.tk, 1 +neboley.cf, 1 +nebra.io, 1 +nebracy.com, 1 +nebucadnezzer.tk, 1 +nebuchadnezzar.codes, 1 +nebul.at, 0 +nebulae.co, 1 +nebulise.com, 1 +nebuso.com, 1 +necd.me, 1 +neckbeard.xyz, 1 +necord.com, 1 +necormansir.com, 1 +necretro.org, 1 +necromantia.tk, 1 +necta.go.tz, 0 +nectere.ca, 1 +nectir-staging.com, 1 +nectir.co, 1 +nedcdata.org, 1 +nedcv-preview.nl, 1 +nedcv.nl, 1 +nedela.tk, 1 +nederland.media, 1 +nederlands-vastgoedfonds.nl, 1 +nedermisp.nl, 1 +nedhome.ml, 1 +nedim-accueil.fr, 1 +nedimon.gq, 1 +nedir.help, 1 +nednex.com, 1 +nedviga.tk, 1 +nedvizhimost.tk, 1 +nedvizhimostthailand.ml, 1 +nedvrf.ru, 1 +nedworks.net, 1 +nedzadalibegovic.com, 1 +neecist.org, 1 +needemand.com, 1 +needfire.ga, 1 +needflare.com, 1 +needing.cf, 1 +needle-demo.azurewebsites.net, 1 +needle.net.nz, 1 +needle.nz, 1 +needrom.com, 1 +needsth.top, 1 +needsupport.us, 1 +neel.ch, 1 +neemdetijd.nl, 1 +neemo.nz, 1 +neemzy.org, 1 +neesousunebonneetoile.ca, 1 +neet-investor.biz, 1 +neev.tech, 1 +neferlim.com, 1 +nefertitis.cz, 1 +neflabs.com, 1 +nefro-cme.de, 1 +nefthy.de, 1 +neftis.es, 1 +neg9.org, 0 +negai.moe, 0 +negardaroo.com, 1 +negativecurvature.net, 1 +negativeentropy.org, 1 +negativex.gq, 1 +neglecteddiseases.gov, 1 +negocios-imatore.com, 1 +negociosurbanos.net, 1 +negoya-shokai.info, 1 +negr.gay, 1 +negr.link, 1 +negr.tv, 1 +negrete.tk, 1 +negril.com, 0 +negroes.forsale, 1 +nehalem.gov, 1 +neheim-huesten.de, 1 +nehnutelnosti.io, 1 +nehoupat.cz, 1 +nehrp.gov, 1 +neht.xyz, 1 +nehta.gov.au, 1 +neide.ga, 1 +neighbor.co.il, 1 +neighborhoodelectricwa.com, 1 +neighborshop.de, 1 +neil-barrett.com, 1 +neil-barrett.uk, 1 +neildaniels.com, 1 +neilfarrington.com, 1 +neilhosting.net, 1 +neillans.co.uk, 1 +neillans.com, 1 +neilpatel.com, 1 +neilwynne.com, 1 +neimadtelliam.fr, 1 +neio.uk, 1 +neither-side-news.com, 1 +nejenpneu.cz, 1 +nejlevnejsi-parapety.cz, 1 +nejmaklerka.cz, 1 +nejrecept.cz, 1 +neko-nyan-nuko.com, 1 +neko-nyan.org, 1 +neko.am, 1 +nekoart.net, 1 +nekochan.blog, 1 +nekoku.io, 1 +nekolove.jp, 1 +nekomimi.pl, 1 +nekomimirouter.com, 1 +nekomio.com, 1 +nekondiciya.cf, 1 +nekorektni.cz, 1 +nekosc.com, 1 +nekox.ml, 1 +nekrasowsky.ml, 1 +nekretnine-lidl.hr, 1 +nekrylov.ee, 0 +nekrylov.org.ru, 0 +nekrylov.spb.ru, 0 +nekusoul.de, 1 +nelefon.com, 1 +nelegal-edition.tk, 1 +nelflex.com.br, 1 +nelhage.com, 1 +nella-project.org, 1 +nellacms.com, 1 +nellacms.org, 1 +nellafw.org, 1 +nellen.it, 1 +nellyarias.com, 1 +nellydallois.fr, 1 +nelnetbank.com, 1 +nelson-marine.com, 1 +nelsondiazrodriguez.tk, 1 +nelty.be, 1 +nemagiya.tk, 1 +nemberone.com, 1 +nemcd.com, 1 +nemecisolutions.com, 1 +nemecl.eu, 1 +nemesisenterprises.de, 1 +nemez.net, 1 +neminis.net, 1 +nemiroth.net, 1 +nemirow.tk, 1 +nemkoff.tk, 1 +nemo.run, 1 +nemopan.com, 1 +nemopret.dk, 1 +nemplex.com, 1 +nemplex.win, 0 +nemplex.xyz, 1 +nemsurvey.dk, 1 +nemumu.com, 1 +nemunai.re, 1 +nemzetizaszlok.hu, 1 +nenapu.tk, 1 +neneko.moe, 1 +nengzhen.com.cn, 1 +neniu.gr, 1 +nenkin-kikin.jp, 1 +neno.io, 1 +neo1.com, 1 +neo2k.dk, 1 +neo2shyalien.eu, 0 +neobits.nl, 1 +neoblog.tk, 1 +neocenter.org, 1 +neochan.net, 1 +neochan.ru, 1 +neocharge.net, 1 +neocities.org, 1 +neocyd.com, 1 +neodaedalus.com.au, 1 +neodigital.bg, 1 +neodrive.ch, 1 +neoedresources.org, 1 +neoeliteconsulting.com, 1 +neofilia.tk, 1 +neograftaustintx.com, 1 +neohu.com, 1 +neojo.org, 1 +neoko.fr, 1 +neokobe.city, 1 +neolaudia.es, 1 +neomodern.de, 1 +neonataleducationalresources.org, 1 +neonatalgoldenhours.org, 1 +neonfestival.net, 1 +neoni.me, 1 +neonknight.ch, 1 +neons.org, 1 +neophilus.net, 1 +neophotonics.com, 1 +neoreflex.nz, 1 +neos.co.jp, 1 +neosdesignstudio.co.uk, 1 +neoseo.com.ua, 1 +neostralis.com, 1 +neosys.com, 1 +neosys.eu, 1 +neotiv-care.com, 1 +neotiv.com, 1 +neotlojka25.ru, 1 +neotracker.io, 1 +neovapo.com, 1 +neoverso.tk, 1 +neowa.tk, 1 +neowin.net, 1 +neowlan.net, 1 +neoxcrf.com, 1 +neoz.com.br, 1 +nepal-evolution.org, 0 +nepal.ga, 1 +nepalese.tk, 1 +nepali-fonts.tk, 1 +nepalsnews.tk, 1 +nepdtp.in, 1 +nepezzano13.com, 1 +nephelion.org, 1 +nephology.net.au, 1 +nephos.xyz, 1 +nephrogo.com, 1 +nephrogo.lt, 1 +nephrolog.lt, 1 +nephy.jp, 1 +nepovolenainternetovahazardnihra.cz, 1 +nepozitkova.cz, 1 +neppglobal.top, 1 +nepremicninar.com, 1 +nepremicnine-lidl.si, 1 +nepremicnine.click, 1 +nepremicnine.net, 1 +neptun-rio.tk, 1 +neptuna.hu, 1 +neptuneliveaboards.com, 1 +neptunescubadiving.com, 1 +neptunosrefugio.tk, 1 +nerba.net, 1 +nerd.gallery, 1 +nerdaristocracy.com, 1 +nerdbox.cc, 1 +nerdca.st, 1 +nerdgift.ml, 1 +nerdherd.fun, 1 +nerdhouse.io, 1 +nerdin.space, 1 +nerdinator.ddns.net, 1 +nerdjokes.de, 1 +nerdmachina.com, 1 +nerdmind.de, 1 +nerdnet.goip.de, 1 +nerdoftheherd.com, 1 +nerdoutstudios.tv, 1 +nerdpol.ch, 1 +nerdpol.org, 1 +nerds-gegen-stephan.de, 1 +nerds.company, 0 +nerdsin.space, 1 +nerdsuits.tk, 1 +nerdwallet.com, 1 +nerdycharmer.com, 1 +nerdydev.net, 1 +nereustech.com, 1 +nerfroute.com, 1 +neriumrx.com, 1 +neropiceno.tk, 1 +neroshana.com, 1 +nerot.eu, 1 +nert.gq, 1 +nertus.ua, 1 +nerull7.info, 1 +nerv.com.au, 1 +nerven.se, 1 +nervi.ga, 1 +nes-watch.de, 1 +nesabamedia.com, 1 +nesbase.com, 1 +nesez.com, 1 +nesez.net, 1 +nesheims.com, 1 +nesheimswaterrestoration.com, 1 +neskins.com, 1 +nesolabs.com, 1 +nesolabs.de, 1 +ness.sh, 1 +nesscitycatholic.org, 1 +nestedquotes.ca, 0 +nesterov.pw, 1 +nestone.ru, 1 +nestor.nu, 1 +nestorgaleanomegamariachi.com, 1 +nestreeo.com, 1 +neswec.org.uk, 1 +net-combo-ja.com, 1 +net-investissement.fr, 1 +net-provider.cloud, 1 +net-safe.info, 1 +net-script.tk, 1 +netamia.com, 1 +netapps.de, 1 +netassessor.nl, 1 +netba.net, 1 +netbank.com.au, 1 +netbeacon.de, 1 +netbears.com, 1 +netbears.ro, 1 +netbeyond.de, 1 +netbows.com, 1 +netbows.es, 1 +netbox.org, 1 +netbrewventures.com, 1 +netbrief.ml, 1 +netbulls.io, 1 +netbuzz.ru, 1 +netcenteret.tk, 1 +netchameleon.com, 1 +netcials.in, 1 +netconnect.at, 1 +netcoolusers.org, 1 +netcrew.de, 1 +netculturejokes.tk, 1 +netd.at, 1 +netdego.jp, 1 +netdex.co, 1 +netdiode.com, 1 +netdiode.eu, 1 +netdiode.net, 1 +netdiode.org, 1 +netdisk.io, 1 +netdox.asia, 1 +netducks.com, 1 +netducks.space, 1 +netdude.tk, 1 +netelite.tk, 1 +netera.se, 1 +neteraser.de, 1 +netexem.com, 1 +netexpatcommunity.com, 0 +netfabb.com, 1 +netfeeds.eu, 1 +netferie.de, 1 +netferie.dk, 1 +netferie.no, 1 +netfirmtextile.com, 1 +netflixlife.com, 1 +netflowanalysissolution.com, 1 +netflowanalysissolutions.com, 1 +netflowcalculator.com, 1 +netflowcollector.com, 1 +netflowknight.com, 1 +netflowknights.com, 1 +netflowreplicator.com, 1 +netflowsword.com, 1 +netflowtoday.com, 1 +netflowtrafficanalysis.net, 1 +netfog.de, 1 +netfolio.pt, 1 +netfoundry.io, 1 +netframe.net, 1 +netfs.pl, 1 +netfuture.ch, 1 +netgaming.de, 1 +netgroupsa.com, 1 +netguide.co.nz, 1 +nethack.ninja, 1 +nethackwiki.com, 1 +nethask.ru, 1 +netheadsonair.com, 1 +nethealth.cf, 1 +nethealth.ga, 1 +nethealth.tk, 1 +nethlon.net, 1 +nethorizon.cn, 1 +nethostingtalk.com, 1 +nethound.ga, 1 +nethruster.com, 0 +nethui.nz, 1 +nethunter.top, 1 +netica.fr, 0 +netim.pl, 1 +netki.com, 1 +netkigestioncomercial.com, 1 +netkolik.org, 1 +netlentes.com.br, 1 +netletic.com, 1 +netlevel.ga, 1 +netlify.com, 1 +netliste.com, 1 +netlocal.ru, 1 +netmaddy.com, 1 +netmagicas.com.br, 1 +netmajstor.eu, 1 +netmania.tk, 1 +netmarvic.com, 1 +netmeister.org, 1 +netmouse.tk, 1 +netnea.com, 1 +netnik.de, 0 +netnodes.net, 1 +netoborona.tk, 1 +netolink.co.il, 1 +netolink.com, 1 +netolink.ru, 1 +netor.ga, 1 +netpenge.tk, 1 +netpreneur.co.za, 1 +netprofile.com.au, 0 +netrabota.tk, 1 +netracks.ga, 1 +netradyne.com, 1 +netraising.com, 0 +netreviews.tk, 1 +netrewrite.com, 1 +netrider.net.au, 0 +netrino.be, 1 +netrino.info, 1 +netrino.io, 1 +netrogue.ninja, 1 +netronix.be, 1 +netrustcontractor.com, 0 +netscaler.expert, 1 +netschool.tk, 1 +netsearch.ga, 1 +netsec.cloud, 1 +netsecma.com, 1 +netsite.dk, 1 +netslum.tk, 1 +netsoftit.com, 1 +netsoins.org, 1 +netsoj.nl, 1 +netsparker.com, 1 +netsparker.com.tr, 1 +netspeedia.net, 1 +netsphere.cloud, 1 +netsphere.cz, 1 +netsyms.com, 1 +netsys.com.tr, 1 +netsystems.pro, 1 +nettamente.com, 1 +nette.org, 1 +nettegeschenke.de, 1 +nettgiro.no, 1 +netthier.net, 1 +nettia.fi, 1 +nettiger.tk, 1 +nettilamppu.fi, 1 +netto-service.ch, 0 +nettools.link, 1 +nettoyage.email, 1 +nettruepro.com, 1 +nettx.co.uk, 1 +netube.org, 1 +netulo.com, 1 +netvizura.co.uk, 1 +netvpn.ml, 1 +netvpn.net, 1 +netwaf.com, 1 +netwarc.eu, 1 +netwarc.nl, 1 +netweaver.uk, 1 +netwerkmanager.nl, 0 +netwiseprofits.com, 1 +networg.com, 1 +networg.cz, 1 +networg.pl, 1 +network-midlands.co.uk, 1 +network-midlands.uk, 1 +network-notes.com, 0 +network.ae, 1 +network23.nl, 1 +networkarena.tk, 1 +networkdiode.com, 1 +networkdiode.eu, 1 +networkdiode.net, 1 +networkdiode.org, 1 +networker.dk, 1 +networkersdiary.com, 1 +networking-groups.co.uk, 1 +networking4all.com, 1 +networkingnexus.net, 1 +networkingphoenix.com, 1 +networkinternetmonitor.com, 1 +networkmas.com, 1 +networkmidlands.co.uk, 1 +networkmidlands.uk, 1 +networkmon.net, 1 +networkofarts.com, 1 +networkperformancemonitoring.net, 1 +networkposting.com, 1 +networksecuritysolutions.info, 1 +networksolutionsconsultant.com, 1 +networkthreatdetection.com, 1 +networkthreatprotection.com, 1 +networktools.tk, 1 +networktrafficanalysis.net, 1 +networktrafficanalyzer.net, 1 +networktrafficmonitoring.net, 1 +networkuser.de, 1 +networth.at, 1 +networx-online.de, 1 +netz0.com, 1 +netzabfragen.de, 1 +netzer-stuttgart.de, 1 +netzer.ml, 1 +netzfabrik.com, 1 +netzfrauen.org, 1 +netzklad.de, 1 +netzona.org, 1 +netzspielplatz.de, 0 +netzsv.website, 1 +netzvieh.de, 1 +netzwerk-lq.com, 1 +netzwerk-sozialliberal.de, 1 +netzwerkwerk.de, 1 +neuber.uno, 1 +neuch.info, 0 +neuelandschaft-welzow.de, 1 +neuflizeobc.net, 1 +neuhaus-city.de, 1 +neumarkcb.com, 1 +neurabyte.com, 1 +neuraforce.com, 1 +neuraforce.de, 1 +neuraforce.eu, 1 +neuraforce.net, 1 +neuraspike.com, 1 +neurexcellence.com, 1 +neurobiology.com, 1 +neurochip.com, 1 +neurocny.cloud, 1 +neurococi.ro, 1 +neurolab.no, 1 +neurologysantamonica.com, 1 +neurontinprice.ga, 1 +neuronus.com.br, 1 +neuropharmacology.com, 1 +neuropsychexams.com, 1 +neuropsychologisthouston.com, 1 +neurostimtms.com, 1 +neurosurgeryinmexico.com, 1 +neuroticosanonimos.tk, 1 +neurotransmitter.net, 1 +neurozentrum-zentralschweiz.ch, 1 +neustate.com, 1 +neutralox.com, 1 +neutron.ch, 1 +neuwal.com, 1 +nev.si, 1 +neva-star.ml, 1 +neva.li, 1 +nevadafiber.com, 1 +nevadafiber.net, 1 +nevalogic.com, 1 +nevam.cf, 1 +neve.in.ua, 1 +never-afk.de, 0 +never-more.tk, 1 +never.pet, 1 +nevergirl.tk, 1 +nevergreen.io, 1 +neverguess.ca, 1 +nevermore.fi, 1 +neverwasinparis.com, 1 +nevim-co-varit.cz, 1 +nevivur.net, 1 +nevntech.com, 1 +nevolution.me, 1 +nevoxo.com, 1 +nevrodiversitet.no, 1 +nevychova.cz, 1 +new, 1 +new-black-order.com, 1 +new-boiler-prices.co.uk, 1 +new-jersey-online-casinos.com, 1 +new-medic.com, 1 +new-ms.com, 1 +new-mvp.com, 1 +new-process.ch, 1 +new-process.com, 1 +new-process.de, 1 +new-process.eu, 1 +new-smile.cf, 1 +new-standart.tk, 1 +new-tuning.tk, 1 +new-vip.com, 1 +new-web-studio.com, 1 +new10.com, 1 +newagehoops.com, 1 +newantiagingcreams.com, 1 +newbackup.ml, 1 +newbasemedia.us, 1 +newbeginningsresale.com, 1 +newbernpost539.com, 1 +newberryfl.gov, 1 +newbies.tk, 1 +newbietech.cn, 0 +newblogr.com, 1 +newborncryptocoin.com, 1 +newbownerton.xyz, 1 +newbrest.tk, 1 +newbrunswick.today, 1 +newbrunswicktoday.com, 1 +newbuilding.tk, 1 +newburybouncycastles.co.uk, 1 +newburyparkelectric.com, 1 +newburyparkelectrical.com, 1 +newburyparkelectrician.com, 1 +newburyparkexteriorlighting.com, 1 +newburyparklandscapelighting.com, 1 +newburyparkoutdoorlighting.com, 1 +newcars.tk, 1 +newchance.store, 1 +newchoicesspb.ru, 1 +newcitygas.ca, 1 +newcityinfo.ch, 0 +newcityinfo.info, 1 +newcitystudio.ch, 0 +newconcept.tk, 1 +newcontext.com, 1 +newcreamforface.com, 1 +newday.host, 1 +newdenversurvivors.tk, 1 +newdimensioninterlock.com, 1 +newdirectionsolar.com.au, 1 +newearth.press, 1 +neweggsoft.org, 1 +newendsoft.com, 1 +newenglandradioforum.tk, 1 +newenglandworkinjury.com, 1 +neweratshirts.co.za, 1 +newfacialbeautycream.com, 1 +newfangledscoop.com, 1 +newfiepedia.ca, 1 +newflavor.design, 1 +newflora.ru, 1 +newfordmustang.com.au, 1 +newforex.ml, 1 +newforms.nl, 1 +newfoundland-labradorflora.ca, 1 +newgle.xyz, 1 +newgrowbook.com, 1 +newguidance.ch, 0 +newhamyoungbloods.co.uk, 1 +newhomedesign.tk, 1 +newhope.org.au, 1 +newhopeofindiana.org, 1 +newillusion.tk, 1 +newind.info, 1 +newinf.at, 1 +newinternet.media, 1 +newizv.ru, 0 +newjerseyvideography.com, 1 +newjianzhi.com, 1 +newknd.com, 1 +newlegalsteroid.com, 1 +newlifehempoil.com, 1 +newlight.net.br, 1 +newlovers.ga, 1 +newlovers.gq, 1 +newlynamed.com, 1 +newlytricks.ml, 1 +newmarketbouncycastlehire.co.uk, 1 +newmatworld.com, 1 +newmed.com.br, 1 +newmediaone.net, 1 +newmeproducts.com, 1 +newmusic.org, 1 +newmusicjackson.org, 1 +newmuslims.tk, 1 +newodesign.com, 1 +neworiflame.tk, 1 +newparadigmventures.net, 0 +newparrot.tk, 1 +newposts.ru, 1 +newpress24.tk, 1 +newquilters.com, 1 +newreleases.io, 1 +newreop.com, 1 +news-big.com, 1 +news-club.tk, 1 +news-novoros.cf, 1 +news-of-russia.gq, 1 +news-police.tk, 1 +news-srilanka.tk, 1 +news-sy.cf, 1 +news-technology.ml, 1 +news-trendlab.com, 1 +news-zp.tk, 1 +news.mc, 1 +news123.ga, 1 +news12elite.tk, 1 +news17.tk, 1 +news24rus.tk, 1 +news29.tk, 1 +news47ell.com, 1 +news53today.tk, 1 +news54.tk, 1 +news60.tk, 1 +news89.cf, 1 +news89.gq, 1 +newsa2.com, 1 +newsall.gr, 1 +newsarmenia.tk, 1 +newsarticle.ml, 1 +newsasia7.com, 1 +newsbali.tk, 1 +newsbay.gr, 1 +newsbomba.ml, 1 +newsbusiness.cf, 1 +newsbytesapp.com, 1 +newscheck.tk, 1 +newscultural.tk, 1 +newsdiff.eu, 1 +newsdiff.nl, 1 +newsdiffs.eu, 1 +newserumforskin.com, 1 +newsforum.ml, 1 +newsforyou.cf, 1 +newsgroups.io, 1 +newsgrowing.com, 1 +newshell.it, 1 +newshome.tk, 1 +newshour.media, 1 +newsinfo71.com, 1 +newsinformer.ga, 1 +newsinkansas.ml, 1 +newsinpolitics.ga, 1 +newsireland.tk, 1 +newslanka.tk, 1 +newsletteralerts.com, 1 +newsletters.gq, 1 +newsmotor.info, 1 +newsound.vn, 1 +newspaper-myapp.herokuapp.com, 1 +newspiritfilms.com, 1 +newspsychology.com, 1 +newsspotify.com, 1 +newstel.tk, 1 +newsthai.ml, 1 +newsticker.tk, 1 +newstone-tech.com, 1 +newstraveltoday.gq, 1 +newsuk.tk, 1 +newsunited.com, 1 +newsuzbekistan.tk, 1 +newsvideo.tk, 1 +newsvoice.com, 1 +newsworld247.tk, 1 +newsxp.tk, 1 +newsyclub.tk, 1 +newsyslog.org, 1 +newtambov.gq, 1 +newtambov.tk, 1 +newtekstil.ga, 1 +newtlgpacks.ml, 1 +newtnote.com, 1 +newtoncountymo.gov, 1 +newtonhaus.com, 1 +newtons-erben.space, 1 +newtrackon.com, 1 +newtravelplans.com, 1 +newusatoday.ga, 1 +newvehicle.com, 1 +newway.ie, 1 +newwind.tk, 1 +newworldnewlife.tk, 1 +newxit.tk, 1 +newyearsdishes.tk, 1 +newyorkcardiac.com, 1 +newyorkcoffeejobs.com, 1 +newyorkhiltonmidtown.com, 1 +newyorkhipknee.com, 1 +newyorknews.tk, 1 +newyoushampoo.com, 1 +newzashitnik.tk, 1 +newzealandadventure.tk, 1 +nex.li, 1 +nex.sx, 1 +nexalis.co.za, 1 +nexcoda.io, 1 +nexd.com, 1 +nexgeneration-solutions.com, 1 +nexicafiles.com, 1 +nexiumgeneric.tk, 1 +nexlp.com, 1 +nexril.net, 0 +next-idea.co, 1 +next-log.ru, 0 +next-web.ad.jp, 0 +next24.io, 1 +next47.com, 1 +nextads.ch, 1 +nextalefieldrecording.com, 1 +nextbranders.com, 1 +nextcairn.com, 1 +nextcloud-miyamoto.spdns.org, 1 +nextcloud-server.spdns.de, 1 +nextcloud.at, 1 +nextcloud.com, 1 +nextcloud.de, 1 +nextcloud.nerdpol.ovh, 1 +nextcloud.org, 1 +nextclouddarwinkel.nl, 1 +nextcom.digital, 1 +nextend.net, 1 +nexter.cloud, 1 +nextevolution.co.uk, 1 +nextfm.tk, 1 +nextgen-life-insurance.com, 1 +nextgen-wealth.com, 1 +nextgen.sk, 1 +nextgensocialnetwork.com, 1 +nextgenthemes.com, 1 +nextgreatmess.com, 1 +nextiot.de, 1 +nextiva.com, 1 +nextlevel-it.co.uk, 1 +nextmbta.com, 1 +nextme.se, 1 +nextnely.com, 1 +nextnet.cc, 1 +nextos.com, 1 +nextpup.net, 1 +nextrasp.it, 1 +nextrec.site, 1 +nextrend.co, 1 +nextright.tk, 1 +nextsfd.co.uk, 1 +nextsound.tk, 1 +nextstart-staging.azurewebsites.net, 1 +nextstart.azurewebsites.net, 1 +nextstep-labs.gr, 1 +nextstepstudios.ga, 1 +nexttv.co.il, 1 +nextus.me, 1 +nextvery.com, 1 +nextvision.pt, 1 +nextwab.com, 1 +nexus-vienna.at, 1 +nexusbyte.de, 1 +nexussystems.tk, 1 +nexwebsites.com, 1 +nexxus-sistemas.net.br, 1 +nexzcore.com, 1 +neyer-lorenz.de, 1 +neyjens.com, 1 +nezis.tk, 1 +nezkakukec.si, 1 +nezrouge-est-vaudois.ch, 0 +nezrouge-geneve.ch, 0 +nf4.net, 1 +nf9q.com, 1 +nfam.de, 1 +nfcweb.de, 1 +nfe-elektro.de, 1 +nfir.nl, 1 +nfitraining.nl, 1 +nfl.ddns.net, 1 +nfl.dedyn.io, 1 +nfl.duckdns.org, 1 +nfl.zapto.org, 1 +nflchan.org, 1 +nflmocks.com, 1 +nfls.io, 1 +nflsic.org, 1 +nfltshirt.com, 1 +nfluence.io, 1 +nfluence.org, 1 +nforto.com, 1 +nframe.io, 1 +nfrost.me, 1 +nfsec.pl, 1 +ng-musique.com, 1 +ngarate.com, 1 +ngatikuri.tk, 1 +ngawa-avocat-paris.fr, 1 +ngc.gov, 0 +ngetik.id, 1 +nghe.net, 1 +ngi.eu, 0 +ngiemboon.net, 1 +nginx.io, 1 +nginxconfig.com, 1 +nginxtest.ml, 1 +nginxyii.tk, 1 +ngla.gov, 1 +ngmx.com, 1 +ngmx.net, 1 +ngmx.org, 1 +ngndn.jp, 1 +ngo-online.de, 1 +ngorod.tk, 1 +ngospelmedia.net, 1 +ngpest.com, 1 +nguoimuahangmy.com, 1 +nguru.net, 1 +ngutek.com, 1 +nguyencucthanh.com, 1 +nguyendiep.com, 1 +nguyenfamily.tk, 1 +nguyenminhhung.com, 1 +ngvf.de, 1 +ngx.hk, 1 +ngxpkg.com, 1 +nhakhoabella.com, 1 +nhakhoangocanh.net, 1 +nhanlucnhatban.com, 1 +nhaoi.com, 0 +nhasicuibap.com, 1 +nhatrang.tk, 1 +nhatrangbooks.com, 1 +nhbp-nsn.gov, 1 +nhccnews.org, 1 +nhchalton.com, 1 +nhdsilentheroes.org, 1 +nhglobalpartners.com, 1 +nhhoteljobs.nl, 1 +nhimf.org, 1 +nhnieuws.nl, 1 +nhome.ba, 1 +nhsinform.scot, 1 +nhsolutions.be, 0 +nhtsa.gov, 1 +nhv-vintagelemans.com, 1 +nhw.ovh, 1 +ni-mate.com, 1 +ni.sb, 1 +ni.search.yahoo.com, 0 +niadd.com, 1 +niagara.ru, 0 +niagarafalls.ca, 1 +niagaraschoice.org, 1 +niallator.com, 1 +niamniukas.lt, 1 +nianubo.net, 1 +nibadesign.nl, 1 +nibb13.tech, 0 +nibbler.ai, 1 +nibiru.com.uy, 1 +nibletllc.com, 1 +nibo.blog, 1 +nibouw.nl, 1 +nic.ads, 1 +nic.android, 1 +nic.app, 1 +nic.boo, 1 +nic.cal, 1 +nic.channel, 1 +nic.chrome, 1 +nic.dad, 1 +nic.day, 1 +nic.dclk, 1 +nic.dev, 1 +nic.docs, 1 +nic.drive, 1 +nic.eat, 1 +nic.esq, 1 +nic.fly, 1 +nic.foo, 1 +nic.gbiz, 1 +nic.gle, 1 +nic.gmail, 1 +nic.goog, 1 +nic.google, 1 +nic.gov, 1 +nic.guge, 1 +nic.hangout, 1 +nic.here, 1 +nic.how, 1 +nic.ing, 1 +nic.meet, 1 +nic.meme, 1 +nic.mov, 1 +nic.new, 1 +nic.nexus, 1 +nic.page, 1 +nic.play, 1 +nic.prod, 1 +nic.prof, 1 +nic.rsvp, 1 +nic.soy, 1 +nic.xn--q9jyb4c, 1 +nic.youtube, 1 +nic.zip, 1 +nic199.ru, 1 +nicaieri.ro, 1 +nicapollo.com, 1 +nicastrosalvatore.tk, 1 +nicat.cf, 1 +nicava.com.mx, 1 +nice-autosurf.com, 1 +nice-germany.tk, 1 +nice-links.tk, 1 +nice.ch, 1 +nice.com, 1 +niceb5y.net, 0 +nicecockb.ro, 1 +niceguyit.biz, 1 +nicekicks.com, 1 +nicesco.re, 1 +nicesleepo.com, 1 +nicestudio.co.il, 0 +nicesurf.tk, 1 +nicetaninaka.com, 1 +nicheosala.tk, 1 +nichesite.gq, 1 +nichi.co, 1 +nichijou.com, 1 +nicholasperkins.io, 1 +nicholasquigley.com, 1 +nicholasruddick.com, 1 +nicholaswilliams.net, 1 +nicht-blau.de, 1 +nichteinschalten.de, 0 +nichthelfer.de, 1 +nichya.tk, 1 +nichyaforum.tk, 1 +nicic.gov, 1 +niciunde.ro, 1 +nick-black.com, 1 +nick-slowinski.de, 1 +nickcleans.co.uk, 1 +nickcraver.com, 1 +nickdekruijk.nl, 1 +nickfoerster.io, 1 +nickfrost.rocks, 1 +nickgenom.com, 1 +nickguyver.com, 1 +nickhitch.co.uk, 1 +nickhowell.co.uk, 0 +nickkallis.com, 1 +nicklazarov.com, 1 +nickloose.de, 1 +nickmandler.tk, 1 +nickmchardy.com, 1 +nickmiller.ie, 1 +nickmorri.com, 0 +nickmorris.name, 0 +nickoticko.tk, 1 +nickplotnek.co.uk, 1 +nickrickard.co.uk, 1 +nickrickard.uk, 1 +nicks-autos.com, 1 +nickscomputers.nl, 1 +nickserv.eu, 1 +nickserve.com, 1 +nickserve.eu, 1 +nickserve.net, 1 +nickserve.nl, 1 +nickserve.org, 1 +nickstories.de, 1 +nicktheitguy.com, 1 +nickwasused.de, 1 +nickwasused.ga, 1 +nickwasused.gq, 1 +nickymoore.com, 1 +nicn.me, 1 +nico.st, 1 +nicochinese.com, 1 +nicoknibbe.nl, 1 +nicola-bertini.com, 1 +nicoladixonrealestate.com, 1 +nicolaeiotcu.ro, 1 +nicolaiteglskov.dk, 1 +nicolajanedesigns.co.uk, 1 +nicolaottomano.it, 1 +nicolas-dumermuth.com, 1 +nicolas-hoffmann.net, 0 +nicolas-hoizey.com, 1 +nicolas-simond.ch, 1 +nicolas-simond.com, 1 +nicolasfriedli.ch, 0 +nicolasiung.me, 1 +nicolaszambetti.ch, 1 +nicolaw.uk, 1 +nicolemathew.com, 1 +nicoleta-prestescu.tk, 1 +nicolettajennings.com, 1 +niconico.ooo, 1 +niconode.com, 0 +nicoobank.com, 1 +nicoobook.net, 1 +nicorevin.ru, 1 +nicsezcheckfbi.gov, 1 +nicul.in, 1 +nidhoeggr.duckdns.org, 1 +nidialozano.com, 1 +nidosi.nu, 1 +nidro.de, 1 +nidsuber.ch, 1 +niduxcomercial.com, 1 +niederalt.com, 1 +niederohmig.de, 1 +niekbrekelmans.nl, 1 +niels-modeltog.tk, 1 +nielsbohr.ai, 1 +niemaler.de, 1 +niemandmussirgendwas.de, 1 +nien.cf, 1 +nien.co, 1 +nien.com, 1 +nien.eu.org, 1 +nien.gq, 1 +nien.org, 1 +nien.taipei, 1 +nien.tk, 1 +nienfun.com, 1 +nienkeslop.nl, 1 +nierenpraxis-dr-merkel.de, 1 +nierenpraxis-merkel.de, 1 +nierha.us, 1 +niers.land, 1 +nieselregen.com, 1 +niess.space, 1 +niesstar.com, 0 +nietmvwoensel.com, 1 +nietvolgensdeboekjes.nl, 1 +nietzsche.com, 1 +nieuwebroek.com, 1 +nieuwebroek.nl, 1 +nieuwpoort.tk, 1 +nieuwsberichten.eu, 1 +nieuwsfiets.nu, 1 +nieuwslagmaat.nl, 1 +nifc.gov, 1 +niffler.software, 1 +niftiestsoftware.com, 1 +nifume.com, 1 +nigelvm.com, 1 +nigelvm.email, 1 +nigensha.co.jp, 1 +nigeriaimagefoundation.org, 1 +nigeriaportal.tk, 1 +nigger.racing, 1 +niggo.eu, 1 +night2stay.cn, 1 +night2stay.de, 1 +night2stay.fr, 1 +night2stay.ru, 1 +nightblue.tk, 1 +nightbox.cf, 1 +nightbura.biz, 1 +nightdreamer.me, 1 +nightfirec.at, 1 +nightfirecat.com, 1 +nighthawkstrategies.com, 1 +nightkiss66.org, 1 +nightline.ie, 0 +nightmareabyss.top, 0 +nightmarejoker2.com, 1 +nightmoose.org, 1 +nightoutrecords.tk, 1 +nightscapesoutdoorlighting.com, 1 +nightsi.de, 1 +nightstand.io, 1 +nightstar-online.tk, 1 +nightwinds.tk, 1 +nightwishchile.tk, 1 +nightwood.cf, 1 +nigmapictures.tk, 1 +nihaarpstars.com, 1 +nihad.dk, 1 +nihaoonline.tk, 1 +nihilistan.tk, 1 +nihilocomunidad.tk, 1 +nihon-rosoku.com, 1 +nihseniorhealth.gov, 0 +nihtek.in, 1 +nii2.org, 1 +niinaratsula.com, 1 +niituva.ga, 1 +nij.gov, 1 +nijiero-ch.com, 0 +nijikata.com, 1 +nijimama-life.com, 1 +nijm.nl, 1 +nijniy-novgorod.tk, 1 +nijzoon.nl, 1 +nika-travel.ga, 1 +nikahplus.com, 1 +nikahsekeri.tk, 1 +nikandcara.com, 1 +nikant.tk, 1 +nikavandenbos.nl, 1 +nikcub.com, 0 +nikelunartw.net, 1 +nikesoccerbodotoutlet.ga, 1 +nikest.tk, 1 +nikhilnimiya.love, 1 +nikhilramakrishnan.tk, 1 +nikimix.com, 0 +nikitenko.tk, 1 +nikitina.ml, 1 +nikkasystems.com, 1 +nikksno.io, 1 +niklas.pw, 1 +niklasbabel.com, 1 +niklasstinkt.com, 1 +niko-mapping-studio.tk, 1 +niko-vfx.com, 0 +nikolahost.tk, 1 +nikolai-schmidt.tk, 1 +nikolaj-platoshkin.cf, 1 +nikolasbradshaw.com, 1 +nikomo.fi, 0 +nikonlibrary.co.uk, 1 +nikonnps.co.uk, 1 +nikosoikonomopoulos.tk, 1 +nikosverths.tk, 1 +nikscloud.eu, 1 +nikz.in, 1 +nil.gs, 0 +nil.mx, 1 +nilab.ru, 1 +nilahue.com, 1 +nilefi.cf, 1 +niles-simmons.de, 1 +niles.xyz, 1 +nilgirispice.co.uk, 1 +nilianwo.com, 1 +nilmaracursos.com.br, 1 +nilmaraquintela.com.br, 1 +nilosoft.com, 1 +niloxy.com, 1 +nilpointer.com, 1 +nilrem.org, 0 +nils.ch, 1 +nilsanenglish.com, 1 +nimanranch.com, 1 +nimbl.nz, 1 +nimble.com.br, 1 +nimbo.com.au, 1 +nimbus-net.tk, 1 +nimelainsurance.com, 1 +nimfomanki.tk, 1 +nimidam.com, 1 +nimiedad.com, 1 +nimnordic.com, 1 +nimus.tk, 1 +nina-woerz.tk, 1 +ninaafenehjelm.com, 1 +ninadevil.org, 1 +ninaforever.com, 1 +ninasofian.ro, 1 +ninaundandre.de, 1 +ninchat.com, 1 +nine-hells.net, 1 +ninebennink.com, 0 +ninedaysmore.tk, 1 +ninepints.co, 1 +ninesix.cc, 1 +ninespec.com, 1 +ninetailed.ninja, 1 +ninetaillabs.com, 1 +ninetaillabs.xyz, 1 +nineteensixtyone.co.uk, 1 +ninetyseven.tk, 1 +ninfora.com, 1 +ningbo.co.uk, 1 +ningrui.me, 0 +ningwei.net, 1 +niniko.tk, 1 +ninja-corner.tk, 1 +ninjacomputing.com, 1 +ninjan.co, 1 +ninjasproxy.com, 1 +ninjasquad.fr, 1 +ninjaworld.co.uk, 1 +ninkt.com, 1 +ninmegam.gq, 1 +ninofink.com, 1 +ninpang.com, 1 +ninreiei.jp, 1 +ninsin-akachan.com, 1 +nintendocarddelivery.com, 1 +nintendocollectionsystem.com, 1 +nintendohill.com, 1 +nintendoreporters.com, 1 +ninth.cat, 1 +ninthfloor.org, 1 +ninux.ch, 0 +ninverse.com, 1 +niourk.com, 1 +nipax.cz, 1 +nipe-systems.de, 1 +nipit.biz, 1 +nippangift.com, 1 +nippel.tk, 1 +nipplefucking.com, 1 +nipponkempoph.tk, 1 +nipponnews.tk, 1 +nipponprinting.co.jp, 1 +niqex.com, 1 +nirada.info, 1 +nirhub.ru, 1 +nirjonmela.com, 1 +nirjonmela.net, 1 +nirmalroy.ml, 1 +nirudo.me, 1 +nirvana-esport.fr, 1 +nirvanashop.com, 1 +niscemi.tk, 1 +nishikino-maki.com, 1 +nishimebistro.cz, 1 +nishisbma.com, 1 +nishiwaki-shonaifoods.com, 1 +nishiyama-shoten.com, 1 +nissanofbismarckparts.com, 1 +nisselrooij.nl, 1 +nist.tech, 1 +nistorvictor.software, 1 +nitaonline.org, 1 +nitecore.ga, 1 +nitifilter.com, 1 +nitinpandey.info, 1 +nitix.games, 1 +nitrix.me, 1 +nitrocloud.ddns.net, 1 +nitrohorse.com, 0 +nitrokey.com, 1 +nitropanel.com, 1 +nitropur.com, 1 +nitropur.de, 1 +nitrous-networks.com, 1 +nitschinger.at, 1 +niunaimilk.cn, 1 +nivalandemarit.fi, 1 +nivarussia.ml, 1 +nivel03.com, 1 +nivelul2.ro, 1 +nivoit.cf, 1 +nix-sender.com, 1 +nix-sender.ru, 1 +nix.org.ua, 0 +nix13.xyz, 1 +nixcore.gq, 1 +nixcp.com, 1 +nixnet.email, 1 +nixnet.services, 1 +nixnetmail.com, 1 +nixonlibrary.gov, 1 +nixops.me, 1 +nixplus.tk, 1 +nixram.com, 1 +nixrepair.nl, 1 +nixtest.net, 1 +nixval.com, 1 +nixx-gel.cz, 1 +nixxin.tk, 1 +niyawe.de, 1 +niyazpoyilan.com, 0 +niyen.com, 1 +niyen.eu, 1 +niyen.net, 1 +niyen.org, 1 +nizhaoheng.com, 1 +nizozemsku.nl, 1 +nja.id.au, 1 +njast.net, 1 +njbr.ml, 1 +njbr.tk, 1 +njcareers.org, 1 +njhq.org, 1 +njilc.com, 1 +njleg.gov, 1 +njliner.me, 1 +njngroup.org, 1 +njpjanssen.nl, 1 +nk-vision.com, 1 +nk1.de, 1 +nkapliev.org, 1 +nkbwnx.com, 1 +nkinka.de, 1 +nkjwmn.com, 1 +nkjwrs.com, 1 +nklwhx.com, 1 +nko.org, 1 +nkontur.com, 1 +nkorolev.tk, 1 +nkp-media.de, 1 +nkp.bg, 1 +nksky.cn, 1 +nksmart.ru, 1 +nktsee.com, 1 +nkvd-farm.ru, 1 +nkx4sjyrk4tcv0sluhwajyc-n6icja9gchqxmhp.com, 0 +nl-comunistas.tk, 1 +nl-ix.net, 1 +nl.search.yahoo.com, 0 +nl3ehv.nl, 1 +nlagstage.in, 1 +nlap.ca, 0 +nlc-business.com, 1 +nlc.org.au, 1 +nlivestream.com, 1 +nllboard.co.uk, 1 +nlleisure.co.uk, 1 +nlm.gov, 1 +nlpdiscovery.ro, 1 +nlponline.com.ua, 1 +nlucon.com, 1 +nm.cx, 1 +nm2d.nl, 1 +nmb.gov, 1 +nmcep.net, 1 +nmd.so, 1 +nmegent.be, 1 +nmfinanciallaw.com, 1 +nmmlp.org, 1 +nmnd.de, 1 +nmontag.com, 1 +nms-thoracic-surgery.com, 1 +nmu.university, 1 +nmx.moe, 1 +nn-vol.ga, 1 +nn.cz, 1 +nn0.net, 1 +nn01.cc, 1 +nn01.com, 1 +nn5197.co, 1 +nn6729.co, 1 +nn6729.com, 1 +nn6957.co, 1 +nn9297.co, 1 +nn9397.com, 1 +nn9721.com, 1 +nn9728.co, 1 +nna774.net, 1 +nndfn.com, 1 +nnews.tk, 1 +nnkkserver02.ddns.net, 1 +nnnow.com, 1 +nnov.ru, 0 +nnsa-ecp.org, 1 +no-andishan.ir, 1 +no-data.tk, 1 +no-ice.be, 1 +no-ice.nl, 1 +no-ip.cz, 1 +no-more-gray-hair.ga, 1 +no-real.tk, 1 +no-terrorism.tk, 1 +no-war-on-iraq.tk, 1 +no-xice.com, 0 +no.search.yahoo.com, 0 +noaccess.tk, 1 +noachgilor.co.il, 1 +noagendahr.org, 1 +noah-witt.com, 1 +noahjacobson.com, 1 +noahmodas.com.br, 1 +noahsaso.com, 1 +noahwitt.me, 1 +noart.tk, 1 +noatec.eu, 1 +noawildschut.com, 1 +nob.ro, 1 +nobasico.com.br, 1 +nobilefoods.com, 1 +nobitex.net, 1 +noble-diagnostic.com, 1 +nobledust.com, 1 +nobleparkapartments.com.au, 1 +noblesmart.com, 1 +nobly.de, 1 +nobodyplex.gq, 0 +nobreaks.ca, 1 +noc.org, 1 +noc.wang, 1 +nocit.dk, 1 +nocks.com, 1 +noclegiwchecinach.pl, 1 +nocloud.website, 1 +noco.nl, 1 +nocoffeetech.de, 1 +nocommentsallowed.com, 1 +nocrm.io, 1 +noctinus.tk, 1 +noctisphoto.tk, 1 +nocturnos.tk, 1 +nocturnus.tk, 1 +nodde.cf, 1 +nodecdn.net, 1 +nodecraft.com, 1 +nodeedge.com, 1 +nodefoo.com, 1 +nodegalaxy.com, 1 +nodejs.de, 1 +nodelab-it.de, 1 +nodelia.com, 1 +nodepositcasinouk.com, 1 +nodesonic.com, 1 +nodespin.com, 1 +nodi.at, 0 +nodi.cloud, 1 +nodist.club, 1 +nodl.cloud, 1 +noedidacticos.com, 1 +noel.wf, 1 +noel.yt, 1 +noelblog.ga, 1 +noellabo.jp, 1 +noematic.space, 1 +noemax.com, 1 +noeontheend.com, 1 +noexec.org, 1 +noez.de, 1 +nofrillsdns.com, 1 +noga4you.de, 1 +nogerondier.eu, 1 +nogetime.com, 1 +nogfw.org, 1 +nogfw.pro, 1 +nogfwsite.com, 1 +noggalito.com, 1 +nogradhont.hu, 1 +nohats.ca, 1 +nohkan.fr, 0 +nohm.eu, 1 +nohttps.org, 1 +nohungerfoodbank.org, 1 +nohup.se, 1 +nohup.xyz, 1 +noideas.tk, 1 +noiglosujemy.com.pl, 1 +noiglosujemy.pl, 1 +noincludesubdomains.preloaded.test, 0 +noirpvp.com, 1 +noiseandheat.com, 1 +noisebridge.social, 1 +noisetrap.cz, 1 +noisky.cn, 0 +noisyfox.cn, 1 +noisyfox.io, 1 +noites.pt, 1 +noj.ac, 1 +nojok.es, 1 +nokia.la, 1 +noknow.ovh, 1 +nokono.com, 1 +noktadedektor.com, 1 +noktadetectors.com, 1 +noktaradyo.com, 1 +nokumbaya.com, 1 +nokya.tk, 1 +nokzedoc.tv, 1 +nolaautomotiverepairs.com, 1 +nolakitchen.com, 1 +nolanpowellisaho.com, 1 +nolanvilletx.gov, 1 +nolatepayments.com, 1 +nolaviz.org, 1 +noleggio-bagni-chimici.it, 1 +noleggiobagnichimici.perugia.it, 1 +noleggioimbarcazioni.it, 1 +noleggiolimousine.roma.it, 1 +nolinobaby.pl, 1 +nolische.com, 1 +nolte-tver.ru, 1 +nolz.cloud, 1 +noma-film.com, 1 +nomadaregalos.com, 1 +nomadese.com, 1 +nomadichome.com, 1 +nomadichome.org, 1 +nomadichomes.com, 1 +nomadichomes.org, 1 +nomadiclifes.com, 1 +nomadicrootsco.com, 1 +nomadlist.com, 1 +nomadproject.io, 0 +nomagic.software, 1 +nomaster.cc, 1 +nomenclator.org, 1 +nomesbiblicos.com, 1 +nomial.co.uk, 1 +nomifensine.com, 1 +nomik.xyz, 1 +nomio.com, 1 +nomo.my, 1 +nomoondev.azurewebsites.net, 1 +nomsing.tk, 1 +nomsy.net, 1 +nomzamo.spdns.org, 1 +non0.com, 1 +noname-ev.de, 1 +nonametheme.com, 1 +noncombatant.org, 1 +nonemail.ch, 1 +nonemu.ninja, 1 +nonglamfarm.vn, 1 +nonobstant.cafe, 1 +nonomnismoriar.com.pl, 1 +nonprofit.info, 1 +nonsa.pl, 1 +nonsense.fyi, 1 +nonstopjob.ga, 1 +nontonfilem.ml, 1 +nonuplebroken.com, 1 +nonx.pro, 1 +nonxsistent.tk, 1 +nony.no, 1 +nonzero.io, 1 +noob-box.net, 1 +noob-rp.ru, 1 +nooben.com, 1 +noobit.org, 1 +noobow.me, 1 +noobsrus.co.uk, 1 +noobsunited.de, 1 +noobswhatelse.net, 1 +noobunbox.net, 1 +noodles.net.nz, 0 +noodles.wtf, 1 +noodplan.co.za, 1 +noodweer.be, 1 +noom.com, 1 +noomist.com, 1 +noon-entertainments.com, 1 +noonan.family, 1 +noonan.tech, 1 +nooneshere.co.uk, 1 +noop.ch, 1 +noop.com.au, 1 +noordsee.de, 1 +noordwesthoekrit.nl, 1 +noorsolidarity.com, 0 +noortronic.com, 1 +noosxe.com, 1 +nootroic.com, 0 +nootronerd.com, 1 +nootropic.com, 1 +nootropicpedia.com, 1 +noovell.com, 1 +nooverviewavailable.com, 1 +nopaincenter.ro, 1 +nopajam.tk, 1 +nopaste.eu, 1 +nopaste.xyz, 1 +nopaynocure.com, 1 +nophelet.com, 1 +nopm.xyz, 1 +nora.dog, 1 +norad.sytes.net, 1 +noradanismanlik.com, 1 +noradevot.com, 1 +noradrenalina.com, 1 +norala.tk, 1 +norbert-wollheim-platz.tk, 1 +norbertorabinovichblog.com, 1 +nord-sud.be, 1 +nordaccount.com, 1 +nordcheckout.com, 1 +nordcity.ga, 1 +norden.eu.org, 1 +nordesttrasporti.it, 1 +nordfinck.de, 1 +nordicess.dk, 1 +nordicirc.com, 1 +nordicportalen.tk, 1 +nordicsolutionsgroup.com, 1 +nordicsrit.tk, 1 +nordinfo.fi, 1 +nordiva.dk, 1 +nordlandverliebt.de, 1 +nordlichter-brv.de, 1 +nordlocker.com, 1 +nordmoregatebilklubb.com, 1 +nordnetz-hamburg.de, 1 +nordor.homeip.net, 1 +nordpass.asia, 1 +nordpass.com, 1 +nordsec.com, 1 +nordseeblicke.de, 1 +nordstromheating.com, 1 +nordtec.se, 1 +nordvestkysten.de, 1 +nordvestkysten.dk, 1 +nordvpn.com, 1 +nordvpnteams.com, 1 +nordwal.de, 1 +nordwaldzendo.de, 1 +noref.tk, 1 +noreply.mx, 1 +norfolkgardencare.co.uk, 1 +norichanmama.com, 1 +noriel.ro, 1 +noris.de, 0 +noriskit.nl, 1 +normaculta.com.br, 1 +normalady.com, 1 +normalized.ga, 1 +normalporter.tk, 1 +norman-legal.com, 1 +norman-preusser-gmbh.de, 1 +normanbauer.com, 1 +normandcyr.com, 1 +normandgascon.com, 1 +normandy.tk, 1 +normankranich.de, 1 +normanschwaneberg.de, 1 +normapro.es, 1 +norml.fr, 1 +norouzi-jeep.ir, 1 +norrishome.tk, 1 +norrkemi.se, 1 +norrlandsbilverkstad.se, 1 +norrliden.de, 1 +norsewars.com, 1 +norskpensjon.no, 1 +nortecompartidoexperience.es, 1 +nortecultural.tk, 1 +northampton-vets.co.uk, 1 +northatlantalaw.net, 1 +northbayvillage-fl.gov, 1 +northbengaltourism.com, 1 +northbrisbaneapartments.com.au, 1 +northcoastlabs.com, 1 +northconsulting.fr, 1 +northcountykiaparts.com, 1 +northcreekresort.com, 1 +northcreekresortblue.ca, 1 +northdakotahealthnetwork.com, 1 +northdevonbouncycastles.co.uk, 1 +northeastcdc.org, 1 +northeasternsportfishing.com, 1 +northebridge.com, 1 +northern-lakes.com, 1 +northerngate.net, 1 +northernhamsterclub.com, 1 +northernmuscle.ca, 1 +northernpowertrain.com, 1 +northernselfstorage.co.za, 1 +northfinance.dk, 1 +northflightaeromed.org, 1 +northhampton-nh-pd.gov, 1 +northkoreainsider.tk, 1 +northliner.tk, 1 +northoaksmn.gov, 1 +northokanaganbookkeeping.com, 1 +northpointoutdoors.com, 1 +northpole.dance, 1 +northpost.is, 1 +northridgeelectrical.com, 1 +northrose.net, 1 +northscottsdaleloan.com, 1 +northsegment.com, 1 +northstate.net, 1 +northtek.tk, 1 +northtexasvasectomy.com, 1 +northwest-events.co.uk, 1 +northwindfence.com, 1 +northwoodsfish.com, 1 +northwoodstudios.org, 1 +northzone.ml, 1 +norway.ml, 1 +norwestantennas.com.au, 1 +norwestpodiatry.co.nz, 1 +norys-escape.de, 1 +norzetto.com, 1 +nos-medias.fr, 1 +nos-oignons.net, 1 +nosacheva.ru, 1 +nosbenevolesontdutalent.com, 1 +noscript.net, 1 +noscura.nl, 1 +noseastumismo.com, 1 +nosecrets.ch, 1 +nosedoctor.net, 1 +nosfermiers.com, 1 +noslite.nl, 1 +nosmoking.tk, 1 +nosnik.dk, 1 +nosproduitsdequalite.fr, 1 +nossasenhora.net, 1 +nossasenhoradodesterro.com.br, 1 +nossasenhoradopranto.pt, 1 +nossorepresentante.com.br, 1 +nostalgicinfinity.tk, 1 +nostalgiktv.ml, 1 +nostalgimidi.se, 1 +nostalgische-attracties.nl, 1 +nostaljicicekcilik.com, 1 +nostoautomaatti.fi, 1 +nostosh.eu.org, 1 +nostradansacornella.tk, 1 +nostraforma.com, 0 +nosuch.blog, 1 +nosuch.site, 1 +nosuch.website, 1 +noswap.com, 1 +nosyu.pe.kr, 1 +not4me.ga, 1 +nota-web.com, 1 +nota.moe, 1 +notabug.org, 1 +notacooldomain.com, 1 +notadd.store, 1 +notallmine.net, 1 +notalone.gov, 1 +notar-glagowski.com, 1 +notar-glagowski.de, 1 +notar-peikert.com, 1 +notariat-tineretului.net, 1 +notariatpublic.com, 1 +notaries-europe.com, 1 +notariusz-bialystok.com, 1 +notariuszprzybylowicz.pl, 1 +notariuszsych.pl, 1 +notarkrauss.de, 1 +notary24.ru, 1 +notaryassistant.com, 1 +notbolaget.se, 1 +notboring.co.uk, 1 +notbot.es, 1 +notcompletelycorrect.com, 1 +notcurses.com, 1 +note.ms, 1 +note.wf, 1 +note64.com, 1 +note7forever.com, 1 +noteboat.net, 1 +notebrook.com, 1 +notecoffee.tw, 1 +notedinstyle.co.uk, 1 +notenarchiv.eu, 1 +notepad.nz, 1 +notepam.com, 1 +notequal.me, 1 +notesforpebble.com, 1 +noteskeeper.ru, 1 +notevencode.com, 1 +nothinbutnets.com, 1 +nothinfancy.ca, 1 +nothing.net.nz, 1 +nothing.org.uk, 1 +nothingwired.com, 1 +noticaballos.com, 1 +noticiaelmundo.com, 1 +noticiasdeautos.site, 1 +noticiasdetv.com, 1 +noticiasdocambio.com.br, 1 +noticiasymas.cl, 1 +noticies.tk, 1 +notificami.com, 1 +notifications.net, 1 +notigatos.es, 1 +notilus.fr, 1 +notilus.it, 1 +notime.tk, 1 +notimesupport.com, 1 +notinglife.com, 1 +notisec.hu, 1 +notisecit.hu, 1 +notizie.ai, 1 +notjustvacs.com, 1 +notliriklagu.com, 1 +notmybox.com, 1 +notmyserver.com, 0 +notnewz.tk, 1 +notnize.net, 1 +notnl.com, 1 +notofilia.com, 1 +notonprem.com, 1 +notora.tech, 1 +notoriousdev.com, 1 +nototema.com, 1 +notre-planete.info, 1 +notrefuse.tk, 1 +notrero13.com, 1 +notresiteduvercors.tk, 1 +notsafefor.work, 1 +nottres.com, 1 +notube.net, 1 +noty.tech, 1 +nou9ta.tk, 1 +noudjalink.nl, 1 +nougat-anduze.fr, 1 +noujoumtounes.com, 1 +nourishandnestle.com, 1 +nourishbyfrida.com, 1 +noussommesluniversite.org, 1 +noustique.com, 1 +noustramits.com, 1 +nousyukum.com, 1 +nouveauhosting.com.au, 1 +nouvelle.net.au, 1 +nova-dess.ch, 0 +nova-eq.com, 1 +nova-host.ml, 1 +nova-kultura.org, 1 +nova.live, 1 +nova.moe, 1 +novabench.com, 1 +novacleaning.ru, 1 +novacoaching.nl, 1 +novacoast.com, 1 +novadermis.es, 1 +novafreixo.pt, 1 +novak.cf, 1 +novalite.rs, 1 +novanetwork.ml, 1 +novapur.pl, 1 +novarock.tk, 1 +novascan.net, 1 +novasprint.tk, 1 +novawatch.de, 1 +novaway.ca, 1 +nove.city, 1 +noveciti.com, 1 +novecity.cloud, 1 +novecity.com, 1 +novecity.info, 1 +novecity.it, 1 +novecity.org, 1 +novecitymail.com, 1 +novel543.com, 1 +novelinglife.net, 0 +novelvyretraite.fr, 1 +novema.jp, 1 +novengi.mu, 1 +novenopiso.tk, 1 +novezamky.tk, 1 +novgorod24.tk, 1 +novgorodinfo.tk, 1 +novi.com, 1 +novicecamp.com, 1 +noviceman.tk, 1 +novichek-plus.ml, 1 +novichok.ml, 1 +novickoe.ml, 1 +novilaw.com, 1 +novilidery.com, 1 +novinivo.com, 1 +novinkihd.tk, 1 +novobi.com, 1 +novobudowa.pl, 1 +novodiegomaia.com.br, 1 +novogimn.tk, 1 +novogradnje.si, 1 +novojet.cl, 1 +novokurovka.tk, 1 +novokuznetsk.tk, 1 +novonegoc.io, 1 +novoodesabibl.tk, 1 +novopromo.ru, 1 +novoregalos.com, 1 +novoresume.com, 0 +novorossiysk.tk, 1 +novorussiya.tk, 1 +novosad-kom.tk, 1 +novosel.ga, 1 +novoselie.ga, 1 +novosti-novorossii.ml, 1 +novosti-novosibirsk.tk, 1 +novosti-online.tk, 1 +novosti-tv.tk, 1 +novostimira.gq, 1 +novostionline.tk, 1 +novostiz.tk, 1 +novostroyki.ml, 1 +novotoznanie.com, 1 +novsti.cf, 1 +novu.com, 1 +novurania.com, 1 +novye-kuhni.ml, 1 +novysvit.com.ua, 1 +now.sh, 1 +now101atm.tk, 1 +nowarning.cc, 1 +nowbb.tk, 1 +nowcomplete.com.br, 1 +nowebsite.tk, 1 +nowecor.de, 1 +noweigh.co.uk, 1 +nowhere.dk, 1 +nowitzki.me, 1 +nowitzki.network, 1 +nowlas.org, 0 +nowloading.co, 1 +nowloading.tk, 1 +nowremindme.com, 1 +nowtime.cc, 1 +nowzarimd.com, 1 +nowzuwan.org, 0 +noxi.ga, 1 +noxlogic.nl, 1 +noxomusic.com, 1 +noxx.global, 1 +noxx.solutions, 1 +noxx.uk, 1 +noydeen.com, 1 +noyocenter.org, 1 +nozaka-k.com, 1 +nozel.gq, 1 +np-edv.at, 1 +np.search.yahoo.com, 0 +np39.de, 1 +npaccel.com, 1 +npath.de, 1 +npbeta.com, 1 +npc-ts.org, 1 +npc.org.au, 1 +npcradio.tk, 1 +npcrcss.org, 1 +npdigital.com, 1 +npgateway.com, 1 +npgcdn.net, 1 +nphrm.com, 1 +npiconsultoria.com.br, 1 +npm.li, 1 +npmcdn.com, 1 +npool.org, 1 +npregion.org, 1 +npsas.org, 1 +nptn.tk, 1 +npu.best, 1 +npw.ca, 1 +nqeshreviewer.com, 1 +nr-sputnik.ru, 1 +nr1hosting.com, 1 +nrail.eu, 1 +nrbpublishing.com, 1 +nrd.gov, 1 +nrd.li, 1 +nrdigitalbranding.com, 1 +nrdstd.io, 1 +nrealsport.com, 1 +nrev.ch, 0 +nriol.net, 1 +nrkn.fr, 1 +nrm.co.nz, 1 +nrmc.pt, 1 +nrsmart.com, 1 +nrsweb.org, 1 +nrthcdn.me, 1 +nrv-linux.io, 1 +nrvc.net, 1 +nrvn.cc, 0 +nrvnastudios.com, 1 +ns2servers.pw, 1 +nsa.lol, 1 +nsa.ovh, 1 +nsadns.uk, 1 +nsamail.uk, 1 +nsapwn.com, 1 +nsbfalconacademy.org, 1 +nsboston.org, 1 +nsboutique.com, 1 +nscai.gov, 1 +nscnet.jp, 1 +nscondominios.pt, 1 +nsdcprayerforce.com, 1 +nsep.gov, 1 +nsfw-story.com, 1 +nshipster.cn, 1 +nshipster.co.kr, 1 +nshipster.com, 1 +nshipster.es, 1 +nsine.be, 1 +nsinternational.com, 1 +nsinternational.nl, 1 +nslacandelaria.com, 1 +nsm.ee, 1 +nsmail.cn, 1 +nsnsp.org, 1 +nso.ie, 1 +nsofficeinteriors.com, 1 +nsoft.nu, 1 +nsoiran.tk, 1 +nsopr.gov, 1 +nsopw.gov, 1 +nsp.com.ua, 1 +nsp.ua, 1 +nspawn.org, 1 +nspeaks.com, 1 +nspireoutreach.org, 0 +nsquaredong.com, 1 +nsradiology.net, 1 +nsrc.nz, 1 +nssfchile.tk, 1 +nst-maroc.com, 1 +nstatic.xyz, 1 +nstd.net, 1 +nstinvoiceqa.com, 1 +nstnet.org, 1 +nsu.pw, 1 +nsure.us, 1 +nsworks.com, 1 +nt-catala.com, 1 +ntags.org, 1 +ntcp.ph, 1 +nte.email, 1 +ntecha.com, 1 +ntechp.com, 1 +ntgltema.ml, 1 +ntgvision.com, 1 +nth.sh, 0 +nti.de, 1 +ntia.gov, 1 +ntlabs.org, 1 +ntotten.com, 1 +ntppool.org, 0 +ntut.net, 1 +ntx360grad-fallakte.de, 1 +ntzlaw.com, 1 +ntzwrk.org, 1 +nu-pogodi.net, 1 +nu-spine.com, 1 +nu3tion.com, 1 +nu3tion.cz, 1 +nu3vex.com, 1 +nuacht.ie, 1 +nualgiponds.com, 1 +nubehogar.nsupdate.info, 1 +nubilum.noip.me, 1 +nubium.net, 1 +nubu.at, 1 +nubunk.com.ng, 1 +nucameratoezicht.nl, 1 +nuclea.id, 0 +nuclea.site, 1 +nuclearcake.de, 1 +nuclearcat.com, 1 +nuclearforum.tk, 1 +nuclearhell.tk, 1 +nuclearnation.tk, 1 +nuclearsky.tk, 1 +nucleios.com, 1 +nucleosynth.space, 1 +nucleuscore.org, 1 +nucleuspanel.com, 1 +nudaveritas.tk, 1 +nudeandfresh.tk, 1 +nudel.ninja, 1 +nudes.ovh, 1 +nudevotion.com, 1 +nudge.ai, 1 +nuel.cl, 1 +nuestratecnologia.com, 1 +nuevacombarbala.tk, 1 +nuevaimagenpublicidad.es, 1 +nuffield.nl, 1 +nugdev.co, 0 +nuggit.ga, 1 +nugmanov.net, 1 +nugush.tk, 1 +nuipogoda.ru, 1 +nuitec.com.br, 1 +nuits-franciliennes.fr, 1 +nuke-masters.tk, 1 +nukeportal.ml, 1 +nukeportal.tk, 1 +nukeshop.tk, 1 +nukleosome.com, 1 +nukleoti.de, 1 +nukleovisual.com, 1 +null-d.com, 1 +null-life.com, 1 +nullbox.co, 1 +nulle-part.org, 1 +nulledme.ga, 1 +nulleds.tk, 1 +nullonerror.org, 1 +nullroute.com, 1 +nullscripts.tk, 1 +nullshare.tk, 1 +nulltime.net, 0 +nullxsec.net, 1 +nully.xyz, 1 +numancia.tk, 1 +numarasorgulama.tel, 1 +number.me, 1 +numbercult.net, 1 +numbermunchers.net, 1 +numberzero.org, 1 +numbrz.co.uk, 1 +numericall.gq, 1 +numerik-games.ch, 0 +numeritelefonici.it, 1 +numero-aleatorio.com, 1 +numero1.ch, 0 +numerologist.com, 1 +numerouno.ml, 1 +numismatica.info.ve, 0 +numismed-seniorcare.de, 1 +numista.com, 1 +numo.co, 1 +numwave.nl, 1 +nunesgh.com, 1 +nunnenmacher.net, 1 +nunnun.jp, 1 +nunoarruda.com, 1 +nunoefabia.tk, 1 +nunogand.com, 1 +nunoleiria.com, 1 +nunomoura.com, 1 +nunoprospero.com, 1 +nunsarean.tk, 1 +nuntiicaelo.in.ua, 1 +nuoha.com, 1 +nuos.org, 1 +nuovaelle.it, 1 +nuovicasino.it, 1 +nupef.org.br, 0 +nuquery.com, 1 +nuquery.org, 1 +nur.berlin, 1 +nureg.club, 1 +nureg.net, 1 +nureg.xyz, 1 +nuria-fergo.tk, 1 +nuriaamat.com, 1 +nuriacamaras.com, 1 +nurlyn.com, 0 +nursejj.com, 1 +nursemom.ca, 1 +nurseregistry.com, 1 +nurses.dating, 1 +nurshka.com, 1 +nursingschool.network, 1 +nursingschoolsnearme.com, 1 +nuryahan.com.br, 1 +nusaceningan.io, 1 +nusatrip-api.com, 1 +nussadoclub.org, 1 +nussschale.eu, 1 +nut-dev.com, 1 +nut.services, 1 +nutbot.co.uk, 1 +nutextonline.com, 1 +nutikell.com, 1 +nutleyarchives.org, 1 +nutleyeducationalfoundation.org, 1 +nutleyef.org, 1 +nutmeg.com, 1 +nutra-creations.com, 1 +nutradian.com, 1 +nutralivbio.com, 1 +nutrashop.fr, 1 +nutri-spec.me, 1 +nutriciametabolics-shop.de, 1 +nutriclub.co.id, 1 +nutridieta.com, 1 +nutrienti.eu, 1 +nutrifyyourself.com, 1 +nutrimedcn.com, 1 +nutrindoideias.com, 1 +nutripedia.gr, 1 +nutrishop.com, 1 +nutrisidangym.com, 1 +nutrislice.com, 1 +nutristories.gr, 1 +nutrition.gov, 1 +nutritionalsupplement.co.uk, 1 +nutritious.cf, 1 +nutrizionista.roma.it, 1 +nutsforfruits.com.au, 1 +nuus.hu, 1 +nuva.hu, 1 +nuvechtdal.nl, 1 +nuvini.com, 1 +nuxer.fr, 1 +nuzhenkredit.ga, 1 +nuzhenkredit.gq, 1 +nuzhenkredit.ml, 1 +nuzhenkredit.tk, 1 +nvcogct.gov, 1 +nve-qatar.com, 1 +nvfoundation.com, 1 +nvigate.gov, 1 +nvl-game.tokyo, 1 +nvlifeinsurance.info, 1 +nvlop.xyz, 0 +nvmo.org, 1 +nvoip.com.br, 1 +nvq.nl, 1 +nvr.bz, 1 +nvtc.gov, 1 +nwautorebuild.com, 1 +nwbc.gov, 0 +nwea.nl, 1 +nwerc.party, 1 +nwfdaz.gov, 1 +nwh.nz, 1 +nwimports.com, 1 +nwitt.us, 1 +nwk1.com, 1 +nwmd.nl, 0 +nwperformanceandoffroad.com, 1 +nwps.fi, 1 +nwra.com, 1 +nwradio.tk, 1 +nwshell.com, 1 +nwtrb.gov, 1 +nwuss.okinawa, 1 +nwwnetwork.net, 1 +nx42.pw, 1 +nxgn.io, 1 +nxinfo.ch, 0 +nxit.ca, 1 +nxlogis.kr, 1 +nxnt.link, 1 +nxtgenbroadband.in, 1 +nxtgensn.com, 1 +nxth.io, 1 +nya-cloud.com, 1 +nya.as, 1 +nya.one, 1 +nyaa.am, 1 +nyadora.com, 1 +nyadora.moe, 1 +nyamulab.net, 1 +nyan.it, 1 +nyan.kim, 1 +nyan.stream, 1 +nyan.to, 1 +nyangasm.com, 1 +nyangasm.net, 1 +nyangasm.org, 1 +nyanpasu.tv, 1 +nyansparkle.com, 1 +nyantec.com, 1 +nyatane.com, 1 +nyawork.com, 1 +nybcreative.com, 1 +nycdentalimplantscenter.com, 1 +nyconcretelifting.com, 1 +nycoyote.org, 1 +nycstyleboutique.com, 1 +nycu.moe, 1 +nydig.com, 1 +nyerjachioval.hu, 1 +nyerjakekszekkel.hu, 1 +nyerjamilkaval.hu, 1 +nyerjazoreoval.hu, 1 +nyerjenaheraval.hu, 1 +nyfurnitureoutlets.com, 1 +nyhaoyuan.net, 1 +nyhemsgarden.se, 1 +nyiarlumar.tk, 1 +nyip.co.uk, 1 +nylasercenter.com.pl, 1 +nylevemusic.com, 1 +nyliveauctions.com, 1 +nyloc.de, 1 +nylonfeetporn.com, 0 +nymphetomania.net, 1 +nyoka.io, 1 +nyoliveoil.com, 1 +nyphox.ovh, 1 +nyrany.online, 1 +nyronet.de, 0 +nysis.fr, 1 +nysis.net, 1 +nysis.org, 1 +nysteak5.com, 1 +nystrom.tk, 1 +nystudio107.com, 1 +nytrafficticket.com, 1 +nyyu.tk, 1 +nyzed.com, 1 +nzbr.de, 1 +nzelaweb.com, 1 +nzguns.co.nz, 1 +nzpost.ga, 1 +nzstudy.ac.nz, 1 +nzt.capital, 1 +nzt.co, 1 +nzt.dev, 1 +nzt.foundation, 1 +nzt.holdings, 1 +nzt.io, 1 +nzt.one, 1 +nzt.productions, 1 +nzt.properties, 1 +nzt.services, 1 +nzt.team, 1 +nzt.technology, 1 +nzt.tools, 1 +nzt.ventures, 1 +nztcap.com, 1 +nztcap.de, 1 +nztcapital.com, 1 +nztcapital.de, 1 +nztcapital.net, 1 +nztfoundation.com, 1 +nztholdings.com, 1 +nztproperties.com, 1 +nztservices.com, 1 +nzttechnology.com, 1 +nzttools.com, 1 +nzttools.net, 1 +nztventures.com, 1 +nztventures.de, 1 +nztventures.net, 1 +nzws.me, 0 +o-aconsult.com, 1 +o-bereg.ru, 1 +o-dvor.tk, 1 +o-results.ch, 1 +o-s.no, 1 +o-sp.com, 1 +o00228.com, 1 +o0c.cc, 1 +o15y.com, 1 +o2.tn, 1 +o2design.tk, 1 +o2ss.com, 1 +o3.wf, 1 +o30365.com, 1 +o36533.com, 1 +o3c.com.br, 1 +o3ptitschats.fr, 1 +o3wallet.com, 1 +o5.cx, 0 +o5.vc, 1 +o5197.co, 1 +o6729.co, 1 +o6729.com, 1 +o6957.co, 1 +o6asan.com, 1 +o81365.com, 1 +o82365.com, 1 +o8b.club, 1 +o9297.co, 1 +o9397.com, 1 +o9728.co, 1 +o98.com, 1 +o98.net, 1 +oacloud.nl, 1 +oadeo.com, 1 +oadpoaw.xyz, 1 +oahpmdata.net, 1 +oaic.gov.au, 1 +oakbarnvets.com, 1 +oakbarnwellness.com, 1 +oaken.duckdns.org, 1 +oakesfam.net, 1 +oakface.club, 1 +oakface.com.au, 1 +oakparkelectrical.com, 1 +oakparkexteriorlighting.com, 1 +oakparklandscapelighting.com, 1 +oakparklighting.com, 1 +oakparkmedicalcentre.ga, 1 +oakparkoutdoorlighting.com, 1 +oakridgeclinic.ca, 1 +oakshield.nl, 1 +oaktree-realtors.com, 1 +oaktreelodge.org.uk, 1 +oakwood-park.tk, 1 +oandareview.co, 1 +oapks.com, 1 +oase-fuer-wohlbefinden.ch, 1 +oasegroen.nl, 1 +oasiristorantebagno.it, 1 +oasis-conference.org.nz, 0 +oasis9.net, 1 +oasisbahamas.com, 1 +oasisbodycare.jp, 1 +oasisgenetics.com, 1 +oasiskitchens.com, 1 +oasisorthodontics.com.au, 1 +oatmealdome.me, 1 +oatycloud.spdns.de, 1 +oauth.how, 1 +oauthaccountmanager.googleapis.com, 1 +ob-salon.ru, 1 +obala.ga, 1 +obalky-obaly.sk, 1 +obamalibrary.gov, 1 +obamawhitehouse.gov, 1 +obamed.com, 1 +obasigeorge.com, 1 +obatjantungrematik.tk, 1 +obbr.tk, 1 +obcevents.co.uk, 1 +obclub.tk, 1 +obdchekautomotriz.co, 1 +obdinvest.ru, 1 +obdlink.com, 1 +obdolbacca.ru, 1 +obec-krakovany.cz, 1 +obecvinodol.tk, 1 +obed-doma.tk, 1 +oberam.de, 1 +obereg.ga, 1 +oberg.us, 1 +oberhofdrinks.com, 1 +oberhofjuice.com, 1 +obermeiers.eu, 1 +oberoi.de, 1 +obery.com, 1 +obesidadlavega.com, 1 +obet901vip.com, 1 +obfuscate.xyz, 1 +obg-global.com, 1 +obg.ceo, 1 +obgalslancaster.com, 1 +obgynecologistnyc.com, 1 +obgynmiamifl.com, 1 +obgynqueensnyc.com, 1 +obi-betriebsrat.tk, 1 +obioncountytn.gov, 1 +object.earth, 1 +objectif-securite.ch, 1 +objectif-terre.ch, 0 +objectif-vancouver-2010.fr, 1 +objectifs-fitness.com, 1 +objectorientedsolutions.com, 1 +objekt-textil.ch, 0 +objetodestaque.com.br, 1 +objexunlimited.com, 1 +oblast45.ru, 0 +obligacjekk.pl, 1 +oblik.pp.ua, 1 +oblik.press, 1 +oblinvest.org, 1 +oblitsov.ru, 1 +oblivious.ml, 1 +oblojka.tk, 1 +oblondata.io, 0 +obmen-viz.tk, 1 +obmen-vizitami.ml, 1 +obmenka.tk, 1 +obnalichka.ga, 1 +obnalichka.gq, 1 +obnalichka.tk, 1 +obocat.tk, 1 +obomne.tk, 1 +obozrevatel.tk, 1 +obra.com.br, 1 +obrabotka-zakazow.tk, 1 +obrasereformasbh.com.br, 1 +obrobka-zdjec.pl, 1 +obs.group, 1 +obs.plus, 1 +obscur.tk, 1 +obscur.us, 1 +obscureware.xyz, 1 +observass.com, 1 +observednews.com, 1 +observer.com, 1 +observer.name, 1 +obsessedwithknives.ru, 1 +obsessharness.com, 1 +obsessivecompulsiveexplained.com, 1 +obsidianirc.net, 1 +obsproject.com, 1 +obsuzhday.com, 1 +obsydian.org, 0 +obtima.org, 1 +obuchowicz.pl, 1 +obve.nl, 1 +obxlistings.com, 1 +obyvateleceska.cz, 1 +obzor-znakomstv.tk, 1 +obzory-evgeny.tk, 1 +oc-minecraft.com, 1 +oc-sa.ch, 0 +ocad.com.au, 1 +ocalaflwomenshealth.com, 1 +ocalculator.com, 1 +ocapic.com, 1 +ocarupo.com, 1 +ocasio.es, 1 +ocastrowork.com, 1 +occ.gov, 1 +occasion-impro.com, 1 +occenterprises.org, 1 +occentus.net, 1 +occult-magick.gq, 1 +occult-magick.ml, 1 +occultism.tk, 1 +occultisme.tk, 1 +occultumproductions.tk, 1 +occupational-therapy-colleges.com, 1 +occupations.org.ru, 1 +occupybakersfield.tk, 1 +occupymedia.org, 1 +ocd2016.com, 1 +ocdadmin.com, 1 +ocdhub.co.za, 1 +ocean-of-love.ml, 1 +oceanborn.tk, 1 +oceanbreezehomes.com, 1 +oceancore.ru, 1 +oceancrew.org, 1 +oceandns.eu, 1 +oceandns.net, 1 +oceandns.nl, 1 +oceane.training, 1 +oceaniahome.tk, 1 +oceanings.com, 1 +oceanlogisticgroup.com, 1 +oceanlord.me, 1 +oceanofapk.com, 1 +oceanofpdf.com, 1 +oceanshaman.cf, 1 +oceanspraymiami.com, 1 +oceanspringsarchives.net, 1 +oceansurplus.tk, 1 +oceanviewde.gov, 1 +oceanvisuals.com, 1 +ocenka-nedv.ml, 1 +ocenka.tk, 1 +ocenovani-inspekce.cz, 1 +ocf.io, 1 +ocg-card.com, 1 +ochki-linzi.tk, 1 +ochrebridge.com, 1 +ochrepoint.com.au, 1 +ochsenfeld.co, 1 +ochsundjunior.ch, 1 +ochsundjunior.swiss, 1 +ociaw.com, 1 +ocim.ch, 0 +ocimumcdn.net, 1 +ockendenhemming.co.uk, 1 +oclausen.com, 1 +ocloud.fr, 1 +ocloudhost.com, 1 +ocmwgent.be, 1 +ocni-ambulance-most.cz, 1 +ocnjapartment.com, 1 +ocodo.ru, 1 +ocolere.ch, 1 +ocongo.com, 1 +ocotg.com, 1 +ocponj.gov, 1 +ocrn.nl, 1 +ocsamochodu.pl, 1 +ocsan.gov, 1 +octagon.institute, 1 +octane.net.au, 1 +octanio.com, 1 +octarineparrot.com, 1 +octav.name, 1 +octava.ua, 0 +octaviosimon.com, 1 +octo.im, 1 +octobered.com, 1 +octocaptcha.com, 1 +octod.tk, 1 +octohedralpvp.tk, 1 +octohost.net, 1 +octolopagon.games, 1 +octopoos.com, 1 +octopoos.org, 1 +octopub.tk, 1 +octopus-agents.com, 1 +octopus-apps.be, 1 +octothorpe.club, 1 +octothorpe.ninja, 1 +octovpn.com, 1 +oculta.ml, 1 +oculus.com, 1 +ocupat.ro, 1 +ocwr.gov, 1 +odabilocal.com, 1 +odacyeux.fr, 1 +odatakao.com, 1 +oddba.cn, 0 +oddlama.org, 1 +oddmouse.com, 0 +oddmuse.org, 1 +oddnumber.ca, 1 +oddsandevens.ca, 1 +oddsandevensbookkeeping.ca, 1 +oddtime.net, 1 +oddtoes.com, 1 +ode.red, 1 +odedigitale.marketing, 1 +odegua.com, 1 +odejdamoda.tk, 1 +odensc.com, 1 +odensc.me, 1 +odenvilleal.gov, 1 +odeonentertainment.co.uk, 1 +odessalove.tk, 1 +odezdaotto.tk, 1 +odhosc.ca, 1 +odiall.co, 1 +odiall.tk, 1 +odigitalmarketing.com.br, 1 +odijmond.nl, 1 +odinraz.ga, 1 +odinseye.net, 1 +odinson.tk, 1 +odiris.lk, 1 +odlicomul.ga, 1 +odnostranichnik.tk, 1 +odo-pro.ru, 1 +odolbeau.fr, 1 +odonoghue.kiwi, 1 +odontologia-online.com, 0 +odontologiawilliampizarro.com, 1 +odoo.co.th, 1 +odoru.ga, 1 +odosblog.de, 1 +odpikedoslike.com, 1 +odsylvie.cz, 1 +oducs.org, 1 +odvps.com, 0 +odxin.com, 1 +odysea.cat, 1 +odyssee-animation.tk, 1 +odyssey44.com, 1 +odysseyofthemind.eu, 1 +odysseytraining.com.au, 1 +odziezrobocza.pl, 1 +odzyskaniedomeny.pl, 1 +odzywianie.info.pl, 1 +oe-boston.com, 1 +oe0fcdncxjpdd05b.myfritz.net, 1 +oe2018.gov.pt, 1 +oe2019.gov.pt, 1 +oea.gov, 1 +oec-music.com, 0 +oecdpisaforschools.org, 1 +oegd.at, 1 +oeh.ac.at, 1 +oeko-bundesfreiwilligendienst-sh.de, 1 +oeko-bundesfreiwilligendienst.de, 1 +oeko-jahr-jubilaeum.de, 1 +oeko-jahr.de, 1 +oelbilder-oelmalerei.de, 1 +oelsner.net, 1 +oemwolf.com, 1 +oenings.eu, 1 +oeno.link, 1 +oenolab-vidalies.com, 1 +oepsbanaan.nl, 1 +oermen.com, 1 +oessi.eu, 1 +oestemc.com.br, 1 +oettig.xyz, 1 +oetzies-quiz.com, 1 +oevenezolano.org, 1 +of-sound-mind.com, 1 +of2106.dnsalias.org, 1 +ofaqim.city, 1 +ofasoft.com, 1 +ofcampuslausanne.ch, 0 +ofertasadsl.com, 1 +ofertastop.es, 1 +ofertaviva.com.br, 1 +ofertino.es, 1 +ofertolino.fr, 1 +off-rabota.tk, 1 +offandonagain.org, 1 +offbyinfinity.com, 1 +offcasesstore.com, 1 +offenekommune.de, 1 +offenes-deutschland.de, 1 +offensity.com, 1 +offerhome.com, 1 +offermann-koeln.de, 1 +offermom.com, 0 +offers-daraghmehstores.com, 1 +offersgame.com, 1 +offertegiuste.com, 1 +offertemodule.com, 1 +offgames.io, 1 +offgridauto.com, 1 +offgridbound.com, 1 +offgridhub.com, 1 +office-aslabo.com, 1 +office-de-tourisme.net, 0 +office-discount.at, 1 +office-discount.de, 1 +office-dolmetscher-scharnagl.de, 1 +office-furniture-direct.co.uk, 1 +office-house.tk, 1 +office-ruru.com, 1 +office.urown.cloud, 1 +office365-apps.com, 1 +office365.us, 1 +officecode.co.uk, 1 +officeefficient.de, 1 +officeface.cf, 1 +officeforstudents.org.uk, 1 +officefundays.co.uk, 1 +officeinteriors.co.nz, 1 +officemovepro.com, 1 +officert.ga, 1 +officevibe.com, 1 +officezoneonline.com, 1 +official-sensitive.com, 1 +officina.roma.it, 1 +officium.tech, 1 +offlimo.com, 1 +offpageseopro.tk, 1 +offramp13.com, 1 +offroadhoverboard.net, 1 +offsetservices.co.uk, 1 +offshoot.ie, 1 +offshoot.rentals, 0 +offshore.digital, 1 +offshoreclamp.com, 1 +offshoremoney.tk, 1 +offtherails.ie, 1 +offtherayles.com, 1 +offtopica.uk, 0 +ofggolf.com, 1 +ofileo.fr, 1 +ofisescort.tk, 1 +oflow.me, 1 +ofo.moe, 1 +ofo2.com, 0 +oformi.net, 1 +oformit-zajm-kruglosutochno.ga, 1 +oformlaj.ga, 1 +ofrion.lu, 1 +ofsetas.lt, 1 +oftamedic.com, 0 +ofthethorn.be, 1 +oftn.org, 1 +oga.fit, 0 +ogamerezine.tk, 1 +ogarkovo.ml, 1 +ogatsu-cho.com, 1 +oge.ch, 0 +ogfarms.in, 1 +oggw.us, 1 +ogis.gov, 1 +ogkw.de, 1 +oglen.ca, 1 +ognedoor.ru, 1 +ognemet.net, 1 +ognyan.tk, 1 +ogo-knigi.ml, 1 +ogogo-knigi.ml, 1 +ogorod-money.tk, 1 +ogretmenimsanat.com, 0 +ogurishun.tk, 1 +oguya.ch, 1 +ogyaa.jp, 0 +oh-leg.com, 1 +oh14.de, 0 +ohai.su, 1 +ohari5336.in, 1 +ohartl.de, 1 +ohayosoro.me, 1 +ohbabybean.com, 1 +ohchouette.com, 1 +ohd.dk, 1 +oheila.com, 1 +ohentpay.com, 1 +ohhappy.win, 1 +ohhere.xyz, 1 +ohioag.gov, 1 +ohioago.gov, 1 +ohiobrewweek.com, 1 +ohiobusinesscentral.gov, 1 +ohioflockcote.com, 1 +ohiooutside.com, 1 +ohiosos.gov, 1 +ohiostateparks.gov, 1 +ohiot21.gov, 1 +ohiotobacco21.gov, 1 +ohiowebtech.com, 1 +ohitsviral.com, 0 +ohling.org, 1 +ohlmeier.com, 1 +ohlmeier.net, 1 +ohlmeier.org, 1 +ohm.sg, 1 +ohm2013.org, 1 +ohmanager.kr, 1 +ohmayonnaise.com, 1 +ohmy.ca, 1 +ohmyunix.com, 1 +ohne-name.de, 1 +ohnonotme.com, 1 +ohokbd.tk, 1 +ohol.se, 1 +ohome.io, 1 +ohoreviews.com, 1 +ohrange-music.tk, 1 +ohreally.de, 1 +ohsocool.org, 1 +ohsohairy.co.uk, 1 +ohsweetart.com, 1 +ohyooo.com, 1 +ohype.ga, 1 +oi-wiki.org, 1 +oiahe.org.uk, 1 +oic-ci.gc.ca, 1 +oidrava.tk, 1 +oikontroloi.tk, 1 +oikosweb.com, 1 +oil-ecn.ru, 1 +oil-heaters.tk, 1 +oilfieldinjury.attorney, 1 +oilman.ml, 1 +oilpaintingsonly.com, 1 +oimexico.tk, 1 +oinky.ddns.net, 1 +oisabre.com, 1 +oisd.nl, 1 +oiseaux-mania.com, 1 +oita-homes.com, 1 +ojaioliveoil.com, 1 +ojeremy.com, 0 +ojk.ee, 1 +ojp.gov, 1 +ok-test.de, 1 +ok-travel.tk, 1 +ok.ru, 1 +ok118.com, 1 +ok3on.cz, 1 +okad-center.de, 1 +okad.de, 1 +okad.eu, 1 +okaidi.es, 1 +okaidi.fr, 1 +okakuro.org, 1 +okanaybek.tk, 1 +okashi.me, 1 +okay.cf, 1 +okay.coffee, 1 +okayloser.com, 1 +okaz.de, 1 +okazoo.eu, 1 +okburrito.com, 1 +okcasino.ga, 1 +okchousebuyer.com, 1 +okeeferanch.ca, 1 +okhanvatansever.tk, 1 +okhrana.agency, 1 +okib.ca, 1 +okinawa-mag.net, 1 +okinawa-seaside.com, 1 +okkhor52.com, 1 +okkultemysterier.tk, 1 +okkur.community, 1 +okkur.dev, 1 +okkur.io, 1 +okkur.net, 1 +okkur.org, 1 +okkur.team, 1 +okkurlabs.com, 1 +oklahomafibroids.com, 1 +oklahomamoversassociation.org, 1 +oklahomanotepro.com, 1 +okmaybe.ca, 1 +okmirror.net, 1 +okmulgeecounty.gov, 1 +okmx.cloud, 1 +okmx.de, 1 +okna-tm.kz, 1 +okna-vek.com.ua, 1 +okna.ua, 1 +oknarating.ru, 1 +oknavdom-rf.ru, 1 +oknavdom.tk, 1 +oknopvh.ml, 1 +okobojitech.com, 1 +okonto.com, 1 +okoris.net, 1 +okotelecom.ml, 1 +okotoksbeach.ca, 1 +okpo.tk, 1 +okqubit.net, 1 +okremarketing.com, 1 +oksafe-t.org, 1 +oksmclub.ga, 1 +oktave.co, 1 +oktayincesuturizm.com, 1 +oktime.cz, 1 +oktour.ca, 1 +okubo-shika.jp, 1 +okuguchihifuka-clinic.com, 1 +okukan.com.au, 1 +okulistiyoruz.tk, 1 +okurapictures.com, 1 +okusiassociates.com, 1 +okviz.com, 1 +okweb.mx, 1 +okwu.cz, 1 +olacatlitter.com, 1 +olafnorge.de, 1 +olafvantol.nl, 1 +olamisys.com, 1 +olamisys.email, 1 +olamisys.xyz, 1 +olasouris.com, 0 +olastrafford.org, 1 +olatiferreira.com, 1 +olax.tk, 1 +olback.net, 1 +olbat.net, 1 +olcayanar.com, 1 +olcbrookhaven.org, 1 +old-computer-club.ml, 1 +old-times.ga, 1 +old-tomsk.tk, 1 +old-wheelers.tk, 1 +oldaine.tk, 1 +oldbkcom.tk, 1 +oldbrookinflatables.co.uk, 1 +oldbrookmarqueehire.co.uk, 1 +oldcars.tk, 1 +oldcastle.tk, 1 +oldcity.tk, 1 +oldcitysmokehouse.com, 1 +oldcold.co, 1 +olddisk.ml, 1 +oldenglishsheepdog.com.br, 1 +oldenzaal.tk, 1 +older-racer.com, 1 +oldfieldmusic.tk, 1 +oldforgeinn.ddns.net, 1 +oldfriends.tk, 1 +oldiesmusicguide.tk, 1 +oldiesradio.tk, 1 +oldita.ru, 1 +oldliverpoolrailways.tk, 1 +oldnews.news, 1 +oldno07.com, 1 +oldnorthbanter.com, 1 +oldonyosafaris.com, 1 +oldpc.com.ua, 1 +oldriver.tk, 1 +oldroutetwo.com, 1 +oldrun.is, 1 +oldscans.tk, 1 +oldschool-criminal.com, 1 +oldskoolreviews.tk, 1 +oldsticker.com, 1 +oldstmary.com, 1 +oldtavern.tk, 1 +oldtimerparts.de, 1 +oldtimerreifen-moeller.de, 1 +oldvaliken.tk, 1 +olecoin.io, 1 +olegchursin.com, 1 +olegon.ru, 1 +olegrpg.in.ua, 1 +olegs.be, 1 +oleksii.name, 1 +olenergie.com, 1 +olenergie.fr, 1 +olenergies.com, 1 +olenergies.eu, 1 +olenergies.fr, 1 +oleodecopayba.com.br, 1 +oles-hundehaus.de, 1 +olesaindustrial.cat, 1 +olesaradio.tk, 1 +olfnewcastle.com, 1 +olfsecane.org, 1 +olgallery.tk, 1 +olgaserebrennikova.tk, 1 +olgcc.net, 1 +olgiati.org, 0 +olgui.net, 1 +olgun.eu, 1 +olhcparish.net, 1 +olibomb.cc, 1 +olifant.fr, 1 +oligenesi.it, 1 +olightstore.ro, 1 +olimpikfit.com, 1 +olimpikfit.ru, 1 +olimpoao.tk, 1 +olinux.fr, 1 +olitham.com, 1 +olive.my, 1 +oliveconcept.com, 1 +olivejs.com, 1 +olivemultispecialist.com, 1 +oliveoil.bot, 1 +oliveoilschool.org, 1 +oliveoilshop.com, 1 +oliveoiltest.com, 1 +oliveoiltimes.com, 1 +oliverah.com, 1 +oliverclausen.com, 1 +oliverdunk.com, 0 +olivereats.ca, 1 +oliverfaircliff.com, 1 +oliverjoss.com, 1 +olivernaraki.com, 1 +oliverniebuhr.de, 0 +oliverschmid.space, 1 +oliverspringer.eu, 1 +oliverst.com, 1 +olivetbgc.org, 1 +olivia.cf, 1 +olivialufkin.tk, 1 +olivier-giroud.tk, 1 +olivier-rochet.com, 1 +olivierberardphotographe.com, 0 +oliviercreation.tk, 1 +olivierdurand.tk, 1 +olivierpieters.be, 1 +oliviers-co.no, 1 +oliviervaillancourt.com, 1 +olivlabs.com, 1 +olizeite.ch, 0 +oll.dj, 1 +ollaexpress.site, 1 +ollie.io, 1 +ollieowlsblog.com, 1 +ollies.cloud, 1 +ollies.cz, 1 +olliespage.com, 1 +olliespage.net, 1 +olliespage.uk, 1 +ollning.com, 1 +ollo.ga, 1 +olltechjob.com, 1 +olmari.fi, 1 +olmc-nutley.org, 1 +olmcjc.com, 1 +olmcnewark.com, 1 +olmik.net, 1 +olmmcc.tk, 1 +olmsted.io, 1 +olmstedcounty.gov, 1 +oloadvid.tk, 1 +olofsson.cc, 1 +ololmke.org, 1 +olomercy.com, 1 +olopp.org, 1 +olphseaside.org, 1 +olqoa.org, 1 +olschurch.com, 1 +olsh-hilltown.com, 1 +olson25.org, 1 +olsonproperties.com, 1 +oluchiedmundmusic.com, 1 +olydemy.com, 1 +olyfed.com, 1 +olygazoo.com, 1 +olymp-arts.world, 0 +olympe-transport.fr, 1 +olympeakgaming.tv, 1 +olympia-blerick.tk, 1 +olympiads.ca, 1 +olympiaduilawyers.com, 1 +olympiamanzanilla.tk, 1 +olympic-research.com, 1 +olympicfitness.com.mx, 1 +om.yoga, 1 +om1.com, 1 +omachi.top, 1 +omaedu.ro, 1 +omahachapterone.org, 1 +omaharoofpros.com, 1 +omandatapark.com, 1 +omangrid.com, 1 +omanhr.cf, 1 +omanko.porn, 0 +omaosurveys.org, 0 +omarbaba.shop, 1 +omarh.net, 1 +omarhussien.tk, 1 +omarpalos.com, 1 +omarsamarah.tk, 1 +omarzunic.com, 1 +omaxe.tk, 1 +omayn.com, 1 +ombregialle.it, 1 +omdesign.cz, 0 +omega-intranet.com, 1 +omega-marijuana.com, 1 +omegachess.tk, 1 +omegahosting.net, 1 +omegalan.tk, 1 +omegarazer.ca, 1 +omegathermoproducts.nl, 1 +omegletalk.com, 1 +omenprinting.com.au, 1 +omeopatiadinamica.it, 1 +omerta.tk, 1 +omertabeyond.com, 1 +omertabeyond.net, 1 +omestudios.tk, 1 +ometepeislandinfo.com, 1 +omexcables.com, 1 +omf.link, 1 +omgbouncycastlehire.co.uk, 1 +omggo.ph, 1 +omgpu.com, 1 +omgvaneyckwashere.be, 1 +omgvaneyckwashere.com, 1 +omgvaneyckwashere.eu, 1 +omgvaneyckwashere.gent, 1 +omicron3069.com, 1 +omintmais.azurewebsites.net, 0 +omitech.co.uk, 1 +ommcitalflex.com, 1 +omnel.ml, 1 +omniaclubs.com, 1 +omniasig.ro, 1 +omniatv.com, 1 +omniballot.us, 1 +omnibot.tv, 1 +omnicourt.jp, 1 +omnienviro.com, 0 +omnienviro.com.au, 0 +omnifurgone.it, 1 +omnigon.network, 1 +omnimoto.it, 1 +omniscimus.net, 0 +omnisiens.se, 1 +omnisinal.pt, 0 +omnisky.dk, 1 +omnissimmo.fr, 1 +omniteck.com, 1 +omniverse.ru, 1 +omny.info, 1 +omoide-hitokoto.com, 1 +omorashi.org, 1 +omoteura.com, 1 +omranic.com, 1 +omronwellness.com, 1 +omsdieppe.fr, 1 +omshivalab.com, 1 +omsk-web.ml, 1 +omsknews.tk, 1 +omskrock.com, 1 +omskweb.tk, 1 +omtcloud.jp, 1 +omtleden.nl, 1 +omveda.org, 1 +on-air.today, 1 +on-targettrainingcourses.com, 1 +on-tech.co.uk, 1 +on-the-wave.com, 1 +on-tv.tk, 1 +on2it.net, 1 +ona.io, 1 +onaboat.se, 1 +onahonavi.com, 1 +onair.ovh, 1 +onby.org, 1 +onceuagain.tk, 1 +onceuponabow.org, 1 +onceuponarainbow.co.uk, 1 +oncf.asso.fr, 1 +oncodedesign.com, 1 +oncotarget.ru, 1 +ond-inc.com, 1 +ond-inc.jp, 1 +ondajoven.tk, 1 +ondav.com, 1 +ondcp.gov, 1 +onde.xyz, 1 +ondeapostar.pt, 1 +ondemandassociate.com, 1 +onderwijscentrum.gent, 1 +onderwijscentrumgent.be, 1 +onderwijstransparant.nl, 1 +ondevamosjantar.com, 1 +ondiet.biz, 1 +ondoorgrond.tk, 1 +ondrej.org, 1 +ondrejbudin.cz, 1 +ondrejhoralek.cz, 1 +ondrejsramek.cz, 1 +ondrejvasicek.cz, 1 +one---line.com, 1 +one-clue.com, 1 +one-host.ga, 1 +one-million-places.com, 1 +one-news.net, 0 +one-promise.org, 1 +one-resource.com, 1 +one-s.co.jp, 1 +one-tab.com, 1 +one-two.ro, 1 +one6688.com, 1 +oneartyminute.com, 1 +oneazcu.com, 0 +onebigcow.com, 1 +onebookstore.ml, 1 +onebreadcrumb.com, 1 +onebreadcrumb.com.au, 1 +onechoice.co.nz, 1 +onechronos.com, 1 +oneclic.ch, 0 +oneclick2books.cf, 1 +oneclickbooks.ml, 1 +oneclickjailbreak.com, 1 +oneclickmoney.cf, 1 +oneclickmoney.ml, 1 +oneclickmoney.tk, 1 +onedigitize.com, 1 +onedollar.fund, 1 +onedot.nl, 1 +onedrive.com, 0 +onedrive.live.com, 0 +onee3.org, 1 +oneearthsacredarts.com, 1 +onefinebaby.com.au, 1 +onefour.ga, 0 +oneheartbali.church, 0 +onehost.kz, 1 +oneidentity.me, 1 +oneindex.tk, 1 +oneirosociety.tk, 1 +onejoon.de, 1 +onejourney.global, 1 +oneless.tk, 1 +onelifenutrition.co.uk, 1 +onemac.pl, 1 +onemeter.com, 1 +oneminute.io, 0 +oneminutetomindfulness.com, 1 +onemonthcamera.tk, 1 +onemoonmedia.de, 1 +onenetcdn.com, 1 +oneone.moe, 1 +oneononeonone.de, 1 +oneononeonone.tv, 1 +oneplaykh.com, 1 +onepointsafeband.ca, 1 +onepointsafeband.com, 1 +onepointzero.com, 1 +oneprediction.com, 1 +onereview.in, 1 +ones.buzz, 1 +onescience.tk, 1 +oneshotmediakc.com, 1 +oneso.win, 1 +onesports.cz, 1 +onestasolar.com, 1 +onestepbooks.gq, 1 +onestepbooks.ml, 1 +onestopcastles.co.uk, 1 +onestopmedicalsupplies.com, 1 +onestopshop.ml, 1 +onestoptown.com, 1 +onestpasdesanges.fr, 1 +onetakeonehit.tk, 1 +onetap.com, 1 +onetcenter.org, 1 +onetcodeconnector.org, 1 +onetech.it, 1 +onetestatatime.com, 1 +onetime.info, 1 +onetly.com, 1 +onetonline.org, 1 +onetouchrevealplus.com, 1 +onetouchtour.com, 1 +onetown.gq, 1 +onetranslations.com.br, 1 +onetrust.com, 1 +onetwentyseven001.com, 1 +onetwo-vermietung.de, 1 +onetwosweetatelier.com, 1 +oneurl.co, 1 +onevpn.com, 1 +oneway.ga, 1 +onewaymail.com, 1 +oneweb.hu, 1 +onewebdev.info, 1 +onezero24.net, 1 +onfilm.tk, 1 +ongea.io, 1 +ongiaenegogoa.com, 1 +onglobetrotter.com, 1 +onhistory.co.uk, 1 +onhub1.com, 1 +oni.nl, 1 +onice.ch, 1 +onidesign.tk, 1 +onionbot.ga, 1 +onionbot.me, 1 +onionplay.eu, 1 +onionplay.is, 1 +onionplay.org, 1 +onionscan.org, 1 +onionsocial.com, 1 +onionyst.com, 1 +oniria.ch, 0 +oniriamultimedia.com, 1 +onix.eu.com, 1 +onixcco.com.br, 1 +onkentessegertdij.hu, 1 +onkfaktor.de, 0 +onkologiya.ga, 1 +onlanka.com, 1 +onlfait.ch, 0 +online-backup.se, 1 +online-biblio.tk, 1 +online-bookmakers.ru, 0 +online-calculator.com, 1 +online-car-show.com, 1 +online-carhire.tk, 1 +online-clothing-store.tk, 1 +online-consulting-corp.com, 1 +online-divorce.co.za, 1 +online-eikaiwa-guide.com, 1 +online-fix.me, 1 +online-health-insurance.com, 1 +online-jobs.cf, 1 +online-lernprogramme.de, 1 +online-mobile-phone-shop.tk, 1 +online-news-usa.tk, 1 +online-pochta.ml, 1 +online-pr.at, 1 +online-scene.com, 1 +online-shop-equipment.tk, 1 +online-sql-editor.com, 1 +online-stopwatch.com, 1 +online-store-phones.tk, 1 +online-taxes.tk, 1 +online-textil.com, 1 +online-textil.cz, 1 +online-textil.sk, 1 +online.marketing, 1 +online.net.gr, 1 +online.swedbank.se, 1 +online24.pt, 1 +online365.ga, 1 +onlinebiller.com, 1 +onlinebookmarks.tk, 1 +onlinebupropion.gq, 1 +onlinebusiness.law, 1 +onlinecarstyling.nl, 1 +onlinecasinobluebook.com, 1 +onlinecasinosportugal.pt, 1 +onlinecensorship.org, 1 +onlinecollegeessay.com, 1 +onlinecorners.com, 1 +onlinecosmeticsstore.tk, 1 +onlinecrafts.tk, 1 +onlinedapoxetina.gq, 1 +onlinedemo.hu, 1 +onlinedivorce.com, 1 +onlinedoctors24.com, 1 +onlinefashion.it, 1 +onlineformatter.net, 1 +onlinefurniture.us, 1 +onlinegallery.cf, 1 +onlinegamesforgirls.tk, 1 +onlinehaircuts.com, 1 +onlinehartha.com, 1 +onlinehashfollow.com, 1 +onlineinfographic.com, 1 +onlinekmc.com, 1 +onlineknighki.ga, 1 +onlinekocunuz.com, 1 +onlinekreditmitsofortzusage.com, 1 +onlinelegalmarketing.com, 1 +onlinelegalmedia.com, 1 +onlineltctraining.com, 1 +onlinemagento.com, 1 +onlinemarketingmuscle.com, 1 +onlinemarketingtraining.co.uk, 1 +onlineosago.pro, 1 +onlinepaydayloans365.tk, 1 +onlineporno.cc, 1 +onlineprofecional.com, 1 +onlineprogrammingbooks.com, 1 +onlineradio.com.pl, 1 +onlineradio.pp.ua, 1 +onlineradiobr.com, 1 +onlineradiomix.com, 1 +onlineradious.com, 1 +onlineschipaanpak.nl, 1 +onlinesorusor.cf, 1 +onlinesports.cf, 1 +onlinesports.tk, 1 +onlinestoresite.com.au, 1 +onlinesystem.jp, 1 +onlinetadacip.gq, 1 +onlinetextil.cz, 1 +onlineth.com, 0 +onlinetravelmoney.co.uk, 1 +onlineunitedcountry.com, 1 +onlinevardenafil.gq, 1 +onlinevergidanismani.com, 1 +onlineviewers.tk, 1 +onlinevisa.ru, 1 +onlinevoting.tk, 1 +onlinewallpapers.tk, 1 +onlineweblearning.com, 1 +onlineworkshops.tk, 1 +onlinewot.ru, 1 +onlinews.ml, 1 +onlinexl.nl, 1 +onlineyearbook.tk, 1 +onlinezaim.ml, 1 +onload.pt, 1 +only-fragrances.com, 0 +only.lc, 1 +only.sh, 1 +only4free.tk, 1 +onlybooks.gq, 1 +onlyesb.net, 1 +onlyfans.com, 1 +onlyfanslink.com, 1 +onlyinfotech.com, 1 +onlyjesus.net, 1 +onlylithiumhere.gq, 1 +onlylovastatin.gq, 1 +onlymammoths.com, 1 +onlysim.nl, 1 +onlysmoker.com, 1 +onlyssd.com, 1 +onlystars.news, 1 +onlyu.eu, 1 +onlyveg.tk, 1 +onmaps.de, 1 +onmarketbookbuilds.com, 1 +onmaru.com, 1 +onmed.com, 1 +onnatuurlijk.tk, 1 +onnee.ch, 1 +onnext.cc, 1 +onodera.com.br, 1 +onoelixir.gr, 1 +onoranze-funebri.biz, 1 +onoranzefunebri.roma.it, 1 +onore.org, 1 +onpaws.com, 1 +onpay.io, 1 +onpermit.net, 1 +onpointplugins.com, 1 +onporn.red, 1 +onporn.tube, 1 +onrealt.ru, 0 +onrr.gov, 1 +onsgenoegen-waz.nl, 1 +onshuistrust.co.za, 1 +onsinscrit.com, 1 +onsite4u.de, 1 +onsitemower.com, 1 +onsitespeedometer.com, 1 +onslaughtstreetboarding.tk, 1 +onspring.com, 1 +onstat.tk, 1 +onstud.com, 1 +onsudoku.com, 1 +ontariocountyny.gov, 1 +ontariostorage.com, 1 +ontdekhetzelf.nu, 1 +onthe.network, 1 +ontheballbuilding.com.au, 1 +onthecheap.store, 1 +onthegosystems.com, 1 +onthehook.ru, 1 +ontheten.org, 1 +onthewaypodcast.com, 1 +ontogenese.net, 1 +ontopoflove.nl, 1 +ontourmarketing.at, 1 +ontrio.cz, 1 +ontsnappingskamer.nl, 1 +ontstoppingsdienst123.be, 1 +onurer.net, 1 +onvey.io, 1 +onviga.de, 1 +onvirt.de, 1 +onvisible.website, 1 +onvori.com, 1 +onvori.de, 1 +onvousment.fr, 1 +onwie.com, 1 +onwie.fr, 1 +onysix.net, 1 +onyx-groups.com, 1 +onyxcts.com, 1 +onyxfireinc.com, 1 +onyxgen.duckdns.org, 1 +onzelievevrouw-veldegem.tk, 1 +onzerelaties.net, 1 +oo5197.co, 1 +oo6729.co, 1 +oo6729.com, 1 +oo6957.co, 1 +oo918.com, 1 +oo9297.co, 1 +oo9397.com, 1 +oo9721.com, 1 +oo9728.co, 1 +oodlessoftplay.co.uk, 1 +ooeste.com, 1 +oofishing.ru, 1 +oog-osaka.jp, 1 +oogami.name, 1 +oogartsennet.nl, 1 +oogent.be, 1 +ooharttemplates.com, 1 +ookinhetpaars.nl, 1 +ookjesprookje.nl, 1 +oomepu.com, 1 +oomuj.info, 1 +oonie.co.za, 1 +oonne.com, 1 +ooo-santal.ml, 1 +oooh.events, 1 +ooonja.de, 1 +ooooo.cz, 1 +oopsis.com, 1 +oorbellen.nl, 1 +oortcast.com, 1 +oositk.tk, 1 +oosm.org, 1 +oosolutions.nl, 1 +ooyo.be, 1 +op11.co.uk, 0 +op3racional.eu, 1 +op3y.com, 1 +opaco.tk, 1 +opadaily.com, 1 +opale-concept.com, 1 +opalesurfcasting.net, 1 +opalhunter.at, 1 +oparamo.tk, 1 +oparl.org, 1 +opatut.de, 0 +opbedbugcanines.com, 1 +opcare.co.uk, 1 +opcenter.de, 1 +opcionpublicitaria.com, 1 +opcod3.io, 1 +ope.ee, 1 +opel-focken.de, 1 +open-banking-access.uk, 1 +open-bs.com, 1 +open-bs.ru, 1 +open-data-apps.org, 1 +open-domotics.info, 1 +open-fixture-library.org, 1 +open-future.be, 1 +open-gaming.net, 1 +open-infrastructure.net, 1 +open-letters.de, 1 +open-mesh.org, 1 +open-novel.work, 1 +open-sauce-recipes.co.uk, 1 +open-source.gr, 1 +open-trip.id, 1 +open.film, 1 +open.gl, 1 +open.my.id, 1 +open.ru, 1 +openacte.ch, 0 +openai.community, 1 +openalgeria.org, 1 +openarch.nl, 1 +openarchivaris.nl, 1 +openbayes.blog, 1 +openbayes.com, 1 +openbayes.network, 1 +openbayesstatus.com, 1 +openbeecloud.com, 1 +openblox.org, 1 +openbsd.cz, 1 +openbsdhosting.com, 1 +openbusiness.tk, 1 +opencache.uk, 1 +opencaves.io, 1 +openchronicles.net, 1 +opencircuit.nl, 1 +opencity.spb.ru, 1 +openclima.com, 1 +openclub24.ru, 1 +opencluster.at, 1 +openconf.uk, 1 +openconnect.com.au, 1 +opencpes.com, 1 +opencpes.info, 1 +opencpes.io, 1 +opencpes.net, 1 +opencpes.org, 1 +opencrm.co.uk, 1 +opendata.cz, 1 +opendataincubator.eu, 1 +opendecide.com, 1 +opendolls.com, 1 +opendoorcounselingpa.com, 1 +opendoorsnsh.org, 1 +openevic.info, 1 +openfir.st, 1 +openfitapi-falke.azurewebsites.net, 1 +openfuture.digital, 1 +opengg.me, 1 +opengovpartnership.de, 1 +openhistory.de, 1 +openid.net.br, 1 +openings.ninja, 1 +openiocdb.com, 1 +openit.center, 1 +openjur.de, 1 +openkim.org, 1 +openkvk.nl, 1 +openmail.ml, 1 +openmetals.com, 1 +openmind.ga, 1 +openmirrors.cf, 1 +openmirrors.ml, 1 +opennippon.com, 1 +opennippon.ru, 1 +openpictures.ch, 1 +openproject.com, 1 +openproton.cf, 1 +openprovider.nl, 0 +openqnx.com, 1 +openquery.com.au, 1 +openrainbow.com, 1 +openrainbow.health, 1 +openrainbow.net, 1 +openrainbow.org, 1 +openre.site, 1 +openrealestate.co, 1 +openresearch.amsterdam, 1 +openreview.net, 1 +openroademail.com, 1 +openrtm.org, 1 +openruhr.de, 1 +openscreen.lu, 1 +opensend.net, 1 +openslava.tk, 1 +opensource-cms.nl, 1 +opensource-training.de, 1 +opensource.fund, 1 +opensourcecombat.com, 1 +opensourcesoftware.rocks, 1 +opensourcesurvey.org, 1 +opensourcex.tk, 1 +openspa.webhop.info, 1 +openssl.org, 1 +openstackid.org, 1 +openstandia.jp, 1 +openstem.com.au, 1 +openstorage.io, 1 +openstreetmap.is, 1 +openstreetmap.org, 1 +opentable.com, 1 +opentable.com.au, 1 +opentrack.info, 1 +opentrash.org, 1 +openverse.com, 1 +openvision.tk, 1 +openvz.org, 1 +openwaveguide.de, 1 +openwifi.gr, 1 +openwrt-dist.tk, 1 +operad.fr, 1 +operadotejo.org, 1 +operanavigation.ro, 1 +operatic.gq, 1 +operationforever.com, 1 +operationkiwi.work, 1 +operationturkey.tk, 1 +operd.gob.do, 1 +operrhealth.com, 0 +opexterminating.com, 1 +opfin.com, 1 +opiates.ca, 1 +opiates.net, 0 +opic.gov, 1 +opikini.com, 1 +opil.no, 1 +opin.me, 1 +opinio.fr, 1 +opinionipannolini.it, 1 +opinionitech.com, 1 +opinionmodel.it, 1 +opinionproduct.com, 1 +opioids.co.uk, 1 +opioids.com, 1 +opioids.gov, 1 +opioneers.ga, 1 +opioneers.tk, 1 +opisrael.tk, 1 +opium.io, 0 +oplata-mvd.ga, 1 +oplata-vklike.tk, 1 +oplata.uz, 1 +oplatki-charistia.pl, 1 +oplop.appspot.com, 1 +opncld.com, 1 +opopulechki.tk, 1 +oportaln10.com.br, 1 +opos.cf, 1 +oposicionesapolicialocal.es, 1 +oposicionescorreos.es, 1 +oposicionescorreos.info, 1 +oposicionescorreos.net, 1 +oposicionesdejusticia.org, 1 +oposicionesjusticia.info, 1 +oposicionesprofesores.tk, 1 +oposicionesycursos.com, 1 +opp.moe, 1 +oppabet.com, 1 +oppada.com, 1 +oppaiti.me, 1 +oppejoud.ee, 1 +opportunis.me, 1 +opportunity.de, 1 +opportunityliu.top, 1 +opposer.me, 1 +oppositionsecurity.com, 1 +oppress.life, 1 +oppressed.news, 1 +oppwa.com, 1 +opq.pw, 1 +opraab.ga, 1 +oprbox.com, 1 +oprueba.com, 1 +opryshok.com, 1 +ops-com.com, 1 +ops.ai, 1 +ops.com.pl, 1 +opskiwi.work, 1 +opsmate.com, 0 +opsnotepad.com, 1 +opstory.com, 1 +opsystems.bg, 1 +opti-net.at, 1 +opti-net.solutions, 1 +opticaltest.com, 1 +opticamasvision.com, 1 +opticoolheadgear.com, 1 +opticsboss.com, 1 +optiekdemeester.be, 1 +optigear.nl, 1 +optik-sehstern.de, 1 +optik-trosdorff.de, 1 +optiker-gilde.de, 1 +optim-ease.fr, 1 +optimale.co.uk, 1 +optimalforlife.com, 1 +optimall.tk, 1 +optimalrehab.se, 1 +optimalsetup.com, 1 +optimaner.pl, 1 +optimausa.com, 1 +optimed.tk, 1 +optimised.cloud, 1 +optimised.io, 1 +optimisedlabs.co.uk, 1 +optimisedlabs.info, 1 +optimisedlabs.net, 1 +optimisedlabs.uk, 1 +optimism.ru, 1 +optimist.bg, 1 +optimize-jpeg.com, 1 +optimize-jpg.com, 1 +optimizedlabs.co.uk, 1 +optimizedlabs.info, 1 +optimizedlabs.net, 1 +optimizedlabs.uk, 1 +optimom.ca, 1 +optimumcoffeesv.com, 1 +optimummenhealth.com, 1 +optimumterapia.pl, 1 +optimumwebdesigns.com, 1 +optimus.io, 1 +optimuscrime.net, 1 +optique-morice.com, 1 +optiqueh.ca, 1 +optiqueh.com, 1 +optischmopti.de, 1 +optisell.ga, 1 +optitaxes.com, 1 +optizym.de, 1 +optm.us, 1 +optmos.at, 1 +optoms.tk, 1 +optoutday.de, 1 +opture.ch, 1 +opus-codium.fr, 1 +opus-nail.com, 1 +opuselsalvador.com, 1 +opussystems.com.au, 1 +opvakantie-noorwegen.nl, 1 +opvakantie-zweden.nl, 1 +opvoedingswinkelgent.be, 1 +opzich.nl, 1 +oqooled.com, 1 +oqrqtn7ynmgc7qrgwd-ubhdvfiymfbjrh5ethdti8.com, 0 +oqwebdesign.com, 1 +orablanket.co.nz, 1 +oraculobrasil.com.br, 1 +oralb-prestazioni-odontoiatriche.it, 1 +oralbregalaoralb.it, 1 +oralee.org, 1 +oralemiraza.com, 1 +oralight.ml, 1 +orang-utans.com, 1 +orangeacademy.cz, 1 +orangecomputers.com, 1 +orangefab.asia, 1 +orangefinanse.com.pl, 1 +orangehome.ga, 1 +orangejetpack.com, 1 +orangekey.tk, 1 +orangenbaum.at, 1 +orangenj.gov, 1 +orangenuts.in, 1 +orangerock.tk, 1 +orangesquash.org.uk, 0 +orangesquirrelevents.co.uk, 1 +orangewombat.com, 1 +orangtua.tk, 1 +orangutan.org, 1 +oranjee.net, 0 +orano.vn, 1 +orazen.it, 1 +orbeimaginario.com, 1 +orbik.com, 1 +orbisbi.com, 1 +orbitabaja.com, 1 +orbitaclub.cf, 1 +orbital3.com, 1 +orbitalcommerce.com.br, 1 +orbitcleaning.com.au, 1 +orbitdefence.co.uk, 1 +orbitfoods.ca, 1 +orbitgoods.ca, 1 +orbits.ga, 1 +orbu.net, 1 +orca.pet, 0 +orcada.co, 1 +orcahq.com, 1 +orcamarine.tk, 1 +orcawiki.nl, 1 +orchardnh.org, 1 +orchardscribe.com, 1 +orchestra.tk, 1 +orchideenettoyage.com, 1 +orchidhouse.sk, 1 +orchidlive.com, 1 +orchids.ua, 1 +orchidsforum.com, 1 +orcsnet.com, 1 +orcz.cz, 1 +ordbokpro.se, 1 +ordenmutantes.tk, 1 +order-a-laura.de, 1 +order-ftw.de, 1 +ordercipro.gq, 1 +orderdiflucan.ga, 1 +orderlao.com, 1 +ordermore.cloud, 1 +ordermygear.com, 1 +orderomnicef.gq, 1 +orderpizza.tk, 1 +ordervaltrexonlines.ga, 1 +ordevanoranjenassau.nl, 1 +ordigame.com, 1 +ordina.tk, 1 +ordoh.com, 1 +ordoro.com, 1 +ordr.mobi, 1 +ordr.net, 1 +ordr.no, 1 +oregon2020census.gov, 1 +oregonenergysaver.com, 1 +orehoreh.ru, 1 +oreka.online, 1 +orel-city.ml, 1 +orel-sait.tk, 1 +orel.ga, 1 +orelblog.tk, 1 +orellfuessli.ch, 1 +orelnet.tk, 1 +orenburg-life.tk, 1 +orendamebliv.com.ua, 1 +orenohatake.com, 1 +oreshinya.xyz, 1 +oreskylaw.com, 1 +oreto.de, 0 +orf-digitalsatkarte.at, 0 +orf-kartentausch.at, 0 +orfelios.com, 1 +orfeo-engineering.ch, 1 +org-css.tk, 1 +organdonor.gov, 1 +organicae.com, 1 +organicpoint.in, 1 +organicrootsfestival.tk, 1 +organicseo4u.com, 1 +organicstraw.vn, 1 +organisatieteam.nl, 1 +organise.earth, 1 +organizacasa.com.br, 1 +organization-of-holidays.tk, 1 +orgasmium.com, 1 +orged.de, 1 +orgoniteindonesia.com, 1 +orgosias.com, 1 +orgsyn.in, 1 +orgsyn.xyz, 1 +orgtech.ga, 1 +orgyporngroup.com, 1 +orians.eu, 1 +oribia.net, 1 +oricejoc.com, 0 +oriental-events.net, 1 +orientalart.nl, 1 +orientalcollege.tk, 1 +orientalcuisine.tk, 1 +orientalgadgets.tk, 1 +orientravelmacas.com, 1 +orienttime.com.tw, 1 +oriflamesamara.tk, 1 +oriflameszepsegkozpont.hu, 1 +origami.to, 1 +origamiking.wiki, 1 +origenarts.com, 1 +original-christstollen.com, 1 +original-christstollen.de, 1 +originalabsinthe.com, 1 +originalblackfilms.ga, 1 +originalgyms.com, 1 +originalniknihy.cz, 1 +originalpharmacygrup.ml, 1 +originpc.com, 0 +orikadabra.nl, 1 +orikos.tk, 1 +orikum.org, 1 +orimex-mebel.ru, 1 +orion-rentals.tk, 1 +orion-universe.com, 1 +orionadvisor.com, 1 +orioneclipse.com, 1 +orionfcu.com, 1 +orionfinancialservices.com, 1 +orionleasing.com, 1 +oriontravel.co, 1 +oriveda.ch, 1 +oriveda.co.uk, 1 +oriveda.com, 1 +oriveda.nl, 1 +oriya-hrs.com, 1 +orkestar-krizevci.hr, 1 +orkiv.com, 0 +orlandobalbas.com, 1 +orlandooutdoor.com, 1 +orlandoprojects.com, 1 +orleika.io, 1 +ormer.nl, 1 +ornitina.com, 1 +ornsyn.no, 1 +ornua.com, 1 +oro.roma.it, 1 +orocojuco.com, 1 +oroconews.com.br, 1 +orodelsalento.com, 1 +orologeria.roma.it, 1 +oromolido.org, 1 +orovillelaw.com, 1 +oroygrana.com, 1 +orpf.ir, 1 +orphee-beaute.com, 0 +orpheus.network, 1 +orquestaataulfoargenta.com, 1 +orquestas.tk, 1 +orrs.de, 1 +orsal.fr, 1 +ortaev.tk, 1 +ortanatech.com, 1 +orteo.co, 1 +ortho-europe.com, 1 +ortho-graz.at, 1 +orthocop.cz, 1 +orthodontiste-geneve-docteur-rioux.com, 0 +orthodoxy.lt, 0 +orthogennix.com, 1 +orthograph.ch, 1 +orthopedic-shoes.tk, 1 +orthopedicsalon.tk, 1 +orthosportiv.de, 1 +orthotictransfers.com, 1 +ortizmario.com, 1 +ortocraft.tk, 1 +ortoemangiato.it, 1 +ortoinnovapanama.com, 1 +ortopertutti.it, 1 +oruggt.is, 1 +orum.in, 1 +orwell1984.today, 1 +oryva.com, 1 +orzechot.pl, 1 +os-s.net, 1 +os-t.de, 1 +os24.cz, 1 +os76.xyz, 1 +osa.org.za, 1 +osac.gov, 1 +osacrypt.studio, 1 +osagenation-nsn.gov, 1 +osagokasko.ga, 1 +osaka-hero-project.com, 1 +osakeannit.fi, 1 +osakerekisteri.fi, 1 +osaki.fr, 1 +osamabook.tk, 1 +osamakhalid.com, 1 +osamatoon.ml, 1 +osankj.tk, 1 +osano.com, 1 +osau.com, 1 +osbeck.com, 1 +osbi.pl, 1 +osborn.io, 1 +osborneinn.com, 1 +osborneprice.com, 1 +osburn.com, 1 +oscars-web.tk, 1 +oscarsalas.tk, 1 +oscarvk.ch, 1 +osceolacountyia.gov, 1 +osci.io, 1 +oscillation-services.fr, 1 +oscloud.com, 1 +oscpi.com, 1 +oscreen.ru, 1 +osdls.gov, 1 +osdnc.com, 1 +ose-group.com, 1 +osepideasthatwork.org, 1 +osereso.tn, 1 +oses.mobi, 1 +osetia.tk, 1 +osetinskie-pirogi.ga, 1 +osetiya.gq, 1 +osetiya.ml, 1 +osez-l-odyssee.fr, 1 +osgroup.tk, 1 +oshayr.com, 1 +oshea.cc, 1 +oshens.com, 1 +oshershalom.com, 1 +osholife.tk, 1 +oshrc.gov, 1 +osielnava.com, 1 +osimmo.fr, 1 +osirisrp.online, 1 +osirium.com, 1 +oskrba.net, 1 +oskrba.online, 1 +oskuro.net, 1 +osla.org, 1 +oslo-kammerorkester.no, 1 +osm.is, 1 +osm.org, 1 +osm.ovh, 1 +osmaniyehaber.tk, 1 +osmanlitorunu.com, 1 +osmarks.tk, 1 +osmdroid.net, 1 +osmosis-inversa.online, 1 +osmosis.org, 1 +osmre.gov, 1 +osnova.cz, 1 +osobliwydom.pl, 1 +osobnyak.tk, 1 +osolutionscorp.com, 1 +osom.finance, 1 +osomagicmountain.com, 1 +osomjournal.org, 1 +osorio.io, 0 +ospree.me, 1 +osrs.news, 1 +osssr.com, 1 +osszekotatermeszettel.hu, 1 +ostankino.tk, 1 +ostatargalt.ee, 1 +ostechnix.com, 1 +osteendiner.com, 1 +ostendus.club, 1 +osteolaclusaz.com, 0 +osteopathe-palaiseau.com, 1 +osteopathe-voisine.com, 1 +osteopathie-guggenberger.de, 1 +osterkraenzchen.de, 1 +osterlensyd.se, 1 +ostgotamusiken.se, 1 +osti.gov, 1 +ostimwebyazilim.com, 1 +osto.us, 1 +ostr.io, 1 +ostra.gg, 1 +ostra.me, 1 +ostracize.net, 1 +ostrov8.com, 1 +ostrovseocitra.ml, 1 +ostylelimo.com, 1 +osuarez3.com, 1 +osugiving.com, 1 +osuszanie-krakow.pl, 1 +osuszanie-radom.pl, 1 +osuszanie-warszawa.pl, 1 +osvaldocontreras.tk, 1 +oswaldlabs.com, 1 +oswalds.co.uk, 1 +oswaldsmillaudio.com, 1 +oswbouncycastles.co.uk, 1 +osx86spain.com, 0 +oszri.hu, 1 +ot-vinta.tk, 1 +ota365.com, 1 +otakubox.de, 1 +otakuie.tk, 1 +otakurepublic.com, 1 +otakurumi.de, 1 +otchecker.com, 1 +otdelka56.ml, 1 +otdelka76.tk, 1 +otdelochnik.tk, 1 +otdih-krim.tk, 1 +otdyh-v-abhazii.tk, 1 +otg-drives.tk, 1 +otgadaika.tk, 1 +other98.com, 1 +otherkinforum.com, 1 +otherlandlabs.com, 1 +oticasvisao.net.br, 1 +otimismoemrede.tk, 1 +otinane.eu, 1 +otisko.com, 1 +otiumtech.com, 1 +otixz.com, 1 +otkm-stuttgart.tk, 1 +otoblok.com, 1 +otocenterfelix.com.br, 1 +otokirala.com, 1 +otokiralama.name.tr, 1 +otoma.tk, 1 +otomania.tk, 1 +otomobilforumu.com, 1 +otooil.com, 1 +otopan.com, 1 +otoplastik.ml, 1 +otoplenie-ufa.ml, 1 +otorrino.pt, 1 +otoy.com, 1 +otprema.hr, 1 +otpsmart.com.ua, 1 +otptikforum.cf, 1 +otr.ie, 1 +otrm.de, 1 +ots.gov, 1 +otsfreestyle.jp, 1 +otsu.beer, 1 +otterpops.tk, 1 +otterupdate.com, 1 +ottervillemo.gov, 1 +ottmarliebert.tk, 1 +ottomanbedsuk.tk, 1 +ottoproject.io, 0 +ottoversand.at, 1 +otus-magnum.com, 1 +otus.ru, 1 +otvaracie-hodiny.sk, 1 +ouaibe.qc.ca, 1 +ouattara.ch, 1 +oudedokken.be, 1 +ouestacro.fr, 1 +ouestfrance-auto.pro, 1 +ouestsolutions.com, 1 +ouin.land, 0 +oulunjujutsu.com, 1 +oumactive.com, 1 +oumorienteering.com, 1 +oumpower.com, 1 +oumrace.com, 1 +oumsnatch.com, 1 +oumsport.com, 1 +ounage.de, 1 +ouowo.gq, 1 +our-box.de, 1 +our-box.net, 1 +our-little-secret.tk, 1 +our-store.ml, 1 +ourai.ws, 1 +ourchoice2016.com, 1 +ourcloud.at, 1 +ourcnc.com, 1 +ourcodinglives.com, 1 +ourcreolesoul.com, 1 +ourdataprotected.com, 1 +ourdocuments.gov, 1 +ourevents.net, 1 +ourgame.ie, 1 +ourgems.com.au, 1 +ourharvest.com, 1 +ourladymountcarmel.net, 1 +ourladymtcarmel.org, 0 +ourladyofcalvary.org, 1 +ourladyoftheassumptionchurch.org, 1 +ourladyqueenofmartyrs.org, 1 +ourls.win, 1 +ournewsindia.ga, 1 +ouroboros.world, 1 +ourocg.cn, 1 +ouronyx.com, 1 +ourplanetary.com, 1 +ours-tudio.com, 1 +oursiteupdates.com, 1 +ourstory.rip, 1 +oursurplus.com, 1 +ouruglyfood.com, 1 +ourwits.com, 1 +ourworldindata.org, 1 +ourworldspeaks.com, 1 +out-of-england.cf, 1 +out-of-scope.de, 1 +outbound.tk, 1 +outbreak.games, 1 +outdoorfurniture.ie, 1 +outdoorimagingportal.com, 1 +outdoorlearningmap.com, 1 +outdoorlightingagoura.com, 1 +outdoorlightingagourahills.com, 1 +outdoorlightingcalabasas.com, 1 +outdoorlightingconejovalley.com, 1 +outdoorlightingdosvientos.com, 1 +outdoorlightinghiddenhills.com, 1 +outdoorlightinglakesherwood.com, 1 +outdoorlightingmalibu.com, 1 +outdoorlightingmoorpark.com, 1 +outdoorlightingnewburypark.com, 1 +outdoorlightingoakpark.com, 1 +outdoorlightingsimivalley.com, 1 +outdoorlightingthousandoaks.com, 1 +outdoorlightingwestlakevillage.com, 1 +outdoormanufaktur.com, 1 +outdoortrip.com, 1 +outerface.net, 1 +outerlimitsdigital.com, 1 +outernet.tk, 1 +outerspace.ga, 1 +outervision.com, 1 +outetc.com, 1 +outfit-weimar.eu, 1 +outfunnel.com, 1 +outgress.com, 1 +outgrow.co, 1 +outincanberra.com.au, 1 +outinjersey.net, 1 +outlaw-star.tk, 1 +outline.ski, 1 +outline.vn, 1 +outlook.com, 1 +outlookonthedesktop.com, 1 +outnow.ch, 1 +outoftheboxfitness.com, 1 +outplnr.fr, 1 +outpostinfo.com, 1 +output.com, 1 +outrider.ai, 1 +outshinesolutions.nl, 1 +outsideconnections.com, 1 +outsiders.paris, 0 +outsidology.com, 1 +outsourcingdenomina.co, 1 +outsourcingnominabogota.com, 1 +outstack.vote, 1 +outstandingpromotion.com, 1 +outurnate.com, 0 +outwoodz.co.uk, 1 +ouvindo.com.br, 1 +ouwerling.tk, 1 +ouxiang.me, 1 +ov-chipkaart.nl, 1 +ovabastecedoraindustrial.com, 1 +ovago.com, 1 +ovalle.tk, 1 +ovallevirtual.tk, 1 +ovedy.com, 1 +ovelhaostra.com, 1 +oven.media, 1 +ovenapp.io, 1 +ovenrepairaustin.com, 1 +overallscanners.tk, 1 +overcached.com, 1 +overcame.cf, 1 +overcasthq.com, 1 +overclockers.ga, 1 +overclockers.ge, 1 +overdrive-usedcars.be, 0 +overframe.gg, 1 +overheek.tk, 1 +overijsselsemerentocht.nl, 1 +overlandliberty.be, 1 +overlord.network, 1 +overnetfaq.tk, 1 +overnightglasses.com, 1 +overpb.gq, 1 +overps.cf, 1 +overrated.ga, 1 +overs.jp, 1 +overs.top, 1 +oversea.com.br, 1 +overseamusic.de, 1 +overside.ml, 1 +oversight.garden, 1 +oversight.gov, 1 +oversightboard.com, 1 +oversimplifiedeconomics.com, 1 +oversimplifiedstatistics.com, 1 +overstap.deals, 1 +overstemmen.nl, 1 +overstockpromote.com, 1 +overthecloud.it, 1 +overthegate.tk, 1 +overtunes.tk, 1 +overwall.org, 1 +overwatchss.club, 1 +overzicht.pro, 1 +overzicht.ws, 1 +oveweddings.com, 1 +ovez.ga, 1 +ovianca.com, 1 +ovidro.pt, 0 +ovirt.org, 1 +ovisy.com, 1 +ovkerk-avezaath.nl, 1 +ovnrain.com, 1 +ovodakadarkut.tk, 1 +ovpn.com, 1 +ovpn.to, 1 +ovuk.ru, 1 +ovvy.net, 0 +owall.ml, 1 +owapi.net, 1 +owbt.pl, 1 +owddm.com, 1 +owennelson.co.uk, 1 +owensmith.website, 1 +owid.cloud, 1 +owl-media.pl, 1 +owl-media.ru, 1 +owl-media.us, 1 +owl-square.com, 1 +owl-stat.ch, 0 +owl.net, 1 +owlandrabbitgallery.com, 1 +owljumpstart.com, 1 +owlscrap.ru, 1 +owmobility.com, 1 +own3d.ch, 1 +ownagepranks.com, 1 +ownc.at, 1 +owncloud.ch, 1 +owncloud.ml, 0 +owner.pw, 1 +ownerbusiness.org, 1 +ownersre.com, 1 +ownian.com, 1 +owningless.fr, 1 +ownmay.com, 0 +ownspec.com, 1 +owntournament.org, 1 +ownwolke.de, 1 +oxalato.com, 1 +oxaliz.gq, 1 +oxanababy.com, 1 +oxborrow.ca, 1 +oxbridge.eu, 1 +oxelie.com, 0 +oxfordbio.com, 1 +oxfordtutors.com, 1 +oxfordurgentclinic.com, 1 +oxia.me, 1 +oxialive.fr, 1 +oxiame.eu, 1 +oxidemusic.com, 1 +oxidized.org, 1 +oxigenoinformatica.tk, 1 +oximedia.ga, 1 +oximo.lviv.ua, 1 +oximoron.tk, 1 +oxinails.salon, 1 +oxlab.com.ar, 1 +oxo.cloud, 1 +oxsec.co.uk, 1 +oxt.co, 1 +oxygenated.cf, 1 +oxygenserv.com, 1 +oxygin.net, 0 +oxymail.ru, 1 +oxymoron.tk, 1 +oxynux.xyz, 1 +oxyx.tk, 1 +oxz.me, 1 +oxzeth3sboard.com, 1 +oyakmadenmetalurji.com.tr, 1 +oyama-conf.com, 1 +oyap.ca, 1 +oyaquelegal.com.br, 1 +oyesunn.com, 1 +oyk13tyuj8ljpete31edj2tes-9if7bi.com, 0 +oyosoft.fr, 1 +oyosoft.net, 1 +oysterworldwide.com, 1 +oyungg.net, 0 +oyunmadeni.tk, 1 +oyunoynuyalim.tk, 1 +oz-artfocus.com, 1 +oz-style.com, 1 +ozalp.dk, 1 +ozcreatives.tech, 1 +ozel-ders.tk, 1 +ozli.ga, 1 +oznamovacipovinnost.cz, 1 +ozon.ru, 1 +ozone-medical.fr, 1 +ozonitron.com, 1 +ozonitron.de, 1 +ozonitron.eu, 1 +ozonstyle.ga, 1 +ozonytron.com, 1 +ozonytron.de, 1 +ozonytron.eu, 1 +ozudogru.com, 1 +ozvolvo.org, 1 +ozzyfant.de, 1 +p-0.me, 1 +p-art.design, 1 +p-mint.jp, 1 +p-p.site, 1 +p-pc.de, 1 +p-s-b.com, 1 +p-soc.com.br, 1 +p-store.net, 1 +p-t.io, 1 +p-vegas.com, 1 +p.lu, 1 +p02.de, 1 +p10.ru, 1 +p1984.nl, 0 +p1cn.com, 1 +p1group.com, 1 +p1ratrulezzz.me, 1 +p22.co, 1 +p2p-tv.tk, 1 +p2phearthealth.com, 1 +p2r.ru, 1 +p3.marketing, 1 +p30365.com, 1 +p30mororgar.ir, 1 +p333aa.com, 1 +p333b.net, 1 +p333e.net, 1 +p333hhh.com, 1 +p333j.net, 1 +p36533.com, 1 +p4chivtac.com, 1 +p5197.co, 1 +p58101.com, 1 +p58102.com, 1 +p58103.com, 1 +p58104.com, 1 +p58201.com, 1 +p58203.com, 1 +p58204.com, 1 +p58205.com, 1 +p5on.net, 1 +p5r.uk, 1 +p6729.co, 1 +p6957.co, 1 +p7jl.com, 1 +p81365.com, 1 +p82365.com, 1 +p888010.com, 1 +p88813.com, 1 +p88814.com, 1 +p88816.com, 1 +p88817.com, 1 +p88823.com, 1 +p88825.com, 1 +p88827.com, 1 +p88829.com, 1 +p88835.com, 1 +p88836.com, 1 +p88845.com, 1 +p88856.com, 1 +p88867.com, 1 +p888a.com, 1 +p8r.de, 1 +p9165.com, 1 +p91aa.com, 1 +p9297.co, 1 +p9721.com, 1 +p9728.co, 1 +p9cq.com, 1 +p9d1.com, 1 +pa-w.de, 1 +pa.search.yahoo.com, 0 +paal.network, 1 +paalam.ir, 1 +paarberatung-hn.de, 1 +paardenhulp.nl, 1 +paardenpro.nl, 1 +paardensportbak.nl, 1 +paas-inf.net, 1 +paaspasst.de, 1 +paass.net, 0 +paazmaya.fi, 1 +pabel.tech, 1 +pablikado.cz, 1 +pablo.im, 0 +pablo.io, 1 +pablo.scot, 1 +pablo.sh, 1 +pabloarcuri.com, 1 +pabloartea.ga, 1 +pabloarteaga.co.uk, 1 +pabloarteaga.com, 1 +pabloarteaga.com.es, 1 +pabloarteaga.es, 1 +pabloarteaga.eu, 1 +pabloarteaga.info, 1 +pabloarteaga.me, 1 +pabloarteaga.name, 1 +pabloarteaga.net, 1 +pabloarteaga.nom.es, 1 +pabloarteaga.org, 1 +pabloarteaga.science, 1 +pabloarteaga.tech, 1 +pabloarteaga.uk, 1 +pabloarteaga.xyz, 1 +pablocamino.tk, 1 +pablofain.com, 1 +pablofonta.es, 1 +pablomoreno.tk, 1 +pablonadiecomotu.tk, 1 +pabloroblesminister.com, 1 +pablosaraiva.com, 1 +pabpunk.tk, 1 +pabuzo.vn, 0 +pacaom.com, 1 +pacatlantic.com, 1 +pacch.io, 1 +pacchioni.me, 1 +paccolat.name, 1 +pace.car, 1 +pacecounsel.com, 1 +paced.me, 1 +paceda.nl, 1 +paceinvestmentclub.com, 1 +pacelink.de, 1 +pacemakers.ml, 1 +pachaiyappas.org, 1 +pachalingo.tk, 1 +pachamamaproduct.com, 1 +pacharmi.org, 1 +pachinstyle.com, 1 +pacificaent.net, 1 +pacificarperu.com, 1 +pacificautobody.net, 1 +pacificbeachpub.com, 1 +pacificcashforcars.com.au, 1 +pacificcycling.ga, 1 +pacificgynsurgicalgroup.com, 1 +pacifichospitalists.com, 1 +pacificintegration.ca, 0 +pacificocooler.com, 1 +pacificpalisadeselectric.com, 1 +pacificpalisadeselectrical.com, 1 +pacificpalisadeselectrician.com, 1 +pacificpalisadeslandscapelighting.com, 1 +pacificpalisadeslighting.com, 1 +pacificpuke.com, 1 +pacifictilkin-occasions.be, 0 +pacifique-web.nc, 1 +pack-haus.de, 1 +pack.io, 1 +packagingproject.management, 1 +packagist.jp, 1 +packagist.org, 0 +packaware.com, 1 +packer.io, 0 +packetapp.ru, 1 +packetcrash.net, 1 +packetdigital.com, 1 +packetlinux.com, 1 +packetoverflow.com, 1 +packliberte.org, 1 +packov.cz, 1 +packservice.es, 1 +paclease.com.my, 1 +pacobarbera.tk, 1 +pacoda.de, 0 +pact2017.nl, 1 +pactf-flag-4boxdpa21ogonzkcrs9p.com, 1 +pactf.com, 1 +pactrol.com, 1 +pacxodka.ru, 1 +pad.wf, 1 +padam-group.com, 1 +padberx-marketing-consultants.de, 1 +padderne.tk, 1 +paddestoelen-encyclopedie.tk, 1 +paddy.rocks, 1 +padelbox.de, 1 +pader-deko.de, 0 +padisahbilisim.tk, 1 +padmagroup.com, 1 +padovani.de, 1 +padpilot.co, 1 +padron.com.es, 1 +padshah.tk, 1 +paducaheic.com, 1 +padzilla.com, 1 +pae.com, 1 +paediatricdata.eu, 1 +paedlink.ca, 1 +paella-service.net, 1 +paesa.es, 1 +paesi.info, 1 +paf-events.ch, 0 +paff.xyz, 1 +paga.red, 1 +pagalofacil.com, 1 +pagalsongs.club, 1 +pagalsongs.com, 1 +pagalsongs.live, 1 +pagalworld.com, 1 +pagalworld.info, 1 +pagalworld.la, 1 +pagalworld.me, 1 +pagalworld.org, 1 +pagalworld.wiki, 1 +paganismguide.com, 1 +paganistisch-forum.tk, 1 +pagatuarriendo.cl, 1 +pagbitcoin.com, 1 +page, 1 +page-engine.tk, 1 +page-speed.ru, 1 +pageantsnews.com, 0 +pageboard.fr, 1 +pagecdn.io, 1 +pagedesignhub.com, 1 +pagedesignpro.com, 1 +pagedesignshop.com, 1 +pagedesignweb.com, 1 +pagefulloflies.io, 1 +pagenstedt.de, 1 +pagepapi.com, 1 +pagerange.com, 1 +pagerduty.com, 1 +pages-tocaven.com, 1 +pagespeedtweaks.com, 1 +pageuppeople.com, 1 +pagevitals.com, 1 +pagewizz.com, 1 +pagexl.com, 1 +pagiamtzis.com, 1 +pagina394.com.br, 1 +paginamaravillosa.tk, 1 +paginaweb4u.com, 1 +pagliucadb.ddns.net, 1 +paguponku.com, 1 +pagure.io, 1 +pagure.org, 1 +pahealthbilling.com, 1 +pahira.gq, 1 +pahlawanpulsa.com, 1 +pahom.gq, 1 +paidcashforhouses.com, 1 +paidikasymeon.gr, 1 +paidonclick.com, 1 +paidtocode.com, 1 +paidtodesign.com, 1 +paidtodev.com, 1 +paidtohavesex.com, 1 +paiementdp.com, 1 +paige.ai, 1 +paigeglass.com, 1 +paigethegeek.com, 1 +paikkatietokanta.net, 1 +pain-talk.org.uk, 1 +painart.ru, 1 +paincareehr.com, 1 +painclinic.tk, 1 +paindata.dk, 1 +painefamily.co.uk, 1 +painfreenyc.com, 1 +painful.fun, 1 +painmanagementnyc.com, 1 +painosso.org, 1 +paint-it.pink, 1 +paint4.life, 1 +paintball-ljubljana.si, 1 +paintball-shop.sk, 1 +paintballer.co, 1 +paintbrush.ga, 1 +paintcolorsbysue.com, 1 +paintersgc.com.au, 1 +paintingindurban.co.za, 1 +paintlabcustom.com.br, 1 +paio2-rec.com, 1 +paipuman.jp, 1 +paireepinart.com, 1 +pairfum.com, 1 +paisleyandsparrow.com, 1 +pajadam.me, 1 +pajuvuo.fi, 1 +pakaranggrek.com, 1 +pakarrumah.com, 1 +pakcha.com.ar, 1 +paketbox-systems.at, 1 +paketo.cz, 1 +paketo.sk, 1 +paketverfolgung.info, 1 +paketwatch.de, 0 +paketwisataliburan.com, 1 +pakeystonescholars.gov, 1 +pakho.xyz, 1 +pakingas.lt, 1 +pakistan24.tk, 1 +pakistanblogger.tk, 1 +pakistanheadline.tk, 1 +pakistani.dating, 1 +pakistanientertainers.ga, 1 +pakistanpost.ga, 1 +pakitow.fr, 1 +pakjefooi.be, 1 +pakjefooi.com, 1 +pakjefooi.email, 1 +pakjefooi.eu, 1 +pakjefooi.net, 1 +pakjefooi.nl, 1 +pakjefooi.org, 1 +paknetworking.org, 1 +pakostane-apartments.tk, 1 +pakpak.tk, 1 +pakremit.com, 1 +paktolos.net, 1 +palabr.as, 1 +palaceitalia.tk, 1 +palant.info, 1 +palariviera.com, 1 +palary.work, 1 +palatin.at, 1 +palationtrade.com, 1 +palatte.ml, 1 +palaubluetours.com, 1 +palava.tv, 1 +palavalbasket.it, 1 +palavatv.com, 1 +palawan.jp, 0 +palazzo.work, 1 +palazzofiano.it, 1 +palazzotalamo.it, 1 +paleblue.cloud, 1 +palem.com, 1 +palenque.tk, 1 +paleo.io, 1 +paleodietfoodlist.com, 1 +paleodietrecipes.com, 1 +paleontologiadebagua.tk, 1 +paleorecipepro.com, 1 +paleoself.com, 1 +paleoso.com, 1 +paleosquawk.com, 1 +palermoantagonista.tk, 1 +palermofc.com, 1 +palermopride.it, 1 +paless-aless.by, 1 +palessit.com, 1 +palestra.roma.it, 1 +paletdecor.com.ua, 1 +palladium46.com, 1 +palletflow.com, 1 +palletsprojects.com, 1 +palli.ch, 0 +palmaprop.com, 1 +palmavile.us, 1 +palmaville.com, 1 +palmbeachcuisine.com, 1 +palmbeachwebsitehosting.com, 1 +palmen-apotheke.de, 1 +palmiye.tk, 1 +palmoilpledge.id, 1 +palmosradio.gr, 1 +palner.eu, 1 +palomalopez.tk, 1 +palomardisplays.com, 1 +palucamoveis.com.br, 1 +palucms.de, 1 +pama.fun, 1 +pamaniqu.nl, 1 +pamashield.com, 1 +pamc.tk, 1 +pamiers-citoyenne.fr, 1 +pamm.tk, 1 +pampers.com, 1 +pamperssamples.ca, 1 +pamsorel.co.za, 1 +pamvo.com, 1 +pan-lleveme.com, 1 +pan-portugal.com, 1 +pan-therra.ru, 1 +pan.digital, 1 +panamatravel.tk, 1 +panamatrippin.com, 1 +panangelium.tk, 1 +panasca.is, 1 +panascais.at, 1 +panascais.ch, 1 +panascais.co, 1 +panascais.com, 1 +panascais.cz, 1 +panascais.es, 1 +panascais.fi, 1 +panascais.fr, 1 +panascais.host, 1 +panascais.info, 1 +panascais.io, 1 +panascais.me, 1 +panascais.net, 1 +panascais.network, 1 +panascais.nl, 1 +panascais.org, 1 +panascais.pl, 1 +panascais.pt, 1 +panascais.pw, 1 +panascais.ru, 1 +panascais.site, 1 +panascais.tech, 1 +panascais.us, 1 +panascais.zone, 1 +panasproducciones.com, 1 +panavision.com, 1 +panaxis.biz, 1 +panaxis.ch, 1 +panaxis.li, 1 +pancakesfromscratch.com, 1 +pancybertronics.com, 1 +panda-community.com, 1 +panda-craft.tk, 1 +panda-life.tk, 1 +panda.tf, 1 +pandacbd.com, 1 +pandahut.net, 1 +pandakid.tk, 1 +pandaltd.nl, 0 +pandapsy.com, 1 +pandelys.tk, 1 +pandemicflu.gov, 1 +pandemicoversight.gov, 1 +pandit.tech, 1 +pandithaya.tk, 1 +pandjes.com, 1 +pandkonijn.nl, 1 +panduan-hamil.tk, 1 +pandymic.com, 1 +panel-stroy.cf, 1 +paneldewelopera.pl, 1 +paneldoorsolutions.com, 1 +panele-fotowoltaiczne.pl, 1 +paneu.de, 1 +panevo.com, 1 +panezai.tk, 1 +pang.ga, 1 +pangash.com, 1 +pangeaservices.com, 1 +panghu.me, 1 +pangoly.com, 1 +panhandlemenshealth.com, 1 +panhardclub.nl, 1 +panheelstraat.tk, 1 +panic.tk, 1 +panier-legumes.bio, 1 +panino.gr, 1 +paninohome.com, 1 +paniodpolskiego.eu, 1 +paniyanovska.ua, 1 +panj.ws, 1 +panjiva.com, 1 +panlex.org, 1 +pannovate.com, 1 +pano-guru.com, 1 +pano.ie, 1 +panoramacambios.com, 1 +panoramahurtowni.pl, 1 +panoramaphoto.cf, 1 +panoramaresidence-moesern.at, 1 +panoramiquesorganya.tk, 1 +panoti.com, 0 +panpa.ca, 1 +panpsychism.com, 1 +panpsychist.com, 1 +pansino.net, 1 +pantai.com.my, 1 +pantallasled.mx, 1 +pantallasparalamparas.es, 1 +pantallasyescenarios.com, 0 +pantera.tk, 1 +panthenolplus.co.uk, 1 +panthenolplus.com, 1 +pantheoncrafters.com, 1 +pantherage.co.uk, 1 +pantherscore.com, 1 +panthi.lk, 1 +pantingly.tk, 1 +pantographe.info, 0 +pantou.org, 0 +pants-off.xyz, 1 +pantsu.club, 1 +pantypit.com, 1 +panzdravi.cz, 1 +panzer72.ru, 1 +panzers.tk, 1 +pao.moe, 1 +paocaibang.net, 1 +paocloud.co.th, 1 +paolodemichele.it, 1 +paolomargari.tk, 1 +paolotagliaferri.com, 1 +pap.la, 0 +papa---mama.tk, 1 +papa-webzeit.de, 1 +papabearsautocenter.com, 1 +papabrand.tk, 1 +papadoccaffe.pt, 1 +papadopoulos.me, 1 +papakarlohas.ru, 1 +papakatsu-life.com, 1 +papakonstantinou.tk, 1 +papamama-goodlife.net, 1 +papapa-members.club, 1 +paparazzie.de, 1 +paparazzo.net, 1 +papastratosmazi.gr, 1 +papatest24.de, 1 +papaya.me.uk, 1 +papayapythons.com, 1 +papelcraft.co.uk, 1 +paper-republic.org, 1 +paper.sc, 1 +paper.wf, 1 +papergamer.co.uk, 1 +paperhoney.by, 1 +paperlesssolutionsltd.com.ng, 1 +papermasters.com, 1 +papermuseum.jp, 1 +paperopedia.com, 1 +paperplatefun.com, 1 +paperplus.com.au, 1 +paperpress.gq, 1 +papersmart.net, 1 +papertracker.net, 1 +paperwallets.io, 1 +paperwork.co.za, 1 +paperworkspace.com, 1 +paperworld.online, 1 +paperwritinghelp.net, 1 +paperwritten.com, 1 +papierkrieger.net, 1 +papiermakerijdehoop.nl, 1 +papiermeteenverhaal.nl, 1 +papierniak.net, 1 +papierniczy.eu, 1 +papillon-events.be, 1 +papini.fr, 1 +papkinadochka.ru, 1 +papotage.net, 1 +pappacoda.it, 1 +pappasappar.se, 1 +paprikas.fr, 1 +par-allel.ru, 1 +parabellum-barakaldo.tk, 1 +paraborsa.net, 1 +parachute.live, 1 +parachute70.com, 0 +parachuteteam.co.uk, 1 +paracomer.es, 1 +paradaux.io, 1 +paradies-baar.ch, 1 +paradiesgirls.ch, 1 +paradigma-med.ru, 1 +paradigmas.tk, 1 +paradigmshift.com.pk, 1 +paradiscapacitados.site, 1 +paradise-engineer.com, 1 +paradise-engineering.com, 1 +paradise-engineers.com, 1 +paradise-travel.net, 1 +paradise-world.ml, 1 +paradiselost.com, 1 +paradiseprivatehospital.com, 1 +paradiserydes.com, 1 +paradisestore.org, 1 +paradisim.tk, 1 +paradordelgitano.com, 1 +paradoxdesigns.org, 1 +paragon-consult.ru, 1 +paragonie.com, 0 +paragonsigns.tk, 1 +paragontasarim.com, 1 +paragreen.net, 1 +parallaxsite.com, 1 +parallel-worlds.tk, 1 +paraluman.be, 1 +paralysis.ga, 1 +paramapa.com.py, 1 +paramaquetas.com, 1 +parameterizer.me, 1 +paramo-pineiro.tk, 1 +paramountdentalcenter.com, 1 +paramountelectronics.co.uk, 1 +paranoid.network, 1 +paranoidandroid.tk, 1 +paranoidcrypto.com, 1 +paranoidpenguin.net, 1 +paranoxer.hu, 1 +parapenteciconia.tk, 1 +paraplyen.tk, 1 +parapsihologia.tk, 1 +parareflex.fr, 1 +paras.tk, 1 +parasitologyclub.org, 1 +parasol.fi, 0 +parasomnia.tk, 1 +parasosto.fi, 1 +parastaran.tk, 1 +paratlan.hu, 1 +paratlantalalkozas.hu, 1 +parattusdecora.com.br, 1 +paratxt.org, 1 +parcbotanique.com, 1 +parcelauditpartners.com, 1 +parcelbroker.co.uk, 0 +parcely.online, 1 +parchcraftaustralia.com, 1 +parckwart.de, 1 +parcon.it, 1 +parcoursup-nouvelle-caledonie.fr, 1 +parcoursup.fr, 1 +pardnoy.com, 1 +pareachat.com, 1 +pareaki.com, 1 +paredesdecoura.pt, 0 +parelweb.nl, 1 +paremvasi.net, 1 +parentelement.com, 1 +parentheseardenne.be, 0 +parenthood.guide, 1 +parentingalpha.com, 1 +parentinterview.com, 1 +parentmail.co.uk, 1 +parentpayments.com.au, 1 +parentsandzebrasunited.com, 1 +parentsguidetotheworld.com, 1 +parentsintouch.co.uk, 1 +parenttheirpassion.com, 1 +parenttv.com, 1 +parfum-best.ml, 1 +parfumer.tk, 1 +parfumerie-de-grasse.fr, 0 +parfumi.tk, 1 +pari.cz, 1 +pariga.co.uk, 1 +parina.vn, 1 +paris-elysees.com, 1 +parisackerman.com, 1 +parisbesttravel.com, 1 +parisbloom.com, 1 +parisdimitriou.com, 1 +parisdomino.tk, 1 +parisescortgirls.com, 1 +parisfranceparking.com, 1 +parisfranceparking.de, 1 +parisfranceparking.fr, 1 +parisfranceparking.nl, 1 +parishome.jp, 1 +parisprovincedemenagements.fr, 1 +paritexpressions.com, 1 +parizhanka.tk, 1 +park-trek.com, 1 +parkbee.com.br, 1 +parkcitycu.org, 1 +parkefficient.de, 1 +parkercs.cf, 1 +parkercs.ga, 1 +parkercs.gq, 1 +parkercs.ml, 1 +parkercs.tech, 1 +parkercs.technology, 1 +parkercs.tk, 1 +parkeren.in, 1 +parkerforum.tk, 1 +parkerplumbingcompany.com.au, 1 +parkers.cf, 1 +parkers.co.uk, 1 +parkers.ga, 1 +parkers.gq, 1 +parkers.ml, 1 +parkers.tk, 1 +parkersbarbershop.com, 1 +parket.gq, 1 +parketdoska.ua, 0 +parki.cloud, 1 +parking4less.com, 0 +parkinginparis.fr, 1 +parkingparisnord.fr, 1 +parkngo.com.au, 1 +parkr.io, 1 +parkrocker.com, 1 +parkrunstats.servehttp.com, 1 +parkscandles.com, 1 +parksprings.com, 1 +parksubaruoemparts.com, 1 +parkvetgroup.com, 1 +parkviewcity.com.pk, 1 +parkviewmotorcompany.com, 1 +parkwayminyan.org, 1 +parlament.cf, 1 +parlamento.gub.uy, 1 +parleamonluc.fr, 1 +parlerdeathcountdown.com, 1 +parleu2016.nl, 1 +parleur.net, 1 +parltrack.org, 0 +parmels.com.br, 1 +parnassys.net, 1 +parniplus.com, 1 +parnizaziteksasko.cz, 1 +parodesigns.com, 0 +paroisses-theix-surzur.com, 1 +parolu.io, 1 +parovozov.ga, 1 +paroxetine.gq, 1 +parque-batlle.tk, 1 +parquebatlle.tk, 1 +parquettista.milano.it, 1 +parquettista.roma.it, 1 +parrilladasparaeventos.com, 1 +parrocchiadimeana.tk, 1 +parrocchiamontevecchia.it, 1 +parroquiacorazondemaria.tk, 1 +parroquiaelcarmen.org, 1 +parrotbook.cf, 1 +parry.org, 1 +pars.work, 1 +parsemail.org, 1 +parser.nu, 1 +parsonsfamilyhomes.com, 1 +parspanel.com, 1 +parsuv.ir, 1 +part-of-that-world.com, 1 +part.la, 1 +partage-noir.fr, 1 +parteaga.com, 1 +parteaga.net, 1 +partecipa.tn.it, 1 +partenopei.net, 1 +parthkolekar.me, 1 +particle-vision.ch, 1 +particles.cf, 1 +partidolibertario.tk, 1 +partii.tk, 1 +partijtjevoordevrijheid.nl, 0 +partin.nl, 1 +partiono.com, 1 +partisaani.com, 1 +partitioningjohannesburg.co.za, 1 +partner.sh, 1 +partnerbeam.com, 1 +partnercardservices.com, 1 +partnerchik.tk, 1 +partnerforex.tk, 1 +partnermobil.de, 1 +partnerobzor.tk, 1 +partners4results.net, 1 +partnersofprc.com, 1 +partnerwerk.de, 0 +partofthequeue.ml, 1 +partridge.tech, 1 +parts4phone.com, 0 +partsbox.com, 1 +partsbox.io, 1 +partsestore.com, 1 +partsguysusa.com, 1 +partshop.be, 1 +partusedtyres.net, 1 +party-kneipe-bar.com, 1 +party-produkte.eu, 1 +party-time-inflatables-durham.co.uk, 1 +partyausstatter24.de, 1 +partybounceplay.co.uk, 1 +partyclub.tk, 1 +partycoin.ga, 1 +partydesign.vn, 1 +partydj.be, 1 +partyhireliverpool.co.uk, 1 +partykid.shop, 1 +partypearl.de, 1 +partyphoto.tk, 1 +partyrocksbounce.co.uk, 1 +partyschnaps.com, 1 +partyshop.ge, 1 +partytime-uk.co.uk, 1 +partytimeltd.ie, 1 +partyvan.io, 1 +partyyy.io, 1 +partyzone.ie, 1 +paru-design.com, 1 +parvaneh.fr, 1 +parys.org, 1 +pasadenapooch.org, 1 +pasalt.com, 1 +pasarella.eu, 1 +pasaruang.id, 1 +pascal-bourhis.com, 1 +pascal-koelsch.de, 1 +pascal-ua.tk, 1 +pascal-wittmann.de, 1 +pascal90.de, 1 +pascalchristen.ch, 1 +pascaline-jouis.fr, 1 +pascalleguern.com, 1 +pascalmathis.com, 1 +pascalmathis.me, 1 +pascalmathis.net, 1 +pascoaselecta.com, 1 +pascopresents.com, 1 +pascosystems.com, 1 +pascovotes.gov, 1 +pascualberniz.tk, 1 +pascualinmuebles.com, 1 +pasearch.nl, 1 +paseelite.co, 1 +paseodelariviera.com, 1 +pashminacachemire.com, 1 +pasito.se, 1 +pasnederland.tk, 1 +pasnyburiat.pl, 1 +pasportaservo.org, 1 +pasquarellointeriors.com, 1 +pasquinelli-truebag.ch, 1 +pass.org.my, 1 +passa.org, 1 +passabook.com, 1 +passanodebito.com.br, 1 +passau-webdesign.com, 1 +passbolt.com, 1 +passcod.name, 1 +passedport.eu, 1 +passedport.net, 1 +passedport.org, 1 +passendonderwijs.nl, 0 +passengertravelportal.com, 1 +passfilesafe.com, 1 +passfindr.com, 1 +passfoto-deinfoto.ch, 1 +passgamer.com, 1 +passieposse.nl, 1 +passionandbalance.com, 1 +passionate.org.nz, 1 +passionatefoodie.co.uk, 1 +passionatehorsemanship.com, 1 +passionatelife.com.au, 1 +passionateracers.com, 1 +passiondesigns.web.id, 1 +passionebenessere.com, 1 +passionegriglia.com, 1 +passionpictures.eu, 1 +passions-art.com, 1 +passive-work.gq, 1 +passiveseinkommen.tk, 1 +passivhaus.tk, 1 +passmefaster.net, 1 +passover-fun.com, 1 +passphrase.today, 1 +passport.yandex.by, 1 +passport.yandex.com, 1 +passport.yandex.com.tr, 1 +passport.yandex.kz, 1 +passport.yandex.ru, 1 +passport.yandex.ua, 1 +passports.govt.nz, 1 +passporttrails.com, 1 +passrhce.com, 1 +passrhcsa.com, 1 +passthepopcorn.me, 1 +passumpsicbank.com, 1 +passvanille-reservation.fr, 1 +passvau.lt, 1 +passwd.one, 1 +passwd.org, 1 +password-checker.de, 1 +password.codes, 1 +password.consulting, 1 +passwordgenerator.ml, 1 +passwordhashing.com, 1 +passwordkeeperbooks.com, 1 +passwordlist.io, 0 +passwords.google.com, 1 +passwordscon.com, 1 +passwordscon.org, 1 +passwordsecurity.info, 1 +passwordsleakcheck-pa.googleapis.com, 1 +passworks.io, 1 +pasta-factory.co.il, 1 +pastaenprosecco.nl, 1 +paste.fedoraproject.org, 1 +paste.gg, 1 +paste.rodeo, 1 +paste.to, 1 +pastebin.bet, 1 +pastebin.co.za, 1 +pastebin.tw, 1 +pasteblin.com, 1 +pasteht.ml, 1 +pastelpixels.studio, 1 +pasternok.org, 1 +pasteros.io, 1 +pasticcerialorenzetti.com, 1 +pastillased.gq, 1 +pastimeproject.com, 1 +pastorbelgagroenendael.com.br, 1 +pastorcanadense.com.br, 1 +pastordocaucaso.com.br, 1 +pastorello.cf, 1 +pastorello.ga, 1 +pastorjamesmooney.org, 1 +pastorkleberpedroso.com.br, 1 +pastorluciano.tk, 1 +pastormaremanoabruzes.com.br, 1 +pastorsuico.com.br, 1 +paszkowski.tk, 1 +pasztor.at, 1 +patanegra-jambon.fr, 1 +patanegra-prosciutto.it, 1 +patanegra-schinken.ch, 1 +patanegra-schinken.de, 1 +patapwn.com, 1 +patatbesteld.nl, 1 +patbatesremodeling.com, 0 +patchofabsence.com, 1 +patchyvideo.com, 1 +patdorf.com, 1 +patechmasters.com, 1 +patel.sh, 1 +patentados.com, 1 +patentchallenges.com, 1 +patentfamily.de, 1 +patentmanufaktur.com, 1 +patentmanufaktur.video, 1 +paterno-gaming.com, 1 +pathagoras.com, 1 +pathfindergeo.com, 1 +pathogen.nl, 1 +pathsha.re, 1 +pathwaytofaith.com, 1 +patientwisdom.com, 1 +patikabiztositas.hu, 1 +patikakristaly.hu, 1 +patineteelectrico.shop, 1 +patineteselectricosbaratos.net, 1 +patioroof.cf, 1 +patisserie918.herokuapp.com, 1 +patlis.com, 1 +patma.co.uk, 1 +patmanx.tk, 1 +patralos.at, 0 +patric-lenhart.de, 1 +patrice-carriere.tk, 1 +patricefyffe.gq, 1 +patriceonline.tk, 1 +patricia-lackovic.from.hr, 1 +patriciaandpaul.com, 1 +patriciaramos.pt, 1 +patriciaroy.co, 1 +patrick-omland.de, 1 +patrick-omland.eu, 1 +patrick-othmer.de, 1 +patrick-robrecht.de, 1 +patrick.my-gateway.de, 1 +patrick21.ch, 1 +patrickaudley.ca, 1 +patrickaudley.com, 1 +patrickbrosi.de, 1 +patrickbusch.net, 1 +patrickdankers.nl, 1 +patrickhoefler.net, 1 +patricklustigmediation.com, 1 +patricklynch.xyz, 1 +patrickneuro.de, 1 +patrickpeeters.com, 1 +patrickschneider.me, 1 +patricksymmes.com, 1 +patrikjohan.cf, 1 +patriksima.cz, 1 +patriksimek.cz, 1 +patrikzk.eu, 1 +patriotbearingsupply.com, 1 +patriotcs.tk, 1 +patriquefashion.tk, 1 +patrisnews.com, 1 +patrocinio.com.br, 1 +patrycjamichera.com, 1 +patryk.cf, 1 +patrz.eu, 1 +patsyforyou.ch, 0 +patsytoforyou.ch, 0 +pattanath.com, 1 +pattayafruitgarden.tk, 1 +pattonfanatic.com, 1 +pattuka.com, 1 +pattyliao.com, 1 +patystation.com, 1 +paudley.ca, 1 +paudley.com, 1 +paudley.org, 1 +paul-barton.co.uk, 1 +paul-go.com, 1 +paul-online.tech, 1 +paul-sitarz.com, 1 +paul-zhang.de, 1 +paul.reviews, 1 +paulandmadge.com, 1 +paulbdelaat.nl, 1 +paulborza.com, 1 +paulbramhall.uk, 1 +paulbrown.ddns.net, 1 +paulchen.at, 0 +paulchua.tk, 1 +paulcloud.fr, 1 +paulcoldren.org, 1 +paulcooper.me.uk, 1 +pauld.codes, 1 +pauld.digital, 1 +paulevers.nl, 1 +paulgerberrealtors.com, 1 +paulgo.io, 1 +paulhillmanseo.com, 1 +paulibean.tk, 1 +paulinewesterman.nl, 1 +paulini.ga, 1 +pauljackson.ga, 1 +pauljmartinez.com, 1 +pauljonathan.dk, 1 +paullinmakeup.com, 1 +paullockaby.com, 1 +paulmarc.org, 1 +paulmarvin.tk, 1 +pauloalcobianeves.pt, 1 +paulocolacino.tk, 1 +paulogarcia.tk, 1 +paulorochago.com.br, 1 +paulov.com, 1 +paulov.info, 1 +paulov.ru, 1 +paulrobertlloyd.com, 1 +paulrotter.de, 1 +paulrudge.codes, 1 +paulschreiber.com, 1 +paulscustomauto.com, 1 +paulshir.com, 1 +paulshir.is, 1 +paulsitarz.com, 1 +paulsnar.lv, 1 +paulswartz.net, 1 +paultibbetts.uk, 0 +paulus-foto.pl, 1 +paulus.cloud, 1 +paulward.net, 1 +paulwatabe.com, 1 +paulwendelboe.com, 1 +paulwilhelm.de, 1 +pauly-stahlhandel.com, 1 +pauly-stahlhandel.de, 1 +pautadiaria.com, 1 +pavajebucovina.ro, 1 +pavamtio.cz, 1 +pavando.com, 0 +pavcomm.com, 1 +pavel.cc, 1 +pavelfojt.cz, 1 +pavelfucik.com, 1 +pavelfucik.cz, 1 +pavelfucik.eu, 1 +pavelich.com, 1 +pavelitus.tk, 1 +paveljanda.com, 1 +pavelrebrov.com, 1 +pavelstriz.cz, 1 +paveltoman.cz, 1 +pavernosmatao.tk, 1 +paviformas.es, 1 +pavlic.se, 1 +pavoterrights.com, 1 +paw.cloud, 1 +paw.pt, 1 +pawchewgo.com, 1 +pawel-international.com, 1 +pawelgo.pl, 1 +pawelnazaruk.com, 1 +pawelurbanek.com, 1 +pawelurbanski.com, 1 +pawgearlab.com, 1 +pawnsoft.tk, 1 +pawpatrol.tk, 1 +pawsandpurses.com, 1 +pawson.tk, 1 +pawspuppy.com, 1 +pawsr.us, 1 +pawsru.org, 1 +paxchecker.com, 1 +paxer.com, 1 +paxerahealth.com, 1 +pay-online.in, 1 +pay.gov, 1 +pay.mg, 0 +pay.ubuntu.com, 1 +pay8522.com, 1 +paya.cat, 1 +payblog.org, 1 +payboy.biz, 1 +payboy.rocks, 1 +paybro.eu, 1 +paycardtech.com, 1 +payclock.com, 1 +paydigital.pt, 1 +payexpresse.com, 1 +payfazz.com, 1 +payjunction.com, 1 +payjunctionlabs.com, 1 +paylabs.co.id, 1 +paylike.io, 1 +paylike.se, 1 +payme.plus, 1 +payment-express.net, 1 +payment.ac.cn, 1 +paymentaccuracy.gov, 0 +paymentjs.com, 1 +payments.google.com, 1 +paymill.de, 1 +paymon.tj, 1 +paymongo.com, 1 +paymongo.help, 1 +paynet.com.co, 1 +payoff.com, 1 +paypal.com, 1 +paypaq.com, 1 +paypod.org, 1 +paypodo.com, 1 +paypro.nl, 0 +payps.ru, 1 +payroll.myftp.org, 1 +payrollhr.be, 1 +paysbuy.com, 1 +paysbuy.net, 1 +paysbuy.org, 1 +paysensei.com, 1 +paysera.com, 1 +paysitesreviews.net, 1 +payslipview.com, 1 +payssaintgilles.fr, 0 +paystack.com, 1 +paytm.in, 1 +payupay.ru, 1 +paywait.com, 1 +payxtransfer.co.uk, 1 +pazyarmonia.tk, 1 +pb-design.ch, 1 +pb-eatz.com, 1 +pb-trockeneisreinigung.at, 1 +pb.ax, 0 +pba.org.uk, 1 +pback.se, 1 +pbcables.tk, 1 +pbcknd.ml, 1 +pbdigital.org, 1 +pbern.xyz, 0 +pbest.tk, 1 +pbf.earth, 1 +pblandscapesolutions.com, 1 +pborn.eu, 1 +pbourhis.me, 1 +pbqs.site, 1 +pbr.so, 1 +pbraunschdash.com, 1 +pbrb.gov, 1 +pbrumby.com, 1 +pbscreens.com, 1 +pbsrmoto.com.au, 1 +pbwebdev.com, 1 +pbytes.com, 1 +pbz.im, 1 +pc-master.pl, 1 +pc-reanimator.ru, 0 +pc-rescue.me, 0 +pc-servis-brno.com, 1 +pc-soft.gq, 1 +pc-taskal.net, 1 +pc-tech.ga, 1 +pc-tweak.de, 1 +pc-warriors.com, 1 +pc28yc.com, 1 +pcbarchitect.com, 1 +pcbfl.gov, 1 +pcbmarketing.gq, 1 +pcbmodel.com, 1 +pcbooks.in, 1 +pcbricole.fr, 1 +pcbuildinggr.com, 1 +pcccthicongcungcap.com, 1 +pcdbank.com, 1 +pcdn.cf, 1 +pcdocjim.com, 1 +pcdroid.tk, 1 +pcel.com, 1 +pcert.lat, 1 +pcexpress.tk, 1 +pcf-frankfurt.de, 1 +pcf92.fr, 1 +pcgamingfreaks.at, 1 +pcgho.com, 0 +pchan.is, 1 +pchancs.com, 1 +pchelpforum.net, 1 +pci-e.net, 1 +pciconcursos.com.br, 1 +pcisecuritystandards.org, 1 +pcissc.org, 1 +pckartel.biz, 1 +pckurzypd.sk, 1 +pclaeuft.de, 1 +pcloud.com, 1 +pcmasters.ml, 1 +pcmaw.com, 1 +pcmkrembangan.or.id, 1 +pcmobile.tech, 1 +pcmr.info, 1 +pcmr.rocks, 1 +pcnewsoft.tk, 1 +pcnotdienst-oldenburg-rastede.de, 1 +pcprkolo.pl, 1 +pcrab.ml, 1 +pcrypt.org, 1 +pcsafe.cf, 1 +pcsbrasil.ml, 1 +pcsetting.com, 1 +pcsremodel.com, 1 +pcstoronto.ca, 1 +pctelecom.gq, 1 +pctonic.net, 1 +pctravel.ca, 1 +pctrouble.net, 1 +pculiar.com, 1 +pcunddruckerservice.de, 1 +pcunderground.com.ar, 1 +pcvirusclear.com, 1 +pcw.gov.ph, 1 +pcwdevtwebsite.azurewebsites.net, 1 +pcxserver.com, 0 +pd2bans.org, 1 +pdf-archive.com, 0 +pdfbook-dl.ml, 1 +pdfbooksonline.gq, 1 +pdfconvert.me, 1 +pdfflier.cf, 1 +pdfget.com, 1 +pdflip.cf, 1 +pdfmanga.tk, 1 +pdfmint.com, 1 +pdfpassword.org, 1 +pdfpasswort.de, 1 +pdfpedia.cf, 1 +pdfprostore.cf, 1 +pdfquran.tk, 1 +pdfresizer.com, 1 +pdfsearch.org, 0 +pdfsearches.com, 1 +pdimitrov.com, 1 +pdkrawczyk.com, 1 +pdox.net, 1 +pdpa.ai, 1 +pds.uy, 1 +pdsports.network, 1 +pdtech.ltd, 1 +pdthings.net, 1 +pdvsaargentina.com.ar, 1 +pe-bank.jp, 1 +pe.search.yahoo.com, 0 +peabodytile.com, 1 +peace-is-possible.net, 1 +peaceandjava.com, 1 +peacedivorce.com, 1 +peacefulrock.com, 1 +peaceispossible.cc, 1 +peacekeeper.tk, 1 +peacepiperanch.com, 1 +peacetourco.cf, 1 +peachbuildingproducts.com, 1 +peakd.com, 1 +peakdealershipperformance.com, 1 +peakhomeloan.com, 1 +peakseoservices.co.uk, 1 +peakslead.com, 1 +peaksloth.com, 1 +peaksports.com, 1 +peakvets.co.uk, 1 +peanutbase.org, 1 +peanutpay.de, 1 +peanutproductionsnyc.com, 1 +pearbloom.com, 1 +pearcom.co.uk, 1 +pearlbridal.com.au, 1 +pearlsonly.ca, 1 +pearlsonly.com, 1 +pearlsonly.com.au, 1 +pearlsonly.de, 1 +pearvn.tk, 1 +pease.co.nz, 1 +peatsuki.com, 1 +peawo.com, 1 +pebblepointapartmentsstl.com, 1 +pebbles.net.in, 1 +pebkac.gr, 0 +pebook.tk, 1 +pecadis.de, 1 +pecheneg.tk, 1 +pechibani.by, 1 +pechonova.com, 1 +pecisantri.com, 1 +pecker-johnson.com, 1 +pect.com.pk, 1 +peda.net, 1 +pedago.it, 1 +pedagogiaaopedaletra.com, 1 +pedagoplume.fr, 1 +pedaleuse.be, 1 +pedalirovanie.tk, 1 +pedalr.eu, 1 +pedalsbarcelona.com, 1 +peddie.institute, 1 +peddy.dyndns.org, 1 +peddyland.tk, 1 +pediatersucha.sk, 1 +pediatricdentistrycenter.com, 1 +pediatricdentistsdaculaga.com, 1 +pediatricdentistslilburnga.com, 1 +pedicure-stadspolders.nl, 1 +pedicurean.nl, 1 +pedicureduiven.nl, 1 +pedigreetechnologies.com, 1 +pedikura-vitu.cz, 1 +pedimanie.cz, 1 +pedimoda.com.br, 1 +pedradatattoo.com, 1 +pedrazanoticias.tk, 1 +pedro.com.es, 1 +pedrobotias.tk, 1 +pedrolamas.com, 1 +pedrollo-ua.com, 1 +pedromunoz.tk, 1 +pedrosart.it, 1 +pedrosaurus.com, 1 +pedrosillo-delosaires.tk, 1 +pedroventura.com, 0 +peeekaaabooo.com, 1 +peekier.com, 1 +peelawayyourpain.com, 1 +peelland-fm.tk, 1 +peelmachineryrepair.com, 1 +peen.ch, 1 +peenor.xyz, 1 +peep.gq, 1 +peer.travel, 1 +peercraft.at, 1 +peercraft.be, 1 +peercraft.biz, 1 +peercraft.ch, 1 +peercraft.cn, 1 +peercraft.co.uk, 1 +peercraft.com, 1 +peercraft.de, 1 +peercraft.dk, 1 +peercraft.es, 1 +peercraft.eu, 1 +peercraft.fr, 1 +peercraft.info, 1 +peercraft.it, 1 +peercraft.net, 1 +peercraft.nl, 1 +peercraft.org, 1 +peercraft.pl, 1 +peercraft.pt, 1 +peercraft.se, 1 +peercraft.us, 1 +peerigon.com, 0 +peername.com, 1 +peernode.net, 1 +peerpressurecreative.com, 1 +peers.cloud, 1 +peertube.social, 1 +peerweb.com, 1 +peetah.com, 1 +peew.de, 1 +pefile.tk, 1 +pefricea.com, 1 +pegas-studio.net, 1 +pegasnet.tk, 1 +pegfer.com.br, 1 +pegundugun.tk, 1 +peifi.de, 0 +peippo.at, 1 +peirong.me, 1 +pekarstvivetvrzi.cz, 1 +pekinet.com, 1 +peklostroj.cz, 1 +peklostroj.eu, 1 +peklostroj.sk, 1 +peko.pro, 1 +pelachim.com.br, 1 +pelakefun.com, 1 +pelanucto.cz, 1 +pelevin.gq, 1 +pelgrimhof.be, 1 +pelhamalrecreation.gov, 1 +pelhamlibraryal.gov, 1 +pelhrimov-strmechy.tk, 1 +pelican.ie, 1 +pelicans.tk, 1 +peliculaonline.tk, 1 +peliculasviejas.net, 1 +pelikan.xyz, 1 +pellegrino.ar, 1 +pellet.pordenone.it, 1 +pelletgrillreviews.com, 1 +pelletizermill.com, 1 +pelletsprice.com, 1 +pelmeni.cf, 1 +pelmeniuralskie.tk, 1 +pelopogrund.com, 0 +pelopoplot.com, 0 +pelosanimais.org, 1 +pelotonimports.com, 1 +peluqueriaalcobendas.com, 1 +peluqueriaalcobendas.es, 1 +peluqueriacanina.tk, 1 +pelviclinic.pt, 1 +pem-jp.co.uk, 1 +pemagrid.org, 1 +pemborongbangunan.id, 1 +pemdas.xyz, 1 +pems.gov.au, 1 +pen15art.tk, 1 +pena-party.tk, 1 +pena600.tk, 1 +penatizavarise.com, 1 +penaugustin.com, 1 +pencepay.com, 1 +pencil2d.org, 1 +pencilboutique.com, 1 +pencillab.cn, 1 +penconsultants.com, 1 +pendriveapps.com, 1 +pendrivelinux.com, 1 +penedo.tk, 1 +penetrationstest.se, 1 +penfold.fr, 1 +pengajar.co.id, 1 +pengepung.com, 1 +pengi.me, 1 +pengisatelier.net, 1 +pengui.uk, 1 +penguinbits.net, 1 +penguinclientsystem.com, 1 +penguindrum.moe, 1 +penguinos.tk, 1 +penguinprotocols.com, 1 +penguinshome.tk, 1 +penholder.ga, 1 +peni.tk, 1 +peniarth.cymru, 1 +peninsulaadvancedurology.com, 1 +peninsuladoctor.com, 1 +penisenlargementpro.com, 1 +penispumpen.se, 1 +pennergold.net, 1 +pennington.io, 1 +pennymail.ga, 1 +pennywise.tk, 1 +penopoly.cf, 1 +penopoly.ga, 1 +penosa.ga, 1 +penrithapartments.com.au, 1 +pens-money.cf, 1 +pens-money.ga, 1 +pens.com, 1 +pensacolawinterfest.org, 1 +pensador.com, 1 +pensador.info, 1 +pensan.ge, 1 +pensatore.tk, 1 +pensia.tk, 1 +pensieridigitali.tk, 1 +pensioenfonds-ey.nl, 1 +pension-am-alten-waschhaus.de, 1 +pension-chevaux.com, 1 +pension-ua.tk, 1 +pension-veldzigt.nl, 1 +pensionecani.roma.it, 1 +pensioner-1000.tk, 1 +pensionesdominicanas.com, 1 +pensionpilot.ca, 1 +pensiun.ga, 1 +pensiunea-maria.tk, 1 +pensiunea-paco.ro, 1 +pensiunealido.ro, 1 +penslabyrinth.com, 1 +pentagram.cf, 1 +pentagram.me, 1 +pentamexicali.tk, 1 +pentandra.com, 1 +pentaqu.in, 1 +pentaquin.com, 1 +pentaquin.net, 1 +pentatec.de, 1 +pentechealth.com, 0 +pentekdograma.com, 1 +pentest.blog, 1 +pentesterlab.com, 1 +pentestit.com, 1 +penthack.com, 0 +pentofun.ch, 1 +pentoo.ch, 1 +pentools.org, 1 +pentruprieteni.com, 1 +penuelaspr.gov, 1 +penyavictorhernani.tk, 1 +penz.media, 1 +penza-on-line.tk, 1 +penza-today.tk, 1 +penzaonline.cf, 1 +penzionvzahrade.cz, 1 +peoplelikemeapp.com, 1 +peopleofcolorcareers.com, 1 +peoplescu.com, 1 +peoplesdecade.org, 1 +peoplesguardian.org, 1 +peoplesliberationfront.tk, 1 +peoplesrepublicofchinasucks.com, 1 +peoplesrights.org, 1 +pepechkov.com, 1 +pepeelektro.sk, 1 +pepegym.cz, 1 +pepemodelismo.com.br, 1 +peperstraat.online, 1 +pepfar.gov, 0 +pepgrid.net, 1 +pepkey.net, 1 +peplex.ddns.net, 1 +pepme.net, 1 +peppelmedi.fi, 1 +pepperandpartner.com, 1 +peppyflora.com, 1 +pepsi.investments, 1 +pepsipromos.com, 1 +pepstaff.net, 1 +pepta.net, 1 +pepul.com, 1 +pepwaterproofingllc.com, 1 +pequenosfavoritos.com.br, 0 +per-olsson.se, 1 +peraavcilar.com, 1 +perakampus.com, 1 +peral.ua, 1 +perala.me, 1 +peraparker.cz, 1 +perberestja.gq, 1 +perceptionsaestheticspa.com, 1 +perceptivemeded.com, 1 +perceptyx.com, 1 +percherosdepared.online, 1 +percolate.com, 1 +percraft.com, 1 +percy.io, 1 +percymagic.tk, 1 +perd.re, 1 +perdanabagus.tk, 1 +perdita-capelli.tk, 1 +perdterm.com, 1 +pereceh.eu.org, 1 +perecraft.com, 1 +peredovaya.tk, 1 +peredoz.tk, 1 +pereezd.ml, 1 +peremena.ml, 1 +peresypchanka.tk, 1 +pereuda.com, 1 +perevedi.org, 1 +perevedut.cf, 1 +perevirka.net, 1 +perewall.tk, 1 +perez-marrero.com, 1 +perezdecastro.org, 1 +perezplumbinginc.com, 1 +perf1.com, 1 +perfect-carstyle.de, 1 +perfect-dream.tk, 1 +perfect-privacy.com, 1 +perfect-seo.com.ua, 1 +perfect-tour.ro, 1 +perfect8.com.tw, 1 +perfectbalance.tech, 1 +perfectcloud.org, 1 +perfectcommunity.ga, 1 +perfectfocuseyecare.com, 1 +perfectgarden.es, 1 +perfectgift.tk, 1 +perfectme.ml, 1 +perfectme.tk, 1 +perfectosidiotaspunk.tk, 1 +perfectsize.pl, 1 +perfectsmilesdentistry.net, 1 +perfectsnap.co.uk, 1 +perfectsoft.tk, 1 +perfectstreaming.systems, 1 +perfectworldbot.tk, 1 +perfektesgewicht.com, 1 +perfmatters.io, 1 +perfmed.ro, 1 +performanceetcoaching.fr, 1 +performancegate.com, 1 +performancehealth.com, 0 +performancematters.ie, 1 +performancepiers.com, 1 +performancerunningsolutions.com, 1 +performancetransmission.net, 1 +performetric.net, 1 +performing-art-schools.com, 1 +performiptv.com, 1 +perfumes.com.br, 1 +perfumestudio.in, 1 +perfumesweb.com.br, 1 +pericsope.gq, 1 +peridotcapitalpartners.com, 1 +perigold.com, 1 +perini.com.au, 1 +periodex.co, 1 +periodismoactual.com, 1 +periodista.tk, 1 +periony.com, 1 +periosearch.tk, 1 +perisani.com, 1 +periscope.tv, 1 +perishablepress.com, 1 +perkilo.eu, 1 +perlbanjo.com, 1 +perlego.com, 1 +perlina.co.il, 1 +perlisdigital.com, 1 +perm-avia.ru, 1 +perm-jur.ch, 1 +perm-juridique.ch, 1 +perm-l2.tk, 1 +perm4.com, 1 +permaculture.cf, 1 +permaculture.co.uk, 1 +permajackofstlouis.com, 1 +permajackstlouis.com, 1 +permak.tk, 1 +permanence-juridique.com, 1 +permanencejuridique-ge.ch, 1 +permanencejuridique.com, 1 +permaseal.net, 1 +permasealbasement.com, 1 +permasealbasementsystems.com, 1 +permasealplumbing.com, 1 +permasealwaterproofing.com, 1 +permeance108.com, 1 +permis-apoints.com, 1 +permis.online, 1 +permiscoderoute.fr, 1 +permisecole.com, 1 +permistheorique.be, 1 +permistheoriqueenligne.be, 1 +perniciousgames.com, 0 +peroduaselangor.com, 1 +perot.me, 1 +perpetual.ga, 1 +perpetualemotion.com, 1 +perrau.lt, 1 +perron.ml, 1 +perroon.eu, 1 +perroquet-passion.ch, 0 +perrotts.com.au, 1 +perrybook.tk, 1 +pers-hr.tk, 1 +perscore.tk, 1 +perseo.tk, 1 +persephone.gr, 1 +persiart.shop, 1 +persiennexperten.se, 1 +persiennkompaniet.se, 1 +persistshields.org, 1 +persjrp.ca, 1 +persoform.ch, 1 +personadecoded.com, 1 +personal-genome.com, 1 +personal-injury-attorney.co, 1 +personalidadmagnetica.com, 1 +personalityjunkie.com, 1 +personaljokes.ml, 1 +personaljourneys.co.nz, 1 +personalnames.net.ru, 1 +personalrecreationaltourguides.com, 1 +personaltrainer-senti.de, 1 +personalwebsite.services, 1 +personcar.com.br, 1 +persondatakonsulenterne.dk, 1 +personlookup.com.au, 1 +personnedisparue.fr, 1 +personskadeadvokater.no, 1 +perspective.com.tr, 1 +perspectivum.com, 1 +perspektivwechsel-coaching.de, 1 +persson.im, 1 +persson.me, 1 +persuasionmatters.com, 1 +perth-seo-agency.com.au, 0 +perthhillsarmadale.com.au, 1 +perthtrains.net, 1 +perthunicyclists.tk, 1 +pertwarp.tk, 1 +perubusca.nl, 1 +peruhike.com, 0 +perulinks.tk, 1 +perun.wiki, 1 +perunsoft.rs, 1 +perupoemas.tk, 1 +peruprogramadores.tk, 1 +peruvianphotography.com, 1 +peruviantravel.tk, 1 +pervacio.hu, 1 +perved.org, 1 +pervejshijistochnik.tk, 1 +perversa.cl, 1 +pervoklass.cf, 1 +pervomaysk-city.ml, 1 +perzeidi.hr, 1 +pesandansampai.tk, 1 +pescadorcomunicacao.com, 1 +pescanetworks.tk, 1 +pescco.com.br, 1 +pesnik.tk, 1 +pesnitut.ga, 1 +pesonadewata.com, 1 +pestcontrol.co.uk, 1 +pestici.de, 1 +pestkill.info, 1 +pestleandmortar.hk, 1 +pesto.video, 1 +pestpatrol.ga, 1 +pestpilis.hu, 1 +pestra.tk, 1 +pet-cat-accessories.ml, 1 +pet-distributor.cz, 1 +pet-hotel-mura.net, 1 +pet-net.tk, 1 +pet-tekk.co.uk, 1 +peta.tk, 1 +petabits.de, 1 +petalkr.com, 1 +petalsoft.tk, 1 +petamazing.ga, 1 +petaouchnok.ch, 1 +petar.fyi, 1 +petaxolotl.com, 1 +petbirds.gr, 1 +petblaster.ga, 1 +petbooking.it, 1 +petburial.cf, 1 +petcarvers.com, 1 +petcollections.ga, 1 +petech.ro, 1 +petelew.is, 1 +petemerges.xyz, 1 +peter-hennes.de, 1 +peter-hurtenbach.de, 0 +peter-zhu.ca, 1 +peter.org.ua, 1 +peterackermans.tk, 1 +peterandjoelle.co.uk, 1 +peterbarrett.ca, 1 +peterboers.info, 1 +peterborgapps.com, 1 +peterboweycomputerservices.com.au, 1 +peterbruceharvey.com, 1 +peterbulckaen.tk, 1 +petercawthron.com, 1 +peterdavehello.org, 1 +peterfiorella.com, 1 +peterfolta.net, 1 +petergudo.tk, 1 +peterheery.me, 0 +peterhennes.de, 1 +peterhome.cn, 1 +peterhome.tk, 1 +peterhons.com.au, 1 +peterhuetz.at, 1 +peterhuetz.com, 1 +peterjin.org, 1 +peterjohnson.io, 1 +peterkoren.org, 1 +peterkotula.tk, 1 +peterkrivanek.com, 1 +peterkshultz.com, 0 +peterlajos.com, 1 +peterlew.is, 1 +peterlmai.com, 1 +petermaar.com, 1 +petermamo.com, 1 +petermuenster.tk, 1 +peternagy.ie, 1 +peters.consulting, 1 +peterslavik.com, 0 +petersonchiropractic.net, 1 +petertrevor.com, 1 +petervaldesii.com, 0 +petervantriet.nl, 1 +petevagabond.com, 1 +petfa.ga, 1 +petfoundation.pet, 1 +pethandsome.ga, 1 +petherwick.co.uk, 1 +petherwick.com, 1 +petherwicks.co.uk, 1 +petherwicks.com, 1 +peticion.tk, 1 +petimagine.ga, 1 +petit-archer.com, 1 +petite-annonce.tk, 1 +petite-maison.ch, 0 +petiteframes.com, 1 +petitnuagephotographie.be, 1 +petitsfrenchies.com, 1 +petitsfreresdespauvres.fr, 1 +petitu.mx, 1 +petja.me, 0 +petjoy.co.za, 1 +petless.ga, 1 +petlife.od.ua, 1 +petlife.vet, 1 +petlittle.ga, 1 +petmall.bg, 1 +petnow.gr, 1 +peto.nl, 1 +petops.de, 1 +petos.tk, 1 +petpower.eu, 1 +petpuppy.tk, 1 +petr.as, 1 +petr22shcool.tk, 1 +petrachuk.ru, 1 +petrarca.tk, 1 +petrasestakova.cz, 1 +petresort.pt, 1 +petrocheminc.com, 1 +petrochemprojects.ga, 1 +petroleum-schools.com, 1 +petrologisticsllc.com, 1 +petroscand.eu, 1 +petrotranz.com, 1 +petrotrustlibya.com, 1 +petrovich.pro, 1 +petrovitch.tk, 1 +petrozavodsk.ga, 1 +petruzz.net, 1 +pets-health.com, 1 +petscams.com, 1 +petschnighof.at, 1 +petsnews.ga, 1 +petsnowshoecats.com, 1 +petspark.tk, 1 +petstok.com.br, 1 +petsulcatatortoise.com, 1 +petto.com.co, 1 +pettopsecret.ga, 1 +peturnashes.ga, 1 +petutility.tk, 1 +petwall.info, 1 +petya.cc, 1 +peuf.shop, 1 +peukert.cc, 1 +pew.ninja, 1 +pewat.com, 1 +pewresearch.org, 1 +pex.digital, 0 +pexxi.eu, 1 +peya.tokyo, 1 +peyote.com, 1 +peyote.org, 1 +pf.dk, 1 +pfa.or.jp, 1 +pfadfinder-aurich.de, 1 +pfadfinder-grossauheim.de, 1 +pfarchimedes-pensioen123.nl, 1 +pfarre-kremsmuenster.at, 1 +pfarreiengemeinschaft-neuerburg.de, 1 +pfarrhaus-mon.ch, 1 +pfcafeen.dk, 1 +pfcchavdar.tk, 1 +pfcharland.com, 1 +pfd-nz.com, 0 +pfdevroye.com, 1 +pfefferkuchen-shop.de, 1 +pfefferkuchenprinzessin-dresden.de, 1 +pfeifferszilard.hu, 1 +pferdesportclub-chiemgau.de, 1 +pfernandes.com, 1 +pfeuffer-elektro.de, 1 +pfft.net, 1 +pfish.zone, 1 +pfk.org.pl, 1 +pflan.dk, 1 +pflanzen-shop.ch, 1 +pflege.ch, 1 +pfmeasure.com, 1 +pfolta.net, 1 +pfonks.com, 1 +pfotentour-berlin.de, 1 +pfp.works, 1 +pfrost.me, 1 +pfsquad.blog, 1 +pfsquad.nu, 1 +pfudor.tk, 1 +pg-forum.de, 0 +pg-mana.net, 1 +pg-sec.com, 1 +pg-sec.cz, 1 +pg-sec.eu, 1 +pgazette.tk, 1 +pgh-art.com, 1 +pgitl.com, 1 +pglaum.tk, 1 +pgmsource.com, 1 +pgmtechnologies.com, 1 +pgnetwork.net, 1 +pgp.guru, 1 +pgp.lol, 1 +pgpaintanddesign.com, 1 +pgpmail.cc, 1 +pgregg.com, 1 +pgs.spb.su, 1 +pgsec.cz, 1 +pgsec.eu, 1 +pgsek.cz, 1 +pgsindustries.com.au, 1 +pgui.com, 1 +pgwap.com, 1 +ph.search.yahoo.com, 0 +ph3r3tz.net, 1 +pha.pub, 1 +phannuoc.net, 1 +phant.xyz, 1 +phantasie.cc, 1 +phantasmag.gq, 1 +phantastikon.de, 1 +phantomfund.ml, 1 +phantomlord.tk, 1 +phantomphans.tk, 1 +pharma-display.com, 1 +pharma24.de, 1 +pharmaabsoluta.com.br, 1 +pharmaboard.de, 1 +pharmaboard.org, 1 +pharmaceuticalcannabis.org, 1 +pharmaciechatelle.be, 1 +pharmacieplusfm.ch, 0 +pharmacistinfo.ru, 1 +pharmacy.org.pk, 1 +pharmahealthwholesale.com, 1 +pharmapolitics.com, 1 +pharmasana.co.uk, 1 +pharmasana.de, 1 +pharmasana.ru, 1 +pharmgkb.org, 0 +pharmica.co.uk, 1 +pharmica.uk, 1 +pharside.dyndns.org, 1 +pharynks.com, 1 +pharynx.nl, 1 +phasme-2016.com, 1 +phaux.uno, 1 +phbits.com, 1 +phc-sa.com, 1 +phc4submit.org, 1 +phcimages.com, 1 +phcloud.spdns.de, 1 +phcnetworks.net, 0 +phcorner.net, 1 +phdelivery.com, 1 +phdhub.it, 1 +phdwuda.com, 1 +pheasantrunpress.com, 1 +phellowseven.com, 1 +phelx.de, 1 +phen-garcinia.info, 1 +phenergan.ga, 1 +phenixairsoft.com, 1 +phenq.es, 1 +phenriques.com, 1 +pheramoan.com, 1 +pheramoans.com, 1 +phero.com, 1 +pheroforce.com, 1 +pherologie.com, 1 +pheromeon.com, 1 +pheromeons.com, 1 +pheromoans.com, 1 +pheromoen.com, 1 +pheromoens.com, 1 +pheromones.co, 1 +pheromonetalk.com, 1 +pheromonez.com, 1 +pheronome.com, 1 +pheronomes.com, 1 +pheros.com, 1 +pherotalk.com, 1 +pheroz.com, 1 +phg-eg.com, 1 +phget.com, 1 +phi-works.com, 1 +phibureza.com, 1 +phicreativos.com, 1 +phil-dirt.com, 1 +phil-phillies.com, 1 +phil.red, 0 +phil.tw, 1 +philanima.com, 1 +philarmonic-abaza.tk, 1 +phildevient.tk, 1 +phildonaldson.com, 1 +phileas-psychiatrie.be, 1 +philia-sa.com, 0 +philipdb.com, 1 +philipdb.nl, 1 +philipdeussen.com, 1 +philipdeussen.de, 1 +philiperiksson.se, 1 +philipkdick.tk, 1 +philipkobelt.ch, 1 +philiplowran.tk, 1 +philipmordue.co.uk, 1 +philipp-trulson.de, 0 +philippa.cool, 1 +philippbirkholz.com, 1 +philippbirkholz.de, 1 +philippe-mignotte.fr, 1 +philippebonnard.fr, 1 +philippegoffin.be, 1 +philippehannes.fr, 1 +philippekhau.tk, 1 +philippemunn.photo, 1 +philipperoose.be, 0 +philippheenen.de, 0 +philippinedroneassociation.org, 1 +philippinegreenparty.tk, 1 +philippinenewsvanguard.tk, 1 +philippkaindl.de, 1 +philippkeschl.at, 1 +philipprouhet.com, 1 +philipslater.cf, 1 +philipsmanythougths.cf, 1 +philipssupportforum.com, 1 +philipzhan.tk, 1 +philis-oenologie.fr, 1 +phillipgoldfarb.com, 1 +phillippe-lemarc.ch, 1 +phillippi.me, 1 +phillips66virtualexperience.com, 1 +phillipskaiser.com, 1 +phillipspediatricsoxford.com, 1 +phillprice.com, 0 +philly-injury-law.com, 1 +phillyinjurylawyer.com, 1 +philna.sh, 1 +philo.shop, 1 +philographie.com, 1 +philology.tk, 1 +philomathiclife.com, 1 +philosoftware.com.br, 1 +philosophers.tk, 1 +philosopherswool.com, 1 +philosophy-colleges.com, 1 +philosophyguides.org, 1 +philphonic.de, 1 +phils1990.com, 1 +philstar.com, 1 +philsturgeon.uk, 1 +philux.ch, 0 +philwilson-green.cf, 1 +phimsexjav.top, 1 +phimtor.com, 1 +phinphanatic.com, 1 +phiomegachi.tk, 1 +phishing-studie.org, 1 +phishingusertraining.com, 1 +phive.eu, 1 +phligence.com, 1 +phocept.com.sg, 1 +phoenixcourt.gov, 1 +phoenixdepositionservices.com, 1 +phoenixfrequency.ga, 1 +phoenixlogan.com, 1 +phoenixmunicipalcourt.gov, 1 +phoenixnest.ltd, 1 +phoenixsalon.eu, 1 +phoenixshirt.com, 1 +phoenixurbanspaces.com, 1 +phographer.com, 1 +pholder.com, 1 +phone-service-center.de, 1 +phone-spy.ml, 1 +phone888.cn, 1 +phonearena.com, 1 +phonedoc.it, 1 +phonefilter.co.uk, 1 +phonefleet.fr, 1 +phoneinformation.cf, 1 +phonemore.com, 1 +phonenumber-info.co.uk, 1 +phonenumberfind.tk, 1 +phonesexchat.com, 1 +phonesexnumbers.com, 1 +phonet.tk, 1 +phonetikos.com, 1 +phonetrace.tk, 1 +phongthuygo.com, 1 +phonix-company.fr, 1 +phonosynthese.tk, 1 +phonosynthesis.tk, 1 +phormance.com, 1 +phosagro.biz, 0 +phosagro.com, 0 +phosagro.ru, 0 +phosforum.ga, 1 +phosphene.io, 1 +photek.fm, 1 +photistic.org, 1 +photo-blowup.com, 0 +photo-booth.ro, 1 +photo-castings.com, 1 +photo-design.ml, 1 +photo-host.tk, 1 +photo-livesearch.com, 1 +photo-news.tk, 1 +photo-paysage.com, 1 +photo-travel.tk, 1 +photoancestry.com, 1 +photoartelle.com, 1 +photobooth-romania.ro, 1 +photobooth.id, 1 +photobosco.tk, 1 +photochka.tk, 1 +photoclothing.tk, 1 +photocode.co.rs, 1 +photodeal.fr, 1 +photodyna.tk, 1 +photographe-reims.com, 0 +photographerforwedding.tk, 1 +photographersdaydream.com, 1 +photography-edu.com, 1 +photography-workshops.net, 1 +photographyforchange.com, 1 +photographyforchange.org, 1 +photolakeview.com, 1 +photolessya.by, 1 +photomaniastore.com, 1 +photomizer.com, 0 +photomodelcasting.com, 1 +photops.fr, 1 +photosafari.com.my, 1 +photosafaribg.com, 1 +photosgaia.ch, 1 +photoshop-tipps-und-tricks.de, 1 +photosight.ru, 1 +photosoftware.nl, 1 +phototechnique.tk, 1 +phototravel.uk, 1 +phototrio.com, 1 +photoutils.com, 1 +photowall.tk, 1 +photowhimsybymegan.com, 1 +phoxden.net, 1 +phoxmeh.com, 1 +php-developer.org, 1 +php-tuning.de, 1 +php.watch, 1 +phparcade.com, 1 +phpartners.org, 1 +phpbb-tutorials.cf, 1 +phpbbchinese.com, 0 +phpcrudgenerator.com, 1 +phpdevlabs.tk, 1 +phpdorset.co.uk, 1 +phpfashion.com, 1 +phpinfo.in.th, 1 +phpkari.cz, 1 +phpkoru.com, 1 +phpliteadmin.org, 1 +phpmyadmin.net, 1 +phpmydirectory.ru, 1 +phpmynewsletter.com, 1 +phpprime.com, 1 +phpsecure.info, 1 +phpstan.com, 1 +phpstan.org, 1 +phpunit.de, 1 +phra.gs, 1 +phreakaus.tk, 1 +phreaknet.org, 1 +phrive.space, 1 +phryanjr.com, 0 +phryneas.de, 1 +phtechcommunity.org, 1 +phuductms.com, 1 +phuket-idc.com, 1 +phuket-idc.de, 1 +phuket-nash.ga, 1 +phuket-rawai.school, 1 +phuketbeach.tk, 1 +phuketroman.tk, 1 +phuketstyle.tk, 1 +phukettour.ga, 1 +phukettravel.gq, 1 +phukienchanh.com, 1 +phulyshop.com, 1 +phumin.in.th, 1 +phuoctran.com, 1 +phuoctran.com.vn, 1 +phuoctran.me, 1 +phuoctran.org, 1 +phuoctran.vn, 1 +phuong.faith, 1 +phurl.de, 1 +phurl.io, 1 +phv-bw.de, 1 +phw.org.uk, 1 +phygitalentrepreneur.com, 1 +phyley.com, 1 +phyllischerry.com, 1 +phys.ir, 1 +physia.gr, 1 +physicalism.com, 1 +physicalist.com, 1 +physicpezeshki.com, 1 +physics-schools.com, 1 +physik.hu, 1 +physik.lol, 1 +physio-im-appelbachtal.de, 1 +physiobroadbeach.com.au, 1 +physioteam-franz.de, 1 +physiotherapie-kobiella.de, 1 +physiotherapie-seiwald.de, 1 +physiotherapist-physicaltherapist.com, 1 +physiovesenaz.ch, 0 +pi-dash.com, 1 +pi-hole.net, 1 +pi-net.dedyn.io, 1 +pi-supply.com, 1 +pi1.io, 1 +pia-bardo.tk, 1 +piadouwes.tk, 1 +piajans.com, 1 +pianetaottica.com, 0 +pianetaottica.eu, 1 +pianetaottica.info, 1 +pianetaottica.it, 1 +pianetatatuaggi.it, 1 +pianojockl.org, 1 +pianoplast.com, 1 +pianos.de, 0 +pianostemmer.eu, 1 +pianotuning.cn, 0 +pianyigou.com, 1 +piaohong.tk, 1 +piasativa.com, 1 +piastaola.com, 1 +piasto.com.cy, 1 +piata-imobiliara.tk, 1 +piata.com.br, 1 +piataborrachas.com.br, 1 +piatabrasil.com.br, 1 +piatatem.com.br, 1 +piatenko.ml, 1 +piatika.com, 1 +piavonpadberg.com, 1 +piazzafrancesco.com, 1 +piboston.org, 1 +piboubes.me, 1 +pic.gov, 0 +pic.pm, 1 +pic.sr, 1 +pic2map.com, 1 +pic2pat.com, 1 +pic2pat.nl, 1 +piccirello.com, 1 +piccoliamicisport.it, 1 +piccolinokids.gr, 1 +piccolo-parties.co.uk, 1 +pichainlabs.com, 1 +pick.aw, 1 +pick150.hu, 1 +picka.gift, 1 +pickabrain.fr, 1 +pickaw.click, 1 +pickaw.com, 1 +pickaw.link, 1 +pickawaycountyohio.gov, 1 +picked.cf, 1 +pickelhaubes.com, 1 +pickherznyeremeny.hu, 1 +picklinik.id, 1 +pickme.nl, 0 +pickmysoap.gr, 1 +picksin.club, 1 +pickupalliance.com, 1 +pickupenc.ru, 1 +piclect.com, 1 +picme.tk, 1 +picobellos.tk, 1 +picom365.com, 1 +picone.com.au, 1 +piconepress.com, 1 +picordi.fr, 1 +picr.ws, 1 +picsastock.com, 1 +picshare.nz, 1 +picstar.tk, 1 +picsto.re, 0 +picstreak.com, 1 +pictopat.com, 1 +pictopat.nl, 1 +pictorial.com.sg, 1 +pictoriastudios.com, 1 +pictorista.com, 1 +pictr.nl, 1 +picture.team, 1 +pictureguy.de, 1 +picturevictoria.vic.gov.au, 1 +picturingjordan.com, 1 +picturoftheday.tk, 1 +pidelo-peru.com, 1 +pidginhost.com, 1 +pidjipi.com, 1 +pidmanager.de, 1 +pie-express.xxx, 1 +pieceofcake.solutions, 1 +pieceofme.be, 0 +piechart.ga, 1 +piedrahita.tk, 1 +piedrasblancas.gov, 1 +piedroshop.nl, 1 +piekacz.co.uk, 1 +piekacz.eu.org, 1 +piekacz.net, 1 +piekacz.tel, 1 +piekblog.com, 1 +piektraining.com, 1 +piel.ai, 1 +pieland.eu, 1 +pieloveyoudesserts.com, 1 +piem.org, 1 +piening.ddns.net, 1 +piensa-escribe.tk, 1 +piepermail.nl, 1 +piepschuimlogo.nl, 1 +pieq.eu, 1 +pieq.eu.org, 1 +pier1url.com, 1 +pier28.com, 1 +piercingnagykereskedes.hu, 1 +piercingpiac.hu, 1 +piercraft.com, 1 +pierianservices.com, 1 +pierre-denoblens.net, 1 +pierre-schmitz.com, 1 +pierreau.fr, 1 +pierrebruynooghe.fr, 0 +pierrefv.com, 0 +pierrejeansuau.fr, 1 +pierreprinetti.com, 0 +pierreterrien.fr, 1 +pierreyvesdick.fr, 1 +piersmana.com, 1 +pierson.tk, 1 +pietbrakman.tk, 1 +pietechsf.com, 0 +pieter-verweij.nl, 1 +pieterbamps.tk, 1 +pieterbos.nl, 1 +pieterdev.net, 1 +pieterhordijk.com, 0 +pietron.name, 1 +pietrosoft.tk, 1 +pietz.uk, 1 +piezus.ru, 1 +pif.email, 1 +piffer.ind.br, 1 +pig-breeding.tk, 1 +pigb.net, 1 +pigeonracinginformation.com, 1 +pigeons-rings.com, 1 +pighouse.info, 1 +pigliadesigns.com, 1 +pigzilla.co, 1 +pihaar.de, 1 +pii.bz, 1 +pijamasbichopreguica.com.br, 1 +pijuice.com, 1 +pijusmagnificus.com, 1 +pik.bzh, 1 +pikafederation.ca, 1 +pikecountyohcommissioners.gov, 1 +pikeitservices.com.au, 1 +piken.eu, 1 +pikimusic.moe, 1 +pikio.pl, 1 +pikker.ee, 1 +pikkuegypti.tk, 1 +pikmy.com, 1 +piknichok.ml, 1 +pilani.ch, 0 +pilar-institute.com, 1 +pilarguineagil.com, 1 +pilatesavenue.co.uk, 1 +pilatesbyval.com, 1 +pilatescenteraz.com, 1 +pilatespt.nl, 1 +pilatesstation.co.th, 1 +pilatesstudiozutphen.nl, 1 +pildat.org, 1 +pileofgarbage.net, 1 +pilesyk.tk, 1 +piliszek.net, 1 +pill.id, 1 +pillar.ninja, 1 +pillar.us, 1 +pillitteriobgyn.com, 1 +pillowcast.net, 1 +pillowfort.pub, 1 +pilot-colleges.com, 1 +pilot.co, 0 +pilot.com, 1 +pilotcareercenter.com, 1 +pilotcareercentre.com, 1 +pilotgrowth.com, 1 +pilotpov.com, 1 +pilotproject.tk, 1 +pilsen.fun, 1 +pilvi.pw, 1 +pilvi.space, 1 +pilvin.pl, 1 +pimanta.com, 1 +pimastoneaz.com, 1 +pimbletree.com, 1 +pimentokinderboeken.nl, 1 +pimhaarsma.nl, 1 +pimhaarsmamedia.nl, 1 +pimichi.com, 1 +pimoid.fr, 1 +pimpmymac.ru, 1 +pimpmypaper.com, 1 +pimpmyperf.fr, 0 +pimpstack.com, 1 +pimylifeup.com, 1 +pin.net.au, 1 +pinale.es, 1 +pinaro.de, 1 +pinarshivmarket.com, 1 +pinceaux.org, 1 +pincha.com.tw, 0 +pinchoparados.tk, 1 +pinchuk.tk, 1 +pincodehome.com, 1 +pincodeit.com, 1 +pincong.rocks, 1 +pindanutjes.be, 0 +pindex.ch, 1 +pindostan.tk, 1 +pinebaylibrary.org, 1 +pinebrook.tk, 1 +pinedadegiguela.tk, 1 +pinellaslaser.com, 1 +pinemountainnursery.com.au, 1 +pinemountbaptistchurch.org, 1 +pinetopazrealestate.com, 1 +pinflux2.com, 1 +ping-books.cf, 1 +pingandsue.us, 1 +pingrc.net, 1 +pingu.info, 1 +pinguinreal.sk, 1 +pinhadigital.com, 1 +pinigseu.xyz, 1 +pinimg.com, 1 +pink-check.school, 1 +pink-panther.tk, 1 +pinkapple.com, 1 +pinkbike.com, 1 +pinkbikecycle.com, 1 +pinkerton.io, 1 +pinkitalia.tk, 1 +pinklecfest.org, 1 +pinklittlenotebook.com, 1 +pinkoi.com, 1 +pinkplay.com.br, 1 +pinksec.com.au, 1 +pinkwalk.co.nz, 1 +pinkylam.me, 1 +pinnacle-tex.com, 1 +pinnacleallergy.net, 1 +pinnaclelife.co.nz, 0 +pinnaclelife.nz, 1 +pinnacleraffles.com, 1 +pinnakl.com, 1 +pinnoto.org, 1 +pinot.it, 1 +pinoydailytvshow.net, 1 +pinoyreal.com, 1 +pinoytech.ph, 1 +pinpaituiguang.com.cn, 1 +pinpaiyunying.com.cn, 1 +pinpayments.com, 1 +pinpointengineer.co.uk, 1 +pinskupakki.fi, 1 +pinterest.at, 1 +pinterest.ca, 1 +pinterest.co.uk, 1 +pinterest.com, 1 +pinterest.de, 1 +pinterest.engineering, 1 +pinterest.es, 1 +pinterest.ie, 1 +pinterest.info, 1 +pinterest.jp, 1 +pinterest.nz, 1 +pinterest.ph, 1 +pinterest.ru, 1 +pinterjann.is, 1 +pintiaux.com, 1 +pintosbeeremovals.co.za, 1 +pintoselectricfencing.co.za, 1 +pintoselectrician.co.za, 1 +pintosplumbing.co.za, 1 +pinup-app.com, 1 +pinupbets.gq, 1 +pioneer-car.eu, 1 +pioneer-rus.ru, 1 +pioneerbible.org, 1 +pionierboat.ga, 1 +pionieren.tk, 1 +piotrandpawel.pl, 1 +piotrlewandowski.xyz, 1 +pipabella.com, 1 +pipeclub.tk, 1 +pipenav.gq, 1 +pipenny.net, 1 +pipeuro.com, 1 +pipfrosch.com, 0 +piplwize.com, 1 +pippenainteasy.com, 1 +piprotec.com, 1 +pipscprd.ca, 1 +piraeuspress.gr, 1 +piraino.fr, 1 +piramalglassusa.com, 1 +piranhaattack.tk, 1 +piranja-cola.de, 1 +piranjasoul.de, 1 +pirapiserver.ddns.net, 1 +pirate.chat, 1 +piratebayproxy.tf, 1 +piraten-basel.ch, 1 +piraten-kleinbasel.ch, 1 +piraten-recording.tk, 1 +pirateparty.org.uk, 1 +piratepay.io, 0 +pirateproxy.bet, 1 +pirateproxy.blue, 1 +pirateproxy.buzz, 1 +pirateproxy.cam, 1 +pirateproxy.cat, 1 +pirateproxy.cc, 1 +pirateproxy.cloud, 1 +pirateproxy.earth, 1 +pirateproxy.gdn, 1 +pirateproxy.id, 1 +pirateproxy.ist, 1 +pirateproxy.la, 1 +pirateproxy.lat, 1 +pirateproxy.name, 1 +pirateproxy.one, 1 +pirateproxy.onl, 1 +pirateproxy.pl, 1 +pirateproxy.pw, 1 +pirateproxy.red, 1 +pirateproxy.sh, 1 +pirateproxy.tube, 1 +pirateproxy.tv, 1 +pirateproxy.uno, 1 +pirateproxy.vc, 1 +pirateproxy.vet, 1 +pirateproxy.voto, 1 +pirates-comic.com, 1 +pirates.click, 1 +piratesbrewcoffee.net, 1 +piratesforums.co, 1 +pirateship.com, 1 +piratesofthewadden.tk, 1 +pircher.co.uk, 1 +pircher.tk, 1 +pires.ovh, 1 +pirganj24.com, 1 +pirman.es, 1 +pirnhub.xyz, 1 +piro.io, 1 +pirogi.ga, 1 +piroleikki.co.jp, 1 +pirscapital.com, 1 +pirxpilot.me, 1 +pis.eu.com, 1 +pisaggni.ch, 1 +pisanpeikot.tk, 1 +pisarzowa.tk, 1 +piscine.roma.it, 1 +piseach.be, 1 +pisearch.cc, 1 +pisearch.cn, 1 +pisf.in, 1 +pishgamiran.tk, 1 +pishifu.org, 0 +piskenfuerwehr.de, 1 +pisquettes.fr, 1 +pissblau.com, 1 +pissflaps.co.uk, 1 +pistonkandidatu.tk, 1 +pistonpowered.com, 1 +pisupp.ly, 1 +piszmak.pl, 1 +pit-stop-sto.tk, 1 +pitaiatrade.com, 1 +pitbooks.ga, 1 +pitbullclub.tk, 1 +pitbullsecuritysolutions.ca, 1 +pitch.com, 1 +pitchforkunion.tk, 1 +pitchup.com, 1 +pitchupp.com, 1 +piter-print.tk, 1 +piter178.tk, 1 +pitfire.io, 1 +pitius.tk, 1 +pitman.tk, 1 +pitomec.tk, 1 +pitot-rs.org, 1 +pitoufi.fr, 1 +pitshift.co, 1 +pitshift.com, 1 +pitsstop.nu, 1 +pittmancentertn.gov, 1 +piu.moe, 1 +piucellulare.it, 1 +piuincontri.com, 1 +piuplayer.com, 1 +piurvolium.tk, 1 +pivbar.tk, 1 +pivnica.gq, 1 +pivniraj.com, 1 +pivotalshift.co.uk, 1 +pivotaltracker.com, 1 +pivotanimation.org, 1 +pivotanimation.tk, 1 +pivovarcunak.cz, 1 +piwko.co, 1 +pix5.de, 1 +pixael.com, 1 +pixe2019.org, 1 +pixel-history.tk, 1 +pixel.facebook.com, 0 +pixel.google.com, 1 +pixelabs.fr, 1 +pixelcatproductions.net, 1 +pixelcomunicacion.com, 1 +pixelcrayons.com, 1 +pixelcubed.com, 1 +pixelecommerce.com, 1 +pixelesque.uk, 1 +pixelflex.com, 1 +pixelfou.com, 0 +pixelgliders.de, 1 +pixelglue.com.au, 1 +pixelheaven.tk, 1 +pixelhero.co.uk, 0 +pixelmedianetwork.com, 1 +pixelmonworld.fr, 1 +pixelpoint.io, 0 +pixelrain.info, 1 +pixelsketch.co.uk, 1 +pixelsquared.us, 1 +pixelumin3d.com, 1 +pixelurbia.com, 1 +pixeluser.de, 1 +pixelution.at, 1 +pixelw.design, 1 +pixelz.cc, 1 +pixend.de, 1 +pixeon.com, 1 +pixiin.com, 1 +pixiv.cat, 1 +pixiv.moe, 1 +pixivimg.me, 1 +pixlfox.com, 1 +pixloc.fr, 1 +pixnel.com.br, 1 +pixshop.fr, 1 +pixstash.net, 1 +pixxxels.cc, 1 +pizala.de, 1 +pizdelka.tk, 1 +pizponim.co.il, 1 +pizza-calzone.com, 1 +pizza-curator.com, 1 +pizza-house.tk, 1 +pizza-odessa.com.ua, 1 +pizza-soprano.pl, 1 +pizzabesteld.nl, 1 +pizzafest.ddns.net, 1 +pizzagigant.hu, 1 +pizzahut.co.id, 1 +pizzahut.co.in, 1 +pizzahut.ru, 1 +pizzamc.eu, 1 +pizzaplus.tk, 1 +pizzariapartiupizza.com.br, 1 +pizzariaroma.cf, 1 +pizzeria-mehrhoog.de, 1 +pizzeriaamadeus.hr, 1 +pizzeriasmallorca.com, 1 +pj00100.com, 1 +pj00200.com, 1 +pj00300.com, 1 +pj00400.com, 1 +pj00600.com, 1 +pj00700.com, 1 +pj00800.com, 1 +pj00900.com, 1 +pj11018.com, 1 +pj21j.com, 0 +pj21m.com, 1 +pj4488.cc, 1 +pj5588.cc, 1 +pj83.duckdns.org, 1 +pjax.xyz, 1 +pjentertainments.co.uk, 1 +pjleisure.co.uk, 1 +pjo.no, 1 +pjshop.cf, 1 +pjuu.com, 0 +pk-master.tk, 1 +pk-soft.tk, 1 +pk.search.yahoo.com, 0 +pk.wiki, 1 +pk8k.com, 1 +pkbjateng.com, 1 +pkdhungthinh.com, 1 +pkeus.de, 1 +pkgbuild.com, 1 +pkgt.de, 0 +pkirwan.com, 1 +pkisolutions.com, 1 +pko.ch, 0 +pkov.cz, 1 +pkphotobooths.co.uk, 1 +pkq5.com, 1 +pkrank.com, 1 +pkspskov.tk, 1 +pkudh.org, 1 +pkvitality.com, 1 +pkwebsolutions.cf, 1 +pl-cours.ch, 0 +pl-trans.tk, 1 +pl.search.yahoo.com, 0 +pl2.es, 1 +placasonline.com.br, 1 +placeandsee.com, 1 +placedaffiliate.com, 1 +placedapps.com, 1 +placedsupport.com, 1 +placehold.co, 1 +placeitsf.com, 1 +placenet.fr, 1 +placepugs.com, 1 +placeralplato.com, 1 +placercountyelections.gov, 1 +placidoandriolo.tk, 1 +placker.com, 1 +plae.com.au, 1 +plage-les-pirates.fr, 0 +plagiarismcheck.org, 1 +plainbulktshirts.co.za, 1 +plainjs.com, 1 +plainlanguage.gov, 1 +plaintech.net.au, 1 +plaintextpledge.com, 1 +plaintextpledge.email, 1 +plaintextpledge.eu, 1 +plaintextpledge.net, 1 +plaintextpledge.org, 1 +plaintray.com, 1 +plaisirdumouvement.com, 1 +plaisirs-coquins.com, 1 +plakbak.nl, 1 +plan-immobilier.fr, 1 +plan-it-events.de, 1 +plan.in.ua, 1 +planboardapp.com, 1 +planbox.info, 1 +plancke.io, 1 +plandegralba.net, 1 +plandemicvideo.com, 1 +planecon.nz, 1 +planeexplanation.com, 1 +planer.me, 1 +planet-laas.de, 1 +planet-work.com, 1 +planet.live, 1 +planeta-deti.org, 1 +planeta-remontika.ga, 1 +planeta-tierra.cl, 1 +planetadeti.org, 1 +planetalife.com, 1 +planetamend.com, 1 +planetamusik.tk, 1 +planetanim.fr, 1 +planetapolska.com, 1 +planetaprogramas.tk, 1 +planetarian.moe, 1 +planetarydesign.com, 1 +planetasuboficial.com.br, 1 +planetau2.com, 1 +planetbreath.ch, 0 +planetchiropracticga.com, 1 +planete-cocoon.com, 1 +planete-lira.fr, 1 +planete-secu.com, 1 +planeteroliste.com, 1 +planeteroliste.fr, 1 +planetknauer.net, 1 +planetmath.org, 1 +planetmetroidprime.tk, 1 +planetofsound.tk, 1 +planetofthegames.tv, 1 +planetonline.tk, 1 +planetpowershell.com, 1 +planetromeo.com, 1 +planetromeofoundation.org, 1 +planetsoftware.com.au, 1 +planettimer.com, 1 +planify.io, 0 +planisware.cn, 1 +planisware.com, 1 +planisware.io, 1 +planisware.live, 1 +planiswareusa.com, 1 +planisys.net, 1 +planitz.com, 1 +planitz.net, 1 +planitz.org, 1 +planktonforhealth.co.uk, 1 +planled.ga, 1 +planlos.net, 1 +planmemberpartners.com, 1 +planned-cities.com, 1 +plannedgrocery.com, 1 +plannedlink.com, 1 +planning.ga, 1 +planningsagenda.nl, 1 +plano.gq, 1 +planolowcarb.com, 1 +planosvivointernet.com.br, 0 +planosylicencias.de, 1 +planovivofibra.com.br, 1 +planrow.com, 1 +planshetnik.tk, 1 +plansight.com, 1 +plant-gift.jp, 1 +plantarportugal.org, 1 +plantastique.ch, 0 +plantdaddie.com, 1 +planteforum.no, 1 +plantekno.com, 1 +plantes.ch, 1 +plantezcheznous.com, 0 +planther.nl, 1 +plantprosperous.com, 1 +plantron.gr, 1 +plantroon.com, 1 +plantrustler.com, 1 +plantsupplement.co.uk, 1 +planujemywesele.pl, 1 +planungsregion-abw.de, 1 +planview.com, 1 +plaque-funeraire.fr, 1 +plaque-immatriculation-auto.com, 1 +plaredo.tk, 1 +plaros.ml, 1 +plasapulsa.tk, 1 +plashenkov.com, 1 +plaskiewicz.pl, 1 +plassmann.ws, 1 +plast.bg, 1 +plast.design, 1 +plastdesign.com.ua, 1 +plastex.tk, 1 +plastic2print.com, 1 +plasticobiodegradable.com, 1 +plasticosbiobasados.com, 1 +plasticstare.com, 1 +plasticsurgerynola.com, 1 +plasticsurgeryservices.com, 1 +plasticwindows.tk, 1 +plastiflex.it, 1 +plastischechirurgie-linz.at, 1 +plastovelehatko.cz, 1 +plateformecandidature.com, 1 +platform-med.org, 1 +platform.ltd.uk, 1 +platform2020prague.com, 1 +platforma2020praha.cz, 1 +platformadmin.com, 1 +platformcore.com, 1 +platformlms.org, 1 +platinapump.com, 1 +platiniumvapes.com, 1 +platinmods.my.id, 1 +platinumcat.info, 1 +platinumexpress.com.ar, 1 +platinumsystems.biz, 1 +platodecomida.com, 1 +platschi.net, 0 +platten-nach-mass.de, 1 +platter.ga, 1 +platterlauncher.com, 1 +platypiduses.com, 1 +plavdoma.com.ua, 1 +play, 1 +play-casino-japan.com, 1 +play-charades.com, 1 +play-lu.com, 1 +play-telochki.tk, 1 +play.cash, 1 +play.google.com, 1 +play3niu1.com, 1 +play3niu18.com, 1 +play3niu6.com, 1 +play3niu8.com, 1 +play3niu88.com, 1 +playabalares.ga, 1 +playandwin.co.uk, 1 +playanka.com, 1 +playasmiles.com, 1 +playawaycastles.co.uk, 1 +playblightnight.com, 1 +playcollect.net, 1 +playdaysparties.co.uk, 1 +playdlawosp.pl, 1 +playdrop.ml, 1 +playelephant.com, 1 +player.me, 1 +playerdb.co, 1 +playface.ml, 1 +playground.place, 1 +playhappywheelsunblocked.com, 1 +playinfinity.com, 1 +playinfinityvr.com, 1 +playit.rs, 1 +playlisten.radio.br, 1 +playmei.com, 1 +playmfe.com, 1 +playmytime.com, 1 +playnation.io, 1 +playnow.com, 1 +playnuganug.com, 1 +playocean.net, 1 +playorigin.com, 1 +playpirates.com, 1 +playpower.tk, 1 +playreal.city, 1 +playsnake.org, 1 +playsoftware.tk, 1 +playsprout.industries, 1 +playstation-network.ga, 1 +playstationplus.es, 1 +playstationtrophies.org, 1 +playtictactoe.org, 1 +playtoearn.net, 1 +playtop.tk, 1 +playtopia.com, 1 +playtopia.fr, 1 +playtopia.nl, 1 +playtopia.no, 1 +playtzolk.in, 1 +playupnow.com, 1 +playviolinmusic.com, 1 +playwhyyza.com, 1 +playxylo.com, 1 +playyou.be, 1 +plaza.ph, 1 +plazaproductionone.com, 1 +plazasummerlin.com, 1 +plcclosets.com, 1 +plcgurus.net, 1 +plchardware.com, 1 +pldx.org, 1 +ple-conseil.fr, 1 +pleasantonca.gov, 1 +pleasantonmobilenotary.com, 1 +please-uwu.me, 1 +pleaseuseansnisupportedbrowser.ml, 1 +pleasure-science.com, 1 +pleb.cc, 1 +plebeian.com.tw, 1 +pleger.tk, 1 +pleiar.no, 1 +pleier.no, 1 +pleindedemsvaart.tk, 1 +pleine-conscience.ch, 0 +plekker.be, 1 +plenigo.com, 1 +plenkanaotrez.ml, 1 +plentybetter.com, 1 +plentybetter.org, 1 +plesse.pl, 1 +plex-server.cz, 1 +plexa.de, 1 +plexbpvr.ddns.net, 1 +plexhome13.ddns.net, 1 +plexiglasssheetscuttosize.com, 1 +plexmark.net, 1 +plexmark.tk, 1 +plexnet.cz, 1 +plexpy13.ddns.net, 1 +plextv.de, 1 +plexusworldwide.com, 1 +plexverzoek.nl, 1 +pley.today, 1 +plgr.cc, 1 +plgr.tech, 1 +plichso.de, 1 +pliosoft.com, 1 +plissee-experte.de, 1 +plitu.de, 1 +plixar.com, 1 +plixer.com, 1 +plixer.net, 1 +plkeenecc.com, 1 +plob.org, 1 +plochka.bg, 1 +ploi.io, 1 +plokigames.com, 1 +plokko.com, 1 +plomberie-rivesud.ca, 1 +plongee-phuket.fr, 1 +plotbubble.com, 1 +plothost.com, 1 +ploxel.com, 1 +plr4wp.com, 1 +plsboop.me, 1 +plugboard.xyz, 1 +plugcubed.net, 0 +plugin-planet.com, 1 +pluginfactory.io, 1 +pluginhayati.tk, 1 +pluginsloaded.com, 1 +pluimveeplanner.nl, 1 +plum.fr, 1 +plumber-in-sandton.co.za, 1 +plumbercincoranch.com, 1 +plumberlewisvilletexas.com, 1 +plumbermountedgecombe.co.za, 1 +plumberumhlangarocks.co.za, 1 +plumbingandheatingspecialistnw.com, 1 +plumbingbenoni.co.za, 1 +plumbingcentral.com.au, 1 +plumbingglenvista.co.za, 1 +plumbingkingsllc.com, 1 +plumbingshop.tk, 1 +plumlocosoft.com, 1 +plumnet.ch, 1 +plumpie.net, 0 +plumplat.com, 1 +plumtreelaw.com, 1 +plumz.me, 1 +plur.com.au, 1 +plural.cafe, 1 +pluralistic.net, 1 +pluralpedia.org, 1 +pluricosmetica.com, 1 +plus-5.com, 1 +plus-aliance.ru, 1 +plus.google.com, 1 +plus.sandbox.google.com, 1 +plus15.ml, 1 +plus1s.site, 1 +plusbot.tk, 1 +pluslink.co.jp, 1 +plusmobile.fr, 1 +plusreed.com, 1 +plussizereviews.com, 1 +plustream.com, 1 +pluta.net, 1 +plutiedev.com, 1 +plutokorea.com, 1 +plutopia.ch, 1 +plymouthbouncycastles.co.uk, 1 +plymouthcountyiowa.gov, 1 +plz.report, 1 +plzdontpwn.me, 1 +plzen-sadrokarton.cz, 1 +plzen.fun, 1 +plzh4x.me, 1 +plzz.de, 1 +pm-onboarding-external-dev.azurewebsites.net, 1 +pm-partners-management-dev.azurewebsites.net, 1 +pm.gov.au, 1 +pm.link, 1 +pm.me, 1 +pm13.cz, 1 +pm13.org, 1 +pm25.im, 1 +pma-iss.com, 1 +pmalaty.com, 1 +pmarques.info, 1 +pmartin.tech, 1 +pmbc.org, 1 +pmbsteelbuildings.com, 1 +pmbtf.com, 1 +pmcc.net, 1 +pmccrystal.com, 1 +pmcfarland.space, 1 +pmcorganometallix.com, 1 +pmcouvrie.com, 1 +pmcvinyladditives.com, 1 +pmessage.ch, 1 +pmf.gov, 1 +pmg-offshore-company.com, 1 +pmg-p4p.de, 1 +pmg-purchase.com, 1 +pmg-purchase.net, 1 +pmi-install.com, 1 +pmk.ddns.net, 0 +pmklaassen.com, 1 +pmnaish.co.uk, 1 +pmnd.rs, 1 +pmoreau.org, 1 +pmoscr.com, 1 +pmp-art.com, 1 +pmp6.fr, 1 +pmpm.tk, 1 +pmrockstars.com, 1 +pms.myiphost.com, 1 +pmsacorp.com, 1 +pmsf.eu, 1 +pmsfdev.com, 1 +pmsg.ml, 1 +pmsoft.nl, 0 +pmt-documenten.nl, 1 +pmtcookware.com, 1 +pn.com.au, 1 +pn.id.lv, 1 +pnakosoft.com, 1 +pnakosoft.com.au, 1 +pnawrocki.com, 1 +pncfx.com, 1 +pneu01.fr, 1 +pneu74.fr, 1 +pneuhaus-lemp.ch, 1 +pneumatikos.me, 1 +pnimmobilier.ch, 0 +pnnl.gov, 1 +pnoec.org.do, 1 +pnona.cz, 1 +pnp.ac.id, 1 +pnsc.is, 1 +pnut.io, 0 +po-krasivi.bg, 1 +po-sha-go-vo.ru, 1 +po.net, 1 +po0k.ie, 1 +poc060.com, 1 +poc080.com, 1 +poc090.com, 1 +poc100.com, 1 +poc109.com, 1 +poc11.com, 1 +poc116.com, 1 +poc118.com, 1 +poc119.com, 1 +poc120.com, 1 +poc128.com, 1 +poc13.com, 1 +poc15.com, 1 +poc16.com, 1 +poc17.com, 1 +poc18.com, 1 +poc19.com, 1 +poc21.com, 1 +poc211.com, 1 +poc22.com, 1 +poc226.com, 1 +poc228.com, 1 +poc23.com, 1 +poc25.com, 1 +poc26.com, 1 +poc261.com, 1 +poc262.com, 1 +poc27.com, 1 +poc290.com, 1 +poc298.com, 1 +poc31.com, 1 +poc32.com, 1 +poc33.com, 1 +poc35.com, 1 +poc36.com, 1 +poc37.com, 1 +poc38.com, 1 +poc51.com, 1 +poc518.com, 1 +poc52.com, 1 +poc53.com, 1 +poc55.com, 1 +poc56.com, 1 +poc568.com, 1 +poc57.com, 1 +poc58.com, 1 +poc586.com, 1 +poc588.com, 1 +poc59.com, 1 +poc601.com, 1 +poc618.com, 1 +poc63.com, 1 +poc65.com, 1 +poc66.com, 1 +poc661.com, 1 +poc663.com, 1 +poc665.com, 1 +poc668.com, 1 +poc669.com, 1 +poc67.com, 1 +poc68.com, 1 +poc69.com, 1 +poc699.com, 1 +poc7.com, 1 +poc71.com, 1 +poc718.com, 1 +poc72.com, 1 +poc75.com, 1 +poc76.com, 1 +poc768.com, 1 +poc77.com, 1 +poc771.com, 1 +poc772.com, 1 +poc773.com, 1 +poc779.com, 1 +poc78.com, 1 +poc79.com, 1 +poc8.com, 1 +poc816.com, 1 +poc86.com, 1 +poc866.com, 1 +poc88.vip, 1 +poc8811.com, 1 +poc882.com, 1 +poc8822.com, 1 +poc883.com, 1 +poc8833.com, 1 +poc885.com, 1 +poc8855.com, 1 +poc886.com, 1 +poc8866.com, 1 +poc887.com, 1 +poc8877.com, 1 +poc888.com, 1 +poc889.com, 1 +poc8899.com, 1 +poc89.com, 1 +poc899.com, 1 +poc916.com, 1 +poc918.com, 1 +poc965.com, 1 +poc98.com, 1 +poc99.com, 1 +poc992.com, 1 +poc993.com, 1 +poc995.com, 1 +poc996.com, 1 +poc997.com, 1 +poc998.com, 1 +pocakking.tk, 1 +pocatellonissanparts.com, 1 +pochaneko.com, 1 +pochoden-praha.cz, 1 +pocitacezababku.cz, 1 +pocketbookdot.tk, 1 +pocketcraft.io, 1 +pocketdeer.cc, 1 +pocketfruity.com, 1 +pocketfullofkittens.com, 1 +pocketinsure.com, 1 +pocketmags.com, 1 +pocketpasta.com, 0 +pockets.jp, 1 +pocobelli.ch, 0 +pocze.ch, 1 +podari-radost.tk, 1 +podari.tk, 1 +podarki-deda-moroza.tk, 1 +podarkiboss.tk, 1 +podarky.gq, 1 +podarochek.tk, 1 +podarochkki.tk, 1 +podatrans.com, 1 +podcast.style, 1 +podcastmusic.com, 1 +podcrto.si, 1 +podd.xyz, 1 +podemos.info, 1 +poder.tech, 1 +podia.com.gr, 0 +podia.gq, 1 +podipod.com, 1 +podlibre.org, 1 +podo-podo.com, 1 +podobovo.if.ua, 1 +podologie-diever.nl, 1 +podroof.com, 1 +podroof.com.au, 1 +podshrink.de, 1 +podsvojostreho.net, 1 +podvenec.tk, 1 +poe-sensor.com, 1 +poed.com.au, 1 +poed.net.au, 1 +poemasonline.tk, 1 +poemerx.com, 1 +poemerx.net, 1 +poemindia.cf, 1 +poemlife.com, 1 +poems-bodywear.store, 1 +poemwall.ml, 1 +poenhub.xyz, 1 +poesiafm.tk, 1 +poetasmenores.tk, 1 +poetenblog.tk, 1 +poetka.tk, 1 +poetry.ge, 1 +poetryinmusic.tk, 1 +poetsjeboot.nl, 1 +poezja.art, 1 +poezja.com.pl, 1 +poezjagala.pl, 1 +poffenhouse.ddns.net, 1 +pogera.com, 1 +pogetback.pl, 1 +pogljad-brest.tk, 1 +pogodavolgograd.tk, 1 +pogodok.tk, 1 +pogomate.com, 1 +pogoswine.com, 1 +pogotowiekomputeroweolsztyn.pl, 1 +pogrebisky.net, 1 +pogs.us, 1 +pohatta.com, 1 +pohica.com, 1 +pohlmann.io, 1 +pohoron.ru, 1 +poi-radary.eu, 1 +poiema.com.sg, 0 +poimel.ga, 1 +poinsot.info, 1 +point-to-point.org, 1 +point.pink, 1 +pointaction.com, 1 +pointagri.com, 1 +pointcab.vn, 1 +pointclickcare.com, 1 +pointer2.com, 1 +pointermate.com, 1 +pointforwardinc.net, 1 +pointhost.de, 1 +pointiswunderland.de, 1 +pointmaquininha.com, 1 +pointpalace.tk, 1 +points-pote.com, 1 +points4unitedway.com, 1 +pointsixtyfive.com, 1 +pointum.com, 1 +pointworksacademy.com, 1 +pointzip.ml, 1 +poiru.net, 1 +poisk-books.ml, 1 +poisk.kharkov.ua, 1 +poiskdru.ga, 1 +poiskkladov.tk, 1 +poiskkristinity.ml, 1 +poiskrus.ml, 1 +poisoncolombia.tk, 1 +poisonget-rid-ofac.tk, 1 +poitiers-ttacc-86.eu.org, 1 +pojdnafp.cz, 1 +pojer.me, 1 +pokalsocial.de, 1 +pokazy-iluzji.pl, 1 +poke.blue, 1 +pokedex.mobi, 1 +pokefarm.com, 1 +pokeforest.io, 1 +pokeinthe.io, 1 +pokelens.tk, 1 +pokeli.de, 1 +pokemmo.eu, 1 +pokemonargentina.tk, 1 +pokemondb.net, 1 +pokemonforums.tk, 1 +pokemongochamp.com, 1 +pokemongoclub.tk, 1 +pokemongosearch.com, 1 +pokemongostatus.org, 1 +pokemonguide.tk, 1 +pokemonlab.com, 1 +pokemonsimulator.com, 1 +pokemontabletopadventures.com, 1 +pokemori.jp, 1 +pokepon.center, 1 +poker4all.tk, 1 +pokeram.ml, 1 +pokerblog.tk, 1 +pokerking.club, 1 +pokermix.ca, 1 +pokerslab.com, 1 +pokerventure.ga, 1 +pokkareindeermeat.com, 1 +pokl.cz, 1 +pokoiki.pl, 1 +pokon548.ink, 1 +pokpok.tk, 1 +pokrowcecardo.pl, 1 +pokupaisumom.ee, 1 +pokupkionline.tk, 1 +polaire.org, 1 +polak-import.tk, 1 +polan.tk, 1 +polanda.com, 1 +polandb2b.directory, 1 +polar-baer.com, 1 +polarauto.pt, 1 +polarhome.tk, 1 +polaristaxandaccounting.com, 1 +polaroidmag.com, 1 +polaschin.ch, 1 +polaxtor.com, 1 +poldrack.me, 1 +pole-emotion.ch, 0 +poleacademie.com, 0 +poleartschool.com, 0 +polebarn.com, 1 +poleka.co, 1 +polemik.tk, 1 +polestar.com.tw, 1 +poletaem.tk, 1 +police-schools.com, 1 +policereferencecheck.com, 1 +policesromandesrecrutement.ch, 1 +policymakr.com, 1 +policyreporter.com, 1 +policyreporter.us, 1 +polifisio.com.br, 1 +poliground.com, 1 +polimer39.ml, 1 +polina-gagarina.gq, 1 +polinet.de, 1 +polioptics.com, 1 +polis.or.at, 1 +polis.to, 0 +polis812.ru, 1 +polisanaraka.pl, 1 +polisanarciarska.pl, 1 +polish-dictionary.com, 1 +polish-flag.com, 1 +polish-translations.com, 1 +polish-translator.com, 1 +polish-translator.net, 1 +polish-translators.net, 1 +polish.directory, 1 +polishdating.cf, 1 +polishforums.com, 0 +polishhockey.tk, 1 +polishmarriage.org, 1 +polishmodels.net, 1 +polishtranslation.com, 1 +polishwomen.com, 1 +polisipati.tk, 1 +polisport.tk, 1 +polisynazycie.com.pl, 1 +polit-it.pro, 1 +polit.im, 1 +politeka.net, 1 +politic.org.ua, 1 +political-science-schools.com, 1 +politicalasylum.tk, 1 +politicalle.com, 1 +politicalplot.com, 1 +politicaprivacidade.com, 1 +politiciancompare.com, 1 +politicnation.com, 1 +politicsandnews.cf, 1 +politicsnews.ga, 1 +politiegent.be, 1 +politiezoneriho.be, 1 +politik-bei-uns.de, 1 +politisor.com, 1 +politoboz.com, 1 +politsei.ee, 1 +politvesti.tk, 1 +polizeiwallis.ch, 0 +polkhealthforanewyou.net, 0 +polki.com, 1 +pollendine.co.uk, 1 +pollet-ghijs.be, 1 +pollet-ghys.be, 1 +polletmera.com, 0 +pollev.com, 1 +polleverywhere.com, 1 +polliconstruction.com, 1 +pollies.nl, 1 +polliga.tk, 1 +pollingplace.uk, 1 +pollpodium.nl, 1 +polly.spdns.org, 1 +pollybarks.com, 1 +pollyundpaule.de, 1 +polmods.com, 1 +polog.tk, 1 +pologalileo.eu, 1 +polomack.eu, 1 +poloniainfo.com, 1 +polonialidzbark.tk, 1 +polskiemalzenstwo.org, 1 +polskienewsy.tk, 1 +poly-fast.com, 0 +polyairepricebook.com.au, 1 +polybius.io, 1 +polycoise.com, 1 +polycraftual.co.uk, 1 +polyfluoroltd.com, 0 +polygamer.net, 1 +polygraphi.ae, 1 +polymake.org, 1 +polymathian.com, 1 +polymerclay.de, 1 +polymorph.rs, 1 +polymtl.ca, 1 +polynomapp.com, 1 +polypane.rocks, 1 +polypet.com.sg, 1 +polyr.xyz, 1 +polytarian.com, 1 +polytechecosystem.vc, 1 +polytekniskforening.dk, 1 +pomadgw.xyz, 1 +pomba.pl, 1 +pomdoc.com, 1 +pomelo-paradigm.com, 1 +pomfeed.fr, 1 +pommedepain.fr, 1 +pomockypredeti.sk, 1 +pomocniczy.eu.org, 1 +pomogidrugu.tk, 1 +pomogite.ml, 1 +pomorskibereg.ml, 1 +pomozmruczkom.pl, 1 +pompefunebrilariviera.it, 0 +pompeii.tickets, 1 +pompo.com.br, 1 +pompoco.info, 1 +pomsinoz.com, 1 +pomtom.co.nz, 1 +ponca-nsn.gov, 1 +poncho-bedrucken.de, 0 +pondof.fish, 1 +poneypourtous.com, 0 +ponga.se, 1 +ponio.org, 1 +ponio.xyz, 1 +ponnau.com, 1 +ponnohaat.com, 1 +ponpon05.com, 1 +ponselsoak.com, 1 +ponsot.cloud, 1 +ponte-camp.de, 1 +pontiwerx.com.au, 1 +pontodogame.com.br, 1 +ponxel.com, 1 +pony-cl.co.jp, 1 +pony.tf, 1 +ponyar.net, 1 +ponychan.net, 1 +ponycyclepals.co.uk, 1 +ponydesignclub.nl, 1 +ponyfoo.com, 1 +ponyhof-muensterland.de, 1 +ponzi.life, 1 +poobert.tk, 1 +poodleassassin.com, 1 +poodlefan.net, 1 +pookl.com, 1 +pool-selber-bauen.de, 1 +poolheatingsolutionswa.com.au, 1 +poolinstallers.co.za, 1 +poollicht.be, 1 +poolmans.se, 1 +poolpowershop.de, 1 +poolsafely.gov, 1 +poolsafety.gov, 1 +poolsonline.tk, 1 +poolspondsandwaterscapes.com, 1 +pooltools.net, 1 +poon.io, 1 +poopjournal.rocks, 1 +poopr.ru, 1 +poopthereitisla.com, 1 +poorclarepa.org, 1 +pooteng.com, 1 +pop-culture.tk, 1 +pop.dk, 1 +pop3.jp, 0 +pop3.support, 1 +popcat.ru, 1 +popcorncult.ru, 1 +popcornpalacefundraising.com, 1 +popcultureshack.com, 1 +popecountyar.gov, 1 +popfitclothing.com, 1 +popflow.gq, 1 +popimed.com, 1 +popinga.it, 1 +popitsnack.com, 1 +popjudge.ml, 1 +popka.sk, 1 +popki.tk, 1 +popkins.cf, 1 +popkins.ga, 1 +popkins.gq, 1 +popkins.ml, 1 +popkins.tk, 1 +popkultura.info.pl, 1 +popl.uz, 1 +poplavok77.tk, 1 +popmagz.com, 1 +popmundoforum.tk, 1 +popotesetcocottes.fr, 1 +popotomodem.com, 1 +popova.tk, 1 +popoway.cloud, 1 +popoway.me, 1 +popoway9.ml, 1 +poppetsphere.de, 1 +poppingdance.tk, 1 +poppinspayroll.com, 1 +poppylala.com, 1 +poptattoo.tk, 1 +popular-male-kitten-names.tk, 1 +populardiets.tk, 1 +populardogs.gq, 1 +population-ethics.com, 1 +popup-stores.online, 1 +popupbazaar.tk, 1 +popvitrin.com, 1 +popxclusive.com, 1 +poquiloco.com, 1 +poquvi.net, 0 +porady-wnetrzarskie.pl, 1 +poradywnetrzarskie.pl, 1 +porchdaydreamer.com, 1 +porcore.com, 1 +porelcorazon.com, 1 +porelsam.ml, 1 +porevo.tk, 1 +porg.es, 1 +poriadok.eu, 1 +porinnuotiopojat.tk, 1 +pork.org.uk, 1 +porka.gq, 1 +porkbun.com, 1 +porkmart.ga, 1 +porkolab.digital, 1 +porkpiesonline.co.nz, 1 +porm.club, 1 +porn2019.tk, 1 +porn77.info, 1 +pornagent.de, 1 +pornalpha.com, 1 +pornbabetyra.net, 1 +pornbay.eu, 1 +pornbay.org, 1 +pornblog.org, 1 +pornbot.co, 1 +porncompanions.com, 1 +porndoe.com, 1 +porndragon.net, 1 +pornfacefinder.com, 0 +pornflare.net, 1 +pornforwomentube.com, 1 +pornfreesites.com, 1 +pornfriends.tk, 1 +porngay.co, 1 +pornhib.xyz, 1 +pornhun.xyz, 1 +pornimg.net, 1 +porniwi.com, 1 +pornkit.net, 1 +pornleg.com, 0 +pornless.biz, 1 +pornline.porn, 1 +pornline.sex, 1 +pornloupe.com, 1 +pornmad.com, 1 +pornmax.net, 1 +pornmega.net, 1 +porno-geschichten.com, 1 +porno-gif.ru, 1 +porno-stars-video.ru, 1 +porno.watch, 1 +pornoclips.net, 1 +pornodvdkopen.nl, 1 +pornofilme.top, 1 +pornofilmovi.us, 1 +pornogam.porn, 1 +pornogo.sex, 0 +pornogo.tube, 1 +pornohypnosis.tk, 1 +pornojimo.com, 1 +pornokran.com, 1 +pornolab.su, 1 +pornolarizlehd.com, 1 +pornomens.be, 1 +pornomovies.mobi, 1 +pornomovieshd.com, 1 +pornopark.nl, 1 +pornopica.com, 1 +pornopica.com.br, 1 +pornorapido.net, 1 +pornotexte.com, 1 +pornovk.xxx, 1 +pornoxxx.online, 1 +pornport.org, 1 +pornquebec.com, 1 +pornshop.biz, 1 +pornsocket.com, 1 +pornstop.net, 1 +pornsuper.net, 1 +pornteddy.com, 1 +porntop100.com, 1 +pornultra.net, 1 +pornvidsfree.com, 1 +pornxxnxx.com, 1 +pornxxxvideos.xyz, 1 +porny.xyz, 1 +porondam.lk, 1 +pororoca.xyz, 1 +pors-sw.cz, 1 +porschen.fr, 1 +porsi.pt, 1 +porsiaedenora.it, 1 +porsolt.com, 1 +port.gdynia.pl, 1 +port.im, 1 +port.social, 1 +port443.hamburg, 0 +port443.se, 1 +port5060.net, 1 +port67.org, 1 +port80.hamburg, 0 +portable-games.tk, 1 +portablespeakers.tk, 1 +portablespeakersfinder.com, 1 +portaequipajes.online, 1 +portagecounty-oh.gov, 1 +portagein.gov, 1 +portal-books.ga, 1 +portal-ru.tk, 1 +portal-uang.com, 1 +portal.tirol.gv.at, 0 +portaladictos.tk, 1 +portalcarriers.com, 1 +portaleldense.tk, 1 +portalexpressservices.com, 1 +portalm.tk, 1 +portalmundo.xyz, 1 +portalmv.com, 1 +portalpandalandia.tk, 1 +portalz.xyz, 1 +portamiinpista.it, 0 +portatiles-baratos.net, 1 +portativ-mobi.tk, 1 +portchesterny.gov, 1 +porte.roma.it, 1 +portefeuillesignalen.nl, 0 +porterpeds.com, 1 +porterranchelectrical.com, 1 +portesmagistral.com, 1 +portfolio-alberto.es, 1 +portfoliobox.net, 1 +portfreezone.com, 1 +porthos.com.ar, 1 +porthys.pt, 1 +portiaweb.org.uk, 1 +portierato.it, 1 +portoccd.org, 0 +portofala.pt, 1 +portofrotterdam.com, 0 +portokalliali.tk, 1 +portorchardwa.gov, 1 +portosonline.pl, 1 +portovelhoshopping.com.br, 1 +portsdebalears.gob.es, 1 +portsmouthbouncycastles.co.uk, 1 +portsmoutheic.com, 1 +portsmouthohpd.gov, 1 +portsmouthsheriffsofficeva.gov, 1 +portsolent.com, 1 +portstal.ru, 1 +portugal-a-programar.pt, 1 +portugal-reisetipps.de, 1 +portugalivre.tk, 1 +portugalsko.net, 1 +portugalsurflessons.com, 1 +portusidades.com.pt, 1 +portvaletickets.com, 1 +porwal.pl, 1 +porybox.com, 1 +porzellantreff.de, 1 +posaunenchor-senden.de, 1 +posbank.co.uk, 1 +posbich.net, 1 +poseidonwaterproofing.com, 1 +poshcastles.co.uk, 1 +poshe.tk, 1 +poshlashes.se, 1 +poshmark.com, 1 +poshsecurity.com, 1 +poshvine.com, 0 +posicioncero.com, 1 +posied.ga, 1 +posijson.stream, 1 +positionus.io, 1 +positive-thinking-for-you.com, 1 +positive.com.cy, 1 +positive.photography, 1 +positivefocus.ie, 1 +positivenames.net, 1 +positiverbeitrag.net, 1 +positiverbeitrag.org, 1 +positivityeffect.com, 1 +positivos.tk, 1 +positronicmoron.tk, 1 +poskok.info, 1 +posoco.in, 1 +posoiu.net, 1 +posowetuite.ru, 1 +pospisilik.eu, 1 +pospisilikovi.cz, 1 +post-anon.tk, 1 +post-darwinian.com, 1 +post-darwinism.com, 1 +post-office.tk, 1 +post.com.ar, 1 +post.io, 1 +post.monster, 1 +post4me.at, 1 +postacyprus.com, 1 +postal.dk, 1 +postal3.es, 1 +postandfly.com, 1 +postari.ro, 1 +postat.com, 1 +postawnasiebie.pl, 1 +postback.io, 0 +postblue.info, 1 +postbox.life, 1 +postcardpayment.com, 1 +postcode.nl, 1 +postcodeswag.co.uk, 1 +postcodeswag.com, 1 +postcodeswag.uk, 1 +postcrossing.com, 1 +postdarwinian.com, 1 +postdarwinism.com, 1 +postdeck.de, 1 +posteo.de, 1 +postermywall.com, 1 +postern.org, 1 +posters.win, 1 +posterspy.com, 1 +postex.com, 1 +postfalls-naturopathic.com, 1 +postfinance.ch, 1 +postfree.gr, 1 +postimages.org, 1 +postimg.cc, 1 +postlogistic.tk, 1 +postman.ga, 1 +postmarka.tk, 1 +postmart.vn, 1 +postmatescode.com, 1 +postmistress.email, 1 +postmoderns.info, 1 +postmusicologia.tk, 1 +postn.eu, 1 +postofficenear.com, 1 +postoyanstvo.cf, 1 +postpot.co.kr, 1 +postroim.tk, 1 +postsubmeta.net, 1 +posttigo.com, 1 +posturografia.info, 1 +posturographie.info, 1 +posturography.courses, 1 +posturography.education, 1 +posturography.equipment, 1 +posturography.info, 1 +posturography.science, 1 +posturography.software, 1 +posturography.solutions, 1 +posturography.systems, 1 +posturography.training, 1 +posturologie.info, 1 +posukovskaschola.cz, 1 +posutochno.ml, 1 +posyperfume.com, 1 +potatiz.com, 1 +potato.im, 1 +potatodiet.ca, 1 +potatotee.com, 1 +potatron.tech, 1 +potature.it, 1 +potature.org, 1 +potature.rimini.it, 1 +potature.roma.it, 1 +potbar.com, 1 +potcha.net, 1 +potentialunlockedtuition.com, 1 +poterepersonale.it, 1 +poterscy.pl, 1 +potgrowersunion.com, 1 +pothe.com, 1 +pothe.de, 1 +potionlabs.de, 1 +potkani.tk, 1 +potlytics.com, 1 +potolok-brest.tk, 1 +potolok.am, 1 +potomac.cf, 1 +potomacurology.com, 1 +potomania.cz, 1 +potosi-bolivia.tk, 1 +potrahushki.tk, 1 +potreningu.pl, 1 +potrillionaires.com, 1 +potsdam.directory, 1 +potterish.com, 1 +potterperfect.tk, 1 +pottersheartministry.org, 1 +pottershouse.tk, 1 +potterybroker.ga, 1 +pottshome.co.uk, 1 +potty.party, 1 +potvorka.tk, 1 +potwin.tk, 1 +potworowski.de, 1 +potz.tk, 1 +potzwonen.nl, 1 +pouchulu.tk, 1 +poudlard.fr, 1 +pouets.ovh, 1 +poun.tk, 1 +poundgatepark.co.uk, 1 +poupee.me, 1 +pouwels-oss.nl, 1 +povar.ru, 1 +povarenok.cf, 1 +povareschka.ru, 1 +povareshka.tk, 1 +povesham.tk, 1 +povmacrostabiliteit.nl, 1 +pow-s.com, 1 +pow.jp, 1 +powch.com, 1 +powdercoatatl.com, 1 +powdercoatingatl.com, 1 +powderedcloud.ga, 1 +powderspraymachine.com, 1 +powelljones.co.uk, 1 +power-coonies.de, 1 +power-flowengineer.com, 1 +power-magnetic.ml, 1 +power-tools24.com, 1 +poweranalitica.com, 1 +powerb.ch, 0 +powerbalance.tk, 1 +powerball.cf, 1 +powerball.club, 1 +powerball.shop, 1 +powerbi.istanbul, 1 +powerblanket.com, 1 +powercomputers.nl, 1 +poweredbyiris.nl, 1 +powerentertainment.tv, 1 +powerforpeople.tk, 1 +powerfortunes.com, 1 +powergridess.com, 0 +powerhockey.info, 1 +powerinboxperformance.com, 1 +powerlifting.tk, 1 +powermeter.at, 1 +powerofsocialtech.com, 1 +powerofwater.fish, 1 +powerpadel.com, 1 +powerplanter.com, 1 +powerplantmall.com, 1 +powerplayer.tk, 1 +powerpointschool.com, 1 +powersaleskc.com, 1 +powerscif.com, 1 +powerserg.net, 1 +powerserg.us, 1 +powersergdatasystems.com, 1 +powersergdynamic.com, 1 +powersergedatasystems.com, 1 +powersergfeds.com, 1 +powersergholdings.com, 1 +powersergisrc.com, 1 +powersergmysteryshopping.com, 1 +powersergpiv.com, 1 +powersergsis.com, 1 +powersergthisisthetunnelfuckyouscott.com, 1 +powersergthisisthewebsitefuckyouchris.com, 1 +powersergthisisthewebsitefuckyouscott.com, 1 +powersergunited.com, 1 +powersergunited.org, 1 +powersergusercontent.com, 1 +powershellmagic.com, 1 +powersolusa.com, 1 +powerspeaking.com, 1 +powersubmitter.tk, 1 +powersurgedatasystems.com, 1 +powertoolsrater.net, 1 +powertop.com, 1 +poweruser.su, 1 +powerwellness-korecki.de, 1 +powerzonewrestling.tk, 1 +poylabo.com, 1 +poynter.net, 1 +pozarevac.tk, 1 +pozd.tk, 1 +pozega.eu, 1 +pozemedicale.org, 1 +pozharnyi.tk, 1 +pozitiffchik.cf, 1 +pozitiffchik.ml, 1 +pozitiffchik.tk, 1 +pozitiv.gq, 1 +pozitive.pl, 1 +pozitone.com, 1 +poziworld.com, 1 +pozlife.net, 1 +poznaj-siebie.pl, 1 +poznajrynek.pl, 1 +poznannoe-nepoznannoe.ru, 1 +poznavatelno.ml, 1 +pozzitiv.ro, 1 +pp3345.net, 1 +pp5197.co, 1 +pp6729.co, 1 +pp6729.com, 1 +pp6957.co, 1 +pp9297.co, 1 +pp9397.com, 1 +pp9721.com, 1 +pp9728.co, 1 +ppapogey.com, 1 +ppapogey.ru, 1 +ppbi.com, 1 +ppcads.agency, 1 +ppcrestaurants.com, 1 +ppipe.net, 1 +ppissis.com.cy, 1 +pplsoft.nl, 1 +pplsvc.com, 1 +ppmathis.ch, 1 +ppmathis.com, 1 +ppmoon.com, 1 +ppoou.co.uk, 1 +ppoozl.com, 1 +pppo.gov, 1 +ppro.com, 1 +pptavmdata.org, 1 +ppweb.pro, 1 +ppy.la, 1 +ppy.sh, 1 +pqd.ru, 1 +pqgruber.com, 1 +pqscript.com, 1 +pr-news.spb.ru, 1 +pr-project.tk, 1 +pr-release.top, 1 +pr.search.yahoo.com, 0 +pr1sm.com, 1 +pr2studio.com, 1 +pr3-space-staging.ga, 1 +pr3.space, 1 +pra.rip, 1 +prac.to, 1 +pracevjihlave.cz, 1 +practicalbytes.de, 1 +practicalhomes.com.au, 1 +practicallabs.com, 1 +practicalprogrammer.tech, 1 +practicepanther.com, 1 +practisforms.com, 1 +practixdevelopment.com, 1 +practo.com, 1 +practodev.com, 1 +pradeek.tk, 1 +pradersystems.ch, 1 +pradmin.ru, 1 +prado.it, 1 +pradohalcones.com, 1 +praeparation-keppner.de, 1 +praerien-racing.com, 1 +praetzlich-hamburg.de, 1 +pragatiparasguesthouse.co.in, 1 +prageeth-niranjan.tk, 1 +pragma-solution.com, 0 +pragmatist.nl, 1 +pragtravel.cf, 1 +prague-swim.cz, 1 +praguepsychology.com, 1 +praguepsychology.cz, 1 +pragueswim.cz, 1 +praha-9.eu, 1 +praha-kominictvi.cz, 1 +praha.tk, 1 +praiagrande.tk, 1 +praiss.net, 1 +praizeej.com, 1 +prajwal-koirala.com, 1 +prakhar.uk, 1 +prakharprasad.com, 1 +praksite.fr, 1 +praktijkdeeersteindruk.nl, 1 +praktijkdevecht.nl, 1 +praktijkpassepartout.nl, 1 +praktijktian.be, 1 +praktiker.hu, 1 +praktikum.tk, 1 +praleria.com, 1 +pranabesh.com, 1 +pranafilms.tk, 1 +prancor.ru, 1 +pranita-schals.de, 1 +pranita.cz, 1 +pranita.sk, 1 +prankawards.ga, 1 +pranksearch.ml, 1 +prankstercompany.com, 1 +prashantcafe.tk, 1 +prasos.fi, 1 +prasso.se, 1 +prateep.io, 1 +pratemarkets.com, 1 +praticienmedecinechinoise.be, 1 +pratopronto.org, 1 +pratorotoli.it, 1 +pravagolosa.gq, 1 +praveenravichandran.xyz, 1 +pravlife.ru, 1 +pravnisistem.rs, 1 +pravo-brest-belarus.tk, 1 +pravo911.tk, 1 +pravoslavie.tk, 1 +pravoslavnayarus.tk, 1 +pravosudie.tk, 1 +praxino.de, 0 +praxis-dingeldey.de, 1 +praxis-familienglueck.de, 1 +praxis-kobiella.de, 1 +praxis-liebner.de, 1 +praxis-waedicity.ch, 1 +praxisfilms.org, 1 +praxistipp24.com, 1 +prayag.tk, 1 +prayercentric.com, 1 +prayerrequest.com, 1 +prayum.com, 1 +prazdnik-volgodonsk.tk, 1 +prazdniki-sait.tk, 1 +prazdniktost.tk, 1 +prazeresdavida.com.br, 1 +prc.gov, 1 +prcarrier.tk, 1 +prdashboard.tk, 1 +pre-renewal.com, 1 +pread.fr, 1 +preambulecommunication.com, 1 +precambridge.tk, 1 +precedecaritas.com.br, 1 +precedencemedia.com, 1 +precedenceum.com, 1 +precept.uk.com, 1 +preci0.com, 1 +preciadictos.tk, 1 +preciouslife.fr, 1 +preciscx.com, 1 +preciseassemblies.com, 1 +precision-tops.com, 1 +precision.st, 1 +precisionclan.com, 1 +precisioncoolingco.com, 1 +precisiondentalnyc.com, 1 +precisiondigital-llc.com, 1 +precisionhealthpilot.org, 1 +precisionhockey.net, 1 +precisionicerinks.com, 1 +precisionlender.com, 0 +precisionmachineservice.com, 1 +precisionsportsonline.com, 1 +precisionstocks.com, 1 +precisionvaccinations.com, 1 +precode.eu, 1 +predalco.be, 1 +predatorworld.tk, 1 +predckazanie.ru, 1 +predkosci.pl, 1 +predmetnyj-fotograf.by, 1 +prednisolone1.gq, 1 +predoiu.ro, 1 +predskazanie.cf, 1 +predskazanie.ml, 1 +predskazanie.tk, 1 +predstavitelstvo-v-sude.tk, 1 +prefabricadosdelcaribe.com, 1 +prefabrik-ev.co, 1 +prefabrik-ev.com, 1 +preference.ga, 1 +preferredreverse.com, 1 +prefix.eu, 1 +prefontaine.name, 1 +pregen.tk, 1 +prego-shop.de, 1 +preguntasdeciudadania.com, 1 +pregunteleakaren.gov, 1 +preigu.de, 1 +preis-alarm.info, 1 +preis-alarm.org, 1 +preis-reifen.de, 1 +preisser-it.de, 1 +preisser.it, 1 +preissler.co.uk, 0 +prekladysanca.cz, 1 +prelesti.tk, 1 +prelist.org, 1 +preload.link, 1 +preloaded-hsts.badssl.com, 1 +prelogica.com.br, 1 +preludes.org, 1 +prelved.com, 1 +prelved.es, 1 +prelved.fi, 1 +prelved.fr, 1 +prelved.it, 1 +prelved.nl, 1 +prelved.pl, 1 +prelved.se, 1 +prematureacceleration.club, 1 +preme.name, 1 +premier-podiatry.com, 1 +premierbb.com, 1 +premierbouncycastles.co.uk, 1 +premiercreditmasters.com, 1 +premierdisco.co.uk, 1 +premiereco.com.sg, 1 +premieresloges.ca, 0 +premierheart.com, 1 +premierjewelersjax.com, 1 +premierleague.gq, 1 +premiermaldives.com, 1 +premiermortgageservices.com, 1 +premierpups.com, 1 +premierrisksolutions.com, 1 +premiership-predictors.co.uk, 1 +premierwebservice.com, 1 +premierwomensrobotic.com, 1 +premioambiente.it, 1 +premiovapozicovna.sk, 1 +premised.land, 1 +premium-computer.fr, 1 +premium-job.ru, 1 +premiumcbd.cz, 1 +premiumcredit.am, 1 +premiumdeal.org, 1 +premiumhosting.com.hr, 1 +premiumlegalsupport.ga, 1 +premiumplusiptv.com, 1 +premiumwebdesign.it, 1 +premkumar.net, 1 +premsarswat.me, 1 +premtech.nl, 1 +prepa-benjam.fr, 1 +prepadefi.fr, 1 +prepagosyescortforyou.com, 1 +prepaid-cards.xyz, 1 +prepaid-voip.nl, 1 +prepaidgirl.com, 1 +prepaidkredietkaart.be, 1 +prepare-job-hunting.com, 1 +preparetheword.com, 1 +prepavesale.fr, 1 +prepfba.com, 1 +preply.com, 1 +prepperswill.com, 1 +preppertactics.com, 1 +preprodfan.gov, 1 +prepscouts.tk, 1 +prepsiedy.cf, 1 +prepz.es, 1 +presbee.com, 1 +presbvm.org, 1 +presbyterian-colleges.com, 1 +preschoole.gq, 1 +prescotonline.co.uk, 1 +presdesdunes.com, 1 +presenciainternet.com, 1 +present-m.com, 1 +presentacionesweb.com, 1 +presentationmedia.com, 1 +preservegrandcountyhistory.org, 1 +preserveourhillcountry.org, 1 +preserverollinspass.org, 1 +preserving.tk, 1 +president.bg, 1 +presidentdirectory.ga, 1 +presidentialinnovationfellows.gov, 1 +presidentialserviceawards.org, 1 +presidentinternet.org, 1 +presidio.gov, 1 +presly.org, 1 +presnya.tk, 1 +press-presse.ca, 1 +press-wall24.ru, 1 +pressakey.com, 1 +pressakey.de, 1 +presscenter.jp, 1 +presscuozzo.com, 1 +presseagrume.net, 1 +pressento.com, 1 +pressertech.com, 1 +presses.ch, 0 +pressfreedomtracker.us, 1 +pressnetwork.tk, 1 +pressnewscafe.gq, 1 +pressography.org, 1 +pressrush.com, 1 +pressspace2hack.com, 1 +pressspacetohack.com, 1 +pressup.it, 1 +pressureradio.com, 1 +prestatyn-scala.info, 1 +prestatynflowershow.co.uk, 1 +prestige-car-location.ch, 0 +prestigebouncycastles.co.uk, 1 +prestigeeventshire.co.uk, 1 +prestigerepairs.com.au, 1 +prestigesoundandlight.co.uk, 1 +prestigeworldwidepr.com, 1 +prestigiouskitchen.com, 1 +prestonandsons.com.au, 1 +prestonapp.com, 1 +prestonbrant.com, 1 +prestopizzas63.fr, 1 +prestupniki.tk, 1 +pretalx.com, 1 +prethost.com, 1 +pretix.eu, 1 +pretor-sa.com, 1 +pretor.com.pl, 1 +pretor.eu, 1 +pretorcup.pl, 1 +pretty-liars.tk, 1 +pretty.hu, 1 +prettyceos.com, 1 +prettycities.ga, 1 +prettygirlcheats.com, 1 +prettymama.co.uk, 1 +prettynode.com, 0 +prettytunesapp.com, 1 +pretzelhands.com, 0 +pretzelx.com, 1 +prevenir.ch, 0 +preventfalls.com, 1 +preventshare.com, 1 +preview-it-now.com, 1 +previh.eu, 1 +previous.one, 1 +previousmagazine.com, 1 +previsiemens.com.br, 1 +previsora.gov.co, 0 +previstart.com, 1 +prevodkazet.cz, 1 +prexxorvita.com, 1 +preziti.eu, 1 +prgrmmr.nl, 1 +priboutiquedasflores.com.br, 0 +price-tracker.duckdns.org, 1 +price.bond, 1 +pricedaily.pk, 1 +pricegg.com, 1 +priceholic.com, 1 +priceless-jewelry.com, 1 +pricelesspics.tk, 1 +pricelikeit.com, 1 +pricelistforbxmodules.ga, 1 +pricelooper.com, 0 +priceofdollar.com, 1 +priceremoval.net, 1 +pricesdoors.com, 1 +pricesniffer.co, 1 +pricetum.com, 1 +pricevortex.com, 1 +prideindomination.com, 1 +pridnestrovye.gq, 1 +prielwurmjaeger.de, 1 +priestess.tk, 1 +priestessbali.com, 1 +prifo.se, 1 +prij.fr, 1 +prijmeni.eu, 1 +prijsvergelijken.ml, 1 +prikolkz.tk, 1 +prima-assol.com, 1 +primaconsulting.net, 1 +primaflorafloristaccrington.co.uk, 1 +primakeysmarketingsolutions.com, 1 +primalinea.pro, 1 +primalshop.dk, 1 +primalsurvivor.net, 1 +primananda.com, 1 +primark.guru, 1 +primary.fit, 1 +primates.com, 1 +primaveradesign.com.br, 1 +primbit.ru, 1 +prime-host.ml, 1 +primeauconsultinggroup.com, 1 +primecursos.com.br, 1 +primeequityproperties.com, 1 +primegiftindia.com, 1 +primekinoshita.com, 1 +primelendingdallasfw.com, 1 +primelogistics.cf, 1 +primeops.co, 1 +primerdeal.com, 1 +primersbc.com.br, 1 +primetics.co.uk, 1 +primeticsseed.com, 1 +primeview.com, 1 +primglaz.ru, 1 +primitiv.tk, 1 +primitivehuman.com, 1 +primoloyalty.com, 1 +primopan.org, 1 +primordialsnooze.com, 1 +primorus.lt, 1 +primos-tech.com, 1 +princedavidlodge.org.uk, 1 +princefamilylaw.co.uk, 1 +princelishan.com, 1 +princelishan.com.tw, 1 +princemathew.tk, 1 +princemolak.ga, 1 +princesparktouch.com, 1 +princess-vip-escort.com, 1 +princess.software, 1 +princessbackpack.de, 1 +princessefoulard.com, 1 +princesspawg.tk, 1 +princetonnassaupediatrics.com, 1 +princetonradiationoncology.com, 1 +princez.uk, 1 +princezna.club, 1 +principalsexam.com, 1 +principalship.net, 1 +principalstest.com, 1 +principaltoolbox.com, 1 +principedepaz.gt, 1 +principia-journal.de, 1 +principia-magazin.de, 1 +principia-online.de, 1 +princovi.cz, 1 +prinesec.com, 1 +prinice.org, 1 +print-street.tk, 1 +printeknologies.com, 1 +printerinks.ie, 1 +printerinktoutlet.nl, 1 +printerleasing.be, 1 +printertonerkopen.nl, 1 +printexpress.cloud, 1 +printfn.com, 0 +printguru.dk, 1 +printler.com, 1 +println.org, 1 +printmet.com, 1 +printmet.ru, 1 +printmijn3dmodel.be, 1 +printmydesigns.ml, 1 +printpoint.tk, 1 +printserverpa.com, 1 +printus.de, 1 +printus.pro, 1 +printwasteminimizer.com, 1 +prinzoka.com.br, 1 +prior-it.be, 1 +prior.cloud, 1 +priorite-education.com, 1 +priorityelectric-agourahills.com, 1 +priorityelectric-calabasas.com, 1 +priorityelectric-camarillo.com, 1 +priorityelectric-dosvientos.com, 1 +priorityelectric-hiddenhills.com, 1 +priorityelectric-lakesherwood.com, 1 +priorityelectric-malibu.com, 1 +priorityelectric-moorpark.com, 1 +priorityelectric-newburypark.com, 1 +priorityelectric-oakpark.com, 1 +priorityelectric-simivalley.com, 1 +priorityelectric-thousandoaks.com, 1 +priorityelectric-westlakevillage.com, 1 +priorityelectric.biz, 1 +priorityelectric.info, 1 +priorityelectric.mobi, 1 +priorityelectric.net, 1 +priorityessays.com, 1 +priorityfakes.com, 1 +prioritynissannewportnewsparts.com, 1 +priorlakemn.gov, 1 +prisel.fr, 1 +prism-communication.com, 1 +prismacloud.com, 1 +prismacloud.green, 1 +prismacloud.xyz, 1 +prismalite.com.br, 1 +prismapixel.studio, 1 +prisminfosys.com, 1 +prisonerresource.com, 1 +pristal.eu, 1 +pristinepotty.com, 1 +prisync.com, 1 +pritalk.com, 1 +pritchett.xyz, 1 +pritchi.tk, 1 +priv.gc.ca, 1 +priv.im, 1 +privaci.ai, 1 +privacy-week-vienna.at, 1 +privacy-week.at, 1 +privacy.com, 1 +privacybydesign.foundation, 1 +privacychick.com, 1 +privacychick.io, 1 +privacycloud.nl, 1 +privacyculture.com, 1 +privacyend.com, 1 +privacyforjournalists.org.au, 1 +privacyget.tk, 1 +privacyinternational.org, 1 +privacymanatee.com, 1 +privacynow.eu, 1 +privacysavvy.com, 1 +privacyscore.org, 1 +privacysecuritybrainiacs.com, 1 +privacysvcs.net, 1 +privacytools.io, 1 +privacyweek.at, 1 +privacyweek.de, 1 +privacyweek.eu, 1 +privacyweek.wien, 1 +privacyweekvienna.at, 1 +privaday.de, 0 +privasphere.com, 1 +private-diary-taka.com, 1 +private-mail-for.me, 1 +private-relay.email, 1 +privatebanks.uk, 1 +privatebin.info, 1 +privatecapsecurity.org, 1 +privatedns.nl, 0 +privateger.me, 1 +privategiant.com, 1 +privatehd.to, 1 +privateideas.de, 1 +privateimarketing.com, 1 +privateimoveis.com, 1 +privatemillionaire.com, 1 +privatenebula.eu, 1 +privatepilot.lu, 0 +privatepokertour.com, 1 +privatepropertymallorca.com, 1 +privaterelay.com, 0 +privateservice.cz, 1 +privatetrainingonline.se, 1 +privatevoid.net, 1 +privatewolke.com, 0 +privatfrei.de, 1 +privatislauga.lt, 1 +privatmeet.com, 1 +privatpatient-krankenhaus.de, 1 +privatstunden.express, 1 +privc.io, 1 +privcloud.cc, 1 +privcloud.org, 1 +privea.fr, 1 +privelust.nl, 1 +priverify.com, 1 +privilegevisa.fr, 1 +privorot-taro.com, 1 +privorot.cf, 1 +privu.me, 1 +privy-staging.com, 1 +privy.com, 1 +prix-pneus.fr, 1 +prizehometickets.com.au, 1 +prizelink.com.au, 1 +prizesnapper.com, 1 +prizrak-v-dospehah.ga, 1 +prjktruby.com, 0 +prknje.co, 1 +prlved.co.uk, 1 +prm-taiwan.com, 1 +prmihoc.com, 1 +prnav.com, 1 +pro-alter.ch, 1 +pro-ben.sk, 1 +pro-clean.org, 1 +pro-co.at, 1 +pro-esb.net, 1 +pro-ing.com, 0 +pro-kemerovo.ml, 1 +pro-kolhoz.tk, 1 +pro-lq.at, 1 +pro-lq.ch, 1 +pro-lq.com, 1 +pro-lq.de, 1 +pro-lq.hu, 1 +pro-lq.it, 1 +pro-lq.net, 1 +pro-lq.ro, 1 +pro-mile.pl, 1 +pro-taucher.com, 1 +pro-taucher.de, 1 +pro.co.il, 1 +pro100systems.com.ua, 1 +pro3ozonio.com.br, 1 +proact-it.co.uk, 1 +proactive.run, 1 +proactivenews.ml, 1 +proactivestructuresolutions.com, 1 +proadvanced.com, 1 +proagile.se, 1 +proalist.com, 1 +proalter.ch, 1 +proastec.com.br, 1 +probano.com, 1 +probase.ph, 1 +probateandplanning.com, 1 +probationforms.com, 1 +probationnotes.com, 1 +probazen.com, 1 +probely.com, 1 +probiv.biz, 1 +probiv.cc, 1 +problempaws.ie, 1 +problemstate.com, 1 +problemstate.de, 1 +problemstate.net, 1 +problemstate.org, 1 +problemysholkama.cz, 1 +probono14.org, 1 +probonus.tk, 1 +probooks.gq, 1 +procalc.be, 1 +procar-rheinland.de, 1 +procarservices.com, 1 +procarswoking.com, 1 +proceed.tk, 1 +procens.us, 0 +procensus.com, 1 +procert.ch, 0 +procesadorafenix.com.mx, 1 +processesinmotion.com, 1 +processout.com, 1 +procharter.com, 1 +prochaskamediation.com, 1 +procinorte.net, 1 +procitec.cz, 1 +proclassifieds.in, 1 +proclubs.news, 1 +procode.ch, 1 +procode.gq, 1 +proconnectengenharia.com.br, 1 +procore.space, 1 +procountorsolo.com, 1 +procrastinatingengineer.co.uk, 1 +procrastinatingengineer.uk, 1 +procrastinationland.com, 1 +procreditbank-kos.com, 0 +procsec.top, 1 +proctorauth.com, 1 +proctorial.cf, 1 +proctorio.com, 1 +proctorio.net, 1 +proculsk.tk, 1 +procurx.pt, 1 +prod-simplesend-api.azurewebsites.net, 1 +prodampro.ru, 1 +prodatalabs.com, 1 +prodct.info, 1 +prodegree.com, 1 +prodentalsantacruz.es, 1 +prodesigntools.com, 1 +prodevsblog.com, 1 +prodhealthcare.org, 1 +prodietix.cz, 1 +prodigibook.com, 1 +prodigious.work, 1 +prodigyhacking.com, 1 +prodigyhq.io, 1 +prodinger.com, 1 +prodottitipicidellatoscana.it, 1 +prodottogiusto.com, 1 +produccioneskm.cl, 1 +producemybook.com, 1 +producentbalustrad.pl, 1 +producepromotions.com, 1 +producertools.io, 1 +productbarcodes.com, 1 +productboard.com, 1 +productdesignsoftware.com.au, 0 +productfurniture.ga, 1 +production.vn, 1 +productionscime.com, 1 +productive-garden.com, 1 +productivemachine.net, 1 +productlondon.com, 1 +productmarketingalliance.com, 1 +productosdeteruel.es, 1 +productosfitness.com, 1 +productpeo.pl, 1 +products-for-health.tk, 1 +products88.com, 1 +productsblockbuster.com, 1 +productsbrandleader.com, 1 +productscastle.com, 1 +productsmansion.com, 1 +productum.eu, 1 +produkt.cf, 1 +produkttest-online.com, 1 +produktum.eu, 1 +produra.nl, 1 +prodwa.re, 1 +prodware.fr, 1 +prodware.nl, 1 +proeflokaalbakker.nl, 1 +proefteksten.nl, 0 +proekt.tk, 1 +proemployeeprotection.com, 1 +proemployeeprotection.net, 1 +proesb.net, 1 +proevlifecycle.eu, 1 +proextenderindia.com, 1 +prof-toplivo.ru, 1 +prof-waldowski.de, 1 +profarm.top, 1 +profection.biz, 1 +profession.email, 1 +professional.cleaning, 1 +professionalbeautyshop.it, 1 +professionalblog.tk, 1 +professionaleducation.tk, 1 +professionallawyer.tk, 1 +professions.org.ru, 1 +professors.ee, 1 +professorwidget.tk, 1 +proficio.cz, 1 +proficiodigital.com, 1 +proficiodigital.sk, 1 +profidea.cz, 1 +profielektrik.tk, 1 +profil-doors.spb.ru, 1 +profile.ooo, 1 +profile.tf, 1 +profiles.google.com, 1 +profilewatcher.ga, 1 +profilib.top, 1 +profilmonline.cn, 1 +profilmonline.com, 1 +profilmonline.jp, 1 +profilwerkstatt.de, 1 +profinetz.de, 1 +profinvestment.com, 1 +profiservis.info, 1 +profissionalstool.ga, 1 +profit24.ml, 1 +profitablewebprojects.com, 1 +profitfromtech.com, 1 +profitopia.de, 1 +profloorstl.com, 1 +profmetod.com, 1 +proformer.io, 1 +proformi.com, 1 +profritual.ru, 1 +profsaranya.com, 1 +proft.eu, 1 +profumeria.roma.it, 1 +profuntime.tk, 1 +profvideo.kharkov.ua, 1 +profwald.4lima.de, 1 +prog-d.tk, 1 +prog-mailolder.tk, 1 +prog.olsztyn.pl, 1 +prog.sh, 1 +prog24.net, 1 +progamehackers.tk, 1 +progamermundo.com, 1 +progarm.org, 1 +progaudio.be, 1 +progenda.be, 1 +progeon.nl, 1 +proger.ga, 1 +progeste.pt, 1 +progettograjau.com, 1 +progg.no, 1 +proggersession.com, 1 +proggersession.de, 1 +progiscad.com, 0 +prognozis.cf, 1 +progolfjourney.com, 1 +progolfnow.com, 1 +progon.cf, 1 +prograce.info, 1 +program-and.work, 1 +programador-web-freelance.es, 1 +programadorwp.com, 1 +programarya.com, 1 +programer21.com, 1 +programlama.tk, 1 +programmaticmagic.com, 1 +programmatv.tk, 1 +programme-launch28-code854-com.ml, 1 +programmes-neufs-corse.fr, 1 +programming-solutions.tk, 1 +programnews.tk, 1 +programsareproofs.com, 1 +programsupport300procent.com, 1 +programtracker.net, 1 +programvaruexperten.se, 1 +progresivoptic.ro, 1 +progreso.pl, 1 +progress-linux.org, 1 +progress.photos, 1 +progressive.ml, 1 +progressivecfo.co.nz, 1 +progressiveplanning.com, 1 +progressivepurchasing.com.au, 1 +progressivestreetdance.tk, 1 +progressm.tk, 1 +progressnet.nl, 1 +progresswww.nl, 1 +progtime.net, 1 +prohelpers.tk, 1 +prohost24.tk, 1 +prohrcloud.com, 1 +proibidoler.com, 1 +proiceresurfacer.com, 1 +proimpact.it, 1 +proitsecurity.cl, 0 +proitsecurity.com, 0 +proj.org.cn, 1 +proj3ct.me, 1 +proj6.site, 1 +project-forum.tk, 1 +project-merlin.co.uk, 1 +project-novis.org, 1 +project-rune.tech, 1 +project-stats.com, 1 +project86fashion.com, 1 +projectalias.com, 1 +projectarmy.net, 1 +projectbenson.com, 0 +projectborealis.com, 1 +projectborealisgitlab.site, 1 +projectbotticelli.com, 1 +projectemail.co, 1 +projectforge.org, 1 +projectfreehosting.ga, 1 +projectguru.in, 1 +projecthelius.com, 1 +projecthopeless.tk, 1 +projectimagine.com, 1 +projectinnovation.org, 1 +projection.gq, 1 +projectl1b1t1na.tk, 1 +projectlinuseasttn.org, 1 +projectmailext.co, 1 +projectmaka.io, 1 +projectmakeit.com, 1 +projectnom.com, 1 +projectsafechildhood.gov, 1 +projectskynet.org, 1 +projectte.ch, 1 +projecttools.info, 1 +projectveritasaction.com, 0 +projectview.ai, 1 +projectxyz.eu, 1 +projekt-allianz.de, 1 +projekt-umbriel.de, 1 +projekt-wild.tk, 1 +projektarbeit-projektplanung.de, 1 +projektentwicklung-westfalen.de, 1 +projektzentrisch.de, 1 +projest.ch, 0 +projet-fly.ch, 1 +projet-saara.com, 1 +projetomovase.com, 1 +projetoscan.online, 1 +proklimat.pro, 1 +proledwall.nl, 1 +prolens-lankaran.tk, 1 +prolinos.de, 1 +prolocofrascarolo.tk, 1 +promax.nl, 1 +promea.net, 1 +promedyczny.pl, 1 +prometheanfire.net, 1 +prometheanfire.org, 1 +promexbol.com.bo, 1 +promiflash.de, 1 +promifotos.com, 1 +promisesaplus.com, 1 +promislovik.tk, 1 +prommontag.com, 1 +promo-brille.at, 0 +promo-brille.ch, 0 +promo-brille.de, 0 +promo-code.tk, 1 +promo-kodi.tk, 1 +promo-matelas.com, 1 +promo-mobilhonda.com, 1 +promo.lc, 1 +promobo.fr, 1 +promocao.email, 1 +promocjedladzieci.pl, 1 +promocodes777.com, 1 +promocodius.com, 1 +promodance.cz, 1 +promodoble.com, 1 +promods.cn, 1 +promods.download, 1 +promods.net, 1 +promods.store, 1 +promods.web.tr, 1 +promohulp.nl, 1 +promohunt.ru, 0 +promokodi.tk, 1 +promolover.com, 1 +promopony.com, 1 +promorder.ru, 1 +promoscuola.net, 1 +promosjungle.com, 1 +promospg.es, 1 +promotech.pro, 1 +promoterms.com.au, 1 +promotioncentre.co.uk, 1 +promotiongeeks.com, 0 +promotionnissanauto.com, 1 +promotionvillanakarin.com, 1 +promtechosnastka.ru, 1 +promuovi.tv, 1 +promusicante.ch, 1 +pron4ik.gq, 1 +pronto-intervento-fognature.it, 1 +pronto-intervento.net, 1 +prontocleaners.co.uk, 1 +prontointerventofognature.roma.it, 1 +prontointerventoimmediato.it, 1 +prontolight.com, 1 +prontossl.com, 1 +proofwiki.org, 1 +proos.nl, 1 +proovn.com, 1 +propagandablog.de, 0 +propagationtools.com, 1 +propanesale.cf, 1 +propcierge.in, 1 +propecia.ml, 1 +propelgrowth.com, 1 +propermatches.com, 1 +propershave.com, 1 +propertech.com.br, 1 +properticons.com, 1 +propertiesmiami.com, 1 +property-catalogue.eu, 1 +property-tax.cf, 1 +property-tax.ga, 1 +propertyauctionaction.co.uk, 1 +propertycareincorporated.com, 1 +propertycrawl.com, 1 +propertyfindercdn.com, 1 +propertyflare.com, 1 +propertygroup.pl, 1 +propertyinside.id, 1 +propertymingo.com, 1 +propertyofariana.pw, 1 +propertyone.mk, 1 +propertysales-almeria.com, 1 +propertyselling.ga, 1 +propertysold.ca, 1 +propertyupdate.com.au, 1 +prophitt.me, 1 +propipesystem.com, 1 +propiteer.com, 1 +propiteercapitalplc.com, 1 +propolisturkiye.tk, 1 +proporcer.tk, 1 +proposalonline.com, 1 +proposeinspain.net, 1 +propr.no, 1 +propranolol.cf, 1 +propranololgeneric.ml, 1 +proprietairesmaisons.fr, 1 +propseller.com, 1 +propshub.com, 1 +proquotient.com, 1 +proris.com, 1 +prosafilosofica.com.br, 1 +proschlaf.at, 1 +proseo4u.com, 1 +proservices-informatique.fr, 1 +proservices.vip, 1 +prosharp.com.au, 1 +proshnotori.com, 1 +proshop.pl, 1 +proshow.com.ua, 1 +proslimdiets.com, 1 +prosocialmachines.com, 1 +prosoft.com.es, 1 +prosoft.es, 1 +prosoft.pe, 1 +prosony.es, 1 +prospa.digital, 1 +prospect1838.com.au, 1 +prospecto.com.au, 1 +prospecto.ee, 1 +prospecto.hr, 1 +prospecto.lt, 1 +prosperbot.com, 1 +prosperegypt.com, 1 +prosperfit.com, 1 +prosperfit.org, 1 +prosperident.com, 1 +prosperity-textile.com, 1 +prosperontheweb.com, 1 +prosperops.com, 1 +prosperstack.com, 1 +prosperus.ru, 1 +prospo.co, 1 +prospreads.com, 1 +prostaglandina.com, 1 +prostavropol.cf, 1 +prostecheat.xyz, 1 +prostitutka.cf, 1 +prostitutka.ml, 1 +prostitutki-narvskaja.ga, 1 +prostitytki-nijnevartovsk.club, 1 +prosto-dengi.tk, 1 +prostocash.com, 1 +prostodengi.ml, 1 +prostohobby.ru, 1 +prostoivkusno.ml, 1 +prostoporno.fun, 1 +prostoporno.guru, 1 +prostoporno.life, 1 +prostoporno.live, 1 +prostoporno.love, 1 +prostoporno.net, 1 +prostoporno.sexy, 1 +prostoporno.vip, 1 +prostoporno.zone, 1 +prostor.cf, 1 +prostoskidki.ml, 1 +prostozaim.ml, 1 +prostye-recepty.com, 1 +prosurveillancegear.com, 1 +prosyscom.tech, 1 +protanki.ml, 1 +protanki.tk, 1 +protapnews.tk, 1 +protech.ge, 1 +proteco.sk, 1 +protectedpayments.net, 1 +protectedreport.com, 1 +protectem.de, 1 +protection-plexi.com, 1 +protection-plexi.fr, 1 +protection.ga, 1 +protectionformula.com.ua, 1 +protectwrap.ml, 1 +protectyourspeech.org, 1 +protege.moi, 1 +protegetudescanso.com, 1 +proteh.com.ua, 1 +protein-riegel-test.de, 1 +proteinreport.org, 1 +protek.tk, 1 +proteogenix-products.com, 1 +proteogenix.science, 1 +protestantsegemeentekaag.nl, 1 +protesthongkong.com, 1 +proteus-eretes.nl, 1 +proteus-tech.com, 1 +protez.ga, 1 +protez.ml, 1 +protez.tk, 1 +protic.online, 1 +protic.pt, 1 +protiksana.gr, 1 +proto.io, 1 +protobetatest.com, 1 +protocol.ai, 1 +protocol.co.il, 1 +protogenbrainbooster.tk, 1 +protok.tk, 1 +protonmail.ch, 1 +protonmail.com, 1 +protonpix.com, 1 +protonvpn.com, 1 +prototayl.gq, 1 +prototypefund.de, 1 +prototyping-computer.ml, 1 +protoxin.net, 0 +protrainerbrasil.com.br, 1 +protrolley.cf, 1 +proudplus.com, 1 +proust.ch, 0 +proust.media, 0 +proustmedia.de, 0 +provakil.com, 1 +prove-uru.co.uk, 1 +prove.no, 1 +proveits.me, 0 +provence-appartements.com, 0 +provencemckinney.com, 1 +provent.io, 1 +provera10mg.tk, 1 +proverennie-kursi.gq, 1 +proverennie-kursi.ml, 1 +proverennie-kursi.tk, 1 +provereno-rabotaet.gq, 1 +provereno-rabotaet.tk, 1 +proverochka.tk, 1 +provide-your-image.de, 1 +providence.org, 1 +providentfireplus.com, 1 +providential.be, 1 +providentins.com, 1 +providerlijst.com, 1 +providerlijst.ml, 1 +providerlijst.nl, 1 +provinciaotlavoro.it, 1 +provinzblogger.de, 1 +provision-isr.nl, 1 +provisionircd.tk, 1 +provitec.com, 1 +provitec.de, 1 +provlas.se, 1 +prowebcenter.com, 0 +prowindow.sk, 1 +prowise.com, 1 +prowise.me, 1 +prowpcare.com, 1 +prowrestlingevents.tk, 1 +prox.ru, 1 +proximasrl.eu, 1 +proximity.ga, 1 +proximityradio.fr, 1 +proximoconcurso.com.br, 1 +proxirealtime.com, 1 +proxybay.bet, 1 +proxybay.buzz, 1 +proxybay.bz, 1 +proxybay.cc, 1 +proxybay.co, 1 +proxybay.earth, 1 +proxybay.gdn, 1 +proxybay.id, 1 +proxybay.ink, 1 +proxybay.ist, 1 +proxybay.kim, 1 +proxybay.la, 1 +proxybay.lat, 1 +proxybay.ltd, 1 +proxybay.one, 1 +proxybay.onl, 1 +proxybay.red, 1 +proxybay.tv, 1 +proxybay.uno, 1 +proxytool.cf, 1 +proyectafengshui.com, 1 +proyectosinelec.com, 1 +proyectostep.tk, 1 +proyectosx.net, 1 +prozac20mg.cf, 1 +prozapchast24.ru, 1 +prozorlivec.tk, 1 +prpferrara.it, 1 +prpr.cloud, 1 +prsg.tk, 1 +prsnlafk.com, 1 +prstatic.com, 1 +prt.in.th, 1 +prtimes.com, 1 +prtpe.com, 1 +prtscloud.ddns.net, 1 +pru.com.hk, 1 +pru.hk, 1 +pruebapg.cl, 1 +pruikshop.nl, 1 +pruma.com.br, 1 +pruna.org, 1 +prushka.gq, 1 +prushka.ml, 1 +prushka.tk, 1 +pruve.it, 1 +prvcy.one, 1 +prvnirodinna.cz, 1 +prws.kr, 1 +pryan.org, 1 +prylarprylar.se, 1 +prynhawn.com, 1 +prynhawn.net, 1 +prynhawn.org, 1 +przemas.pl, 1 +przerabianiezdjec.pl, 1 +ps-clinic.jp, 1 +ps-playback.com, 1 +ps-provider.co.jp, 1 +ps-sale.ru, 1 +ps-w.ru, 1 +ps.energy, 1 +ps2911.com, 1 +ps2online.tk, 1 +ps3419.org, 1 +ps4all.nl, 1 +ps5ssd.com, 1 +ps8318.com, 1 +psa-travel-care.com, 1 +psalmer.tk, 1 +psasines.pt, 1 +psau.edu.sa, 1 +psauxit.com, 1 +psazy.ml, 1 +psb.cloud, 1 +psb1.org, 1 +psb1911.com, 1 +psb4ukr.org, 1 +psbarrett.com, 1 +psblog.fr, 1 +psc.gov, 1 +psc.gov.ws, 1 +pschierl.com, 1 +pschunt.com, 1 +pscp.tv, 1 +pscr.gov, 1 +psd2.club, 1 +psdpt-tpfd.gc.ca, 1 +psdreams.com, 1 +psdsfn.com, 1 +psdsuc.com, 1 +pseek.com, 1 +pself.net, 1 +pservicer.com.mx, 1 +pseta.ru, 1 +psevdonim.ga, 1 +psg-calw.de, 1 +psg.bg, 1 +pshostpk.com, 1 +pshweb.tk, 1 +psi-tv.tk, 1 +psicanalista.milano.it, 1 +psici.eu, 1 +psicoexpansao.com.br, 1 +psicologajanainapresotto.com.br, 1 +psicologo-especialista-barcelona.com, 1 +psicologo-infantil-barcelona.com, 1 +psicologomogidascruzes.com.br, 1 +psicometricas.mx, 1 +psihologonline.tk, 1 +psihology.gq, 1 +psihoterapevt1.by, 1 +psihotest.tk, 1 +psinergy.info, 1 +psinergyhealth.com, 1 +psinergytech.com, 1 +psinetika.tk, 1 +psitarz.com, 1 +psixotest.tk, 1 +psixotesty.tk, 1 +psknv.com, 1 +psknv.ru, 1 +pskov-daily.tk, 1 +psm.org.ph, 1 +psmpl.com, 1 +psncarddelivery.com, 1 +psncardplus.be, 1 +psncardplus.com, 1 +psncardplus.dk, 1 +psncardplus.nl, 1 +psncardplus.se, 1 +psochecker.com, 1 +pson.ninja, 1 +psono.pw, 1 +psoppc.com, 1 +psoppc.net, 1 +psoppc.org, 1 +psoriasischecker.com, 1 +pspenvases.es, 1 +pspepper.com.br, 1 +psphp.tk, 1 +pssgcsim.org, 1 +pssjd.org, 1 +pst.moe, 1 +pste.pw, 1 +pstrykmyk.eu, 1 +psu.je, 1 +psucompare.com, 1 +psv-herford-badminton.de, 1 +psw-consulting.de, 1 +psw-group.de, 1 +psw-training.de, 1 +psw.net, 1 +pswatcher.com, 1 +psyart.tk, 1 +psycenter.tk, 1 +psychedelia.com, 1 +psychedelics.org, 1 +psychiatrie-ricany.cz, 1 +psychiatriepapezova.net, 1 +psychic-healer-mariya-i-petrova-boyankinska-b-borovan-bg.com, 1 +psychic-parapsychologist.com, 1 +psychicfairnetwork.gq, 1 +psychiq.com, 1 +psycho-lobby.fr, 1 +psycho-news.tk, 1 +psycho.space, 1 +psychoactive.com, 1 +psychoco.net, 0 +psychologbruksela.be, 1 +psychologi.cf, 1 +psychologic.tk, 1 +psychologie-hofner.at, 1 +psychologist.ga, 1 +psychologue-a-paris.com, 1 +psychologue-grenoble.org, 1 +psychology-ifk.com, 1 +psychologytests.tk, 1 +psychometrictest.ca, 1 +psychometrictest.co.il, 1 +psychometrictests.ca, 1 +psychometrictests.in, 1 +psychometrictests.uk, 1 +psychometrischetests.de, 1 +psychomotricien-la-rochelle.com, 1 +psychonews.tk, 1 +psychopathtest.com, 1 +psychopersonnalite.com, 1 +psychosis.tk, 1 +psychotechnique.africa, 1 +psychotechnique.be, 1 +psychotechnique.ch, 1 +psychotechnique.com, 1 +psychotechniquetest.fr, 1 +psychotel.tk, 1 +psychotest.gq, 1 +psychotherapie-kp.de, 0 +psychotherapie-leipzig.eu, 1 +psychotherapie1220wien.at, 0 +psychotherapy-vienna.com, 1 +psychotiq.tk, 1 +psycolleges.com, 1 +psydix.org, 1 +psygame.cf, 1 +psyh.tk, 1 +psyk-patienten.tk, 1 +psykologtidningen.gq, 1 +psykometrisk.se, 1 +psylab.cc, 0 +psylab.re, 1 +psylab.vip, 1 +psylliums.com, 1 +psynapse.net.au, 1 +psyshell.tk, 1 +psytrance-pro.com, 1 +pszinfo.hu, 1 +pt-d.ru, 1 +pt-server.de, 1 +pt.im, 1 +pt4.tech, 1 +pta-security.nl, 1 +pta.world, 1 +ptab2pt.ga, 1 +ptal.eu, 1 +ptasiepodroze.eu, 1 +ptbi.org.pl, 1 +ptboys.tk, 1 +ptcbooks.gq, 1 +ptcdogpark.com, 1 +pteceng.com, 1 +pterodactyl.org.cn, 1 +pterodactylus.cz, 1 +pteroforge.com, 1 +ptfiber.com, 1 +ptfiber.ru, 1 +ptfiber.spb.ru, 1 +ptgoldensun.com, 1 +ptheophanidis.com, 1 +pthsec.com, 1 +ptit-trocoeur.fr, 1 +ptk-svarka.ru, 0 +ptlibrary.ml, 1 +ptltrade.com, 1 +ptlync.com.au, 1 +ptm.ro, 1 +ptmarquees.ie, 1 +ptrbrs.nl, 1 +ptrl.ws, 1 +ptron.org, 1 +ptrt.xyz, 1 +ptshft.co, 1 +ptupapers.tk, 1 +pturl.tk, 1 +pty.gg, 1 +puac.de, 1 +pub-online.ro, 1 +pubclub.com, 1 +pube.tk, 1 +pubertytalk.com, 1 +pubg-tournament.com, 1 +pubi.me, 1 +pubkit.io, 1 +publanda.nl, 1 +publi-all.be, 1 +public-g.de, 1 +public-measures.com, 1 +public-projects.com, 1 +public-projects.de, 1 +public-vocals.de, 1 +public-welfare.com, 1 +publiccarauctionscalifornia.com, 1 +publicintegrity.org, 1 +publicintelligence.net, 1 +publicrea.com, 1 +publicspeakingcamps.com, 1 +publicsuffix.org, 1 +publik.ml, 1 +publimepa.it, 0 +publiq.space, 1 +publish.ga, 1 +publishedpaper.ga, 1 +publisherservices.co, 1 +publivate.ca, 1 +publixphere.net, 1 +pubreview.com.au, 1 +pubsasiedzi.pl, 1 +pubsavoy.tk, 1 +puckcreations.com, 1 +pucogid.ga, 1 +pucsr.tech, 1 +pudding.tk, 1 +puddis.de, 1 +pudro.com, 1 +puebladesoto.tk, 1 +pueblanmilksnake.com, 1 +pueblocantabro.tk, 1 +pueblosamerica.com, 1 +puenteviejo.tk, 1 +puer.eu.org, 1 +puertodramaturgia.tk, 1 +puestifiestas.mx, 1 +puestosdeferia.mx, 1 +puetter.eu, 1 +pugetsoundspas.com, 1 +puggan.se, 1 +pugilares.com.pl, 1 +pugovka72.ru, 1 +puhe.se, 1 +puhka.me, 1 +puhudefu.de, 1 +puissancemac.ch, 0 +puiterwijk.org, 1 +pujasharma.associates, 1 +pukeking.com, 1 +pukfalkenberg.dk, 1 +pulcinella.tk, 1 +puli.com.br, 1 +pulizia.milano.it, 1 +pulizia.roma.it, 1 +pulizieuffici.milano.it, 1 +pulizievap.it, 1 +pulledporkheaven.com, 1 +pulley.co.jp, 1 +pullnopunchesradio.tk, 1 +pulpproject.org, 1 +pulser.stream, 1 +pulseroot.ga, 1 +pulsnitzer-lebkuchen-shop.de, 1 +pulsnitzer-lebkuchen.de, 1 +pulsnitzer-lebkuchen.shop, 1 +pulsnitzer-pfefferkuchen-shop.de, 1 +pulsnitzer-pfefferkuchen.shop, 1 +pulsr.ml, 1 +pumarin.tk, 1 +pump19.eu, 1 +pumperszene.com, 1 +pumpkin-business.com, 1 +pumpn.net, 1 +punchadragon.com, 1 +punchlinetheatre.co.uk, 1 +punchlinetheatre.com, 1 +punchunique.com, 1 +punctually.gq, 1 +pundix.com, 1 +punematka.com, 1 +pungatv.ml, 1 +punikonta.de, 1 +punishment.institute, 1 +punitsheth.com, 1 +punjabdirectory.in, 1 +punjabprime.com, 1 +punkapoule.fr, 1 +punkart.tk, 1 +punkas.tk, 1 +punkcolombia.tk, 1 +punknews.org, 1 +punknmetal.tk, 1 +punkrockpsychology.com, 1 +puntacanalink.com, 1 +puntacananetwork.com, 1 +puntacanatransporte.com, 1 +puntacanavapor.com, 1 +puntaprop.com, 1 +puntcunts.com, 1 +puntoestadodemexico.com, 1 +puntogommevenegono.it, 1 +puntonium.hu, 1 +puntoseguro.com, 0 +pupboss.com, 1 +pupok.cf, 1 +pupok.gq, 1 +puppet.pl, 1 +puppo.space, 0 +pupsikstudio.com, 1 +puq.moe, 1 +pura-ponia.gq, 1 +puralps.ch, 1 +puravayalchurch.tk, 1 +puravida-estate.com, 1 +purchasescooters.ga, 1 +purchasetncrash.gov, 1 +pure-gmbh.com, 1 +pure-host.de, 1 +pure-paste.tk, 1 +pure2life.nl, 1 +purecbdvapors.com, 1 +puredayshop.com.tw, 1 +puredisinfecting.com, 1 +puredisinfection.com, 1 +purefoot.jp, 1 +purefreefrom.co.uk, 0 +pureindoorair.com, 1 +pureitsolutionsllp.com, 1 +purejewels.com, 1 +purelunch.co.uk, 1 +purelypestcontrol.com, 1 +puremosquito.com, 1 +purenhd.com, 1 +purenvi.ca, 0 +purepest.com, 1 +purepestandlawn.com, 1 +purepowercycle.com, 1 +puresanitization.com, 1 +puretermite.com, 1 +purevapeofficial.com, 1 +purewaterguide.net, 1 +purikore.com, 1 +purityclothing.co.uk, 1 +purple.tech, 1 +purplebooth.co.uk, 0 +purplebricks.co.uk, 1 +purplebricks.com, 1 +purplebricks.com.au, 1 +purplebricksplc.com, 1 +purplehotel.cf, 1 +purplemet.com, 1 +purplemoon.ch, 1 +purplemoon.mobi, 1 +purpleplains.net, 1 +purplepr.bg, 1 +purples.cf, 1 +purplestar.ch, 1 +purplestar.com, 1 +purplestar.mobi, 1 +purpletech.com.br, 1 +purpletter.tk, 1 +purplewindows.net, 1 +purplez.pw, 1 +purplscientific.com, 1 +purpspc.com, 1 +purrfectboudoir.com, 1 +purrfectcams.com, 1 +purrfectlove.net, 1 +purrfectmembersclub.com, 1 +purrfectswingers.com, 1 +purse-les.com, 1 +pursuable.cf, 1 +pursuehappiness.tk, 1 +pursuingoutdoors.com, 1 +purupuru-shibuya.school, 1 +purupuru.school, 1 +puryearlaw.com, 1 +pusatcucikarpet.com, 1 +pusehusetkattehotell.no, 1 +pusehusetmalvik.no, 1 +pushers.com.mx, 1 +pushoflove.com, 1 +pushok.tk, 1 +pushpanel.io, 1 +pushphp.com, 1 +pushroi.com, 1 +pusichatka.ddns.net, 1 +pussplay.com, 1 +pussr.com, 1 +pussycat.ml, 1 +pussylickingnow.com, 1 +pustakvishwa.tk, 1 +put-k-uspekhuy.tk, 1 +put-spaseniya.ml, 1 +put.moe, 1 +put.re, 1 +putana.gq, 1 +putanaru.gq, 1 +putani.gq, 1 +putany.tk, 1 +putanypitera.ml, 1 +putasdelporno.com, 1 +putasenvalencia.es, 1 +putatara.net, 1 +puteulanus.xyz, 1 +puthenthope.tk, 1 +putin.red, 1 +putlocker.vg, 1 +putman-it.nl, 1 +putnamcollision.com, 1 +putney.io, 1 +putnik.tk, 1 +putrock.be, 1 +puttymonos.club, 1 +puur.gent, 1 +puurgent.be, 1 +puxlit.net, 1 +puyallupnissanparts.com, 1 +puyblanc.info, 1 +puzz.gg, 1 +puzzlage.com, 1 +puzzle-welt.ch, 1 +puzzleetc.com, 1 +puzzlegames.com, 1 +puzzlepoint.ch, 1 +puzzles-to-print.com, 1 +pv-golf.com, 1 +pv-paderborn-now.de, 1 +pvalaw.com, 1 +pvamg.org, 1 +pvao.gov.ph, 1 +pvc-stolarija.co, 0 +pvcvoordeel.nl, 0 +pvda.nl, 1 +pvdplanet.tk, 1 +pvhe.pl, 1 +pvideo.cz, 1 +pvmotorco.com, 1 +pvpagario.tk, 1 +pvpcraft.ca, 1 +pvpctutorials.de, 1 +pvpheroes.gg, 1 +pvpheroes.no, 1 +pvphs98.com, 1 +pvplist.ml, 1 +pvpserverler.pro, 1 +pvpzone.fr, 1 +pvtschlag.com, 0 +pvv-vermietung.de, 1 +pwaiwm.site, 1 +pwanotes.ga, 1 +pwaresume.com, 1 +pwcva.gov, 1 +pwd.az, 1 +pwdgen.net, 0 +pwdsafe.com, 0 +pwe.vision, 1 +pwg-see.de, 1 +pwgenerator.net, 1 +pwned.life, 1 +pwnedpass.tk, 1 +pwneo.com, 1 +pwnies.dk, 1 +pwolk.com, 1 +pwoss.org, 1 +pwoss.xyz, 1 +pwud.ga, 1 +pxetech.com, 1 +pxgamer.xyz, 1 +pxio.de, 0 +pxl-mailtracker.com, 1 +pxl.blue, 1 +pxl.cl, 1 +pxld.sh, 1 +pxstart.cz, 1 +pxx.io, 1 +py-amf.org, 1 +py.search.yahoo.com, 0 +pya.org.tr, 1 +pybtex.org, 1 +pyca.tk, 1 +pychef.com, 1 +pycrc.org, 1 +pycrypto.org, 1 +pycycle.info, 1 +pygarage.com, 0 +pygb.cl, 1 +pygmyleafchameleon.com, 1 +pyhello.world, 1 +pyjiaoyi.cc, 1 +pylad.se, 1 +pylon.bot, 1 +pymebi.cl, 1 +pymescentro.net, 1 +pymeup.org, 1 +pyopenssl.org, 1 +pypa.io, 1 +pypi.io, 1 +pypi.org, 1 +pypi.python.org, 1 +pyra-explorer.tk, 1 +pyramid-it.co.uk, 1 +pyrenees.io, 1 +pyrios.pro, 1 +pyro.works, 1 +pyroballpcbs.com, 1 +pyrohandel.de, 1 +pyrotechnologie.de, 1 +pysays.net, 1 +pyshem.com, 0 +pyspace.org, 1 +pythia.nz, 1 +python.org, 0 +pythonatrix.com, 1 +pythonhosted.org, 1 +pytradebot.com.br, 1 +pywikibot.org, 1 +pyxo.net, 0 +pyzlnar.com, 1 +pzpittsburgh.com, 1 +pzsearch.nl, 1 +q-and-a.tk, 1 +q-inn.com, 1 +q-inn.nl, 1 +q-m.design, 1 +q-m.space, 1 +q-technologies.com.au, 1 +q-xtra.com, 1 +q00228.com, 1 +q01.us, 1 +q1000.nl, 1 +q1q2q3.tk, 1 +q1z.net, 1 +q30365.com, 1 +q3jlzwq.com, 1 +q5118.com, 1 +q5197.co, 1 +q6729.co, 1 +q6729.com, 1 +q6957.co, 1 +q81365.com, 1 +q82365.com, 1 +q8igh228tq.tk, 1 +q9297.co, 1 +q9297.com, 1 +q9397.com, 1 +q9721.com, 1 +q9728.co, 1 +qa-brandywineglobal.com, 1 +qa-team.xyz, 1 +qa.fedoraproject.org, 1 +qa.stg.fedoraproject.org, 1 +qabalah.jp, 1 +qabel.de, 1 +qaconstrucciones.com, 1 +qadmium.com, 1 +qadmium.tk, 1 +qadrishattari.tk, 1 +qaina.net, 1 +qalab.tk, 1 +qambarraza.com, 1 +qanatnews.tk, 1 +qandavision.com, 0 +qani.me, 1 +qaq.cloud, 1 +qaq.sh, 1 +qarto.com, 1 +qask.ml, 1 +qatartimes.tk, 1 +qaz.cloud, 1 +qbasicsite.tk, 1 +qbd.eu, 1 +qbiju.com.br, 1 +qbiltrade.com, 1 +qbit.website, 1 +qbtechs.com, 1 +qbug.cf, 1 +qc.immo, 1 +qc.search.yahoo.com, 0 +qcbrna.qa, 1 +qccareerschool.com, 0 +qcdesignschool.com, 0 +qclean.com.au, 1 +qclt.com, 1 +qcmakeupacademy.com, 0 +qcmlw.com, 1 +qconnan-photos.fr, 1 +qcrx.cn, 1 +qcstudentcenter.com, 0 +qcstyleacademy.com, 0 +qctravelschool.com, 0 +qcuarto.com.py, 1 +qd6kz.net, 1 +qdabogados.com, 1 +qdon.space, 1 +qdqlh.cn, 1 +qdrat.ml, 1 +qdrcst.com, 1 +qdstationary.co.uk, 1 +qdstationery.co.uk, 1 +qe-lab.at, 1 +qed.ai, 1 +qedcon.org, 0 +qeepintelligence.tk, 1 +qei.org.au, 1 +qelectrotech.org, 1 +qeshmminer.com, 1 +qetesh.de, 1 +qetic.co.jp, 1 +qewc.com, 1 +qfes.qld.gov.au, 1 +qgblog.org, 0 +qhost.cf, 1 +qhse-professionals.nl, 1 +qhzwz.com, 1 +qianalysis.com, 1 +qiangtou.net, 1 +qianqiao.me, 1 +qiaohong.org, 1 +qicsystems.com, 1 +qifu.me, 1 +qifu.org.cn, 1 +qigehl.com, 1 +qihl.gg, 1 +qike.tk, 1 +qikify.com, 1 +qikroof.com, 1 +qiliang.wang, 1 +qingly.me, 1 +qingniantuzhai.com, 1 +qingpat.com, 1 +qingpei.me, 1 +qingyule.com, 1 +qionouu.cn, 1 +qipllc.com, 1 +qis.fr, 1 +qiscience.tk, 1 +qitarabutrans.com, 1 +qits.de, 0 +qivonline.pt, 1 +qiwi.be, 1 +qixi.biz, 1 +qiyan.email, 0 +qjg.com.br, 1 +qkek.tk, 1 +qkka.org, 1 +qklshequ.com, 1 +qkmortgage.com, 1 +ql.tc, 1 +qlares.nl, 1 +qlarititech.io, 1 +qlcvea.com, 0 +qlcvea.it, 1 +qldcarwreckers.com.au, 1 +qldconservation.org.au, 1 +qldformulaford.org, 1 +qliving.com, 1 +qlrace.com, 0 +qm-marzahnnordwest.de, 1 +qmarket.tk, 1 +qmee.com, 1 +qmeriaux.fr, 1 +qnected.nl, 1 +qnixon.com, 1 +qnotafm.com.co, 1 +qnq.moe, 1 +qnsgmd.com, 1 +qochealth.com, 1 +qoml.net, 1 +qonto.com, 1 +qoor.io, 0 +qoptalk.com, 1 +qosmoschools.edu.my, 1 +qotw.net, 1 +qp666d.com, 1 +qpaypro.com, 1 +qpcna.org, 1 +qponverzum.hu, 1 +qpsinc.com, 1 +qq5197.co, 1 +qq52o.me, 1 +qq6177.net, 1 +qq6729.co, 1 +qq6729.com, 1 +qq6957.co, 1 +qq885.com, 1 +qq9297.co, 1 +qq9397.com, 1 +qq9728.co, 1 +qqiao.me, 1 +qqmingzi.cc, 1 +qqq6.com, 1 +qqq63.com, 1 +qqq67.com, 1 +qqqq.plus, 1 +qqrss.com, 1 +qr.ae, 1 +qr.cl, 1 +qr.sb, 1 +qr0.ch, 1 +qr1.at, 1 +qr70.com, 1 +qrara.net, 1 +qrbird.com, 1 +qrcontagion.com, 1 +qrd.by, 1 +qrguestbook.com, 1 +qrlab.ch, 1 +qrlfinancial.com, 0 +qrpatrol.com, 1 +qrpth.eu, 1 +qrsecuriteanimal.com, 1 +qruiser.com, 1 +qryo.nl, 1 +qrz.one, 1 +qscco.com, 1 +qscloud.de, 1 +qseek.cf, 1 +qslstudio.tk, 1 +qt.to, 1 +qtacairsoft.com, 1 +qtl.me, 0 +qtmd.org, 1 +qtmsheep.com, 1 +qtn.net, 1 +qto.chat, 1 +qto.cloud, 1 +qto.co, 1 +qto.com, 1 +qto.com.hk, 1 +qto.de, 1 +qto.fr, 1 +qto.info, 1 +qto.name, 1 +qto.net, 1 +qto.org, 1 +qto.support, 1 +qto.to, 1 +qto.wiki, 1 +qtpass.org, 1 +qtpower.co.uk, 1 +qtpower.net, 1 +qtpower.org, 1 +qttransformation.com, 1 +qtv.ge, 1 +qtvr.com, 1 +qtxh.net, 1 +quacc.me, 1 +quackerswaterproofing.com, 1 +quackquack.in, 1 +quadcityjuggalos.tk, 1 +quadomania.tk, 1 +quadrantrd.com, 1 +quadratimkreis.tk, 1 +quaedam.org, 1 +quafe.tech, 1 +quaggan.co, 1 +quakeworld.tk, 1 +qualbe.com, 1 +qualebroker.com, 1 +qualiacomputers.com, 0 +qualidesign.com.br, 1 +qualite-ecole-et-formation.ch, 0 +qualith.tk, 1 +quality-life.gr, 1 +qualityasphaltutah.com, 1 +qualitybazarbd.com, 1 +qualitycarbonfiber.com, 1 +qualityconcreteleveling.com, 1 +qualityconcreteraising.com, 1 +qualityconcreterepair.com, 1 +qualitydns.net, 1 +qualityfactory.com, 1 +qualityhomesystems.com, 1 +qualitymark.com.br, 1 +qualitymudjacking.com, 1 +qualityofcourse.com, 0 +qualityoflife.tk, 1 +qualitypiering.com, 1 +qualitypolyjacking.com, 1 +qualitypropertycare.co.uk, 1 +qualitytools.com, 1 +qualitywaterproofing.com, 1 +qualitywaterproofingco.com, 1 +qualityworks.tk, 1 +qualpay.com, 1 +qualtrics.com, 1 +qualyven.com, 1 +quant-labs.de, 0 +quantaloupe.tech, 1 +quantalytics.com, 1 +quantatec.com.br, 1 +quanterra.ch, 0 +quanticlab.com, 1 +quantifiedcommerce.com, 1 +quantolytic.de, 1 +quantomaisconsorcios.com.br, 1 +quantris.net, 1 +quantrix.com, 1 +quanttydesignweb.com.br, 1 +quantuin.com, 1 +quantum-evolution.jp, 1 +quantum-lviv.pp.ua, 1 +quantum-mechanics.com, 1 +quantum.gov, 1 +quantum2.xyz, 1 +quantumcrypto.nl, 1 +quantumfinance.com.au, 1 +quantumfurball.net, 1 +quantumlink.tk, 1 +quantumpair.net, 1 +quantumtelecom.com.br, 0 +quantweb.tk, 1 +quanwuji.com, 1 +quareal.ru, 1 +quarep.org, 1 +quarim.cz, 1 +quarkcore.pt, 1 +quarkdose.de, 1 +quarrymill.com, 1 +quarterfull.com, 1 +quarterhorses.es, 1 +quarticon.com, 1 +quartix.com, 1 +quartz.im, 1 +quartzclinical.com, 1 +quarus.net, 1 +quasarelectronics.co.uk, 1 +quasetio.ml, 1 +quasiproxy.com, 1 +quasseldroid.info, 1 +quassowski.de, 1 +quatermass.tk, 1 +quaternion.tk, 1 +quatrefoiscent.fr, 1 +quattro.tk, 1 +quaxio.com, 1 +quay.net, 1 +quayhudanhbai.com, 1 +qubes-os.org, 1 +qubhockey.tk, 1 +qubyte.codes, 1 +quchao.com, 1 +quebajelagasolina.com, 1 +quedos.com.au, 1 +queenbeer.com, 1 +queencomplex.net, 1 +queencreekaz.gov, 1 +queenkedi.net, 1 +queenmargaret.ddns.net, 1 +queenparis-porn.com, 1 +queensbotanical.org, 1 +queensfactory.it, 1 +queenshaflo.com, 1 +queensrdapartments.com.au, 1 +queenstyles.tk, 1 +queer-augsburg.de, 1 +queer.farm, 1 +queer.party, 1 +queerativity.art, 1 +queercinema.ch, 1 +queextensiones.com, 1 +quehay.de, 0 +queirozmiotto.adv.br, 1 +queirozmiotto.com.br, 1 +quellarotondasembrafi.ga, 1 +quelle-catalog.tk, 1 +quelle.at, 1 +quelle.ch, 1 +quelle.de, 1 +quelleformation.net, 1 +quellenwiese.ski, 1 +quemadoresdegrasa.org, 1 +quemmeliga.com, 1 +quena-artesania.tk, 1 +quenecesitopara.com, 1 +quenotejodan.cl, 1 +quentar.tk, 1 +quentin-sauvetre.fr, 1 +quentinchevre.ch, 1 +quepourlesjuristes.fr, 1 +quera.ir, 1 +querenciavirtual.com.br, 1 +query-massage.com, 0 +quesartencomprar.com, 1 +quesecelebra.info, 1 +quest-medica.com, 1 +quest3.com, 1 +questbars.cf, 1 +questbars.ga, 1 +questdairy.com, 1 +questforgaming.com, 1 +question.cf, 1 +question.com, 1 +questionable.host, 1 +questionandanswer.ml, 1 +questionscafe.org, 1 +questoj.cn, 1 +questsocial.it, 1 +quetico.tk, 1 +quevisiongrafica.com, 1 +quezmedia.com, 1 +quezoncity.ml, 1 +quhyu.xyz, 1 +quic-hosting.de, 1 +quic.cf, 1 +quic.fr, 1 +quic.stream, 1 +quichante.com, 1 +quiche-quic.cf, 1 +quichost.com, 1 +quickassortments.com, 1 +quickboysvrouwen2.nl, 1 +quickcashcarremovals.com.au, 1 +quickerticker.tk, 1 +quickformspro.com, 1 +quickhomedecor.com, 1 +quickinfosystem.com, 1 +quickjobsfinder.com, 1 +quicklinkz.tk, 1 +quickq.nu, 1 +quickrate.de, 1 +quickrelations.de, 1 +quicksell.store, 1 +quickshops.ga, 1 +quicksupplies.us, 1 +quickudpinternetconnections.com, 1 +quickvideo.tk, 1 +quickyshare.com, 1 +quieoltre.it, 1 +quieroserbombero.org, 1 +quieroserdoula.com, 1 +quieroserdoula.es, 1 +quieroserdoula.org, 1 +quierosermercedario.tk, 1 +quierosersanta.tk, 1 +quiescent.gq, 1 +quiet-downloads.tk, 1 +quiet-waters.org, 1 +quietapple.com, 1 +quietapple.org, 1 +quietlife.tk, 1 +quietplace.tk, 1 +quietstudyactivities.tk, 1 +quik.legal, 1 +quikchange.net, 1 +quikpay.com.au, 1 +quillandpage.com, 1 +quilmo.com, 1 +quiltednorthern.com, 1 +quimatic.com.br, 1 +quimica.science, 1 +quimsertek.com, 0 +quinmedia.tk, 1 +quinnlabs.com, 0 +quinoa24.com, 1 +quintacbls.cl, 1 +quintanadelmonte.tk, 1 +quintanilla.tk, 1 +quintenbraakman.com, 1 +quintenbraakman.nl, 1 +quinteroorthodontics.com, 1 +quintessa.org, 1 +quintobarrio.tk, 1 +quiq-cdn.com, 1 +quiq-uri.com, 1 +quiq-url.com, 1 +quiq.com, 1 +quiq.im, 1 +quiq.sh, 1 +quiq.us, 1 +quiqd.com, 1 +quiqstatus.com, 1 +quiqurl.com, 1 +quiqurls.com, 1 +quire.io, 1 +quirkytravelguy.com, 1 +quisildenafil.gq, 1 +quitimes.com, 1 +quiz.biz, 1 +quiz4math.gr, 1 +quizandmoney.com, 1 +quizapps.se, 1 +quizhub.ml, 1 +quizinn.live, 1 +quizogames.com, 1 +quizz.biz, 1 +quizzard.tk, 1 +quizzen.tk, 1 +qul.link, 1 +qulix.ch, 1 +qulixqa.com, 1 +qunix.net, 1 +qunzi.la, 1 +quocdesign.ch, 1 +quoinstudio.it, 1 +quora.com, 1 +quotable.ga, 1 +quote.gq, 0 +quoteee.com, 1 +quoteidiot.com, 1 +quoteoftheday300.ga, 1 +quotesofgta.tk, 1 +quotev.com, 1 +quotidiani.net, 1 +quovadisaustria.com, 1 +qupom.com.br, 1 +quppa.net, 1 +quprop.com, 1 +quran-archive.org, 1 +quranliveonline.com, 1 +quranpdf.cf, 1 +quranvoice.tk, 1 +qurium.org, 1 +qurplus.nl, 1 +quuz.org, 1 +qvady.com, 0 +qvg.company, 1 +qvggroup.com, 1 +qvision.ml, 1 +qvq.cloud, 1 +qvq.one, 1 +qw-dev.net, 1 +qwant.com, 1 +qwantjunior.com, 1 +qwantrank.eu, 1 +qwaser.fr, 1 +qwd.no, 1 +qwdqwd.de, 1 +qwe7002.com, 1 +qwertee.com, 1 +qwerty.work, 1 +qwertyatom100.me, 1 +qwikdash.com, 1 +qwitsmoking.com, 1 +qwords.com, 0 +qwq.moe, 1 +qwrk.io, 1 +qx.fi, 1 +qx.se, 1 +qxpress.com.py, 1 +qxq.moe, 0 +qxzg.org, 1 +qxzg.xyz, 1 +qxzgssr.xyz, 1 +qybot.cn, 1 +qzhou.ddns.net, 1 +qzin.jp, 1 +r-ay.cn, 1 +r-baruth.de, 1 +r-core.org, 1 +r-ix.de, 1 +r-proj.com, 1 +r-rwebdesign.com, 1 +r-t-b.fr, 1 +r-t-n.tk, 1 +r00tsolutions.ca, 1 +r0ck1t.com.au, 1 +r0t.co, 1 +r0uzic.net, 1 +r102.ch, 1 +r15cookie.com, 1 +r16.ru, 1 +r18.moe, 1 +r1a.eu, 1 +r1ch.net, 1 +r1h3.nl, 1 +r2d2pc.com, 1 +r30365.com, 1 +r33.space, 1 +r36533.com, 1 +r3bl.blog, 1 +r3s1stanc3.me, 1 +r3t.io, 1 +r40.us, 1 +r4g3baby.com, 1 +r5197.co, 1 +r6729.co, 1 +r6729.com, 1 +r6957.co, 1 +r7.com.au, 1 +r72w.com, 1 +r7h.at, 1 +r81365.com, 1 +r82365.com, 1 +r9297.co, 1 +r9397.com, 1 +r9721.com, 1 +r9728.co, 1 +ra-joergensen.de, 1 +ra-jurochnik.de, 0 +ra-micro-koeln.de, 1 +ra-schaal.de, 1 +ra-studio.ml, 1 +ra.vc, 1 +ra3y.xyz, 1 +raadgiverborsen.com, 1 +raadvanstate.nl, 1 +raafat.ninja, 1 +raafwelfaretrustfund.gov.au, 1 +raailto.com, 1 +raamattuopisto.fi, 1 +raaynk.com, 1 +raazamooz.com, 1 +raballder.tk, 1 +rabatcity.tk, 1 +rabatt24.net, 1 +rabatt24.org, 1 +rabatz.tk, 1 +rabb-it-days.tokyo, 1 +rabbit.finance, 1 +rabbitcallcenter.com, 1 +rabbitfinance.com, 1 +rabbitinternet.com, 1 +rabbitsstore.com, 1 +rabenkralle.tk, 1 +rabica.de, 1 +rabinson2005.tk, 1 +rabota-online.tk, 1 +rabota-x.ru, 1 +rabotabiz.tk, 1 +rabotaemdoma.tk, 1 +rabotanet.tk, 1 +rabotaprofily.tk, 1 +rabotayte.tk, 1 +rabotenkadot.tk, 1 +rabynska.eu, 1 +racaliz.tk, 1 +racamera.com, 1 +racasdecachorro.org, 1 +raccoltarifiuti.com, 1 +raccoon.fun, 1 +raccoon.io, 1 +racermaster.xyz, 1 +racesimscoring.com, 1 +rachaeltaylor.tk, 1 +rachelchen.me, 1 +racheldiensthuette.de, 1 +rachelmoorelaw.com, 1 +rachelreagan.com, 1 +rachelsbouncycastles.co.uk, 1 +racheltinniswood.ie, 1 +rachnacollege.tk, 1 +racing-planet.cz, 1 +racingfanclub.tk, 1 +racius.com, 1 +rackblue.com, 1 +rackoon.de, 1 +raclet.co.uk, 1 +raconconsulting.co.uk, 1 +raconteurs.gent, 1 +racunovodstvo-prina.si, 1 +rad-route.de, 1 +rad2share.com, 1 +rada-group.eu, 1 +radar.sx, 1 +radaravia.ru, 1 +radarbanyumas.co.id, 1 +radarcoupon.ch, 1 +radarcoupon.it, 1 +radarcupao.pt, 1 +radarcupom.com.br, 1 +radarcupon.com.ar, 1 +radarcupon.com.mx, 1 +radarcupon.es, 1 +radarnext.com, 1 +radartatska.se, 1 +radartek.com, 1 +radcliffky.gov, 1 +radcloud.de, 1 +radcube.hu, 1 +raddle.me, 1 +radechefonne.it, 1 +radegundisfest.de, 1 +radekmazar.eu, 1 +rader.ninja, 1 +raderamig.com, 1 +radfieldhomecare.co.uk, 1 +radfieldhomecarefranchising.co.uk, 1 +radharanikijay.tk, 1 +radiantenergy.tk, 1 +radiantweb.co.za, 1 +radiation-oncologist.gr, 1 +radiationserviceswa.com.au, 1 +radiationtherapy.tk, 1 +radical.org, 1 +radicaldream.tk, 1 +radicalepil-haguenau.fr, 1 +radicalfuture.tk, 1 +radicaloptimism.org, 1 +radicalsub.com.br, 1 +radicalwebdesign.co.uk, 1 +radio-angelos.tk, 1 +radio-az.tk, 1 +radio-bandit.ml, 1 +radio-brest.tk, 1 +radio-club.ml, 1 +radio-delmare.tk, 1 +radio-mix.ml, 1 +radio-mouse.tk, 1 +radio-one.ml, 1 +radio-online.tk, 1 +radio-pulsar.com, 1 +radio-pulsar.eu, 1 +radio-utopie.de, 1 +radio-valois-multien.fr, 1 +radio1.ie, 1 +radio404.tk, 1 +radio99.tk, 1 +radioactivenetwork.xyz, 1 +radioafibra.com.br, 1 +radioaltamar.tk, 1 +radiobandung.tk, 1 +radioborges.tk, 1 +radiobox.net, 0 +radiocappissima.tk, 1 +radiocartel.tk, 1 +radiocommande-industrielle.fr, 1 +radiocommg.com.br, 1 +radiocomsaocarlos.com.br, 1 +radiocrash.tk, 1 +radiocrazy.ml, 1 +radioculture.tk, 1 +radiodance.tk, 1 +radiodeluxe.ml, 1 +radiodetali-gold.ru, 1 +radiodeutsch.com, 1 +radiodiagonal.tk, 1 +radiodoblen.tk, 1 +radioduepuntozero.it, 1 +radiodxguatemala.tk, 1 +radioelectronic.tk, 1 +radioenam.tk, 1 +radiofmimagen.net, 1 +radiogaga.ga, 1 +radiogear.ru, 1 +radiogomezone.tk, 1 +radioharrastus.tk, 1 +radioheaven.co.kr, 1 +radioheikrekel.tk, 1 +radioheteroglossia.com, 1 +radiohlam.ga, 1 +radiohouse.tk, 1 +radiohub.ru, 1 +radioibiapina.tk, 1 +radioilusion.es, 1 +radioilusiones.tk, 1 +radiojackienorth.tk, 1 +radioknop.nl, 1 +radiokukesi.tk, 1 +radioldpr.ru, 1 +radiolla.com, 1 +radiology-technician.com, 1 +radiom.fr, 1 +radiomacuto.gq, 1 +radiomagicafm.tk, 1 +radiomercure.net, 1 +radiomikelerentxun.tk, 1 +radiomodem.dk, 1 +radiomontebianco.it, 1 +radiomoodmix.tk, 1 +radionetcolombia.tk, 1 +radionojavan.ir, 1 +radionrg.tk, 1 +radiooffice.tk, 1 +radioperfect.tk, 1 +radiopharereims.tk, 1 +radiopleer.net, 1 +radiopolarniki.spb.ru, 1 +radiopranfm.cf, 1 +radiopush.tk, 1 +radior9.it, 1 +radioradicchio.it, 1 +radiorainbow.tk, 1 +radiorecord.ml, 1 +radioremix80.tk, 1 +radioricardo.tk, 1 +radios-associatives.tk, 1 +radiosatbolivia.com, 1 +radiosdeguate.com, 0 +radioseda.ca, 1 +radiosimba.ug, 1 +radiosuperplus.tk, 1 +radiotataouine.tk, 1 +radiotelephoni.tk, 1 +radiotv.tk, 1 +radioumbrella.ga, 1 +radiounofm.tk, 1 +radiounost.tk, 1 +radiowakeup.tk, 1 +radiozetta.tk, 1 +radis-adopt.com, 1 +radito.com, 1 +radium-it.ru, 1 +radium.group, 1 +radiumcode.com, 1 +radiumone.io, 1 +radixsalon.tk, 1 +radixweb.com, 1 +radlina.com, 1 +radnas.com, 1 +radnickapartija.tk, 1 +radomir-online.ru, 1 +radon.tk, 1 +radondetectionandcontrol.com, 1 +radost.digital, 1 +radreisetraumtreibstoff.de, 1 +raduga-tv.tk, 1 +raduga4.ml, 1 +radyabkhodro.net, 1 +radyn.com, 1 +radyodinle.mobi, 1 +radzikow.ski, 1 +raeder-test.azurewebsites.net, 1 +raeu.me, 1 +raeven.nl, 1 +raevinnd.com, 1 +raewardfresh.co.nz, 1 +rafaeltuber.cf, 1 +rafaroca.net, 1 +rafas.com.tr, 1 +raffaellaosti.com, 1 +raffleshospital.co.id, 0 +rafo.tk, 1 +rafsurveys.co.uk, 1 +raft.pub, 1 +rafting-japan.com, 1 +rafue.com, 1 +rafunnews.com, 1 +ragasto.nl, 1 +rage-overload.ch, 1 +rage4.com, 1 +raghughphotography.tk, 1 +raghuspeaks.com, 1 +raginggaming.ga, 1 +ragingserenity.com, 1 +raglits.co.uk, 1 +ragnaroktop.com.br, 1 +ragprint.com, 1 +ragrosstudios.com, 1 +ragu.co.uk, 1 +rahayi.tk, 1 +rahedm.ir, 1 +raheel.cf, 1 +raheel.tk, 1 +rahilworld.tk, 1 +rahulpnath.com, 1 +raiceshebreas.org, 1 +raid-runners.fr, 1 +raidemeraude.com, 1 +raidensnakesden.co.uk, 1 +raidensnakesden.com, 1 +raidensnakesden.net, 1 +raiderhacks.com, 1 +raidstone.net, 1 +raidstone.rocks, 1 +raiffeisen-kosovo.com, 1 +raiffeisen-lune.de, 1 +raiffeisenleasing-kosovo.com, 1 +raiilto.com, 1 +raiito.com, 1 +rail-o-rama.nl, 1 +rail-to.com, 1 +rail24.nl, 1 +rail360.nl, 1 +railbird.nl, 1 +railbus.fan, 1 +railclub.tk, 1 +railduction.eu, 1 +railgun.ac, 1 +railjob.cn, 1 +raillto.com, 1 +railorama.nl, 1 +railpassie.nl, 1 +railsideworks.com, 1 +railto-sucks.com, 1 +railto.cm, 1 +railto.co, 1 +railto.com, 1 +railto.com.de, 1 +railto.com.se, 1 +railto.llc, 1 +railto.net, 1 +railto.org, 1 +railtocom.com, 1 +railtoexchange.com, 1 +railtollc.com, 1 +railtosucks.com, 1 +railtto.com, 1 +railvideo.co.uk, 1 +railvideo.net, 1 +railvideo.nl, 1 +rain.bz, 1 +rainbeaus.gq, 1 +rainbow-web.com, 1 +rainbow.pizza, 1 +rainbowbay.org, 1 +rainbowbrains.com, 1 +rainbowcomputer.tk, 1 +rainbowflowers.co.uk, 0 +rainbowinflatables.co.uk, 1 +rainbowloompattern.com, 1 +rainbowloompatterns.com, 1 +rainbowmath.tk, 1 +rainbowpvtech.com, 1 +rainbowsmoothies.win, 1 +rainbowstore.com.au, 1 +rainbowstore.com.ua, 1 +rainbowswingers.net, 1 +raincoat.systems, 1 +rainel.at, 1 +rainer-knappe.de, 1 +rainforest.engineering, 1 +rainierpros.com, 1 +rainiv.com, 1 +rainmanzone.com, 1 +rainnetwork.tk, 1 +rainpaper.com, 1 +rainstormsinjuly.co, 1 +raintreatment.ga, 1 +rainturtle.com, 1 +rainville.me, 1 +rainway.com, 1 +rainway.io, 1 +raipet.no-ip.biz, 1 +raipet.spdns.eu, 1 +raisecorp.com, 1 +raiseyourflag.com, 1 +raisingzona.com, 1 +raissarobles.com, 1 +raistrick.art, 1 +raistrick.it, 1 +raitlo.com, 1 +raitza.de, 1 +raivis.com, 0 +rajaealhoceima.tk, 1 +rajasatour.id, 1 +rajeshkochhar.com, 1 +rajivdeepinsights.com, 1 +rajkapoordas.com, 1 +rajofestival.tk, 1 +rak-business-service.com, 1 +raketa.travel, 1 +raketaro.de, 1 +raketenwolke.de, 1 +rakipro.com, 1 +rakom.tk, 1 +rakovec.hr, 1 +raksha-bandhanwish.ga, 1 +raku.bzh, 1 +rakugaki.cn, 1 +rakugokai.net, 1 +rakuma.xyz, 1 +ralfs-zusizone.de, 1 +ralimtek.com, 0 +ralix.net, 1 +rallto.com, 1 +rally-base.com, 1 +rally-base.cz, 1 +rally-base.eu, 1 +rally-results.eu, 1 +rally-vysledky.cz, 1 +rallybase.cz, 1 +rallybase.eu, 1 +rallycycling.com, 1 +rallytrophy.tk, 1 +ralphbisschops.com, 1 +raltha.com, 1 +ralvke.rocks, 1 +ram-it.nl, 1 +ram.nl, 1 +rama.ovh, 1 +ramatola.uk, 0 +ramblingrf.tech, 1 +rambo.codes, 1 +ramdigital.xyz, 1 +ramen-dealer.de, 1 +rametrix.com, 1 +ramiabusalah.tk, 1 +ramieres.cf, 1 +ramirito.tk, 1 +ramitan.com, 1 +ramitmittal.com, 1 +ramleather.vn, 1 +rammstein-portugal.com, 1 +rammsteinaustralia.tk, 1 +rammsteinzone.tk, 1 +ramos.tur.br, 1 +rampestyuma.com, 1 +ramrecha.com, 0 +ramsaver.com.br, 1 +ramsdensforcash.co.uk, 1 +ramsdensplc.com, 1 +ramsor-gaming.de, 1 +ramt.tk, 1 +ramtechmodular.com, 1 +ramuel.com, 0 +ramydent.no, 1 +ramynetwork.tk, 1 +ran-drunken.tk, 1 +ran-sama.ddns.net, 1 +ranalawassociates.com, 1 +ranasinha.com, 1 +rancowar.com, 1 +randc.org, 1 +randolf.ca, 1 +randolphcareertech.com, 1 +random-samplings.org, 1 +random.org, 1 +randomadversary.com, 1 +randomarticle.ml, 1 +randombit.eu, 0 +randombooks.gq, 1 +randombrainwave.cf, 1 +randomcode.org, 1 +randomdomain.io, 1 +randomkindness.tk, 1 +randomkoalafacts.com, 1 +randomprecision.co.uk, 1 +randomquotesapp.com, 1 +randomsearching.ml, 1 +randomserver.pw, 1 +randomserver.xyz, 1 +randomsnapshots.tk, 1 +randomstuffproductions.tk, 1 +randomtest.cf, 1 +randomthings.cf, 1 +randstalker.ovh, 1 +randy.su, 1 +randyrhoads.tk, 1 +ranfics.tk, 1 +ranfurlychambers.co.nz, 1 +rangde.org, 1 +range.co, 1 +rangercollege.edu, 1 +rangerfiles.tk, 1 +rangersloyalsite.tk, 1 +rangersofbelgium.be, 1 +rangsmo.se, 1 +rangzol.now.sh, 1 +ranikaart.com, 1 +raniwan.com, 1 +ranjanbiswas.com, 1 +ranjanbiswas.in, 1 +rank-net.de, 1 +rankgiants.com, 1 +rankgrowup.com, 1 +rankia.ga, 1 +ranking-deli.jp, 1 +ranking-mensesthe.jp, 1 +ranking10hits.tk, 1 +rankingide.tk, 1 +rankingofe.com.pl, 1 +rankingubezpieczeniowy.pl, 1 +rankingubezpieczennazycie.pl, 1 +ranksite.ga, 1 +ranksite.tk, 1 +ranktopay.com, 1 +rannamoisaaiasalong.ee, 1 +rannseier.org, 1 +ranos.org, 1 +ranson.com.au, 1 +rantamplan.tk, 1 +rantanda.com, 1 +ranters.nl, 1 +ranwest.com, 1 +ranyeh.co, 1 +ranzbak.nl, 1 +raoliveoil.ga, 1 +raomed.com.ar, 1 +raoul-kieffer.net, 1 +rap4ever.org, 1 +rapanui.tk, 1 +rapay.net, 1 +rapdinle.tk, 1 +rapdogg.com, 1 +rapenroer.com, 1 +rapenroer.nl, 1 +raphael.li, 1 +raphaeladdile.com, 1 +raphaelcasazza.ch, 0 +raphaelmoura.ddns.net, 1 +raphrfg.com, 1 +rapidapp.io, 1 +rapidflow.io, 1 +rapidgator.net, 1 +rapidhubs.com, 1 +rapidminer.com, 0 +rapidoo.com.br, 1 +rapidscale.net, 1 +rapidsec.net, 1 +rapidshit.net, 1 +rapidstone.com, 1 +rapidxray.biz, 1 +raportdnia.pl, 1 +rappet.de, 0 +rapport.link, 1 +rapportdecoracoes.com.br, 1 +raps.org, 1 +raptechpk.com, 1 +raptorsrapture.com, 1 +rapu.nz, 1 +rapwoyska.tk, 1 +raqm1.com, 1 +raqoo.jp, 1 +raquelmolinacases.tk, 1 +raraflora.com.au, 1 +rarbgmirror.com, 1 +rarbgproxy.com, 1 +rarece.cf, 1 +rarefish.tk, 1 +rarename.tk, 1 +rarlab.com, 1 +raryosu.info, 1 +ras34.ru, 1 +rasagiline.com, 1 +rasberry.cf, 1 +rasc.info, 1 +rascahan.org, 1 +rascals-castles.co.uk, 1 +rascals.ga, 1 +rascalscastles.co.uk, 1 +rascalscastlesdoncaster.co.uk, 1 +rascript.tk, 1 +rascvet.tk, 1 +rase.rocks, 1 +rasebo.ro, 1 +raserbajs.tk, 1 +rashbogota.tk, 1 +rasheed-nuss.tk, 1 +rashmipandit.com, 1 +raskruti.ml, 1 +raskrutka.cf, 1 +rasmushaslund.com, 1 +raspberryultradrops.com, 1 +raspii.tech, 1 +raspitec.ddns.net, 1 +rassadacvetov.com, 0 +rasset.ie, 1 +rassro.sk, 1 +rastabooks.ga, 1 +rastasorganics.com, 1 +rastko-jevtovic.tk, 1 +rasto.sk, 1 +rasty.cz, 1 +ratajczak.one, 1 +ratasdesign.com, 1 +ratd.net, 1 +rate.is, 1 +ratebridge.com, 1 +rateddomain.ml, 1 +ratelimited.me, 1 +ratelsec.com, 1 +ratepayeralliance.org, 1 +rathbonesonline.com, 1 +rathgeb.org, 1 +rathorian.fr, 1 +ratihluhur.com, 1 +ratinq.co, 1 +ratiocinat.ga, 1 +rationalcreation.com, 1 +rationalism.com, 1 +rationalops.com, 1 +ratirl.be, 1 +ratsmicedormice.com, 1 +rattattees.com, 1 +rattenkot.io, 1 +ratujemyzwierzaki.net, 1 +ratujmydzikiekoty.org, 1 +ratujmydzikiekoty.pl, 1 +ratusha.ml, 1 +raucris.ro, 1 +raulmalea.ro, 1 +raulrivero.es, 1 +raumzeitlabor.de, 0 +rauros.net, 1 +rauschenbach.de, 1 +rautarutto.tk, 1 +ravada-vdi.com, 1 +ravagers.tk, 1 +ravages.tk, 1 +ravasco-football-team.herokuapp.com, 1 +ravchat.com, 1 +raveboy.dyndns.org, 1 +ravelin.com, 1 +raven.dog, 1 +raven.express, 1 +ravencoin.com, 1 +ravencoin.org, 1 +ravengergaming.net, 1 +ravenrockrp.com, 1 +ravensbuch.de, 1 +ravenstonejeweler.com, 1 +raventechnology.es, 1 +ravenx.me, 1 +raveseguros.com, 1 +ravhaaglanden.org, 1 +ravihotel.com, 0 +ravijuhend.ee, 1 +ravik.tk, 1 +ravimiamet.ee, 1 +ravindran.me, 1 +raviparekh.co.uk, 1 +ravis.org, 1 +ravkr.duckdns.org, 1 +ravne.land, 1 +ravron.com, 1 +ravse.dk, 1 +rawa-ruska-union-nationale.fr, 1 +rawbeautysource.com, 1 +rawcbd.shop, 1 +rawdamental.com, 1 +rawdutch.nl, 1 +rawfitco.com.au, 1 +rawforce.tk, 1 +rawinfosec.com, 1 +rawlord.ga, 1 +rawpearls.com, 1 +rawr.sexy, 1 +raxion.cf, 1 +raxion.tk, 1 +ray-works.de, 1 +raya.io, 0 +rayadventure.com, 1 +raycarruthersphotography.co.uk, 1 +raycon.io, 1 +raydius.de, 1 +rayfalling.com, 1 +rayhanshop.online, 1 +rayiris.com, 1 +raykitchenware.com, 1 +raym.ml, 1 +raymcbride.com, 1 +raymd.de, 1 +raymondelooff.nl, 1 +raymondha.ca, 1 +raymondha.com, 1 +raymundo.doctor, 1 +raynbo.ai, 1 +raynersorchard.com.au, 1 +raynis.net, 1 +raynoonanwindows.ie, 1 +raysei.com, 1 +raysmtp.ga, 1 +raysolutions.tk, 1 +raystark.com, 1 +raywardapparel.com, 1 +raywisdom.tk, 1 +rayworks.de, 1 +raza.gr, 1 +razajewellers.com, 1 +razalabs.gr, 1 +razberry.kr, 1 +razborpoletov.cf, 1 +razborpoletov.ml, 1 +razborpoletov.tk, 1 +razborpoletovsite.tk, 1 +razdolnoe.tk, 1 +razeencheng.com, 1 +razgon.ga, 1 +razrabo.tk, 1 +razrsec.uk, 1 +razvanburz.ro, 1 +razvanvatamanu.ro, 1 +razvlekuha.cf, 1 +razvlekuhablog.tk, 1 +rb-china.net, 1 +rb0.de, 1 +rb67.de, 1 +rbcservicehub-uat.azurewebsites.net, 1 +rbd.events, 1 +rbensch.com, 1 +rbet.tk, 1 +rbflote.lv, 1 +rbh.co.uk, 1 +rbiacademylms.org, 1 +rbin.nl, 1 +rbltracker.com, 1 +rblx.red, 1 +rbmafrica.co.za, 1 +rbmland.com, 1 +rbn.is, 1 +rbnet.xyz, 1 +rbran.com, 1 +rbs.co.uk, 1 +rbs.com, 1 +rbscrochet.com, 1 +rbsexshop.com.br, 1 +rbt.sx, 1 +rbtvshitstorm.de, 1 +rbuddenhagen.com, 1 +rburchell.com, 0 +rburz.com, 1 +rbx.com, 1 +rbx.gg, 1 +rbxcatalog.com, 1 +rc-offi.net, 1 +rc-shop.ch, 1 +rc21x.com, 1 +rc7.ch, 1 +rca.fr, 1 +rca.ink, 1 +rca2015.ru, 1 +rccom.ru, 1 +rccsc.org, 1 +rcd.cz, 0 +rcdocuments.com, 1 +rcdrone.tk, 1 +rcgoncalves.pt, 1 +rchavez.site, 1 +rchrdsn.uk, 1 +rclaywilliamsdo.com, 1 +rclsm.net, 1 +rcmlinx.com, 1 +rcmstream.com, 1 +rcnitrotalk.com, 1 +rcoliveira.com, 1 +rcpdesign.cl, 1 +rcraigmurphy.net, 1 +rcsda.net, 1 +rcsolutions.nl, 1 +rcsscontractors.com, 1 +rct-chair.com, 1 +rct.sk, 0 +rct.uk, 1 +rctalk.com, 1 +rctiads.com, 1 +rctx.tk, 1 +rcxzsc.com, 1 +rdactive.de, 1 +rdactive.net, 1 +rdap.co.il, 1 +rdcdesign.com, 1 +rddjapan.info, 1 +rded.nl, 1 +rdesigner.tk, 1 +rdfencingandgates.co.uk, 1 +rdfmapped.com, 1 +rdfproject.it, 1 +rdfz.tech, 1 +rdh.asia, 1 +rdienclosures.com, 1 +rdimedical.com, 1 +rdjb2b.com, 1 +rdkf.de, 1 +rdl.at, 1 +rdmc.fr, 1 +rdmc.io, 1 +rdmc.network, 1 +rdmc.support, 1 +rdmrotterdam.nl, 1 +rdmshit.net, 1 +rdmtaxservice.com, 1 +rdns.cc, 0 +rdns.gq, 1 +rdv-cni.fr, 1 +rdv-coquin-rapide.fr, 1 +rdv-prefecture.com, 1 +rdviitd.org, 1 +rdvobras.pt, 0 +rdwh.tech, 0 +rdxbioscience.com, 1 +rdxsattamatka.mobi, 1 +rdzenie.pl, 1 +re-crawl.com, 1 +re-engines.com, 1 +re-inspect.com, 1 +re-presented.de, 1 +re-security.com, 1 +re-wilding.com, 1 +re.yt.nom.br, 1 +reach-on.de, 1 +reach.gov, 1 +reachhead.com, 1 +reachley.net, 1 +reachrss.com, 1 +reaconverter.com, 1 +react-db.com, 1 +reactionindex.com, 1 +reactions.ai, 1 +reactive-press.com, 1 +reactivemarkets.com, 1 +reactor-family.tk, 1 +reactpwa.com, 1 +read.mk, 1 +readabilitychecker.com, 1 +readable.pw, 1 +readcomics.gq, 1 +reades.co.uk, 1 +reades.uk, 1 +readify.net, 1 +readifycloud.com, 1 +reading-assist.com, 1 +readingandmath.org, 1 +readingea.com, 1 +readingrats.de, 1 +readlater.de, 1 +readless.cf, 1 +readmusiccoleman.com, 1 +readmynews.cf, 1 +readonly.de, 1 +readouble.com, 0 +readpages.gq, 1 +ready4bf.tk, 1 +readybetwin.com, 1 +readychurchsites.com, 1 +readydedis.com, 1 +readyelec.com, 1 +readyrowan.com, 1 +readyrowan.org, 1 +readyscif.com, 1 +readysell.net, 1 +readysetscif.com, 1 +readystep.ga, 1 +readytongue.com, 0 +readytowear.es, 1 +readywithresourcestn.gov, 1 +reaganlibrary.gov, 1 +reakcjonista.tk, 1 +reaksi.id, 1 +real-bits.com, 1 +real-digital.co.uk, 1 +real-it.nl, 1 +real-neo.me, 1 +real-srebrenica-genocide.cf, 1 +real-work.tk, 1 +real360show.com, 1 +realbiz.ml, 1 +realcanada.com.gt, 1 +realcapoeira.ru, 1 +realestate-in-uruguay.com, 1 +realestate-lidl.at, 1 +realestate-lidl.be, 1 +realestate-lidl.bg, 1 +realestate-lidl.ch, 1 +realestate-lidl.co.uk, 1 +realestate-lidl.com, 1 +realestate-lidl.cz, 1 +realestate-lidl.dk, 1 +realestate-lidl.fr, 1 +realestate-lidl.gr, 1 +realestate-lidl.it, 1 +realestate-lidl.lt, 1 +realestate-lidl.lu, 1 +realestate-lidl.lv, 1 +realestate-lidl.pl, 1 +realestate-lidl.pt, 1 +realestate-lidl.ro, 1 +realestate-lidl.rs, 1 +realestate-lidl.se, 1 +realestate-lidl.sk, 1 +realestateagency.cf, 1 +realestatecentralcoast.info, 1 +realestatemarketingblog.org, 1 +realestateonehowell.com, 1 +realestatesales.gov, 1 +realfamilyincest.com, 1 +realfreedom.city, 0 +realgogo.com, 1 +realhorsegirls.net, 1 +realhost.name, 1 +realhypnosistraining.com.au, 1 +realincest.tv, 1 +realinsurance.com.au, 1 +reality.news, 1 +reality0ne.com, 0 +realitycrazy.com, 1 +realitystarfacts.com, 1 +realitytoday.cf, 1 +realkeywords.ga, 1 +reall.uk, 1 +reallifeforums.com, 1 +reallivingcc.com, 1 +realloc.me, 1 +reallovetab.ga, 1 +really-simple-ssl.com, 1 +really.ai, 1 +reallycooljobs.ga, 1 +reallytrusted.com, 1 +reallywild.tk, 1 +realm-of-shade.com, 1 +realm.is, 1 +realme.govt.nz, 1 +realmofaesir.com, 1 +realmofespionage.xyz, 1 +realnature.com.br, 1 +realneo.me, 1 +realno-money.tk, 1 +realoteam.ddns.net, 1 +realpropertyprofile.gov, 1 +realpython.com, 1 +realrapfans.tk, 1 +realtechreviews.com, 1 +realtime1.com.br, 1 +realtoraidan.com, 1 +realty-pochta.tk, 1 +realty.tatar, 1 +realtygroup-virginia.com, 1 +realtyink.net, 1 +realum.com, 1 +realum.de, 1 +realum.eu, 1 +realum.net, 1 +realvnc.help, 1 +realwaycome.com, 1 +realwebsite.ga, 1 +realwildart.com, 1 +realwinner.es, 1 +realworldholidays.co.uk, 1 +reancos.report, 1 +reanimated.eu, 1 +rearmatch.cf, 1 +rearmatch.ga, 1 +reath.xyz, 1 +reavaninc.com, 1 +reaven.nl, 1 +rebajasoferta.com, 1 +rebalancenyc.com, 1 +rebane2001.com, 1 +rebatekey.com, 1 +rebeagle.com, 1 +rebeccawendlandt.com, 1 +rebeccawilson.co.uk, 1 +rebelbranding.nl, 1 +rebelcorp.cloud, 1 +rebelcorp.ltd, 1 +rebelessex.com, 1 +rebelko.de, 1 +rebellecare.com, 1 +rebellion.scot, 1 +rebelonline.nl, 1 +rebelz.se, 1 +rebirthia.me, 1 +rebizzield.com, 1 +rebonus.com, 1 +reboundtravel.com, 1 +reboxetine.com, 1 +reboxonline.com, 1 +rebuga.com, 0 +rebull.fr, 1 +reby.tk, 1 +recalls.gov, 1 +recantoshop.com, 1 +recantoshop.com.br, 1 +recaptcha-demo.appspot.com, 1 +recardio.info, 0 +recebersms.com, 1 +receitas.tk, 1 +receptenwebsite.com, 1 +receptenwebsite.nl, 1 +receptionpoint.com, 1 +receptionsbook.com, 1 +recessmonkeyz.tk, 1 +recetasboricuas.com, 1 +recetasdemape.com, 0 +recetin.com, 1 +recettemedievale.fr, 0 +rechenknaecht.de, 1 +rechenwerk.net, 1 +recherchegruppe.tk, 1 +recht.us, 1 +rechtenliteratuurleiden.nl, 0 +rechtsanwaeltin-vollmer.de, 1 +rechtschreibpruefung24.de, 1 +recidivism.com, 1 +recipea.com, 1 +recipegym.com, 1 +recipekensaku.com, 1 +recipeslist.tk, 1 +recipesmadeeasy.co.uk, 1 +recipex.ru, 1 +recipeyak.com, 1 +reciplast.cl, 1 +recitoners.net, 1 +recklessly.ga, 1 +reckoning.gq, 1 +reckontalk.com, 1 +reclaimmysparkle.com, 1 +reclametoolz.nl, 1 +reclusiam.net, 1 +recmon.hu, 1 +reco-studio.de, 1 +recolic.cc, 1 +recolic.net, 1 +recolic.org, 1 +recolor.ml, 1 +recomendador.cl, 1 +recommend.pro, 1 +recommended.reviews, 1 +recommends.ml, 1 +recompiled.org, 0 +recon-networks.com, 1 +recordexpressllc.com, 1 +recordmeeting.jp, 1 +recordmeeting.net, 1 +recordsmanagement.gov, 1 +recordstudio.tk, 1 +recoveringfromfaith.com, 1 +recoveringircaddicts.org, 1 +recoveringmarketer.com, 1 +recoveryohio.gov, 1 +recoveryonline.org, 1 +recoveryteam.org, 1 +recoveryunplugged.com, 1 +recrea.pl, 1 +recreatieftotaal.nl, 1 +recruit.net, 1 +recruiterbox.com, 1 +recruitmade.jp, 1 +recruitnow.nl, 1 +recruitsecuritytraining.co.uk, 1 +recruitsecuritytraining.com, 1 +recruitskill.cf, 1 +rectecforum.com, 1 +rectoraudiparts.com, 1 +recuperatucuentaya.com, 1 +recuperatufigura.com, 1 +recupero.it, 1 +recuperodatiraidfastec.it, 1 +recurly.com, 1 +recurrentmeningitis.org, 1 +recursionrecursion.co.uk, 1 +recursos.vip, 1 +recursoscristianosleinad.com, 1 +recursosdeautoayuda.com, 1 +recursosmi.com.br, 1 +recycle.cf, 1 +recyclebin.email, 1 +recycledinorsett.co.uk, 1 +recycledinorsett.com, 1 +recycling.tk, 1 +recyclingisland.com, 1 +recyklacekovu.cz, 1 +red-button.hu, 1 +red-dragon.tk, 1 +red-eyed-tree-frogs.com, 1 +red-lightning.tk, 1 +red-planet.tk, 1 +red-t-shirt.ru, 1 +red-train.de, 1 +red-trigger.net, 1 +red031000.com, 1 +red2fred2.com, 1 +redable.hosting, 1 +redable.nl, 1 +redacted.life, 1 +redactedmedia.org, 1 +redactieco.nl, 1 +redballoonsecurity.com, 1 +redbarnwoodwork.com, 1 +redburn.com, 1 +redcabbage.tk, 1 +redcanary.co, 1 +redcapital.cl, 1 +redcardinal.tk, 1 +redcarpetmonday.com, 1 +redcat.tk, 1 +redcatrampageforum.com, 1 +redchat.cz, 1 +redchip.com.au, 1 +redcoded.com, 1 +redcone.net, 1 +redcorus.com, 1 +redcross.com.ph, 1 +redcupit.com, 1 +redd.it, 1 +reddcrypt.com, 1 +reddepsicologosdecr.com, 1 +reddevilarmada.com, 1 +reddingo.at, 1 +reddingo.be, 1 +reddingo.ch, 1 +reddingo.com, 1 +reddingo.com.au, 1 +reddingo.de, 1 +reddingo.es, 1 +reddingo.eu, 1 +reddingo.fr, 1 +reddingo.it, 1 +reddingo.jp, 1 +reddingo.nl, 1 +reddingo.nz, 1 +reddingrancheria-nsn.gov, 1 +reddingsbrigade-zwolle.nl, 1 +reddingsbrigadeveghel.nl, 1 +reddiseals.com, 0 +reddit.com, 1 +reddit2kindle.com, 1 +reddraggone9.com, 1 +reddyai.com, 1 +rede-reim.de, 1 +rede-t.com, 1 +redearsliderturtles.com, 1 +redecloud.xyz, 1 +redecsirt.pt, 1 +redeemingbeautyminerals.com, 1 +redelectrical.co.uk, 0 +redemption.gq, 1 +redes-neuronales.tk, 1 +redeshoprural.com.br, 1 +redespaulista.com, 0 +redessantaluzia.com.br, 1 +redeyeguatemala.tk, 1 +redflare.com.au, 1 +redfog.com, 1 +redfox-infosec.de, 0 +redfoxmarketiing.com, 1 +redgatesoftware.co.uk, 1 +redgeek.cf, 1 +redgoose.ca, 1 +redgravity.net, 1 +redhandedsecurity.com.au, 1 +redhawkwa.com, 1 +redheadfuck.com, 1 +redheeler.com.br, 1 +redhillboardriders.tk, 1 +redhottube.cf, 1 +redhottube.ga, 1 +redhottube.gq, 1 +redhottube.ml, 1 +redi.tk, 1 +rediazauthor.com, 1 +redicare.ml, 1 +redion.me, 1 +redir.me, 1 +redireci.one, 1 +redirecionarnoticias.ml, 1 +redirect.fedoraproject.org, 1 +redirect.stg.fedoraproject.org, 1 +redirection-plf.online, 1 +redisgreen.com, 1 +rediske.me, 1 +redite.co, 1 +redivis.com, 1 +redjuice.co.uk, 1 +redkiwi.nl, 1 +redlands.net.au, 1 +redlatam.org, 1 +redleslie.com, 1 +redletter.link, 1 +redlinelap.com, 1 +redlink.de, 1 +redlinker.ml, 1 +redlionclub.ga, 1 +redmangallpsychologists.com.au, 1 +redmejoracontinua.com, 1 +redmind.se, 1 +redmondoregon.gov, 1 +redmondtea.com, 1 +redmoon.cloud, 1 +redmore.me, 1 +redneck-radio.tk, 1 +redneragenturen.org, 1 +rednsx.org, 1 +rednumberone.com, 1 +redparrotstudios.tk, 1 +redpen.gr, 1 +redper.serveminecraft.net, 1 +redphi.dedyn.io, 1 +redprice.by, 1 +redq.now.sh, 1 +redrafting.ga, 1 +redraven.studio, 1 +redray.org, 1 +redrichindia.com, 1 +redriverhealthandwellness.com, 1 +redrivernm.gov, 1 +redrowcareers.co.uk, 1 +reds-dev.ga, 1 +redsequence.com, 1 +redshiftcybersecurity.co.za, 1 +redshoeswalking.net, 1 +redsicom.com, 1 +redsiege.com, 1 +redskullstuff.gq, 1 +redsolutor.gq, 1 +redsquarelasvegas.com, 1 +redstack.tk, 1 +redstarpictures.tk, 1 +redstarsurf.com, 1 +redstoner.com, 1 +redtails.tk, 1 +redteam-pentesting.de, 1 +redtomato.ga, 1 +redtrig.ca, 1 +redtrig.com, 1 +redtsar2000papers.tk, 1 +redtubs.tk, 1 +reducealcoholism.com, 1 +reducto.tk, 1 +redunion.tk, 1 +redwater.co.uk, 1 +redwaterhost.com, 1 +redwaymu.cf, 1 +redweek.com, 1 +redwhey.com, 1 +redwiki.tk, 1 +redworks.nl, 1 +redzonedaily.com, 1 +reecewindows.com, 1 +reed-sensor.com, 1 +reedloden.com, 1 +reeftrip.com, 1 +reelnews.ga, 1 +reemployks.gov, 1 +reenergo.ru, 1 +reening.net, 1 +reensshop.com, 1 +reentry.gov, 1 +rees-carter.net, 1 +reesmichael1.com, 1 +reeson.at, 1 +reeson.de, 1 +reeson.info, 1 +reeson.org, 1 +reevaappliances.co.uk, 1 +reeves-family.com, 1 +reexporta.com, 1 +ref1oct.nl, 1 +refalm.com, 1 +refansta.com, 1 +refer.codes, 1 +referat.club, 1 +referat.me, 1 +referati-ru.tk, 1 +referati.tk, 1 +referdell.com, 1 +refertimacuan.com, 1 +refillthecity.eu, 1 +refinansiering.no, 1 +refinedlightingaz.com, 1 +refinedroomsllc.com, 1 +refinery29.com, 1 +refjob.jp, 1 +reflectiondentallasvegas.com, 1 +reflecton.io, 1 +refletindosaude.com.br, 1 +reflets.info, 1 +reflexions.co, 1 +reflexionspain.tk, 1 +reflexive-engineering.com, 1 +reflexive.xyz, 1 +refluxogastroesofagico.ga, 1 +refood-cascaiscpr.eu, 1 +reformasflores.com, 1 +reformasiluro.com, 1 +reformation.financial, 1 +reformatreality.com, 1 +refreshcartridges.co.uk, 1 +refreshingserum.com, 1 +refreshliving.us, 1 +refrigeracion2hermanos.com.mx, 1 +refrigeratorrepair-austin.com, 1 +refu.net, 1 +refuelcreative.com.au, 1 +refundo.cz, 1 +refundo.sk, 1 +refurb-tracker.com, 1 +reg.place, 1 +regalador.com, 1 +regalcapitalwi.com, 1 +regalosymuestrasgratis.com, 1 +regalpaintingfdl.com, 1 +regalradio.net, 1 +regaltheatre.com.au, 1 +regamega.ru, 1 +reganclassics.co.uk, 1 +reganclassics.com, 1 +reganparty.com, 1 +regasportshop.it, 1 +regata2015.tk, 1 +regatesenbretagne.bzh, 1 +regazofotografia.com, 1 +regendevices.eu, 1 +regeneo.cz, 1 +regenerapoint.it, 1 +regenerescence.com, 1 +regenpfeifer.net, 1 +regenpod.com, 1 +regensburg-repariert.de, 1 +regentcruises.com, 1 +regentinvest.com, 1 +regg.ae, 1 +reggea.tk, 1 +regiamo.ch, 1 +regie-sc.ch, 1 +regime-anticellulite.com, 1 +regime-maigrir-vite.com, 1 +regimebonheur.com, 1 +reginaclinic.jp, 1 +reginfo.gov, 1 +regio-salland.nl, 1 +regiobeveland.nl, 1 +region-vologda.tk, 1 +region22.tk, 1 +region6armymars.org, 1 +regionaalenergieloket.nl, 1 +regional-rabatt.de, 1 +regionalbasementandcrawlspacerepair.com, 1 +regionalgrowth.com, 1 +regionethost.tk, 1 +regionmedia.cf, 1 +regiosalland.nl, 1 +regiovertrieb.de, 0 +regis.tech, 1 +regisearch.co.uk, 1 +register.to, 0 +registerex.me, 1 +registerforevent.co.uk, 1 +registerforhappywellth.com, 1 +registerra.nl, 1 +registr.io, 1 +registry.google, 1 +regmyr.se, 1 +regnix.net, 1 +regnr.info, 1 +regolithmedia.com, 1 +regon.hu, 1 +regospel.tk, 1 +regraph.de, 1 +regsec.com, 1 +regtech.tk, 1 +regtify.co.uk, 1 +regtify.com, 1 +regtify.com.cy, 1 +regtify.eu, 1 +regtify.org, 1 +regtify.uk, 1 +regularizaeudora.com.br, 1 +regulations.gov, 1 +regulative.gq, 1 +reha-honpo.jp, 1 +rehabili-shigoto.com, 1 +rehabphilippines.com, 1 +rehabreviews.com, 1 +rehabthailand.com, 1 +rehabthailand.org, 1 +rehau-ua.com, 1 +reher.pro, 1 +rehobothma.gov, 1 +rei.ki, 1 +reichardt-home.goip.de, 1 +reichel-steinmetz.de, 1 +reichelt-cloud.de, 1 +reichl-online.net, 1 +reiciunas.lt, 1 +reidasbombas.com, 1 +reidope.com.br, 1 +reidostorrents.com, 1 +reidrice.com, 1 +reiff-schlauchkonfigurator.de, 1 +reifr.net, 1 +reignsphere.net, 1 +reiki-coaching.nl, 0 +reiki-france.fr, 1 +reikimaster.tk, 1 +reikimontreal.org, 1 +reilly.io, 1 +reimaginebelonging.de, 1 +reimaginebelonging.org, 0 +reimann.me, 1 +reimers.de, 1 +rein.kr, 1 +reinaertvandecruys.com, 1 +reinaertvandecruys.me, 1 +reinaldudras.ee, 1 +reinaldudrasfamily.ee, 1 +reinascba.com.ar, 1 +reindersfoodfashion.nl, 1 +reinencaressa.be, 1 +reiner-h.de, 1 +reinfer.io, 1 +reinhardtsgrimma.de, 1 +reinhart-auto.cz, 1 +reinheft.de, 1 +reinierjonker.nl, 1 +reinisch.io, 1 +reinodemurcia.tk, 1 +reinoldus.ddns.net, 1 +reinotools.com, 1 +reinout.nu, 1 +reinouthoornweg.nl, 1 +reintjens.de, 1 +reinventetoi.com, 0 +reinventfit.ro, 0 +reirei.cc, 1 +reiseversicherung-werner-hahn.de, 1 +reiseziel-hiddensee.de, 1 +reishunger.de, 1 +reismil.ch, 1 +reisslittle.com, 1 +reissnehme.com, 1 +reitmeier.me, 1 +reitoracle.com, 1 +reitstall-goettingen.de, 1 +reittherapie-tschoepke.de, 1 +rejahrehim.com, 1 +rejected-by-society.tk, 1 +rejected.tk, 1 +rejects.email, 1 +rejido.tk, 1 +rejushiiplotter.ru, 1 +rekisuta.com, 1 +rekka-j.com, 1 +rekkur.com, 1 +rekkur.consulting, 1 +rekkur.de, 1 +rekkur.dev, 1 +rekkur.io, 1 +rekkur.net, 1 +rekkur.org, 1 +rekkur.solutions, 1 +rekkur.team, 1 +rekkur.tech, 1 +rekkur.technology, 1 +rekkursolutions.com, 1 +rekkurtechnology.com, 1 +reklamaandroid.pp.ua, 1 +reklamaios.pp.ua, 1 +reklamirui.tk, 1 +reklamjog.hu, 1 +reklammaster.ru, 1 +reklamy-led.tk, 1 +rekmedia.tk, 1 +rekurasi.com, 1 +relates.link, 1 +relatethesport.com, 0 +relatic.net, 1 +relations-business.com, 1 +relatory.nl, 1 +relatosypoesias.tk, 1 +relax.hn, 1 +relaxcenternederland.nl, 1 +relaxdom.net, 1 +relaxhavefun.com, 1 +relaxpointhyncice.cz, 1 +relaxti.me, 1 +relaybox.io, 1 +release-monitoring.org, 1 +release.monster, 0 +releasepoint.com, 1 +releases.live, 1 +releasetimes.io, 1 +relentlessroofing.com, 1 +relevanttomyinterests.com, 1 +reley.me, 1 +reliabledegree.com, 1 +reliablemaids.co.uk, 1 +reliableremovals-blackpool.co.uk, 1 +relialink.co.uk, 1 +reliancebank.bank, 1 +reliant3sixty.com, 1 +reliantfundservices.com, 1 +relic.gq, 1 +relieftn.com, 1 +religionandpubliclife.org, 1 +religious-life.com, 1 +religiya.tk, 1 +relijon.com, 1 +relitas.cz, 1 +reloading.ml, 1 +relocatefeds.gov, 1 +relojeriajoyeria.com, 1 +relojes-online.com, 1 +relsak.cz, 1 +relvan.com, 1 +relvan.tech, 1 +relyonnutec.com, 1 +rem0te.net, 1 +remaimodern.org, 1 +remain.london, 1 +remake-projects.tk, 1 +remambo.jp, 1 +remarketable.org, 1 +remateszarate.cl, 1 +remax.at, 1 +remeb.de, 1 +remedi.tokyo, 1 +remediohalkiparaladiabetes.org, 1 +remedionaturales.com, 1 +remedioparaherpes.com, 1 +remedyrow.market, 1 +remejeanne.com, 1 +rememberingjordan.org, 1 +remembermidi.sytes.net, 1 +remembertheend.com, 1 +rememberthemilk.com, 0 +remennik.tk, 1 +remetall.cz, 1 +remhomut.ru, 1 +remi-decker.tk, 1 +remi-saurel.com, 1 +remiafon.com, 1 +remifajardo.cf, 1 +remigius-michael.de, 1 +remilner.co.uk, 1 +reminded.tk, 1 +remini.cz, 1 +reminisceaudio.com, 1 +remirampin.com, 1 +remissan.com, 1 +remitano.com, 1 +remitatm.com, 0 +remiz.org, 1 +remmik.com, 1 +remodelwithlegacy.com, 1 +remodeus.com, 1 +remonline.ru, 1 +remont-45.tk, 1 +remont-kazan.tk, 1 +remont-kvartirvmoskve.ga, 1 +remont-naushnikov.tk, 1 +remont-p.com, 1 +remont-rollet-izgotovlenie.cf, 1 +remont-rukami.tk, 1 +remontdot.tk, 1 +remontfirm.tk, 1 +remonti.info, 1 +remontmebliv.lviv.ua, 1 +remontpc.cf, 1 +remontportal.tk, 1 +remora.tk, 1 +remorques-du-nord.fr, 1 +remorse.ga, 1 +remotedesktop.corp.google.com, 1 +remoteham.com, 1 +remoteoffice.ga, 1 +remoteroom.jp, 1 +remoteshack.ml, 1 +remoteutilities.com, 1 +remoteworkertech.asia, 1 +remotish.com, 1 +remotley.com, 1 +removalcellulite.com, 1 +removallaser.com, 1 +removeandreplace.com, 1 +removedrepo.com, 1 +remptmotors.com, 1 +remrol.ru, 1 +remwhile.com, 1 +remy-daillet-wiedemann.fr, 1 +remy.codes, 1 +rena.am, 1 +rena.cloud, 1 +renaatsioncke.com, 1 +renam.md, 1 +renanoliveira.design, 1 +renatoenoch.com.br, 1 +renatopazmino.com, 0 +renaudmuller.fr, 1 +renaultclubticino.ch, 0 +rendall.tv, 1 +render.com, 1 +renderloop.com, 1 +renderworld.tk, 1 +rendez-vous.gq, 1 +rendre-service.ch, 0 +rene-eizenhoefer.de, 1 +rene-schwarz.com, 1 +rene-stolp.de, 1 +renearends.nl, 1 +renedekoeijer.com, 1 +renehsz.com, 1 +reneleu.ch, 1 +renem.net, 0 +renemayrhofer.com, 0 +reneschmidt.de, 1 +renet.tk, 1 +renewablefreedom.org, 1 +renewablemaine.org, 1 +renewcleaningservices.net, 1 +renewedfreedomcenter.com, 1 +renewgsa.com, 1 +renewmedispa.com, 1 +renewpfc.com, 1 +renezuo.com, 1 +renfis.de, 1 +renicimery.com.br, 1 +renkenlaw.com, 1 +rennes-bachata.com, 1 +rennes-blues.com, 1 +rennes-dancehall.com, 1 +rennes-danse-africaine.com, 1 +rennes-danse-orientale.com, 1 +rennes-danses-en-ligne.com, 1 +rennes-hip-hop.com, 1 +rennes-lindy-hop.com, 1 +rennes-pilates.com, 1 +rennes-reggaeton.com, 1 +rennes-rock-6-temps.com, 1 +rennes-rock.com, 1 +rennes-salsa-portoricaine.com, 1 +rennes-salsa.com, 1 +rennes-tango.com, 1 +rennes-valse.com, 1 +rennes-west-coast-swing.com, 1 +rennes-yoga.com, 1 +rennes-zumba.com, 1 +rennfire.org, 1 +renoproject.org, 1 +renov8sa.co.za, 1 +renovablesverdes.com, 1 +renovandoingresos.com, 1 +renovationsf.ga, 1 +renovum.es, 1 +rens.nu, 1 +rensa-datorn.se, 1 +renscreations.com, 1 +rent-a-c.io, 1 +rent-a-coder.de, 1 +rent-to-own-home.ga, 1 +rentacar.name.tr, 1 +rentacaramerica.com, 1 +rentalboatsafety.com, 1 +rentalmed.com.br, 1 +rentamosandamios.com.mx, 1 +rentandamiosycasetas.com, 1 +rentandgo.it, 1 +rentaplant.hr, 1 +rentasweb.gob.ar, 1 +rentbrowser.com, 1 +renthelper.us, 1 +rentinsingapore.com.sg, 1 +rentmama.cf, 1 +rentnow.my, 1 +rentourhomeinprovence.com, 1 +rentsbg.com, 1 +renuo.ch, 1 +renut.com.np, 1 +renwerks.com, 1 +renxinge.cn, 0 +renyiyou.com, 1 +reo.gov, 0 +reorz.com, 0 +reox.at, 1 +repaik.com, 1 +repairdriveshafts.tk, 1 +repairgeniuses.com, 1 +repairguy.dk, 1 +repairingmobile.tk, 1 +repairit.support, 1 +repairmysolarpanels.com, 1 +repairtly.com, 0 +repalanca.com, 1 +repalcateia.com.br, 1 +repaper.org, 1 +reparacionesdecalefones.com, 1 +reparacionmovilesmurcia.com, 1 +reparatiecrm.nl, 1 +reparation-traceur.com, 1 +reparaturcafe-pfullendorf.de, 1 +reparizy.com, 1 +repat.de, 1 +repauto.com.ua, 1 +repaxan.com, 1 +repgad.com, 1 +repin.in.ua, 1 +replaceits.me, 1 +replacementrate.ga, 1 +replay.ga, 1 +replica.plus, 1 +replicacoin.ga, 1 +replicagold.ml, 1 +replicaswiss.nl, 1 +replici.net, 1 +replikatelefon.tk, 1 +repliksword.com, 1 +repo.ml, 1 +repology.org, 1 +report-incident.de, 1 +report-uri.com, 1 +reportando.com, 1 +reportband.gov, 1 +reportercareer.ga, 1 +reporting.gov, 1 +reportkey.ru, 1 +reportoid.tk, 1 +reposaarenkuva.fi, 1 +reposeed.dev, 1 +reposeed.org, 1 +reproduciblescience.org, 1 +reproductive-revolution.com, 1 +reproductiverevolution.com, 1 +reprogramming-predators.com, 1 +reprogrammingpredators.com, 1 +reprozip.org, 1 +repsltd.co.uk, 1 +repsomelt.com, 1 +reptieleninfo.tk, 1 +reptrax.com, 1 +reptv.online, 1 +republic.gg, 1 +republic.gr, 1 +republicafederal.tk, 1 +republicanleader.gov, 1 +republicanwhip.gov, 1 +republicasantabanana.org, 1 +republicghana.com, 1 +republicmo.gov, 1 +republictelecom.net, 1 +republik-sombora.tk, 1 +republique.org, 1 +repuestosmedellin.com, 1 +repugnant-conclusion.com, 1 +repugnantconclusion.com, 1 +reputatiedesigners.nl, 1 +reputationweaver.com, 1 +requesthymn.com, 1 +requestr.co.uk, 1 +requeue.ga, 1 +reregu.cf, 1 +reroboto.com, 1 +reroboto.eu, 1 +reroboto.net, 1 +reroboto.org, 1 +resama.eu, 1 +resanebartar.tk, 1 +resc.la, 1 +resch.pro, 1 +rescms-secure.com, 1 +rescuer.gq, 1 +research-panel.jp, 1 +research.facebook.com, 0 +research.md, 1 +researchgate.net, 1 +researchstory.com, 1 +reseau-protestant.ch, 0 +reseausyndic.ca, 1 +resellrefreshrepeat.com, 1 +resepimok.com, 0 +resepkuerenyah.com, 1 +resepsimbok.com, 1 +reservadecitasonline.com, 1 +reservetonshift.com, 1 +reservilaisliitto.fi, 1 +reshebnik.ml, 1 +reshka.ga, 1 +resibo.pl, 1 +residence-donatello.be, 1 +residence-simoncelli.com, 1 +residencedesign.net, 1 +residencesatthebluffs.com, 1 +resident-evil.tk, 1 +residentiallocksmithdallas.com, 1 +residentialmortgageholdings.com, 1 +resilience-france.org, 1 +resilientlives.com, 1 +resilienzatropical.it, 1 +resine.roma.it, 1 +resinflooringcompany.com, 1 +resisfestival.com, 1 +resist.ca, 1 +resistav.com, 1 +resize2fs.de, 1 +resju21.ch, 1 +resmigazete.gov.tr, 1 +resnickandnash.com, 1 +resolute.com, 1 +resolutesystems.com, 1 +resolve-portal.it, 1 +resolvefa.co.uk, 1 +resolvefa.com, 1 +resolvergroup.com.au, 1 +resolving.com, 1 +resolvo.com, 1 +resolvs.com, 1 +resoplus.ch, 0 +resort-islands.net, 1 +resortafroditatucepi.com, 1 +resortohshima.com, 1 +resorts.ru, 1 +resoundpro.ca, 1 +resourceconnect.com, 1 +resourceguruapp.com, 1 +resources.flowfinity.com, 1 +resourcesmanagementcorp.com, 1 +respectmyprivacy.eu, 1 +respectmyprivacy.net, 1 +respectmyprivacy.nl, 1 +respecttheflame.com, 1 +respinar.com, 1 +respiradores.tk, 1 +respiranto.de, 1 +respire-yoga.fr, 1 +respon.jp, 1 +responer.com, 1 +respons.je, 1 +respons.me, 1 +respons.mobi, 1 +respons.us, 1 +respons.ws, 1 +responscode.eu, 1 +responscode.info, 1 +responscode.mobi, 1 +responscode.nl, 1 +responsecode.info, 1 +responsecode.mobi, 1 +responsecode.nl, 1 +responsepartner.com, 1 +responsibledisclosure.nl, 0 +responsivepaper.com, 1 +respostas.com.br, 1 +resqdesk.com, 1 +ressl.ch, 1 +resslovaci.net, 1 +ressupply.com, 1 +rest-in-moscow.tk, 1 +restartperm.ml, 1 +restauracjabazylia.pl, 1 +restaurant-de-notenkraker.be, 1 +restaurant-eatenjoy.be, 1 +restaurant-fujiyama.fr, 1 +restaurant-oregano.de, 1 +restaurant-rosengarten.at, 1 +restaurantbetriebe.schwarz, 1 +restaurantdetgulepakhus.tk, 1 +restaurantedonono.com.br, 1 +restaurantesimonetti.com.br, 1 +restauranthugo.nl, 1 +restauranttester.at, 1 +restauratorin-maubach-dresden.de, 1 +restauriedili.roma.it, 1 +rester-a-domicile.ch, 1 +rester-autonome-chez-soi.ch, 1 +restic.net, 1 +restioson.me, 1 +resto-renaissance.be, 1 +restoran-radovce.me, 1 +restoran.cf, 1 +restorationphotos.tk, 1 +restorethegulf.gov, 1 +restoringhopeberks.org, 1 +restoruns.com, 1 +restrealitaet.de, 1 +restrito.org, 1 +resultsatretail.com, 1 +resultscommercial.com, 1 +resultsdate.news, 1 +resulttado.com, 1 +resume4dummies.com, 1 +resumeget.com, 1 +resumelab.com, 1 +resumelibros.tk, 1 +resumeprofessionalwriters.com, 1 +resumeshoppe.com, 1 +resumeworded.com, 1 +resumic.com, 1 +resumic.dev, 1 +resumic.io, 1 +resumic.net, 1 +resumic.org, 1 +resursedigitale.ro, 1 +resurspartner.tk, 1 +resveratrolsupplement.co.uk, 1 +retailcybersolutions.com, 1 +retailing.cf, 1 +retardedstudios.tk, 1 +retcor.net, 1 +retefarmaciecostadamalfi.it, 1 +retefrati.it, 0 +reteteaz.net, 1 +retetenoi.net, 1 +retetop95.it, 1 +reth.ch, 1 +rethymnorooms.tk, 1 +reticket.me, 1 +reticle.cf, 1 +reticon.de, 1 +retics.cf, 1 +retidurc.fr, 1 +retinacv.es, 1 +retireearlyandtravel.com, 1 +retirest.com, 1 +retireyourpassword.org, 1 +retmig.dk, 1 +reto.ch, 0 +reto.io, 1 +reto.tv, 1 +retofunctional.com, 0 +retogroup.com, 1 +retohaeberli.com, 1 +retokromer.ch, 0 +retornaz.com, 1 +retornaz.eu, 1 +retornaz.fr, 1 +retractableawningssydney.com.au, 1 +retraitebysaulsplace.nl, 1 +retro-game.org, 1 +retro.camp, 1 +retro.rocks, 1 +retro.sx, 0 +retroarms.com, 1 +retroarms.cz, 1 +retrocdn.net, 1 +retrofitlab.com, 0 +retroity.net, 1 +retrojar.top, 1 +retrojugo.tk, 1 +retrokuchynka.sk, 1 +retronet.nl, 1 +retropack.org, 1 +retroride.cz, 1 +retroroundup.com, 1 +retroskoter.tk, 1 +retroslave.ga, 1 +retrotown.ws, 1 +retrotracks.net, 0 +retrotubesporn.com, 1 +retrovideospiele.com, 1 +rets.org.br, 0 +rettig.xyz, 0 +retube.ga, 1 +return-profit.tk, 1 +retzer.me, 1 +reucon.com, 1 +reueljohnk.com, 1 +reulitz.de, 0 +reuna.me, 1 +reunion.tk, 1 +reupo.com, 1 +reussirsavie.info, 1 +reut42.de, 1 +reuter-profishop.de, 0 +reuter.de, 0 +revaio.com, 1 +revaloriza.cf, 1 +revapost.fr, 1 +revayd.net, 1 +revconnect.tk, 1 +revcord.com, 1 +reveal-sound.com, 1 +revealdata.com, 1 +revellio.tk, 1 +revenge-spells.com, 1 +reverenceglobal.com, 1 +reverencestudios.com, 1 +reverseaustralia.com, 1 +reversecanada.com, 1 +reversedns.tk, 1 +reverseloansolutions.com, 1 +reverselookupphone.us, 1 +reversesouthafrica.com, 1 +reviderm-skinmedics-rheinbach.de, 1 +review.jp, 1 +reviewbestseller.com, 1 +reviewcenter.in, 1 +reviewdetector.ml, 1 +reviewgeek.com, 1 +reviewinteriors.com.au, 1 +reviewninja.net, 1 +reviewpipe.com, 1 +reviews.anime.my, 0 +reviewsonline.ml, 1 +reviewsweb.tk, 1 +reviewu.ca, 1 +revinc.com, 1 +revis-online.ml, 1 +revisionnotes.xyz, 1 +revisionvillage.com, 1 +revisores.pt, 1 +revisoronline.ml, 1 +revisoronline.tk, 1 +revista-programar.info, 1 +revistabifrontal.com, 1 +revistadiscover.com, 1 +revistasomos.com, 1 +revitalisierungs-akademie.de, 1 +reviuu.com, 1 +revivalinhisword.com, 1 +revivalprayerfellowship.com, 1 +revivemoment.com, 1 +reviveplumbingmelbourne.com.au, 1 +reviviendolavilla.tk, 1 +revivingtheredeemed.org, 1 +revizor-online.cf, 1 +revizor-online.ga, 1 +revizor-online.gq, 1 +revizor-online.ml, 1 +revizor-online.tk, 1 +revizor.ml, 1 +revizoronline.tk, 1 +revlect.com, 1 +revoluciondelacuchara-fusa.tk, 1 +revoluruguay.com, 1 +revolution.net.nz, 1 +revolutionaryaim-vienna.tk, 1 +revolutionaryireland.cf, 1 +revolutionenkommer.dk, 1 +revolutionhive.com, 1 +revolutionofgaming.tk, 1 +revolve.com, 1 +revolware.com, 1 +revthefox.co.uk, 1 +revuestarlight.me, 1 +revworld.org, 1 +rewardingexcellence.com, 1 +rewardscout.eu, 1 +rewiredweightloss.com, 1 +rewrite3.com, 1 +rex.st, 1 +rex.tc, 1 +rexbaumgartnerdds.com, 1 +rexcutty.com, 1 +rexdf.net, 1 +rexeroofing.com, 1 +rexfinland.fi, 1 +rexled.fi, 1 +rexskz.info, 1 +rexxworld.com, 1 +reyborg.com, 1 +reykjavik.guide, 1 +reyna.cc, 1 +reynders.xyz, 1 +rez.ee, 1 +rezendemultimarcas.com.br, 1 +rezept-planer.de, 1 +rezio.io, 0 +rezistor.tk, 1 +rezka-burenie.cf, 1 +rezni.cz, 1 +rezultant.ru, 1 +rezun.cloud, 1 +rf-gamer.gq, 1 +rf-meters.com, 1 +rf.studio, 1 +rfbcnet.tk, 1 +rfdirectory.tk, 1 +rfeif.org, 1 +rfnews.tk, 1 +rfomega.ga, 1 +rfp-rechtsanwaelte.de, 1 +rfs-zbpe.net, 1 +rftoon.com, 1 +rfxanalyst.com, 1 +rgb2hex.online, 1 +rgbinnovation.com, 1 +rgbpty.com, 1 +rgcomportement.fr, 0 +rgdt.tk, 1 +rggraphics.mx, 1 +rghost.net, 1 +rgiohio.com, 1 +rgl.support, 1 +rgpdkit.io, 1 +rgraph.net, 1 +rgtn.com, 1 +rgz.ee, 1 +rhaegal.me, 1 +rhamzeh.com, 1 +rhaniegghe.be, 1 +rhaniegghesoftwaresecurity.be, 1 +rhd-instruments.com, 1 +rhd-instruments.de, 1 +rhees.nl, 1 +rheijmans.com, 1 +rheijmans.email, 1 +rheijmans.io, 1 +rheijmans.nl, 1 +rhein-liebe.de, 1 +rheinneckarmetal.com, 1 +rheinturm.nrw, 1 +rhese.net, 1 +rhetorical.ml, 0 +rhetthenckel.com, 1 +rheuma-online.de, 1 +rhevelo.com, 0 +rhforum.tk, 1 +rhhfoamsystems.com, 1 +rhinelander.ca, 1 +rhino.co.tz, 1 +rhinobase.net, 0 +rhinoceroses.org, 1 +rhiskiapril.com, 0 +rhkg.dk, 1 +rhnet.at, 1 +rhodenmanorcattery.co.uk, 1 +rhodesianridgeback.com.br, 1 +rhodos.fr, 1 +rhodri.io, 1 +rhowell.io, 1 +rhubarb.land, 1 +rhumblineadvisers.com, 1 +rhye.tk, 1 +rhyme.com, 1 +rhymesofreason.com, 1 +rhymeswithmogul.com, 1 +rhynl.io, 1 +rhyno.io, 1 +rhysperry.com, 1 +rhysre.net, 1 +riajenaka.com, 1 +riaki.net, 1 +rial.space, 1 +rian.gq, 1 +riared.net, 1 +riaucybersolution.net, 0 +rib-leipzig.com, 1 +riba-lov.ga, 1 +ribafs.tk, 1 +ribdigital.com, 1 +ribeirostore.com.br, 0 +ribella.net, 1 +ribes.design, 0 +ribolov.tk, 1 +ribtours.co, 1 +ricardo.nu, 1 +ricardobalk.nl, 1 +ricardojsanchez.com.ar, 1 +ricardopq.com, 1 +ricardoquaresma.tk, 1 +ricardotaakehb.tk, 1 +ricaribeiro.com.br, 1 +ricaud.me, 1 +riccardopiccioni.it, 1 +ricci-ingenieria.com, 1 +riccy.org, 1 +riceadvice.info, 1 +ricettesemplicieveloci.altervista.org, 1 +ricewarner.com, 1 +richadams.me, 1 +richandsteph.co.uk, 1 +richandsteph.uk, 1 +richardb.me, 0 +richardbloomfield.blog, 1 +richardbulley.com.au, 1 +richardcrosby.co.uk, 1 +richardharpur.com, 1 +richardhouts.tk, 1 +richardinesrolltop.com, 1 +richardjgreen.net, 1 +richardlangham.plumbing, 1 +richardlangworth.com, 1 +richardlevinmd.com, 1 +richardrblocker.net, 1 +richardschut.nl, 1 +richardsdebt.com, 1 +richardson.cam, 1 +richardson.engineering, 1 +richardson.pictures, 1 +richardson.software, 1 +richardson.systems, 1 +richardson.tw, 1 +richardstonerealestate.com, 1 +richardvd.nl, 1 +richardwarrender.com, 1 +richbutler.co.uk, 1 +richcat.tw, 1 +richecommecresus.com, 1 +richelelahaise.nl, 1 +richeyweb.com, 1 +richeza.com, 1 +richfieldsean.org, 1 +richie.cloud, 1 +richie.fi, 1 +richie.network, 1 +richie.pm, 1 +richieheijmans.com, 1 +richieheijmans.email, 1 +richieheijmans.eu, 1 +richieheijmans.io, 1 +richieheijmans.network, 1 +richieheijmans.one, 1 +richkidmarketing.com, 1 +richlandcountyoh.gov, 1 +richlj.com, 1 +richlj.net, 1 +richmondcountyclerk.com, 1 +richmondradiologists.com, 1 +richmondsunlight.com, 1 +richmoney.us, 1 +richmtdriver.com, 1 +richviajero.com, 1 +richwayfun.com, 1 +ricketyspace.net, 1 +ricki-z.com, 1 +rickmakes.com, 1 +rickmartensen.nl, 0 +rickrongen.nl, 1 +rickscastles.co.uk, 1 +ricksdailytips.com, 1 +ricksfamilycarpetcleaning.com, 1 +rickvanderzwet.nl, 1 +rickweijers.nl, 1 +rickyromero.com, 1 +rico-brase.de, 0 +rico-j.de, 1 +rico.ovh, 1 +ricobaldegger.ch, 1 +ricochet.com, 1 +ricochet.im, 1 +ricor.cl, 0 +ricordisiciliani.it, 1 +ricoydesign.com, 1 +ricozienke.de, 1 +ricreare.com, 1 +ridayu.jp, 1 +riddickthemovie.tk, 1 +riddimsworld.com, 1 +riddler.com.ar, 1 +rideapart.com, 1 +ridegravel.ch, 1 +rideintaxi.com, 1 +rident-estetic.ro, 1 +ridepanda.com, 1 +riderchris.com, 1 +riders.ga, 1 +rides-japan.jp, 1 +ridetour.ru, 1 +ridgelandchurch.org, 1 +ridingoklahoma.com, 1 +rido.ml, 1 +ridvan-vllasaliu.tk, 1 +riechsteiner.tech, 1 +riederle.com, 1 +riem.in, 1 +riemzac.com, 1 +riesenmagnete.de, 1 +riesenweber.id.au, 1 +riesheating.com, 1 +riesurya.com, 0 +riffelhaus.ch, 1 +riffreporter.de, 0 +rift.pictures, 1 +rifugioselvabella.tk, 1 +rigabeerbike.com, 1 +rigabeerbike.lv, 1 +rigart-michael.be, 1 +rigartmichael.be, 1 +rigasudens.lv, 1 +rigelsport.com, 1 +riggosrag.com, 1 +righettod.eu, 1 +righini.ch, 0 +right-to-love.name, 1 +rightblog.tk, 1 +rightbrain.training, 1 +rightducks.com, 1 +rightfold.io, 1 +rightlaw.nz, 1 +rightmovecanada.com, 1 +rightnetworks.com, 1 +rightrasta.com, 1 +rightreview.co.uk, 1 +rights.ninja, 1 +rightsem.com, 1 +rightsolutionplumbing.com.au, 1 +rightstuff.link, 0 +righttobuy.gov.uk, 1 +rigintegrity.com, 1 +rigous.net, 1 +rigsalesaustralia.com, 1 +rihal-humain.com, 1 +riight.online, 1 +riimihaku.fi, 1 +rijk-catering.nl, 0 +rijnland.net, 1 +rijschoolgevonden.nl, 0 +rijschoolrichardschut.nl, 1 +rijschoolsafetyfirst.nl, 1 +rijsinkunst.nl, 1 +rik.onl, 1 +rikaidoshop.com, 1 +rikaz.tech, 1 +riklewis.com, 1 +riku.pro, 1 +riku.pw, 1 +rikunori.com.tw, 1 +rikuras.cl, 1 +rile5.com, 1 +riley.love, 1 +rileyevans.co.uk, 1 +rileyskains.com, 1 +rileystar.com, 1 +rilish.cf, 1 +rilretg.com, 1 +rimax.vn, 1 +rimcountrymuseum.org, 1 +rime.com.hr, 1 +rimeto.io, 1 +rimikis.de, 1 +rimkereso.hu, 1 +rimo.site, 1 +rimonhwang.com, 1 +rimorrecherche.nl, 1 +rincon-nsn.gov, 1 +rincondenoticas.com, 1 +rindlerwahn.de, 1 +ring.com, 0 +ringgitplus.com, 1 +ringingliberty.com, 1 +ringjewellery.co.uk, 1 +ringlightstudios.com, 1 +ringneckparakeets.com, 1 +ringofglory.gq, 1 +ringsandthings.scot, 1 +ringtune.ir, 1 +rinkhill.com, 1 +rinkpieters.nl, 1 +rinsepimp.com, 1 +rinton.ru, 1 +rinvex.com, 1 +rio-weimar.de, 1 +rioinbox.com.br, 1 +riomaisbrindes.com.br, 1 +riosoil.co.uk, 1 +riosoil.com, 1 +riosoils.co.uk, 1 +riosoils.com, 1 +riostones.com, 1 +rioxmarketing.com, 1 +rioxmarketing.pt, 1 +rioxmarketing.us, 1 +rip-sport.cz, 1 +ripa.io, 1 +ripadores.tk, 1 +ripaton.fr, 1 +ripcityproject.com, 1 +ripcorddesign.com, 1 +ripcordsandbox.com, 1 +ripley.red, 1 +ripmixmake.org, 1 +ripp-it.com, 1 +ripper.store, 1 +ripple.com, 1 +ripplemarkeg.com, 1 +ripplenews.club, 1 +ripplenews.co, 1 +ripplenews.io, 1 +ripplenews.live, 1 +ripplenews.media, 1 +ripplenews.news, 1 +ripplenews.online, 1 +ripplenews.world, 1 +riproduzionichiavi.it, 1 +riptidetech.io, 1 +ripuree.com, 1 +ris-bad-wurzach.de, 1 +ris.fi, 1 +risada.nl, 1 +risalatconsultants.com, 1 +risaphuketproperty.com, 0 +riscascape.net, 1 +risco.ro, 1 +riscoshardware.tk, 1 +rise-technologies.com, 1 +rise.com, 1 +rise.global, 1 +riseandrank.com, 1 +risecomedy.com, 1 +risecstate.gov, 1 +riselab.com.ua, 1 +riseofthewildwoman.com, 1 +riseshost.ml, 1 +riseup.net, 1 +rishabh.me, 1 +risheriffs.gov, 1 +rishikeshyoga.in, 1 +risi-china.com, 1 +risiinfo.com, 1 +risoscotti.es, 1 +risounokareshi.com, 1 +risparmiare.info, 1 +ristioja.ee, 1 +ristisanat.fi, 1 +ristoarea.it, 1 +ristorantelittleitaly.com, 1 +ristoviitanen.fi, 1 +ristrutturazioneappartamenti.milano.it, 1 +ristrutturazioneappartamento.roma.it, 1 +ristrutturazioniappartamentinapoli.it, 1 +risunki.ga, 1 +risxx.com, 0 +rit.space, 1 +ritaohio.gov, 1 +riteboost.com, 1 +ritel.nl, 1 +ritense.nl, 1 +riteway.rocks, 1 +ritirocalcinacci.viterbo.it, 1 +ritoge.com, 1 +ritoner.it, 1 +ritsu-life.com, 1 +rittau.biz, 1 +rittau.org, 1 +ritual.ml, 1 +ritus.md, 1 +ritzlux.com.tw, 1 +riunioni.online, 1 +rivaforum.de, 1 +rivals.space, 1 +rivalsa.cn, 1 +rivalsa.net, 1 +rivastation.de, 1 +riveraurology.com, 1 +riverbanktearooms.co.uk, 1 +riverbednetflowsupport.com, 1 +riverbendroofingnd.com, 1 +rivercitybni.com, 1 +riverdale.net.au, 1 +riverford.co.uk, 1 +rivermist.com.au, 1 +riveroaksdentaljax.com, 1 +riverotravel.cl, 1 +riverridgecc.com, 1 +rivers.gov, 1 +riverschool.net, 1 +riversideiowa.gov, 1 +riversideradio.nl, 1 +riversmeet.co.uk, 1 +riverstyxgame.com, 1 +riverviewmotel.ca, 1 +riverviewurologic.com, 1 +riverweb.gr, 1 +rivierasaints.ch, 0 +riviere.pro, 1 +rivingtongreenwich.co.uk, 1 +rivoflor.it, 1 +rivoligroup.com, 1 +rivolta.tk, 1 +rivoniaplumber24-7.co.za, 1 +rivus.net, 1 +riweco.ga, 1 +riwick.com, 0 +rix.ninja, 1 +rixcloud.moe, 1 +rixzz.ovh, 1 +riyadbankacademy.com, 1 +riyono.com, 1 +rizalpalawan.gov.ph, 1 +rizikaockovani.cz, 1 +rizonrice.club, 1 +rizospastis.gr, 1 +rj-onderneemt.nl, 1 +rjan.nl, 1 +rje-hub.net, 1 +rjfedor.ddns.net, 1 +rjicpas.com, 1 +rk-box.ru, 1 +rk-links.ml, 1 +rk-mediawork.de, 1 +rk.mk, 1 +rk12.de, 1 +rkabworks.uk, 1 +rkbegraafplaats.com, 1 +rkesport.com, 0 +rkfp.cz, 1 +rkmantpur.org, 0 +rkmedia.no, 1 +rkmns.edu.in, 1 +rknews.tk, 1 +rko.guru, 1 +rlaftershock.com, 1 +rlahaise.nl, 1 +rlalique.com, 1 +rld.org, 1 +rlds.ch, 0 +rleeden.servehttp.com, 1 +rleh.de, 1 +rlove.org, 1 +rm-it.de, 1 +rmb.li, 1 +rmcbs.de, 1 +rmdb.tk, 1 +rmdhnreza.my.id, 0 +rmdscreen.com, 1 +rme.li, 0 +rmeuropean.com, 1 +rmf.io, 1 +rmi.com.ar, 1 +rmit.me, 1 +rmm-i.com, 1 +rmmanfredi.com, 1 +rmol.tk, 1 +rmp-gebaeudedienste.de, 1 +rmrig.org, 1 +rms.sexy, 1 +rmshg.com, 1 +rmsk.tk, 1 +rmstudio.tw, 1 +rmsupply.nl, 1 +rmtconstruction.co.za, 1 +rmvalues.com, 1 +rmyachting.com, 1 +rn29.me, 1 +rnag.ie, 1 +rnb-storenbau.ch, 1 +rnbjunk.com, 1 +rncc.mx, 1 +rndtool.info, 1 +rnews.tk, 1 +rngmeme.com, 1 +rnoax.com, 1 +ro.co, 1 +ro.exchange, 1 +ro.search.yahoo.com, 0 +ro89.com, 1 +roach.nz, 1 +roachesofficial.com, 1 +road-safety.cz, 1 +roadandtransport.ga, 1 +roaddoc.de, 1 +roadguard.nl, 0 +roadtochina.tk, 1 +roadtopgm.com, 1 +roadtripusa.tk, 1 +roalogic.com, 1 +roamfreun.tk, 1 +roams.es, 1 +roams.mx, 1 +roar.com.br, 1 +roaster.ga, 1 +rob006.net, 1 +robandjanine.com, 1 +robaxin750mg.ml, 1 +robben.io, 1 +robbertt.com, 0 +robbiebird.tk, 1 +robbiecrash.me, 1 +robbielowe.co, 1 +robbievasquez.com, 1 +robbinsgaragedoorwenatchee.com, 1 +robbrestyle.com, 1 +robbysmets.be, 1 +robdavidson.network, 1 +robersonaudio.tk, 1 +robert-ewert.tk, 1 +robert-flynn.de, 1 +robert-reisemobil.de, 1 +robert-wiek-transporte.de, 1 +robertattfield.com, 1 +robertayamashita.com, 1 +robertayamashita.com.br, 1 +robertbln.com, 1 +robertg.me, 1 +robertglastra.com, 1 +robertgonzalez.tk, 1 +roberthurlbut.com, 1 +robertjquinn.com, 1 +robertkotlermd.com, 1 +robertkrueger.de, 1 +robertlysik.com, 1 +robertmusil.ml, 1 +robertobilic.com, 1 +robertocasares.no-ip.biz, 0 +robertoentringer.com, 0 +robertof.ovh, 1 +robertopazeller.ch, 1 +robertoullan.tk, 1 +robertreiser.photography, 1 +robertrijnders.nl, 1 +robertsjoneslaw.com, 1 +robertsmits.be, 1 +robeschinoises.fr, 1 +robgorman.ie, 1 +robhorstmanshof.nl, 1 +robi-aesch.ch, 1 +robi-net.it, 1 +robicue.com, 0 +robigalia.org, 0 +robijomasszazs.com, 1 +robimgood.com.ua, 1 +robin-kusch.de, 1 +robin-novotny.com, 1 +robin.co.kr, 1 +robin.info, 1 +robindeheer.nl, 1 +robinevandenbos.nl, 1 +robinflikkema.nl, 1 +robinfrancq.ml, 1 +robinlinden.eu, 1 +robinloeffel.ch, 1 +robinminto.com, 1 +robinsonphotos.uk, 1 +robinsonstrategy.com, 1 +robinsonyu.com, 1 +robinvdmarkt.nl, 1 +robinwill.de, 1 +robinwinslow.uk, 1 +robison.pro, 1 +robisonweb.net, 1 +robjager-fotografie.nl, 1 +roblog.tk, 1 +robnicholls.co.uk, 1 +robocop.no, 1 +robodeidentidad.gov, 1 +roboform.com, 1 +robohash.org, 1 +robokits.co.in, 1 +robomonkey.org, 1 +robot-invest.ml, 1 +robot.car, 1 +robotattack.org, 1 +robotbattle.tk, 1 +roboth.am, 1 +robotham.org, 1 +robotimeshop.com, 1 +robotkvarnen.se, 1 +robots-ju.ch, 1 +robotsbigdata.com, 1 +robotstxt.com, 1 +robottip.com, 1 +robpol86.com, 1 +robspc.repair, 1 +robspeed.rocks, 1 +robsutter.com, 0 +robtatemusic.com, 1 +robtex.com, 1 +robu.in, 1 +robust.ga, 1 +robustac.com, 1 +robustevents.in, 1 +robuxemporium.com, 1 +robuxkingz.ml, 1 +rocabot.ddns.net, 1 +rochakhand-knitcraft.com.np, 1 +rochcloud.cf, 1 +rochesterglobal.com, 1 +rochman.id, 0 +rocis.gov, 1 +rock-base.tk, 1 +rocka.me, 1 +rockagogo.com, 1 +rockbankland.com.au, 1 +rockcanyonbank.com, 0 +rockcellar.ch, 1 +rockefellergroup.info, 1 +rockenfuerlachenhelfen.de, 1 +rockernj.com, 1 +rocket-resume.com, 1 +rocketdashboard.com, 1 +rocketeer.tk, 1 +rocketevents.com.au, 1 +rocketgnomes.com, 1 +rocketmill.co.uk, 1 +rocketnet.ml, 1 +rocketr.net, 1 +rocketsandtutus.com, 1 +rocketsworld.tk, 1 +rockfax.com, 1 +rockfordtow.com, 1 +rockfs.ml, 1 +rockhounds.co.za, 1 +rockinronniescastles.co.uk, 1 +rockitinflatables.co.uk, 1 +rocklabs.xyz, 1 +rocklinhousecleaning.com, 1 +rocknwater.com, 1 +rockpesado.com.br, 1 +rockset.com, 1 +rockshooters.com, 1 +rockslideengineering.com, 1 +rockstargame.su, 1 +rockthebabybump.com, 1 +rockworldteam.tk, 1 +rockymountaininsurancecenter.com, 1 +rockymountainspice.com, 1 +rockypest.com.au, 1 +rocmartialartsacademy.com, 1 +rocsole.com, 1 +rocssti.net, 1 +rodab.party, 1 +rodafe.sk, 1 +rodarion.pl, 1 +rodchapman.com, 0 +roddis.net, 1 +rodehutskors.net, 1 +rodelstein.eu, 1 +rodeobull.biz, 1 +rodeodrive.tk, 1 +rodeohire.com, 1 +rodeoimport.com, 1 +rodeosales.co.uk, 1 +rodest.net, 0 +rodevlaggen.nl, 1 +rodichi.net, 1 +rodinka.tk, 1 +rodinnebyvanie.eu, 1 +rodinneodpoledne2018.cz, 1 +roditely.cf, 1 +rodnik-pansionat.ru, 1 +rodobike.com.br, 1 +rodoelectrodomesticos.com, 1 +rodolfo.gs, 1 +rodolphe-lebrun.fr, 1 +rodomonte.org, 1 +rodrigoacevedo.com.uy, 1 +rodrigoarriaran.com, 1 +rodrigocarvalho.blog.br, 1 +rodrigodematos.tk, 1 +rody-design.com, 1 +rodykossen.com, 1 +roeckx.be, 1 +roed.gg, 1 +roeden.dk, 1 +roeitijd.nl, 0 +roelenscitynews.ml, 1 +roelhollander.eu, 1 +roeljoyas.com, 1 +roellcapital.com, 1 +roelmagdaleno.com, 1 +roelof.io, 1 +roelonline.tk, 1 +roelsworld.eu, 1 +roemhild.de, 1 +roenhorst.net, 1 +roerstaafjes.nl, 1 +roessner-network-solutions.com, 1 +roethelheim.net, 1 +roethelheim.org, 1 +rofl.com.ua, 1 +rofrank.space, 1 +rogagym.com, 1 +rogaineforwomen.ga, 1 +rogard.fr, 0 +rogarden.ro, 1 +roge.pw, 1 +rogeiro.net, 1 +rogell.tk, 1 +rogerdat.ovh, 1 +rogerdeflor.tk, 1 +rogerhub.com, 1 +rogeriosantos.pt, 1 +rogerkunz.ch, 1 +rogerriendeau.ca, 1 +rogersaam.ch, 0 +rogersnowing.cn, 1 +rogersvilleumc.org, 1 +rogiershikes.tk, 1 +rognhaugen.no, 1 +rogo.cz, 1 +rogoff.xyz, 1 +rogue-e.xyz, 1 +rogue.pw, 1 +roguecoder.net, 1 +roguefortgame.com, 1 +roguenation.space, 1 +roguenetworks.me, 1 +roguerocket.com, 1 +roguesignal.net, 1 +roguetechhub.org, 1 +roh.one, 1 +rohanbassett.com, 1 +rohansingh.cf, 1 +rohde.de, 1 +rohedaten.de, 1 +rohitagr.com, 1 +rohitpatil.com, 1 +rohlik.cz, 1 +rohrreinigung-zentrale.de, 1 +roi-project.be, 1 +roi-project.eu, 1 +roiblozyxfswe.ga, 1 +roidsstore.com, 1 +rointe.online, 1 +roishopper.com, 1 +roisu.org, 0 +rojiblancos.tk, 1 +roka9.de, 1 +rokass.nl, 1 +rokcupusa.com, 1 +rokki.ch, 1 +roko-foto.de, 1 +rokort.dk, 1 +rokudenashi.de, 1 +roland.io, 1 +rolandlips.com, 1 +rolandlips.nl, 1 +rolandoredi.com, 1 +rolandozarate.tk, 1 +rolandreed.cn, 1 +rolandszabo.com, 1 +rolandvanipenburg.com, 1 +roldeco.nl, 1 +rolecontj.com, 1 +roleplaybdsm.com, 1 +roleplayhome.com, 1 +rolibo.com, 1 +roligh.cf, 1 +roligt.tk, 1 +roliki.ml, 1 +roll-bakery.com.tw, 1 +roll.hockey, 1 +rollatorweb.nl, 1 +rollbackdiabetes.com, 1 +rollenspiel.monster, 1 +rolleyes.org, 1 +rollforadventure.com.au, 1 +rollingbarge.com, 1 +rollingcouchapp.com, 1 +rollingshuttle.org, 1 +rollingstocks.tk, 1 +rollinspass.org, 1 +rolluplab.it, 1 +rolodato.com, 0 +rolotrans.cf, 1 +rolstoelappartementen.tk, 1 +rolzzandik.cf, 1 +roma-servizi.it, 1 +romab.com, 1 +romacoffee.co.nz, 1 +romain-arias.fr, 1 +romaindepeigne.fr, 1 +romainlapoux.com, 1 +romainlapoux.fr, 1 +roman-pavlik.cz, 1 +roman.systems, 1 +romanchuvashov.ru, 0 +romancloud.com, 1 +romancoinsforsale.org, 0 +romania-film.ml, 1 +romanian.cam, 1 +romanmichel.de, 1 +romano.guru, 1 +romanos.tk, 1 +romanpavlodar.kz, 1 +romantelychko.com, 1 +romantica-hotel.de, 1 +romanticschemer.com, 1 +romanticschemermovie.com, 1 +romanticsexshopguatemala.com, 1 +romanticvillas.com.au, 0 +romantik-fm.ml, 1 +romantik-fm.tk, 1 +romantik.cf, 1 +romantik.tk, 1 +romapk.tk, 1 +romarin.es, 1 +romaservicegroup.it, 1 +romastantra.com, 1 +romatours.pt, 0 +romatrip.it, 1 +romediatori.com, 1 +romeoijulio.tk, 1 +rometoptentravel.com, 1 +rommelhuntermusic.tk, 1 +rommelmark.nl, 1 +rommelwood.de, 1 +romo-holidays.de, 1 +romo-holidays.dk, 1 +romsey.org, 1 +romtter.com, 1 +romun.net, 1 +romy.tw, 1 +ron2k.za.net, 1 +ronaldguevara.com, 1 +ronaldleite.tk, 1 +ronan-hello.fr, 1 +ronan.cf, 1 +ronbongamis.com, 1 +ronbyrne.com, 1 +roncoutilities.com, 1 +rondommen.nl, 1 +rondouin.fr, 1 +rondreis-amerika.be, 1 +rondreis-schotland.nl, 1 +ronem.com.au, 1 +ronghexx.com, 1 +rongreenbaum.com, 1 +ronhose.com, 1 +roninf.ch, 1 +roninitconsulting.com, 1 +ronjagers.nl, 1 +ronniegane.kiwi, 1 +ronnylindner.de, 1 +ronomon.com, 1 +ronsguideservice.com, 1 +ronvil.com, 1 +ronzertnert.xyz, 1 +roodfruit.com, 1 +roodfruit.nl, 1 +roodfruit.studio, 1 +roodhealth.co.uk, 1 +roodjongindesp.nl, 1 +roof.ai, 0 +roofconsultants-inc.com, 1 +roofdoctorutah.com, 1 +roofer.cf, 1 +rooferindallas.com, 1 +roofingandconstructionllc.com, 1 +roofingomaha.com, 1 +roofingpioneers.com, 1 +roofpost.gq, 1 +roofsandbasements.com, 1 +rook-playz.net, 1 +rookiehpc.com, 1 +roolife.xyz, 1 +roolnews.id, 1 +room-checkin24.de, 1 +room-composite.com, 1 +room.to, 0 +room208.org, 1 +room362.com, 1 +room3b.eu, 1 +room45.tk, 1 +roombase.nl, 1 +roomcube.tk, 1 +roomee.tk, 1 +roomhub.jp, 1 +roomlab.cl, 1 +roomonline.tk, 1 +roomsatevents.eu, 1 +roopakv.com, 1 +roopakvenkatakrishnan.com, 1 +roosabels.nl, 0 +roosta.xyz, 1 +roosterpets.com, 1 +root-books.gq, 1 +root-books.ml, 1 +root-couture.de, 1 +root-space.eu, 1 +root.bg, 1 +root.cz, 1 +root.eu.org, 1 +root.place, 1 +rootbsd.at, 1 +rootcamp.net, 1 +rootcommand.com, 1 +rootear.com, 1 +rootedlifemontessori.com, 1 +rootetsy.com, 1 +rootfor.me, 1 +rootie.de, 1 +rootkit.es, 1 +rootlair.com, 1 +rootly.io, 1 +rootonline.de, 1 +rootpigeon.com, 1 +rootrelativity.com, 1 +roots-example-project.com, 1 +roots.io, 1 +rootsandrain.com, 1 +rootsbar.fr, 0 +rootscope.co.uk, 0 +rootsh3ll.com, 1 +rootsmusicmanagement.tk, 1 +rootsskininstitute.com, 1 +rootstation.de, 1 +rootswitch.com, 1 +roottsquare.com, 1 +rootusers.com, 1 +rootze.com, 1 +roozaneh.net, 1 +rop.cx, 1 +ropd.info, 1 +roppit.nl, 1 +roques.tk, 1 +rorelseprojektet.se, 1 +roromendut.online, 1 +rorr.im, 1 +rory.best, 1 +roryneville.com, 1 +rosa-spain.tk, 1 +rosabellas.co.uk, 1 +rosabrasiv.ga, 1 +rosahijab.com, 1 +rosakkreditatsiya-forum.ru, 1 +rosalindturner.co.uk, 1 +rosalopezcortes.tk, 1 +rosamystica.tk, 1 +rosanaestevezabogadovigo.es, 1 +rosanerolife.tk, 1 +rosaquest.ru, 1 +rosaserra.es, 1 +rosbass.ru, 1 +rosbiznes.tk, 1 +rosdpk.ru, 1 +rosdver.ru, 1 +rose-prism.org, 1 +roseberyvenues.co.uk, 1 +roseboom-bouwkundigadvies.nl, 1 +rosecrance.org, 1 +rosehosting.reviews, 1 +roseitsolutions.co.uk, 1 +roseitsolutions.uk, 1 +roseliere.com, 0 +roseluna.com, 1 +rosemariefloydballet.com, 1 +rosemountmn.gov, 1 +rosenberg-fansite.tk, 1 +rosenheimsingles.de, 1 +rosenkavalier.tk, 1 +rosenkeller.org, 1 +roseparkhouse.com, 1 +rosesciences.com, 1 +rosetiger.life, 1 +rosetwig.ca, 1 +rosetwig.systems, 1 +rosevillefacialplasticsurgery.com, 1 +rosewater.me, 1 +rosewebdesignstudio.co.uk, 1 +rosewebdesignstudio.uk, 1 +roshhashanahfun.com, 1 +roshiya.co.in, 1 +roshiya.pw, 1 +rosi-royal.com, 1 +rosiervandenbosch.nl, 1 +roslynpad.net, 1 +rosme.it, 1 +rospotreb.com, 1 +rosrabota.tk, 1 +rosset.me, 1 +rosset.net, 1 +rossfrance.com, 1 +rossfrancis.co.uk, 1 +rossia.ga, 1 +rossiyskaja.cf, 1 +rosskopfs.de, 1 +rosslug.org.uk, 1 +rossome.org, 1 +rosspecstroy.ru, 1 +rosstroj-balashiha.ml, 1 +rosswilson.co.uk, 0 +rost.tv, 1 +rostclub.ro, 1 +rostlau.be, 1 +rostov-arena.ml, 1 +rostov.cf, 1 +roswellcity.tk, 1 +rot256.io, 1 +rot47.net, 1 +rotamap.net, 1 +rotanaval.tk, 1 +rotaractclubtucuman.tk, 1 +rotary.org.ru, 1 +rotaryceuta.tk, 1 +rotaryeclubsafari.org, 1 +rotaryfunds.ga, 1 +rotate4all.com, 1 +rotate4u.eu, 1 +rotatingchefs.com, 1 +rotek.at, 1 +roten.email, 1 +rothbruederlein.tk, 1 +rothe.io, 1 +rothkranz.net, 1 +rothwellgornthomes.com, 1 +rotol.me, 1 +rotonde.gq, 1 +rotozen.com, 1 +rotring.com, 1 +rottamazioni.it, 1 +rotterdamjazz.info, 1 +rottie.xyz, 1 +rottweil-hilft.de, 1 +rottweilerdogcare.com, 1 +rotunneling.net, 1 +rouair.com, 1 +rouamatfashion.gr, 1 +rougechocolat.fr, 1 +rougeetblanc.tk, 1 +roughcopy.com.au, 1 +roughgrain.com, 1 +roughtime.se, 1 +roulettecarnival.com, 1 +roulettestar.com, 1 +roulinfo.ch, 0 +roulons-autrement.com, 1 +rounda.it, 1 +roundaboutweb.net, 1 +roundcube.mayfirst.org, 0 +roundgarden.nl, 1 +roundrock-locksmith.com, 1 +roundtablekzn.co.za, 1 +roundtoprealestate.com, 1 +roussos.cc, 1 +roussosmanos.gr, 1 +rout0r.org, 1 +route-wird-berechnet.de, 1 +routerchart.com, 1 +routerclub.ru, 1 +routeto.com, 1 +routetracker.co, 1 +rouwcentrumterheide.be, 1 +rouxh.com, 1 +rovatronic.tk, 1 +rove3d.com, 1 +roverglobal.ga, 1 +rovezzano.tk, 1 +rovian.ua, 1 +rovity.io, 1 +rovohout.nl, 1 +rovota.com, 1 +rowancasting.com, 1 +rowancasting.ie, 1 +rowancounty911.com, 1 +rowancounty911.org, 1 +rowancountyairport.com, 1 +rowankaag.nl, 1 +rowanpubliclibrary.com, 1 +rowansheriff.com, 1 +rowansheriff.org, 1 +rowantransit.com, 1 +rowantransit.org, 1 +rowanz.nl, 1 +rowery.org, 1 +rowingsa.asn.au, 1 +rowlog.com, 1 +rowra.org, 1 +roxanaherguz.com, 1 +roxburytech.tk, 1 +roxiesbouncycastlehire.co.uk, 1 +roxtri.cz, 1 +roxxz.nl, 0 +roy-buehring.de, 1 +royal-life.tk, 1 +royal-rangers.de, 1 +royal71.com, 1 +royal72.com, 1 +royal806.com, 1 +royal810.com, 1 +royal811.com, 1 +royal812.com, 1 +royal813.com, 1 +royal816.com, 1 +royal817.com, 1 +royal818.com, 1 +royal821.com, 1 +royal822.com, 1 +royal826.com, 1 +royal828.com, 1 +royal83.com, 1 +royal830.com, 1 +royal831.com, 1 +royal833.com, 1 +royal84.com, 1 +royal850.com, 1 +royal851.com, 1 +royal852.com, 1 +royal853.com, 1 +royal855.com, 1 +royal856.com, 1 +royal857.com, 1 +royal858.com, 1 +royal859.com, 1 +royal86.com, 1 +royal865.com, 1 +royal868.com, 1 +royal869.com, 1 +royal876.com, 1 +royal877.com, 1 +royal88.com, 1 +royal88.tech, 1 +royal881.com, 1 +royal882.com, 1 +royal883.com, 1 +royal885.com, 1 +royal886.com, 1 +royal887.com, 1 +royal889.com, 1 +royal896.com, 1 +royal898.com, 1 +royal899.com, 1 +royal929.com, 1 +royal939.com, 1 +royalacademy.org.uk, 1 +royalasianescorts.co.uk, 1 +royalaubar.com, 1 +royalbluewa3.cc, 1 +royalcavaliers.tk, 1 +royalcitystudios.ca, 1 +royalcitytaxi.ca, 1 +royalcrowns.tk, 1 +royalfitnesschennai.in, 1 +royalhosting.ch, 1 +royalkitchensandfurniture.co.ug, 1 +royalmarinesassociation.org.uk, 1 +royalmech.tk, 1 +royalnissanparts.com, 1 +royaloz.ma, 1 +royalpainters.co, 1 +royalpalacenogent.fr, 1 +royalrace.tk, 1 +royalstylefit.com, 1 +royalteam.fr, 1 +royaltube.net, 1 +royalty-market.com, 1 +royaltyexchange.com, 1 +royalvortex.co, 1 +royalyule.com, 1 +royalz.ro, 1 +royaume-smoke.com, 1 +roycampbell.tk, 1 +royceandsteph.com, 1 +roycewilliams.net, 1 +roychan.org, 1 +royger.tk, 1 +royjr.com, 1 +roynuesca.com, 1 +roys.design, 1 +roystowingrockford.com, 1 +royveenendaal.com, 1 +royzez.com, 1 +rozalisbengal.ro, 1 +rozalynne-dawn.ga, 1 +rozar.eu, 1 +rozar.sk, 1 +rozhodce.cz, 1 +rozprodat.cz, 1 +rp-megapolis.tk, 1 +rp-murk.tk, 1 +rpadonline.com, 1 +rpattisonroofing.co.uk, 1 +rpauto.ru, 1 +rpcinmobiliaria.net, 1 +rpg-maker.net, 1 +rpg-maker.org, 1 +rpgamers.fr, 1 +rpgchan.cf, 1 +rpgfactory.tk, 1 +rpgmaker.es, 1 +rpguru.com, 1 +rpherbig.com, 1 +rphl.net, 1 +rphyncice.cz, 1 +rpi-pihole-mon.ddns.net, 1 +rpine.net, 0 +rpj.life, 1 +rpmdrivingschool.com.au, 1 +rpora.co, 1 +rps-auto.com, 1 +rpschultz.de, 1 +rpus.co, 1 +rpy.xyz, 1 +rq-labo.jp, 1 +rr30019.com, 1 +rr5197.co, 1 +rr6729.co, 1 +rr6729.com, 1 +rr6957.co, 1 +rr9297.co, 1 +rr9397.com, 1 +rr9721.com, 1 +rr9728.co, 1 +rrailto.com, 1 +rrbt.eu, 1 +rrbt.net, 1 +rrbts.com, 1 +rrdesignsuisse.com, 0 +rrdtool.com, 1 +rrg-partner.ch, 0 +rritv.com, 1 +rrmiran.com, 1 +rro.rs, 1 +rrssww.space, 1 +rrudnik.com, 1 +rrvmz.cf, 1 +rrwolfe.com, 1 +rs-cloud.ddns.net, 1 +rs-devdemo.host, 1 +rs-maschinenverleih.de, 1 +rsa-erp.com, 1 +rsa-homeinsurance.co.uk, 1 +rsanahuano.com, 1 +rsap.ca, 1 +rsarchive.net, 1 +rsarchive.org, 1 +rsauget.fr, 1 +rsb.net, 1 +rsblake.net, 1 +rsc-cronenberg.de, 1 +rsc.wiki, 1 +rscturmoil.com, 1 +rsdisedezzari.it, 1 +rsdns.ml, 1 +rsec.kr, 1 +rsecure.tk, 1 +rsgcard.com, 1 +rsingermd.com, 1 +rsl.gd, 1 +rslcaresa.com.au, 1 +rsldb.com, 1 +rslnd.com, 1 +rsm-intern.de, 1 +rsmith.io, 1 +rsmmail.com, 0 +rsp-blogs.de, 1 +rspevents.ro, 1 +rsquare.nl, 1 +rsridentassist.com, 1 +rsrnd.org, 1 +rsrv.fr, 1 +rss.org.uk, 1 +rss.sh, 0 +rssfeedonline.tk, 1 +rssl.me, 1 +rssr.ddns.net, 1 +rssr.se, 1 +rstele.ru, 1 +rstraining.co.uk, 0 +rstsecuritygroup.co.uk, 1 +rsttraining.co.uk, 1 +rsvaachen.de, 1 +rsvpdesign.co.uk, 1 +rswebsols.com, 1 +rswow.ru, 1 +rsync.eu, 0 +rszm.com.br, 1 +rt22.ch, 1 +rtate.ca, 1 +rtate.se, 1 +rtc-israel.com, 1 +rtd.uk, 1 +rtd.uk.com, 0 +rte.eu, 1 +rte.host, 1 +rte.mobi, 1 +rte.radio, 1 +rte1.ie, 1 +rte2fm.ie, 1 +rteaertel.ie, 1 +rtechservices.io, 1 +rteguide.ie, 1 +rteinternational.ie, 1 +rtejr.ie, 1 +rtek.se, 1 +rtenews.eu, 1 +rteone.ie, 1 +rteplayer.co.uk, 1 +rteplayer.com, 1 +rteplayer.ie, 1 +rteplayer.org, 1 +rtesport.eu, 1 +rtestore.eu, 1 +rteworld.com, 1 +rtgnews.cf, 1 +rthe.xyz, 1 +rtho.me, 1 +rths.tk, 0 +rthsoftware.net, 0 +rtkbe.com, 1 +rtl.de, 1 +rtlspiele.de, 1 +rtmoran.org, 1 +rtonin.com, 1 +rtparket.ga, 1 +rtsak.com, 1 +rtsr.ch, 0 +rttss.com, 1 +rttvip.com, 1 +rttvvip.com, 1 +rtveen.nl, 1 +rtvslos.nl, 1 +rtwcourse.com, 1 +ru-acyclopedia.cf, 1 +ru-adv.tk, 1 +ru-auto.tk, 1 +ru-sale.tk, 1 +ru-sport.ga, 1 +ru-sprachstudio.ch, 1 +ru.search.yahoo.com, 0 +ru251.tk, 1 +ruaneattorneys.com, 1 +ruanmi.de, 1 +ruanwen168.com, 1 +rubashki-opt.ml, 1 +rubashki.tk, 1 +rubbaduckee.tk, 1 +rubber.cf, 1 +rubberfurs.org, 1 +rubberlegscastles.co.uk, 1 +rubbermaidoutlet.com, 1 +rubbix.net, 1 +rubblekempton.co.za, 1 +rubblerandburg.co.za, 1 +rubbleremovalcapetown.com, 1 +rubbleremovalhillcrest.co.za, 1 +rubblerock.com, 1 +rubdiavila.com, 1 +ruben.am, 0 +rubenbaer.ch, 1 +rubenbrito.net, 1 +rubenmamo.com, 1 +rubenpeeters.ml, 1 +rubenruiz.org, 1 +rubens.cloud, 1 +rubenschulz.nl, 1 +rubenslikkarchive.com, 1 +rubia.ca, 1 +rubiales.tk, 1 +rubic.tk, 1 +rubidium.ml, 1 +rublacklist.net, 1 +rublev.tk, 1 +rubooks.gq, 1 +rubreklama.tk, 1 +ruby-auf-schienen.de, 1 +rubyist.today, 1 +rubymartin.com.au, 1 +rubyonline.tk, 1 +rubyquincunx.com, 1 +rubyquincunx.org, 1 +rubystore.ga, 1 +rubytune.com, 0 +ruchka-mashinka.gq, 1 +rucksack-rauf-und-weg.de, 1 +ruckzuck-privatpatient.de, 1 +rucnerobene.eu, 1 +rud.is, 1 +rudating.tk, 1 +rudd-o.com, 1 +ruddick.org.uk, 1 +ruddick.uk, 1 +rudewiki.com, 1 +rudibora.ml, 1 +rudimart.com, 1 +rudimeds.com, 1 +rudimentalconsolidated.com, 1 +rudimentalconsulting.com, 1 +rudimentalfoods.com, 1 +rudimentalkitchens.com, 1 +rudimentalluxury.com, 1 +rudimentalretail.com, 1 +rudloff.pro, 1 +rudnikas.com, 1 +rudolf.gq, 1 +rudolph.life, 1 +rudovasky.com, 1 +rudrastyh.com, 1 +rudy.ga, 1 +rudymendoza.tk, 1 +rue-de-la-vieille.fr, 1 +rueckert-gymnasium-blog.de, 1 +rueckgr.at, 1 +rueder.com, 1 +ruediger-voigt.eu, 1 +ruedigervoigt.de, 1 +ruedirrenggli.ch, 0 +rueduparticulier.tk, 0 +rueduverre.com, 1 +rueg.eu, 1 +ruerte.net, 1 +ruexpert.cf, 1 +ruf888.com, 1 +rufartabs.ml, 1 +ruffbeatz.com, 1 +ruffinstorage.com, 1 +ruffnecks.tk, 1 +ruflay.ru, 1 +rugadgets.tk, 1 +rugbugecoflooring.com, 1 +rugby.tk, 1 +rugby.video, 1 +rugcleaninglondon.co.uk, 1 +rugeley-vets.co.uk, 1 +rugged-cctv.com, 1 +rugk.dedyn.io, 1 +ruha.co.in, 1 +ruhigehand.de, 1 +ruhimustafa.tk, 1 +ruhnke.cloud, 1 +ruhproject.kz, 1 +ruhrmobil-e.de, 1 +ruhrnalist.de, 1 +ruicore.cn, 1 +ruifu.tech, 1 +ruimoreira.co.uk, 1 +ruimtevoor.gent, 1 +ruimtevoorgent.be, 1 +ruinme.tk, 1 +ruiruigeblog.com, 1 +ruitershoponline.nl, 1 +ruitersportbak.nl, 1 +rujbin.ddns.net, 1 +ruk.ca, 1 +rukhaiyar.com, 1 +rukminicarrentals.com, 1 +ruknguk.tk, 1 +rulaholding.fi, 1 +rulu.tv, 1 +rulutv.com, 1 +rumahminimalisoi.com, 1 +rumahpropertigratis.com, 1 +rumartinez.es, 1 +rumbasguayaquil.com, 1 +rumbies.co.uk, 1 +rumble.com, 1 +rumenka.tk, 1 +ruminecraftru.tk, 1 +rumix.tk, 1 +rumlager.de, 1 +rummage4property.co.uk, 1 +rummey.co.uk, 1 +rumtaste.com, 1 +rumtaste.de, 1 +rumus.co.id, 1 +run-forrest.run, 1 +run-it-direct.co.uk, 1 +runagain.ch, 0 +runame.ml, 1 +runbo-australia.ga, 1 +runbo-new-zealand.ga, 1 +runbo-nz.ga, 1 +runboaustralia.ga, 1 +runcarina.com, 1 +rundesign.it, 1 +rundh-audio.de, 1 +rundh.de, 1 +rundum-service-omh.de, 1 +rundumcolumn.xyz, 1 +runebet.com, 1 +runefake.com, 1 +runementors.com, 0 +runes.cf, 1 +runescape.wiki, 1 +runescapelordsconquest.tk, 1 +runesforbeginners.com, 1 +runet.cf, 1 +runetracker.org, 1 +runeworldforums.tk, 1 +runews.cf, 1 +runfitcoaching.com, 1 +rungstedhave.dk, 1 +rungutan.com, 1 +runicspells.com, 1 +runklesecurity.com, 1 +runlet.gq, 1 +runmyvillage.com, 1 +runner.az, 1 +runnergrapher.com, 1 +runners.yoga, 1 +runnerslab.com, 1 +runningfast.cf, 1 +runningrabb.it, 1 +runningshows.tk, 1 +runosklep.pl, 1 +runreport.fr, 1 +runrocknroll.com, 1 +runschrauger.com, 1 +runvs.io, 1 +ruobiyi.com, 1 +ruobr.ru, 1 +ruoskachile.tk, 1 +rupeespeaks.tk, 1 +rupeevest.com, 1 +rupool.tk, 1 +rupostel.com, 1 +rupressa.tk, 1 +ruprivorot.tk, 1 +rupture-skate.tk, 1 +ruqbnsmokebbq.ga, 1 +ruquay.com, 1 +ruquiz.tk, 1 +rural-house.tk, 1 +ruralink.com.ar, 1 +ruralsuppliesdirect.co.uk, 1 +ruri.io, 1 +rurian-gyohen.com, 1 +rus-blog.tk, 1 +rus-manual.tk, 1 +rus-trip.ru, 0 +rusdigisolutions.com, 1 +ruse.church, 1 +rusenemas.tk, 1 +rusexmany.ml, 1 +rushashkyfond.com, 1 +rushesflorist.co.uk, 1 +rushmix.com, 1 +rushmyessay.gq, 1 +rushpoppershop.co.uk, 1 +rushter.com, 1 +rushtonparay.com, 1 +rushyo.com, 1 +rusi-ns.ca, 1 +rusichi.tk, 1 +rusiptv.cf, 1 +ruska-modra.cz, 1 +ruskamodra.cz, 1 +ruskod.net, 1 +rusmodel.tk, 1 +rusmolotok.ru, 1 +rusnicolas.cf, 1 +rusposuda.cf, 1 +russ-portal.tk, 1 +russandol.eu, 1 +russchooljordan.tk, 1 +russell-tech.co.uk, 1 +russellenvy.com, 1 +russelljohn.net, 1 +russellupevents.co.uk, 1 +russenes.com, 1 +russia-furniture.tk, 1 +russia-knigi.ga, 1 +russia-rp.tk, 1 +russia.dating, 1 +russia.wtf, 1 +russiaeconomy.org, 1 +russiahockey.tk, 1 +russiahunting.tk, 1 +russialife.gq, 1 +russian-artist.tk, 1 +russian-fur.tk, 1 +russian-knights.ru, 1 +russian-page.tk, 1 +russianbearsmotorsport.tk, 1 +russianbluecatsguide.com, 1 +russianbristol.tk, 1 +russianews.cf, 1 +russianpunkrock.tk, 1 +russianrandom.ru, 1 +russisch.tk, 1 +russograffix.tk, 1 +russt.me, 1 +rust.cf, 1 +rust.mn, 1 +rust.pm, 1 +rustable.com, 1 +rustambek.tk, 1 +rustamkhanko.gq, 1 +rustfu.rs, 1 +rusticpathways.com.au, 1 +rustikalwallis.ch, 1 +rustls.com, 1 +rustls.org, 1 +rustyrambles.com, 1 +rusunion.org, 1 +ruswomen.tk, 1 +rusxakep.com, 1 +rut2.tk, 1 +rutalimon.com, 1 +rutar.org, 1 +rutasypostales.com, 1 +rutavietnam.com, 1 +rutgerschimmel.nl, 1 +ruthbarrettmusic.com, 1 +ruthbellgrahammemorial.org, 1 +ruthlavidente.com, 1 +ruthmontenegro.com, 1 +ruthschoenmaekers.com, 1 +rutiger.com, 1 +rutika.ru, 1 +rutten.me, 0 +ruttenadvocaat.be, 1 +ruudkoot.nl, 1 +ruurdboomsma.nl, 1 +ruvinroshan.com, 1 +ruwhof.net, 1 +ruya.com, 1 +ruyana.tk, 1 +ruyatabirleri.com, 1 +ruzaevka.tk, 1 +ruzzll.com, 1 +rv-jpshop.com, 1 +rva-asbestgroep.nl, 1 +rva.gov, 1 +rvantwembeke.tk, 1 +rvdbict.nl, 1 +rvecomercio.com.br, 1 +rvender.cz, 1 +rvfit.dk, 1 +rvg.zone, 1 +rvmfm.com, 1 +rvnoel.net, 0 +rvoigt.eu, 1 +rvpoweroutlet.com, 1 +rvsa2bevestigingen.nl, 1 +rvsa4bevestigingen.nl, 1 +rvsbevestigingen.nl, 1 +rvvc.im, 1 +rw-invest.com, 1 +rw.search.yahoo.com, 0 +rw2.de, 1 +rwalch.at, 1 +rway.pro, 1 +rwbstuff.com, 1 +rwgamernl.ml, 1 +rwky.net, 1 +rws-vertriebsportal.de, 1 +rwx.ovh, 1 +rwx.work, 1 +rx-diet.com, 1 +rx-safety.com, 1 +rxbn.de, 1 +rxbusiness.com, 1 +rxguide.nl, 1 +rxyz.rocks, 1 +ry88url.com, 1 +ryabinushka.tk, 1 +ryan-13.tk, 1 +ryan-gehring.com, 1 +ryan-goldstein.com, 1 +ryan.cafe, 1 +ryanbritton.com, 1 +ryandewsbury.co.uk, 1 +ryanfamily.net.au, 1 +ryanhowell.io, 1 +ryankearney.com, 0 +ryankilfedder.com, 1 +ryanmcdonough.co.uk, 0 +ryanparman.com, 1 +ryanrichardwalker.com, 1 +ryanteck.uk, 1 +ryazagro.ru, 1 +ryazan-region.ru, 1 +ryazancity.tk, 1 +rybalku.ru, 1 +rybarski.com, 1 +rybinsk.ga, 1 +rybnitsa.cf, 1 +rybox.info, 1 +rychlikoderi.cz, 0 +rydeify.com, 1 +rydi.org, 1 +ryejuice.sytes.net, 1 +rygh.no, 1 +rygy.com.br, 1 +ryland.consulting, 1 +rylore.com, 1 +rymanow.tk, 1 +rymergames.tk, 1 +rynekpierwotny.pl, 1 +rynkebo.dk, 1 +ryois.me, 1 +rys.pw, 1 +rythgs.co, 0 +rythm.es, 1 +ryu22e.org, 1 +ryuanerin.kr, 1 +ryzen.cz, 1 +ryzex.de, 1 +ryzhov.me, 1 +rzegocki.pl, 1 +rzentarzewski.net, 1 +rzero.tk, 1 +s-4.host, 1 +s-a.xyz, 1 +s-c.se, 1 +s-cubed.net, 1 +s-culture.co.kr, 1 +s-geiser.de, 1 +s-gong.com, 1 +s-huset.dk, 1 +s-ip-media.de, 1 +s-kanbanya.com, 1 +s-mainte.com, 1 +s-mall.com.sg, 1 +s-on.li, 1 +s-pira.games, 1 +s-pro.io, 1 +s-s-paint.com, 1 +s-u.pw, 1 +s-yuz.com, 1 +s.cat, 1 +s007.co, 1 +s0923.com, 1 +s0laris.co.uk, 1 +s1-llc.com, 1 +s10y.eu, 1 +s1128.com, 1 +s1mplescripts.de, 1 +s1ris.org, 1 +s2.coach, 1 +s20121946.ml, 1 +s2i.ch, 0 +s2member.com, 1 +s2p.moe, 1 +s2t.net, 1 +s30365.com, 1 +s36533.com, 1 +s3cur3.it, 1 +s3gfault.com, 1 +s3lph.me, 1 +s3n.se, 1 +s402.de, 1 +s404.de, 1 +s44.eu, 1 +s4db.net, 1 +s4media.org, 1 +s4q.me, 1 +s4tips.com, 1 +s4ur0n.com, 1 +s5118.com, 1 +s5197.co, 1 +s550.cc, 0 +s551.cc, 0 +s552.cc, 0 +s553.cc, 0 +s554.cc, 0 +s556.cc, 0 +s557.cc, 0 +s558.cc, 0 +s559.cc, 0 +s5g8.com, 1 +s5hxsrv.xyz, 1 +s64.cz, 1 +s6729.co, 1 +s6729.com, 1 +s6957.co, 1 +s6jl.com, 1 +s81365.com, 1 +s82365.com, 1 +s88.com, 1 +s8a.us, 1 +s92.cloud, 1 +s92.io, 1 +s92.me, 1 +s9297.co, 1 +s9397.com, 1 +s95.de, 1 +s9721.com, 1 +s9728.co, 1 +sa-blog.net, 1 +sa-hc.com, 1 +sa-mp.me, 1 +sa-mp.ro, 1 +sa.net, 1 +sa68.cc, 1 +sa88.cc, 1 +saadat.in.ua, 1 +saalfrank.at, 1 +saalfrank.de, 1 +saamhorigheidsfonds.nl, 0 +saaremaa.tk, 1 +saas.de, 1 +saatchiart.com, 1 +saathi.asia, 1 +sab.id, 1 +saba-piserver.info, 1 +saba-shop.tk, 1 +sabachat.tk, 1 +sabahattin-gucukoglu.com, 1 +sabaikonotes.com, 1 +sabaland.tk, 1 +sabatikirooms.com, 1 +sabbat-wildfire.tk, 1 +sabbottlabs.com, 1 +sabbry.com, 1 +sabedinovski.tk, 1 +saber-nyan.com, 1 +saberhortifruti.com.br, 1 +sabghijewelers.com, 1 +sabhijobs.com, 1 +sabians.tk, 1 +sabine-forschbach.de, 1 +sabineforschbach.de, 1 +sabkappers.nl, 1 +sablanout.com, 1 +sable.gq, 1 +sabmobile.pk, 1 +saborcaribe.tk, 1 +sabrinajoias.com.br, 1 +sabrinajoiasprontaentrega.com.br, 1 +sabrinajoiasvarejo.com.br, 1 +sabrinamiskiewicz.tk, 1 +sabrinarus.tk, 1 +sabrine.tk, 1 +sabworldtricks.tk, 1 +sacademica.tk, 1 +sacaentradas.com, 1 +saccani.net, 1 +saccounty.gov, 1 +sacharidovejednotky.eu, 1 +sachasmets.be, 1 +sachk.com, 1 +sachse.info, 1 +sacibo.ga, 1 +sackmesser.ch, 1 +saclier.at, 1 +sacodealegria.com, 1 +sacodecuentos.com, 1 +sacprincesse.com, 1 +sacramentocounty.gov, 1 +sacramentum.tk, 1 +sacred-knights.net, 1 +sacredart-murals.co.uk, 1 +sacredheart-cliftonheights.net, 1 +sacredsecondhandbooks.com.au, 1 +sacrome.com, 1 +sacrosanctus.tk, 1 +sacult.com, 1 +sad-berezka.ru, 0 +sadbox.es, 1 +sadbox.org, 1 +sadbox.xyz, 1 +sadeghian.us, 1 +sadev.co.za, 1 +sadhana.cz, 1 +sadhawkict.org, 1 +sadiejanehair.com, 1 +sadiejewellery.co.uk, 1 +sadiestavern.cf, 1 +sadievilleky.gov, 1 +sadjiri.com, 1 +sadko-group.com, 1 +sadkodesign.com.ua, 1 +sadmansh.com, 1 +sadou.kyoto.jp, 1 +sadoun.com, 1 +sadsu.com, 0 +saechsischer-christstollen.shop, 1 +saeder-krupp.de, 1 +saeedvaladbaygi.info, 1 +saenforcement.agency, 1 +saengsook.com, 1 +saengsuk.com, 1 +saevor.com, 1 +saf.earth, 1 +safalfasalonline.in, 1 +safar.sk, 1 +safara.host, 1 +safarimasaimara.com, 1 +safaritenten.nl, 1 +safc.tk, 1 +safcstore.com, 1 +safeacs.com, 1 +safeadmin.ga, 1 +safeandsecureserver.com, 1 +safearth.training, 1 +safeathomeohio.gov, 1 +safebaseflorida.com, 1 +safebasements.com, 1 +safebasementsnorthdakota.com, 1 +safebasementsofindiana.com, 1 +safebasementswaterproofing.com, 1 +safeboard.ml, 1 +safebuyerscheme.co.uk, 1 +safecar.gov, 1 +safecash.id, 1 +safecoin.tech, 1 +safecso.cf, 1 +safefreehost.gq, 1 +safefreepornsites.com, 1 +safegold.ca, 1 +safegroup.pl, 1 +safeguardhosting.ca, 1 +safeguardstudents.com, 1 +safehero.com, 1 +safehouse.zone, 1 +safeinfra.nl, 1 +safeitup.se, 1 +safejourney.education, 1 +safeme.ga, 1 +safemt.gov, 1 +safenetwork.it, 1 +safeo.fr, 1 +safeocs.gov, 1 +safeprint.pt, 1 +safer-software.tk, 1 +safercar.gov, 1 +saferchildren.eu, 0 +saferedirect.link, 1 +saferedirectlink.com, 1 +saferequest.net, 1 +safermao.fr, 1 +saferpost.com, 1 +saferproduct.gov, 1 +safersurfing.eu, 0 +safertruck.gov, 1 +safescan.com, 1 +safescif.com, 1 +safesearchs.com, 1 +safesoundcounselingllc.com, 1 +safestore.io, 1 +safestreets.cf, 1 +safetables.ga, 1 +safetext.me, 1 +safethishome.com, 1 +safetycloud.me, 1 +safetydrivessuccess.com, 1 +safetymeasuresas.com, 1 +safetymp3.com, 1 +safetynames.com, 1 +safetynetwork.me, 1 +safetyrange.com, 1 +safetysite.tips, 1 +safeui.com, 0 +safevault.org, 1 +safewaysecurityscreens.com.au, 1 +safewaywaterproofing.com, 1 +safiosolutions.com, 1 +safirakbar.tk, 1 +safire.ac.za, 1 +safirkimya.com, 1 +safungerar.se, 1 +sagaenterprizes.com, 1 +sagafalabellacatalogo.net, 1 +sagagardencentre.co.uk, 1 +sagame88vip.com, 1 +sagan.tk, 1 +sagargandecha.com.au, 0 +sageclinic.org, 1 +sagedocumentmanager.com, 1 +sagefalab.com, 1 +sageinkenya.org, 1 +sagenesykkel.com, 1 +sagenet.net.au, 1 +sagerus.com, 1 +saggiocc.com, 1 +saghekin.com, 1 +sagitta.hr, 1 +saglikhaber.tk, 1 +sagliklidegisim.com, 1 +sagnette.xyz, 1 +sagomedia.tk, 1 +sagracefarms.com, 1 +sagrande.ru, 1 +sahajbooks.com, 1 +sahalin.tk, 1 +sahalinskiy.gq, 1 +sahar.io, 1 +saharacloud.com, 1 +saharmassachi.com, 1 +sahb.dk, 1 +sahccareers.com, 1 +sahibinden.com, 1 +sahkotyot.eu, 1 +saibacademy.com, 1 +saibotk.de, 1 +said.id, 1 +said.it, 1 +said.my.id, 1 +saidit.net, 1 +saier.me, 1 +saifonvillas.com, 1 +saifoundation.in, 1 +saigaocy.moe, 1 +saigonflowers.com, 1 +saigonland24h.vn, 1 +saigonstar.de, 1 +saikarra.com, 1 +saikou.moe, 1 +saikouji.tokushima.jp, 1 +sail-nyc.com, 1 +sailing-yacht.club, 1 +sailormoonevents.org, 1 +sailormoongallery.org, 1 +sailormoonlibrary.org, 1 +sailwiz.com, 1 +saimatravels.in, 1 +saimoe.moe, 1 +saimoe.org, 1 +sainetworks.net, 1 +sainokuni-eng.jp, 1 +sainshand.tk, 1 +saint-aubin-sur-scie.fr, 1 +saint-cyril.com, 1 +saint-leonard.fr, 1 +saint-peterburg.tk, 1 +saint-petersburg.cf, 1 +saint-petersburg.gq, 1 +saint-petersburg.ml, 1 +saint-ssd.org, 1 +saintaardvarkthecarpeted.com, 1 +saintanne.net, 1 +saintanthonylakin.org, 1 +saintanthonyscorner.com, 1 +saintaugustineschool.tk, 1 +saintbernardpetcare.com, 1 +saintereso.tk, 1 +sainteugenechurch.net, 1 +sainteugeneschurch.com, 1 +saintfrancescabrini.net, 1 +sainth.de, 0 +sainthedwig-saintmary.org, 1 +sainthelena-centersquare.net, 1 +sainthelenas.org, 1 +saintisidorecyo.com, 1 +saintjamestheapostle.org, 1 +saintjohn-bocaraton.com, 1 +saintjosephschurch.net, 1 +saintleochurch.net, 1 +saintlouisfence.com, 1 +saintmarkchurch.net, 1 +saintmaryna.com, 1 +saintmaryscathedral-trenton.org, 1 +saintpatrick-norristown.net, 1 +saintpeterchurch.net, 1 +saintpetersburg.cf, 1 +saintpetersburg.ga, 1 +saintpetersburg.gq, 1 +saintpetersburg.ml, 1 +saintphilipneri.org, 1 +saintpius.net, 1 +saintpolycarp.org, 1 +saintvincent.tk, 1 +saintw.com, 1 +sainzderozas.com, 1 +saipariwar.com, 1 +saipeople.net, 1 +saiputra.com, 1 +sairadio.net, 1 +sairadio.net.in, 1 +sairai.bid, 1 +sairlerimiz.tk, 1 +sairus.fr, 1 +saisecure.net, 1 +saisyuusyou-ikebukuro.com, 1 +saisyuusyou-omiya.com, 1 +saisyuusyou-takasaki.com, 1 +saisyuusyou-utsunomiya.com, 1 +saitapovan.com, 1 +saitas.net, 1 +saitechgroups.com, 1 +saito-koken.co.jp, 1 +saitrance.com, 1 +saitschool.ml, 1 +saitv.org.in, 1 +saityvkaluge.ru, 1 +saiyans.com.ve, 1 +sajamstudija.info, 1 +sajdowski.de, 1 +sajjadzaidi.com, 1 +sajt-vizitka-nedorogo.ru, 1 +sajter.ga, 1 +sajtoskal.hu, 0 +sajtr.ga, 1 +sakainvest.com, 1 +sakaki.anime.my, 0 +sakakun.de, 1 +sakamichi.moe, 1 +sakenohana.com, 1 +sakerhetskopiering.nu, 1 +sakiborislam.com, 1 +sakostacloud.de, 1 +saksonski-szlak-parowozow.pl, 1 +sakura-paris.org, 1 +sakura.zone, 1 +sakuracdn.com, 1 +sakuracommunity.com, 1 +sakuradata.com, 0 +sakurapalace.tk, 1 +sakuraplay.com, 1 +salaamgateway.com, 1 +saladgo.id, 1 +salaervergleich.com, 0 +salaire-minimum.com, 1 +salalfoundation.ca, 1 +salamanders.tk, 1 +salaminos.no-ip.org, 1 +salandalairconditioning.com, 1 +salariominimo.com.co, 1 +salarycalculatoruk.co.uk, 1 +salas.cf, 1 +salas.tk, 1 +salasbanquetes.cl, 1 +salati.tk, 1 +salatiga.com, 1 +salatiga.net, 1 +sald.us, 1 +salde.net, 1 +sale-internet.cf, 1 +sale4ru.ru, 1 +saleaks.org, 1 +salebaba.com, 1 +saleduck.at, 1 +saleduck.ch, 1 +saleduck.co.id, 1 +saleduck.co.th, 1 +saleduck.com.my, 1 +saleduck.com.ph, 1 +saleduck.com.sg, 1 +saleduck.com.vn, 1 +saleduck.dk, 1 +saleduck.fi, 1 +saleduck.se, 1 +saledump.nl, 1 +salegor.tk, 1 +salekaz.ru, 1 +salemedia.pro, 1 +salensmotors-usedcars.be, 0 +salento-nostro.tk, 1 +salentocab.com, 1 +saleproductsoffer.com, 1 +salery.ga, 1 +salesdivisie.nl, 1 +salesflare.com, 1 +salesoutcomes.com, 1 +salestaxspecialists.com, 1 +saletodo.com, 1 +saleturs.tk, 1 +saletzki.de, 1 +salexy.kz, 1 +salibandy.tk, 1 +salidaswap.com, 1 +salilab.org, 1 +salkield.uk, 1 +sallah-kw.com, 1 +salland1.nl, 1 +salle-quali.fr, 0 +sallyandruss.ca, 1 +sallyangeli.tk, 1 +sallycooke.co.uk, 1 +sallydowns.name, 1 +sallyman.de, 1 +sallysubs.com, 0 +salmanravoof.com, 1 +salmododia.net, 1 +salmonelectric.com, 1 +salmonella.co.uk, 1 +salmonvision.com.tw, 1 +salmotierra-salvatierra.com, 0 +salnet.wf, 1 +salo.fi, 1 +salon-claudia.ch, 1 +salon-de-patchouli.com, 1 +salon-hinata.biz, 1 +salon-largo.com, 1 +salon-minipli.de, 1 +salon-svadbi.tk, 1 +salon.io, 0 +salonasymetria.com, 1 +salonasymetria.pl, 1 +salonestella.it, 1 +salonsantebienetre.ch, 0 +salrosadohimalaia.com, 1 +salsa-straubing.de, 1 +salt-documentary.blog, 1 +salt-travel.cf, 1 +salt.fish, 1 +saltbythesea.com, 1 +saltcave.gq, 1 +saltedfish.network, 1 +saltercane.com, 0 +saltlakedjcompany.com, 1 +saltlakepediatricdentist.com, 1 +saltnsauce.cf, 1 +saltosaltos.eu, 1 +saltrecovery.com.au, 1 +saltro.nl, 0 +saltstack.cz, 1 +saltsugarlove.de, 1 +saltwaterfishaspets.com, 1 +saltydogpaddle.org, 1 +saltyfish.tech, 1 +saltyproshop.com, 1 +salud-paratodos.com, 1 +salud.top, 0 +saludakeuring.nl, 1 +saluddecalidad.com, 0 +saludmas.site, 1 +saludnutrivida.com, 1 +saludsis.mil.co, 1 +saluels.servemp3.com, 1 +salukinet.tk, 1 +salut-butovo.cf, 1 +salutenaturale.com.br, 1 +salutes.tk, 1 +salutethefish.com, 1 +salutethegrains.com, 1 +salutparis.ml, 1 +salva.re, 1 +salvaalocombia.com, 1 +salvadoralevin.tk, 1 +salvadorcorriols.tk, 1 +salvadorinfantil.tk, 1 +salvagedfurnitureparlour.com, 1 +salvameblog.tk, 1 +salvandoalocombia.com, 1 +salverainha.org, 1 +salzamt.tk, 1 +salzerperu.com, 1 +sam-football.fr, 1 +sam.gov, 1 +sam66.cc, 1 +sam88.cc, 1 +samalderson.co.uk, 1 +samalova-chata.cz, 1 +samandavani.com, 1 +samandcatonline.tk, 1 +samandej.ir, 1 +samandroscosrestaurant.com, 1 +samanexports.in, 1 +samanthabiggers.com, 1 +samanthasgeckos.com, 1 +samappleton.com, 1 +samar-leyte.tk, 1 +samara-avia.ru, 1 +samara-hosting.tk, 1 +samaresane.com, 1 +samariafar.com, 0 +samaritainsmeyrin.ch, 0 +samarth.edu.in, 1 +samatva-yogalaya.com, 1 +samba.org, 1 +sambaash.com, 1 +sambeso.net, 1 +sambot22.tk, 1 +sambuchanan.tk, 1 +sambus.com, 1 +samcoestate.ro, 1 +samdev.io, 1 +samdrewtakeson.com, 1 +samedamci.com, 1 +samegoal.com, 1 +samegoal.org, 1 +samel.de, 1 +samentest.tk, 1 +samenuitsamenthuis.tk, 1 +samenwerkingsportaal.nl, 1 +samenwerkingsportaal.tk, 1 +samepage.io, 1 +samesound.ru, 1 +sametimetomorrow.tk, 1 +sameworks.com, 1 +samhsa.gov, 1 +samhuri.net, 1 +samiamelikian.com.br, 1 +samic.ir, 1 +samic.org, 1 +samic.us, 1 +samifar.in, 1 +samin.tk, 1 +samindgroup.com, 1 +samir-software.tk, 1 +samiratv.tk, 1 +samisoft.ir, 1 +samiysok.cf, 1 +samkelleher.com, 1 +samkoandmikotoywarehouse.com, 1 +saml-gateway.org, 1 +samlam.ddns.net, 1 +samlamac.com, 1 +samlaw.co.nz, 1 +sammamish--locksmith.com, 1 +sammichscripts.com, 1 +sammyjohnson.com, 1 +sammyservers.com, 1 +sammyservers.net, 1 +samodel.ml, 1 +samodel.tk, 1 +samogonka.tk, 1 +samokhin.cf, 1 +samorazvitie.ru, 1 +samotorsporttyres.com.au, 1 +samoyeddogsguide.com, 1 +samp.im, 1 +sampaguide.com, 1 +sampatjewelers.com, 1 +sample-site.click, 1 +samplefashion.nl, 1 +sampurna.shop, 1 +samri.pt, 1 +samroelants.com, 1 +sams.wtf, 1 +samsebe.ml, 1 +samsebe.tk, 1 +samshouseofspaghetti.net, 1 +samskaar.in, 1 +samsonova.de, 1 +samsreseller.com, 1 +samtalen.nl, 1 +samthecomputerman.com.au, 1 +samuel-brown.com, 1 +samuel-philipp.de, 1 +samuelbeckett.tk, 1 +samuelbramley.com, 1 +samuelcoles.co.uk, 1 +samueletoo.tk, 1 +samuelkeeley.com, 1 +samuelkyalo.tk, 1 +samuellaulhau.fr, 0 +samui-samui.de, 0 +samuidiving.net, 1 +samuirehabcenter.com, 1 +samurai-implant.com, 1 +samuraicafeauc.com, 1 +samuraiskye.com, 1 +samusil.org, 1 +samvanderkris.com, 1 +samwilberforce.com, 1 +samwrigley.co.uk, 1 +samystic.com, 1 +san.tv, 1 +sana-store.com, 1 +sana-store.cz, 1 +sana-store.sk, 1 +sanalaile.tk, 1 +sanalsergi.com, 1 +sanandreasstories.com, 1 +sanantoniolocksmithinc.com, 1 +sanantoniolocksmithtx.com, 1 +sanantoniourologygroup.com, 1 +sanasport.cz, 1 +sanasport.sk, 1 +sanates.cz, 1 +sanatfilan.com, 0 +sanatori-elochka.tk, 1 +sanatori-teterev.tk, 1 +sanatorii-sverdlovskoy-oblasti.ru, 1 +sanatorionosti.com.ar, 1 +sanatstore.ir, 1 +sanayi.gov.tr, 1 +sanbornteam.com, 1 +sancaktepehaber.tk, 1 +sanchez.adv.br, 0 +sanchezt.fr, 1 +sanctum.geek.nz, 1 +sanctumwealth.com, 0 +sanctus-de.tk, 1 +sand-and-mercury.tk, 1 +sand-craft.ml, 1 +sand-stoneinc.com, 1 +sand66.cc, 1 +sand66.com, 1 +sandalj.com, 1 +sandbox.mydigipass.com, 0 +sandboxstationchildcare.com, 1 +sandburner.net, 1 +sandeepjinagal.com, 1 +sandelduggal.com, 1 +sander.sh, 1 +sanderdorigo.nl, 1 +sanderkoenders.eu, 1 +sanderkoenders.nl, 1 +sanderpoppe.com, 1 +sanderstech.solutions, 1 +sandervanderstap.nl, 1 +sandervankasteel.nl, 0 +sandgatebaysidedental.com.au, 1 +sandhaufen.tk, 1 +sandiegoluxuryhomes.org, 1 +sandiegotown.com, 1 +sandiuno.ml, 1 +sandmanintel.com, 1 +sandmarc.cz, 1 +sandokan.tk, 1 +sandor.wtf, 1 +sandr0.tk, 1 +sandra-perlbach.de, 1 +sandrabernardo.com, 1 +sandrainden.nl, 1 +sandraindenfotografie.nl, 1 +sandramorrone.tk, 1 +sandras-hobbystueble.de, 1 +sandrinesite.tk, 1 +sandrolittke.de, 1 +sandrproperty.com, 1 +sandstroh.network, 1 +sandtears.com, 1 +sandtime.io, 1 +sandtohand.com, 1 +sandton-plumbing.co.za, 1 +sandtonescorts.com, 1 +sandtonplumbing.co.za, 1 +sanduskycountyoh.gov, 1 +sandwichclub.tk, 1 +sandwichcouncil.tk, 1 +sandwoman.tk, 1 +sandybigboobs.net, 1 +sandyrobison.org, 1 +sandyrobsonhypnotherapy.co.uk, 1 +sanemind.de, 1 +sanepsychologen.nl, 1 +sanex.ca, 1 +sanfernando.tk, 1 +sangen.ml, 1 +sangheon.com, 1 +sangiovannilipioni.tk, 1 +sangitafoodmess.com, 1 +sanglierhurlant.fr, 1 +sangoandmiroku.tk, 1 +sangobion.com, 0 +sangobion.com.my, 1 +sangowen.xyz, 1 +sangreytinta.tk, 1 +sangwanbeach.tk, 1 +sangyoui.health, 1 +sanierungskonzept.pro, 1 +sanificazioni.roma.it, 1 +sanikapandit.com, 1 +sanin.gq, 1 +sanipousse.com, 1 +sanisafepro.com, 1 +sanitaer-notdienst-zentrale.de, 1 +sanitairkiezer.nl, 1 +sanitairwinkel.be, 1 +sanitairwinkel.com, 1 +sanitairwinkel.nl, 1 +sanitix.com, 1 +sanitizinggurus.com, 1 +sanity.host, 1 +sanity.io, 1 +sanityrant.cf, 1 +sanix.org, 0 +sanjacintotitle.com, 1 +sanjosecolorectal.com, 1 +sanjosecostarica.org, 1 +sanjuandeabajo.tk, 1 +sanjuanerita.com, 1 +sanketsu.ml, 0 +sankovitzmediation.com, 1 +sanktpetriskole.dk, 1 +sanluisdequillota.tk, 1 +sanmarcovecchio.tk, 1 +sanmonjiya-kimono.com, 1 +sanmuding.com, 1 +sannefoltz.com, 1 +sannesfotklinikk.no, 1 +sannikfk.gq, 1 +sanodent.com.ua, 1 +sanogueiraazulejaria.com, 1 +sanogym.com, 1 +sanook69.com, 1 +sanooktiew.com, 0 +sanpablo.tk, 1 +sanpancrazio.tk, 1 +sanpatriciocountytx.gov, 1 +sanpei-design.com, 1 +sanpham-balea.org, 1 +sanqinyinshi.com.cn, 1 +sans-hotel.com, 1 +sanskrit.pub, 1 +sanskrit.site, 1 +sanskritiyoga.com, 1 +sansonehowell.com, 1 +santa-fell-from.space, 1 +santabarbaraca.gov, 1 +santacruzdescargas.tk, 1 +santaijia.com, 0 +santamargarita.tk, 1 +santamariadelaisla.tk, 1 +santamonicapost123.org, 1 +santander.com, 1 +santanderassetmanagement.es, 1 +santanderideas.com, 0 +santandertrade.com, 1 +santarosaca.gov, 1 +santarosadetail.com, 1 +santegra.tk, 1 +santehart.by, 1 +santehnica.ml, 1 +santehnik-home.ru, 1 +santekhmarket-nn.ru, 1 +santenatureetcie.com, 0 +santeriabeliefs.com, 1 +santevege.fr, 1 +santevie.ch, 0 +santhoshveer.com, 1 +santi-club.de, 1 +santiagogarza.co, 1 +santibanezdetera.tk, 1 +santimb.photos, 1 +santing.net, 1 +santippolito-borgo.tk, 1 +santjoandevilassar.tk, 1 +santmark.com, 1 +santmark.eu, 1 +santmark.fi, 1 +santmark.info, 1 +santmark.net, 1 +santmark.org, 1 +santo.fi, 1 +santong.tk, 1 +santoscarmelitas.tk, 1 +santoshpandit.com, 1 +santugon.tk, 1 +sanukarlos.tk, 1 +sanweb.info, 1 +sanych-msk.ru, 1 +saol.eu, 1 +saorsa.fr, 1 +saorsat.com, 1 +saorsat.ie, 1 +saorsat.net, 1 +saorsat.tv, 1 +saorview.com, 1 +saorview.ie, 1 +saorview.net, 1 +saorviewconnect.ie, 1 +saorviewconnected.ie, 1 +sap-inc.co.jp, 1 +sapac.es, 1 +sapancavillalari.com, 1 +sapaship.ru, 1 +sapibatam.com, 1 +sapien-ci.com, 1 +sapience.com, 1 +sapiensmedicus.org, 0 +sapienz.tk, 1 +sapienza-eclipse.com, 1 +sapienzaconsulting.com, 1 +sapindus.pl, 1 +sapiperelining.com.au, 1 +sapk.fr, 1 +saplumbers.com.au, 1 +sapoghki.tk, 1 +saposute-s.jp, 1 +sapphi.st, 1 +sapphireblue.me, 1 +sapphirepack.org, 1 +sapphirepearl.com.sg, 1 +sapphireservicesga.com, 1 +sapporo-asaichi.com, 1 +sapporobeer.com, 1 +sapprendre.ch, 0 +saprima.de, 0 +sapuseven.com, 1 +saputra.org, 1 +saq.com, 0 +sarafanchiki.tk, 1 +sarafani.tk, 1 +sarafshop.tk, 1 +sarah-brown.tk, 1 +sarah-harding.tk, 1 +sarah-jane.nl, 1 +sarah-secret.com, 1 +sarahjaneethan.co.uk, 1 +sarahjaneredmond.com, 1 +sarahlicity.co.uk, 1 +sarahlicity.me.uk, 1 +sarahplusdrei.de, 1 +sarahshabrina.tk, 1 +sarahvanessen.tk, 1 +sarahwellington.com, 1 +sarahwikeley.co.uk, 1 +saraleebread.com, 0 +saralmai.com, 1 +saranamayyappa.tk, 1 +sarariman.com, 1 +saraskins.tk, 1 +sarasotadentistry.com, 1 +sarasotaroboticurology.com, 1 +saratov24.tk, 1 +saratovlive.tk, 1 +saratovnews.ml, 1 +saratovtime.tk, 1 +sarayeirani.com, 1 +sarbash.ee, 1 +sarcastic.com.au, 1 +sard.ro, 1 +sardacompost.it, 1 +sardegnarifiuti.it, 1 +sardegnatirocini.it, 1 +sardine.tk, 1 +sardinianvillas.co.uk, 1 +sardinianvillas.com, 1 +sardinianvillas.ru, 1 +sardoche.lol, 1 +sarecords.tk, 1 +sarella.org, 1 +sargeson.it, 1 +sarhua.tk, 1 +sarink.eu, 1 +sarisander.com, 1 +sarjakuvakauppa.fi, 1 +sarkar.xyz, 1 +sarkaribabu.in, 1 +sarkarinaukriworld.net, 1 +sarkisianbuilders.com, 1 +sarmpel.tk, 1 +sarndipity.com, 1 +sarny.at, 1 +saro.me, 1 +sarogiw.tk, 1 +saronikos.guide, 1 +saropa.com, 1 +sarouel.fr, 1 +sarox.com.au, 0 +sarpsb.org, 1 +sars-cov-2.com, 1 +sartoria.roma.it, 1 +sarumtechnologies.com, 1 +sarv.com, 1 +sarvaapp.com, 1 +sarvaappstage.com, 1 +sas-snowboarding.sk, 1 +sasakala.tk, 1 +sasapost.co, 1 +sascha-brockel.de, 1 +sascha.io, 1 +sascha.is, 1 +saschaeggenberger.ch, 1 +saschaeggenberger.com, 1 +sash.pw, 1 +sashabognibov.tk, 1 +sashakrasnoyarsk.tk, 1 +sashascollections.com, 1 +sashka.com.ua, 1 +sashleighaust.com, 1 +sasioglu.co.uk, 1 +sasrobotics.xyz, 1 +sasroli.tk, 1 +sastd.com, 1 +sasyabapi.com, 1 +sat-kw.net, 1 +sat4all.com, 1 +sata-group.com, 1 +satai.dk, 1 +satal.in, 1 +satangcorp.com, 1 +satania.moe, 1 +satanindito.tk, 1 +satanspowers.tk, 1 +satario.vn, 1 +sateahafreedi.com, 1 +satellite-equipment.tk, 1 +satellite-prof.com, 1 +satellite-shop.tk, 1 +satellite-top.com, 1 +satellites.hopto.me, 1 +satellitetelevision.tk, 1 +satena.com, 1 +satimagingcorp.com, 1 +satinn.pl, 1 +satisfaction.su, 1 +satisfactory-calculator.com, 1 +satisperfectacollections.com, 1 +sativatunja.com, 1 +satmd.de, 1 +satoshibattles.com, 1 +satoshilabs.com, 1 +satoshinumbers.com, 1 +satpersian.tk, 1 +satplay.host, 1 +satramana.org, 1 +satserwis.xyz, 1 +satsukii.moe, 1 +satsumi.tk, 1 +sattamatka420.mobi, 0 +sattaresult.in, 1 +sattaresult.net, 1 +saturdayenterprises.ga, 1 +satyamshivamsundaram.in, 1 +sauber.dk, 1 +saucelabs.com, 1 +saudeealimentos.com, 1 +saudeintimadamulher.com.br, 1 +saudenoclique.com.br, 1 +saudiglasses.com, 1 +sauenytt.no, 1 +sauerbrey.eu, 1 +sauerland-rundflug.de, 1 +sauerland-schnittgruen.de, 1 +saul-eslake.com, 1 +saulchristie.com, 1 +saulsplace.com, 1 +saulsplacehealth.com, 1 +saulsplacewebdesign.com, 1 +saultdefencelaw.ca, 1 +saulvanderbijl.com, 1 +saumon-de-france.com, 0 +saumon-france.com, 0 +saumondefrance.fr, 0 +saumonfrance.fr, 0 +sauna.re, 1 +saunafahrten.ch, 1 +saunahats.eu, 1 +saunas.fr, 1 +saunatime.jp, 1 +saurel.me, 1 +saurusly.com, 1 +sauvagebridge.nl, 1 +sauve-tes-euros.com, 1 +savaari.com, 1 +savage-harmony.tk, 1 +savagecore.eu, 1 +savageorgiev.com, 1 +savanna.io, 1 +savannahhappycats.com, 1 +savantic.io, 1 +savatha.tk, 1 +savbus.com, 1 +savbus.net, 1 +savbus.ws, 1 +savchenko.net, 1 +save-me-aachen.de, 1 +save-me-koeln.de, 1 +savebees.org, 1 +savebt.net, 1 +saveoney.ca, 1 +saveora.com, 1 +saveora.shop, 1 +savestatecentral.tk, 1 +savethedogfishfoundation.org, 1 +savetheinternet.eu, 1 +savetomp3.net, 1 +saveusfromavril.tk, 1 +savewildcats.eu, 1 +savewildcats.foundation, 1 +savewildcats.life, 1 +savewithtrove.com, 0 +saveworldpets.ga, 1 +savic.com, 0 +saviezvousque.net, 1 +savilleassessment.com, 1 +savin.ga, 1 +savinggoliath.com, 1 +savingsbondwizard.gov, 1 +savingsoftheyear.com, 1 +savingsomegreen.com, 1 +savoir.fr, 1 +savonsuuntaporaus.fi, 1 +saw249.de, 1 +sawiday.at, 1 +sawiday.be, 1 +sawiday.com, 1 +sawiday.cz, 1 +sawiday.de, 1 +sawiday.es, 1 +sawiday.fi, 1 +sawiday.fr, 1 +sawiday.it, 1 +sawiday.nl, 1 +sawiday.pl, 1 +sawiday.se, 1 +sawiday.work, 1 +sawyerroofing.com, 1 +saxeandthecity.com, 1 +saxis.dk, 1 +saxobroko.com, 1 +saxobroko.gq, 1 +saxojoe.co.uk, 1 +saxojoe.de, 1 +saxol-group.com, 1 +saxoncreative.com, 1 +saxonsink.com, 1 +saxopholis.com, 1 +saxophone.tk, 1 +saxotex.de, 1 +say-it-loud.com, 1 +saybecraft.ru, 1 +sayeghonline.com, 1 +saygoodbyetoie.com, 1 +sayilarmuhendislik.com, 1 +sayprepay.com, 1 +sayrodigital.com, 1 +says.lol, 1 +sayura.net, 1 +sayver22.com, 1 +saz.sh, 1 +saznworld.com, 1 +sazuz.cz, 1 +sb-graph.com, 1 +sb-group.dk, 1 +sb-sd.org, 1 +sb-tuning.ru, 1 +sb-webdev.de, 1 +sb.im, 1 +sb.sb, 1 +sb0.io, 1 +sbabeshin.tk, 1 +sbanken.no, 1 +sbaten.nl, 1 +sbblog.cn, 1 +sbbz-bad-wurzach.de, 1 +sbcargo.com, 1 +sbconstrucciones.com, 1 +sber.us, 1 +sberbank.ch, 1 +sbercontactmonitoring.ru, 1 +sberna-fotofast.cz, 1 +sbetinsiders.com, 1 +sbf888.com, 1 +sbgroup.dk, 1 +sbiewald.de, 1 +sbir.gov, 1 +sbirwot.xyz, 1 +sbit.com.br, 1 +sbivc.jp, 1 +sbl01.com, 1 +sbl250.com, 1 +sbli-webhook.herokuapp.com, 1 +sbm.cloud, 1 +sbmenedzsment.hu, 1 +sbmsite.cf, 1 +sbmsitelist.ml, 1 +sbmsitelist.tk, 1 +sbmt.cc, 1 +sbodewissel.tk, 1 +sborka.ml, 1 +sbox-servers.com, 1 +sbpropman.co.uk, 1 +sbrouwer.org, 1 +sbrownbourne.com, 0 +sbsavings.bank, 1 +sbscyber.com, 1 +sbsrv.ml, 1 +sbssoft.ru, 1 +sbst.gov, 1 +sbstattoo.com, 1 +sbwebshops.nl, 1 +sc-artworks.co.uk, 0 +sc019.com, 1 +sc5.jp, 1 +scabieslice.com, 1 +scaffalature.roma.it, 1 +scaffoldhireeastrand.co.za, 1 +scaffoldhiremidrand.co.za, 1 +scaffoldhirerandburg.co.za, 1 +scaffoldhiresandton.co.za, 1 +scaffoldingsolutions.com, 1 +scag9.com, 1 +scai.org, 1 +scala.click, 1 +scalaire.com, 1 +scalaire.fr, 1 +scale.milano.it, 1 +scale.roma.it, 1 +scalemodeling.tk, 1 +scalesbiolab.com, 1 +scaling.solutions, 0 +scalive.tv, 1 +scallywagsbouncycastles.co.uk, 1 +scallywagskids.co.uk, 1 +scalpel.com, 1 +scamadviser.com, 1 +scamblockplus.org, 1 +scambusters.club, 1 +scamtested.com, 1 +scan.co.uk, 1 +scan.computer, 1 +scanamed.tk, 1 +scanbetting.ga, 1 +scandalindo.ml, 1 +scandalpunk.tk, 1 +scandicom.fi, 1 +scandinavia.dating, 1 +scandinavia.ga, 1 +scandinaviancorner.tk, 1 +scaner.ga, 1 +scangeo.net, 1 +scanmailx.com, 1 +scanmy.email, 1 +scanpassword.com, 1 +scanpay.dk, 1 +scanutracker.com, 1 +scanyachat.cf, 1 +scarabcoder.com, 1 +scaracloud.ddns.net, 1 +scarafaggio.it, 1 +scarboroughscrapcars.com, 1 +scardracs.blog, 1 +scarecrow-cn.com, 1 +scaricamusica.tk, 1 +scarinex.tk, 1 +scartazzini.com, 1 +scatgirls.net, 1 +scatsbouncingcastles.ie, 1 +scatteredcode.net, 1 +scatters.com, 1 +scatterscasino.com, 1 +scavalentenx.duckdns.org, 1 +scavalentewp.duckdns.org, 1 +scavenged.ga, 1 +scbdh.org, 1 +sccd.co.uk, 1 +sccoaching.io, 1 +scde.ventures, 1 +sceenfox.de, 1 +scelec.com.au, 1 +scenari-community.org, 1 +scenari.eu, 1 +scenari.ovh, 1 +scenariossecuritygroup.com, 1 +scenastu.pl, 1 +scene.mx, 1 +scenester.tv, 0 +scenetv.ga, 1 +scenicbyways.info, 1 +scepticism.com, 1 +sceventures.com, 1 +scevity.com, 1 +scfpensante.ca, 1 +sch44r0n.de, 1 +sch5-gusev.ru, 1 +schaafenstrasse.koeln, 1 +schaatsenenskeelers.nl, 1 +schachburg.de, 1 +schack.dk, 1 +schadevergoedingen.eu, 1 +schaffensdrang.at, 1 +schallert.com, 0 +schambereich.org, 1 +schamlosharmlos.de, 1 +schaper-sport.com, 1 +schastie.ml, 1 +schat.top, 1 +schatzibaers.de, 1 +schauraum.tk, 1 +schausteller.de, 1 +schawe.me, 1 +schbebtv.fr, 1 +scheduleme.io, 1 +scheervergelijker.nl, 1 +schefczyk.com, 1 +schefczyk.de, 1 +schefczyk.eu, 1 +schefczyk.net, 1 +scheidingspuntlansingerland.nl, 1 +scheidsrechtersinfo.nl, 1 +scheinerhaus.at, 1 +scheinlichter.de, 1 +scheldestromen.nl, 1 +schelkovo.tk, 1 +schellebelle.tk, 1 +schellenberger-brushes.com, 1 +schellenberger.biz, 1 +schellevis.net, 0 +schemingmind.com, 1 +schenkel.tk, 1 +schenkelimoveis.com.br, 1 +schenkes.de, 0 +scherfke.de, 1 +schermkapot.nl, 1 +scheuchenstuel.at, 1 +schgroup.com, 1 +schiau.co, 1 +schiavaonei.tk, 1 +schielandendekrimpenerwaard.nl, 1 +schier.info, 1 +schil.li, 1 +schildbach.de, 1 +schillers-friedberg.de, 1 +schiltron.tk, 1 +schimmel-test.info, 1 +schimmelnagelspecialist.nl, 0 +schipholwatch.nl, 1 +schippendale.de, 1 +schippers-it.nl, 1 +schirmer.io, 1 +schizoids.net, 1 +schizomatrix.tk, 1 +schlachter.ca, 1 +schlaf-los.de, 1 +schlaf.guru, 1 +schlafteq.com, 1 +schlagenhauf.info, 0 +schlagma.de, 0 +schlarb.eu, 1 +schlarp.com, 1 +schlechtewitze.com, 1 +schleifenbaum.org, 1 +schlick.wedding, 1 +schlitzbergers.com, 1 +schlossereieder.at, 1 +schlossfuchs.de, 1 +schluesseldienst-berlin.de, 1 +schluesseldienst-hannover24.de, 1 +schluesseldienstzentrum.de, 1 +schluss-aus-en.de, 1 +schmaeh-coaching.ch, 1 +schmatloch.cloud, 1 +schmelzle.io, 1 +schmidthomes.com, 1 +schmidtlohwasser.de, 1 +schmidtplasticsurgery.com, 1 +schmiggywibblits.net, 1 +schmitt-etienne.fr, 1 +schmitt-max.com, 1 +schmitt.ws, 0 +schmitzvertalingen.nl, 1 +schmuggelware.de, 0 +schnapke.name, 1 +schnaube.de, 1 +schnauzer-dogs.com, 1 +schneckenhilfe.de, 0 +schnegg.name, 0 +schneidr.de, 1 +schneids.me, 1 +schnellno.de, 1 +schnitzel-und-co.de, 1 +schnouki.net, 1 +schnuckenhof-wesseloh.de, 1 +schnyder-werbung.ch, 0 +schody-rozycki.pl, 1 +schoeller.click, 1 +schoenstatt-fathers.link, 1 +schoenstatt-movement.us, 1 +schoenstatt.link, 1 +schoepski.de, 1 +schoffelcountry.com, 1 +schoknecht.net, 1 +schoknecht.one, 1 +schoko-ferien.de, 1 +schokoferien.de, 1 +schokofoto.de, 1 +schokokeks.org, 1 +schokoladensouffle.eu, 1 +scholar.group, 0 +scholar.site, 0 +scholarbaze.cf, 1 +scholarchip.com, 1 +scholareducation.tk, 1 +scholarly.com.ph, 1 +scholarly.ph, 1 +scholarnet.cn, 1 +scholarsclub.club, 1 +scholarships.link, 1 +scholarships.tech, 1 +scholarstyle.com, 0 +scholenlijst.tk, 1 +scholieren.com, 1 +schollbox.de, 0 +scholledev.com, 1 +scholohost.tk, 1 +scholtensupport.nl, 1 +scholz-kallies.de, 1 +schonstedt.com, 1 +schont.org, 1 +schonversichert.tk, 1 +school-22.tk, 1 +school-27-lpr.tk, 1 +school-33.tk, 1 +school-adventures.tk, 1 +school-project.tk, 1 +school-register.co.za, 0 +school.in.th, 1 +school16-tob.tk, 1 +school173.tk, 1 +school32.tk, 1 +school43.tk, 1 +schoolairband.fun, 1 +schoolantwoorden.tk, 1 +schoolbuddy.ch, 1 +schoolbus.at, 0 +schoolbytes.com.au, 1 +schoolbytes.education, 1 +schoolcafe.com, 1 +schooldatasquad.com, 1 +schoolheads.ph, 1 +schooli.io, 1 +schoolofphilosophy.org.au, 1 +schoolotzyv.ru, 1 +schoolroom.ga, 1 +schoolrumble.tk, 1 +schoolsafety.gov, 1 +schoolsonice.nl, 1 +schoop.me, 1 +schopenhauer-institut.de, 1 +schorel.eu, 1 +schorel.ovh, 1 +schorelweb.nl, 1 +schorers.org, 0 +schottenland.de, 1 +schoutenseo.com, 1 +schrader-institute.de, 1 +schrauger.com, 1 +schrauger.info, 1 +schrauger.net, 1 +schrauger.org, 1 +schrauger.run, 1 +schraugerrun.com, 1 +schreck-thomas.de, 1 +schreibers.ca, 1 +schreilechner.tk, 1 +schreinerei-jahreis.de, 1 +schreinerei-schweikl.de, 1 +schreinerei-schwenk.com, 1 +schritt4fit.de, 1 +schrodingersscat.com, 1 +schrodingersscat.org, 1 +schroeder-immobilien-sundern.de, 1 +schroepfi.de, 1 +schroettle.com, 1 +schrok.eu, 1 +schrolm.de, 1 +schsrch.org, 1 +schtiehve.duckdns.org, 1 +schu.be, 1 +schubergphilis.com, 1 +schubertgmbh-ingelheim.de, 1 +schubertnest.at, 1 +schuelerzeitung-ideenlos.de, 1 +schuetzen-ehrenbreitstein.de, 1 +schuhbeck.tk, 1 +schuhbedarf.de, 1 +schuhwerkstatt.at, 1 +schuhzoo.de, 1 +schulden.tk, 1 +schulderinsky.de, 1 +schule.wtf, 1 +schuler.st, 1 +schulferien.org, 1 +schulfotograf-deinfoto.ch, 1 +schull.ch, 0 +schum.world, 0 +schuman.tk, 1 +schumanandmonnet.eu, 1 +schummar.de, 0 +schunako.ch, 1 +schuppentier.org, 1 +schutterijschinveld.nl, 1 +schutz-vor-schmutz.de, 1 +schutznetze24.de, 0 +schutzwerk.com, 1 +schwabenhaus-ka.de, 1 +schwanke.in, 0 +schwano-dent.at, 1 +schwartz.pro, 1 +schwarz-gelbe-fuechse.de, 1 +schwarzegar.de, 1 +schwarzenberg.tk, 1 +schwarzer.it, 1 +schwarzer.wang, 1 +schwarzes-muenchen.de, 1 +schwarzhenri.ch, 0 +schwarztrade.cz, 1 +schwarzwald-flirt.de, 1 +schwb.nl, 1 +schwedenkiosk.de, 1 +schwedischezahnaerztin.com, 1 +schwedischezahnaerztin.de, 1 +schweingehabt.expert, 1 +schweininchen.de, 1 +schweiz-sextreffen.ch, 1 +schweizerbanken.tk, 1 +schwerkraftlabor.de, 1 +schwimmschule-kleine-fische.de, 1 +schwinabart.com, 1 +schwingen.net, 0 +schwinger.me, 1 +schwinnbike.ru, 1 +schwuppengrillen.de, 0 +sci-internet.tk, 1 +scib.tk, 1 +sciburg.com, 1 +scicomm.xyz, 1 +science-network.ch, 1 +science-questions.org, 1 +science-texts.de, 1 +science.gov, 1 +scienceasfashion.ga, 1 +sciencebase.gov, 1 +scienceminnesota.com, 1 +sciencemonster.co.uk, 1 +sciencenews.gq, 1 +scienceofpeople.com, 0 +sciencequality.tk, 1 +sciences-world.com, 1 +sciencesolutions.eu, 1 +sciencetechworld.tk, 1 +sciencetram.tk, 1 +scienceweb.tk, 1 +sciencex.com, 1 +scientia.ga, 1 +scientific-socialism.cf, 1 +scientificallytalking.com, 1 +scientificwomen.net, 1 +scif.com, 1 +scifplus.com, 1 +scifsafe.com, 1 +scigov.xyz, 1 +scijinks.gov, 1 +scindustries.it, 1 +scintilla.nl, 1 +scintillating.stream, 1 +sciotoaccounting.com, 1 +sciototownship-oh.gov, 1 +scip.ch, 1 +scislowcy.pl, 1 +scistarter.com, 1 +scitheory.com, 1 +scitopia.me, 1 +scity88.com, 1 +scjtt.fr, 1 +scm-2017.org, 1 +scoach475k.net, 1 +scohetal.de, 1 +scolasti.co, 1 +scoliosisinstitute.com, 1 +scom.org.uk, 1 +sconecloud.com, 1 +scoolcode.com, 1 +scoop6.co.uk, 1 +scoopgalleries.com, 1 +scootaloo.co.uk, 1 +scooter-experts.com, 1 +scooterinaustralia.tk, 1 +scooterservis.com, 1 +scootertechnofrance.tk, 1 +scootfleet.com, 1 +scope.studio, 1 +scopea.fr, 0 +scorb.com.br, 1 +scorobudem.ru, 1 +scorp13.com, 1 +scorpioncomputers.nl, 1 +scorpions.tk, 1 +scotbirchfield.com, 1 +scothauscounseling.com, 1 +scott.cm, 1 +scott.st, 1 +scottainslie.me.uk, 1 +scottandtammy.com, 1 +scottbot.tk, 1 +scottdunn.com, 1 +scottgalvin.com, 1 +scottgthomas.com, 1 +scotthelme.co.uk, 1 +scotthelmesucks.com, 1 +scottipc.com, 1 +scottish-fold-cats.com, 1 +scottish-paranormal.tk, 1 +scottishcca.co.uk, 1 +scottishcu.org, 1 +scottishseniorsgolf.com, 1 +scottjbeigelmemorialfund.com, 1 +scottlanderkingman.com, 1 +scottmay.id.au, 1 +scottniven.tk, 1 +scottpilgrim.tk, 1 +scottrae.me.uk, 1 +scotts-restaurant.com, 1 +scottseditaacting.com, 1 +scottshorter.com.au, 1 +scottspainting.com, 1 +scottyspot.tk, 1 +scour.cc, 1 +scourgesofcarpathia.tk, 1 +scoutbee.com, 1 +scoutbee.io, 1 +scouting-kontiki.nl, 1 +scouting-wageningen.nl, 1 +scoutingkontiki.nl, 1 +scoutingridderkerk.nl, 1 +scoutingtungelroy.nl, 1 +scoutnet.de, 1 +scoutreinosa.tk, 1 +scoutsanbartolome.tk, 1 +scoutsanpieropatti.tk, 1 +scoutsberg.be, 0 +scoutsdeldesierto.tk, 1 +scouttrails.com, 1 +scp-rustenholz-trens.notaires.fr, 1 +scp-trens.notaires.fr, 1 +scp500.com, 1 +scphotography.co.uk, 1 +scpi-is.fr, 1 +scpsecretlab.com, 1 +scpsecretlaboratory.com, 1 +scpslgame.com, 1 +scqpw.com, 1 +scra.gov, 1 +scrabble-solver.com, 1 +scrambled.online, 1 +scrambox.com, 1 +scramget.com, 1 +scramsoft.com, 1 +scrap-car-removal.ca, 1 +scrap.photos, 1 +scrap.tf, 1 +scrapbookdecorations.ga, 1 +scrapcarbrampton.ca, 1 +scrapcarremovalmississauga.ca, 1 +scrapcars.net.au, 1 +scrapmycarperth.com.au, 1 +scratch-ppp.jp, 1 +scratchbot.tk, 1 +scratchzeeland.nl, 1 +scrayos.net, 1 +screamager.tk, 1 +scredible.com, 0 +screefox.de, 1 +screen-fox.de, 1 +screen64.tk, 1 +screenart.tv, 1 +screenfax.de, 1 +screenfox.de, 1 +screenfox.eu, 1 +screenfox.info, 1 +screenfox.net, 1 +screenmachine.com, 1 +screenpublisher.com, 1 +screensizemap.com, 1 +screenwriter.tk, 1 +screenzy.io, 1 +scripo-bay.com, 1 +script.google.com, 1 +scripter.co, 1 +scriptgates.ru, 1 +scripthost.org, 1 +scriptjunkie.us, 1 +scriptline.ga, 1 +scriptmaker.tk, 1 +scriptolab.com, 1 +scriptomania.tk, 1 +scriptslug.com, 1 +scriptsrus.tk, 1 +scrod.me, 1 +scroll-to-top-button.com, 1 +scroll.in, 1 +scroollocker.tk, 1 +scruffy.ga, 1 +scruffymen.com, 1 +scrumplex.net, 1 +scrumpus.com, 1 +scrumstack.co.uk, 1 +scrutinizer.com, 1 +scryfall.com, 1 +scsd.si, 1 +scstg.net, 1 +scswam.com, 0 +sctiger.me, 1 +sctiger.men, 1 +sctiger.ml, 1 +sctm.at, 1 +sctrainingllc.com, 1 +scubadavediving.com, 1 +scubadiving-phuket.com, 1 +scubaland.hu, 1 +scul.net, 1 +sculptaestheticsclinic.co.uk, 1 +sculpture.support, 1 +sculpturesworldwide.tk, 1 +sculpturos.com, 1 +scungioborst.com, 1 +scuolaguidalame.ch, 0 +scuolamazzini.livorno.it, 1 +scuolatdm.com, 1 +scurtam.tk, 1 +scuters.club, 1 +scvoet.me, 1 +scvotes.gov, 1 +scw.nz, 1 +scwildflours.com, 1 +scwilliams.co.uk, 1 +scwilliams.uk, 1 +scylla.live, 1 +sd.af, 1 +sd4u.be, 1 +sda.one, 1 +sdare.ru, 1 +sdcardrecovery.de, 1 +sdebitati.it, 1 +sdeu.fr, 1 +sdfamilycare.org, 1 +sdg-tracker.org, 1 +sdgllc.com, 1 +sdguitdagingen.be, 1 +sdguitdagingen.gent, 1 +sdhb.cz, 1 +sdhb.eu, 1 +sdhblatnice.cz, 1 +sdhblatnice.eu, 1 +sdhda.org, 1 +sdho.org, 1 +sdipolanight.co.uk, 1 +sdis-trib.fr, 1 +sdn.cz, 1 +sdns.fr, 1 +sdocast.com, 1 +sdruzeniprovltavu.cz, 1 +sds-marburg.de, 0 +sdsi.us, 1 +sdsite.tk, 1 +sdsk.one, 1 +sdsmanagement.me, 0 +sdsmt.engineering, 1 +sduconnect.nl, 1 +sduoxminty.cn, 1 +sdut.gq, 1 +sdvigpress.org, 0 +sdxcentral.com, 1 +sdyzmun.club, 1 +se-booster.com, 1 +se-live.org, 1 +se-theories.org, 1 +se.com, 1 +se.gg, 1 +se.search.yahoo.com, 0 +se86.us, 1 +sea-airinternational.tk, 1 +sea-godzilla.com, 1 +sea-man.org, 1 +seabehind.me, 1 +seabooty.com, 1 +seabrooklocksmith.com, 1 +seachef.it, 1 +seadrive.cc, 1 +seadus.ee, 1 +seaelba.com, 1 +seaholmwines.com, 1 +sealaw.com, 1 +sealbaker.com, 1 +sealoffantasy.de, 1 +sealtitebasement.com, 1 +seamester.com, 1 +seamoo.se, 1 +sean-wright.com, 1 +seanchaidh.org, 1 +seanchristian.tk, 1 +seandawson.info, 1 +seanholcroft.co.uk, 1 +seankilgarriff.com, 1 +seanmeedevworld.com, 1 +seanrodda.com, 1 +seanstaffiery.com, 1 +search, 1 +search-documents-free-download.com, 1 +search-engine-optimization.xyz, 1 +search-job-in.com, 1 +search-one.de, 1 +search.gov, 1 +search.yahoo.com, 0 +searchable.ml, 1 +searchandfilter.com, 1 +searchcandy.nl, 1 +searchcandy.uk, 1 +searchdatalogy.com, 1 +searchenginepartner.com, 1 +searchenginereports.net, 1 +searchforbeer.com, 1 +searchfox.org, 1 +searchlight.community, 1 +searchmore.dk, 1 +searchpartners.dk, 1 +searchshops.com, 1 +searchwork.tk, 1 +searchyourdublinhome.com, 0 +searchzone.ch, 1 +seareytraining.com, 1 +searsucker.com, 1 +searx.be, 1 +searx.ca, 1 +searx.nu, 1 +searx.one, 1 +searx.pw, 1 +searx.ru, 1 +searx.run, 1 +searx.space, 1 +searx.xyz, 1 +seashkey.com, 1 +seasidestudios.co.uk, 1 +seasistent.tk, 1 +season.moe, 1 +seasons-vintage.com, 1 +seasons.nu, 0 +seaspiration.com, 1 +seatbeltpledge.com, 1 +seatinglane2u.com, 1 +seats2meet.com, 1 +seatsurfing.de, 1 +seattle-life.net, 1 +seattlebasementwaterproofers.com, 1 +seattledevicerepair.com, 1 +seattleduiattorneys.com, 1 +seattlefabrication.com, 1 +seattlemesh.net, 1 +seattleprivacy.org, 1 +seattleshadeandawning.com, 1 +seattlewalkinbathtubs.com, 1 +seavancouver.com, 1 +seaview.gq, 1 +seaviewkohchang.com, 1 +seb-mgl.de, 1 +seb8iaan.com, 1 +sebald.com, 1 +sebald.org, 1 +sebandroid.com, 1 +sebar-iklan.gq, 1 +sebariklanmassal.gq, 1 +sebarin.tk, 1 +sebastiaandouma.co.uk, 1 +sebastiaandouma.com, 1 +sebastiaanwijnimport.nl, 1 +sebastian-bravo.com, 1 +sebastian-haeutle.de, 1 +sebastian-janich.de, 1 +sebastian-kraus.me, 1 +sebastian-kuhnert.de, 1 +sebastian-lutsch.de, 1 +sebastian-walla.com, 1 +sebastianblade.com, 1 +sebastianboegl.de, 1 +sebastianhofmann.legal, 1 +sebastianjaworecki.tk, 1 +sebastiantroncoso.tk, 1 +sebastianungureanu.com, 1 +sebastiaperis.com, 1 +sebastien-meric.com, 1 +sebasveeke.nl, 1 +sebeobrana.ml, 1 +sebepoznani.eu, 1 +seberova.cz, 1 +sebi.org, 1 +sebjacobs.com, 1 +seblod.com, 1 +seboluo.com, 1 +seboreia.tk, 1 +sebster.com, 1 +seby.io, 1 +sec-mails.de, 1 +sec-research.com, 1 +sec-wiki.com, 1 +sec.fish, 0 +sec.gd, 1 +sec.gov, 1 +sec30.com, 1 +sec3ure.co.uk, 1 +sec44.com, 0 +sec44.net, 0 +sec44.org, 0 +sec455.com, 1 +sec530.com, 1 +secapp.fi, 1 +secard.cc, 1 +secard.me, 1 +secctexasgiving.org, 0 +secfish.com, 0 +secfish.net, 0 +secgui.de, 1 +sech.me, 1 +sechat.one, 1 +sechssiwwe.de, 1 +secinto.at, 1 +secinto.com, 1 +secitem.de, 1 +seclimax.site, 1 +seclimax7.pw, 1 +secluded.site, 1 +secnews.gr, 1 +secomo.org, 1 +second-life-partner-ichien.com, 1 +secondchancejobsforfelons.com, 1 +secondmileservice.com, 1 +secondnature.bio, 1 +seconfig.sytes.net, 1 +secong.tk, 1 +secopsolution.com, 1 +secoseal.de, 1 +secpatrol.de, 1 +secpoc.online, 1 +secrecion.com, 1 +secret-queen.ga, 1 +secret-queen.ml, 1 +secretagentclub.tk, 1 +secretar.is, 1 +secretary-schools.com, 1 +secretdeals.ga, 1 +secrethub.io, 1 +secretimports.com.br, 1 +secretmolodosti.ga, 1 +secretmolodosti.ml, 1 +secretmolodosti.tk, 1 +secretofanah.com, 1 +secretosbolivia.tk, 1 +secretpanties.com, 1 +secretpigeon.com, 1 +secrets-marketing.tk, 1 +secretsauceangel.com, 1 +secretsdujeu.com, 1 +secretserveronline.com, 1 +secretshoppermall.com, 1 +secretstomartialarts.tk, 1 +secretum.tech, 1 +secretworld.ml, 1 +secretzone.bg, 1 +secrium.io, 1 +secs.london, 1 +secta.cf, 1 +sectelligence.nl, 1 +sectember.com, 1 +sectember.events, 1 +sectest.ml, 1 +secthirty.com, 1 +sectio-aurea.org, 1 +section-31.org, 1 +section.io, 1 +section215.com, 1 +section508.gov, 0 +section77.de, 1 +sector.zone, 1 +sector5.xyz, 1 +sector7.nu, 1 +sectrans.tk, 1 +sectun.com, 1 +secumailer.com, 1 +secumailer.nl, 1 +secundity.nl, 1 +securai.de, 1 +secure-automotive-cloud.com, 1 +secure-automotive-cloud.org, 1 +secure-computing.net, 1 +secure-consult.com, 1 +secure-cooprincon.com, 1 +secure-graphic.de, 1 +secure-gw.de, 1 +secure-server-hosting.com, 1 +secure.advancepayroll.com.au, 1 +secure.facebook.com, 0 +securecheck360.com, 1 +securecloudplatform.nl, 1 +secureddocumentshredding.com, 1 +securedrop.org, 1 +secureenduserconnection.se, 1 +secureesolutions.com, 1 +securefiletransfer.nl, 1 +securegovernment.us, 1 +secureheaders.com, 1 +securehealth.care, 1 +securehugs.com, 1 +secureim.de, 1 +secureinfo.pl, 1 +securejabber.me, 1 +securelect-inspection.com, 1 +securemailbox.com, 1 +securemantra.net, 1 +securemessage.nl, 1 +securemy.website, 1 +securenets.nl, 1 +secureobscure.com, 1 +secureonline.co, 1 +secureover.com, 1 +secureprivacy101.org, 1 +securerepository.net, 1 +securesense.nl, 1 +securesite.azurewebsites.net, 1 +securesuite.co.uk, 1 +securesystems.de, 1 +securethe.news, 1 +securetrustbank.com, 1 +securevideo.com, 1 +securewebcomputing.com, 1 +secureworks.com, 1 +secureyourerp.nl, 1 +securi-tay.co.uk, 1 +securify.nl, 1 +securipy.com, 1 +securist.nl, 1 +securitelandry.com, 1 +security-24-7.com, 1 +security-brokers.com, 1 +security-courses.online, 1 +security-systems.nl, 1 +security.gives, 1 +security.golf, 1 +security.google.com, 1 +security.pl, 1 +security.xn--q9jyb4c, 1 +security201.co.uk, 1 +security201.com, 1 +securityaware.me, 1 +securityblues.co.uk, 0 +securitybrief.asia, 1 +securitybrief.co.nz, 1 +securitybrief.com.au, 1 +securitybrief.eu, 1 +securitybsides.pl, 0 +securitydriver.com, 0 +securityescrownews.com, 1 +securityfest.com, 1 +securitygladiators.com, 1 +securityhandbook.cz, 1 +securityheaders.com, 1 +securityheaders.io, 1 +securityheaders.nl, 1 +securityindicators.com, 1 +securitykey.co, 1 +securitymap.wiki, 1 +securitypluspro.com, 1 +securityprimes.in, 1 +securitypuppy.com, 1 +securitysense.co.uk, 1 +securitysnobs.com, 0 +securitysoapbox.com, 1 +securitystreak.com, 1 +securitytalk.pl, 1 +securitytestfan.gov, 1 +securitytrails.com, 1 +securitywatch.co.nz, 1 +securitywithnick.com, 1 +securitywithoutborders.org, 1 +securix.hk, 1 +securl.chat, 1 +securl.link, 1 +securocloud.com, 1 +securon.io, 1 +securoswiss.ch, 1 +securot.eu, 1 +securview.ch, 0 +secutorcloud.com, 1 +secutrans.com, 1 +secuvera.de, 0 +secvault.io, 0 +secwall.me, 1 +secwise.nl, 0 +secyourity.se, 1 +sedico.mx, 1 +sedirector.net, 1 +seditious.games, 1 +sedkisghairi.com, 0 +sedlakovalegal.com, 1 +sedlex.fr, 1 +sedmicka.sk, 0 +sedoexpert.nl, 1 +sedoexperts.nl, 1 +see.asso.fr, 1 +see.wtf, 1 +seearmenia.tk, 1 +seedandleisure.co.uk, 1 +seedboite.ovh, 1 +seedbox.fr, 1 +seedcoworking.es, 1 +seedisclaimers.com, 1 +seedno.de, 1 +seednode.co, 1 +seedspark.com, 1 +seehimnaked.com, 0 +seehisnudes.com, 0 +seeinred.tk, 1 +seekfirstthekingdom.ca, 1 +seeks.ru, 1 +seeksupply.ga, 1 +seekweb.com, 1 +seeme.ai, 1 +seemeagain.com, 1 +seemomclick.com, 1 +seemyreality.tk, 1 +seeonce.co, 1 +seerainer.com, 1 +seestersmexicancantina.com, 1 +seesuite.com, 0 +seetheprogress.com, 1 +seetheprogress.de, 1 +seetheprogress.eu, 1 +seetheprogress.net, 1 +seetheprogress.org, 1 +seewang.me, 1 +seewhatididhere.com, 1 +seewines.com, 1 +seeworkdone.com, 1 +seexw.com, 1 +sefor.nc, 1 +sefru.de, 1 +seg-leipzig.org, 1 +seg-sys.com, 1 +segaretro.org, 1 +segdomedia.com, 1 +segenstore.com, 1 +segmentify.com, 1 +segmetic.com, 1 +segnalabullo.com, 1 +segnalabullo.eu, 1 +segnalabullo.it, 1 +segnidisegni.eu, 1 +segtronix.com, 1 +seguidores.com.br, 1 +segulink.com, 1 +segurancaresidencialbh.com.br, 1 +segurdatacr.com, 1 +seguridadconsumidor.gov, 1 +seguridadsistem.tech, 1 +seguridadsistemtienda.tech, 1 +seguridadyredes.tk, 1 +segurosdesaluddominicanos.com, 1 +segurosmaurobracchieri.com, 1 +segurosocial.gov, 0 +segurosprivados.net, 1 +segurosproteccion.com, 1 +seguroviagem.srv.br, 0 +sehat-solusi-makmur.com, 1 +sehd.top, 1 +sehnenweh.org, 1 +sei-yu.net, 1 +seibert.ninja, 1 +seibu-kikaku.co.jp, 1 +seicochimica.it, 1 +seida.at, 1 +seidel-immobilienberatung.de, 1 +seifried.org, 1 +seikatu-navi.com, 1 +seiko-dojo.com, 1 +seilgold.de, 1 +seincojavea.es, 1 +seinfeldquote.com, 1 +seira.tk, 1 +seirdy.one, 1 +seirei.ne.jp, 1 +seiryokuzai-ch.com, 1 +seisansei.net, 1 +seishinan.xyz, 1 +seishinchuo-lawoffice.com, 1 +seismas1.com, 1 +seitai-nabejun.jp, 1 +seitai-taiyou.com, 1 +seitaisalon-ti-da-ouji.com, 1 +seitenwaelzer.de, 1 +sejageek.com, 1 +sek.ai, 1 +sekainokokki.jp, 1 +sekfung.me, 1 +sekisonn.com, 1 +sekko2.jp, 1 +sekkom.com, 1 +sekoia.io, 1 +sekoya.org, 1 +sekreti-biznesa.cf, 1 +sekshikayeler.tk, 1 +sektor-news.tk, 1 +sektor.ro, 1 +sektor.tech, 1 +sektor41.com, 1 +sekurak.pl, 1 +sekusi-tochiki.tk, 1 +selaluberkah.com, 1 +selber-coden.de, 1 +selbys.net.au, 1 +selco-himejiminami.com, 1 +selcusters.nl, 1 +seldax.com, 1 +selea.se, 1 +selebrita.ml, 1 +selected-properties.com, 0 +selectel.com, 0 +selectel.ru, 1 +selectionengine.ca, 1 +selectionengine.com, 1 +selectionengine.net, 1 +selectionengine.org, 1 +selectiveasia.com, 1 +selectsplat.com, 1 +selegiline.com, 1 +selekzo.com, 1 +selena-armavir.ml, 1 +selenapelletier.tk, 1 +seleondar.ru, 1 +selezionebarbrboguaccero.ga, 1 +self-business.tk, 1 +self-evident.org, 1 +self-signed.com, 1 +selfassess.govt.nz, 1 +selfbattery.ga, 1 +selfcaregate.com, 1 +selfdevelopment.com.au, 1 +selfemployed.ga, 1 +selfhosted.eu, 1 +selfici.com, 1 +selfici.cz, 1 +selfiehome.cz, 1 +selfishness.com, 1 +selfloath.in, 1 +selfmade4u.de, 1 +selfrealize.ga, 1 +selfretire.cf, 1 +selfserverx.com, 0 +selftech.tk, 1 +selfycheck.it, 1 +selimcerkezi.tk, 1 +selkiemckatrick.com, 1 +sellajoch.com, 1 +sellbit.io, 1 +sellcoins.top, 1 +selldone.com, 1 +selldorado.com, 1 +selldurango.com, 1 +seller.diamonds, 1 +sellersmart1.com, 1 +sellguard.pl, 1 +sellingsherpa.com, 1 +sellmymobile.com, 1 +sello.com, 1 +sellocdn.com, 1 +sellorbuy.uk, 1 +sellorbuy.us, 1 +sellsmartwatches.tk, 1 +selltous.com.au, 1 +sellwithsquare.com, 1 +selo-cer.tk, 1 +seloc.org, 1 +selsovet56.tk, 1 +seltendoof.de, 1 +semacode.com, 1 +semaflex.it, 1 +semantica.cz, 0 +semao.org, 1 +semaphore-studios.com, 1 +sembosihosting.tk, 1 +sembska.de, 1 +sembyotic.com, 1 +semenov.ml, 1 +semenov.su, 1 +sementes.gratis, 1 +semesur.com, 1 +semi.social, 1 +semianalog.com, 1 +semicvetik.tk, 1 +semillainfinita.com, 1 +semillasdelucha.com, 1 +seminariruum.ee, 1 +seminarraum-isny.de, 1 +seminolecountyoklahoma.gov, 1 +semiocast.com, 1 +semiotical.com, 0 +semiotika.tk, 1 +semira.tk, 1 +semirben.de, 1 +semiread.com, 1 +semiretire.ga, 1 +semiweb.ca, 1 +semmuhely.tk, 1 +semobr.cf, 1 +semops.gq, 1 +semox.de, 1 +semplicementelight.com, 1 +sempoctet.ca, 1 +semps-2fa.de, 1 +semps-threema.de, 1 +semps.de, 1 +semrush.com, 1 +semsec.net, 1 +semtinde.com, 1 +semyonov.su, 1 +semyonov.us, 1 +sen.bo, 1 +senaofertaeducativa.com, 1 +senarea.nl, 1 +senarin.kr, 1 +senarist.tk, 1 +senarius.de, 1 +sendai-cc.jp, 1 +sendai-cdc.com, 1 +sendai-cooking.com, 1 +sendai-ctr.com, 1 +sendai-himawari.jp, 1 +sendai-rc.com, 1 +sendai-sisters.com, 1 +sendai-sougou.com, 1 +sendai-works.com, 1 +sendaimori.com, 1 +sendaiouji.com, 1 +sendbox.cz, 1 +sendc.at, 1 +sendcat.com, 1 +sender.services, 1 +senderismoinfantil.tk, 1 +sendigperu.com, 1 +sendingbee.com, 1 +senditvia.email, 1 +sendmeback.de, 0 +sendonce.io, 1 +sendpulse.com, 1 +sendthisfile.com, 1 +sendtrix.nl, 1 +sendzik.eu, 1 +senego.com, 1 +senekalstorageman.co.za, 1 +senergiya.tk, 1 +senergyconsultants.com, 1 +senhorst.com, 1 +senhost.tk, 1 +senior-sigan.ml, 1 +seniorchoicesonline.com, 1 +seniorem.eu, 1 +seniorhomexchange.com, 1 +seniorhost.net, 1 +seniorinhomecare.com, 1 +seniormanager.cz, 1 +seniors.singles, 1 +senjukannonreiki.com, 1 +senlife.cz, 1 +senmendai-reform.com, 1 +senneeeraerts.be, 1 +senobio.com, 1 +senoctarsoft.tk, 1 +senok.ml, 1 +senooken.jp, 1 +senork.de, 1 +senpromotion.com, 1 +sens2lavie.com, 1 +sense.hamburg, 1 +sensebridge.net, 1 +senseful-online.eu, 0 +senseful-online.info, 1 +senseiclassroom.tk, 1 +senseict.com.au, 1 +sensepixel.com, 1 +senshot.com, 1 +senshudo.tv, 1 +sensitidolls.com, 1 +sensivo.eu, 1 +sensoft-int.com, 1 +sensoft-int.net, 1 +sensoft-int.org, 1 +sensor-dream.ru, 0 +sensorsoft-waterontharder.nl, 1 +sensorville.com.br, 1 +sensound.ml, 1 +sensualgoth.com, 1 +sensualism.com, 1 +sentandsecure.com, 1 +sentencing.net, 1 +sentenza.tk, 1 +senterada.tk, 1 +sentic.info, 1 +sentidosdelatierra.org, 1 +sentiments.io, 1 +sentinel.gov, 1 +sentinelnet.tk, 1 +sentinelpeakmedia.com, 1 +sentinelproject.io, 1 +sentirmebien.org, 1 +sentitvia.email, 1 +sentmail.ga, 1 +sentrafield.com, 1 +sentralshop.com, 1 +sentry.io, 1 +sentry.nu, 1 +sentrybay.com, 1 +sentworks.com, 1 +senu.pro, 1 +senzaparole.de, 1 +seo-analyse.com, 1 +seo-blog12.tk, 1 +seo-dr-it.com, 0 +seo-en-barcelona.es, 1 +seo-forum.nu, 0 +seo-linz.at, 1 +seo-obmen.tk, 1 +seo-phpbb.cf, 1 +seo-piar.tk, 1 +seo-portal.de, 1 +seo-portal.tk, 1 +seo-reality.cf, 1 +seo-reklama.ml, 1 +seo-website.ru, 1 +seo.london, 1 +seo.services, 1 +seoankara.name.tr, 1 +seoarchive.org, 1 +seoargentina.com.ar, 1 +seobase.pro, 0 +seobgynpc.com, 1 +seoblogs.cf, 1 +seobook2015.gq, 1 +seobutler.com, 1 +seoclubs.tk, 1 +seocluj.com, 1 +seocompliant.com, 1 +seocontents24.tk, 1 +seocraft.me, 1 +seocreator-blog24.tk, 1 +seodayo.com, 1 +seodefinitivo.com, 1 +seodrug.tk, 1 +seoenmexico.com.mx, 1 +seoexpert.com.br, 1 +seogeek.nl, 1 +seogeky.com, 1 +seogood.cf, 1 +seohackers.fr, 1 +seohouston.com, 1 +seoified.com, 1 +seoinc.com, 1 +seojaguar.tk, 1 +seojames.com, 1 +seokatka.tk, 1 +seolabuitest.azurewebsites.net, 1 +seolib.org, 1 +seoline.cf, 1 +seolister.cf, 1 +seolisting.cf, 1 +seolisting.tk, 1 +seolord.cf, 1 +seomag.tk, 1 +seomarketing.bg, 1 +seomaton.com, 1 +seomaton.org, 1 +seomedo.com, 1 +seomen.biz, 1 +seomik.dk, 1 +seomoft.com, 1 +seon.me, 1 +seonurse.com, 1 +seoonline.cf, 1 +seoonlinejaipur.tk, 1 +seopiar.tk, 1 +seopost.ga, 1 +seoprnews.cf, 1 +seopromotion.tk, 1 +seoquake.com, 1 +seoquero.com, 1 +seoranker.tk, 1 +seorus.cf, 1 +seorus.ml, 1 +seoruse.com, 1 +seos.ga, 1 +seoscan.ga, 1 +seoscribe.net, 1 +seosearch.org, 1 +seoserfing.tk, 1 +seoshanti.ru, 1 +seoshnik.tk, 1 +seosmart.gq, 1 +seosof.com, 1 +seosos.gq, 1 +seospecialist.ma, 1 +seosprint.gq, 1 +seostrit.cf, 1 +seostrit.tk, 1 +seoteam.tk, 1 +seotip.top, 1 +seotoolset.tk, 1 +seotutorials32.tk, 1 +seoulartcollective.tk, 1 +seovision.se, 1 +seovisits.tk, 1 +seoviziti50.tk, 1 +seowebexpert.co.uk, 0 +seowordpress.pl, 1 +seowork.tk, 1 +seoz.com.au, 1 +seozel.tk, 1 +sepakbola.id, 1 +separacioniglesiaestado.tk, 1 +sepenggal.info, 1 +seproco.com, 0 +septakkordeon.de, 1 +septentrionalist.org, 1 +septfinance.ch, 0 +septicrepairspecialists.com, 1 +septonol.tk, 1 +septs.blog, 1 +sequachee.com, 1 +sequatchiecounty-tn.gov, 1 +sequatchiecountytn.gov, 1 +sequencing.com, 1 +sequitur.tech, 1 +sequiturs.com, 1 +ser-it.pl, 1 +sera.jp, 1 +serafin.tech, 1 +seraph.tokyo, 1 +serasa.com.br, 1 +serban.ro, 1 +serbanpaun.ro, 1 +serbiaonline.tk, 1 +sercasindustry.tk, 1 +sercasystems.com, 1 +serdarwork.com, 1 +sereema.com, 1 +serele.fr, 1 +serenaden.at, 1 +serenascreations.com, 1 +serenata.tk, 1 +serenavilage.net, 1 +serenavillage.net, 1 +serenavillageresidence.com, 1 +serendeputy.com, 1 +serenitygwinnett.com, 1 +serf.io, 1 +serfas.gr, 1 +sergal.club, 1 +sergal.de, 1 +sergal.gay, 1 +serge-design.ch, 1 +sergeemond.ca, 1 +sergefonville.nl, 1 +sergen.tk, 1 +sergeyburov.tk, 1 +sergeyesenin.tk, 1 +sergicoll.cat, 1 +sergije-stanic.me, 1 +sergio-rivero.tk, 1 +sergiozygmunt.com, 1 +sergivb01.me, 0 +serhinco.com, 1 +serial-kinder.tk, 1 +serialize.gq, 1 +seriesdatv.pt, 1 +seriesfeed.com, 1 +seriesgratis.tk, 1 +serigraphs.co.uk, 1 +serinamusic.com, 1 +seriousaboutsecurity.com, 1 +seriousclimbing.com, 1 +seriouss.am, 1 +serioussam.ml, 1 +serkanceyhan.com, 1 +serkaneles.com, 1 +serkanyarbas.com, 1 +serkanyarbas.com.tr, 1 +sermasvital.com, 1 +sernate.com, 1 +seroquel50mg.tk, 1 +seroquelonline.tk, 1 +serotiuk.com, 0 +serpenteq.com, 1 +serphost.ml, 1 +serpic.photo, 1 +serptoolsuite.com, 1 +serrande.roma.it, 1 +serrano-chris.ch, 0 +serrature.roma.it, 1 +sersanto.com.br, 1 +sertaobom.eco.br, 1 +sertaovivo.tk, 1 +sertasimmons.com, 1 +sertkayagroup.com, 1 +seru.eu, 1 +serve.work, 1 +serveatechnologies.com, 1 +servecrypt.com, 1 +servecrypt.net, 1 +servecrypt.ru, 1 +servepublic.com, 1 +servepublic.org, 1 +server-bg.net, 1 +server-check.co.uk, 1 +server-daten.de, 1 +server-essentials.com, 1 +server72a.ddns.net, 1 +server92.eu, 1 +server92.tk, 1 +serveradium.com, 1 +serveradmin.ovh, 1 +serveradminz.com, 1 +serverco.com, 1 +serverd.de, 1 +serverdensity.io, 1 +serverexpose.com, 1 +serverfix.net, 1 +serverfrog.de, 1 +serverhost.no, 1 +serverhunter.com, 1 +serverka.tk, 1 +serverlauget.no, 1 +serverlog.net, 1 +servermacher.de, 1 +servermaster.sk, 1 +serverninja.tk, 1 +serveroffline.net, 1 +serverpedia.de, 1 +serverportugal.com, 1 +serversfrom.space, 1 +serverstatus.tk, 1 +serverstuff.info, 1 +serversuit.com, 1 +servertastic.com, 1 +servertutorial.eu, 1 +serveru.us, 1 +servetten-groothandel.nl, 1 +serveur.nl, 1 +serveursminecraft.org, 1 +servfefe.com, 1 +servgate.jp, 1 +servi-tek.net, 1 +service-centre.cf, 1 +service-wueste-vodafone.tk, 1 +service.gov.uk, 1 +serviceair.com.ar, 1 +servicebeaute.fr, 1 +serviceboss.de, 1 +servicecentreperth.com.au, 1 +serviceflow.co.za, 1 +serviceinconstanta.ro, 1 +servicemagicusa.com, 1 +servicemaxgreencleaning.com, 1 +servicemembers.gov, 1 +serviceparts.nl, 1 +serviceslotenmaker.nl, 0 +servicestechnologiquesam.ca, 1 +servicesurgence24h.ca, 1 +servicevie.com, 1 +serviciales.com, 1 +servicii-funerare.tk, 1 +serviciodebarralibreparaeventos.com, 1 +servicios-electricos.com, 1 +serviciosparaconsorcio.com, 1 +servida.ch, 1 +servietten-grosshandel.at, 1 +servietten-grosshandel.be, 1 +servietten-grosshandel.ch, 1 +servietten-grosshandel.de, 1 +serviettes-et-plus.com, 1 +servilletas-de-papel.es, 1 +servilletas-de-papel.mx, 1 +servingbaby.com, 1 +servingroddick.tk, 1 +servingupsouthern.com, 1 +servis-azd.cz, 1 +servisna.com, 1 +servispocitacov.com, 1 +servitecsm.com, 1 +servitel.ga, 1 +servitor.cf, 1 +serviziourgente.it, 1 +servmaslt.com, 1 +servo.org, 1 +servonline.de, 1 +servtraq-staging.azurewebsites.net, 1 +servtraqazure.com, 1 +servus.ca, 1 +servx.org, 1 +serw.org, 1 +serwetki-papierowe.pl, 1 +serwis-telewizorow.pl, 1 +serwis-wroclaw.pl, 1 +serwistomy.pl, 1 +seryovpn.com, 1 +seryox.com, 1 +ses-egy.com, 1 +sesam-biotech.com, 1 +sesamomusical.tk, 1 +sescoen.tk, 1 +sesenaonline.tk, 1 +sesrdcem.cz, 1 +sessile-oak.co.uk, 1 +session.bbc.co.uk, 1 +session.bbc.com, 1 +sessionslogning.dk, 1 +sestry.tk, 1 +setasgourmet.es, 1 +seteampty.net, 1 +setenforce.one, 1 +setesat.com.br, 1 +setevik.tk, 1 +sethcaplan.com, 1 +sethcorker.com, 1 +sethjust.com, 1 +sethlmatarassomd.com, 1 +sethoedjo.com, 1 +sethriedel.com, 1 +sethvargo.com, 1 +seti-germany.de, 1 +seti.co.il, 1 +setin.srl, 1 +setkit.net, 1 +setmore.com, 1 +setphaserstostun.org, 0 +setptusa.com, 1 +settberg.de, 1 +setterirlandes.com.br, 1 +settimanadellascienza.it, 1 +settleapp.co, 1 +setuid.io, 1 +setuid0.kr, 1 +setuplog.io, 1 +setxrm.com, 1 +seu-emprego.com, 0 +seu.edu.sa, 1 +seucreditodigital.com.br, 1 +seutens.be, 1 +seutens.eu, 1 +seva.fashion, 1 +sevasmos.gr, 1 +sevastopol.tk, 1 +sevathian.com, 1 +seve7.com.br, 1 +seveiller-simplement.fr, 1 +seven-purple.com, 1 +seven-seas.ml, 1 +seven.social, 1 +sevenartzpublicidad.com, 1 +sevenhillsapartments.com.au, 1 +sevenicealimentos.com.br, 1 +sevenmatches.com, 1 +seventwentynine.com, 1 +sevenwizes.com, 1 +severine-trousselard.com, 1 +severing.cf, 1 +severntrentinsuranceportal.com, 1 +sevilinux.es, 1 +sevillalinces.tk, 1 +sevillanazarena.tk, 1 +sevinci.ch, 1 +sevocomm.com, 1 +sevsey.ru, 1 +sevwebdesign.com, 1 +sewa.nu, 1 +sewafineseam.com, 1 +sewamobilperdana.com, 0 +sewatec.com, 1 +sewavillamurah.tk, 1 +sewfarsewgood.co.uk, 1 +sewfarsewgood.uk, 1 +sewing-machines.com.ua, 1 +sewing-world.ru, 1 +sewinginsight.com, 1 +sewoo.co.uk, 1 +seworld.ml, 1 +sex-education.com, 1 +sex-sex-cam.com, 1 +sex5.com, 1 +sexaki.com, 1 +sexandthecitty.tk, 1 +sexar.info, 1 +sexara.co, 1 +sexdocka.nu, 1 +sexedquickies.com, 1 +sexedrescue.com, 1 +sexflare.net, 1 +sexgarage.de, 1 +sexhab.guru, 1 +sexi-model.ru, 1 +sexminister.tk, 1 +sexmobil.de, 1 +sexocomgravidas.com, 1 +sexologist.cf, 1 +sexonv.mobi, 1 +sexoyrelax.com, 1 +sexpay.net, 1 +sexpdf.com, 1 +sexruby.com, 1 +sexshopfacil.com.br, 1 +sexshopnet.com.br, 1 +sexswing.com, 0 +sextacy.tk, 1 +sextoysproductstore.com, 1 +sextreffendeutschland.com, 1 +sexualdiversity.org, 1 +sexvideos.tel, 1 +sexvirtualspace.com, 1 +sexy-store.nl, 1 +sexycosplay.fun, 1 +sexyfish.com, 1 +sexyfotosvandep.nl, 1 +sexyjenjen.net, 1 +sexynaty.org, 1 +sexytagram.com, 1 +seyfarth.de, 1 +seyr.it, 1 +seyr.me, 1 +seyrederiz.com, 1 +seyv.io, 1 +sezon.ua, 1 +sf3223.com, 1 +sfa.sk, 1 +sfaparish.org, 1 +sfat.llc, 1 +sfaturiit.ro, 1 +sfdev.ovh, 1 +sfeerhuisbaan.nl, 1 +sfera360.es, 1 +sfg-net.com, 1 +sfg-net.eu, 1 +sfg-net.net, 1 +sfg-net.org, 1 +sfg-nordholz.de, 1 +sfi.sh, 0 +sfile.eu, 1 +sfirat-haomer.com, 1 +sfleisure.com, 1 +sflhidta.gov, 1 +sflowanalyzer.com, 1 +sfltrends.com, 1 +sfo-fog.ch, 0 +sfpebblesstones.com, 1 +sft-framework.org, 1 +sftkey.com, 1 +sftool.gov, 1 +sfvonline.nl, 1 +sfweef.gq, 1 +sg-elektro.de, 1 +sg.search.yahoo.com, 0 +sg1.tech, 1 +sgatlantis.tk, 1 +sgb.co, 1 +sgcaccounts.co.uk, 1 +sgcy.vip, 0 +sgdementia.ca, 1 +sggame990.com, 1 +sgi.org, 1 +sgitc.de, 1 +sgj0.net, 1 +sglazov.ru, 1 +sglibellen.de, 1 +sgombero.it, 1 +sgrmreproduccionapp.azurewebsites.net, 1 +sgrossi.it, 1 +sgrub.xyz, 1 +sgs-systems.de, 1 +sgs.camera, 1 +sgs.systems, 1 +sgsmart.ru, 1 +sgsp.nl, 1 +sgtcodfish.com, 1 +sgtech.ga, 1 +sgthotshot.com, 1 +sgtsnookums.net, 1 +sgtt.ch, 0 +sguerrero.com, 1 +sgutranscripts.org, 1 +sh-heppelmann.de, 1 +sh-network.de, 1 +sh.org.sa, 1 +sh0rt.in, 1 +sh0rt.zone, 1 +sh0uld.net, 1 +sh4y.cn, 1 +sh4y.com, 1 +sh68.cc, 1 +sha.bi, 1 +sha2017.org, 1 +sha512.online, 1 +shaadithailand.com, 1 +shabashka.ml, 1 +shabiwangyou.com, 1 +shacall.com, 1 +shad.waw.pl, 1 +shade.cash, 1 +shadedesign.cz, 1 +shadefix.co.za, 1 +shademid.com, 1 +shadesofgrayadr.com, 1 +shadesofgraylaw.com, 1 +shadex.net, 1 +shadigee.org, 1 +shadikhan.tk, 1 +shadow-forum.tk, 1 +shadowcp.eu, 1 +shadowdomain.ml, 1 +shadowfight2.tk, 1 +shadowfox.tk, 1 +shadowguardian507.tk, 1 +shadowkingdomrecords.com, 1 +shadowkitsune.net, 1 +shadowlurker.com.au, 1 +shadowmorph.info, 1 +shadownet.tk, 1 +shadowping.com, 1 +shadowplus.net, 1 +shadowrocket.net, 1 +shadowsing.com, 1 +shadowsocks.com, 1 +shadowsocks.com.au, 1 +shadowsocks.com.hk, 1 +shadowsocks.fr, 0 +shadowsocks.la, 1 +shadowsocks.live, 1 +shadowsocks.se, 1 +shadowsocks.software, 1 +shadowsocks.to, 1 +shadowsproject.ru, 1 +shadowstalkers.tk, 1 +shadowvolt.net, 1 +shadwe.com, 1 +shadynook.net, 1 +shadypark.tk, 1 +shafou.net, 1 +shag-shag.ru, 1 +shahar.cc, 0 +shaharyaranjum.com, 1 +shahidafkar.tk, 1 +shahidfakih.com, 0 +shahidhashmi.net, 1 +shahinclub.com, 0 +shahpurjat.xyz, 1 +shahrsazan.tk, 1 +shahrvand.ga, 1 +shahurology.com, 1 +shahzaibm.com, 1 +shaicoleman.com, 1 +shaimensonline.com, 1 +shainessim.com, 1 +shaitan.eu, 1 +shajiangchang.cn, 1 +shakalaka.co.za, 1 +shakan.ch, 0 +shakardara.com, 1 +shaken-kyoto.jp, 1 +shaken110.com, 1 +shakerwebdesign.net, 1 +shakespeareans.net, 1 +shakespearesolutions.com.au, 0 +shakespearevet.com, 1 +shakesprimer.tk, 1 +shakingthehabitual.com, 1 +shaknews.tk, 1 +shakthifacility.com, 1 +shaloc.site, 1 +shalomamuzik.tk, 1 +shalombolivia.tk, 1 +shalomcottage.tk, 1 +shalyapin.by, 1 +sham-rock.tk, 1 +shamaev.me, 1 +shamans.ga, 1 +shambala.cf, 1 +shambhu.info, 1 +shamimmedia.ir, 1 +shamiphotos.tk, 1 +shampoo63.ru, 1 +shan.io, 0 +shan.si, 1 +shanesofos.com, 0 +shanesofos.info, 0 +shanesofos.net, 0 +shanetully.com, 1 +shanevandermeer.com, 1 +shanewadleigh.com, 1 +shangobud.com, 1 +shanhay.tk, 1 +shanju.tk, 1 +shankangke.com, 1 +shanli.tk, 1 +shannapeeples.com, 1 +shanoviyam.in, 1 +shansen-online.de, 1 +shanshushu.com, 1 +shansing.cn, 1 +shansing.com, 1 +shansing.net, 1 +shansing.org, 1 +shansing.space, 1 +shanteo.com, 1 +shantitsafar.com, 1 +shanxia.com, 1 +shanxiapark.com, 1 +shaoxia.xyz, 0 +shape.pink, 1 +shapediver.com, 1 +shapin.tv, 1 +shapingthebay.com.au, 1 +sharanyamunsi.net, 1 +shard.vc, 1 +share-io.com, 1 +share.la, 1 +share2act-dev.io, 1 +share2act-test.io, 1 +share2x.com, 1 +share4brain.org, 1 +shareasale-analytics.com, 1 +sharebee.space, 1 +sharebot.ga, 1 +shareby.cam, 1 +sharedgoals.co, 1 +sharedhost.de, 1 +shareeri.com, 1 +sharefox.eu, 1 +sharefox.nl, 1 +shareiva.com, 1 +sharejoy.cn, 0 +sharekey.com, 0 +sharelinks.tk, 1 +sharelovenotsecrets.com, 1 +sharemessage.net, 1 +sharenergy.com.br, 1 +shareoffice.ch, 1 +sharepointdrive.com, 1 +sharerotic.com, 1 +sharescope.co.uk, 0 +shareselecttools.com, 1 +sharethe.link, 1 +sharetheroad.org, 1 +sharevari.com, 1 +shareworks.com, 1 +shareworx.net, 1 +sharezen.de, 0 +shariahlawcenter.com, 1 +shariahlawcenter.org, 1 +sharialawcenter.com, 1 +sharialawcenter.org, 1 +shariftown.tk, 1 +sharik-msk.ga, 1 +sharik.ml, 1 +sharing-kyoto.com, 1 +sharingcolombia.com, 1 +sharingiscaring.cc, 1 +sharingphotos.co, 0 +sharisharpe.com, 1 +shark-host.tk, 1 +shark5060.net, 1 +sharkeyscuba.com, 1 +sharking.gq, 1 +sharks.football, 1 +sharmafamily.tk, 1 +sharonsplace.biz, 1 +sharpe-practice.co.uk, 1 +sharpe.systems, 1 +sharperedge.pw, 1 +sharpreporters.com, 1 +sharpsburg-ga.gov, 1 +sharpyspawn.com, 1 +sharren.org, 1 +sharu.me, 1 +sharvey.ca, 1 +shashlik.tk, 1 +shaumine.ml, 1 +shaun.net, 1 +shaunallen.co.uk, 1 +shaunandamyswedding.com, 1 +shaunc.com, 1 +shaundanielz.com, 1 +shavegazette.com, 1 +shavingks.com, 1 +shavit.space, 1 +shavitech.com, 1 +shawcentral.ca, 0 +shawclan.id.au, 1 +shawfactor.com, 1 +shawfamily.id.au, 1 +shawiah.tk, 1 +shawnalucey.com, 1 +shawngvs.com, 1 +shawnhogan.com, 1 +shawnow.com, 1 +shawnwilkerson.com, 1 +shawnz.org, 1 +shawty.tk, 1 +shaytan.tk, 1 +shazbots.org, 1 +shazzlemd.com, 1 +shazzlepro.com, 1 +shc.gov.sa, 1 +shcode.de, 1 +shd.one, 1 +shdw.cc, 1 +she.run, 0 +she.tw, 1 +sheaf.site, 1 +shearcomfort.com, 1 +shearin.pro, 1 +shearwaterdental.com, 1 +sheaspire.com, 1 +shechipin.cf, 1 +shechipin.ga, 1 +shechipin.gq, 1 +shechipin.ml, 1 +shedrin.tk, 1 +shee.org, 1 +sheehyinfinitioftysonsparts.com, 1 +sheekdeveloper.com, 1 +sheekmedia.com, 1 +sheenveininstitutestl.com, 1 +sheepfriends.com, 1 +sheepproductions.com, 1 +sheeprock.tk, 1 +sheerchain.com, 1 +sheet.host, 1 +sheey.moe, 0 +shef.com, 1 +sheffield-wednesday-fc.tk, 1 +shefftunes.tk, 1 +shehaal.com, 1 +shehata.com, 1 +sheilasdrivingschool.com, 1 +shejumm.com, 1 +shejutu.com, 1 +shek.zone, 1 +shelbymunsch.com, 1 +sheldon.sk, 1 +shelehov.tk, 1 +shelfordsandstaplefordscouts.org.uk, 1 +shelfplanner.com, 1 +shelike.me, 1 +shellavartanian.tk, 1 +shellcon.io, 1 +shellcore.fr, 1 +shellday.cc, 1 +shelleystoybox.com, 1 +shellfire.de, 1 +shellgame.io, 1 +shelljuggler.com, 0 +shellopolis.com, 1 +shellot.com, 1 +shellphotostudio.com, 1 +shellshock.eu, 1 +shellta.com, 1 +shellta.net, 1 +shellvatore.us, 1 +shellwhite.ga, 1 +shellwhite.tk, 1 +sheltieplanet.com, 1 +sheltonvirtual.com, 1 +shelvacu.com, 1 +shemalexxxfreetube.com, 1 +shemogo.com, 1 +shemsconseils.ma, 1 +shemsharples.co.uk, 1 +shena.co.uk, 1 +shenannigans.tk, 1 +shenderman.ml, 1 +shenghaiautoparts.com, 1 +shengrenyu.com, 1 +shenpei.net, 1 +shenqi.com, 1 +shens.ai, 1 +shentengtu.idv.tw, 1 +shepherdsfriendly.co.uk, 1 +sheplus.net, 1 +sheptytsky.ga, 1 +sheraatours.com, 1 +sherbers.de, 1 +sheremetka.com, 1 +sheriffmiamicountyks.gov, 1 +sheriffpawneecountyne.gov, 1 +sheriffwashingtoncountymaine.gov, 1 +sherijames.com, 1 +shermancountyks.gov, 1 +shermanmorgan.mx, 1 +shermantank.biz, 1 +sherpa.blog, 1 +sherpnortheast.com, 1 +sherrikelley.com, 1 +sherut.net, 1 +shethbox.com, 1 +shevans.com, 1 +shevelev.design, 1 +shevet-achim.tk, 1 +shewanders.de, 1 +sheweek.ml, 1 +shft.cl, 1 +shfzzz.org, 1 +shg-pornographieabhaengigkeit.de, 0 +shgroup.xyz, 1 +shgt.jp, 1 +shgw186.com, 1 +shh-listen.com, 1 +shh.sh, 1 +shiawasedo.co.jp, 1 +shibainu.com.br, 1 +shibbydex.com, 1 +shichibukai.net, 1 +shichidadoma.ru, 1 +shico.org, 1 +shidai88.cc, 1 +shidurdan.com, 1 +shielder.it, 1 +shieldnsheath.com, 1 +shieldofachilles.in, 1 +shifaat.com, 1 +shift-record.com, 1 +shift-to.co.jp, 1 +shift.email, 1 +shiftade.band, 1 +shiftadeband.com, 1 +shiftcrypto.ch, 1 +shiftcrypto.shop, 1 +shiftcrypto.support, 1 +shiftdevices.com, 1 +shiftj.is, 1 +shiftleft.org, 1 +shiftregister.top, 1 +shiftsixth.com, 1 +shiga1.jp, 1 +shigaben.or.jp, 1 +shiganmartialarts.com, 1 +shigotoba.com, 1 +shih-tzu-dogs.com, 1 +shihabuddin.tk, 1 +shihadwiki.com, 1 +shiji.info, 1 +shijij.com, 1 +shijing.me, 1 +shikimori.org, 1 +shikiryu.com, 1 +shilled.tk, 1 +shilpaonline.tk, 1 +shima1.net, 1 +shimi.blog, 1 +shimi.guru, 1 +shimi.net, 1 +shimitower.pw, 1 +shimmy1996.com, 1 +shimo.im, 1 +shimonfly.com, 1 +shin-yo.de, 1 +shincastella.com, 1 +shindocuba.tk, 1 +shineindiarktutorial.ml, 1 +shineleds.ga, 1 +shines.ml, 1 +shinetsuamerica.com, 1 +shinetsusilicones.com, 1 +shinghoi.com, 1 +shinglereplacementlv.com, 1 +shinice.net, 1 +shining.gifts, 1 +shinko-osaka.jp, 1 +shinnyosangha.org, 0 +shinobayderm.com, 1 +shinobi-fansub.ro, 1 +shinobu.chat, 1 +shinomiya.group, 0 +shinonome-lab.eu.org, 1 +shinsandenki.com, 1 +shinsyo.com, 1 +shinta.ro, 1 +shintoism.com, 1 +shinuytodaati.co.il, 1 +shinyoko-saisyuusyou.com, 1 +shinyuu.net, 1 +shipard.com, 1 +shipard.cz, 1 +shipbuddies.com, 1 +shipcloud.io, 1 +shipito.kg, 1 +shipmonk.cloud, 1 +shipmonk.com, 1 +shipmyroom.com, 1 +shipnak.com, 1 +shippercenter.info, 1 +shippexx.com, 1 +shipping-trade.ga, 1 +shipping24h.com, 0 +shippingbo.com, 1 +shippinglabel.de, 1 +shiptek.co, 1 +shiqi.ca, 1 +shiqi.lol, 1 +shiqi.one, 1 +shiqi.online, 1 +shiqi.se, 1 +shiqi.tv, 1 +shiqi1.com, 1 +shiqishidai.cc, 1 +shiqisifu.cc, 1 +shira-diamonds.com, 1 +shiranaitenshi.tk, 1 +shirao.jp, 1 +shirazi.tk, 1 +shiresvets.com, 1 +shirevirtual.tk, 1 +shireyishunjian.com, 1 +shireyishunjian.pro, 1 +shirhashirim.org.il, 1 +shiriforum.tk, 1 +shirlygilad.com, 1 +shiroanime.es, 1 +shiroki-k.net, 1 +shiropaev.tk, 1 +shirosaki-hana.fun, 1 +shirro.com, 1 +shirts2u.com, 1 +shirtsdelivered.com, 1 +shirtsofholland.com, 1 +shishadenbosch.nl, 1 +shishamania.de, 1 +shishlik.net, 1 +shit.software, 1 +shitagi-shop.com, 1 +shitbeast.institute, 1 +shitcountries.org, 1 +shitdick.tk, 1 +shitmybradsays.com, 0 +shitnikovo.tk, 1 +shitposter.io, 1 +shitposts.se, 1 +shitproductions.org, 1 +shitsta.in, 1 +shittyurl.org, 1 +shittywok.tk, 1 +shiuki.eu.org, 1 +shiulungkungfu.com.au, 1 +shiva-temple.tk, 1 +shivamber.com, 1 +shivammathur.com, 1 +shivamohanam.com, 1 +shivering-isles.com, 1 +shivkrupanandfoundation.org, 1 +shivyogphysiotherapy.in, 1 +shixuen.com, 1 +shiyouqkl.com, 1 +shkolladigjitale.com, 1 +shkolnyimir.gq, 1 +shkololo.cf, 1 +shkololo.ga, 1 +shkololo.gq, 1 +shkololo.ml, 1 +shkololo.tk, 1 +shlang.tk, 1 +shlemenkov.by, 1 +shlmail.info, 1 +shlupka.ml, 1 +shlupka.tk, 1 +shlyakpavel.tk, 1 +shlyapa-com.tk, 1 +shlyhi.tk, 1 +shmotki.ml, 1 +shmulvad.com, 1 +shoarq.com, 1 +shochikubai.tk, 1 +shock.ee, 1 +shockercityservices.com, 1 +shockerdragon.tk, 1 +shockproof.systems, 1 +shodan.io, 1 +shodanian.com, 1 +shoejitsu.co, 1 +shoemakerywc.com, 1 +shoeracks.uk, 1 +shoes4gentlemen.de, 1 +shoesoutlet.tk, 1 +shoestorebiz.tk, 1 +shoestorenet.tk, 1 +shoestringeventing.co.uk, 1 +shokofarehab.ir, 1 +shokureach.jp, 1 +shola.ga, 1 +sholtowu.com, 1 +shontakleinpeter.tk, 1 +shooba.net, 1 +shoobacreations.com, 1 +shoogar.herokuapp.com, 1 +shooter.dog, 1 +shootpooloklahoma.com, 1 +shop-cosmetic.tk, 1 +shop-cosmetics.tk, 1 +shop-eldorado.tk, 1 +shop-hellsheadbangers.com, 1 +shop-lingerie.tk, 1 +shop-links.co, 1 +shop-ok.tk, 1 +shop-s.net, 1 +shop-slivki.tk, 1 +shop3dmili.com, 1 +shop4d.com, 1 +shopadvies.nl, 1 +shopalike.cz, 1 +shopalike.dk, 1 +shopalike.es, 1 +shopalike.fi, 1 +shopalike.fr, 1 +shopalike.hu, 1 +shopalike.it, 1 +shopalike.nl, 1 +shopalike.pl, 1 +shopalike.se, 1 +shopalike.sk, 1 +shopandworld.net, 1 +shopapi.cz, 1 +shoparbonne.co.uk, 1 +shopasa.de, 1 +shopatkei.com, 1 +shopazmoon.ir, 1 +shopbabymonitors.gq, 1 +shopbakersnook.com, 1 +shopcceputnam.com, 1 +shopcom.tk, 1 +shopcon.vn, 1 +shopcosmetic.tk, 1 +shopcoupons.co.id, 1 +shopcoupons.my, 1 +shopcoupons.ph, 1 +shopcoupons.sg, 1 +shopcrocs.in, 1 +shopee6.com, 1 +shopexo.in, 1 +shopfazz.com, 1 +shopfinale.com, 1 +shopforeverproducts.com, 1 +shophisway.com, 1 +shopific.co, 1 +shopific.com, 1 +shopify.com, 1 +shopifycloud.com, 1 +shopikal.com, 1 +shopingbiz.tk, 1 +shopkini.com, 1 +shoplandia.co, 1 +shoplogcap.com, 1 +shoplyft.co.za, 1 +shopmacher.de, 1 +shopmalinka.cf, 1 +shopminut.com, 1 +shopocratic.com, 1 +shopofturkey.com, 1 +shoponlinedeals.tk, 1 +shoposal.com, 1 +shoppencph.dk, 1 +shopperexperts.com, 1 +shopperexpertss.com, 1 +shoppies.tk, 1 +shoppinganchor.ga, 1 +shoppingandreviews.it, 1 +shoppingcarnival.ga, 1 +shoppingclearance.ga, 1 +shoppingcorporation.ga, 1 +shoppingdascapinhas.com.br, 1 +shoppingdowntown.ga, 1 +shoppingguerilla.ga, 1 +shoppingicarai.com, 1 +shoppingjin.pk, 1 +shoppinglowprice.ga, 1 +shoppingplaza.eu, 1 +shoppingvrimini.ru, 1 +shoppr.dk, 1 +shopregional.com.br, 1 +shopshap.ru, 1 +shopsici.com, 1 +shopstasy.com, 1 +shoptec.sk, 1 +shopteq.hu, 1 +shoptio.cz, 1 +shoptupperware.in, 1 +shopunderwear.tk, 1 +shopunilever.com, 1 +shopwebhue.com, 1 +shore.co.il, 1 +shorebreaksecurity.com, 1 +shorehamfort.co.uk, 1 +shorewoodmn.gov, 1 +shorinkarate.tk, 1 +short-games.gq, 1 +short-term-plans.com, 1 +short.io, 1 +short.wtf, 1 +shortaudition.com, 1 +shortaudition.net, 1 +shortaudition.tv, 1 +shortbread.systems, 1 +shortcircuit-online.tk, 1 +shortcut.pw, 1 +shortcutable.com, 1 +shortdiary.me, 1 +shorten.ninja, 1 +shorti.ga, 1 +shortr.li, 1 +shortshadows.band, 1 +shoruihokan.com, 1 +shoshin-aikido.de, 1 +shoshin.technology, 1 +shossain.tk, 1 +shost.ga, 1 +shota-sekkotsuin.com, 1 +shotbow.net, 1 +shotgunstudio.com, 1 +shotly.net, 1 +shotsleeve.com, 1 +shoujik8.com, 1 +shouldbetaught.com, 1 +shouldtest.com, 1 +shouldtest.email, 1 +shouldtest.eu, 1 +shouldtest.net, 1 +shouldtest.org, 1 +shouohkai-dental.com, 1 +shouttag.com, 1 +shovonhasan.com, 1 +show-pro.com.au, 1 +show-stream.tv, 1 +showbits.net, 1 +shower.im, 1 +showersnet.com, 1 +showf.om, 1 +showfom.sb, 1 +showgirls.ga, 1 +showmax.com, 1 +showmeengland.co.uk, 1 +shownet.tk, 1 +showpassword.net, 0 +showroom.co.uk, 1 +showroom.de, 0 +showroom.uk, 1 +showroom113.ru, 1 +showslivki.tk, 1 +showsonar.com, 1 +shoxmusic.net, 0 +shoyuf.top, 1 +shpil.by, 1 +shpilevsky.name, 1 +shpiliak.com, 1 +shpiliak.ru, 1 +shq1p.com, 1 +shrapnel.ga, 1 +shraymonks.com, 1 +shred.ch, 0 +shredder.tk, 1 +shredoptics.ch, 0 +shredriteservices.com, 1 +shreyansh26.me, 1 +shrike.me, 0 +shrimpcam.pw, 1 +shrines.ga, 1 +shrines.tk, 1 +shrinidhiclinic.in, 1 +shrinker.tk, 1 +shrinkhub.com, 1 +shrovetide.tv, 1 +shrsl.com, 1 +shrt.tv, 1 +shrturl.io, 1 +shrub.ca, 1 +shrug.ml, 0 +shsh.host, 1 +shssl.vip, 1 +sht-vr-player.cf, 1 +sht.life, 1 +shtaiman.com, 1 +shtaiman.net, 1 +shtaiman.org, 1 +shtaketnik-metall.ru, 1 +shtaketniki.kz, 1 +shtaketniki.ru, 1 +shteiman.com, 1 +shteiman.net, 1 +shteiman.org, 1 +shtorku.com, 1 +shu-fu.net, 1 +shuang.us, 1 +shuax.com, 1 +shucheng.li, 1 +shufflecube.tk, 1 +shufflemix.tk, 1 +shuffleradio.nl, 1 +shuffleware.tk, 1 +shuftipro.com, 1 +shugarmanpsychiatric.com, 1 +shugo.net, 1 +shugua.com.tw, 1 +shuhacksoc.co.uk, 1 +shui.ga, 1 +shulan.moe, 1 +shuletime.ml, 1 +shulker.store, 1 +shulman.tk, 1 +shumnyj-istochnik.tk, 1 +shunliandongli.cn, 1 +shunliandongli.com, 1 +shunmei-hari.com, 1 +shunter.tk, 1 +shunzi.tk, 1 +shuo.li, 0 +shuomingshu88.com, 1 +shura.eu.org, 1 +shurita.org, 1 +shuset.dk, 1 +shuttelservices.nl, 1 +shutter-shower.com, 1 +shutterstreetblog.com, 1 +shutupbabyiknowit.party, 1 +shuvodeep.de, 1 +shux.pro, 1 +shuzicai.cn, 1 +shvedskie-stenki.ml, 1 +shwemyanmarmalay.com, 1 +shwrm.ch, 1 +shymeck.pw, 1 +shymeck.xyz, 1 +shyuka.me, 1 +si-benelux.nl, 1 +si.to, 1 +si2b.fr, 1 +sia.one, 1 +siadlak.com, 1 +siaggiusta.com, 1 +sialis.tk, 1 +sialtv.pk, 1 +siamdevsqua.re, 1 +siamdevsquare.com, 1 +siamega.com, 1 +siamesecatsguide.com, 1 +siamojo.com, 1 +siamrehab.com, 1 +siamsnus.com, 1 +siamwatercraftpromotion.com, 1 +sianjhon.com, 1 +siatris.qc.ca, 1 +siava.ru, 1 +sib.li, 1 +sibekohirescaffolding.co.za, 1 +siberas.de, 1 +siberia.gq, 1 +siberiactiva.com, 1 +siberiancatsinformation.com, 1 +siberianhuskypets.com, 1 +siberkulupler.com, 1 +sibernet.tk, 1 +sibertakvim.com, 0 +sibfk.org, 1 +sibirium-red.ga, 1 +sibrenvasse.nl, 1 +siccardisport.it, 1 +sice-si.org, 1 +sich-fight.club, 1 +sich-positionieren.net, 1 +siciliadisinfestazioni.it, 1 +siciliamconsulting.com, 1 +sicilianbalm.com, 1 +siciliapulizie.it, 1 +sicken.eu, 1 +sickfile.com, 0 +sickhou.se, 1 +sickhouse.se, 1 +sicklepod.com, 1 +sicol.es, 1 +sicoobpaulista.com.br, 1 +sicurezza24.info, 1 +sicurezzalavoro24.com, 1 +sicurled.com, 1 +sicz.de, 1 +sid.group, 1 +sidd.swiss, 1 +siddigsami.com, 1 +sidecredit.ga, 1 +sidekix.nl, 1 +sideleau.com, 1 +sidelka-tver.ru, 1 +sidema.be, 1 +sidemount-forum.com, 1 +sidemount-tauchen.com, 1 +sidepodcast.com, 1 +sidepodcastdaily.com, 1 +sidepodcastextra.com, 1 +sideral.is, 1 +sideshowbarker.net, 1 +sidi-smotri.ru, 1 +sidirokastro.ga, 1 +sidium.de, 1 +sidmax.ca, 1 +sidnicio.us, 1 +sidocsa.com, 1 +sidonge.com, 1 +sidongkim.com, 1 +sidpod.ru, 1 +sidsun.com, 1 +siduga.com, 1 +siebeve.be, 1 +siecledigital.fr, 1 +siegemund-frankfurt.de, 1 +siegprod.tk, 1 +sieh.es, 1 +sieiro.tk, 1 +siel.nl, 1 +sielsystems.nl, 1 +siemens-srm.com, 1 +siemens-stockawards.com, 1 +siemens.co.uk, 1 +siemens.de, 1 +sientemendoza.com.ar, 1 +siepomaga.net, 1 +sierpinska.co, 1 +sierpinska.eu, 1 +sierramusic.tk, 1 +sietejefes.com.ar, 1 +sieulog.com, 1 +sifasharing.tk, 1 +sifecs.ml, 1 +sift-tool.org, 0 +sift.com, 1 +sifuondemand.com, 1 +sig6.org, 1 +siga.com, 1 +sigabrt.org, 1 +sigcafe.net, 1 +siggi.io, 1 +sight-restoration.tk, 1 +sight-sound.com, 1 +sightcure.jp, 1 +sighup.nz, 1 +sigi.tk, 1 +sigil.lt, 1 +sigint.pw, 1 +sigismonda.ch, 0 +sigma-signalisation.com, 1 +sigma957.net, 1 +sigmacomputers.ga, 1 +sigmalux.ca, 1 +sigmalux.co.nz, 1 +sigmalux.co.uk, 1 +sigmalux.com.au, 1 +sigmalux.es, 1 +sigmalux.fr, 1 +sigmalux.ltd, 1 +sigmalux.lu, 1 +sigmalux.nz, 1 +sigmalux.sarl, 1 +sigmalux.uk, 1 +sigmaomeganu.tk, 1 +sigmasensors.com.br, 1 +sigmateca.tk, 1 +sigmaweb.co.uk, 1 +sign.dog, 1 +sign.io, 1 +signaconsultoria.com.br, 1 +signage.red, 1 +signal.org, 0 +signal34.com, 1 +signalmaps.co.uk, 1 +signaltransmitter.de, 1 +signalxtech.com, 1 +signature.in.th, 1 +signature365.com, 1 +signaturechannel.com, 1 +signaturecityllc.com, 1 +signaturecountertops.com, 1 +signaturedallas.com, 1 +signere.com, 1 +signicat.io, 1 +significados.com, 1 +significados.com.br, 1 +significantbanter.com, 1 +signing-milter.org, 0 +signity.com.ph, 1 +signix.net, 1 +signpath.io, 1 +signrightsigns.co.uk, 1 +signsdance.uk, 1 +signslabelstapesandmore.com, 0 +signsymptom.com, 1 +signtul.com, 0 +signup.ly, 1 +signupgenius.com, 1 +sigobierno.com, 1 +sigparser.com, 1 +sigridcrm.com, 1 +sigriderp.com, 1 +sigsrv.net, 1 +sigterm.no, 1 +sigterm.sh, 1 +sigurnost.online, 1 +sihaizixun.net, 1 +siika.solutions, 1 +siikaflix.tv, 1 +siirtutkusu.com, 0 +sijbesmaverhuizingen.nl, 1 +sik-it.nl, 1 +sikademy.com, 1 +sikaranbrotherhood.tk, 1 +sikayetvar.com, 0 +sike.org, 1 +sikevux.se, 1 +sikkind.com, 0 +sikko.biz, 1 +siku-shop.ch, 1 +siku.pro, 1 +silagra.ml, 1 +silasborowy.de, 1 +silashes.com, 1 +silashes.ru, 1 +silaslova-ekb.ru, 1 +sildenafilcitrate.cf, 1 +sildenafilcitrate100mg.ga, 1 +silent-clean.de, 1 +silent-yachts.com, 1 +silent.se, 1 +silentdream.tk, 1 +silentexplosion.de, 1 +silentinstaller.com, 1 +silentkernel.fr, 1 +silentneko.ga, 1 +silentsky.tk, 1 +silentsystem.com, 1 +silentsystem.it, 1 +silentundo.org, 1 +silesianus.pl, 1 +silica-project.com, 1 +silica-project.jp, 1 +silicanetworks.com, 1 +silicateillusion.org, 1 +silicon-north.com, 1 +silicon-vision.com, 1 +silina.tk, 1 +silindir-taslama.tk, 1 +silkebaekken.no, 1 +silken-madame.tk, 1 +silkproducts.tk, 1 +sillisalaatti.fi, 1 +sillysnapz.co.uk, 1 +silo.nyc, 1 +silo.org.br, 1 +siloportem.net, 1 +silqueskineyeserum.com, 1 +silsha.me, 1 +silv.me, 1 +silv.tk, 1 +silver-drachenkrieger.de, 1 +silver-heart.co.uk, 1 +silverartcollector.com, 1 +silverblog.org, 1 +silverbowflyshop.com, 1 +silverbox.ga, 1 +silverdollaracademy.com, 1 +silverfalcon.me, 1 +silvergoldbull.ba, 1 +silvergoldbull.bg, 1 +silvergoldbull.bj, 1 +silvergoldbull.by, 1 +silvergoldbull.cl, 1 +silvergoldbull.cm, 1 +silvergoldbull.cn, 1 +silvergoldbull.co, 1 +silvergoldbull.co.ao, 1 +silvergoldbull.co.tz, 1 +silvergoldbull.com.ar, 1 +silvergoldbull.com.gh, 1 +silvergoldbull.com.mt, 1 +silvergoldbull.cr, 1 +silvergoldbull.do, 1 +silvergoldbull.ec, 1 +silvergoldbull.gd, 1 +silvergoldbull.ge, 1 +silvergoldbull.gl, 1 +silvergoldbull.gr, 1 +silvergoldbull.gt, 1 +silvergoldbull.hn, 1 +silvergoldbull.hr, 1 +silvergoldbull.hu, 1 +silvergoldbull.id, 1 +silvergoldbull.in, 1 +silvergoldbull.kg, 1 +silvergoldbull.ky, 1 +silvergoldbull.lk, 1 +silvergoldbull.lt, 1 +silvergoldbull.lv, 1 +silvergoldbull.ma, 1 +silvergoldbull.md, 1 +silvergoldbull.ml, 1 +silvergoldbull.my, 1 +silvergoldbull.ph, 1 +silvergoldbull.pt, 1 +silvergoldbull.rs, 1 +silvergoldbull.ru, 1 +silvergoldbull.si, 1 +silvergoldbull.sn, 1 +silvergoldbull.sv, 1 +silvergoldbull.tg, 1 +silvergoldbull.tj, 1 +silvergoldbull.tn, 1 +silvergoldbull.tw, 1 +silvergoldbull.uy, 1 +silvergoldbull.uz, 1 +silvergoldbull.ws, 1 +silverlinkz.net, 1 +silvermatch.ga, 1 +silvernight.social, 1 +silversgarage.com, 1 +silversgarage.net, 1 +silversgarage.org, 1 +silvershadow.cc, 1 +silverspottrading.com, 1 +silverstartup.sk, 1 +silvertonmd.com, 1 +silvertorrents.cf, 1 +silverwind.io, 1 +silvesrom.ro, 1 +silvester-mitterschida.de, 0 +silviacataldi.com, 1 +silvianavarro.tk, 1 +silviaroddey.tk, 1 +silvine.xyz, 1 +silviorodriguez.tk, 1 +silvistefi.com, 1 +silvius.at, 1 +silvobeat.blog, 1 +silvobeat.com, 1 +sim-karten.net, 1 +sim-minaoshi.jp, 1 +sim-mobile.ml, 1 +sim-sim.appspot.com, 1 +sim-usa.mobi, 1 +sim4seed.org, 1 +simam.de, 1 +simaogv.net, 1 +simark.ca, 1 +simart.cf, 1 +simasoft.com, 1 +simava.org, 1 +simbamail.de, 1 +simbdo.jp, 1 +simbeton.nl, 1 +simbike.ru, 1 +simbolo.co.uk, 0 +simcityjoy.tk, 1 +simcoecurlingclub.ca, 1 +simcongroup.ir, 1 +simdex.org, 1 +simeonoff.ninja, 1 +simetal.ch, 0 +simetria.org, 1 +simex.tk, 1 +simfdr.com, 1 +simha.online, 1 +simhaf.cf, 1 +simi-reizen.nl, 1 +simivalleyelectrical.com, 1 +simivalleyexteriorlighting.com, 1 +simivalleylandscapelighting.com, 1 +simivalleylighting.com, 1 +simivalleyoutdoorlighting.com, 1 +simkartya.hu, 1 +simkin.tk, 1 +simkova-reality.cz, 1 +simlau.net, 0 +simmis.fr, 0 +simmtronic.com, 1 +simnovo.net, 1 +simoesgoulart.com.br, 1 +simon-agozzino.fr, 1 +simon-hofmann.org, 1 +simon-mueller.de, 1 +simon.butcher.name, 0 +simon3k.moe, 1 +simonagancia.com, 1 +simonastallone.com, 1 +simonberard.garden, 1 +simonbondo.dk, 1 +simoncommunity.org.uk, 1 +simoncook.org, 1 +simone.sh, 1 +simonevans.uk, 1 +simonfischer.info, 1 +simonheung.com, 1 +simonhirscher.de, 1 +simonkjellberg.com, 1 +simonkjellberg.se, 1 +simonmaddox.com, 1 +simonmanuel.com, 1 +simonoener.com, 1 +simonreich.de, 1 +simonreynoldsfavesunfaves.cf, 1 +simonschmitt.ch, 1 +simonspeich.ch, 1 +simonsreich.de, 1 +simonssh.ddns.net, 1 +simonweil.com, 1 +simonwessel.net, 1 +simonwoodside.com, 1 +simonzoellner.de, 1 +simosol.de, 1 +simosol.dk, 1 +simotrescu.ro, 1 +simpbx.net, 1 +simpel.be, 1 +simpelkoken.be, 1 +simpelkoken.com, 1 +simpelkoken.net, 1 +simpelkoken.nl, 1 +simpelkoken.org, 1 +simpeo.org, 1 +simphony.cz, 1 +simple-perfect.tk, 1 +simple-test-to-demonstrate-the-maximum-length-of-a-domain-name.com, 1 +simple-test-to-demonstrate-the-maximum-length-of-a-domain-name.eu, 1 +simple-test-to-demonstrate-the-maximum-length-of-a-domain-name.international, 1 +simple.com, 0 +simplechoicesuper.com.au, 1 +simpleclassiclife.com, 1 +simplecmsdemo.com, 1 +simplecoding.click, 1 +simplecontacts.com, 1 +simplecrypt.io, 1 +simplecryptoconvert.com, 1 +simplednscrypt.org, 1 +simplefraud.com, 1 +simplegoodhealth.com, 1 +simpleinout.com, 1 +simpleinvoices.io, 1 +simpleit.services, 1 +simpleline.studio, 1 +simplelinux.tk, 1 +simplelist.ga, 1 +simplelogin.co, 1 +simplelogin.fr, 1 +simplelogin.io, 1 +simpleman.cf, 1 +simplemining.net, 1 +simpleports.eu, 1 +simpleports.net, 1 +simpleports.org, 1 +simpleprojects.net, 1 +simplerses.com, 1 +simplerust.ru, 1 +simplesend.io, 1 +simplesite.hu, 1 +simplespy.tk, 1 +simpletax.ca, 1 +simpletherapy.com, 1 +simpletools.tk, 1 +simpletrace.nz, 1 +simplewire.de, 1 +simplexdigital.com, 1 +simplexgame.net, 1 +simplia.cz, 1 +simplicitypvp.net, 1 +simplidesigns.nl, 1 +simplifixed.com, 1 +simplifyengineering.co.uk, 1 +simplifylivelove.com, 1 +simplixos.org, 1 +simplonevents.ch, 1 +simplosoft.co.uk, 1 +simply-pattinson.tk, 1 +simply-premium.com, 1 +simply.black, 1 +simply.com, 1 +simply.scot, 1 +simply2020.com, 1 +simplyathenee.com, 1 +simplybrave.net, 1 +simplycateringequipment.co.uk, 1 +simplycharlottemason.com, 1 +simplycloud.de, 1 +simplyfitperth.com.au, 1 +simplyfixit.co.uk, 1 +simplyheadwear.com.au, 1 +simplyhelen.de, 1 +simplyjet.tk, 1 +simplyml.com, 1 +simplymozzo.se, 1 +simplyowners.net, 1 +simplypromo.com.au, 1 +simplyregister.net, 1 +simplysmartgardening.com, 1 +simplytiles.com, 1 +simplyuniforms.com.au, 1 +simpservices.com, 1 +simpte.com, 1 +simrail.nl, 1 +simscale.com, 1 +simsimi.ml, 1 +simsnieuws.nl, 1 +simstarstyle.tk, 1 +simulfund.com, 0 +simulise.cloud, 1 +simulise.com, 1 +simulping.com, 1 +simumiehet.com, 1 +simus.fr, 1 +simyayayinlari.com, 0 +sin-el-fil.com, 0 +sin-nombre-alleria.de, 1 +sin.swiss, 0 +sin4psi77.tk, 1 +sinakuhestani.ir, 0 +sinalizeweb.com.br, 0 +sinan.mobi, 1 +sinanaydemir.com.tr, 1 +sinapuros.tk, 1 +sinaryuda.web.id, 1 +sinatralegal.com, 1 +sinavelvet.com, 1 +sinavtakvimim.com, 1 +sinavyo.ml, 1 +sincelockdown.co.uk, 1 +sincemydivorce.com, 1 +sinceschool.com, 1 +sincitymushrooms.com, 1 +sinclairinat0r.com, 1 +sincordones.net, 1 +sincromyl.com, 1 +sindarina.com, 1 +sindarina.eu, 1 +sindarina.net, 1 +sindarina.org, 1 +sindastra.de, 1 +sinde.ru, 1 +sindicatoburgos.org, 1 +sindlerova.com, 1 +sindlerova.cz, 1 +sindominio.net, 1 +sindromebenjamin.tk, 1 +sineadobrien.com, 1 +sineafoods.com, 1 +sinefili.com, 1 +sinemakurd.tk, 1 +sinergy.ch, 0 +sinergylabs.com, 1 +sinetron.ga, 1 +sinews.tk, 1 +sinfield.com, 0 +sinfulforums.net, 1 +sinfully.gq, 1 +sinfulthrills.co.uk, 1 +singaporebrand.com.sg, 1 +singaporefreelegaladvice.com, 1 +singaporetoptentravel.com, 1 +singapur24.tk, 1 +singapurfirma.com, 1 +singee.me, 1 +singee.site, 1 +singel.ch, 1 +singer.ru, 1 +singerfamily.ca, 1 +singerpragathi.tk, 1 +singerwang.com, 1 +singharora.de, 1 +singhpackersmovers.com, 0 +singingblackbird.tk, 1 +single-in-stuttgart.de, 1 +singlehandedsailing.tk, 1 +singlenine.gq, 1 +singleproduction.com, 1 +singles-aus-hamburg.de, 1 +singles-berlin.de, 1 +singleuse.link, 1 +singlu10.org, 0 +singluten.tk, 1 +sinhnhatbaby.com, 1 +sinistragiovanile.tk, 1 +sinkhole-florida.com, 1 +sinkholerepairsflorida.com, 1 +sinkip.com, 1 +sinktank.de, 1 +sinluzvenezuela.tk, 1 +sinnersprojects.ro, 1 +sinnvoll-online.de, 1 +sinnvoll-online.info, 1 +sinog.si, 1 +sinok.tk, 1 +sinonimos.com.br, 1 +sinonimosonline.com, 1 +sinonimosonline.com.br, 1 +sinopx.cf, 1 +sinoscandinavia.se, 1 +sinquin.eu, 1 +sinronet.com, 1 +sinsalida.tk, 1 +sinsastudio.com, 1 +sint-joris.nl, 1 +sintas.lt, 1 +sintaxis.org, 1 +sintbaafsabdij.gent, 1 +sintbaafsabdijgent.be, 1 +sinterama.biz, 1 +sintergetica.org, 1 +sintomasdocancer.com, 1 +sintpietersabdijgent.be, 1 +sintraunipricol.com.co, 1 +sintsationeel.nl, 1 +sinuate.gq, 1 +sinuelovirtual.com.br, 1 +sinusinfectionhelp.org, 1 +sinusitis-bronchitis.ch, 1 +sinusitisexplained.com, 1 +sinvid.co, 1 +sinvideovault.com, 1 +sioeckes.hu, 1 +siogyumolcs.hu, 1 +sion-colony.tk, 1 +sion.info, 1 +siongseafood.com, 1 +sipa.nc, 1 +sipa.pf, 1 +sipadmin.ru, 1 +sipc.org, 1 +sipd.go.id, 1 +sipede.tk, 1 +sipln.com, 1 +sipo.tk, 1 +sipstix.co.za, 1 +sipyuru.com, 1 +sipyuru.lk, 1 +siqi.wang, 1 +siranap.com, 1 +sirandorung.tk, 1 +siraweb.org, 1 +sirbouncealotcastles.co.uk, 1 +sirbouncelot.co.uk, 1 +sircharlesincharge.com, 1 +sirchuk.net, 1 +sircon.no, 1 +sirenasweet.net, 1 +sirencallofficial.com, 1 +sirenslove.com, 1 +siri.cc, 1 +sirihouse.com, 1 +siriusharmonicaensemble.com, 1 +siriuspro.pl, 1 +siriuspup.com, 1 +siro.gq, 1 +sirpsycho.tk, 1 +sirtaptap.com, 1 +sirtuins.com, 1 +sirvio.eu, 1 +sirvoy.ca, 1 +sirvoy.co.nz, 1 +sirvoy.co.uk, 1 +sirvoy.co.za, 1 +sirvoy.com, 1 +sirvoy.com.au, 1 +sirvoy.de, 1 +sirvoy.dk, 1 +sirvoy.es, 1 +sirvoy.fi, 1 +sirvoy.fr, 1 +sirvoy.ie, 1 +sirvoy.jp, 1 +sirvoy.nl, 1 +sirvoy.no, 1 +sirvoy.se, 1 +sisadmin21.tk, 1 +siscompbolivia.tk, 1 +siscompt.com, 1 +siselectrom.com, 1 +sisirbatu.tk, 1 +sismit.com, 1 +sismit.es, 1 +sisqo.tk, 1 +sissden.eu, 1 +sisseastumine.ee, 1 +sisselsteyaert.be, 1 +sistel.es, 1 +sistem-maklumat.com, 1 +sistem-maklumat.com.my, 1 +sistema-trenirovok.ml, 1 +sistema20k.tk, 1 +sistemapronto.ml, 1 +sistemasarquitectonicos.com, 1 +sistemasespecializados.com, 1 +sistimiki-anaparastasi.gr, 1 +sistonenfranco.tk, 1 +sisu.ai, 1 +sisv.eu, 1 +sisver.host, 1 +sisver.mx, 1 +sit-brn.ru, 1 +sit.ec, 1 +sit.moe, 0 +sitak.fi, 1 +sitanleta.de, 1 +sitatravel.gr, 1 +sitc.sk, 1 +site-development.tk, 1 +site-helper.com, 1 +site-oficial-inicio.com, 1 +site-oflcial.com, 1 +site-remont.ml, 1 +site-romania.tk, 1 +site-ua.tk, 1 +site.mu, 1 +site.pictures, 1 +site2002.tk, 1 +siteadvokat.cf, 1 +sitebrass.ru, 1 +sitebuilderreport.com, 0 +sitecentre.com.au, 1 +sitechange.dedyn.io, 1 +sitecreation.tk, 1 +sitecuatui.com, 1 +sitedebelezaemoda.com.br, 1 +sitedrive.fi, 1 +sitefactory.com.br, 1 +siteheft.com, 1 +sitehoster.org, 1 +sitekatalog.tk, 1 +sitelinks.ml, 1 +sitelmexico.com, 1 +sitemai.eu, 1 +sitemaxiphilippe.ch, 1 +sitemydesk.fr, 1 +sitenv.org, 1 +siterank.cf, 1 +siterencontre.me, 1 +siteru.tk, 1 +sites.google.com, 1 +sitesdesign.tk, 1 +sitesforward.com, 1 +sitesko.de, 1 +sitestudio.tk, 1 +sitesweb.gq, 1 +siteweb-seo.fr, 1 +sithijaya.tk, 1 +sithmanifest.com, 1 +sithr.com, 1 +sithr.life, 1 +sithr.net, 1 +sithr.org, 1 +sithr.site, 1 +sitinjau.com, 1 +sitiosantaangela.com.br, 1 +sitischu.com, 1 +sito-online.ch, 1 +sittogether.club, 1 +sittogether.tw, 1 +siulam-wingchun.org, 1 +siusto.com, 1 +sivale.mx, 1 +sivaru.tk, 1 +sivizius.eu, 1 +sivyerge.com, 1 +siw64.com, 1 +siwek.xyz, 1 +siwyd.com, 1 +six-o-one.com, 1 +sixcolors.lu, 1 +sixcorners.info, 1 +sixcorners.net, 1 +sixe.es, 1 +sixpackband.tk, 1 +sixpackholubice.cz, 1 +sixteenweb.in, 1 +sizeunknown.com, 1 +sizeunknown.net, 1 +sj-leisure.com, 1 +sja-se-training.com, 1 +sjaakgilsingfashion.nl, 1 +sjaaktrekhaak.nl, 1 +sjbwoodstock.org, 1 +sjd.is, 0 +sjleisure.co.uk, 1 +sjm-hamburg.de, 1 +sjnp.org, 1 +sjoelen.tk, 1 +sjoelsport.nl, 1 +sjoorm.com, 1 +sjorsvanweert.nl, 1 +sjout.nl, 1 +sjparanormal.tk, 1 +sjrcommercialfinance.co.uk, 1 +sjwheel.net, 1 +sk.tl, 1 +sk33t.tk, 1 +skachat-shablon-rezyume-na-angliyskom-yazyk.tk, 1 +skachat-zip.tk, 1 +skachay-knighki.gq, 1 +skagen-feriebolig.dk, 1 +skaginn.tv, 1 +skaiman.ga, 1 +skaitliukas.tk, 1 +skalar.sk, 1 +skalec.org, 1 +skamper.tk, 1 +skante.tk, 1 +skarox.com, 1 +skarox.ee, 1 +skarox.eu, 1 +skarox.net, 1 +skarox.ru, 1 +skartecedu.in, 1 +skarvruet.com, 1 +skatclub-beratzhausen.de, 1 +skateaustria.at, 1 +skateaustria.events, 1 +skateparkmontbriz.tk, 1 +skaterangels.tk, 1 +skateschoolkostroma.ru, 1 +skatesins.ch, 1 +skatesliide.tk, 1 +skateswagger.com, 1 +skatingchina.com, 1 +skatn.de, 1 +skattesjekk.no, 1 +skautibrno.cz, 1 +skazka.ml, 1 +skazka.ru, 1 +skazochnyj-sait.tk, 1 +skday.com, 1 +skedda.com, 1 +skeditor.tk, 1 +skedr.io, 0 +skeeley.com, 1 +skei.org, 1 +skepneklaw.com, 1 +skeppsbrons.se, 1 +skepticalsports.com, 1 +skeptik.tk, 1 +skeriv.com, 1 +sketch.io, 1 +sketch.jpn.com, 1 +sketchbox.tk, 1 +skgzberichtenbox.nl, 1 +skhaz.io, 1 +skhire.co.uk, 1 +skhoop.cz, 1 +skibikers.tk, 1 +skid.church, 1 +skiddle.com, 1 +skidka.by, 1 +skidki-ru.cf, 1 +skidzun.de, 1 +skifairview.com, 1 +skifttiljutlanderbank.dk, 1 +skigebied.nl, 1 +skigebiete-test.de, 1 +skiingnewsletter.cf, 1 +skiingproperty.com, 1 +skiinstructor.services, 1 +skile.ru, 0 +skiley.net, 1 +skilift-quellenwiese.at, 1 +skill.moe, 1 +skill.tk, 1 +skillablers.com, 1 +skillatwill.com, 1 +skilldetector.com, 1 +skillled.com, 1 +skillmoe.at, 1 +skills2serve.org, 1 +skills2services.com, 1 +skillseo.com, 1 +skin-cosmetic.eu, 1 +skinandglamour.com, 0 +skinbet.co, 1 +skinboost.ga, 1 +skinboost.ml, 1 +skincare-note.com, 1 +skincareagent.cf, 1 +skindb.net, 1 +skinews.tk, 1 +skinexpert.ml, 1 +skinfoodpeachcotton.tk, 1 +sking.io, 1 +skinmarket.co, 1 +skinmodo.com, 1 +skinpet.com, 1 +skinport.com, 1 +skinpwrd.com, 1 +skinseries.cf, 1 +skinship.xyz, 1 +skinstyleglobal.com, 1 +skinwhiteningoptions.com, 0 +skipbounce.com, 1 +skipfault.com, 1 +skipperinnovations.com, 0 +skippers-bin.com, 1 +skippy.dog, 0 +skiptadiabetes.com, 1 +skipton.io, 1 +skirted.cf, 1 +skirts.tk, 1 +skirtskenya.tk, 1 +skischule-wildewiese.de, 1 +skitecsh.com, 1 +skizzen-zeichnungen.de, 1 +skjt.co.jp, 1 +skk-krovlya.ru, 1 +sklepvoip.tel, 1 +sklepwielobranzowymd.com, 1 +sklisen.tk, 1 +sklotechnik.cz, 1 +skmedia.ga, 1 +sknasirali.com, 1 +sknclinics.co.uk, 1 +skoda-im-dialog.de, 1 +skogmans.co.jp, 1 +skol.bzh, 1 +skolagatt.is, 1 +skolakrizik.cz, 1 +skolappar.nu, 1 +skolebil.dk, 1 +skolem.de, 1 +skolni-system.eu, 1 +skolnieks.lv, 1 +skolnilogin.cz, 1 +skolniweby.cz, 1 +skooks.fr, 0 +skoolergraph.azurewebsites.net, 1 +skorbord.tk, 1 +skorepova.info, 1 +skoroff.com, 1 +skoropolnolunie.gq, 1 +skorovsud.ru, 1 +skorpil.cz, 1 +skory.us, 1 +skoskav.org, 1 +skotobaza.tk, 1 +skotty.io, 1 +skou.dk, 0 +skovbosburgerblog.dk, 1 +skovik.com, 1 +skpk.de, 1 +skpracta.info, 1 +skpracta.tk, 1 +skprhome.i234.me, 1 +skram.de, 1 +skreutz.com, 1 +skrid.net, 1 +skripta.tk, 1 +skrivebeskyttet.dk, 1 +skrivebordet.tk, 1 +skrooter.com, 1 +skrprojects.com.au, 1 +skrsv.net, 1 +sksdrivingschool.com.au, 1 +sksongs.com, 1 +sktan.com, 1 +sktsolution.com, 0 +sku-partei.de, 1 +skuizy.ddns.net, 1 +skulblaka.ch, 1 +skulblaka.cloud, 1 +skuldwyrm.no, 1 +skullnet.co.uk, 1 +skunkapeservers.net, 1 +skutry-levne.cz, 1 +skutry.cz, 1 +skux.ch, 1 +skvelecesko.cz, 1 +skvty.com, 0 +skwile-cafe.com, 1 +skwitko.com, 1 +skwlkrs.com, 1 +skxpl.eu.org, 1 +sky-aroma.com, 1 +sky-cargo.at, 1 +sky-coach.com, 1 +sky-coach.nl, 1 +sky-live.fr, 1 +sky-wap.cf, 1 +skyanchor.com, 0 +skyarch.net, 1 +skyautorental.com, 1 +skybirds.org, 1 +skyblond.info, 1 +skybloom.com, 1 +skyblue.co.jp, 1 +skyblueradio.com, 1 +skycmd.net, 1 +skyderby.ru, 1 +skydiverapp.com, 1 +skydiverecuador.com, 1 +skydragoness.com, 1 +skydrive.live.com, 0 +skyeeverest.tk, 1 +skyem.co.uk, 0 +skyfone.cz, 1 +skyfpicture.tk, 1 +skygates.tk, 1 +skyger.cz, 1 +skyhigh-mizell.tk, 1 +skyhooks.tk, 1 +skyla.tk, 1 +skylair.info, 1 +skylander.cf, 1 +skylarker.org, 1 +skylgenet.nl, 1 +skylightcreative.com.au, 1 +skylightipv.com, 1 +skyline.link, 1 +skylinehk.org, 1 +skylinertech.com, 1 +skylineservers.com, 1 +skylocker.net, 1 +skyloisirs.ch, 0 +skyminds.net, 1 +skymonk.tk, 1 +skyn.ai, 1 +skynet-research.us, 1 +skynet233.ch, 0 +skynet800.goip.de, 1 +skynetcloud.site, 1 +skynethk.com, 1 +skynetnetwork.eu.org, 1 +skynetstores.ae, 1 +skynetz.tk, 1 +skyntalent.com, 1 +skyoy.com, 0 +skype.com, 1 +skypefr.com, 1 +skyportcloud.com, 1 +skyquid.co.uk, 1 +skyra.pw, 1 +skyrieptravel.com, 1 +skyros.us, 1 +skys-entertainment.com, 1 +skyscanner.com, 1 +skyscanner.gg, 1 +skyscanner.net, 1 +skyscanner.pt, 1 +skyscanner.ru, 1 +skyscapecanopies.com, 1 +skyscnr.com, 1 +skyseo.cf, 1 +skysoftbg.com, 1 +skysuite.nl, 1 +skyterraathome.com, 1 +skyterraembrace.com, 1 +skyterrawellness.com, 1 +skytickets.ga, 1 +skytown.ga, 1 +skyvault.io, 1 +skywalkers.net, 1 +skywalkersa.ga, 1 +skywindowsnj.com, 1 +skyworldlinktravels.com, 1 +skyworldserver.ddns.net, 1 +skywt.cn, 1 +skyynet.de, 1 +skyzimba.com.br, 1 +sl-bildermacher.de, 1 +sl-informatique.ovh, 1 +sl.al, 1 +sl0.us, 1 +sl41.com.br, 1 +sl66.cc, 1 +slab.com, 1 +slabstage.com, 1 +slack-files.com, 1 +slack.com, 1 +slackline.tk, 1 +sladic.si, 0 +slainvet.net, 1 +slalix.cc, 1 +slalix.pw, 1 +slalix.xyz, 1 +slamdjapan.com, 1 +slamdunkdedication.tk, 1 +slamhope.gq, 1 +slamix.nl, 1 +slan.fr, 1 +slane.cn, 0 +slanterns.net, 1 +slapen17.nl, 1 +slaps.be, 1 +slash32.co.uk, 1 +slash64.co.uk, 1 +slash64.uk, 1 +slashbits.no, 1 +slashcam.de, 1 +slashcrypto.org, 1 +slashorg.net, 1 +slate.to, 1 +slated.ie, 1 +slatemc.com, 1 +slatemc.fun, 1 +slathering.cf, 1 +slaughter.com, 1 +slaughterhouse.fr, 1 +slava.ml, 1 +slavasoloviev.com, 1 +slavasveta.info, 1 +slavblog.ru, 1 +slaws.io, 1 +slayer.tech, 1 +slayingqueen.com, 1 +slbknives.com, 1 +sldev.ovh, 1 +sledgeroofing.com, 1 +sleeker.es, 1 +sleeklounge.com, 0 +sleep-go.info, 1 +sleep-tight.cf, 1 +sleepawaycampseries.tk, 1 +sleepet.tw, 1 +sleepig.com, 1 +sleepingbaghub.com, 0 +sleepingmattressreview.com, 1 +sleeplessbeastie.eu, 0 +sleepmap.de, 1 +sleepo.ga, 1 +sleeps.jp, 1 +sleepstar.co.uk, 1 +sleepstar.fr, 1 +sleio.com, 1 +slemen.tk, 1 +slepsluzbabeograd.org, 1 +sletaem.ml, 1 +sletat.ru, 1 +slev.tk, 1 +slever.cz, 1 +slevermann.de, 1 +slevomat.cz, 1 +slew.gq, 1 +sliceone.com, 1 +slicklines.co.uk, 1 +slicss.com, 1 +slidebatch.com, 1 +slidemembers.com, 1 +slides.zone, 1 +sliferdenver.com, 1 +slik.ai, 1 +slim-planet.com, 1 +slim-slender.com, 1 +slimblogger.com, 1 +slimetutorial.com, 1 +slimk1nd.nl, 1 +slimmarkets.com, 1 +slimopweg.be, 1 +slimspots.com, 1 +slimwindows.gq, 1 +slingo-sta.com, 1 +slingoweb.com, 1 +slink.hr, 1 +slinx.tk, 1 +slipknot-site.tk, 1 +sliptrickrecords.com, 1 +slite.com, 1 +sliteapp.com, 1 +sliverwarthog.cloud, 1 +slix.io, 1 +sllatina.tk, 1 +slma.tk, 1 +slmail.me, 1 +sln.cloud, 1 +slneighbors.org, 1 +slo-net.net, 1 +slo-tech.com, 1 +sloancom.com, 1 +sloanestreetdeli.com, 1 +sloanrealtygroup.com, 1 +sloboda.tk, 1 +slobrowink.com, 1 +sloneczni.pl, 1 +slonep.net, 1 +slopeedge.net, 1 +slopi.net, 1 +slotarazzi.com, 1 +slotfara.com, 1 +slotfara.net, 1 +slothless.com, 1 +sloths.org, 1 +slothy.cloud, 1 +slothy.win, 1 +slotjava.com.br, 1 +slotjava.es, 1 +slotjava.it, 1 +slotlist.info, 1 +slotmad.com, 1 +slotsmegacasino.com, 1 +slouching.ga, 1 +slovenia-trip.tk, 1 +slovenskycestovatel.sk, 1 +slow-coaching.fr, 1 +slow.social, 1 +slow.zone, 0 +slowapi.com, 1 +slowcookingperfected.com, 1 +slowgames.xyz, 1 +slowinski.tk, 1 +slowsocial.email, 1 +slowsocial.eu, 1 +slowsocial.net, 1 +slowsocial.org, 1 +slpm.com, 1 +slpower.com, 0 +slrd-isperih.com, 1 +slrie.de, 1 +slrshoppee.com, 1 +slt24.de, 1 +sluciaconstruccion.com, 1 +slugify.online, 1 +sluhockey.com, 1 +sluimann.de, 1 +sluitkampzeist.nl, 0 +slunecnice.cz, 1 +slunyavchik.tk, 1 +sluo.org, 1 +slusham.com, 1 +slushpool.com, 1 +slutty-girls.cf, 1 +slwilde.ca, 1 +slxh.eu, 1 +slxh.nl, 1 +slymak.com, 1 +slytech.ch, 0 +slyvon.com, 1 +sm-kyoushitsu.com, 1 +sm-supplements.gr, 1 +sm.link, 1 +sm.ms, 1 +sm161.cn, 1 +sm2016.ch, 1 +sma-dev.de, 1 +sma-gift.com, 1 +smackhappy.com, 1 +smadav.ml, 1 +smakassen.no, 1 +smakoszwegrzynka.pl, 1 +smaksbanken.no, 1 +smalandscountryclub.tk, 1 +small-blog.cf, 1 +smallbytedesign.co, 1 +smallchat.nl, 1 +smallcloudsolutions.co.za, 1 +smallcloudsolutions.com, 1 +smallcraftadvisory.tk, 1 +smalldata.tech, 1 +smalle-voet.de, 1 +smallfoot.tk, 1 +smallpath.me, 1 +smalls-world.tk, 1 +smallsites.eu, 1 +smalltalkconsulting.com, 1 +smalltunepress.tk, 1 +smallville.tk, 1 +smallville25.tk, 1 +smallwhitebear.ga, 1 +smaltimento-rifiuti.com, 1 +smaltimento-rifiuti.org, 1 +smaltimento.caserta.it, 1 +smaltimento.milano.it, 1 +smaltimento.napoli.it, 1 +smaltimento.roma.it, 1 +smaltimento.salerno.it, 1 +smaltimentoamianto.campania.it, 1 +smaltimentoamianto.frosinone.it, 1 +smaltimentoamianto.latina.it, 1 +smaltimentorifiuti.firenze.it, 1 +smaltimentorifiuti.livorno.it, 1 +smaltimentorifiuti.milano.it, 1 +smaltimentorifiuti.napoli.it, 1 +smaltimentorifiuti.prato.it, 1 +smaltimentorifiuti.roma.it, 1 +smaltimentorifiuti.veneto.it, 1 +sman1pp.org, 1 +smanson.duckdns.org, 1 +smaragderna.ga, 1 +smares.de, 1 +smarketingbusiness.ca, 1 +smarpshare.com, 1 +smart-cloud.store, 1 +smart-cp.jp, 1 +smart-informatics.com, 1 +smart-ket.com, 1 +smart-media-gmbh.de, 1 +smart-profile.ro, 1 +smart-travel.tk, 1 +smart-tux.de, 1 +smart-wohnen.net, 1 +smart-zona.tk, 1 +smart.gov, 1 +smartacademy.ge, 1 +smartacademy.pro, 1 +smartandcom.ch, 1 +smartandhappychild.ro, 0 +smartart.gr, 1 +smartass.space, 1 +smartass0027.com, 1 +smartassembly.tk, 1 +smartb2balgeria.com, 1 +smartbiz.vn, 1 +smartblock.cloud, 1 +smartboleta.com, 1 +smartcar.com, 1 +smartcents.gold, 1 +smartcleaningcenter.nl, 1 +smartcover.tk, 1 +smartcpa.ca, 1 +smartdb.jp, 1 +smartdigital.ga, 1 +smartdigitech.co.za, 1 +smarteco.tk, 1 +smartedukasi.co.id, 1 +smarterskies.gov, 1 +smartest-trading.com, 1 +smartestate.com, 1 +smartfaktor.pl, 1 +smartfit.cz, 1 +smartfons.tk, 1 +smartftp.com, 1 +smartfuse3d.com, 1 +smartgrid.gov, 1 +smarthdd.com, 1 +smarthealthinnovationlab.com, 1 +smarthome365.nl, 1 +smarthrms.com, 1 +smartime.com.ar, 1 +smartit.gr, 1 +smartjoin.style, 1 +smartleads.tk, 1 +smartlend.se, 1 +smartlinecomputers.nl, 1 +smartlink.sk, 1 +smartlocksmith.com, 1 +smartlogreturns.com, 0 +smartlogstock.com, 0 +smartlogtower.com, 0 +smartlybuy.com, 1 +smartmachine.com, 1 +smartmail24.de, 1 +smartmeal.ru, 1 +smartmessages.net, 1 +smartminibushire.co.uk, 0 +smartmomsmartideas.com, 1 +smartmones.com, 1 +smartpanelsmm.com, 1 +smartpatika.hu, 1 +smartpheromones.com, 1 +smartphone-pliable.wtf, 1 +smartphonecases.tk, 1 +smartphonechecker.co.uk, 1 +smartphones-baratos.com, 1 +smartphonesolution.tk, 1 +smartpolicingplatform.com, 1 +smartpos.net.br, 1 +smartpti.net, 1 +smartrecruit.ro, 1 +smartrentacar.ro, 1 +smartriotour.com.br, 1 +smartrise.us, 1 +smartroofingandsheetmetal.com, 1 +smartservices.nl, 1 +smartshiftme.com, 1 +smartship.co.jp, 1 +smartshoppers.es, 1 +smartsitio.com, 1 +smartspace.ml, 1 +smartsparrow.com, 1 +smartsprouts.com, 1 +smartstep.pt, 1 +smartthursday.hu, 1 +smartvideo.io, 1 +smartwank.com, 1 +smartweb.ge, 1 +smartwoodczech.cz, 1 +smartwritingservice.com, 1 +smartwurk.nl, 0 +smartzona.bg, 1 +smash-gg.club, 1 +smashbros-chile.tk, 1 +smashnl.tk, 1 +smashno.ru, 1 +smb-analytics.pw, 1 +smb445.com, 1 +smbeermen.tk, 1 +smcconsulting.be, 1 +smcconsulting.eu, 1 +smcj.xyz, 1 +smcquistin.uk, 1 +smd-tlt.ru, 1 +smdavis.us, 1 +smdcn.net, 1 +smdtk.com, 1 +sme-gmbh.com, 1 +sme-gmbh.net, 1 +smeetsengraas.com, 1 +smelly.cloud, 1 +smesitel-online.ru, 1 +smeso.it, 1 +smeta.ml, 1 +smetak.cz, 1 +smetbuildingproducts.com, 1 +smexpt.com, 1 +smh.me, 1 +smhatelier.com, 1 +smhotels.com.ph, 1 +smi-a.me, 1 +smialnumenor.tk, 1 +smiatek.name, 1 +smiblog.tk, 1 +smicenter.tk, 1 +smicompact.com, 1 +smictecniservi.com, 1 +smikom.ru, 1 +smileback.co.uk, 1 +smilecon.cf, 1 +smiledirectsales.com, 1 +smilegenerator.tk, 1 +smilemantra.clinic, 1 +smilemantradental.com, 1 +smilenwa.com, 1 +smilesondemand.com, 1 +smilessoftplay.co.uk, 1 +smileytechguy.com, 1 +smileywoodflooring.com, 1 +smilingmiao.com, 1 +smime.io, 1 +smimea.info, 1 +smipty.cn, 1 +smipty.com, 1 +smiraus.cz, 1 +smishnik.tk, 1 +smit.com.ua, 1 +smith-tech.ga, 1 +smith.bz, 1 +smith.co, 0 +smithandellis.com, 1 +smithandnoble.com, 0 +smithchung.eu, 1 +smithcountytxtaxrates.gov, 1 +smithf.red, 1 +smithings.com, 1 +smithsanchez.com, 1 +smithsstational.gov, 1 +smithteresa.tk, 1 +smits.frl, 1 +smkn5smg.sch.id, 1 +smkw.com, 0 +sml.lc, 1 +smlk.org, 1 +smltour.net, 1 +smm.im, 1 +smmcab.ru, 1 +smmlaba.io, 1 +smmpanelweb.com, 1 +smmzilla.net, 1 +smoe.cc, 1 +smokeandmirrors.agency, 1 +smokefree.gov, 1 +smokefreerowan.org, 1 +smokeping.pl, 1 +smokingblendoils.com, 1 +smokinghunks.com, 1 +smokingrio.com.br, 1 +smokingtapes.ga, 1 +smokkelenken.no, 0 +smol.cat, 1 +smolensk-i.ru, 1 +smolensk.ml, 1 +smolensk.tk, 1 +smolkatours.com, 1 +smolnikova.tk, 1 +smoo.st, 1 +smoothgesturesplus.com, 1 +smoothics.at, 1 +smoothics.com, 1 +smoothics.eu, 1 +smoothics.mobi, 1 +smoothics.net, 1 +smoothiecriminals.com, 1 +smoothtalker.com, 1 +smoqerhome.ddns.net, 1 +smorgasblog.ie, 1 +smpetrey.com, 1 +smplace.com, 1 +smplr.uk, 1 +smppcenter.com, 1 +smprecords.nl, 1 +smrdim.cz, 1 +smries.com, 1 +smrtrpck.com, 1 +sms-go.ru, 1 +sms-pro.tk, 1 +sms.storage, 1 +sms1.ro, 1 +sms72.tk, 1 +smsappointment.com, 0 +smsbrana.cz, 0 +smsfa.ir, 1 +smsg-dev.ch, 0 +smsinger.com, 1 +smsk.email, 1 +smsk.io, 1 +smskeywords.co.uk, 1 +smskmail.com, 1 +smslodging.com, 1 +smsprivacy.org, 1 +smsstock.tk, 1 +smstoreoficial.com.br, 1 +smszone.tk, 1 +smtchahal.com, 1 +smtenants.cn, 1 +smtouseef.com, 1 +smtparish.org, 1 +smtpdev.com, 1 +smuhelper.cn, 1 +smuncensored.com, 1 +smuns.ch, 1 +smurffi.net, 1 +smutek.net, 1 +smvcm.com, 1 +smx.net.br, 1 +smxconventioncenter.com, 1 +smyleo.com, 1 +smys.uk, 1 +sn0int.com, 1 +snab-ural.ga, 1 +snabbare-dator.se, 1 +snabbfoting.com, 1 +snabbfoting.se, 1 +snabbit-support.nu, 1 +snabbit-support.se, 1 +snacdata.com, 1 +snack-online.com, 1 +snackbesteld.nl, 1 +snacky.nl, 1 +snafarms.com, 1 +snafu.cz, 1 +snajdr.online, 1 +snajdrova.eu, 1 +snakafya.com, 1 +snake.dog, 0 +snakeanarchy.tk, 1 +snakejs.ga, 1 +snakesandladders.tk, 1 +snap.com, 1 +snapappointments.com, 1 +snapappts.com, 1 +snapfinance.com, 1 +snapintegrations.net, 1 +snapserv.ch, 1 +snapserv.net, 1 +snapsh.com, 1 +snaptools.io, 1 +snarf.in, 1 +snargol.com, 1 +snatch-note.tk, 1 +snatch.com.ua, 1 +snatertlc.it, 1 +snatti.com, 1 +snazel.ae, 1 +snazel.co.il, 1 +snazel.co.uk, 1 +snazel.de, 1 +snazel.ee, 1 +snazel.uk, 1 +snazzie.nl, 1 +snb.com, 1 +sncdn.com, 1 +snd-zentrum.de, 1 +sndbouncycastles.co.uk, 1 +sndcdn.com, 1 +snea-kers.tk, 1 +sneak.berlin, 1 +sneaker.date, 1 +sneakers-sports.tk, 1 +sneakers88.it, 1 +sneakersmexs.com, 1 +sneakpod.de, 1 +sneakycode.net, 1 +sneakynote.com, 1 +sneakypaw.com, 1 +sneberger.cz, 0 +sneed.company, 1 +sneed.it, 1 +sneedit.com, 1 +sneedit.de, 1 +snegozaderzhatel.ru, 1 +snel4u.nl, 1 +snelbv.nl, 1 +snelshops.nl, 1 +snelwebshop.nl, 1 +snelwegzen.nl, 1 +snem.tk, 1 +snerith.com, 1 +snetts.com, 1 +snfdata.com, 0 +sngallery.co.uk, 1 +sngeo.com, 1 +sngnews.tk, 1 +sngukrainatv.tk, 1 +snh48live.org, 1 +snic.website, 1 +sniderman.eu.org, 1 +sniderman.org, 1 +sniderman.pro, 1 +sniderman.us, 1 +sniderman.xyz, 1 +sniep.net, 1 +sniffing.gq, 1 +snight.co, 1 +snille.com, 1 +snip.city, 1 +snipdrive.com, 1 +snipermarkettiming.com, 0 +snipl.io, 1 +snippet.host, 1 +snippet.wiki, 0 +snitch.rocks, 1 +snizl.com, 1 +snj.pt, 1 +snohomishsepticservice.com, 1 +snoopyfacts.com, 1 +snoot.club, 1 +snopyta.com, 1 +snopyta.org, 1 +snorkelaroundtheworld.com, 1 +snortfroken.net, 1 +snote.io, 1 +snoupon.com, 1 +snow-online.com, 1 +snow-online.de, 1 +snow-service.it, 1 +snow.dog, 0 +snowalerts.nl, 1 +snowatka.com, 1 +snowboard-break.tk, 1 +snowboardforum.tk, 1 +snowchamps.nl, 1 +snowcrestdesign.com, 1 +snowdon.io, 1 +snowdrop.moe, 1 +snowdy.dk, 1 +snowdy.eu, 1 +snowdy.link, 1 +snowhana.com, 1 +snowhaze.ch, 1 +snowhaze.com, 1 +snoworld.one, 1 +snowpak.com, 1 +snowparties.com, 1 +snowpaws.de, 1 +snowplane.net, 1 +snowplanet.tk, 1 +snowraven.de, 1 +snowreport.io, 1 +snowrippers.ro, 0 +snowsubs.moe, 1 +snowvictoria.ga, 1 +snowy.ink, 1 +snowy.land, 1 +snowyluma.com, 1 +snowyluma.me, 1 +snperformance.gr, 1 +snrat.com, 1 +snrd.de, 1 +snroth.de, 1 +snrub.co, 1 +sns.med.sa, 1 +snsdomain.com, 1 +snsirius.cf, 1 +sntial.co.za, 1 +snuff.porn, 1 +snukep.kr, 1 +snwsjz.com, 1 +so-buff.com, 1 +so-commerce.com, 1 +so-link.co, 1 +so.is-a-cpa.com, 1 +soacompanhantes.vip, 1 +soakgames.com, 1 +soap-teco.com, 1 +soapex.com, 1 +soapitup.com.au, 1 +soaringdownsouth.com, 1 +soaringtoglory.com, 1 +soat.fr, 1 +sobakasite.tk, 1 +sobaki.tk, 1 +sobaya-gohei.com, 1 +sobchak.ga, 1 +sobczakdesign.de, 1 +sobeelectronics.com, 1 +sobersys.com, 1 +sobie.ch, 1 +sobieray.dyndns.org, 1 +soblaznenie.ru, 1 +soblaznenie2.ru, 1 +sobreitalia.com, 1 +sobreporcentagem.com, 1 +soc.com.br, 1 +soc.net, 1 +socal-babes.com, 1 +socaliente.fr, 1 +socatel.cf, 1 +soccernews.id, 1 +soccers.fr, 1 +soccorso-stradale.org, 1 +socheap.win, 1 +sochi-sochno.ru, 1 +sochi.ooo, 1 +sochic.in, 1 +sochidostavka.com, 1 +sochionline.tk, 1 +sochisan.com, 1 +sochiss.ru, 1 +soci.ml, 1 +sociability.dk, 1 +social-class.ga, 1 +social-directory-list.tk, 1 +social-events.net, 0 +social-line.tk, 1 +social-media-strategies.it, 1 +social-media-strategy.org.uk, 1 +social-network.tk, 1 +social-work-colleges.com, 1 +social-work.tk, 1 +social.com.co, 1 +socialair.tk, 1 +socialblaze.com.au, 1 +socialclimb.com, 1 +socialdemo.ga, 1 +socialdevelop.biz, 0 +socialeyesthailand.com, 1 +socialhams.net, 1 +socialistyouth.tk, 1 +socializator.tk, 1 +sociallyunited.net, 1 +socialmark.mx, 1 +socialmarketingday.nl, 1 +socialmedia-manager.gr, 1 +socialmeeps.ml, 1 +socialnet.ml, 1 +socialnews.ga, 1 +socialnitro.com, 1 +socialnous.co, 1 +socialplanet.pl, 1 +socialproject.ml, 1 +socialrank.com, 1 +socials.gq, 1 +socialsecrets-coaching.de, 1 +socialsecurity.gov, 0 +socialstrata.com, 1 +socialsurvivalist.net, 1 +socialtactics.cf, 1 +socialtournaments.com, 1 +socialtranslation.ga, 1 +socialtrends.pl, 0 +socialwave.tk, 1 +socialworkout.com, 1 +socialworkout.net, 1 +socialworkout.org, 1 +socialworkout.tv, 1 +sociedadcivil.tk, 1 +sociedadecologica.tk, 1 +sociedadsostenible.tk, 1 +societe-chablaisienne-de-revetements.com, 1 +societe-chablaisienne-de-revetements.fr, 1 +societyhilldance.com, 1 +societyparty.ga, 1 +sociobiology.com, 1 +sociology-bg.gq, 1 +sociology-schools.com, 1 +sociologyk.nl, 1 +sociopampers.com.ar, 1 +sociopathy.org, 1 +sociusian.gq, 1 +socket.social, 1 +sockeye.io, 0 +sockfetish.net, 1 +sockscap64.com, 1 +socktopus.io, 1 +socoastal.com, 1 +socomforums.tk, 1 +socraticsolutions.us, 1 +socstation.com, 1 +soczu.duckdns.org, 1 +soda.ga, 1 +sodadigital.com.au, 1 +sodafilm.de, 1 +sodalai.tk, 1 +sodelicious.recipes, 1 +soderestore.com, 1 +sodermans.com, 1 +soderparr.com, 1 +sodexam.pro, 1 +sodi.gent, 1 +sodi.nl, 1 +sodiao.cc, 1 +sodigent.be, 1 +sodigent.gent, 1 +sodiummedia.com, 1 +sodo.top, 1 +sodomojo.com, 1 +sodsouthernindiana.com, 1 +soe-server.com, 1 +soeasy.co.za, 1 +soegi-haru.com, 1 +soepvork.nl, 1 +sofa-bed.tk, 1 +sofa-rockers.org, 1 +sofabedshop.de, 1 +sofaclean.co.uk, 1 +soffit.com, 1 +sofgen.com, 1 +sofi.codes, 1 +sofiadaoutza.gr, 1 +sofiaestado.com, 1 +sofialobocera.com, 1 +sofianeves.tk, 1 +sofiavanmoorsel.com, 1 +sofidelshop.blog, 1 +sofiesteinfeld.com, 1 +sofiesteinfeld.de, 1 +sofoco.us, 1 +sofortcutie24.de, 1 +sofortimplantate-muenchen.de, 1 +sofpedia.ro, 0 +soft-key.tk, 1 +soft-office.tk, 1 +soft-search-system.tk, 1 +soft-valley.net, 1 +soft41.ru, 1 +softandbouncy.co.uk, 1 +softanka.com, 1 +softbabyducks.com, 1 +softbit.pt, 1 +softblinds.co.uk, 1 +softchin.ir, 1 +softconcept.pt, 1 +softcreatr.com, 1 +softcreatr.de, 1 +softfay.com, 1 +softios.com, 1 +softlan.com.py, 1 +softly.sk, 1 +softonic.com, 1 +softonic.com.br, 1 +softonic.com.tr, 1 +softonic.jp, 1 +softonic.pl, 1 +softonic.vn, 1 +softonline.net, 1 +softowa.com, 1 +softpark.ml, 1 +softplay4hire.co.uk, 1 +softprayog.in, 1 +softrobot.se, 1 +softsecmatheodexelle.be, 1 +softsite.cl, 1 +softskills.tech, 1 +softstack.ru, 1 +softtennis-zenei.com, 1 +softview.tk, 1 +softw.net, 1 +software-search.com, 1 +software-tech.tk, 1 +software-voor-projecten.nl, 1 +software.rocks, 1 +softwarebeveiligingtestdomein.be, 1 +softwarecloud.ml, 1 +softwareclub.tk, 1 +softwaredesign.foundation, 0 +softwarepara.net, 1 +softwarepatenten.tk, 1 +softwaresecurityandradefernando.be, 1 +softwaterinc.com, 1 +softweb-dev.de, 1 +softwerk-edv.de, 1 +softwing.de, 1 +softwsabri.be, 1 +softyak.com, 1 +sog-gilde.tk, 1 +sogeek.me, 1 +sogo.com.my, 1 +sogola.com, 1 +sogravatas.com.br, 1 +sogravatas.net.br, 1 +sogutma.com.tr, 1 +sohamroy.me, 1 +sohanakhan.tk, 1 +sohka.eu, 1 +sohomattress.in, 0 +soia.ca, 1 +soilegustafsson.fi, 1 +sointelcom.com.co, 1 +soinvett.com, 0 +soji.io, 1 +sokak-sanati.tk, 1 +sokenconstruction.com, 1 +soket.ee, 1 +sokkenhoek.nl, 1 +soko.nl, 1 +sokolkarvina.cz, 1 +sokolovskyi.ml, 1 +sokosport.com, 1 +sokouchousa.net, 1 +sokrabatt.se, 1 +sol-3.de, 0 +sol-computers.es, 1 +sol-design.jp, 1 +sol-negro.tk, 1 +sol24.net, 1 +solace.com, 1 +solacyre.ch, 0 +solalt.com, 1 +solana-active.tk, 1 +solar-ec.com, 1 +solar-floodlight.ca, 1 +solar-systems.ca, 1 +solar-window.ca, 1 +solarace.tk, 1 +solaradventures.icu, 1 +solareagricola.it, 1 +solarfever.ga, 1 +solargaming.tk, 1 +solarhome.ml, 1 +solariilacheie.ro, 1 +solarium.gov, 1 +solarloon.com, 1 +solaronics.tk, 1 +solarpanels.tk, 1 +solarplan-berlin.de, 1 +solarstrom.net, 1 +solartek.cf, 1 +solartek.ga, 1 +solartrackerapp.com, 1 +solartravel.tk, 1 +solarwave.tk, 1 +solarwind.cf, 1 +solautoescuela.com, 1 +solaxfaq.com, 1 +solbjer.se, 1 +soldamontanhabeachwear.com.br, 1 +soldarizona.ga, 1 +soldaten-genealogie.tk, 1 +solden.be, 1 +soldesduck.be, 1 +soldesduck.ch, 1 +soldierangels.tk, 1 +sole-erdwaermetauscher.de, 1 +soleanos.tk, 1 +soledadmataro.tk, 1 +soledadpenades.com, 0 +solemare-hotel.it, 1 +solentbasketball.co.uk, 1 +solentbubblesandbounce.co.uk, 1 +solepurposetest.com, 1 +solfegiator.ch, 0 +soli.cafe, 1 +solicafe.at, 1 +solidariedadecultura.pt, 1 +solidarita-kosovo.net, 1 +solidarityzone.org, 1 +solidform.ml, 1 +solidhost.cf, 1 +solidimage.com.br, 1 +solidincome.ga, 1 +solidnet.software, 1 +solidnetwork.org, 1 +solidrop.net, 1 +solidshield.com, 1 +solidsteel.tk, 1 +solidtuesday.com, 1 +soliftstore.com, 1 +soligorsk.place, 1 +solihullcarnival.co.uk, 1 +solihullinflatables.com, 1 +solihulllionsclub.org.uk, 1 +solihullpcrepairs.co.uk, 1 +solisboutique.com.au, 1 +solisrey.es, 1 +solit.systems, 1 +solitairenetwork.com, 1 +solitaryride.com, 1 +soliten.de, 1 +solmek.co.uk, 1 +solnascentepapelaria.com.br, 1 +solntsezaschitnye-ochki.tk, 1 +solo.com.sa, 1 +solocalcetines.com, 1 +solochubasqueros.com, 1 +solofajas.online, 1 +solofi.fr, 1 +sologetaway.ga, 1 +sologoc.com, 1 +sologstrand.com, 1 +sologstrand.dk, 1 +sologstrand.nl, 1 +sologstrand.no, 1 +sologstrand.se, 1 +soloinfo.it, 1 +soloingenieria.tk, 1 +sololabs.com, 1 +solomisael.com, 1 +solomo.pt, 1 +solomonsklash.io, 1 +soloparaguas.com, 1 +soloparati.cf, 1 +soloroboto.com, 1 +solos.im, 1 +solostocks.cl, 1 +solostocks.com, 1 +solostocks.com.ar, 1 +solostocks.com.br, 1 +solostocks.com.co, 1 +solostocks.com.mx, 1 +solostocks.de, 1 +solostocks.fr, 1 +solostocks.it, 1 +solostocks.ma, 1 +solostocks.net, 1 +solostocks.pl, 1 +solostocks.pt, 1 +solovey.su, 1 +solovyovalawfirm.com, 1 +solsi.ga, 1 +solsocog.de, 1 +solucionesihd.com, 1 +solucionespicadelly.com, 1 +solucionupsperu.com, 1 +solunci-loznica.tk, 1 +solutionmotsfleches.com, 1 +solutions-teknik.com, 1 +solutionsforest.com.ar, 0 +solutiontestbank.com, 1 +soluzionifightlist.cf, 1 +solvation.de, 1 +solvaybank.com, 1 +solve-it-sol.com, 1 +solve.co.uk, 1 +solved.tips, 1 +solvedapp.io, 1 +solvemethod.com, 1 +solvewebmedia.com, 1 +solviejo.tk, 1 +solvin.com, 1 +solvingforu.com, 1 +solvingproblems.com.au, 1 +solviq.com, 1 +solvops.com, 1 +solxsys.com, 1 +solymar.co, 1 +soma.com.au, 1 +somaini.li, 1 +somaliagenda.com, 1 +somaliaonline.com, 1 +somalilandtalk.tk, 1 +somanao.com, 1 +sombemerchant.com, 1 +somecrazy.com, 1 +somefe.pt, 1 +somehowsomeday.com, 1 +somehsara.tk, 1 +somerm.com, 1 +somersetdev.com, 1 +somersetscr.nhs.uk, 1 +somersetwellbeing.nhs.uk, 1 +someserver.cf, 1 +something-else.cf, 1 +somethingsimilar.com, 1 +somethingsketchy.net, 1 +somewherein.jp, 1 +somewherenews.cf, 1 +sominemo.com, 1 +somix.com, 1 +soml.best, 1 +soml.ml, 1 +sommefeldt.com, 1 +sommeilsante.com, 1 +sommerhusudlejning.com, 1 +somnam.tk, 1 +somnomedics.eu, 1 +somnusoft.com, 1 +somogyivar.hu, 1 +somom.com, 1 +somosbrujas.com, 1 +somosdefensores.org, 1 +somosgesath.com, 1 +somoshuemul.cl, 1 +somoslaarmenia.com, 1 +somosti.cl, 1 +somosweb.cf, 1 +somoyorkies.com, 1 +somuchbetterwithage.com, 1 +somweyr.de, 1 +son-onlajn.tk, 1 +son-tolkovatel.gq, 1 +sona-gaming.com, 1 +sona-systems.cn, 1 +sona-systems.jp, 1 +sona.fr, 1 +sonacupalova.cz, 1 +sonar.ga, 1 +sonaraamat.com, 1 +sonarqube.com, 0 +sonate.jetzt, 1 +sonavankova.cz, 1 +sondebase.com, 1 +sonder.com.au, 1 +sonderfloral.com, 1 +sondergaard.de, 1 +sonderkomission.ch, 1 +sondersobk.dk, 1 +sonesinafar.tk, 1 +sonesisonesi.tk, 1 +sonesonesisi.tk, 1 +song.ski, 1 +songdew.com, 1 +songesdeplumes.fr, 1 +songlifty.com, 1 +songmp3.live, 1 +songsmp3.co, 1 +songsmp3.com, 1 +songsonline.tk, 1 +songsterr.com, 1 +songsthatsavedyourlife.com, 1 +songtianyi.com, 1 +songun.ml, 1 +songyang.cn, 1 +songzhuolun.com, 1 +sonia.ai, 1 +sonia.com, 1 +sonia.com.au, 1 +soniaai.com, 1 +soniaferrer.tk, 1 +sonic.sk, 0 +sonic.studio, 1 +sonicdoe.com, 1 +sonicrainboom.rocks, 1 +sonicseo.co.uk, 1 +sonicworld.tk, 1 +sonidoslibertarios.tk, 1 +sonik.tk, 1 +sonimei.cn, 1 +soninger.ru, 1 +sonix.dk, 1 +sonixonline.com, 1 +sonja-daniels.com, 1 +sonja-kowa.de, 1 +sonmark.ru, 1 +sonnenbergharrison.law, 1 +sonnenta.de, 1 +sonneundstrand.de, 1 +sonnik-znachenie-sna.ga, 1 +sonodrom.tk, 1 +sonoecoracao.com.br, 1 +sonofsunart.com, 1 +sonologic.nl, 1 +sonology.tk, 1 +sonomacounty.gov, 1 +sonomacountywriterscamp.com, 1 +sonometro.online, 1 +sons.cf, 1 +sons.tk, 1 +sonsight.tk, 1 +sony-psvita.ru, 1 +sonyashappenings.com, 1 +sonyunlock.nu, 1 +soohealthy.nl, 1 +soomee.be, 1 +soomee1.be, 1 +soontm.de, 1 +soopure.nl, 1 +soora.jp, 1 +sopelaotaez.tk, 1 +sopenguin.com, 1 +soph.jp, 1 +soph.tk, 1 +soph.us, 1 +sopheos.com, 0 +sopher.io, 1 +sophi.online, 1 +sophia-mood.com, 1 +sophiaandmatt.co.uk, 1 +sophiahatstudio.com, 1 +sophiakligys.com, 1 +sophias-haarmanufaktur.de, 1 +sophiebreslin.co.uk, 1 +sophiefrutti.gr, 1 +sopira.ru, 1 +sopo.me, 1 +soportelatino.ml, 1 +sopra.tk, 1 +soprabalao.com.br, 1 +sopronforras.tk, 1 +soquee.net, 1 +sor.so, 1 +soraharu.com, 1 +soraiaschneider.com.br, 1 +sorakumo.jp, 1 +sorbire.com, 1 +sorcix.com, 1 +sorellecollection.com.au, 1 +soren.xyz, 1 +sorenstudios.com, 1 +sorincocorada.ro, 1 +sorn.service.gov.uk, 1 +sorpresashop.nl, 1 +sorrowfulunfounded.com, 1 +sort.land, 1 +sortaweird.net, 0 +sortesim.com.br, 1 +soruly.com, 1 +soruly.io, 1 +soruly.moe, 1 +soruly.net, 1 +soruly.org, 1 +sorx.tech, 1 +sorz.org, 1 +sos-elettricista.it, 1 +sos-fabbro.it, 1 +sos-falegname.it, 1 +sos-idraulico.it, 1 +sos-loodgieter.com, 1 +sos-muratore.it, 1 +sos-zimmerpflanzen.de, 1 +sos.sk, 0 +sos.vg, 1 +sos.yt, 1 +sosaka.ml, 1 +sosaka.tk, 1 +sosecu.red, 1 +sosedisetka.tk, 1 +sosesh.shop, 1 +sosgate.com, 1 +sosisuka.ga, 1 +sosko.in.rs, 1 +soslsd.org, 1 +sosmicro.tk, 1 +sosnovka.ga, 1 +sosoftplay.co.uk, 1 +sosok.tk, 1 +sosou.eu, 0 +sospeed.net, 1 +sosregistration.eu, 1 +sostacancun.com, 1 +sosteam.jp, 1 +sosteric.si, 1 +sostm.org, 1 +sot-te.ch, 1 +sot.blue, 1 +sot.red, 1 +sotadb.info, 1 +sotar.us, 1 +sotayhoctap.com, 1 +sotaytienganh.com, 1 +soterdev.com, 1 +sotermic.cl, 1 +sotin-hr.tk, 1 +sotiran.com, 1 +sotnya.cf, 1 +sotnyk.ml, 1 +sotoasobi.net, 1 +sotocine.tk, 1 +sotolar.com, 1 +sotolar.net, 1 +sotsiaalkindlustusamet.ee, 1 +sottilealimentos.com.br, 1 +sottm.com.au, 1 +sotypicallydutch.nl, 1 +soubriquet.org, 1 +soufastnet.com.br, 1 +sougou.com, 1 +souked.com, 1 +soukka-seura.fi, 1 +soukodou.jp, 1 +soul-source.co.uk, 1 +soulc.ml, 1 +soulcasa.com.br, 1 +soulconstructors.com, 1 +soulcrazy.org, 1 +soulema.com, 1 +souletter.com, 1 +souleymanecamara.com, 1 +soulike.tech, 1 +soulinbusiness.ga, 1 +soulla.tk, 1 +soulmate.dating, 1 +soulmating.de, 1 +soulplay.com, 1 +soulpowercoaching.ga, 1 +soulshinecreators.com, 1 +soulsinner.tk, 1 +soulsteer.com, 0 +soulveda.com, 1 +soulwinning.tk, 1 +souly.cc, 1 +soumikghosh.com, 1 +soumya.xyz, 1 +soumya92.me, 1 +sounavholidays.com, 1 +sound-recording.org, 1 +sound.as, 1 +soundabout.nl, 1 +soundar.eu.org, 1 +soundblast.tk, 1 +soundcamp.org, 1 +soundclick.com, 1 +soundcloud.com, 1 +soundcloud.org, 1 +soundeo.com, 1 +soundeo.net, 1 +soundforsound.co.uk, 1 +soundgasm.net, 1 +soundgo.gq, 1 +soundhunter.xyz, 0 +soundinthesignals.tk, 1 +soundlight.tk, 1 +soundman.ga, 1 +soundmoney.club, 1 +soundmoney.page, 1 +soundmoney.tech, 1 +soundorabilia.com, 1 +soundprotectionllc.com, 1 +soundrecords.tk, 1 +soundrelief.com, 1 +sounds-familiar.info, 1 +sounds.koeln, 1 +soundtrash.tk, 1 +soundtruckandautorepair.com, 1 +soundtube.tk, 1 +soundviz.fr, 1 +soundzimega.tk, 1 +soungui.cm, 1 +soungui.com, 1 +soungui.net, 1 +sounm.com, 1 +soupbuahtaza.id, 1 +soupcafe.org, 1 +souqtajmeel.com, 1 +sour.is, 1 +souravbhor.gq, 1 +souravbhor.ml, 1 +sourcebox.be, 1 +sourcecode.hosting, 1 +sourcecode.love, 1 +sourcecode.tw, 1 +sourcelair.com, 0 +sourcely.net, 1 +sourceway.de, 1 +sourcing4exports.co.uk, 1 +sourcitec.com, 1 +sourdough.vc, 1 +souris.ch, 0 +sourmatt.xyz, 1 +sous-surveillance.net, 0 +souspind.com.br, 1 +southafrican.dating, 1 +southambouncycastle.co.uk, 1 +southamerican.dating, 1 +southbankregister.com.au, 1 +southbaylatherapy.com, 1 +southbendflooring.com, 1 +southbridge-ma.gov, 1 +southcountyplumbing.com, 1 +southdakotahealthnetwork.com, 1 +southeastradiology.com, 1 +southeastvalleyurology.com, 1 +southernforge.com, 1 +southernlights.cf, 1 +southernlights.club, 1 +southernlights.gq, 1 +southernmost.us, 1 +southernsurgicalga.com, 1 +southernutahinfluencers.com, 1 +southernviewmedia.com, 1 +southessexstatus.co.uk, 1 +southflanewsletter.com, 1 +southlakenissanparts.com, 1 +southlakesinc.org, 1 +southlandurology.com, 1 +southmarengo.com, 1 +southmelbourne.apartments, 1 +southmill.com, 1 +southmorangtownhouses.com.au, 1 +southocpt.com, 1 +southogdencity.gov, 1 +southokcurology.com, 1 +southpawmoto.com, 1 +southpointcollision.com, 1 +southridgeservices.com, 1 +southside-crew.com, 1 +southside-digital.co.uk, 1 +southside-tuning-day.de, 1 +southsidebargaincenter.com, 1 +southsideshowdown.com, 1 +southwestrda.org.uk, 1 +southwindsor-ct.gov, 1 +soutien-naissance.com, 1 +souvenirs-gifts.tk, 1 +souzanabellydance.com, 1 +sova.cc, 1 +sova.st, 1 +sovendus.com, 1 +sovendus.de, 1 +sovereignartfoundation.com, 1 +sovereignpcs.com, 1 +soverin.net, 0 +sovhoz.tk, 1 +sovmestimost-goroskop.cf, 1 +sovmestimost-goroskop.ga, 1 +sovmestimost-goroskop.gq, 1 +sovmestimost-goroskop.ml, 1 +sovmestimost-zodiak.gq, 1 +sovraindebitamento.net, 1 +sovremenik.tk, 1 +sovxoz.gq, 1 +sowhat.dk, 1 +sowncloud.de, 1 +sowtarabiya.com, 1 +soya.com.ua, 1 +soybase.org, 1 +soychef.today, 1 +soydemac.com, 1 +soydoula.com, 1 +soydxn.com, 1 +soyjak.party, 1 +soykaf.eu, 1 +soyladani.com, 1 +soytusitio.com, 1 +soyuznik.ml, 1 +soyvigilante.com, 1 +sozai-good.com, 1 +sozdanie-krana.ml, 1 +sozialabstand.de, 1 +soziale.email, 1 +sozialistische-gruppe.de, 1 +sozialstation-ritterhude.de, 1 +sozialy.com, 1 +sozon.ca, 1 +sp-codes.de, 1 +sp-magic.de, 1 +sp-pallotti.pl, 1 +sp-pn.com, 1 +sp-sites.com.au, 1 +sp.com.pl, 1 +sp.rw, 1 +sp8ce.co, 1 +spa-center.tk, 1 +spabellabolivia.com, 1 +spac2stock.com, 1 +space-inc.co.jp, 1 +space-it.de, 1 +space-net.ml, 1 +space-y.cf, 1 +spaceage.mp, 1 +spaceanimalnutrition.com, 1 +spaceapi.io, 1 +spaceart.de, 1 +spacebabies.nl, 1 +spacebear.ee, 1 +spacebestnews.tk, 1 +spacecaps.xyz, 1 +spacedirectory.org, 1 +spacedots.net, 1 +spacehighway.ms, 1 +spacehighways.net, 1 +spacehost.de, 1 +spacelabs.io, 1 +spacelandpark.ga, 1 +spaceon.tk, 1 +spacepage.be, 1 +spacepirates.tk, 1 +spacesas.com, 1 +spaceshells.tk, 1 +spacestation13.com, 1 +spacetime.am, 1 +spaceunique.de, 1 +spaceunique.eu, 1 +spacinov.com, 1 +spacivox.com, 1 +spackmanimages.com, 1 +spackova.cz, 1 +spaconnection.com, 1 +spactostock.com, 1 +spaenny.tf, 1 +spaghettiphreakers.tk, 1 +spaghettiwesterns.tk, 1 +spahireleeds.co.uk, 1 +spaid.xyz, 0 +spainpol.es, 1 +spakurort.eu, 1 +spalnobelyo.com, 1 +spaltron.net, 1 +spam.lol, 1 +spamasaurus.com, 1 +spamdrain.com, 1 +spamloco.net, 1 +spamty.eu, 1 +spamwc.de, 1 +spanch.cf, 1 +spanch.ga, 1 +spanch.gq, 1 +spanch.ml, 1 +spanch.tk, 1 +spanchelele.cf, 1 +spanchelele.gq, 1 +spanchelele.ml, 1 +spanchelele.tk, 1 +spanda.io, 1 +spanien.guide, 1 +spanier.es, 1 +spanischunterricht.tk, 1 +spanishfox.com, 1 +spanishnow.tk, 1 +spanjeflydrive.nl, 1 +spanmass-portal.org, 1 +spanner.tk, 1 +spanner.works, 1 +spanpine.gq, 1 +spantrix.com, 1 +spanyolul.hu, 1 +spar-ni.co.uk, 1 +sparanoid.blog, 1 +sparanoid.com, 1 +sparanoid.net, 1 +sparanoid.network, 1 +sparanoidstatus.com, 1 +sparendirekt.at, 1 +sparkandpook.com, 1 +sparkar.com, 1 +sparkasse.de, 1 +sparkbase.cn, 1 +sparkforautism.org, 1 +sparkl.fm, 1 +sparklark.com, 1 +sparklatvia.lv, 1 +sparklebastard.com, 1 +sparklesdelivery.com, 1 +sparkletowels.com, 1 +sparklewindowcleaners.co.za, 1 +sparklingessentials.ga, 1 +sparklingloungecampiglio.it, 1 +sparkplug.tk, 1 +sparkresearch.net, 1 +sparkweb.com.au, 1 +sparkwood.org, 1 +sparkz.no, 1 +sparmedo.de, 1 +sparprofi.at, 1 +sparqmedia.nl, 1 +sparta-en.org, 1 +sparta-szczekociny.tk, 1 +sparta-upice.tk, 1 +spartac.be, 1 +spartacuslife.com, 1 +spartaermelo.nl, 1 +spartamet.tk, 1 +spartancoin.ooo, 1 +spartanis.tk, 1 +spartankids.in, 1 +spartantheatre.org, 1 +sparumzuege.de, 1 +spasicilia.it, 1 +spatiugratis.tk, 1 +spatter.cf, 1 +spatter.tk, 1 +spatzenwerkstatt.de, 1 +spawn.cz, 1 +spaysy.com, 1 +spaziobenedetti.com.br, 1 +spaziopervoi.com.br, 1 +spazturtle.co.uk, 1 +spazzacamino.roma.it, 1 +spb-xiaomi.ru, 1 +spb.ooo, 1 +spbet99.com, 1 +spcollege.edu, 1 +spd-porta-westfalica.eu, 1 +spdepartamentos.com.br, 1 +spdf.net, 1 +spdfund.org, 1 +spdi.com.cn, 1 +spdillini.com, 1 +spe.org.co, 1 +speac.jp, 1 +speak-polish.com, 1 +speakeasy.co, 1 +speaker-animateur.com, 1 +speakermatch.com, 1 +speakersbusiness.com, 1 +spear.ga, 1 +specdrones.us, 1 +special-equipment.tk, 1 +specialcameras.tk, 1 +specialeffect.tk, 1 +specialelectronics.tk, 1 +specialized-hosting.eu, 1 +specialofficesupplies.tk, 1 +specialprojectsdesk.com, 1 +specialproperties.com, 1 +specialtechnique.tk, 1 +specialtyalloys.ca, 1 +specialtyjets.ca, 1 +specialtyrigging.com, 1 +specialworld.ml, 1 +speciauxquebec.com, 1 +speciesism.com, 1 +specificenergy.com, 1 +speckrot.ru, 1 +specks.tk, 1 +spectre-network.tk, 1 +spectre.com.br, 1 +spectrosoftware.de, 1 +spectrum-markets.com, 1 +spectrum.gov, 1 +spectrumelectrical-brisbane.com.au, 1 +spediscifiori.com, 1 +spedizioni.roma.it, 1 +speech-balloon.com, 1 +speechdrop.net, 1 +speechmate.com, 1 +speechmore.ml, 1 +speechndraw.com, 0 +speed-bonus.tk, 1 +speed-strike.tk, 1 +speedcam.tk, 1 +speeddate.it, 0 +speeder-vpn.tk, 1 +speeder.best, 1 +speeder.cf, 1 +speeder.im, 1 +speeders.cf, 1 +speeders.ga, 1 +speederss.best, 1 +speedhoundz.com, 1 +speedliner.com, 1 +speedof.me, 1 +speedracer.ca, 1 +speedsportofhull.co.uk, 1 +speedsvip.cc, 1 +speedsvip.net, 1 +speedtailors.com, 1 +speedtemplate.de, 1 +speedtest-russia.com, 1 +speedwaybusinesspark.com, 1 +speedwp.ch, 1 +speedychat.it, 1 +speedyplatypus.com, 1 +speeli.com, 1 +speeltoneel.nl, 1 +speerpunt.info, 1 +speets.ca, 1 +spegeltankar.tk, 1 +speich.net, 1 +speights-law.com, 1 +spek.tech, 1 +speletrodomesticos.com.br, 1 +spellcheck24.net, 1 +spellchecker.net, 1 +spellic.com, 1 +spelling.ml, 1 +spendable.money, 1 +spendo.gq, 1 +spendwise.com.au, 1 +spenglerei-shop.de, 1 +spenny.tf, 1 +sperandii.it, 1 +spermosens.com, 1 +spero.solutions, 1 +sperrstun.de, 1 +spertto.com, 1 +spesys-services.fr, 1 +spetsialist.cf, 1 +spettacolocame.ga, 1 +speventos.es, 1 +spewingmews.moe, 1 +speww.com, 1 +spfl.org.au, 1 +spha.info, 1 +sphacks.io, 1 +sphardy.com, 0 +sphera.com, 1 +sphere-realty.com, 1 +sphereblur.com, 1 +sphericalvision.cz, 1 +sphido.org, 0 +sphinx.network, 1 +sphynx-cats.com, 1 +sphynx.vn, 1 +spicegirlschart.tk, 1 +spicejungle.com, 1 +spicemail.cc, 1 +spicemoney.com, 1 +spichki.tk, 1 +spicture.in, 1 +spicydog.org, 1 +spicydog.tk, 1 +spicymatch.com, 1 +spicystove.com, 1 +spicywombat.com, 1 +spidercrabs.tk, 1 +spidermail.tk, 1 +spidernet.tk, 1 +spideroak.com, 1 +spiders.org.ua, 1 +spidersweb.ga, 1 +spidometr.ml, 1 +spidometrus.ru, 1 +spiegels-op-maat.nl, 0 +spieka.info, 1 +spielezar.ch, 1 +spielland.ch, 1 +spiellawine.de, 1 +spielmit.com, 1 +spieltexte.de, 1 +spiet.nl, 1 +spiga.ch, 0 +spike.sh, 1 +spikefishdesigns.com, 1 +spikejeon.tk, 1 +spikelands.com, 1 +spilka-dyplomativ.tk, 1 +spillersfamily.net, 0 +spillforum.no, 1 +spillmaker.no, 0 +spilnu.dk, 1 +spinal.ga, 1 +spind.energy, 1 +spindle.com.ph, 1 +spinecomms.com, 1 +spinemexin.tk, 1 +spinner.dnshome.de, 1 +spinning-portugal.com, 1 +spinpay.com.br, 1 +spins.fedoraproject.org, 1 +spira.kiev.ua, 1 +spiralstabilization.com, 1 +spirella-shop.ch, 1 +spirit-hunters-germany.de, 0 +spirit55555.dk, 1 +spiritbionic.ro, 1 +spiritdesigns.tk, 1 +spiritous.cf, 1 +spiritual.dating, 1 +spiritualife.net, 1 +spiritualites.ch, 0 +spiritualityrise.com, 1 +spiritworld.ml, 1 +spiro.se, 1 +spiroduct.gr, 1 +spisbilligt.dk, 1 +spiski-domenov.tk, 1 +spisochek.tk, 1 +spisok-domenov.tk, 1 +spit.com.au, 1 +spitfiredialers.com, 1 +spitfireuav.com, 1 +spithoven.tk, 1 +spjaet.dk, 1 +splashily.gq, 1 +splashstoretw.com, 1 +spleis.no, 1 +splendidspoon.com, 1 +splendorservizi.it, 1 +spli.co, 1 +splibrary.tk, 1 +splikity.com, 1 +splintercake.tk, 1 +splintermail.com, 1 +splinternews.com, 1 +splitdna.com, 1 +splitreflection.com, 1 +splnk.net, 1 +sploch.com, 1 +splorge.cloud, 0 +splorge.website, 1 +splosh.me, 1 +splunk.net, 1 +spm-servis.tk, 1 +spmax.design, 1 +spmswiss.com, 1 +spnitalianfestival.com, 1 +spnsv.com, 1 +spodelime.com, 1 +spofia.nu, 1 +spokaneexteriors.com, 1 +spokanepolebuildings.com, 1 +spokeo.com, 1 +spokesly.com, 1 +spolshy.com.ua, 1 +spoluck.ca, 1 +spolwind.de, 1 +spom.net, 1 +sponc.de, 1 +sponec.com, 1 +spongepowered.org, 1 +sponsor.software, 1 +spoofhaus.com, 1 +spookbook.net, 1 +spookquest.com, 1 +spookyinternet.com, 1 +spoorcam.nl, 1 +sporeshore.co.uk, 1 +sporki.fun, 1 +spornkuller.de, 1 +sport-51.ru, 1 +sport-in-sundern.de, 1 +sport-news.ml, 1 +sport-news24hs.tk, 1 +sport-obzor.tk, 1 +sport-online-ru.cf, 1 +sport-potreby.cz, 1 +sport-potreby.sk, 1 +sport-school.tk, 1 +sport-socken.net, 1 +sportabee.com, 0 +sportakrobatik.at, 1 +sportboot.mobi, 1 +sportchirp.com, 1 +sportda.tk, 1 +sporter.com, 1 +sportify-design.fr, 1 +sportinfon.cf, 1 +sportingclubdacruz.pt, 0 +sportingpontenova.es, 1 +sportlesplanner.be, 1 +sportllux.com.br, 1 +sportmedia.ga, 1 +sportmultimedia.pt, 1 +sportmundschutz-info.de, 1 +sportnesia.com, 1 +sportnn.tk, 1 +sportovni.site, 1 +sportovnidum.cz, 1 +sportparks.com, 1 +sportparks.org, 1 +sportprint.hr, 1 +sportraucher.tk, 1 +sports-colleges.com, 1 +sports-equipmen.tk, 1 +sports-news-today.ml, 1 +sports-online.cf, 1 +sports-sites.ml, 1 +sports-wear.tk, 1 +sports.dating, 1 +sportschoolgeelhoed.nl, 1 +sportsdeck.tk, 1 +sportsdrobe.com, 1 +sportsjaw.com, 1 +sportsmagy.com, 1 +sportsmansblog.com, 1 +sportsmashup.com, 1 +sportspainmanagementnyc.com, 1 +sportspassbremen.de, 1 +sportstreetstyle.com, 1 +sportswear.by, 1 +sportsxplay.com, 1 +sportticino.ch, 1 +sporttomorrow.com, 1 +sporttown.it, 1 +sporttrampen.de, 0 +sportugalia.ru, 1 +sportvereine.online, 1 +sportverzorging.tk, 1 +sportxt.ru, 0 +sportygirlsjewels.ga, 1 +sportztalk.com, 1 +spot-cleaner.tk, 1 +spot-lumiere-led.com, 1 +spot.su, 1 +spotfake.news, 1 +spotifyfreetrial.co.uk, 1 +spotlabs.uk, 1 +spotlightsrule.com, 1 +spotonlive.dk, 1 +spotrebitelskecentrum.sk, 1 +spotsee.io, 0 +spotsolutions.com, 1 +spotswoodvet.com, 1 +spotsylvaniacounty-va.gov, 1 +spotsylvaniacountyva.gov, 1 +spottedfoxdigital.com, 1 +spottedpenguin.co.uk, 1 +spotupload.com, 1 +spotworld.co, 1 +spotypal.com, 1 +spotzlight.tk, 1 +sppin.fr, 1 +spr.id.au, 1 +sprachenlernen24.org, 1 +sprachfreudehoch3.de, 1 +sprashivalka.com, 1 +spravka-internet.tk, 1 +spravka.tk, 1 +spravki.cf, 1 +sprax2013.de, 1 +sprayontv.com, 1 +spreadsheetgear.com, 1 +spreadsheets.google.com, 1 +spreadthejam.tk, 1 +spreadthenews.eu, 1 +spreed.me, 1 +spricknet.de, 1 +sprillerer.tk, 1 +springermedia.co, 1 +springerundpartner.de, 1 +springfieldbricks.com, 0 +springhillmaine.com, 1 +springhow.com, 1 +springlanguages.com, 1 +springmountaindistrict.org, 1 +springsoffthegrid.com, 1 +springtxcarpetcleaning.com, 1 +sprintkitchen.com, 1 +sprintlee.com, 1 +spritmonitor.de, 1 +spritsail.io, 1 +sprock.io, 0 +spron.in, 1 +sprossenwand.de, 1 +sproutways.com, 1 +sprucecreekclubs.com, 1 +sprucecreekgcc.com, 1 +spruces.gq, 1 +sprueche-zum-valentinstag.de, 1 +sprueche-zur-hochzeit.de, 1 +sprueche-zur-konfirmation.de, 1 +spruijtparket.nl, 1 +sprutech.de, 1 +sps-lehrgang.de, 1 +spsidahoinc.com, 1 +spslawoffice.com, 1 +spsnewengland.org, 1 +spstaticfiles.com, 1 +spt.tf, 1 +sptk.org, 1 +spuffin.com, 1 +spufpowered.com, 1 +spur.com.br, 1 +spurghi.roma.it, 1 +spurindustrial.com, 1 +spurto.in, 1 +sputnik1net.org, 1 +spychala-it.de, 1 +spyclub.tk, 1 +spydar007.com, 1 +spydar007.net, 1 +spydar007.wiki, 1 +spydersec.com, 1 +spykedigital.com, 1 +spyprofit.ru, 1 +spyroszarzonis.com, 1 +spyse.com, 1 +sqalogic.com, 1 +sqap.pt, 1 +sqclick.com, 1 +sqdll.com, 1 +sqills.com, 1 +sql-injection.cz, 1 +sql-injection.rocks, 1 +sql-query-tool-exact-online.nl, 1 +sql-query-tool.com, 1 +sql-und-xml.de, 1 +sql.bi, 1 +sqlapius.net, 1 +sqlbi.com, 1 +sqli.cz, 1 +sqli.rocks, 1 +sqlinjection.cz, 1 +sqlinjection.rocks, 1 +sqliteonline.com, 1 +sqlwrapper.com, 1 +sqmin.tk, 1 +sqprod.co, 1 +sqr-training.com, 1 +sqreemtech.com, 1 +sqroot.eu, 1 +sqsd.xyz, 1 +sqshq.de, 1 +squadgames.ru, 1 +squadlinx.com, 1 +squadronprotectiveservices.net, 1 +squardllc.ml, 1 +square-gamers.tk, 1 +square-gaming.org, 1 +square-src.de, 0 +square.com, 1 +square.com.mx, 1 +square.engineering, 1 +square.it, 1 +square.ly, 1 +square.mx, 1 +square.site, 1 +squarecat.io, 1 +squaredancedance.tk, 1 +squaredseven.com, 1 +squareforums.com, 1 +squaregift.com, 1 +squaregift.net, 1 +squaregift.org, 1 +squareinstallments.com, 1 +squareinvite.com, 1 +squareinvoices.com, 1 +squarelab.it, 1 +squaremktg.com, 1 +squaremktgstaging.com, 1 +squareoffer.com, 1 +squareonebgc.com.ph, 1 +squarepocketdesign.com, 0 +squareregister.com, 1 +squaresoft.ga, 1 +squaresolutions.com, 1 +squarestagingexternal.com, 1 +squareup.com, 1 +squareupsandbox.com, 1 +squarewave.cloud, 1 +squattra.com, 1 +squeakie.club, 1 +squeaky.services, 1 +squealing-filth.tk, 1 +squeezemetrics.com, 1 +squelcher.cf, 1 +squidnovels.tk, 1 +squido.ch, 1 +squidparty.com, 1 +squids.space, 1 +squirex2.com, 1 +squirtingpussygirl.com, 1 +squirtlesbians.net, 1 +sr-33.com, 1 +sr-f.tk, 1 +sr.ht, 1 +sr33.com, 1 +sr88.co.uk, 1 +sr88.me.uk, 1 +srae.me.uk, 1 +srandom.com, 1 +sranje.rocks, 1 +srb.help, 1 +src-el-main.com, 1 +src.fedoraproject.org, 1 +srchicmodas.com.br, 1 +srchub.org, 1 +srcprivatesecurity.com, 1 +srdinnovativedesigns.com, 1 +srdmarketingservice.com, 1 +sreeharis.tk, 1 +sreenadh.in, 1 +srfloki.com, 1 +srife.net, 1 +srigc.com, 1 +srilankachinasociety.org, 1 +srilankan-hope-for-children.nl, 1 +srimakc.com, 1 +srinivasan.io, 1 +sriravana.tk, 1 +sritafrican.tk, 1 +sritalabama.tk, 1 +sritalaska.tk, 1 +sritcalifornia.tk, 1 +sritcities.tk, 1 +sritclassic.tk, 1 +sritculture.tk, 1 +sritegypt.tk, 1 +srithunters.tk, 1 +sritidaho.tk, 1 +sritongnp.com, 1 +sritsafety.ml, 1 +sritspanish.tk, 1 +srittheatre.tk, 1 +sritvermont.tk, 1 +srix.ml, 1 +srkarra.com, 1 +srkb.net, 1 +srmt82east.com, 1 +sro.center, 1 +sro.fi, 1 +srochno-pohudeti.tk, 1 +srochnozaim.gq, 1 +srochnyj-zajm.ga, 1 +sros.fi, 1 +sroturkey.tk, 1 +srpx.de, 1 +srqpedals.com, 1 +srrdb.com, 1 +srroddy.com, 1 +srsforward.email, 1 +srsfwd.com, 1 +srsfwd.email, 1 +srsfwd.eu, 1 +srsfwd.net, 1 +srsfwd.org, 1 +sruthisjewellery.com, 1 +srv.so, 1 +srvonfire.com, 1 +srx.sx, 1 +ss-news.tk, 1 +ss-x.ru, 0 +ss.com, 1 +ss.lazio.it, 1 +ss.lt, 1 +ss.lv, 1 +ss.systems, 1 +ss.ua, 1 +ss09.com, 1 +ss23.ru, 1 +ss5197.co, 1 +ss64.com, 1 +ss64.org, 1 +ss6729.co, 1 +ss6729.com, 1 +ss6957.co, 1 +ss88.uk, 1 +ss9188.com, 1 +ss9297.co, 1 +ss9397.com, 1 +ss9728.co, 1 +ssa.co.ir, 1 +ssa.gov, 0 +ssasociety.nl, 1 +ssbgportal.net, 1 +ssbkk.ru, 0 +ssbrm.ch, 1 +ssc.vg, 0 +sscd.no, 1 +sschd.cc, 0 +ssconn.com, 1 +ssd.today, 1 +ssdax.com, 1 +ssdpalermo.it, 1 +ssenberg.nl, 1 +ssfbank.no, 1 +ssgo.cloud, 1 +ssh-vault.com, 1 +ssh.in.ua, 1 +sshbox.tk, 1 +sshcrack.com, 1 +sshd.site, 1 +sshool.at, 1 +sshwiki.tk, 1 +sshx.top, 1 +ssk.ovh, 1 +sskb-ey.tech, 1 +ssky.cn, 1 +ssl-zertifikate.de, 1 +ssl.google-analytics.com, 1 +ssl.kim, 1 +ssl.md, 1 +ssl24.pl, 1 +ssl247.co.uk, 1 +ssl247.com.mx, 1 +ssl247.de, 1 +ssl247.dk, 1 +ssl4all.gq, 1 +sslbrain.com, 1 +sslcentral.co.uk, 1 +sslcertificaten.nl, 1 +sslcheck.nl, 1 +ssld.at, 1 +ssldev.net, 1 +sslle.eu, 1 +sslmate.com, 1 +sslmonkey.net, 1 +sslok.com, 0 +sslping.com, 1 +sslpoint.com, 1 +ssls.cz, 1 +sslsecureproxy.com, 1 +ssmato.me, 1 +ssmca.com, 1 +ssmic.com, 0 +ssmm88.cc, 1 +ssmpuc.com, 1 +ssmrca.ca, 1 +ssnet.vip, 1 +sso.to, 1 +ssone.ee, 1 +sspanel.host, 1 +ssprod.tk, 1 +sspu.ml, 1 +ssr.llc, 1 +ssradio.live, 1 +ssready.io, 1 +ssrfq.com, 1 +ssrgov.cn, 1 +ssrvpn.tech, 1 +sss.rip, 1 +ssshh.com, 1 +ssslelectricfencing.co.za, 1 +sssnet.xyz, 1 +sssppp.gq, 1 +sstaging.com, 1 +sstool.vip, 1 +ssuc.net, 1 +ssuiteoffice.com, 1 +ssuitesoft.com, 1 +st-bede.org, 1 +st-kilian-markt-erlbach.de, 1 +st-li.com, 1 +st-news.de, 1 +st-shakyo.jp, 1 +st-steuern.de, 1 +st-tir-pln.fr, 1 +st42.fr, 1 +staatdesinternets.nl, 1 +staatdesnederlandscheninternets.nl, 1 +staatdesnederlandseninternets.nl, 1 +staatschutz.at, 1 +staatsschutz.at, 1 +staatsschutzgesetz.at, 1 +staatvanhetnederlandscheinternet.nl, 1 +staatvanhetnederlandseinternet.nl, 1 +stabilimento.it, 1 +stable.network, 1 +stableflect.finance, 1 +stablelib.com, 1 +stacisezeptat.cz, 1 +stackhub.cc, 1 +stackick.com, 1 +stacklasvegas.com, 1 +stackpath.com, 1 +stackptr.com, 1 +stackstartup.com, 1 +stackstartup.tech, 1 +stacktile.io, 0 +stacktrace.sh, 1 +stackunderflow.com, 1 +stacky.me, 1 +stad.gent, 1 +staddlestonesbowness.co.uk, 1 +stadgent.be, 1 +stadionmanager.com, 1 +stadiumexperience.com, 1 +stadlwirt.at, 1 +stadm.com, 0 +stadsbos013.nl, 1 +stadspaleizengent.be, 1 +stadtbauwerk.at, 0 +stadtbuecherei-bad-wurzach.de, 1 +stadterneuerung-hwb.de, 1 +stadtgartenla.com, 1 +stadtkapelle-oehringen.de, 1 +stadtpapa.de, 1 +stadtplan-ilmenau.de, 1 +stadtundbaum.de, 1 +staer.ro, 1 +staff.direct, 1 +staffglass.io, 1 +staffi.tk, 1 +staffingnation.com, 1 +staffordlabour.org.uk, 1 +stage-props-blank-guns.com, 1 +stage-recuperation-points-bordeaux.com, 1 +stage-recuperation-points-lille.com, 1 +stage-recuperation-points-lyon.com, 1 +stage-recuperation-points-marseille.com, 1 +stage-recuperation-points-montpellier.com, 1 +stage-recuperation-points-nantes.com, 1 +stage-recuperation-points-nice.com, 1 +stage-recuperation-points-paris.com, 1 +stage-recuperation-points-reims.com, 1 +stage-recuperation-points-rennes.com, 1 +stage-recuperation-points-strasbourg.com, 1 +stage-recuperation-points-toulouse.com, 1 +stage.wepay.com, 0 +stage4.ch, 1 +stageirites.com, 1 +stageirites.fr, 1 +stageirites.org, 1 +stagelectrical.com.au, 1 +stagemaster.cz, 1 +stagend.com, 1 +stagespediatrics.com, 1 +staging-covid-games.herokuapp.com, 1 +stagingpepocoin.com, 1 +stagstickets.co.uk, 1 +stahlfors.com, 1 +stail.eu, 1 +stainedglass.net.au, 1 +stainhaufen.de, 1 +stainless-steel-cookware.tk, 1 +stainternational.com, 1 +stair.ch, 1 +stairlin.com, 0 +stairmaster.tk, 1 +stajka.tk, 1 +stakestrategy.com, 1 +staklim-malang.info, 1 +stako.jp, 1 +staktrace.com, 1 +stal-rulon.ru, 1 +stalder.work, 1 +stalker-eyes.ga, 1 +stalker-shop.com, 1 +stalker-source.tk, 1 +stalkerteam.pl, 1 +stalkr.net, 1 +stalkthe.net, 1 +stall-frei.de, 1 +stallardjw.me, 1 +stallionsnow.com, 1 +stalphonsusks.org, 1 +stalplus.ml, 1 +stalstroi.ml, 1 +stalworld.tk, 1 +stamboomforum.nl, 1 +stamboomgids.nl, 1 +stameystreet.com, 1 +stamforddentalarts.com, 1 +stamgent.be, 1 +stamit.nl, 1 +stamkassa.nl, 1 +stammering.ga, 1 +stammtisch-bauwagen.tk, 1 +stammtisch.domains, 1 +stamonicatourandtravel.com, 1 +stamparmakarije.me, 1 +stampederadon.com, 1 +stampingoriginal.com, 1 +stampsbar.co.uk, 1 +stamurai.com, 1 +stanandjerre.org, 1 +standard.co.uk, 1 +standardizarea.ro, 1 +standards.gov, 1 +standartgost.ru, 1 +standdownofnorthjersey.org, 1 +standfore.com, 1 +standheizung-shop.de, 1 +standoff-magic.ru, 1 +standoffdrop.com, 1 +standoffdrop.ru, 1 +stang.moe, 1 +stangeland.tk, 1 +stanglwirt.com, 1 +stankingma.com, 1 +stankingma.nl, 1 +stanmed24.pl, 1 +stannri.org, 1 +stanonline.tk, 1 +stanron.com, 1 +stansweather.net, 1 +stantabler.com, 1 +stanthony-hightstown.net, 1 +stanzolo.com, 1 +stapvoorstapduurzaam.nl, 1 +star-24.cf, 1 +star-citizen.wiki, 1 +star-clean.it, 1 +star-darom.co.il, 1 +star-life.tk, 1 +star-one.co.uk, 1 +star-stuff.de, 0 +star.garden, 1 +star.my.id, 1 +star.watch, 1 +starase.com, 1 +starb.in, 1 +starbaese.de, 1 +starborne.space, 1 +starbreaker.org, 1 +starbusiness.ml, 1 +starbyte.co.uk, 1 +starcitizen.tools, 1 +starcoachservices.ca, 1 +starcomproj.com, 1 +starcraftsource.tk, 1 +starcys.xyz, 1 +stardanceacademy.net, 1 +stardawg.co.uk, 1 +stardrive.cf, 1 +starease.com, 1 +starease.net, 1 +stareplanymiast.pl, 1 +starfall.systems, 1 +starfield.ai, 1 +starfishconstruction.com, 1 +starflix.uk, 1 +starfm.de, 1 +starfm.ml, 1 +starfriend.ru, 1 +stargarder-jungs.de, 1 +stargate365.com, 1 +stargatelrp.co.uk, 1 +stargazer.de, 1 +stargroup.space, 1 +stari.co, 1 +stariders.com, 1 +starina.ru, 1 +starinc.xyz, 1 +starka.st, 1 +starkbim.com, 1 +starking.net.cn, 1 +starkvilleurgentcareclinic.com, 1 +starlim.co.in, 1 +starlim.org, 1 +starlincuesta.gq, 1 +starlinks.tk, 1 +starlux.cz, 1 +starmtech.fr, 1 +starmyworld.ga, 1 +staroch.name, 1 +starorusing.com, 0 +starover.tk, 1 +starpeak.org, 1 +starphotoboothsni.co.uk, 1 +starplatinum.jp, 1 +starpoles.com, 1 +starprime.de, 1 +starrace.eu, 1 +starregistration.net, 1 +starretest.nl, 1 +starreview.tk, 1 +starry.blue, 1 +starrymc.cn, 1 +starryvoid.com, 1 +starsam80.net, 1 +starsbattle.net, 1 +starseersprophecy.com, 1 +starsguru.com, 1 +starsing.bid, 1 +starskim.cn, 1 +starsoft.io, 1 +starsub.com.au, 1 +start-knighki.gq, 1 +start-school.online, 1 +start.biz.id, 1 +startablog.tv, 1 +startaninflatablebusiness.com, 1 +startbetter.tk, 1 +startbiz.biz.id, 1 +startbiz.co.id, 1 +startbiz.id, 1 +startbiz.my.id, 1 +startbiz.web.id, 1 +startersiteweb.com, 1 +startgeophysical.ga, 1 +starthubs.uk, 1 +starti.com.ua, 1 +startingent.be, 1 +startinop.com, 1 +startlab.sk, 1 +startlap.es, 1 +startle.cloud, 1 +startle.studio, 1 +startliste.info, 1 +startmail.com, 1 +startner.com, 1 +startpage.com, 1 +startpage.info, 1 +startplats.tk, 1 +startpoint.tk, 1 +startrek.in, 1 +starts.sh, 1 +startstack.tech, 1 +startstunter.com, 1 +starttls-everywhere.org, 1 +starttraffic.uk, 1 +startup-lab.ro, 1 +startup-stack.com, 1 +startup-stack.tech, 1 +startup.melbourne, 1 +startupbros.com, 1 +startupisland.tw, 1 +startuplevel.com, 1 +startupstack.cloud, 1 +startupstack.llc, 1 +startupstack.net, 1 +startupstack.online, 1 +startupstack.pro, 1 +startupstack.services, 1 +startupstack.site, 1 +startupstack.software, 1 +startupstack.systems, 1 +startupstack.tech, 1 +startupstack.technology, 1 +startupstacksandbox.com, 1 +startupstacktech.com, 1 +startupstash.com, 1 +startupswitzerland.com, 1 +startuptechstack.com, 1 +startupum.ru, 1 +startw.cf, 1 +starvizyon.com, 1 +starwatches.eu, 1 +stasia.ml, 1 +stasiniewicz.com, 1 +stastka.ch, 1 +staszic.waw.pl, 1 +stat.ink, 1 +statcenter.tk, 1 +state-of-body-and-mind.com, 1 +statecollegemortgages.com, 1 +stated.gq, 1 +statefundca.com, 1 +statefunddirect.com, 1 +stategov.us, 1 +stateidea.ga, 1 +statelines.ga, 1 +statelywork.com, 1 +statgram.me, 1 +static-692b8c32.de, 1 +static-assets.io, 1 +static-myfxee-808795.c.cdn77.org, 1 +static-myfxoau-808795.c.cdn77.org, 1 +static-myfxouk-808795.c.cdn77.org, 1 +static.hosting, 1 +static.wepay.com, 0 +statically.io, 1 +staticfury.com, 1 +staticline.de, 1 +staticweb.tk, 1 +stationa.ch, 0 +stationary-traveller.eu, 1 +stationcharlie.co.za, 1 +stationmedia.tk, 1 +statisticalsurveys.com, 1 +statistician-online.com, 0 +statistik-seminare.de, 1 +statistikian.com, 1 +statnevlajky.sk, 1 +statnivlajky.cz, 1 +statofus.com, 1 +stats.do, 1 +stats.g.doubleclick.net, 1 +statsit.ga, 1 +statsnite.com, 1 +status.care, 1 +status.vg, 1 +statusboard.eu, 1 +statusbot.io, 1 +statuscode.ch, 1 +statusforward.com, 1 +statusmachine.com, 1 +statuswatch.io, 1 +stavanger.kommune.no, 1 +stavinchains.tk, 1 +stavnager.net, 1 +stavropol-news.ga, 1 +staxflax.tk, 1 +stay-curious.at, 1 +staycurrent.eu, 1 +staycurrent.nl, 1 +staydryohio.com, 1 +staygold.blog, 1 +staylovely.tk, 1 +stayme.cz, 1 +stayokay.com, 1 +stayschemingco.com, 1 +staytokei.com, 1 +staywild.pl, 1 +stb-lemke.de, 1 +stb-schefczyk.de, 1 +stb-timmler.de, 1 +stb.gov, 1 +stbartholomewmanchester.org, 1 +stbennett.org, 1 +stbl.org, 1 +stc-istok.com.ua, 1 +stcable.net, 1 +stcatharine-stmargaret.org, 1 +stcatharinesromawolves.tk, 1 +stccordoba.com, 1 +stceciliakearny.org, 1 +stclairvet.co.uk, 1 +stclementmatawan.org, 1 +stclementreligioused.org, 1 +stcplasticsurgery.com, 1 +std-home-test.com, 1 +stdavidparish.org, 1 +stderr.cc, 1 +stderr.ch, 1 +stdev.org, 1 +stdev.top, 1 +stdnet.ru, 1 +stdrc.cc, 0 +steacy.tech, 1 +steakovercooked.com, 1 +stealingheather.com, 1 +stealsaga.net, 1 +stealth.net, 1 +stealthmodel.fi, 1 +stealthvape.co.uk, 1 +steam-rewards.tk, 1 +steam-route-saxony.com, 1 +steamcarddelivery.com, 1 +steamcars.be, 1 +steamcleaning.expert, 1 +steamcrack.ga, 1 +steamdb.info, 1 +steamerrors.com, 1 +steamgifts.com, 1 +steamid.net, 1 +steamid.tools, 1 +steamkeyget.ga, 1 +steamold.com, 0 +steamosaic.com, 1 +steampress.io, 1 +steamscore.info, 1 +steamsprays.tk, 1 +steamstat.us, 1 +steamtrades.com, 1 +stebenkov.tk, 1 +stebet.net, 1 +steborio.pw, 1 +steckel.cc, 1 +stecos.co.uk, 1 +stedb.eu, 1 +stedbg.net, 1 +steebel.com.au, 1 +steeble.com.au, 1 +steef389.eu, 1 +steel-roses.de, 1 +steelbeasts.org, 1 +steelcentral.net, 1 +steelehollowvintage.com, 1 +steelephys.com.au, 1 +steelfencestlouis.com, 1 +steelfirm.ga, 1 +steelfxpatinas.com, 1 +steelmounta.in, 1 +steelpoint.com.pl, 1 +steelshop.net, 1 +steelsoldiers.com, 1 +steemit.com, 1 +steempeak.com, 1 +steemworld.org, 1 +steemyy.com, 1 +steering-wheel.tk, 1 +steeve-legal-photographie.fr, 1 +steevels.nl, 1 +stefamedia.com, 1 +stefan-bayer.eu, 1 +stefan-rothe.ch, 1 +stefan-schlueter.de, 1 +stefan-schmid.com, 1 +stefan.de, 1 +stefanbayer.de, 1 +stefancosma.xyz, 1 +stefandepooter.com, 1 +stefanengineering.com, 1 +stefanfriedli.ch, 1 +stefania.tk, 1 +stefaniepetermann.eu, 1 +stefaniharvilla.tk, 1 +stefanknobel.ch, 1 +stefankuehnel.com, 1 +stefanolsdal.tk, 1 +stefanorossi.it, 0 +stefanovski.io, 1 +stefanvanburen.xyz, 0 +stefanvd.net, 1 +stefanviehbacher.de, 1 +stefany.cloud, 1 +stefany.eu, 1 +stefchapman.tk, 1 +steffenmeister.com, 1 +steffentreeservice.com, 1 +steffi-in-australien.com, 1 +steffi-knorn.de, 1 +stefpastoor.nl, 1 +steggemachine.com, 1 +stehlik.co.uk, 1 +stehlik.sk, 1 +steidlewirt.de, 1 +steigerlegal.ch, 1 +steinberg.net, 1 +steinbergmedia.de, 1 +steiner-dominik.at, 1 +steiner.do, 1 +steiner.is, 1 +steiner.is.it, 1 +steiner.sh, 1 +steinerkovarik.de, 1 +steiners.party, 1 +steinibox.de, 1 +steinmetz.cloud, 1 +steklein.de, 1 +stekosouthamerica.com, 1 +stelfox.net, 1 +stelga.ca, 1 +steliosmanousakis.gr, 1 +stella-artis-ensemble.at, 1 +stella-shop.eu, 1 +stellanova-planeten.de, 0 +stellar.com.de, 1 +stellar.guru, 1 +stellar.io, 1 +stellarguard.me, 1 +stellarium-gornergrat.ch, 1 +stellarlumensnews.today, 1 +stellarx.com, 1 +stellatusstudios.com, 1 +stelleninserate.de, 1 +stellenticket.de, 1 +stelletjeafgebeuktemongolen.tk, 1 +stellmacher.name, 1 +stels.ml, 1 +stels.tk, 1 +stem16plus.gent, 1 +stematechnologies.ga, 1 +stembureauledenindenhaag.nl, 1 +stemcellclinic.design, 1 +stemcellclinic.live, 1 +stemcellclinic.ltd, 1 +stemcellclinic.network, 1 +stemcellclinic.services, 1 +stemcellclinic.tech, 1 +stemcellclinic.vip, 1 +stemcellclinic.world, 1 +stemcellstherapynyc.com, 1 +stemgirls.co.za, 1 +stemkit4kids.com, 1 +stemklank.tk, 1 +stemmayhem.com, 1 +stempel-lobenhofer.at, 1 +stempelspirale.eu, 1 +stena.cf, 1 +stenaro.ch, 1 +stenhojmedia.dk, 1 +stening.co, 1 +steno.nl, 1 +stensund.se, 1 +stenvallmcclain.tk, 1 +stenzhorn-cloud.de, 1 +step2web-cms.info, 1 +stepanvanek.cz, 1 +steparovi.cz, 1 +steph.ninja, 1 +steph3n.me, 1 +stephan-matthiesen.de, 1 +stephanao.tk, 1 +stephaniecalahan.com, 1 +stephaniedeady.ie, 1 +stephanieleonidasfan.tk, 1 +stephanieschreiber.com, 1 +stephencorp.com, 1 +stephencreilly.com, 1 +stephenhaunts.com, 1 +stephenj.co.uk, 1 +stephenjvoiceovers.com, 1 +stephenlam.ca, 1 +stephenperreira.com, 1 +stephenreescarter.net, 1 +stephenschirle.ml, 1 +stephenschrauger.com, 1 +stephenschrauger.org, 1 +stephenskory.com, 1 +stephensol.is, 1 +stephensolis.com, 1 +stephensolis.net, 1 +stephensolisrey.es, 1 +stephensoncountyil.gov, 1 +stephsolis.net, 1 +stephspace.net, 1 +stephycom.com, 1 +steplogictalent.com, 1 +steponedanceclub.co.uk, 1 +steponedanceclub.uk, 1 +steppingoutinstyleonline.com, 1 +stepstone.dk, 1 +stepupforeurope.eu, 1 +ster-enzo.nl, 1 +sterchi-fromages.ch, 0 +stereob.it, 1 +stereochro.me, 0 +stereostudio.cf, 1 +sterlingheights.gov, 1 +sterlingmodular.com, 1 +sterlinx.de, 1 +sterlitamak.tk, 1 +stern-freunde.de, 1 +stern.koeln, 1 +sternadel.pl, 1 +sternen-sitzberg.ch, 1 +sternenbund.info, 1 +sterno.cf, 1 +sternplastic.com, 1 +sternsinus.com, 1 +sterohouse.com, 1 +sterva.mobi, 1 +sterydki.pl, 1 +sterz.io, 1 +stesti.cz, 1 +stetson.edu, 1 +stetspa.it, 1 +steuerberater-bayreuth.com, 1 +steuerberater-essen-steele.com, 1 +steuerberater-hopfner.de, 1 +steuerkanzlei-edel.de, 1 +steuern-recht-wirtschaft.de, 1 +steuertipps-sonderausgaben.de, 1 +steve-mason.tk, 1 +steve.kiwi, 1 +steveborba.com, 1 +stevebuck.tk, 1 +stevecostar.com, 1 +stevedoggett.com, 1 +steveellwood.com, 1 +stevegellerhomes.com, 1 +stevegrav.es, 1 +stevehaid.com, 1 +stevejcraig.com, 1 +stevejobsfollowers.tk, 1 +stevemario.com, 1 +stevemason.tk, 1 +stevemonteyne.be, 1 +steven-bennett.com, 1 +steven-klix.de, 0 +steven.photos, 1 +stevenapate.com, 1 +stevenavaldez.tk, 1 +stevenberg.net, 1 +stevenbolgartersnakes.com, 1 +stevengoodpaster.com, 1 +stevengrech.com, 1 +stevenhardy.digital, 1 +stevenjacobs.be, 1 +stevenjacobs.eu, 1 +stevenkendypierre.com, 1 +stevenlapere.co.za, 1 +stevenmdriving.co.uk, 1 +stevenpalmieri.com, 1 +stevenroddis.com, 1 +stevensautotopsandupholstery.com, 1 +stevenselectricllc.com, 1 +stevenski.com, 0 +stevenson.io, 1 +steventress.com, 1 +steventruesdell.com, 1 +stevenz.net, 1 +stevenz.science, 1 +stevenz.xyz, 1 +stevepacheco.com, 1 +stevereedmp.co.uk, 1 +stevesbriefmovierecommendations.com, 1 +stevesdrivingschooltyneside.com, 1 +stevezheng.cf, 1 +stevezheng.tk, 1 +stevezone.in, 1 +steviate.com, 1 +steviate.de, 1 +stewards.tk, 1 +stewartswines.com, 1 +stewonet.nl, 1 +stewpolley.com, 1 +steyaert.be, 0 +stfrancisnaugatuck.org, 1 +stg-0-con.com, 1 +stgabrielavondalepa.org, 1 +stgabrielstowepa.org, 1 +stgen.com, 1 +stgeorgegolfing.com, 1 +stghv.com, 1 +sth.sh, 1 +sthelen.eu, 1 +sthelensoregon.gov, 1 +sthenryrc.org, 1 +sthetix.info, 1 +sthpr.gr, 1 +stian.net, 1 +stichtingdemuziekkamer.nl, 1 +stichtingliab.nl, 1 +stichtingscholierenvervoerzeeland.nl, 1 +stichtingsticky.nl, 0 +stichtingvlinders.nl, 1 +stick2bike.de, 1 +stickandpoketattookit.com, 1 +stickeramoi.com, 1 +stickerparadise.me, 1 +stickertrade.me, 1 +stickertuningfetzt.de, 1 +stickies.io, 1 +stickme.be, 1 +stickmy.cn, 1 +stickstone.co, 1 +stickstueb.de, 1 +stickswag.cf, 1 +stickswag.eu, 1 +sticky.ai, 1 +sticky.to, 1 +stickypassword.com, 1 +stickyricelove.com, 1 +stickywilds.com, 1 +stiebel-eltron.co.nz, 1 +stiebel-eltron.com.au, 1 +stiebel.co.nz, 1 +stiebel.com.au, 1 +stiebelmedia.co.nz, 1 +stiebelmedia.com.au, 1 +stiebelrewards.com.au, 1 +stiebelservice.com.au, 1 +stiebelstore.com.au, 1 +stiehler-leipzig.tk, 1 +stiff.wang, 1 +stifflersmom.ga, 1 +stift-kremsmuenster.at, 1 +stiftemaskinen.no, 1 +stiftung-lq.ch, 1 +stiftung-lq.com, 1 +stiftung-lq.net, 1 +stiftunglq.com, 1 +stigharder.com, 1 +stigviewer.com, 1 +stihiduhi.ru, 1 +stihiya.tk, 1 +stijndv.com, 1 +stijnodink.nl, 1 +stikic.me, 1 +stikkie.me, 1 +stikonas.eu, 0 +stil.dk, 1 +stileapp.com, 1 +stiliankasimov.com, 1 +stilida.com, 1 +stilingavonia.lt, 1 +stillsnfilms.com, 1 +stillwell.me, 1 +stilmobil.se, 1 +stilnaya-odezhda.tk, 1 +stilsvadba.tk, 1 +stiltmedia.com, 1 +stiltnerelectric.com, 1 +stilus-patent.ru, 1 +stimmgabel.lu, 1 +stin.hr, 1 +stina-vino.hr, 1 +stinaspiegelberg.com, 1 +stingraybook.com, 1 +stinici.site, 1 +stinkefingereinhorn.de, 1 +stinkmemes.com, 1 +stinsky.com, 1 +stinter.cf, 1 +stintup.com, 0 +stipsan.me, 1 +stirblaut.de, 1 +stirling.co, 1 +stirlingpoon.com, 1 +stisidores.org, 1 +stitch.money, 1 +stitchfiddle.com, 1 +stitchinprogress.com, 1 +stivesbouncycastlehire.co.uk, 1 +stjohncamden.com, 1 +stjohnin.com, 1 +stjohnnepomucene.com, 1 +stjohnsc.com, 1 +stjohnslutheran.net, 1 +stjohnsottsville.org, 1 +stjoseph-stcatherine.org, 1 +stjosephri.org, 1 +stjosephspringcity.com, 1 +stjosephtheworker.net, 1 +stjscatholicchurch.org, 1 +stjude-ettekkar.tk, 1 +stjustin.org, 1 +stkeverneparishcouncil.org.uk, 1 +stkevin-stbenedict.org, 1 +stkildaosteopathy.com.au, 1 +stl.news, 1 +stla.net, 1 +stleonardmn.org, 1 +stlfamilyattorney.com, 1 +stlfence.com, 1 +stln.ml, 1 +stlouisfence.com, 1 +stlouisinsuranceco.com, 1 +stlouisnativeflute.com, 1 +stlouisstabilizing.com, 1 +stlpoolattendants.com, 1 +stlu.de, 1 +stluciastar.com, 1 +stlukenh.org, 1 +stlukesbrandon.org, 1 +stm-net.de, 1 +stma.is, 1 +stmariagoretti.net, 1 +stmarkseagirt.com, 1 +stmarthachurch.com, 1 +stmaryextra.uk, 1 +stmarysnutley.org, 1 +stmaryswestwarwick.org, 1 +stmatthewri.org, 1 +stmattsparish.com, 1 +stmattsucc.org, 1 +stmichaellvt.com, 1 +stmichaelsmajors.tk, 1 +stmichaelunion.org, 1 +stmohrael.org, 1 +stmosesbookstore.org, 1 +stmsolutions.pl, 1 +stmsouthcoventry.com, 1 +stn.me.uk, 0 +stneotsbouncycastlehire.co.uk, 1 +stnews.ga, 1 +stnl.de, 0 +sto-avtovo.com, 1 +stock-ai.com, 1 +stock-solution.de, 1 +stockanalysis.com, 1 +stockgraphicdesigns.com, 1 +stockholmpride.org, 1 +stockhuntertrading.com, 1 +stockmarkettoday.news, 1 +stockpile.com, 1 +stockportpyramid.co.uk, 1 +stocksfam.com, 1 +stockslam.ga, 1 +stocksnews.tk, 1 +stockstuck.com, 1 +stockt-shirtdesigns.com, 1 +stocktonengineering.co.uk, 1 +stocktout.info, 1 +stocktrader.com, 1 +stockway.tk, 1 +stockx.com, 1 +stocp.org, 1 +stodieck.com, 1 +stodrive.com, 1 +stoebermehl.at, 1 +stoemp.gent, 1 +stoffelnet.de, 1 +stoffhandwerk.tk, 1 +stoianlawfirm.com, 1 +stoicatedy.ovh, 1 +stoildaaliyski.com, 1 +stoinov.com, 1 +stokl.com.au, 0 +stolarka.tk, 1 +stolbart.com, 1 +stolensheep.tk, 1 +stolensun.tk, 1 +stolin.info, 1 +stolina.de, 1 +stolkpotplanten.nl, 1 +stoll.info, 1 +stollen-wurm.de, 1 +stollenwurm.de, 1 +stolpe5674.tk, 1 +stolpersteine-dithmarschen.tk, 1 +stolpi.is, 0 +stoltz-it.de, 1 +stomaline.com.ua, 1 +stomatolog-czestochowa.gq, 1 +stomatolog.cf, 1 +stomatolog.ga, 1 +stomatologiya.gq, 1 +stomatologiya.ml, 1 +stomproced.ro, 1 +stomt.com, 1 +stoneagehealth.com.au, 1 +stonechatjewellers.ie, 1 +stonecutgods.com, 1 +stonedwarf5.net, 1 +stonedworms.de, 0 +stoneedgeconcrete.com, 1 +stonefusion.org.uk, 1 +stonegateapartmentsstl.com, 1 +stonehammerhead.org, 1 +stonehurstcap.com, 1 +stonemain.eu, 1 +stonemanbrasil.com.br, 1 +stoneocean.net, 1 +stoneproperty.ie, 1 +stonerwitch.tk, 1 +stonesnowboards.com, 1 +stonetribute.tk, 1 +stoneworld.ga, 1 +stonewuu.com, 1 +stonystratford.org, 1 +stoom-stichting.nl, 1 +stoomstichting.be, 1 +stoomstichting.biz, 1 +stoomstichting.com, 1 +stoomstichting.de, 1 +stoomstichting.eu, 1 +stoomstichting.info, 1 +stoomstichting.net, 1 +stoomstichting.nl, 1 +stoomstichting.org, 1 +stoomtreinhuren.nl, 1 +stoomtreinreizen.be, 1 +stoomtreinreizen.com, 1 +stoomtreinreizen.eu, 1 +stoomtreinreizen.nl, 1 +stoomtreinreizen.org, 1 +stop-activ.ga, 1 +stop-microsoft.org, 1 +stop-nikotin.tk, 1 +stopakwardhandshakes.org, 1 +stopbreakupnow.org, 1 +stopbullying.gov, 1 +stopforumspam.com, 1 +stopfraud.gov, 1 +stoph.at, 1 +stopka.tk, 1 +stoplossoff.tk, 1 +stopoverconnections.com, 1 +stoppage.cf, 1 +stoprog.ru, 1 +stopsmoke.gq, 1 +stopssherdenking.tk, 1 +stopsvet.ml, 1 +stopthemoss.com, 1 +stopthethyroidmadness.com, 1 +stopthinkconnect.jp, 1 +stoptrading.co.uk, 1 +stopves.tk, 1 +stopvirus.in, 1 +stopyhrdinu.cz, 1 +storage-base.de, 1 +storage-books.gq, 1 +storageideas.uk, 1 +stordbatlag.no, 1 +store10.de, 0 +storeandforward.email, 1 +storeandforward.eu, 1 +storeandforward.nl, 1 +storebusy.nz, 1 +storecove.com, 0 +storedaway.co.uk, 1 +storedieu.com, 1 +storedsafe.com, 1 +storeforward.email, 1 +storeforward.eu, 1 +storeforward.net, 1 +storeforward.nl, 1 +storeforward.org, 1 +storefront.gq, 1 +storeinstallieren.com, 1 +storeit.co.uk, 1 +storemax.com.au, 1 +storeplus.ml, 1 +storey-lines.com, 1 +storgaarddieu.com, 1 +storgom.ua, 0 +storiadellarte.com, 1 +storiesbysign.com, 1 +storillo.com, 1 +storin.nl, 1 +storingdesk.com, 1 +storjar.com, 1 +storm-news.tk, 1 +stormairsoft.tk, 1 +stormboost.cz, 1 +stormdamages.claims, 1 +stormestudios.tk, 1 +stormhub.ml, 1 +stormi.io, 1 +stormingbrain.com, 1 +stormrider.tk, 1 +stormwatcher.org, 1 +stormylegions.tk, 1 +stormyyd.com, 1 +stortiservices.com, 1 +storvann.net, 1 +storvann.no, 1 +storybuilder.me, 1 +storycollective.film, 1 +storycollective.nl, 1 +storycycle.tk, 1 +storyland.ie, 1 +storyoneforty.com, 1 +storysift.news, 1 +storytea.top, 1 +storytell.com, 1 +storytellingforbusiness.com.au, 1 +storytime.hu, 1 +stoumann.dk, 1 +stoutassociates.com, 1 +stouter.nl, 1 +stoverepairaustin.com, 1 +stoxford.com, 1 +stp-ip.com, 1 +stp-ip.net, 1 +stp.dev, 1 +stpatrick.tk, 1 +stpatrickathenscatskill.org, 1 +stpatrickbayshore.org, 1 +stpatrickkennettsquare.org, 1 +stpatrickri.org, 1 +stpatricks-pelham.com, 1 +stpatsschool.org, 1 +stpaulcatholicchurcheastnorriton.net, 1 +stpaulsbullville.org, 1 +stperseo.tk, 1 +stpetersresidence.org, 0 +stphilipneripreschool.com, 1 +stpioparish.com, 1 +stpip.com, 1 +stpip.net, 1 +str8hd.com, 1 +str92.com, 1 +straalatelier.com, 1 +straat.net, 1 +straatderzotten.nl, 1 +stradsolutions.ga, 1 +strafe-muss-sein.at, 1 +strafensau.de, 1 +strafvollzugsgesetze.de, 1 +strahlende-augen.info, 1 +strahovanienet.tk, 1 +straightedgebarbers.ca, 0 +straightlinetutoring.com, 1 +straightnude.com, 1 +strajnar.si, 1 +straka.name, 1 +strakh.tk, 1 +strakonak.cz, 1 +stralingsonzin.com, 1 +strana-snov.tk, 1 +strandbyfysio.dk, 1 +strandedinotter.space, 1 +strandhaus-claassen.de, 1 +strandhaus-hinter-der-duene.de, 1 +strandkorb-jentzsch.de, 1 +strandom.ru, 1 +strandschnuppern.de, 1 +strandypink.co.za, 1 +strange.ga, 1 +strangeelectricdreams.com, 1 +strangelandrecording.com, 1 +strangelandrecordingstudios.com, 1 +strangelandsoundstage.com, 1 +strangelane.com, 1 +strangelanerecords.com, 1 +strangelittlecovers.tk, 1 +strangemusicbox.com, 1 +strangemusichollywood.com, 1 +strangemusicinc.com, 1 +strangemusicinc.net, 1 +strangeonline.tk, 1 +strangerthanusual.de, 1 +strangevip.com, 1 +strangeways.ca, 0 +strangeworksinc.com, 1 +strangeworldmerch.com, 1 +strangeworldmerchandising.com, 1 +straniero.net, 1 +straphael-holyangels.com, 1 +strappazzon.xyz, 1 +strass-sur-mesure.fr, 1 +strassberger.tk, 1 +strate.io, 1 +strategic9.se, 1 +strategicemailservices.com, 1 +strategiclivingblog.com, 1 +strategicmind.com, 1 +strategicpartnersmedia.com, 1 +strategiczni.pl, 1 +strategie-zone.de, 1 +stratejm.com, 1 +stratforge.com, 1 +strathspeycrown.com, 1 +stratik.com.co, 1 +stratlibs.org.uk, 1 +stratmann-b.de, 1 +stratocumulus.legal, 1 +stratreg.com, 1 +stratsoftware.com, 1 +strattonapps.com, 1 +strattonhats.com, 1 +stratuscloud.co.za, 1 +stratuscloudconsulting.net, 1 +stratussc.com, 1 +straubis.org, 1 +strauser.com, 1 +stravers.shoes, 1 +strawberries.tk, 1 +strawberry-laser.gr, 1 +strawberrydreadlocks.tk, 1 +stray-soul.com, 1 +straydio.co.uk, 1 +straylight.tk, 1 +strd.co, 1 +stream-box.tk, 1 +streamblur.net, 1 +streamchan.org, 1 +streamelements.com, 1 +streamgato.com, 1 +streamgoalandres.ml, 1 +streaming-download.net, 1 +streaming.jetzt, 1 +streamlineverify.com, 1 +streamodz.com, 1 +streamonline.fi, 1 +streampanel.net, 1 +streampleasure.xyz, 1 +streamrite.com, 1 +streams.dyndns.org, 1 +streamspouredout.com, 1 +streamtelly.com, 1 +streathamfoodfestival.com, 1 +streemprn.xyz, 1 +streepjesenstipjes.nl, 1 +street-hoops.tk, 1 +street-legal.tk, 1 +street-medics.fr, 1 +street-tek.com, 1 +streetdancecenter.com, 1 +streetforceteam.tk, 1 +streetlightdata.com, 1 +streetmaderecordz.tk, 1 +streetmarket.ru, 1 +streets.mn, 1 +streetshirts.co.uk, 1 +streetspotr.com, 1 +streetstunters.tk, 1 +streetview.wien, 1 +strefapi.com, 1 +strefapi.pl, 1 +strehl.tk, 1 +strelnicesmirice.cz, 1 +stremio.com, 1 +strengthennd.com, 1 +strengthinyoufitness.com, 1 +strengthnutrition.es, 1 +strengthroots.com, 1 +stress-mess-punkte.de, 1 +stressexplained.com, 1 +stretchmarkdestroyer.com, 0 +stretchpc.com, 1 +striae.cf, 1 +striata.com, 1 +striata.mobi, 1 +striata.org, 1 +striatadev.com, 1 +strick-welt.de, 1 +stricken.gq, 1 +stricted.net, 1 +strictlyguitar.de, 1 +strictlynormal.com, 1 +strife.builders, 1 +strijdmeevoorvrede.gent, 1 +strijkshop.be, 1 +strikeout.ga, 1 +strikers.cf, 1 +strikers.futbol, 1 +strikevectorex.com, 1 +strings.cf, 1 +stringtoolbox.com, 1 +stringvox.com, 0 +stripe.com, 1 +stripe.network, 1 +stripecdn.com, 1 +striped.horse, 1 +stripehype.com, 1 +strippersondemand.com, 1 +striptizer.tk, 1 +strivephysmed.com, 0 +strl-tunis.tk, 1 +strm.pl, 1 +strmgt.com, 1 +strobe.cool, 1 +strobel.cl, 1 +strobotti.com, 1 +stroccounioncity.org, 1 +stroeder.com, 1 +stroeder.de, 1 +stroeerdigital.de, 1 +stroginopk.ga, 1 +strogov.me, 1 +strogova.me, 1 +stroifenix.ru, 1 +stroigid.tk, 1 +stroimsami.tk, 1 +stroimvse.ml, 1 +stroiproect.tk, 1 +strojmaster.tk, 1 +stroke-of-luck.com, 1 +strokesb.store, 1 +strom.family, 1 +stromak.cz, 0 +stromkomfort.cz, 1 +stromzivota.sk, 1 +strong-sport.com.ua, 1 +strongdm.com, 1 +strongohio.gov, 1 +strongpassword.club, 1 +strongprorealty.com, 1 +strongrandom.com, 0 +strongsalpinesucculents.com, 1 +strongtieinsurance.com, 1 +strongtomorrow.tk, 1 +strongtowerpc.com, 1 +stroomacties.nl, 1 +stroopwafel.ch, 1 +stropek.eu, 1 +stropkova.eu, 1 +strosemausoleum.com, 1 +stroseoflima.com, 1 +strotmann.de, 1 +strousberg.net, 1 +stroyca.tk, 1 +stroydvor.tk, 1 +stroyka-iz-brusa.ru, 1 +stroykomi.tk, 1 +stroynet.ml, 1 +stroyservice-tver.ru, 1 +strozik.de, 1 +strrl.com, 1 +strtrade.com, 1 +structurally.net, 1 +structure.systems, 1 +strugee.net, 1 +strumpe.lv, 1 +strunecka.cz, 1 +struxureon.com, 1 +strydom.me.uk, 1 +stsolarenerji.com, 1 +ststanislaus.com, 1 +stt.wiki, 1 +sttammanyurology.com, 1 +sttg.com.au, 1 +stthomasbrigantine.org, 1 +sttl-topographie.com, 1 +sttpk.id, 1 +sttrv.ru, 1 +stuartbeard.com, 1 +stuartbell.co.uk, 1 +stuartbell.uk, 1 +stuartcrawford.co.nz, 1 +stuartcrawford.nz, 1 +stuarteggerton.com, 1 +stuartmorris.id.au, 1 +stuartmorris.me, 1 +stuartmorris.name, 1 +stuartmorris.tel, 1 +stuartparsons.com, 1 +stubbings.de, 1 +stubbingsmail.de, 1 +stubbmail.de, 1 +stubentiga.de, 1 +stuckateur-bruno.de, 0 +stucki-bagger.ch, 1 +stuckwithme.tk, 1 +stuco.co, 1 +stucydee.nl, 1 +stud-lib.ml, 1 +studay.fr, 1 +studboo.com, 1 +student.andover.edu, 1 +studentaid.gov, 1 +studentenmobiliteit.be, 1 +studenterguiden.dk, 1 +studentforums.biz, 1 +studenti.tk, 1 +studentingent.be, 1 +studentite.bg, 0 +studentjournalist.ml, 1 +studentklinikk.no, 1 +studentloans.gov, 1 +studentnep.tk, 1 +studentpop.com, 1 +studentproject.be, 1 +studentrightsadvocate.org, 1 +studentse.fr, 1 +studentsfirstnb.com, 1 +studenttenant.com, 1 +studiekort.se, 1 +studiekortet.com, 1 +studiekortet.eu, 1 +studiekortet.net, 1 +studiekortet.nu, 1 +studiekortet.org, 1 +studiekortet.se, 1 +studienportal.eu, 1 +studierttomnoch.de, 1 +studio-637.com, 1 +studio-abok.com, 1 +studio-architetto.com, 1 +studio-fotografico.ru, 1 +studio-happyvalley.com, 1 +studio-impress.com, 1 +studio-mir.tk, 1 +studio-n.pl, 1 +studio-satellite.com, 1 +studio32.tk, 1 +studio3a.design, 1 +studio413.net, 1 +studio678.com, 0 +studioadevents.com, 1 +studioandrew.tk, 1 +studioavvocato.roma.it, 1 +studioavvocato24.it, 1 +studiobrandano.com, 1 +studiocharloslivro.tk, 1 +studiodelbenessere.com, 1 +studiodentisticomasi.com, 1 +studiodentisticosanmarco.it, 1 +studiodewit.nl, 1 +studiodoprazer.com.br, 1 +studiodpe.com, 1 +studioevent.tk, 1 +studiofpvet.it, 1 +studiogavioli.com, 1 +studiogears.com, 1 +studiograou.com, 1 +studiohelder.fr, 0 +studiohomebase.amsterdam, 1 +studiokicca.com, 1 +studiolegalemarchi.tk, 1 +studiolegalepaternostro.it, 1 +studiolupotti.it, 1 +studiomarcella.com, 1 +studiomenfis.com, 1 +studiomko.com, 1 +studionowystyl.pl, 1 +studiopirrate.com, 1 +studiopop.com.br, 1 +studioproapp.com, 1 +studioriehl.com, 1 +studiosql.ml, 1 +studiostawki.com, 1 +studiostudio.net, 1 +studiosuracidenunzio.it, 1 +studiosus-gruppenreisen.com, 1 +studiotheatrestains.fr, 1 +studiotres.com.br, 1 +studiovaud.com, 0 +studioxii.com, 1 +studiozelden.com, 1 +studipad.de, 1 +studipro-formation.fr, 1 +studipro-marketing.fr, 1 +studisys.net, 1 +studium.cz, 1 +studius.gq, 1 +studport.rv.ua, 1 +studsovet.cf, 1 +studuj.digital, 1 +studujdigital.cz, 1 +studujdigital.eu, 1 +studwebs.ml, 1 +study-support-beans.com, 1 +studyero.com, 1 +studyin.jp, 1 +studying-neet.com, 1 +studylish.com, 1 +studyme.ml, 1 +studynoun.com, 1 +studyportal.net, 1 +studyservice.net, 1 +studysive.com, 1 +studystack.ml, 1 +studytactics.com, 1 +studytube.nl, 1 +stuermer.me, 1 +stuetzredli.ch, 1 +stuff-fibre.co.nz, 1 +stuffi.fr, 1 +stuffiwouldbuy.com, 0 +stugor-danmark.com, 1 +stujay.com, 1 +stuka-art.de, 1 +stulda.cz, 1 +stum.io, 1 +stumblefallcrawl.com, 1 +stumeta.de, 1 +stumeta2018.de, 1 +stumeta2019.de, 1 +stumf.si, 1 +stumpblog.com, 1 +stuntman.ga, 1 +stuntmen.xyz, 1 +stupendo.ec, 1 +stupendousproduce.com, 1 +stuphid.tk, 1 +stupidest.org, 1 +stupidstatetricks.com, 1 +stupidthoughts.tk, 1 +stupino-stroy.cf, 1 +stutelage.com, 1 +stutsmancounty.gov, 1 +stuudium-mail.ee, 1 +stuudium.cloud, 1 +stuudium.com, 1 +stuudium.eu, 1 +stuudium.life, 1 +stuudium.link, 1 +stuudium.net, 1 +stuudium.org, 1 +stuudium.pro, 1 +stuvel.eu, 1 +stuvus.de, 1 +stuvus.uni-stuttgart.de, 1 +stuyvesantoutdoor.com, 1 +stview.me, 1 +stx.ie, 1 +stygium.net, 0 +styilishdress.tk, 1 +stylaq.com, 1 +stylearray.com, 1 +stylebajumuslim.com, 1 +stylebeat.tk, 1 +styleci.io, 1 +stylecollective.us, 1 +styledbysally.com.au, 1 +styleelite.tk, 1 +styleetvieperfumes.com, 1 +styleflow.nl, 1 +stylemall.tk, 1 +stylepixo.com, 1 +stylesaag.com, 1 +styletheweb.cf, 1 +styletron.org, 1 +stylett.ru, 1 +stylewish.me, 1 +stylezutra.com, 1 +stylidafm.gr, 1 +stylingstudio.ga, 1 +stylistbazaar.com, 1 +stylle.me, 1 +styllussports.com.br, 1 +stylodessens.fr, 1 +styloeart.com, 1 +styloplumeblog.fr, 1 +stylspire.com, 1 +styplon.cf, 1 +styxxx.de, 1 +stzur.com, 1 +su1ph3r.io, 1 +suachuanha365.com, 1 +suagent.com, 1 +suaraangin.com, 1 +suareforma.com, 0 +suaudeau.fr, 1 +suaudeau.org, 1 +suayslim.com, 1 +sub-net.at, 1 +sub.media, 0 +subafoto.hu, 1 +subahankamal.tk, 1 +subarus.tk, 1 +subastasdecarros.net, 1 +subastasnacionales.com, 1 +subbacultcha.tk, 1 +subdev.org, 1 +subdivider.tk, 1 +subgirl.ga, 1 +subiacotram.com.au, 1 +subject-barred.cf, 1 +subjektzentrisch.de, 1 +sublimated.tk, 1 +sublimebits.com, 1 +sublimesecurity.com, 1 +sublimesurface.fr, 1 +sublimetours.com, 1 +sublimigeek.fr, 1 +sublimm.fr, 1 +sublocale.com, 0 +submedia.tv, 0 +submeet.vet, 1 +submelon.tech, 1 +submit-link.cf, 1 +submityou-rlink.tk, 1 +submityour-link.tk, 1 +subohm.com, 1 +suborbital.io, 1 +subpage.tk, 1 +subrad.io, 1 +subsistence.wiki, 1 +substances.be, 1 +substitutealert.com, 1 +substore.co.il, 1 +subteen.gq, 1 +subtitry.ru, 1 +subtlelonging.com, 0 +suburban-landscape.net, 1 +suburbaninfinitioftroyparts.com, 1 +suburbanprojects.com.au, 1 +suburbanpsych.org, 1 +suburbansites.com, 1 +suburbanweldingandsteel.com, 1 +suburbservice.net, 0 +subversionnews.tk, 1 +subversive-tech.com, 1 +subwaysurfers.tk, 1 +subwaytrain.tk, 1 +succ.in, 1 +succesprojekter.dk, 1 +success.market, 1 +successbox.vn, 1 +successclicker.tk, 1 +successdeliv.com, 1 +successemails.ml, 1 +successful-online-business.com, 1 +successminds.com, 1 +succorfish.net, 1 +succubus.network, 1 +succubus.xxx, 1 +sucessclick.gq, 1 +suceveanca.ro, 1 +suche.org, 1 +suchem.com, 1 +suchhire.com, 1 +suchmaschinen-werkstatt.de, 1 +suckmyan.us, 0 +sucretown.net, 1 +sudabaus.com, 1 +sudak-turizm.tk, 1 +sudametrica.tk, 1 +sudanell.tk, 1 +sudanindependent.com, 1 +sudanindependent.net, 1 +sudaraka.org, 0 +sudcalifornianos.me, 1 +sudmotor-occasions.be, 0 +sudo.ws, 1 +sudoash.com, 1 +sudosaveclimate.com, 1 +sudoschool.com, 1 +sudosu.fr, 1 +suecaunitedfc.tk, 1 +suelyonjones.com, 1 +suempresa.cloud, 1 +sueno.ro, 1 +suenotek.com, 1 +suerteloteria.com, 1 +suessdeko.de, 1 +suevia-ka.de, 1 +suffix.ru, 1 +sufix.cz, 1 +sufleu.ro, 1 +sufleuri.ro, 1 +sugarbrother.com, 0 +sugarcube.ml, 1 +sugardaddy.network, 1 +sugardating.network, 1 +sugarhillsfarm.com, 1 +sugarlandurology.com, 1 +sugarondemand.com, 1 +sugaropencloud.eu, 1 +sugaropencloud.uk, 1 +sugarpiano.com, 1 +sugarroll.ml, 1 +sugarsalted.com, 1 +sugarshin.net, 1 +sugartownfarm.com, 1 +sugaru.pe, 1 +sugatime.tk, 1 +suger.io, 1 +suggea.com, 1 +suggestim.ch, 0 +sugos.ga, 1 +sugos.ml, 1 +suhaildawood.com, 1 +suicide.gq, 1 +suicidegirls.cf, 1 +suike.com, 1 +suikerspinnetje.nl, 1 +suisui.stream, 1 +suiteassured.com, 1 +suitesapp.com, 1 +suitocracy.com, 1 +sujal.com, 1 +sujatadev.in, 1 +sujiao.de, 1 +sujoydhar.in, 1 +sukamusik.tk, 1 +suke3.jp, 1 +sukherchador.org, 1 +suki.moe, 1 +sukiu.net, 1 +sukker-oaxaca.com, 1 +sukoyaka-labo.com, 1 +sukoyakapp.com, 1 +sukrie.net, 1 +sukriyedonmez.com, 1 +sukruarslan.tk, 1 +suksit.com, 0 +sulabs.org, 1 +sulavius.tech, 1 +sulawesi-adventure.tk, 1 +sulek.eu, 1 +sulemanmalik.tk, 1 +sulemanquotes.tk, 1 +suleri.tk, 1 +sulkmen.tk, 1 +sultangroup.ru, 1 +suluvir.com, 1 +sulytics-tool.com, 1 +sumatogroup.com, 1 +sumatphoto.com, 1 +sumatrabarat.ml, 1 +sumatraselatan.ml, 1 +sumatrautara.ml, 1 +sumatriptan365.tk, 1 +sumbur.ga, 1 +sumcrevillent.tk, 1 +sumguy.com, 1 +sumhost.ml, 1 +sumisa.cf, 1 +sumit.blog, 1 +sumit.me, 1 +sumit.sh, 1 +sumitbot.ga, 1 +sumitchahal.blog, 1 +sumitchahal.com, 1 +summa.eu, 0 +summarized.gq, 1 +summer.ga, 1 +summer.today, 1 +summerbo.at, 1 +summercampthailand.com, 1 +summermc.cc, 1 +summermovies.nyc, 1 +summerslandingwr.com, 1 +summing.ga, 1 +summit-humanpotential.com, 1 +summit-level.ru, 1 +summitbankofkc.com, 1 +summitcountyboe.gov, 1 +summiteyekc.com, 1 +summitlighthousela.org, 1 +summus.jp, 1 +summusglobal.com, 1 +sumochki.tk, 1 +sumppumpchicagoil.com, 1 +sumran.in, 1 +sumthing.com, 1 +sumutoday.com, 1 +sun-beach.com.ua, 1 +sun-host.ml, 1 +sun-wellness-online.com.vn, 1 +sun.re, 1 +sun1218.com, 1 +sun1245.com, 1 +sun1338.com, 1 +sun1345.com, 1 +sun1378.com, 1 +sun668.asia, 1 +sun668.co, 1 +sunbit.com, 1 +sunblind.tk, 1 +sunboxstore.jp, 0 +sunbritetv.com, 0 +sunbury.xyz, 1 +sunchasercats.com, 1 +sunchild.ml, 1 +suncity288.com, 1 +suncity288.net, 1 +suncity8118.cn, 1 +suncity8118.com, 1 +suncity818.cn, 1 +suncity818.com, 1 +suncity818.net, 1 +suncity8338.cn, 1 +suncity8338.com, 1 +suncity858.cn, 1 +suncity858.com, 1 +suncity8668.com, 1 +suncity8998.com, 1 +suncitycinemas.com, 1 +suncloud.ch, 1 +sundanceusa.com, 1 +sunday.pm, 1 +sundayfundayjapan.com, 1 +sundiel.tk, 1 +sundragon.se, 1 +suneilpatel.com, 1 +sunfeathers.net, 1 +sunfiregold.com, 1 +sunfireshop.com.br, 1 +sunflyer.cn, 0 +sunfox.cz, 1 +sunfulong.blog, 1 +sunfulong.me, 1 +sungalsses.ml, 1 +sungreen.info, 1 +sunhaoxiang.net, 1 +sunjiutuo.com, 1 +sunkar.tk, 1 +sunlit.cloud, 1 +sunn.ie, 1 +sunny.co.uk, 1 +sunnyhome.tk, 1 +sunnylyx.com, 1 +sunnynetworks.net, 1 +sunnyside-jazzclub.com, 1 +sunnysideups.co, 1 +sunnysin.net, 1 +sunnyx3m.com, 1 +sunpax.ga, 1 +sunpig.com.my, 1 +sunpig.com.sg, 1 +sunpig.my, 1 +sunpig.sg, 1 +sunplay.host, 1 +sunred.info, 1 +sunred.org, 1 +sunrichtec.com, 1 +sunrisecovelodge.com, 1 +sunroof.ga, 1 +sunroomsbywoodland.com, 1 +sunroomsbywoodlandwindows.com, 1 +sunroomschicagoil.com, 1 +sunsdesign.net, 1 +sunsetdentalhenderson.com, 1 +sunsetfire.de, 1 +sunsetnelson.com, 1 +sunsetwx.com, 1 +sunshilin.tk, 1 +sunshine-cleaners.com.au, 1 +sunshinecoastplumbingcompany.com.au, 1 +sunshinefrontier.tk, 1 +sunshinelife.tk, 1 +sunshinerequest.com, 1 +sunshinesf.org, 1 +sunskyview.com, 1 +sunsong.org, 1 +sunsquare.cz, 1 +sunstar.bg, 1 +suntzuparadirectivos.com, 1 +sunwolf.studio, 1 +sunyanzi.cf, 1 +sunyanzi.tk, 1 +suomiheraa.com, 1 +suomika.pl, 1 +suourl.com, 1 +sup39.ml, 1 +supa.sexy, 1 +supdajuice.tk, 1 +supedio.com, 1 +supedium.com, 1 +supel.gq, 1 +super-baik.tk, 1 +super-boy.tk, 1 +super-erotica.ru, 1 +super-knighki.gq, 1 +super-lolitas.tk, 1 +super-o-blog.com, 1 +super11.nl, 1 +superaficionados.com, 1 +superbart.nl, 1 +superbaskirskij-med.tk, 1 +superbdistribute.com, 1 +superbestpalsclub.tk, 1 +superbouncebouncycastles.com, 1 +superbowlkneel.com, 1 +superbshare.com, 1 +supercalorias.com, 1 +supercarpets.ru, 1 +supercarrot.tk, 1 +supercastlesadelaide.com.au, 1 +supercastlesbrisbane.com.au, 1 +supercastlesmelbourne.com.au, 1 +supercastlessouthsydney.com.au, 1 +supercastlessunshinecoast.com.au, 1 +supercentenarian.com, 1 +supercharged.co.uk, 1 +supercima.com, 0 +supercinebattle.fr, 1 +supercours.net, 1 +supercraft.shop, 1 +supercursosonline.store, 1 +superdaddy.club, 1 +superdolly.cf, 1 +superdrillers.tk, 1 +superdroni.com, 1 +superenduro.net, 1 +superfaktura.at, 1 +superfaktura.cz, 1 +superfaktura.sk, 1 +superfastpress.com, 1 +superfly.tk, 1 +superfoodsexplained.com, 1 +superfury.tk, 1 +superglidewardrobes.co.uk, 1 +supergmtransport.com.au, 1 +supergood.ga, 1 +supergoods.tk, 1 +supergroup.tk, 1 +superguide.com.au, 1 +superhappiness.com, 1 +superhappyfun.club, 1 +superherofactory.hu, 1 +superhits.gq, 1 +superhome.com.au, 1 +superidropulitrice.com, 1 +superiordetail.tk, 1 +superiormusic.tk, 1 +superiorseating.com, 1 +superis.eu, 1 +superklima.ro, 0 +superkonsult.se, 1 +superkrasota.tk, 1 +superlandnetwork.de, 1 +superlight.tk, 1 +superlisa.nl, 1 +superlog.tk, 1 +superlol.tk, 1 +supermae.pt, 1 +supermagna.tk, 1 +supermanera.tk, 1 +supermarkets.ga, 1 +supermart.tk, 1 +supermarx.nl, 1 +supermercadosdia.com.ar, 1 +supermercato24.it, 1 +supermil.ch, 1 +supermini-games.tk, 1 +supermustang.tk, 1 +supern0va.net, 0 +supernatural-fans.tk, 1 +supernaut.info, 1 +supernogi.ga, 1 +superpase.com, 1 +superpi.noip.me, 1 +superraclette.fr, 1 +supersahnetorten.de, 1 +supersandro.de, 1 +superservers.ml, 1 +supershrooms.nl, 1 +supersisi.cf, 1 +supersisi.ml, 1 +superskidki.cf, 1 +supersole.net, 0 +supersonnig-festival.de, 1 +supersonnigfestival.de, 1 +superspeller.ng, 1 +supersprowtz.com, 1 +superstargossip.com, 1 +superstarhost.tk, 1 +superstart.tk, 1 +supersteosbouncycastles.com, 1 +superstone.diamonds, 1 +superstropdas.nl, 1 +supersu.kr, 1 +supersuccessfulweightloss.com, 1 +superswingtrainer.com, 1 +supertasker.org, 1 +supertrade.tk, 1 +supertutorial.com.br, 1 +supervets.com.au, 1 +superway.es, 1 +superzaim.ga, 1 +supeuro.com, 1 +supfood.cz, 1 +supioka.com, 1 +suplementasi.com, 1 +suplementosmarket.com, 1 +supmil.net, 1 +suppdeals.eu, 1 +supperclub.net, 1 +supplement.cf, 1 +supplementalconditions.com, 1 +supplementpolice.tk, 1 +supplementswatch.com, 0 +suppliersession2021.com, 1 +supplies24.at, 1 +supplies24.es, 1 +supplycore.com, 1 +supplydoc.com, 1 +supplynation.org.au, 1 +support-ticino.ch, 1 +support.mayfirst.org, 0 +support4professionals.nl, 1 +supportadvantage.co.uk, 1 +supportal.one, 1 +supportericking.org, 1 +supportfan.gov, 1 +supportmeindia.com, 1 +supra.tf, 1 +supracube.com, 1 +suprax365.tk, 1 +suprem.biz, 0 +suprem.ch, 0 +supremaa.com, 1 +supreme-council.me, 1 +supreme-court.tk, 1 +suprememale.tk, 1 +supremestandards.com, 1 +supriville.com.br, 1 +supropionegocio.tk, 1 +supweb.ovh, 1 +sur-v.com, 1 +suranganet.tk, 1 +surasak.org, 1 +surasak.tk, 1 +suraya.online, 1 +surdam.casa, 1 +sure-it.de, 1 +surefit-oms.com, 1 +surefleet.com.au, 1 +surf1969.tk, 1 +surfcaparica.com, 1 +surfingnash.com, 1 +surflessonslisbon.com, 1 +surfnetkids.com, 1 +surfnetparents.com, 1 +surfocal.com, 1 +surfocal.net, 1 +surfseo.ml, 1 +surgeholdinggroup.com, 1 +surgeongeneral.gov, 1 +surgerylifeenhancement.cloud, 1 +surgerylifeenhancement.com, 1 +surgicalassociateswny.com, 1 +surgispa.net, 1 +surialternat.tk, 1 +suricate.ru, 1 +suriname.tk, 1 +surnet.io, 1 +surnganet.tk, 1 +suroil.com, 1 +surpreem.com, 1 +surpriz-net.tk, 1 +surrealcoder.com, 0 +surrealismocantabria.tk, 1 +surrealistas.tk, 1 +surreyheathyc.org.uk, 0 +surthriveak.com, 1 +suruifu.com, 1 +suruifu.tk, 1 +survature.com, 1 +surveer.com, 1 +surveyhealthcare.com, 1 +surveymill.co.uk, 1 +surveyorcloud.com, 1 +survivalfitnessplan.com, 1 +survivebox.fr, 1 +survivebox.net, 1 +survivingmesothelioma.com, 1 +susajja.com, 1 +susanagomez.tk, 1 +susanbpilates.co, 1 +susanbpilates.com, 1 +susanmmeyersauthor.com, 1 +susann-kerk.de, 0 +susanna-komischke.de, 1 +susanvelez.com, 1 +susconam.org, 1 +suseki.ga, 1 +sushi-sakura.tk, 1 +sushi.roma.it, 1 +sushibesteld.nl, 1 +sushifrick.de, 1 +sushikatze.de, 1 +sushilmedicos.tk, 1 +susoft.tk, 1 +susosudon.com, 1 +suspect.id, 1 +suspension-shop.com, 1 +suspiciousdarknet.xyz, 1 +sussexheart.com, 1 +sustain.software, 1 +sustainability.gov, 1 +sustainabilityknowledgegroup.com, 1 +sustainabilitysociety.hk, 1 +sustained.tk, 1 +sustainimum.com, 1 +sustainimum.email, 1 +sustainimum.eu, 1 +sustainimum.net, 1 +sustainimum.org, 1 +sustainoss.org, 1 +sustc.ac.cn, 1 +suste.ch, 0 +susthx.com, 1 +sutabi.tk, 1 +sutas.market, 1 +sutinenmatthews.tk, 1 +sutore.com, 1 +suts.co.uk, 1 +suttacentral.net, 1 +suttonbouncycastles.co.uk, 1 +sutty.nl, 1 +suurhelsinki.cf, 1 +suuria.de, 1 +suv4.net, 1 +suvidhaapay.com, 1 +suwanneecountyfl.gov, 1 +suwanneehealthrehab.com, 1 +suwcountyfl.gov, 1 +suzdalgrad.cf, 1 +suzi3d.com, 1 +suziekovner.com, 1 +suzikogsm.tk, 1 +suzukikenichi.com, 1 +suzukimarinepress.com, 1 +sv-1966-medenbach.de, 0 +sv-bachum-bergheim.de, 1 +sv-schody.cz, 1 +sv-turm-hohenlimburg.de, 1 +sv.search.yahoo.com, 0 +sv443.net, 1 +svager.cz, 1 +svak-gutachter.de, 0 +svanstrom.com, 1 +svanstrom.org, 1 +svantner.sk, 1 +svarka22.ml, 1 +svarovani.tk, 1 +svatba.cf, 1 +svatbamisiaviti.tk, 1 +svatyjur.tk, 1 +svauto.ks.ua, 1 +svc-sitec.com.mx, 1 +svc-sitec.mx, 1 +svc-sitec.org, 1 +svc.bike, 1 +svc1.xyz, 1 +svdb.co, 0 +svdesign.su, 1 +sve-hosting.nl, 1 +svebran.xyz, 1 +svedalataxi.com, 1 +sveikas.info, 1 +sveinerik.org, 1 +sven-erik.org, 1 +sven.ai, 1 +svenbacia.me, 1 +svendubbeld.nl, 1 +sveneckelmann.de, 1 +svenjaundbenni.de, 1 +svenjaundchristian.de, 1 +svenluijten.com, 0 +svenmuller.nl, 1 +svennd.be, 1 +svenpeter.eu, 1 +svenpeter.info, 1 +svenpeter.me, 1 +svenpeter.net, 1 +svenpeter.org, 1 +svenskakyrkansunga.tk, 1 +svenskapsalmer.se, 1 +svenskarnaochinternet.se, 1 +svenskmediabevakning.se, 1 +svensson-generators.be, 1 +sverdlov.spb.ru, 1 +sverdlovsk.gq, 1 +sverdlovsk.ml, 1 +sverdlovsk.tk, 1 +sverigeringen.se, 1 +sverlo.cf, 1 +svet.tk, 1 +svetandroida.cz, 1 +svetapublic.com, 1 +svetila.com, 1 +svetlanamamedova.tk, 1 +svetlilo.com, 1 +svetlograd.tk, 1 +svetoch.ga, 1 +svetodiod.gq, 1 +svetonaushniki.tk, 1 +svetplast.msk.ru, 1 +svetplast.spb.ru, 0 +svetrelaxu.cz, 1 +svg-board.ml, 1 +svgzone.tk, 1 +svhni.nl, 1 +svht.nl, 0 +svia.nl, 1 +svijet-medija.hr, 1 +svinformatica.es, 1 +svirel.ga, 1 +sviz.pro, 1 +svj-stochovska.cz, 1 +svjvn.cz, 1 +svm-basketball.de, 1 +svmedia.be, 1 +svo-intranet.de, 1 +svobodny.fr, 1 +svobodnyblog.cz, 1 +svodjapan.info, 1 +svoi-ugolok.tk, 1 +svoimi-slovami.tk, 1 +svorcikova.cz, 1 +svorkmofotball.tk, 1 +svpe.de, 1 +svpe.eu, 1 +svpoa.org.uk, 1 +svrx.one, 1 +svse.global, 1 +svseglobal.com, 1 +svswebmarketing.com, 1 +svtr.de, 1 +sw-machines.io, 1 +sw-servers.net, 1 +sw33tp34.com, 1 +swa-il.gov, 1 +swabhoomi.org, 1 +swabifoundation.tk, 1 +swacp.com, 1 +swaenenburg.be, 1 +swagfuli.com, 1 +swagger.io, 1 +swagger.london, 1 +swagsocial.net, 1 +swain.tk, 1 +swallowgateway.com, 1 +swallsoft.co.uk, 1 +swallsoft.com, 1 +swamiclub.ru, 1 +swanbitcoin.com, 1 +swankism.com, 1 +swansdoor.org, 1 +swap.gg, 1 +swap.ly, 1 +swapbox.tk, 1 +swapfin.com, 1 +swarfarm.com, 1 +swarlys-server.de, 1 +swarmation.com, 1 +swarmdrone.services, 1 +swat.io, 1 +swat4stats.com, 1 +swatee.com, 1 +swattransport.ae, 1 +sway-cdn.com, 1 +sway.com, 1 +swayampaaka.com, 1 +swc-cfc.gc.ca, 1 +swcloud.io, 1 +swd.agency, 1 +swdevteam.com, 1 +swe77.com, 1 +swe777.com, 1 +sweak.net, 1 +sweat-shirts.tk, 1 +swederica.tk, 1 +swedish-saints.tk, 1 +swedishforces.tk, 1 +swedishhost.com, 1 +swedishhost.se, 1 +sweep-me.net, 1 +sweepay.ch, 0 +sweepy.pw, 1 +sweet-as.co.uk, 1 +sweet-spatula.com, 1 +sweetair.com, 1 +sweetairlines.tk, 1 +sweetbabyjesus.com, 1 +sweetbridge.com, 1 +sweetcalculus.ru, 1 +sweetdata.io, 1 +sweetenedcondensed.com, 1 +sweetgood.de, 1 +sweethomemargarita.com, 1 +sweethomesnohomishrenovations.com, 1 +sweethorses.tk, 1 +sweetintrigue.tk, 1 +sweetlegs.jp, 1 +sweetlycakes.com, 0 +sweetologist.co, 1 +sweetparis.cf, 1 +sweets-mimatsu.com, 1 +sweetspot.co.kr, 1 +sweetvanilla.jp, 1 +sweetwatertx.gov, 1 +sweetydecor.ru, 1 +sweharris.org, 1 +swerve-media-testbed-03.co.uk, 1 +swet.com.ua, 1 +swetrust.com, 1 +swevenstays.com, 1 +swey.net, 0 +swfmax.com, 1 +swgenetx.com, 1 +swha.xyz, 1 +swhw.io, 1 +swi.sytes.net, 1 +swiatpilki.com, 1 +swid.co.uk, 1 +swiffertirimborsa.it, 1 +swift-devedge.de, 1 +swiftbonds.com, 1 +swiftcashforcars.com.au, 1 +swiftcom.co.za, 1 +swiftcrypto.com, 1 +swifteh.net, 1 +swiftirc.net, 1 +swiftpak.co.uk, 1 +swiftqueue.com, 1 +swiftrecharge.com, 1 +swilly.org, 1 +swim-smart.com, 1 +swimmingpoolaccidentattorney.net, 1 +swimmingpoolpumpsbassonia.co.za, 1 +swimpool.co.il, 1 +swimpools.co.il, 1 +swimready.net, 1 +swimwear365.co.uk, 1 +swindontennisclub.azurewebsites.net, 1 +swindontennisclub.org, 1 +swineson.me, 1 +swing-belleville.de, 1 +swingerclub.in, 1 +swingle.ga, 1 +swingmonkey.com, 1 +swingtimeinthegardens.com, 1 +swingular.com, 1 +swingz.com.au, 1 +swipedon.com, 1 +swipetv.ie, 1 +swish-ict.com, 0 +swiss-apartments.com, 0 +swiss-connection.net, 0 +swiss-sale.ch, 1 +swiss-vanilla.ch, 1 +swiss-vanilla.com, 1 +swissbearfoodservices.com, 1 +swisscannabis.club, 1 +swissdojo.ch, 0 +swissdomaintrustee.ch, 1 +swisselement365.com, 0 +swissentreprises.ch, 1 +swisservers.com, 1 +swissfreshaircan.ch, 0 +swissfreshaircan.com, 0 +swissgrid.ch, 1 +swissid.ch, 1 +swissinternationalva.com, 1 +swisslifestyletips.ch, 1 +swisslinux.org, 1 +swisstacticaldevelopment.ch, 1 +swisstechassociation.ch, 1 +swisstechmap.ch, 1 +swisstranslate.ch, 0 +swisstranslate.fr, 0 +swissurf.tk, 1 +swissvanilla.ch, 1 +swissvanilla.com, 1 +swisswebhelp.ch, 1 +swissxperts.ch, 1 +swit.io, 1 +switch-defekt.de, 1 +switch-trader.com, 1 +switchassur.fr, 1 +switcheo.exchange, 1 +switcheo.rocks, 1 +switchinitiatives.com, 1 +switchinitiatives.fr, 1 +switchinitiatives.org, 1 +switchur.com, 1 +swivells.com, 1 +swjtu.today, 1 +swjz.art, 1 +swkdevserver.tk, 1 +swktestserver.tk, 1 +swmcfcu.org, 1 +swmlink.com, 1 +swn-nec.de, 1 +swoop-qa.cloud, 1 +swoop.cloud, 1 +swordfeng.xyz, 1 +swordfighting.net, 1 +sworn.ga, 1 +swostik.com, 1 +swqa.hu, 1 +swrelay.net, 1 +swrelay.xyz, 1 +swrpgitems.com, 1 +swtrayssq.gq, 1 +swtun.com, 1 +swvaux.com, 1 +swxtd.com, 1 +swy.cz, 1 +swyn.net, 1 +swynwyr.com, 1 +sx3.no, 1 +sx6729.com, 1 +sx8.ovh, 1 +sxistolithos.gr, 1 +sxmd99.com, 1 +sy-anduril.de, 1 +sy24.ru, 1 +sy95.de, 1 +syakeapps.net, 1 +syakonavi.com, 1 +syazli7.me, 1 +syc-rotterdam.tk, 1 +sycamorememphis.org, 1 +sycca.com, 1 +sychov.pro, 1 +sydney-sehen.com, 1 +sydney.dating, 1 +sydneybamboo.com.au, 1 +sydneybusinessweb.com.au, 1 +sydneychillies.com.au, 1 +sydneyexperiences.com, 1 +sydneyhelicopters.com.au, 1 +sydneylawnandturf.com.au, 1 +syedmuhdadasgardezi.tk, 1 +syenar.net, 1 +syezd.com.au, 1 +sygnanet.pl, 1 +syhost.at, 1 +syhost.ch, 1 +syhost.de, 1 +sykepleien.no, 0 +sykorp.com, 1 +sylaps.com, 1 +syleam.in, 1 +sylencegsm.com, 1 +sylfie.net, 1 +sylino.tk, 1 +syllogi.xyz, 1 +sylvain.codes, 1 +sylvainboudou.com, 0 +sylvaindurand.fr, 1 +sylvaindurand.org, 1 +sylvaloir.fr, 1 +sylvan.me, 1 +sylvangarden.net, 1 +sylve.ch, 0 +sylwiart.pl, 1 +sylwiasun.com, 1 +sym01.com, 1 +symbiose-com.ch, 0 +symbiose-immobilier.ch, 0 +symbiose.com, 1 +symbiosecom.ch, 0 +symbolics.digital, 1 +symdevinc.com, 1 +symeda.de, 1 +symeonchen.com, 1 +symetrix.tk, 1 +symfora-meander.nl, 1 +symlink.io, 1 +symlnk.de, 1 +symoteb.ir, 1 +symphonise.consulting, 1 +sympletrade.com, 1 +symplexia.com.br, 1 +symplyos.tk, 1 +sympmarc.com, 1 +symposium.beer, 1 +symptome-erklaert.de, 1 +symstar.co.uk, 1 +symvolik.ru, 1 +syna.dev, 1 +syna.site, 1 +synabi.com, 0 +synack.uk, 1 +synackrst.net, 1 +synapsepain.com, 1 +synaptickz.me, 1 +sync-it.no, 1 +synccentre.com, 1 +synccore1.com, 1 +syncevolution.org, 1 +syncflare.com, 1 +syncgal.com, 1 +synchrocube.com, 1 +synchronicity.cz, 1 +synchronyse.com, 1 +synchtu.be, 0 +syncios.com, 1 +synclio.com, 1 +syncmindglobal.com, 1 +syncmylife.net, 0 +syncplay.pl, 1 +syncresis.com, 1 +syncrise.co.jp, 1 +synd.io, 1 +syndic-discount.fr, 0 +syndikalismus-im-laendle.tk, 1 +syneart.com, 1 +synecek11.cz, 1 +synedat.com, 1 +synergenxhealth.com, 1 +synergiedenken.de, 1 +synergisticsoccer.com, 1 +synergy-logistics.tk, 1 +synergyfitness.com.au, 1 +synergyflare.com, 1 +synergyzone.tk, 1 +synerionagile.com, 1 +synfin.org, 1 +syniah.com, 1 +synicalsyntax.com, 1 +synitsa.tk, 1 +synology.com, 0 +synony.me, 1 +synonymedeutsch.com, 1 +synonyymisanakirja.com, 1 +synotna.eu, 1 +synrestaccounting.com, 1 +syntaxnightmare.com, 1 +synth.style, 1 +synthesisorganics.com, 1 +syntheticgrassliving.com.au, 1 +synthetictrading.com, 1 +synthetik.com, 1 +synthv.fun, 0 +syntia.tk, 1 +syo-ryuga.jp, 1 +syobon.org, 1 +syogainenkin119.com, 1 +syoier.com, 1 +syok.my, 1 +syonix.ru, 1 +syphax.ml, 1 +syplasticsurgery.com, 1 +sypra-host.tk, 1 +sypreformas.tk, 1 +syquel-systems.de, 1 +syracuseut.gov, 1 +syrea.com, 1 +syrianet.cf, 1 +syrius.tk, 1 +syronex.com, 1 +sys-admin.fr, 1 +sys-tm.com, 1 +sysadmin.cl, 1 +sysadmin.xyz, 1 +sysadmin21.tk, 1 +sysadmins.ro, 1 +sysadvisors.pl, 1 +sysclouds.de, 1 +syscoon.com, 1 +sysctl.se, 1 +syscurve.com, 1 +sysdb.io, 1 +sysert.tv, 0 +sysgap-gsci.com, 1 +sysin.org, 1 +syskit.com, 1 +syslogic.io, 1 +sysmike.de, 1 +sysmike.net, 1 +sysoon.com, 1 +sysoon.net, 1 +sysoons.com, 1 +sysrq.tech, 0 +systea.fr, 1 +systea.net, 1 +system-admin-girl.com, 1 +system-fehler.tk, 1 +system-m.de, 0 +system.is, 1 +system.md, 1 +system4travel.com, 1 +systemadmin.uk, 1 +systemart.pro, 1 +systematic-momo.com, 1 +systematic-momo.dk, 1 +systemausfall.org, 1 +systemblog.tk, 1 +systemchile.com, 1 +systemd.ch, 0 +systemd.eu.org, 1 +systemd.info, 1 +systemeprod.fr, 0 +systemerr.tk, 1 +systemintegra.ru, 1 +systemisbusy.info, 1 +systemlead.pl, 1 +systemli.org, 1 +systemofabrown.com, 1 +systemonthego.com, 1 +systemplust.com, 1 +systemsense.com.au, 1 +systemspace.link, 1 +systemtoto.ml, 1 +systemzeit.info, 1 +systime.dk, 1 +systoolbox.net, 1 +systrax.com, 1 +syswiki.org, 1 +sysystems.cz, 1 +syt3.net, 1 +syuez.com, 1 +syunpay.cn, 1 +syuumi.me, 1 +sywnthkrawft.tk, 1 +syzdev.com, 1 +syzygy-tables.info, 1 +syzygycareers.com, 1 +sz-ideenlos.de, 1 +sz-lessgym-kamenz.de, 1 +szadeczky.com, 1 +szafkirtv.pl, 1 +szamitogepdepo.com, 1 +szasz.me, 1 +szaszm.tk, 0 +szclsya.me, 0 +szczury.org, 1 +szelagnes.com, 1 +szelagnes.hu, 1 +szentistvanpt.sk, 1 +szepsegbennedrejlik.hu, 1 +szeptylasu.eu, 1 +szerbnyelvkonyv.hu, 1 +szerelem.love, 1 +szhighsun.com, 1 +szlovaknyelv.hu, 1 +szlovennyelv.hu, 1 +szotkowski.info, 1 +szpro.ru, 1 +szs.space, 1 +sztoriboljeles.hu, 1 +sztuanzi.top, 1 +szuecs.net, 1 +szuflady.pl, 1 +szww99.cc, 1 +szybkiebieganie.pl, 1 +szymczak.at, 1 +szyndler.ch, 1 +szzsivf.com, 1 +t-cophony.com, 1 +t-dent.com, 1 +t-hawk.com, 1 +t-m.me, 1 +t-network.nl, 1 +t-nice.com, 1 +t-pc.org, 1 +t-shirt-template.com, 1 +t-shirts4less.nl, 1 +t-shirty.tk, 1 +t-staffing.nl, 1 +t-stonegroup.com, 1 +t-tz.com, 0 +t-unit.ru, 1 +t.facebook.com, 0 +t00228.com, 1 +t00ts.com, 0 +t060.com, 1 +t070.com, 1 +t0ny.name, 1 +t12u.com, 1 +t1everydaymagic.com, 1 +t2-sit-test.tk, 0 +t2000headphones.com, 1 +t2000laserpointers.com, 1 +t22.uk, 1 +t2881.com, 1 +t2i.nl, 1 +t3.ie, 1 +t30365.com, 1 +t36533.com, 1 +t39.com, 1 +t3hty.fr, 1 +t3rror.net, 1 +t404.de, 1 +t449.com, 1 +t47.io, 1 +t49.com, 1 +t4c.link, 1 +t4cc0.re, 1 +t4gh.com, 1 +t4w.me, 1 +t5118.com, 1 +t51365.com, 1 +t5197.co, 1 +t6729.co, 1 +t6957.co, 1 +t776633.com, 1 +t7e.de, 0 +t81365.com, 1 +t82365.com, 1 +t8803.com, 1 +t8805.com, 1 +t8807.com, 1 +t8809.com, 1 +t8815.com, 1 +t8816.com, 1 +t8817.com, 1 +t8819.com, 1 +t8830.com, 1 +t88gg.com, 1 +t88jj.com, 1 +t88kk.com, 1 +t88ll.com, 1 +t88mm.com, 1 +t88nn.com, 1 +t88oo.com, 1 +t88ss.com, 1 +t88vip0.com, 1 +t88vip1.com, 1 +t88vip2.com, 1 +t88vip3.com, 1 +t88vip4.com, 1 +t88vip5.com, 1 +t88vip6.com, 1 +t88vip7.com, 1 +t88ww.com, 1 +t88yy.com, 1 +t90official.games, 1 +t9297.co, 1 +t9721.com, 1 +t9728.co, 1 +t9i.in, 1 +ta-65.com, 1 +ta-nuth.nl, 0 +ta-soest.nl, 0 +ta65.com, 1 +taabe.net, 1 +taalmeisje.nl, 1 +taaltaal.nl, 1 +taanishsaifu.gq, 1 +taartbesteld.nl, 1 +taartenvanthea.nl, 1 +tabacundo.tk, 1 +tabacundolindo.tk, 1 +tabadotupi.tk, 1 +tabakerka.tk, 1 +tabarnak.ga, 1 +tabclassics.tk, 1 +tabegamisama.com, 1 +tabelekaloryczne.waw.pl, 1 +tabernaalibaba.tk, 1 +tabernastudios.pe, 1 +tabi-news.com, 1 +tabi-runrun.com, 1 +tabi-time.com, 1 +tabira.tk, 1 +tabisuta.com, 1 +tablamatica.tk, 1 +tableandhearth.com, 1 +tabledown.ga, 1 +tabledusud.be, 1 +tabledusud.nl, 1 +tablemagnet.com, 1 +tableres.com, 1 +tablerocksbestrealtors.com, 1 +tablescraps.com, 1 +tablet.facebook.com, 0 +tabletd.com, 1 +tabletennis-tt.tk, 1 +tabletsandlaptops.com, 1 +tabletsbaratasya.com, 1 +tablettes-tactiles.tk, 1 +tableturnrms.com, 1 +tablondeempleo.com, 1 +tablotv.com, 0 +tablyrics.com, 1 +tabordaadvogados.ga, 1 +taborsky.cz, 1 +tabpanelwidget.com, 1 +tabtap.shop, 1 +tac-performance.net, 1 +tac-sys.net, 1 +tac-volley.com, 0 +tachi.uk, 1 +tachikawa-saisyuusyou.com, 1 +tachoplus.pl, 1 +tachyonapp.com, 1 +taciso.com, 1 +tackle.io, 1 +tackleyourfeelings.com, 1 +tacoma-dui-attorneys.com, 1 +tacoma-massage.com, 1 +tacomafia.net, 1 +tacomarugby.com, 1 +tacomarugby.org, 1 +tacotown.tk, 1 +tacticalavocado.com, 1 +tacticalgearexperts.com, 1 +tacticalvote.co.uk, 1 +tacticalwalls.com, 1 +tadalafil-tablets.tk, 1 +tadalafilindia.gq, 1 +tadamstudio.ca, 1 +taddiestales.com, 1 +tadiranbatteries.de, 1 +tadj-mahalat.com, 1 +tadjiki.tk, 1 +tadjikistan.tk, 1 +tadluedtke.com, 1 +tadtadya.com, 1 +tadu.de, 1 +tadzkitchen.com, 1 +taekwondo-berlin.tk, 1 +taffe-elec.com, 1 +tafusu-support.com, 1 +tagabrand.co.uk, 1 +tagalliances.com, 1 +tagalog.com, 1 +tagana-anindustrialpark.tk, 1 +tagarelaskidseteens.com.br, 1 +tagat.top, 1 +tagaytayhighlands.com, 1 +tagboards.tk, 1 +tagderinspiration.ch, 1 +tagdocumentary.com, 1 +taggedpdf.com, 0 +taggigkaktus.tk, 1 +taglioepiega.com, 1 +taglioepiega.eu, 1 +taglioepiega.it, 1 +tagnull.de, 1 +tagpay.com, 1 +tagstationen.se, 1 +tagstatravel.com, 1 +tagtog.net, 1 +tagtoys.com, 1 +taguette.com, 0 +taguette.fr, 0 +taguette.org, 1 +taguiginfo.com, 1 +tagungsraum-usedom.de, 1 +tagungsraum-zinnowitz.de, 1 +tagungsstaette-usedom.de, 1 +tagungsstaette-zinnowitz.de, 1 +tahakomlearning.com, 1 +tahaonline.tk, 1 +tahmintr.com, 1 +tahosa.co, 0 +tahrirbazar.com, 1 +tahugocilebut.com, 1 +taiaro.tk, 1 +taibachicken.com, 1 +taibafarms.com, 1 +taichi-jade.com, 1 +taidu.news, 1 +taiga-aikidojo.tk, 1 +taihesy.tk, 1 +taijutsubudo.com.au, 1 +taikhoanfree.com, 1 +taikodom.tk, 1 +tail.id.lv, 1 +tail.ml, 1 +taildb.com, 1 +tailor.com.au, 1 +tailoring.tk, 1 +tailpuff.net, 0 +tails.boum.org, 1 +tailwindapp.com, 1 +taim.io, 1 +taipak-krasnoyar.tk, 1 +taipei-101.tk, 1 +taiphanmem.net, 1 +taishokudaiko.com, 1 +taishon.nagoya, 1 +taiwan-kitchen.com, 1 +taiwan.dating, 1 +taiwanhotspring.net, 1 +taiwania.capital, 1 +taiwania.vc, 1 +taiwaniacapital.com, 1 +taiwaniacapital.com.tw, 1 +taiwaniacapital.tw, 1 +taiwanteama.com.tw, 1 +taiwantechtrek.tk, 1 +taiwantour.info, 0 +taiyou-planning.com, 1 +taiyouko-hatuden.net, 1 +taizegroep.nl, 1 +taj-portal.tk, 1 +tajilamagazine.com.br, 1 +tajniy-smisl.cf, 1 +tajper.pl, 1 +tajr.shop, 1 +takagiconsulting.com, 1 +takano-recruit.com, 1 +takano-takuhai.com, 1 +takanogroup.co.jp, 1 +take1give1.com, 0 +takeaction.ml, 1 +takeaimnow.org, 1 +takebackyourstate.com, 1 +takebackyourstate.net, 1 +takebackyourstate.org, 1 +takebonus.com, 0 +takedownthissite.com, 1 +taken.cf, 1 +taken.pl, 1 +takeomi.jp, 1 +takeshi.cz, 1 +takeshifujimoto.com, 0 +takestars.tk, 1 +takethatspainfanclub.tk, 1 +takeyourpic.co.uk, 1 +taki.sh, 1 +taki.sk, 1 +taki.to, 1 +takinet.kr, 1 +takiplekazan.ga, 1 +takk.pl, 1 +takkaaaaa.com, 1 +takkguitar.net, 1 +tako-miyabi.xyz, 1 +takosen.co.jp, 1 +taksa-club.org.ru, 1 +taktransport.pl, 1 +takuhai12.com, 1 +takumi-s.net, 1 +takusan.ru, 1 +takuto.de, 0 +takzetak.sk, 1 +talado.gr, 0 +taleintwo.com, 1 +talendipank.ee, 1 +talentbazi.com, 1 +talentcast.nl, 1 +talentcast.org, 1 +talented.ga, 1 +talentguru.ml, 1 +talenthubmpi.com, 1 +talentsfromindia.com, 1 +talentsphere-srm.com, 1 +talentuar.com, 1 +talentwall.io, 1 +talentx.hu, 1 +taler.net, 1 +talesbazaar.com, 1 +talichi.com, 1 +talideon.com, 0 +talis-bs.com, 1 +talk.google.com, 1 +talk.vg, 1 +talk.xyz, 1 +talkaboutdesign.com, 1 +talkbasket.net, 1 +talkgadget.google.com, 1 +talking12.com, 1 +talkingband.org, 1 +talkingbittersweet.com, 1 +talkingmoose.net, 1 +talkmojang.club, 1 +talknetwork.ru, 1 +talkreal.net, 1 +talkscope.ml, 1 +talktech.com, 1 +talktobot.com, 1 +talktwincities.com, 1 +talkwithyourbaby.org, 1 +talkx.de, 1 +tallac.tk, 1 +tallcraft.com, 1 +talldude.net, 1 +tallercs.tk, 1 +tallgrasslegal.com, 1 +tallinnsec.ee, 1 +tallinnsex.ee, 1 +tallship.cz, 1 +tallyfy.com, 1 +talonro.com, 1 +talos-app.io, 1 +talos-staging.io, 1 +talroo.com, 1 +talun.de, 1 +talusan.tk, 1 +talxis.com, 1 +talyllyn.co.uk, 1 +tam-moon.com, 1 +tam-safe.com, 1 +tam7t.com, 0 +tamada.expert, 1 +tamamo.cat, 1 +tamareverson.tk, 1 +tamatoyaku.com, 1 +tamayahousing.com, 1 +tambayology.com, 1 +tambo.es, 1 +tamboa.com, 1 +tambov.cf, 1 +tambov.tk, 1 +tambovcity.tk, 1 +tambre.ee, 1 +tamchunho.com, 1 +tamdidpay.tk, 1 +tamersunion.org, 0 +tamilentertainment.tk, 1 +tamilsms.blog, 1 +tamiltax.tk, 1 +tamindir.com, 1 +tammelin.org, 1 +tammie.ga, 1 +tammy.pro, 1 +tamoxifen-citrate.ml, 1 +tamoxifenformen.ga, 1 +tampa.gov, 1 +tampabaybusinesslistings.com, 1 +tampabayhometours.info, 1 +tampacific.net, 1 +tampacific.vn, 1 +tampaexplorer.ml, 1 +tampereenliberaalit.tk, 1 +tamriel-rebuilt.org, 1 +tamronhallshow.com, 1 +tamsulosin.gq, 1 +tamuraei.co.jp, 1 +tan90.tw, 1 +tanabekensetsu.co.jp, 1 +tanacio.com, 1 +tanahtinggi.org, 1 +tanatos.ga, 1 +tanchynski.com, 1 +tancredi.nl, 0 +tancuongtea.tk, 1 +tandakutip.com, 1 +tandarts-ict.nl, 1 +tandartsen-ict.nl, 1 +tandartspraktijkreddingius.nl, 1 +tandartsvanos.nl, 1 +tandartsvanvliet.nl, 1 +tandartszilverschoon.nl, 1 +tandblekningidag.com, 1 +tandem-trade.ru, 0 +tandemexhibits.com, 1 +tandempartnerships.com, 1 +tandemwise.net, 1 +tandemzagan.pl, 1 +tandzorg.link, 1 +tangel.me, 1 +tangle-teezer.net, 1 +tangledmeditations.com, 1 +tango-cats.de, 1 +tango-ouest.com, 0 +tangoalpha.co.uk, 1 +tangochoang.com, 1 +tangoenergy.com, 1 +tangovolcaniqueduvelay.fr, 1 +tangramins.com, 1 +tangsisi.com, 1 +tangyue.date, 1 +tangzhao.net, 1 +tanhaa.tk, 1 +tanhit.com, 1 +taniafitness.co.uk, 1 +taniafitness.com, 1 +tanie-uslugi-ksiegowe.pl, 1 +taniku-succulent.com, 1 +tanjaradovic.tk, 1 +tanjasavicmusic.tk, 1 +tank-scorecard.herokuapp.com, 1 +tankpassen-vergelijken.nl, 1 +tanks.je, 1 +tanks.ml, 1 +tankski.co.uk, 1 +tanned.tk, 1 +tannenhof-moelln.de, 1 +tanner.sh, 1 +tanneradvisorysolutions.com.au, 1 +tannercorporation.com, 1 +tannerdewitt.com, 1 +tannerryan.ca, 1 +tannerwilliamson.com, 1 +tannerwj.com, 1 +tannextcloud.cf, 1 +tanntime.no, 1 +tanovar.com, 1 +tanpopo.io, 1 +tansuya.jp, 1 +tantalos.nl, 1 +tantetilli.de, 0 +tanto259.name, 1 +tantrabali.tk, 1 +tantravoorlichting.nl, 1 +tantrum-rocks.tk, 1 +tantso.com, 1 +tanushka.tk, 1 +tanveersingh.tk, 1 +tanya-avdeeva.cf, 1 +tanyanama.com, 1 +tanyatate.xyz, 1 +tanz-kreativ.de, 0 +tanz.info, 1 +tanzanianfilms.tk, 1 +tanzhijun.com, 1 +tanzo.io, 1 +tao-energie.tk, 1 +taoaworld.com, 1 +taoburee.com, 0 +taokystrong.com, 1 +taoofbeauty.tk, 1 +taotic.eu, 1 +taowa.ca, 1 +taoways.com, 1 +taoyingchang.tk, 1 +taozgt.xyz, 0 +tap.az, 1 +tapbutdao.com, 1 +tapchiphaidep.info, 1 +tapcloud.com, 1 +tapestries.tk, 1 +tapestryjournal.com, 1 +tapesvip.xyz, 1 +tapetenresonanz.de, 1 +tapio.my, 1 +taplemon.at, 1 +taplemon.com, 1 +tappezzeria.roma.it, 1 +tappezziere.milano.it, 0 +tapple.world, 1 +tappyshop.com.br, 1 +taprix.org, 1 +tapsnapp.co, 1 +taqeemi.com, 1 +taquilla.com, 1 +taqun.club, 1 +tara.ai, 1 +tarabici.tk, 1 +tarabooks.com, 1 +tarahancenter.com, 1 +tarakan-klopik.tk, 1 +taraksarkar.tk, 1 +taranagar.tk, 1 +tarantino.tk, 1 +tarantul.org.ua, 1 +tarantula-spider.com, 1 +taraori.tk, 1 +tarapacadigitaltv.tk, 1 +tarasecurity.co.uk, 1 +tarasecurity.com, 1 +tarasevich.by, 1 +tarba-schluesseldienst-duesseldorf.de, 1 +tarchive.xyz, 1 +tardics.com, 1 +tardics.eu, 1 +tardics.net, 1 +tardis.cloud, 1 +tardis.io, 1 +tarek.link, 1 +tarek.wtf, 1 +tarfandgram.com, 1 +targaryen.house, 1 +targetbuilding.com, 1 +targetlonglife.tk, 1 +targetx.pl, 1 +targimieszkaniowe.net, 1 +tarife.at, 1 +tariff.cc, 1 +tarija.tk, 1 +tarik.io, 1 +tarikigaru.ga, 1 +tarjetaspark.es, 1 +tarkari.tk, 1 +tarkasparrows.org.za, 1 +tarketmedia.com, 1 +tarkov-database.com, 1 +tarocchi.blog, 1 +taroe.org, 1 +taron.top, 1 +tarot-online.com.pl, 1 +tarot.vn, 1 +tarotreadingexplained.com, 1 +tarots-et-oracles.com, 1 +tarotsgratuits.com, 1 +tarper24.net, 1 +tarrasque.io, 1 +tarsan.cz, 1 +tarsashaz-biztositas.hu, 1 +tartaneagle.org.uk, 1 +tartanhamedshop.com.br, 1 +tartu.ee, 1 +tarugo.net.br, 1 +taruntarun.net, 0 +tarzanka.ml, 1 +tas.best, 1 +tas2580.net, 0 +tasadar.net, 0 +tasadordecoches.com, 1 +tasarimgazetesi.com, 1 +tasboomkwekerij.nl, 1 +tasbrouwwinkel.nl, 1 +tascout.com, 1 +tascuro.com, 1 +tasintrip.com, 1 +taskboss.at, 1 +taskforce.eu, 1 +taskhorizon.audio, 1 +taskin.me, 1 +taskman.london, 1 +taskotron.fedoraproject.org, 1 +taskotron.stg.fedoraproject.org, 1 +tasks.org, 1 +taskseller.com, 1 +taskulu.com, 1 +taskulu.ir, 1 +taskussa.net, 1 +taskwise.cf, 1 +taskworld.com, 1 +tasogarenoinori.net, 1 +tasswoq.com, 0 +tastenewwines.com, 1 +tasteofadventure.nl, 1 +tasteville.com.au, 1 +tastic.com, 1 +tastycake.net, 0 +tastystakes.com, 1 +tastyworksreview.co, 1 +tat2grl85.com, 1 +tatar-bashqort.tk, 1 +tatara.ne.jp, 1 +tatard.fr, 1 +tataria.tk, 1 +tatarin.ga, 1 +tatarin.gq, 1 +tataristan.tk, 1 +tatarland.tk, 1 +tataru.it, 1 +tatarworld.tk, 1 +tatary.cf, 1 +tatary.tk, 1 +tateishi-ip.com, 1 +tathanhson.com, 1 +tatiana-kpb.tk, 1 +tatildekirala.com, 1 +tatildukkani.com, 1 +tatjana-young.net, 1 +tatler.com, 1 +tato.noip.me, 1 +tatort-fanpage.de, 1 +tatsidou.gr, 1 +tatsuya.tk, 1 +tattoo-art.tk, 1 +tattoo.dating, 1 +tattoonhamon.ru, 1 +tattootoday.org, 0 +tattvaayoga.com, 1 +tatu-love.tk, 1 +tatuantes.com, 1 +taturukav.tk, 1 +taubin.cc, 1 +tauedu.org, 0 +tauflight.com, 1 +taunusstein.net, 1 +tauran.net, 1 +tauriscia.tk, 1 +tauschen.info, 1 +tavda.info, 1 +tavda.net, 1 +tavelbutiken.com, 1 +tavolaquadrada.com.br, 1 +tavoseimai.lt, 1 +tavsiyeforumu.com, 1 +tavsys.net, 1 +tawjihi21.azurewebsites.net, 1 +tax-brain.net, 1 +tax-guard.com, 1 +taxadvantagellc.com, 1 +taxationweb.co.uk, 0 +taxborn.com, 1 +taxdispute.win, 1 +taxedesejour-airbnb.fr, 1 +taxhawk.com, 1 +taxhunter.com.au, 1 +taxi-chamonix.fr, 1 +taxi-collectif.ch, 0 +taxi-domzale.tk, 1 +taxi-doudoune.fr, 1 +taxi-edessas.gr, 1 +taxi-jihlava.cz, 1 +taxi-legroux.com, 1 +taxi-meridian.ru, 1 +taxi-puck.pl, 1 +taxi-zakaz.ml, 1 +taxi24.ml, 1 +taxicollectif.ch, 0 +taxid-k.be, 1 +taximinvody.ml, 1 +taximovies.gq, 1 +taxipool.co.il, 1 +taxis-collectifs.ch, 0 +taxisaeropuertomadrid.com, 1 +taxisafmatosinhos.pt, 1 +taxisantandreudelabarca.es, 1 +taxiscollectifs.ch, 0 +taxiservicedenbosch.nl, 1 +taxiunion.info, 1 +taxlab.co.nz, 1 +taxmadras.com, 1 +taxo.fi, 1 +taxpackagesupport.com, 1 +taxteam.co.il, 1 +tayar2u.my, 1 +taybee.net, 1 +tayebbayri.com, 1 +taylored.ga, 1 +taylorfry.co.nz, 1 +taylorfry.com, 1 +taylorfry.com.au, 1 +taylorfry.nz, 1 +taylorpearson.me, 0 +taylors-castles.co.uk, 1 +taylorshillsamoan.org, 1 +taylorstauss.com, 1 +taytaytiangge.ph, 1 +tazamobile.ga, 1 +tazarcorp.com, 1 +tazarelax.es, 1 +tazemama.biz, 1 +tazendaforever.tk, 1 +tazz.ro, 1 +tb-bolshevik.tk, 1 +tb-devel.de, 1 +tb-itf.de, 1 +tbb2020.com, 0 +tbbank.gov.tm, 1 +tbbvip1.com, 0 +tbcloud.site, 1 +tbejos.com, 1 +tbfocus.com, 1 +tbi.systems, 1 +tbird-q.com, 1 +tbitc.ch, 1 +tbonejs.org, 1 +tbpixel.com, 0 +tbq-s.com, 1 +tbq-s1.com, 1 +tbrindus.ca, 1 +tbs-certificates.co.uk, 1 +tbspace.de, 1 +tbtech.cz, 1 +tbuchloh.de, 1 +tbun.de, 1 +tbys.us, 1 +tc-st-leonard.ch, 0 +tc-triathlon.com, 1 +tc.nz, 1 +tcacademy.co.uk, 1 +tcade.co, 1 +tcb-a.org, 1 +tcb-b.org, 1 +tcbdarts.nl, 1 +tccb.gov.tr, 1 +tccc.org.tw, 1 +tcckonsult.com, 1 +tccmb.com, 1 +tccportal.com, 1 +tcdn.tech, 1 +tcdw.net, 1 +tcdww.cn, 1 +tcf.org, 1 +tcgpraktijk.nl, 1 +tcgrepublic.com, 1 +tch-forum.com, 1 +tchaka.top, 1 +tchalian-boulonnerie.store, 1 +tchannels.tv, 1 +tchatland.fr, 1 +tche.digital, 1 +tchealers.com, 1 +tchebb.me, 1 +tchoukball.ch, 0 +tchverheul.nl, 1 +tci-style.pl, 1 +tciit.pl, 1 +tcit.fr, 0 +tcj.ir, 1 +tcksolutions.com, 1 +tcl.sh, 1 +tcmk-tomsk.ru, 1 +tcnapplications.com, 1 +tcncompany.nl, 1 +tcoa.tk, 1 +tcook.co, 1 +tcook.io, 1 +tcpdf.org, 1 +tcpride.org, 1 +tcptun.com, 1 +tcsemotion.com, 1 +tcshop.ir, 1 +tcspartner.eu, 1 +tcuprs.com, 1 +tcvvip.com, 1 +tcwis.com, 1 +tcybert.com, 1 +tcyoung.co.uk, 1 +td-bambini.ru, 1 +td-olymp.ru, 1 +tdchrom.com, 0 +tddos.pw, 1 +tdeaqua.com, 1 +tdelmas.ovh, 1 +tdfbfoundation.org, 1 +tdlconexion.com, 1 +tdlesovik.ru, 1 +tdolar.com, 1 +tdr.today, 1 +tdrcartuchos.com.br, 1 +tdro.cf, 1 +tdrs.info, 1 +tds-forum.tk, 1 +tdsb.cf, 1 +tdsbhack.tk, 1 +tdsf.io, 1 +tdstoragebay.com, 1 +tdude.co, 1 +tdvg.nl, 1 +tdxexpedited.com, 1 +tdyx-china.com.cn, 1 +tea-empire.co.uk, 1 +tea.in.th, 1 +teach.gq, 1 +teachbiz.net, 1 +teachercall.kr, 1 +teachercreatedmaterials.com, 1 +teacherfrancis.com, 1 +teachermommylife.com, 1 +teacherph.com, 1 +teacherph.review, 1 +teacherpowered.org, 1 +teacherquinten.com, 1 +teachersasap.info, 1 +teachking.tk, 1 +teachmeplease.ru, 1 +teachoo.com, 1 +teachpeople.org, 1 +teachwithouttears.com, 1 +teacuppersiancats.com, 1 +teacupyorkiespets.com, 1 +teahawaii.ga, 1 +teahou.se, 0 +teahouse.gq, 1 +teahut.net, 1 +teaks.nl, 1 +tealdotsinanorangeworld.com, 1 +tealegrar.com.br, 1 +teallhaycock.com, 1 +team-17.tk, 1 +team-a.tk, 1 +team-azerty.com, 1 +team-bbd.com, 1 +team-darkness.tk, 1 +team-io.net, 1 +team-toranomon.com, 1 +team005helpdesk.ddns.net, 1 +team3.io, 1 +team3482.com, 1 +team957.co.uk, 1 +teamacadia.org, 1 +teamapex.site, 1 +teambeam.at, 1 +teambeam.ch, 1 +teambeam.com, 1 +teambeam.de, 1 +teambeoplay.co.uk, 1 +teambim.eu, 1 +teambition.com, 1 +teamcode.tk, 1 +teamconf.ru, 1 +teamdarko.tk, 1 +teamdaylo.xyz, 1 +teamdevelopers.ga, 1 +teamfriet.nl, 1 +teamhinkleyc.com, 1 +teamhybrid.com, 1 +teamhybridforums.com, 1 +teamkankun.tk, 1 +teamkgsr.com, 1 +teamkiller.tk, 1 +teamkoncert.pl, 1 +teamleader-apps-by-invantive.com, 1 +teamlightning.tk, 1 +teamliquid.com, 1 +teamliquidpro.com, 1 +teamliquidstarleague.com, 1 +teammateworld.com, 1 +teammojo.org, 1 +teamninjaapp.com, 1 +teamnissannorthparts.com, 1 +teampaddymurphy.ch, 1 +teampaddymurphy.ie, 1 +teampages.com, 1 +teampatat.nl, 1 +teampoison.tk, 1 +teamredfox.tk, 1 +teamrevolution.tk, 1 +teams.microsoft.us, 1 +teamsass.ca, 1 +teamsimplythebest.com, 1 +teamsuccess.io, 1 +teamsudan.cf, 1 +teamtouring.net, 1 +teamtrack.uk, 1 +teamup.com, 1 +teamup.rocks, 0 +teamupturn.com, 1 +teamupturn.org, 1 +teamusec.de, 1 +teamwpsekure.com, 1 +teamx-gaming.de, 0 +teamxavier4ever.com, 1 +teaparty.id, 1 +tearoomlints.be, 1 +tease.email, 1 +teasenetwork.com, 1 +teaser-trailer.com, 1 +teast.eu, 1 +teatrarium.com, 1 +teatrolatea.org, 1 +teatroutopia.tk, 1 +teawithmum.com, 1 +teazer.tk, 1 +teb-akademia.pl, 1 +tebebo.com, 1 +tebieer.com, 1 +tebis-consulting.my-router.de, 1 +tebodental.com, 1 +tebodentalgroup.com, 1 +tebodentistryatlanta.com, 1 +tebodentistryforkids.com, 1 +teboexperience.com, 1 +tebokidsstore.com, 1 +teboorthodontics.com, 1 +tebothetooth.com, 1 +tebuscotrabajo.com, 1 +tec24.ga, 1 +tec3000.ch, 0 +tecart-cloud.de, 1 +tecart-system.de, 1 +tecart.de, 1 +tecartcrm.de, 1 +teccozed.com, 1 +tecfleet.com, 1 +tech-clips.com, 0 +tech-doc.tk, 1 +tech-essential.com, 1 +tech-ideas.tk, 1 +tech-info.jp, 1 +tech-leaders.jp, 1 +tech-ninja.de, 1 +tech-professor.ir, 1 +tech-rat.com, 1 +tech-seminar.jp, 1 +tech-techno.tk, 1 +tech-urdu.tk, 1 +tech-value.eu, 1 +tech-zealots.com, 1 +tech2gen.com, 1 +tech3araby.com, 1 +tech4arab.net, 1 +tech4greece.gr, 1 +techableme.com, 1 +techace.jp, 1 +techangel.tk, 1 +techanit.de, 1 +techarea.fr, 1 +techask.it, 1 +techassist.io, 0 +techaulogy.com, 1 +techbelife.com, 1 +techbonaza.info, 1 +techbrawl.org, 1 +techbumper.info, 1 +techcavern.ml, 1 +techcentral.ml, 1 +techcenturion.com, 1 +techchip.com, 1 +techclan.ga, 1 +techcluster.tk, 1 +techcody.com, 1 +techcompany.tk, 1 +techcracky.com, 1 +techcu.lt, 1 +techcult.com, 1 +techcultivation.de, 0 +techcultivation.net, 0 +techcultivation.org, 0 +techday.asia, 1 +techday.co.nz, 1 +techday.com, 1 +techday.com.au, 1 +techday.eu, 1 +techday.network, 1 +techdirt.com, 1 +techdost.com, 1 +techdroid.eu, 1 +teched-creations.com, 1 +techendeavors.com, 1 +techexplorist.com, 1 +techfibian.tk, 1 +techfishnews.com, 1 +techformator.pl, 0 +techgama.org, 1 +techgarage.blog, 1 +techgo.re, 1 +techguidereview.com, 1 +techhackhome.tk, 1 +techhappy.ca, 1 +techie-show.com, 0 +techiecomputers.com, 1 +techiehall.com, 1 +techiesmart.tk, 1 +techindo.cf, 1 +techinet.pl, 1 +techinsurance.com, 1 +techisfake.ga, 1 +techitsol.tk, 1 +techiwant.com, 1 +techjobplaybook.nyc, 1 +techjoe.co, 1 +techlab.co.il, 1 +techlearningcollective.com, 1 +techlr.de, 1 +techmagus.icu, 1 +techmajesty.com, 1 +techmanstan.com, 1 +techmasters.io, 1 +techmepro.com, 1 +techmunchies.net, 1 +technavio.com, 1 +technewsetc.tk, 1 +techni-grav.com, 1 +technic3000.com, 1 +technicabv.nl, 1 +technicalbikrammalati.tk, 1 +technicalbrothers.cf, 1 +technicalforensic.com, 1 +technicalhelps.org, 1 +technicallyeasy.net, 1 +technicalproblem.tk, 1 +technicalramblings.com, 1 +technicaltrainer.co.za, 1 +technicalustad.com, 1 +techniclab.net, 0 +techniclab.org, 0 +techniclab.ru, 1 +technik-boeckmann.de, 1 +techno-iptv.com, 1 +technochat.in, 1 +technogps.com, 1 +technogrand.gq, 1 +technogroup.cz, 1 +technoholod.tk, 1 +technohram.tk, 1 +technoids.tk, 1 +technokicks.com, 1 +technoledge.jp, 1 +technologie-innovation.fr, 1 +technology-shopping.com, 1 +technology.cx, 1 +technologyhound.org, 1 +technologyintergrity.ga, 1 +technologysi.com, 1 +technologysnapshot.ga, 1 +technologywatchpost.com, 1 +technolution.tk, 1 +technolux.net, 1 +technomagia.tk, 1 +technomix.tk, 1 +technopedia.gq, 1 +technorely.com, 1 +technosapien.ml, 1 +technosorcery.net, 1 +technospeakco.com, 1 +technoswag.ca, 1 +technoteers.com, 1 +technotronikcanada.ca, 0 +technovisioneng.com, 1 +technoweb.ga, 1 +technowise.tk, 1 +technoyl.com, 1 +techold.ru, 0 +techorbiter.com, 1 +techosmarcelo.com.ar, 1 +techpilipinas.com, 1 +techpit.us, 1 +techpivot.net, 1 +techpoint.org, 1 +techraptor.net, 1 +techsaviours.online, 1 +techsecrets.tk, 1 +techserve.ml, 1 +techsharetx.gov, 1 +techshift.eu, 1 +techshift.nl, 1 +techshift.se, 1 +techsmartstore.com, 1 +techsna.com, 1 +techsocial.nl, 1 +techsolvency.com, 1 +techstackjournal.com, 1 +techstartup.tech, 1 +techsys.cz, 1 +techsystemsa.com, 1 +techto.date, 1 +techtoydeveloper.tk, 1 +techtrader.ai, 1 +techtrader.io, 1 +techtrendnews.tk, 1 +techunit.org, 1 +techusers.de, 1 +techvalue.gr, 1 +techview.link, 1 +techviewforum.com, 1 +techvigil.org, 1 +techwalker.cf, 1 +techwithcromulent.com, 1 +techwolf12.nl, 1 +techwords.io, 1 +techzero.cn, 1 +techzhou.com, 1 +techzjc.com, 0 +tecit.ch, 1 +tecke.tk, 1 +teckgeekz.com, 1 +teckids.org, 1 +tecknobox.fr, 1 +tecknologg.website, 1 +tecma.com, 1 +tecmarkdig.com, 1 +tecnaa.com, 1 +tecne.ws, 1 +tecnewsnow.com, 1 +tecnicapotiguar.com.br, 1 +tecnick.com, 1 +tecnicoelettrodomestici.roma.it, 1 +tecnikan.com.ar, 1 +tecnimotos.com, 1 +tecnipuntoseguridad.com, 1 +tecno-pack.net, 1 +tecnoarea.com.ar, 1 +tecnoblog.net, 1 +tecnobrasilloja.com.br, 1 +tecnocomp-systems.com, 1 +tecnodritte.it, 1 +tecnogaming.com, 1 +tecnogazzetta.it, 1 +tecnogestionsas.com, 1 +tecnograficaimpresos.com, 1 +tecnologia.net, 1 +tecnologiaboliviana.com, 1 +tecnologiasurbanas.com, 1 +tecnomagazine.net, 1 +tecnopiniones.com, 1 +tecnyal.com, 1 +tecon.co.at, 1 +tecscipro.de, 1 +tecta-stag-225720.appspot.com, 1 +tecwolf.com.br, 1 +tecyt.com, 1 +tedb.us, 0 +teddax.com, 1 +tedder.cc, 1 +teddie.eu, 1 +teddy.ch, 1 +teddybradford.com, 1 +teddykatz.com, 1 +teddylu.info, 1 +teddyss.com, 0 +teddywayne.com, 1 +tederomero.com, 1 +tedsdivingsystem.com, 1 +tedxyalesecondaryschool.com, 1 +teedb.de, 1 +teehaus-shila.de, 1 +teektalk.org, 1 +teemulintula.fi, 1 +teen-porno-video.ru, 1 +teengirl.pub, 1 +teenmissions.org, 1 +teenmoviesgallery.ga, 1 +teenpussypornvid.com, 1 +teenringen.nl, 1 +teensexgo.com, 1 +teensybows.hu, 1 +teenwebcams.ml, 1 +teenwolfturkey.tk, 1 +teenworlds.tk, 1 +teepak.ml, 1 +teeqq.com, 1 +teeshirtspace.com, 1 +teesurprise.com, 1 +teesypeesy.com, 1 +teetje-doko.de, 1 +teetoptens.com, 1 +teeverse-photography.com, 1 +teeworlds-friends.de, 1 +teextee.com, 1 +tefek.cz, 1 +tegamisha.com, 1 +teganlaw.ca, 1 +teganlaw.com, 1 +tege-elektronik.hu, 1 +tegel-schoonmaken.nl, 1 +tehnicari-za-racunalstvo.tk, 1 +tehniss.rs, 1 +tehplace.club, 1 +tehrabbitt.com, 0 +tehrankey.ir, 1 +tehranlittmann.com, 1 +teichroeb.net, 1 +teiqui.com, 1 +teiseken.tk, 1 +teixobactin.com, 1 +tejaswi.biz, 1 +teka.ro, 1 +tekanswer.com, 1 +tekingb.com, 0 +tekirdagemlak.tk, 1 +tekittak.com, 1 +tekmoloji.com, 1 +teknemodus.com.au, 1 +teknik.io, 1 +teknikaldomain.me, 1 +tekniksnack.se, 1 +teknisetdemarit.fi, 1 +tekniskakustik.se, 1 +tekno.de, 1 +teknodaim.com, 1 +teknoforums.com, 1 +teknogeek.id, 1 +teknoharekat.com, 1 +teknolama.com, 1 +teknologiia.com, 1 +teknorix.com, 1 +teknoroit.com, 1 +teknotiq.com, 1 +teknow.tk, 1 +teknozone.id, 1 +tekstover.tk, 1 +tekstpesni.tk, 1 +tektouch.net, 1 +tektuts.com, 1 +tela-tatis.com, 1 +telamon.eu, 1 +telangananews.ml, 1 +telani.net, 1 +telcar.cz, 1 +telco.at, 1 +telco.si, 1 +telcodb.net, 1 +teldak.pt, 1 +tele-alarme.ch, 1 +tele-assistance.ch, 1 +tele-points.net, 1 +tele.wiki, 1 +teleafrica.ga, 1 +telealarme.ch, 0 +telealarmevalais.ch, 1 +telecablenostima.tk, 1 +telecallsrl.com, 1 +telecamera.pro, 0 +telechargement-afnor.org, 1 +telecharger-itunes.com, 1 +telecharger-open-office.com, 1 +telecharger-winrar.com, 1 +telecommunications.cf, 1 +telecommutejobs.com, 1 +telecomwestland.nl, 1 +teledivi.com, 1 +telefisk.org, 1 +telefon.report, 1 +telefonabonnement.dk, 1 +telefoncek.si, 1 +telefonkonferenz.ch, 1 +telefonni-ustredna.cz, 1 +telefonseelsorge-paderborn.de, 1 +telefoon.nl, 1 +telefoonreparatieheiloo.nl, 1 +telega.gq, 1 +telegra.ph, 1 +telegram-gp.ml, 1 +telegram-sms.com, 1 +telegram.org, 1 +telegram.poker, 1 +telegramseen.com, 1 +telehealthventures.com, 0 +telekollektiv.org, 1 +telekothonbd.com, 1 +telema.tk, 1 +telemedi.be, 1 +telenco-datacenter.com, 1 +telenco-networks.com, 1 +telenovelas-france.tk, 1 +teleogistic.net, 1 +telepedia.pl, 1 +telephonedirectories.us, 1 +telephoni-cdma.tk, 1 +telepok.com, 1 +telepons.com, 1 +teleport.com.br, 1 +teleportweb.com.br, 1 +teleradio.ga, 1 +teleradio.tk, 1 +teleshop.be, 1 +teleskell.org, 1 +telesoftware.tk, 1 +telesonicengineering.com.my, 1 +telesto.online, 1 +teletaxe.fr, 1 +teletexto.com, 1 +teletxt.me, 1 +televisioncontests.ga, 1 +televisionesendirecto.tk, 1 +televisionsrit.tk, 1 +televizeseznam.cz, 1 +televotia.ch, 1 +telework.gov, 1 +teleworkouts.com, 1 +teleyal.blog, 1 +telford.codes, 1 +telhabrasil.com.br, 1 +telka-online.tk, 1 +telkomuniversity.ac.id, 1 +tellall.com, 1 +tellerify.com, 1 +tellet.tel, 1 +telling.xyz, 1 +tellingua.com, 0 +tellthemachines.com, 1 +tellusaboutus.com, 1 +telly.site, 1 +tellygames.com, 1 +tellyourtale.com, 1 +telnet.dk, 1 +telokchki.ga, 1 +telokchki.ml, 1 +teloo.pl, 1 +telos-analytics.com, 1 +telosglobal.io, 1 +telsu.fi, 1 +teltru.com, 1 +telugu4u.net, 1 +tem.li, 1 +temariogratis.com, 1 +temariopolicianacional.es, 1 +temariosdeoposiciones.es, 1 +tematicas.org, 1 +temirgaliev.tk, 1 +temizlik.ml, 1 +temizmama.com, 1 +teml.in, 1 +temnacepel.cz, 1 +temnhan24h.com, 1 +temp.pm, 1 +temp37c.com, 1 +tempa.com.ua, 1 +tempdatalogger.com, 1 +tempdomain.ml, 1 +tempdomain.tk, 1 +tempflix.com, 1 +templars.army, 1 +template-help.fr, 1 +template-parks.com, 1 +templeandalucia.tk, 1 +templete.tk, 1 +tempmail.ninja, 1 +tempo.co, 1 +tempoprimo.com, 1 +temporal.tk, 1 +temporalmotivation.com, 1 +temporaris.com, 1 +temporaryair.com, 1 +temporarysanity.tk, 1 +tempotem.com.br, 1 +tempsoundsolutions.tk, 1 +temptraining.ru, 1 +tempus-aquilae.de, 1 +tempus.tf, 1 +temtekco.com, 1 +tenable.com.au, 1 +tenber.ge, 1 +tenberg.com, 1 +tencar.ru, 1 +tencent.xn--vuq861b, 1 +tende.roma.it, 1 +tendergrupp.ru, 1 +tendermaster.com.ua, 1 +tenderplan.ru, 1 +tendersoft.pl, 1 +tenderstem.co.uk, 1 +tendiestown.com, 1 +tendinite.org, 1 +tendiris.ga, 1 +tendmed.com.br, 1 +tendomag.com, 1 +tendoryu-aikido.org, 1 +tendure.tk, 1 +tenelco.net, 1 +tenens.ru, 1 +tenenz.com, 1 +teners.me, 0 +tenfeetsquare.net, 1 +tengu.cloud, 1 +tenhourguy.com, 1 +tenispopular.com, 1 +tenisservis.eu, 1 +tenken1010.org, 1 +tenkiz.com, 1 +tenkofx.com, 1 +tenma.pro, 1 +tennis-altai.tk, 1 +tennisadmin.com, 1 +tennisapp.de, 1 +tenniscourtsjoburg.com, 1 +tenniscritic.ga, 1 +tennismindgame.com, 1 +tennisnyi-stol.tk, 1 +tennispensacola.com, 1 +tennisportal.com.ua, 1 +tennistalk.tk, 1 +tennisweb.cf, 1 +tenno.tools, 1 +tenshoku-hanashi.com, 1 +tenshoku-manabu.com, 1 +tenshokudo.com, 1 +tenshokufair.jp, 1 +tent.io, 1 +tenta.com, 1 +tentacle.monster, 1 +tentacle.net, 1 +tentacletank.com, 1 +tentations-voyages.com, 0 +tenthdimensions.com, 1 +tenthirtyonepictures.com, 1 +tenthousandcoffees.com, 1 +tentq.com, 1 +tenx.news, 1 +tenyx.de, 1 +tenzer.dk, 1 +teodorpravicky.com, 1 +teodw.com, 1 +teodw.net, 1 +teogramm.xyz, 1 +teoleonie.com, 0 +teoletextsq.tk, 1 +teologia.promo, 1 +teoskanta.fi, 1 +tepautotuning.com, 1 +tepid.org, 1 +tepitus.de, 1 +teplici-crimea.ru, 1 +teplo-russia.ru, 1 +teplo-unit.ru, 1 +teplofom.ru, 1 +teplohod.kharkov.ua, 1 +teplomash24.ru, 1 +teplotehnik.tk, 1 +teppichfrisch.de, 1 +tepui.io, 1 +teq-automotive.com, 1 +teqip-pms.gov.in, 1 +tequilazor.com, 1 +terabyte-computing.com, 1 +terabyte.services, 1 +terabyteharddrive.net, 1 +terabyteit.co.uk, 1 +teracloud.at, 1 +teradatta.tk, 1 +teramind.co, 1 +teranacreative.com, 1 +teraservice.eu, 1 +teraservice.ml, 1 +terass.com, 1 +terbaruberita.id, 1 +tercosdemaria.com.br, 1 +terence2008.info, 1 +terengganudaily.tk, 1 +terenska-edinica.tk, 1 +tereotech.net, 1 +teriiphotography.com, 1 +teriyakisecret.com, 1 +termbackti.me, 1 +terme.viterbo.it, 1 +termee.com, 1 +termeh-store.com, 1 +termi.tk, 1 +termin-online.com, 1 +terminalhrd.com, 1 +terminationsremembered.com, 1 +termino.eu, 1 +terminsrakning.se, 1 +termitinitus.org, 1 +termografiranje.si, 1 +termoidraulica.roma.it, 1 +termoidraulico.roma.it, 1 +termopares.tk, 1 +termux.com, 1 +ternex.ru, 1 +teronia.net, 1 +terovania.com, 1 +terovania.de, 1 +terovania.games, 1 +terpotiz.net, 1 +terra-24.ru, 1 +terra-x.net, 1 +terra.fitness, 1 +terra7.net, 1 +terrab.de, 1 +terracloud.de, 0 +terraco.ga, 1 +terracom.gr, 1 +terraesencial.com, 1 +terrafinanz.de, 1 +terraform.io, 1 +terragni-sarasin.ch, 1 +terralimno.com, 1 +terralimno.eu, 1 +terraluna.space, 1 +terraneesens.fr, 1 +terranoclub.pt, 1 +terranova.fi, 1 +terrapay.com, 1 +terrapinstationmd.com, 1 +terrarium.tk, 1 +terrasoverkappingvillage.be, 1 +terrasoverkappingvillage.nl, 1 +terrastaffinggroup.com, 0 +terraweb.net, 1 +terrax.net, 1 +terremoto.com.br, 1 +terrenal.tk, 1 +terres-et-territoires.com, 1 +terresmagiques.com, 0 +territoriocuchero.tk, 1 +territoriya.tk, 1 +territory.cf, 1 +terrorbilly.com, 1 +terrorblast.tk, 1 +terrty.net, 1 +terryburton.co.uk, 1 +terryjohnsononline.com, 1 +terryoconnor.org, 1 +ters.ga, 1 +terudon.com, 1 +tervelde.com, 1 +tervemaja.ee, 1 +tesche.biz, 1 +teschenhausen.com, 1 +tescoirelandpayslips.com, 1 +tescolide.cz, 1 +tescoludia.sk, 1 +tescomobile.cz, 1 +tesdrole.tk, 1 +teskaassociates.com, 1 +teskalabs.com, 1 +tesla-tula.tk, 1 +tesladrive.ca, 1 +teslamagician.com, 1 +teslamate.ca, 1 +teslasuit.io, 0 +tespent.cn, 1 +tesseractinitiative.org, 1 +tessierashpool.de, 1 +tessla.org, 1 +test-iq.gq, 1 +test-my.tk, 1 +test-na-beremennost.tk, 1 +test-online.tk, 1 +test-school.ml, 1 +test-sev-web.pantheonsite.io, 1 +test-textbooks.com, 1 +test.support, 1 +testadministrators.net, 1 +testadren.com, 1 +testadron.com, 1 +testapfnxg.com, 1 +testcoz.tk, 1 +testcu.be, 1 +testdemoweb.tk, 1 +testdevelocidad.com, 1 +testdomens.ga, 1 +tested.email, 1 +testem.de, 1 +testeri.fi, 1 +testermerch.pl, 1 +testeveonline.com, 1 +testforce.tk, 1 +testfra.me, 1 +testgeomed.ro, 1 +testikel.be, 1 +testing-server.tk, 1 +testingben.com, 1 +testingbot.com, 1 +testingtask.tk, 1 +testispdomain.ml, 1 +testkinja.com, 1 +testlabs.tk, 1 +testmx.email, 1 +testmx.eu, 1 +testmx.org, 1 +testmy.net, 1 +testmy.tk, 1 +testnode.xyz, 0 +testomato.com, 1 +testone.com.tr, 1 +testoon.com, 1 +testosterone-complex.com, 1 +testosteronedetective.com, 1 +testovaci.ml, 1 +testpool.gq, 1 +testpornsite.com, 1 +testpsicotecnicos.com.es, 1 +testq.se, 1 +tests-and-tips.info, 1 +tests-und-tipps.info, 1 +tests.pp.ru, 1 +testscript.ml, 1 +testsitefortask.xyz, 1 +testsity.tk, 1 +testspsicotecnicos.org, 1 +testsuite.org, 1 +testsweb.ml, 1 +testthis.cf, 1 +testuje.net, 0 +testyonline.tk, 1 +tetedelacourse.ch, 1 +teto.nu, 1 +tetovaweb.tk, 1 +tetrabyte.tk, 1 +tetracycline500mg.ga, 1 +tetraetc.com, 1 +tetraktus.org, 1 +tetrarch.co, 1 +tetrimus.com, 1 +tetsai.net, 1 +teulon.eu, 1 +teunmulder.tk, 1 +teunstuinposters.nl, 1 +teusink.eu, 1 +teutonia-grossenlueder.de, 1 +teutonia08.de, 1 +tevi.uk, 0 +tewarilab.co.uk, 1 +tewkesburybouncycastles.co.uk, 1 +tewkesburyyoga.com, 1 +texasabrasiveblasting.com, 1 +texasbluesalley.com, 1 +texascharterbuscompany.com, 1 +texascommunitypropane.azurewebsites.net, 1 +texascountymo911.gov, 1 +texasgynecomastia.com, 1 +texashealthtrace.gov, 1 +texasholdemevents.net, 1 +texashomesandland.com, 1 +texasllcpros.com, 0 +texasnewsusa.tk, 1 +texasonesource.com, 1 +texaspaintingandgutters.com, 1 +texasparkinglotstriping.com, 1 +texasready.gov, 1 +texastoadranch.com, 1 +texastwostepdivorce.com, 0 +texasurodoc.com, 1 +texasvolunteerattorneys.org, 1 +texaswinetrail.com, 1 +texby.com, 1 +texcolors.com.co, 1 +texel.es, 1 +texiafinishing.com, 1 +texican.nl, 1 +texier.mx, 1 +texnogu.ru, 1 +texnoguru.tk, 1 +texnotroniks.tk, 1 +texosmotr.tk, 1 +text-shirt.com, 0 +textbrawlers.com, 1 +textburst.com, 1 +textcleaner.net, 1 +textcounter.tk, 1 +textecnologia.com.br, 1 +texteditor.co, 1 +texter-linz.at, 1 +texter.at, 1 +texterseo.at, 1 +texterseo.de, 1 +textil-kyoto.tk, 1 +textinmate.com, 1 +textlinktausch.tk, 1 +textonly.email, 1 +textpages.tk, 1 +textpattern.com, 1 +textsite.tk, 1 +textualapp.com, 1 +textundblog.de, 1 +texture.net.au, 1 +texus.me, 1 +texy.info, 1 +teycos.com, 1 +teysens.com, 1 +tezcam.tk, 1 +tezwifi.com, 1 +tf-network.de, 1 +tf2b.com, 1 +tf2calculator.com, 1 +tf2pickup.de, 1 +tf2pickup.pl, 1 +tf7879.com, 1 +tfadictivo.com, 1 +tfb.az, 1 +tferdinand.net, 1 +tfg-bouncycastles.com, 1 +tfiik.com, 1 +tfk.fr, 1 +tfle.xyz, 1 +tflite.com, 1 +tfnapps.de, 1 +tfok.ml, 1 +tfsound.cz, 1 +tfsrcymru.org.uk, 1 +tft-cheat-sheet.com, 1 +tftdom.com, 1 +tfus.co, 1 +tfx.com.br, 1 +tfx.pt, 1 +tfxstartup.com, 1 +tfxstartup.com.br, 1 +tgamobility.co.uk, 1 +tgb.org.uk, 1 +tgbabyzoo.com, 1 +tgbyte.de, 1 +tgcgrain.com, 1 +tgexport.eu, 1 +tgmarketingusa.com, 1 +tgo1111.com, 1 +tgo6688.com, 1 +tgo789.com, 1 +tgo8899.com, 1 +tgoaa.com, 1 +tgoall.com, 1 +tgod.co, 1 +tgtv.tn, 0 +tgtw.cc, 1 +tgui.eu, 1 +tgui.net, 1 +tgw.com, 1 +tgwork.com, 1 +tgymj.gov.tm, 1 +th-bl.de, 1 +th-nuernberg.de, 1 +th.search.yahoo.com, 0 +thablubb.de, 1 +thackbarth.net, 1 +thackert.myfirewall.org, 1 +thaedal.net, 1 +thai-kacha.com, 1 +thai-massage.tk, 1 +thai-ridgeback.tk, 1 +thai.dating, 1 +thai.land, 1 +thai369.com, 1 +thaiboystory.ga, 1 +thaibrokersfx.com, 1 +thaicurry.net, 1 +thaicyberpoint.com, 1 +thaiforest.ch, 0 +thaiforexfamily.com, 1 +thaigirls.cf, 1 +thaihomecooking.com, 1 +thaihong.co.th, 1 +thaihotmodels.tk, 1 +thailandguru.properties, 1 +thailandpharmacy.net, 1 +thailandpropertylisting.ga, 1 +thailandvariety.cf, 1 +thaimega.club, 1 +thaipbspodcast.com, 1 +thaiportal.gq, 1 +thais.tk, 1 +thaitonic.de, 1 +thaiwaterbirds.com, 1 +thajskyraj.com, 1 +thalan.fr, 1 +thalgo-cz.cz, 1 +thalgott.net, 0 +thalhammer.it, 1 +thalia.nu, 1 +thalita-reload.com, 1 +thalliman.com, 1 +thallinger.me, 1 +thalmann.fr, 0 +thambaru.com, 1 +thamesfamilydentistry.com, 1 +thanatoid.net, 1 +thanhquyet.info, 1 +thapduoc.com, 1 +tharuka-app.de, 1 +tharuka.com, 1 +tharuka.de, 1 +thaserv.de, 1 +thassos.tk, 1 +thatdaria.com, 1 +thatdarkplace.com, 1 +thatlooksreallygood.com, 1 +thatshayini-sivananthan.fr, 1 +thaumaturgian-national-university.tk, 1 +thavmacode.gr, 1 +thc-stadvdzon.nl, 1 +thca.ca, 1 +thcdev.de, 1 +thconsulting.co.uk, 1 +thcpbees.co.uk, 1 +thda.org, 1 +the-ace.tk, 1 +the-alan-parsons-project.com, 1 +the-allmighty-mike.tk, 1 +the-archimedeans.org.uk, 1 +the-archive.io, 1 +the-archive.ml, 1 +the-azad.com, 1 +the-bermanns.com, 1 +the-big-bang-theory.com, 1 +the-burtons.xyz, 1 +the-busbys.com, 1 +the-club.fr, 1 +the-deep.tk, 1 +the-digitale.com, 0 +the-dream.tk, 1 +the-earth-yui.net, 0 +the-farm.tk, 1 +the-finance-blog.com, 1 +the-forgotten.net, 1 +the-gdn.net, 1 +the-gist.io, 1 +the-hemingway-code.de, 1 +the-jeuxflash.com, 1 +the-kuusatu.com, 1 +the-life-insurance.com, 1 +the-little-home.com, 1 +the-medium-dolphore.com, 0 +the-metropolitans.tk, 1 +the-morpheus.de, 1 +the-muddy-trophy-team.tk, 1 +the-mystery.org, 1 +the-naked.com, 1 +the-nash-education-program.com, 1 +the-pack.nl, 1 +the-pcca.org, 1 +the-rates.ru, 1 +the-red.pp.ua, 1 +the-spellcaster.com, 1 +the-spoonfeed.club, 1 +the-storm.tk, 1 +the-train.de, 1 +the-trophy-company.com, 1 +the-woods.org.uk, 1 +the-world.tk, 1 +the-zenti.de, 1 +the12by12.com, 1 +the13thtribe.tk, 1 +the1way.net, 1 +the3musketeers.biz, 1 +the51news.ga, 1 +the5th.nl, 1 +the8rules.co.uk, 1 +thea-team.net, 1 +theacademicpapers.co.uk, 1 +theaccountingcompanyleeds.co.uk, 1 +theaceblock.space, 1 +theachero.com, 1 +theactivationfunction.com, 1 +theactuary.ninja, 1 +theadelaideshow.com.au, 1 +theadultswiki.com, 1 +theafleo.ga, 1 +theafleo.gq, 1 +theagencywithoutaname.com, 1 +thealchemistatelier.com, 1 +theallmanteam.com, 1 +thealmsolution.com, 1 +thealonas.ml, 1 +thealonas.tk, 1 +theangelgivingtree.com, 1 +theangelgivingtree.info, 1 +theangelgivingtree.net, 1 +theangelgivingtree.org, 1 +theankhlife.com, 1 +theanswerexperts.com, 1 +theantarcticx.com, 1 +theantarticx.com, 1 +theantisocialengineer.com, 1 +theapplewiki.com, 1 +theappliancedepot.co.uk, 0 +theaps.net, 1 +theaquila.tk, 1 +thearcheryguide.com, 1 +thearchimag.tk, 1 +thearizonatribune.com, 1 +theartistjournal.ca, 1 +theartofe.fr, 1 +theasianshooters.com, 1 +theastrocoach.com, 1 +theater-8.ch, 1 +theater.cf, 1 +theaterfrederik.tk, 1 +theatergroep-o.nl, 1 +theaterreichenhall.tk, 1 +theatheistbook.com, 1 +theatre-schools.com, 1 +theatrepremol.com, 1 +theatresocietyguts.tk, 1 +theatresuite.tk, 1 +theaus.xyz, 1 +theaustinsevenworkshop.com, 1 +theauthenticdad.com, 1 +theaviationagency.com, 1 +theawesomemuse.com, 1 +theazoorsociety.org, 1 +thebabypassport.com, 1 +thebacksplashcompany.com, 1 +thebacteriafight.gq, 1 +thebakery2go.de, 1 +thebannerstore.com, 1 +thebarkofhinkle.com, 1 +thebarrens.nu, 1 +thebarrypatch.com, 1 +thebasebk.org, 1 +thebasicstudio.com, 1 +thebathroomexchange.ga, 1 +thebcm.co.uk, 1 +thebearcanread.com, 1 +thebeardedrapscallion.com, 1 +thebeginningviolinist.com, 1 +theberries.tk, 1 +thebestfun.co.uk, 1 +thebestlaos.ga, 1 +thebestnews.ga, 1 +thebestofthesprings.com, 1 +thebestpersonin.ml, 1 +thebestshopping.tk, 1 +thebigbigworld.tk, 1 +thebigbitch.nl, 1 +thebigdatacompany.com, 1 +thebigdig.xyz, 1 +thebiglaskowski.com, 1 +thebignow.it, 1 +thebigslow.com, 1 +thebigwave.de, 1 +thebikeinsurer.co.uk, 1 +thebimhub.com, 1 +thebinarys.com, 1 +thebirchwoods.com, 1 +thebirthdaysite.co.uk, 1 +thebismarckmarathon.com, 1 +thebit.link, 1 +thebitchneyfiles.tk, 1 +theblackboard.gr, 1 +theblacklock.com, 1 +theblondeabroad.com, 0 +theblueinnovations.com, 1 +theblueroofcottage.ca, 1 +thebluub.com, 1 +theboardroomsubi.com.au, 1 +theboats.agency, 1 +theboats.club, 1 +theboats.com, 1 +theboats.de, 1 +theboats.online, 1 +theboats.pro, 1 +theboats.site, 1 +thebodylanguageguide.tk, 1 +thebodyprinciple.com, 1 +theboltway.com, 1 +thebonerking.com, 1 +thebookiejoint.net, 1 +thebookietrials.com, 1 +theboulders.com, 1 +thebouncedepartment.co.uk, 1 +thebouncyman.co.uk, 1 +theboxofcarlos.com, 1 +theboxoutofthebox.com, 1 +theboysrepublic.tk, 1 +thebrainfactory.eu, 1 +thebreakroom.org, 1 +thebrewingtonfamily.net, 1 +thebridalcollection.com, 1 +thebrightons.co.uk, 1 +thebrightons.uk, 1 +thebroadcastknowledge.com, 1 +thebrookeb.com, 1 +thebrushcreekdistillery.com, 1 +thebsclub.com, 1 +thebss.tk, 1 +thebte.com, 1 +thebucklandreligion.tk, 1 +thebucknetwork.com, 1 +thebuffalotavern.com, 1 +thebulletin.io, 1 +thebusinessofgoodfilm.com, 1 +thebutterflyencounters.com, 1 +thebuttongame.io, 1 +thecalmnessofblankspace.tk, 1 +thecamels.org, 1 +thecameradivision.com, 1 +thecanadarace.com, 1 +thecandidforum.com, 1 +thecardcloset.com, 1 +thecarolingconnection.com, 1 +thecarpenters.tk, 1 +thecarphunter.tk, 1 +thecatbowl.com.au, 1 +thecedarsbb.co.za, 1 +thecelticfiles.tk, 1 +thechallenge.fit, 1 +thechandigarhcity.com, 1 +thechargertimes.com, 1 +thechavs.xyz, 1 +thecheat.tk, 1 +thecheese.co.nz, 1 +thechefsgear.uk, 1 +thecherryship.ch, 0 +thechicanos.tk, 1 +thechoice.tk, 1 +thecigarlibrary.com, 1 +theciso.com, 0 +thecitywarehouse.clothing, 1 +theclearingnw.com, 1 +theclonker.de, 1 +thecloudadmin.eu, 1 +thecluster.xyz, 1 +thecodeninja.net, 1 +thecoffeecamp.com, 1 +thecollegequiz.com, 1 +thecolorrun.hu, 1 +thecolourcloset.ca, 1 +thecombustionway.com, 1 +thecompany.pl, 1 +thecompanysheffield.co.uk, 1 +thecomparativist.com, 1 +theconcordbridge.azurewebsites.net, 1 +thecondemned.tk, 1 +thecondobuyers.com, 1 +theconsultingpeople.tk, 1 +thecontentcloud.com, 1 +theconversation.com, 1 +theconverter.net, 1 +thecook.com.co, 1 +thecorianderkitchen.com, 1 +thecowquerie.tk, 1 +thecozyinterior.com, 1 +thecr3ative.tk, 1 +thecracks.de, 1 +thecraftingstrider.net, 1 +thecrazybrains.tk, 1 +thecrazytravel.com, 1 +thecrescentchildcarecenter.com, 1 +thecrew-exchange.com, 1 +thecrochetcottage.net, 1 +thecskr.in, 1 +thecstick.com, 1 +thecubepsych.com, 1 +thecuriouscat.net, 1 +thecuriousdev.com, 1 +thecurvyfashionista.com, 1 +thecustomdroid.com, 1 +thecustomizewindows.com, 1 +theda.co.za, 1 +thedailyprosper.com, 0 +thedailyshirts.com, 1 +thedailyupvote.com, 1 +thedaleyclan.hopto.org, 1 +thedanceacademybuckscounty.com, 0 +thedark.ga, 1 +thedark1337.com, 1 +thedarkartsandcrafts.com, 1 +thedarkcolonyfansite.tk, 1 +thedarkfusion.tk, 1 +thedeathofannakarina.tk, 1 +thedebug.life, 1 +thedentalstudiomiami.com, 1 +thederminstitute.com, 1 +thedetail.org, 1 +thedevilsbrigade.com, 1 +thedevilwearswibra.nl, 1 +thedevrycommonsbrasil.com, 0 +thediabetesnews.com, 1 +thediamondcenter.com, 1 +thediaryofadam.com, 1 +thedietsolutionprog.tk, 1 +thedigitalparadox.tk, 1 +thedimebank.com, 1 +thedinnerdetective.com, 1 +thediscforum.tk, 1 +thediscovine.com, 1 +thedistance.co.uk, 1 +thedivesource.com, 1 +thedjhookup.com, 1 +thedoc.eu.org, 1 +thedocumentrefinery.com, 1 +thedom.site, 1 +thedonaldarchive.tk, 1 +thedrawbacks.tk, 1 +thedreamtravelgroup.co.uk, 1 +thedrizzle.tk, 1 +thedroidman.com, 1 +thedronechart.com, 1 +thedroneely.com, 1 +thedword.xyz, 1 +thedysfunctionalangel.cf, 1 +theebookkeepers.co.za, 1 +theeducationchannel.info, 1 +theeffingyogablog.com, 1 +theeighthbit.com, 0 +theel0ja.info, 1 +theel0ja.ovh, 1 +theeldritchhounds.cf, 1 +theelephant.info, 1 +theeliteneet.com, 1 +theemasphere.com, 1 +theenchantedannex.co.uk, 1 +theender.net, 1 +theentertainmentcontractor.com, 1 +theentropyofdelicatewonders.com, 1 +theepankar.com, 1 +theepiclounge.com, 1 +theepicsponge.co.uk, 1 +theeuropeanlibrary.org, 1 +theevergreen.me, 0 +theeverycompany.com, 1 +theexpatriate.de, 1 +theeyeopener.com, 1 +thefabulouslifestyles.com, 1 +thefabulouswomen.com, 1 +thefaircottage.com, 1 +thefairieswantmedead.com, 1 +thefamilygarrison.com, 1 +thefanimatrix.net, 1 +thefarleys.ca, 1 +thefashionpolos.com, 1 +thefastmode.com, 1 +thefbstalker.com, 1 +theferrarista.com, 0 +thefestivals.uk, 1 +thefibreapp.com, 1 +thefireandthefreaks.com, 1 +thefireflygrill.com, 0 +thefishshop.ga, 1 +thefitcare.com, 1 +thefitcareerist.com, 1 +theflexerzone.ga, 1 +theflowershopdeddington.com, 1 +theflowstudios.com, 1 +theflyingbear.net, 0 +thefnafarchive.org, 1 +thefoodcops.com, 1 +thefoodellers.com, 1 +thefoodiefit.com, 1 +thefootinstitutela.com, 1 +theforkedspoon.com, 1 +theformtool.com, 1 +thefox.com.fr, 1 +thefoxtalk.com, 0 +thefreebay.tk, 1 +thefreemail.com, 1 +thefreethinker.tk, 1 +thefriedzombie.com, 1 +thefriedzombie.nl, 1 +thefriedzombie.online, 1 +thefrk.pw, 1 +thefrk.xyz, 1 +thefuckingtide.com, 1 +thefuelcardpeople.co.uk, 1 +thefunfirm.co.uk, 1 +thefurnitureco.uk, 1 +thefurniturefamily.com, 1 +thefusion.net.in, 1 +thefussyeater.ie, 1 +thegadget.tk, 1 +thegantars.tk, 1 +thegatewaytoanewworld.com, 1 +thegeekdiary.com, 1 +thegeekiepedia.com, 1 +thegemriverside.com.vn, 1 +thegenesisshop.com, 1 +thegeniusdz.tk, 1 +thegentleman.tk, 1 +thegerwingroup.com, 1 +thegetaway.com, 1 +theghostlytavern.com, 1 +thegingersnapbaker.co.za, 1 +theginnylee.com, 1 +thegioidulich.com.vn, 1 +thegioinano.com, 1 +thegolden.com, 1 +thegoodheartedwoman.com, 1 +thegospell.tk, 1 +thegrandline.tk, 1 +thegrandtour.tk, 1 +thegreatcommissionpodcast.com, 1 +thegreatgonzo.uk, 1 +thegreatplains.com, 1 +thegreenfields.se, 1 +thegreenlivingsolution.com, 1 +thegreenmanpottery.com, 1 +thegreens.us, 1 +thegrio.com, 1 +thegroovecartel.com, 1 +thegrotto.tk, 1 +thegrowhouse.ca, 1 +thegrs.com, 1 +theguitarcompany.nl, 1 +thegvoffice.net, 1 +thehabitat.com, 1 +thehackerblog.com, 1 +thehairrepublic.net, 1 +thehairstandard.com, 1 +thehamiltoncoblog.com, 1 +thehappeny.com, 1 +thehappyxwife.ga, 1 +thehasanyildirim.tk, 1 +thehassanmusic.tk, 1 +thehasty.com, 1 +thehaxbys.co.uk, 1 +thehaze.org, 1 +theheadplug.tk, 1 +theheatingoilclub.co.uk, 1 +thehiddenbay.cc, 0 +thehiltonfirm.tk, 1 +thehivedesign.org, 1 +thehobincompany.com, 1 +thehoff.ddnss.de, 1 +theholloways.tk, 1 +thehomebakery.ie, 1 +thehomemademasks.com, 1 +thehomeofthefuture.com, 1 +thehonorguard.org, 1 +thehookup.be, 1 +thehopefuture.com, 1 +thehopper.io, 1 +thehorsesadvocate.com, 0 +thehotfix.net, 1 +thehotness.tech, 1 +thehotrocks.tk, 1 +thehouseofchronic.com, 1 +thehouseofcode.com, 1 +thehowlinwolfcafe.ga, 1 +thehub.ai, 1 +thehumanjoint.com, 1 +thehumorist.tk, 1 +thehuskyhaul.com, 1 +theideaskitchen.com.au, 1 +theidiotboard.com, 1 +theig.co, 1 +theilluminatisociety.org, 1 +theillustrationstudio.com.au, 1 +theimagefile.com, 1 +theimaginationagency.com, 1 +theinboxpros.com, 1 +theindiangraph.tk, 1 +theinflatables-ni.co.uk, 1 +theinfoblog.com, 1 +theinitium.com, 0 +theinnerprism.com, 1 +theinput.com, 1 +theinstitute.cf, 1 +theintercept.com, 1 +theinternationalgeekconspiracy.eu, 1 +theinventory.com, 1 +theislandtime.com, 1 +theissen.io, 1 +theitaliantimes.it, 1 +theitsage.com, 0 +thejacksoninstitute.com.au, 1 +thejkdrebel.com, 1 +thejoneshub.com, 1 +thejonsey.com, 1 +thejourneydesignstudio.com, 1 +thejsmodel.com, 1 +thejunkfiles.com, 1 +thekalakriti.tk, 1 +thekev.in, 1 +thekeymusic.com, 1 +thekeytobusiness.co.uk, 1 +thekickassvirtualassistant.nl, 1 +thekiddz.com, 1 +thekidszone.in, 1 +thekillertoxin.de, 1 +thekitchenfarnborough.co.uk, 1 +thekitchngic.com, 1 +thekliniquehotdeal.com, 1 +theknockout.tk, 1 +theknowitguy.com, 1 +thekonsulthub.tk, 1 +thekovnerfoundation.org, 1 +thekuwayama.net, 1 +thelaimlife.com, 1 +thelakedistrict.tk, 1 +thelanscape.com, 1 +thelapine.ca, 1 +thelastsurprise.com, 1 +thelastvikings.tk, 1 +thelaurelchiropractor.com, 1 +thelbc.io, 0 +thelearningenterprise.co.uk, 1 +thelegionshirley.co.uk, 1 +thelencystore.com, 1 +thelevelman.com, 1 +thelibertinephilosophy.ga, 1 +thelifeofmala.com, 1 +thelifevison.com, 1 +thelightpoints.eu, 1 +thelimitededition.in, 1 +thelimitlessman.co.uk, 1 +thelinuxspace.com, 1 +thelittlejewel.com, 1 +thelittlepeartree.eu, 1 +thelocals.ru, 1 +thelockerroom.ie, 1 +thelonelyones.co.uk, 1 +thelonious.nl, 1 +theloop.ai, 1 +theloop.build, 1 +thelordofthewing.cf, 1 +thelostfreighter.com, 1 +thelostyankee.com, 1 +thelotter.club, 1 +thelounge.chat, 1 +theluxonomist.es, 1 +thelwallrangers.tk, 1 +themadlabengineer.co.uk, 1 +themagazine.my, 1 +themagician.tk, 1 +themallards.info, 1 +themandogs.tk, 1 +themarkup.org, 1 +themarshallproject.org, 1 +themaster.site, 1 +themaster.tk, 1 +themasterplan.com.au, 1 +themathbehindthe.science, 1 +themathscentre.com, 1 +themattresswarehouse.co.za, 1 +thematyper.tk, 1 +themeaudit.com, 1 +themecraft.studio, 1 +themedicalmedia.com, 1 +themedictips.com, 1 +themegteam.com, 1 +thementornetwork.com, 1 +themenzentrisch.de, 1 +themerchandiser.net, 0 +themeridianway.com, 1 +themesurgeons.net, 1 +themevilles.com, 1 +themiddle.co, 1 +themigraineinstitute.com, 1 +themilanlife.com, 1 +theminiacs.com, 1 +themist.cz, 1 +themodernreviewer.ga, 1 +themomentratchada19.com, 1 +themoneyconverter.com, 1 +themonthly.com.au, 1 +themostexpensiveworkofart.com, 1 +themurrayfamily.me.uk, 1 +themusecollaborative.org, 1 +themusic.cloud, 1 +themusicalsafari.com, 1 +themusicthatnobodylikes.tk, 1 +themusthaves.de, 1 +then.icu, 1 +thenappylaundry.ga, 1 +thenathanmethod.com, 1 +thenational.academy, 1 +thenaturalpath.co.nz, 1 +theneatgadgets.com, 1 +thenerdic.com, 1 +thenest.se, 1 +thenetw.org, 1 +thenewclassics.com, 1 +thenewtoy.net, 1 +thenextasset.com, 1 +thenexwork.com, 1 +thenichecast.com, 1 +thenine.info, 1 +theninenine.com, 1 +thenocman.com, 1 +thenova.me, 1 +thenrdhrd.nl, 1 +theo-andreou.org, 1 +theo.me, 1 +theobg.co, 1 +theobora.fr, 1 +theobromos.fr, 0 +theoc.co, 1 +theocharis.org, 1 +theocjournal.tk, 1 +theocoffee.com, 1 +theocratic.cf, 1 +theocrazzolara.tk, 1 +theodeboer.nl, 1 +theodorahome.co, 1 +theodorahome.com.br, 1 +theofleck.com, 0 +theojellis.com, 1 +theojones.name, 1 +theokouzelis.com, 1 +theoldbrewhouse.info, 1 +theoldmill.tk, 1 +theoldnews.net, 1 +theoldsewingfactory.com, 1 +theolodewijk.nl, 1 +theologique.ch, 0 +theomegagroup.co.uk, 1 +theomg.co, 1 +theonethaimassage.de, 1 +theonion.com, 1 +theonlinecentre.com, 1 +theonyxzone.com, 1 +theoosmetalart.nl, 1 +theopaphitissbs.com, 1 +theophil.tk, 1 +theoriecheck.de, 1 +theoriginalassistant.com, 1 +theoriginalmarkz.com, 1 +theoriginalworkshop.com, 1 +theorioncorrelation.com, 1 +theory-test-online.co.uk, 1 +theory.org, 1 +theoscure.eu, 1 +theosophic.ga, 1 +theosophie-afrique.org, 1 +theoutsiders.stream, 1 +theoverfly.co, 1 +theowlclub.net, 1 +thepaffy.de, 1 +thepaleodiettips.tk, 1 +thepandacustom.com, 1 +thepaperlion.ca, 1 +theparachafamily.tk, 1 +theparkcornwall.com, 1 +theparklane-sukhumvitbearing.com, 1 +theparoxetine.gq, 1 +theparticipants.tk, 1 +thepartner.co.uk, 1 +thepartydoctors.co.uk, 1 +thepathsofdiscovery.com, 1 +thepaulagcompany.com, 0 +thepavilionbanbury.co.uk, 1 +thepaymentscompany.com, 1 +thepcweb.tk, 1 +thepeoplesdata.com, 1 +thepeoplesdata.org, 1 +theperry.group, 1 +thepetsmedia.com, 1 +thepharm.co.nz, 1 +thephp.cc, 1 +thepieslicer.com, 1 +thepigwrestlers.com, 1 +thepillclub.com, 1 +thepilotwoman.cf, 1 +thepinfluencers.com, 1 +thepiratebay.cf, 1 +thepiratesociety.org, 1 +thepitsurfhire.co.uk, 1 +thepixel.tk, 1 +theplasticsurgerycenterofnashville.com, 1 +theplaydaysbus.co.uk, 1 +theploughharborne.co.uk, 1 +theplusfc.com, 1 +thepokerbank.com, 1 +theposhfudgecompany.co.uk, 1 +thepowerboys.tk, 1 +thepricewatcher.co.uk, 1 +theprimetalks.com, 1 +theprincegame.com, 1 +theprinceshort.tk, 1 +thepriorybandbsyresham.co.uk, 1 +theprivacysolution.com, 1 +theproject.cf, 1 +theprojectgroup.com, 1 +theprojectx.tk, 1 +thepromisemusic.com, 1 +theptclist.tk, 1 +theptpractitioner.com.au, 1 +thepulpit.tk, 1 +thepureplan.com, 1 +thepxhubclientportal.co.uk, 1 +thequillmagazine.org, 1 +theracismforum.com, 1 +theragran.co.id, 1 +theralino.de, 1 +therandombits.com, 0 +therankkings.org, 1 +therapistresources.net, 1 +therapyclient.com, 1 +therapyconnects.co.uk, 1 +therapyglobe.com, 1 +therapynotes.com, 1 +therapypartner.com, 1 +therapyportal.com, 1 +therapysxm.com, 0 +therasmusgt.tk, 1 +therasmusperu.tk, 1 +therattrick.com, 1 +thereadingresidence.com, 1 +thereafter.ga, 1 +therealchamps.com, 1 +therealcost.gov, 1 +thereaper.net.au, 1 +theredsgazette.tk, 1 +theregoesbrian.com, 1 +thereisnocloud.fr, 1 +therenderingmachine.com, 1 +therenegade.tk, 1 +thereptiles.tk, 1 +therepublicofliverpool.com, 1 +theresa-mayer.eu, 1 +theresabrant.com, 1 +theresingles.tk, 1 +theresumeapp.com, 1 +therevenge.me, 1 +therewill.be, 1 +therhetorical.ml, 0 +therichardsfamily.tk, 1 +therisk.global, 1 +therivercrosswarwick.co.uk, 1 +thermalbad-therme.de, 1 +thermia.co.nz, 1 +thermia.com.au, 1 +thermique.ch, 0 +thermity.com, 1 +thermolamina.nl, 1 +thermorecetas.com, 1 +thermorhythm.com, 1 +thermostat.gq, 1 +thermowood-bkh.ru, 1 +therniakov.tk, 1 +theroadrunners.tk, 1 +therockawaysny.com, 0 +theroguestormtrooper.com, 1 +therokasshow.tk, 1 +theroks.com, 0 +theromexchange.com, 1 +theroot.com, 1 +theroyal.tk, 1 +theroyalmarinescharity.org.uk, 1 +therra.eu, 1 +therudeworkout.com, 1 +therugswarehouse.co.uk, 1 +theruleslawyer.net, 1 +therumfordcitizen.com, 1 +therunawayspremiere.tk, 1 +theruncibleraven.com, 1 +therusnews.tk, 1 +therworth.com, 1 +therworth.eu, 1 +therworth.net, 1 +therworth.org, 1 +thesacreds.com, 1 +thesalonthing.com, 0 +thesanta.biz, 1 +thesarogroup.com, 1 +thesaturdaypaper.com.au, 1 +thesaurus.net, 1 +thescienceofdeduction.tk, 1 +thescientists.nl, 1 +theseal.tk, 1 +thesearch.com.tw, 1 +thesecondsposts.com, 0 +thesecurityvault.com, 1 +theseed.io, 1 +theseedbox.xyz, 1 +thesehighsandlows.com, 1 +theseletarmall.com, 1 +theselfcarenook.com, 1 +thesemperfibeard.com, 1 +theseofarm.com, 1 +theseoframework.com, 1 +theseonoob.com, 1 +theseosystem.com, 1 +thesepticgroup.com, 1 +theserpent.tk, 1 +theserviceyouneed.com, 1 +thesession.org, 0 +thesetwohands864.com, 1 +theshaker.com.au, 1 +thesharedbrain.ch, 0 +thesharedbrain.com, 0 +theshine.pl, 1 +theshivrajofficial.in, 0 +theshopally.com, 1 +theshots.cz, 1 +thesignacademy.co.uk, 1 +thesignalco.com.au, 1 +thesilentfew.tk, 1 +thesimarchitect.com, 1 +thesimplewebcompany.com, 1 +thesingaporelawyer.com, 1 +thesipher.tk, 1 +thesisgeek.com, 1 +thesishelp.net, 1 +theskingym.co.uk, 1 +thesled.net, 1 +thesleepdoctor.com, 1 +thesmallbusinesswebsiteguy.com, 1 +thesmokingcuban.com, 1 +thesocialmediacentral.com, 1 +thesomepeople.org, 1 +thesoundstageatstrangeland.com, 1 +thespacegame.tk, 1 +thesphinx.ca, 1 +thespiritfm.tk, 1 +thesplashlab.com, 1 +thesslstore.com, 1 +thesslstore.in, 1 +thestable.com, 1 +thestandards.tk, 1 +thestatementjewelry.com, 1 +thestationatwillowgrove.com, 1 +thesteins.org, 0 +thestockoasis.com, 1 +thestoneage.de, 1 +thestoragebay.co.uk, 1 +thestore.tk, 1 +thestoryshack.com, 0 +thestral.pro, 1 +thestralbot.com, 1 +thestrangenessofthings.tk, 1 +thestrategyagency.com.au, 1 +thestreamable.com, 1 +thestreet.cz, 1 +thestudioslucan.com, 1 +thestylebouquet.com, 1 +thesunshinecoasttourcompany.com.au, 1 +thesuppercircle.com, 1 +theswanstation.tk, 1 +theswimdoctors.com, 0 +theswissbay.ch, 1 +theswitch.club, 1 +theta.eu.org, 1 +thetablehuff.com, 1 +thetakeout.com, 1 +thetapirsmouth.com, 1 +thetassos.com, 1 +thetattooedpreacher.com, 1 +theteaguemovie.tk, 1 +thetebodifference.com, 1 +thetechsite.net, 1 +thetfordvt.gov, 1 +thetherapist.tk, 1 +thethinktankpodcast.co, 1 +thethirdroad.com, 0 +thethreadsmiths.com.tw, 1 +thethreepercent.marketing, 1 +thetiedyelab.com, 1 +thetinylife.com, 1 +thetinymom.com, 1 +thetipo01.cf, 1 +thetipo01.tk, 1 +thetomharling.com, 1 +thetopflight.com, 1 +thetopmovie.gq, 1 +thetopsecretepisode.tk, 1 +thetorlock.com, 1 +thetorrentfunk.com, 1 +thetotalemaildelivery.com, 1 +thetradinghall.com, 0 +thetradingletter.com, 1 +thetrafficgeek.com, 1 +thetransformingchurch.org, 1 +thetravel.com, 1 +thetravelczar.com, 1 +thetravelhack.com, 0 +thetrendspotter.net, 1 +thetrove.is, 1 +thetrove.net, 1 +thetrustedzone.com, 0 +thetshirtguy.co.uk, 1 +thetuxkeeper.de, 0 +thetvtraveler.com, 1 +thetwistedrabbit.com, 1 +theunbox.com, 1 +theunconventionalconventionists.tk, 1 +theundefeated.com, 1 +theunitehistoryproject.org, 1 +theuniversallover.tk, 1 +theuniversitiesofasia.ga, 1 +theunleashedpet.com, 1 +thevacweb.com, 1 +thevalentineconstitution.com, 1 +thevanishedvoyager.ml, 1 +theveggietable.com, 1 +theveils.net, 1 +thevelvetlove.tk, 1 +thevenueofhollywood.com, 1 +thevern.co.za, 1 +theverybusyoffice.co.uk, 1 +theviolenceofdevelopment.com, 1 +thevirgin.tk, 1 +thevirtualbookkeepers.com, 1 +thevirtualdetective.games, 1 +thevirtuousdog.com, 1 +thevisasofoz.com, 1 +thevitpro.com, 1 +thevoga.com, 1 +thevoice4you.tk, 1 +thevoid.one, 1 +thevoya.ga, 0 +thewagesroom.co.uk, 1 +thewalkerz.tk, 1 +thewallet.today, 1 +thewashingmachine.tk, 1 +thewave.tk, 1 +thewaxhouse.academy, 1 +thewaxhouse.de, 1 +thewayofislam.ml, 1 +thewayofthedojo.com, 1 +thewaytoyourself.com, 1 +thewebcully.com, 1 +thewebdexter.com, 1 +thewebflash.com, 1 +thewebguru.net, 1 +thewebhut.com.au, 1 +thewebsitedoctors.co.uk, 1 +thewebsitemarketingagency.com, 1 +theweed.tk, 1 +thewest.tk, 1 +thewhitehat.club, 0 +thewhiterabbit.space, 1 +thewhitneypaige.com, 1 +thewindow.com, 1 +thewindowcleaningexperts.com, 1 +thewindowcleaningexperts.net, 1 +thewinedelivery.ga, 1 +thewomenschoice.com, 1 +thewoodkid.com.au, 1 +thewoods.earth, 1 +thewoolroom.com.au, 1 +theworkingeye.nl, 1 +theworld.tk, 1 +theworldbattle.com, 1 +theworldexchange.com, 1 +theworldexchange.net, 1 +theworldexchange.org, 1 +theworldsend.eu, 1 +theworldtakes.tk, 1 +thewraithmovie.tk, 1 +thewrenchmonkey.ca, 1 +thewrightflyer.com, 1 +thewritegrl.com, 1 +thexalla.tk, 1 +thexme.de, 1 +thexpert.ml, 1 +theyakshack.co.uk, 1 +theyarnhookup.com, 0 +theyear199x.org, 1 +theyearinpictures.co.uk, 1 +theyosh.nl, 0 +theyourbittorrent.com, 1 +theyucatantimes.com, 1 +thezero.org, 1 +thezillersathenshotel.com, 1 +thfaid.org, 1 +thgstardragon.com, 1 +thhost.tk, 1 +thiagohersan.com, 1 +thiagoribeiro.ml, 1 +thiasil.com, 1 +thibaultchristin.fr, 1 +thibaultwalle.com, 1 +thibautcharles.net, 1 +thienminhmts.com, 1 +thiepcuoidep.com, 1 +thiepxinh.net, 1 +thierrybasset.ch, 0 +thierryhayoz.ch, 1 +thierrymazue.com, 1 +thierrymazue.fr, 1 +thietbithoathiem.net, 1 +thietkegianhangtttm.com, 1 +thietkenamcuong.com, 1 +thietkenhatho.com.vn, 1 +thietkenoithatshop.com, 1 +thijmen.xyz, 1 +thijmendevalk.nl, 1 +thijmenmathijs.nl, 1 +thijmenverveeltzich.nl, 1 +thijs.amsterdam, 1 +thijs.fr, 1 +thijsbekke.nl, 1 +thijsenarjan.nl, 1 +thijsslop.com, 1 +thijsslop.eu, 1 +thijsslop.nl, 1 +thijsvanderveen.net, 1 +thilko.com, 1 +thilobuchholz.de, 1 +thimbros.tk, 1 +thinair.co, 1 +thinairsolutions.com, 1 +thincats.com, 1 +thing.vn, 1 +thingies.site, 1 +thingsimplied.com, 0 +thingsof.org, 1 +thingswithstuff.llc, 0 +think-asia.org, 1 +think-positive-watches.de, 1 +thinkbot.de, 1 +thinkbrands.co.uk, 1 +thinkcash.nl, 1 +thinkcoconut.com.au, 1 +thinkconsultores.com, 1 +thinkdata.com.br, 1 +thinkdigital.co.id, 1 +thinkelectric.ml, 1 +thinkheaddesign.com, 1 +thinkindifferent.net, 1 +thinkingandcomputing.com, 1 +thinkingliberty.com, 1 +thinkmarketing.ca, 1 +thinkprocedural.com, 1 +thinktac.com, 1 +thinktankofthree.com, 1 +thinktux.net, 1 +thinxtream.com, 1 +thirdbearsolutions.com, 1 +thirdgenphoto.co.uk, 1 +thirdman.auction, 1 +thirdwave.tk, 1 +thirdwaverevenue.com, 1 +thirdworld.moe, 1 +thirstyjourneys.com, 1 +thirteen.pm, 1 +thirtyspot.com, 1 +thiry-automobiles.net, 0 +thiscity.rocks, 1 +thiscloudiscrap.com, 0 +thisdayinhockey.tk, 1 +thisdot.site, 1 +thisfreelife.gov, 1 +thisisart.ie, 1 +thisishugo.com, 1 +thisismit.ch, 1 +thisisrapt.com.au, 1 +thisistechtoday.com, 1 +thisistranquility.life, 1 +thisistwice.tk, 1 +thisiswhywemom.com, 1 +thismatter.com, 1 +thismumdoesntknowbest.com, 1 +thisoldearth.com, 1 +thisserver.dontexist.net, 1 +thistleandleaves.com, 1 +thisuniverse.tk, 1 +thmail.ml, 1 +thmpartners.com, 1 +thn.la, 1 +thoe.xyz, 1 +tholcomb.com, 1 +thole.org, 1 +thom4s.info, 1 +thomalaudan.de, 1 +thomaner.de, 1 +thomas-bronniart.com, 1 +thomas-grobelny.de, 1 +thomas-sammut.com, 1 +thomas-schmittner.de, 1 +thomas-steel.com, 1 +thomas-suchon.fr, 1 +thomas.computer, 1 +thomas.love, 0 +thomas717.com, 1 +thomasbeckers.be, 1 +thomasbreads.com, 0 +thomascauquil.fr, 1 +thomasduerlund.com, 1 +thomasduerlund.dk, 1 +thomasebenrett.de, 1 +thomaseyck.com, 1 +thomasfoster.co, 1 +thomasgriffin.io, 1 +thomashunter.name, 0 +thomaskaviani.be, 1 +thomasmcfly.com, 1 +thomasmeester.nl, 0 +thomasmerritt.de, 1 +thomaspluschris.com, 1 +thomassen.sh, 1 +thomasstevensmusic.com, 0 +thomassynekmd.com, 1 +thomastestor.tk, 1 +thomastimepieces.com.au, 1 +thomastonmaine.gov, 1 +thomasverhelst.be, 1 +thomasvochten.com, 1 +thomaswoo.com, 1 +thomien.de, 1 +thompsonfamily.cloud, 1 +thompsonfunerals.com, 1 +thomsonscleaning.co.uk, 1 +thomspooren.nl, 0 +thomwiggers.nl, 1 +thooka.com, 1 +thoplam.com, 1 +thor.edu, 1 +thor.re, 1 +thorbiswebsitedesign.com, 1 +thoreau.tk, 1 +thoroquel.org, 1 +thoroughbreddiesel.com, 1 +thorsten-schaefer.com, 1 +thorstenschaefer.name, 1 +thotpublicidad.com, 1 +thoughtfullife.org, 1 +thoughtlessleaders.online, 1 +thoughtsynth.com, 1 +thoughtsynth.net, 1 +thoughtsynth.org, 1 +thoughtworthy.info, 1 +thouqi.com, 1 +thousandoakselectrical.com, 1 +thousandoaksexteriorlighting.com, 1 +thousandoakslandscapelighting.com, 1 +thousandoakslighting.com, 1 +thousandoaksoutdoorlighting.com, 1 +thoxyn.com, 1 +thpatch.net, 1 +thpay.com, 1 +thrashed.tk, 1 +threadtrails.com, 1 +threadythready.com, 1 +threatcentral.io, 1 +threatcon.io, 1 +threatdetection.info, 1 +threatmonitor.io, 1 +threatworking.com, 1 +three-wheels.cf, 1 +threedpro.me, 1 +threefantasy.com, 1 +threefours.net, 0 +threelions.ch, 1 +threema.ch, 1 +threeringdev.com, 1 +threerivers.edu, 1 +threeshipswhisky.co.za, 1 +threexxx.ch, 1 +threit.de, 1 +thriftdiving.com, 1 +thrillernyc.com, 1 +thrillkill.tk, 1 +thrivebymitchelle.com, 1 +thriveweb.com.au, 1 +throttlerz.in, 1 +throughout.ga, 1 +throughtheglass.photo, 1 +throwable.website, 1 +throwaway.link, 1 +throwmails.com, 1 +throwpass.com, 1 +thrush.com, 1 +thrustrules.tk, 1 +thrw.ml, 1 +thsc.us, 1 +thscpac.org, 1 +thsecurity.cz, 1 +thues.eu, 1 +thugcityrecords.tk, 1 +thullbery.com, 1 +thumbnail.site, 1 +thumbsnap.com, 1 +thumbsupcandy.com, 1 +thummer.net, 1 +thunderbase.tk, 1 +thunderbolt.tk, 1 +thunderboltlaptop.com, 1 +thundercloud.onthewifi.com, 1 +thunderfield-boat.co.uk, 1 +thunderfox.nl, 1 +thunderkeys.net, 1 +thundr.eu, 1 +thunraz.com, 1 +thuongthuccuocsong.com, 1 +thuongtravel.com, 1 +thurn.net, 1 +thusoy.com, 1 +thuthuatios.com, 1 +thutucxuatnhapkhau.net, 1 +thuviensoft.com, 1 +thuviensoft.net, 1 +thuyetphapmoi.com, 1 +thvideo.tv, 1 +thw-bernburg.de, 1 +thwebdesigns.com, 1 +thweis.com, 1 +thwiki.cc, 1 +thxandbye.de, 1 +thycotic.ru, 1 +thynx.io, 1 +thyrex.fr, 0 +thzone.net, 1 +ti-js.com, 1 +ti-pla.net, 1 +ti-planet.org, 1 +ti780.com, 1 +tiagocasalribeiro.ml, 1 +tiagoealine.com.br, 1 +tiagoneves.tk, 1 +tiagonunes.pt, 1 +tiagosimao.com, 1 +tiamabi.tk, 1 +tiamarcia.com.br, 1 +tian123.com, 1 +tian888.com, 1 +tianbaobo05.com, 1 +tianbaobo06.com, 1 +tianbaobo07.com, 1 +tianbaobo08.com, 0 +tianbaobo09.com, 1 +tianbo1088.com, 1 +tianbo1988.com, 1 +tianbo1998.com, 1 +tiance.me, 1 +tiandixing.org, 1 +tianeptine.com, 1 +tianjiaxi.com, 1 +tianshili.me, 1 +tiantangbt.com, 1 +tianxicaipiao.com, 1 +tianxicaipiao.win, 1 +tianxicp.com, 1 +tianyis.net, 1 +tiaria.id, 1 +tib1.com, 1 +tibbitshall.ca, 1 +tibicinagarricola.com, 1 +tibipg.com, 1 +tibovanheule.site, 1 +tibovanheule.space, 0 +tiburgundysi.ga, 1 +ticfleet.com, 1 +tichdiem80.com, 1 +tichieru.pw, 1 +ticinoscout.ch, 1 +ticketassist.nl, 1 +ticketbahia.com, 1 +ticketcity.com, 1 +ticketdriver.com, 1 +ticketpro.ca, 0 +ticketrunway.com, 1 +ticketslover.com, 1 +ticketsmate.com, 1 +ticketsource.co.uk, 1 +ticketsource.eu, 1 +ticketsource.io, 1 +ticketsource.us, 1 +ticketsourcebeta.co.uk, 1 +ticketswap.at, 1 +ticketswap.be, 1 +ticketswap.ch, 1 +ticketswap.co, 1 +ticketswap.co.nz, 1 +ticketswap.com, 1 +ticketswap.com.au, 1 +ticketswap.com.br, 1 +ticketswap.cz, 1 +ticketswap.de, 1 +ticketswap.dk, 1 +ticketswap.es, 1 +ticketswap.fi, 1 +ticketswap.fr, 1 +ticketswap.hu, 1 +ticketswap.ie, 1 +ticketswap.in, 1 +ticketswap.it, 1 +ticketswap.nl, 1 +ticketswap.no, 1 +ticketswap.pl, 1 +ticketswap.pt, 1 +ticketswap.ru, 1 +ticketswap.se, 1 +ticketswap.uk, 1 +tickettailor.com, 1 +ticketure.com, 1 +ticketyn.com, 1 +tickit.ca, 0 +tid.jp, 1 +tide.com, 0 +tidehunter.ml, 1 +tidton.com, 1 +tidy.chat, 1 +tidych.at, 1 +tidycustoms.net, 1 +tiekoetter.com, 1 +tielectric.ch, 1 +tielsebakkers.tk, 1 +tiempoalegria.com, 1 +tiempolibre.nl, 1 +tienda.cx, 1 +tiendabna.com.ar, 1 +tiendacanper.com, 1 +tiendadeperros.com, 1 +tiendadolca.com, 1 +tiendaengeneral.com, 1 +tiendafetichista.com, 1 +tiendamaquillajes.com, 1 +tiendashuacho.com, 1 +tiendatecnologica.net, 1 +tiener-herentals.be, 1 +tienerdienst-johanneskapel.tk, 1 +tienic.com, 1 +tiens-ib.cz, 1 +tierarzt-karlsruhe-durlach.de, 1 +tierarztpraxis-illerwinkel.de, 1 +tierarztpraxis-weinert.de, 1 +tiergear.com.au, 1 +tiernanx.com, 1 +tieronegraphics.com, 1 +tierra-indomables.tk, 1 +tierracenter.com, 1 +tierradeayala.com, 1 +tierrahost.com, 1 +tierschutz-niederrhein.de, 1 +ties.com, 1 +tietotori.fi, 1 +tietsikka.fi, 0 +tiew.pl, 0 +tifan.net, 1 +tifaware.com, 1 +tifenn.eu, 1 +tifenn.nl, 1 +tiffanitooley.tk, 1 +tiffany-remixed.tk, 1 +tiffany.life, 1 +tiffany.moe, 1 +tiffanyblooms.ru, 1 +tiffanywatson.xyz, 1 +tiffnix.com, 1 +tifile.ir, 1 +tiflonet.tk, 1 +tifokaos.tk, 1 +tiga-design.com, 1 +tigerads.digital, 1 +tigerdile.com, 1 +tigerfm.tk, 1 +tigerforce.tk, 1 +tigergroup.tk, 1 +tigernero.duckdns.org, 1 +tigernode.com, 1 +tigernode.net, 1 +tigerscu.org, 1 +tigerzplace.tk, 1 +tiggeriffic.com, 1 +tiggi.pw, 0 +tightassporntube.com, 1 +tigit.co.nz, 1 +tiglitub.com, 1 +tigreblanco.tk, 1 +tigzirt.tk, 1 +tihvin.tk, 1 +tiihosen.fi, 1 +tiim.technology, 1 +tijden.nu, 1 +tijerasnm.gov, 1 +tijo.ch, 1 +tik.edu.ee, 1 +tik.help, 1 +tiki-god.co.uk, 1 +tikona.ga, 1 +tiktak.su, 1 +tiktok.com, 1 +tiktokgenie.ru, 1 +tiktokoff.com, 1 +tilcra.de, 1 +tilde.institute, 1 +tilde.link, 1 +tildes.net, 1 +tilecleaningservicepros.com, 1 +tileco.ga, 1 +tileflooringideas.ml, 1 +tilellit.pro, 1 +tiles-for-facing.tk, 1 +tilesbay.com, 1 +tilid.com, 1 +tilikum.io, 1 +tilisi.ga, 1 +tilitoimistokota.fi, 1 +tilitop.tk, 1 +till.im, 1 +tillberg.us, 1 +tilleysbouncycastles.co.uk, 1 +tillmanassociates.com, 1 +tillseasyscore.com, 1 +tillwalldrug.com, 1 +tilosp.de, 1 +tiltedscalescollective.org, 1 +tiltedwindmillcrafts.com, 1 +tilysthings.com, 1 +tim-demisch.com, 1 +tim-demisch.de, 1 +tim-demisch.email, 1 +tim-demisch.eu, 1 +tim-demisch.online, 1 +tim-lawrence.cf, 1 +tim-niclas-demisch.de, 1 +tim-niclas-demisch.eu, 1 +tim427.net, 1 +timacdonald.me, 1 +timawesomeness.com, 1 +timbarlotta.com, 1 +timberjewelleryboxes.ga, 1 +timberjoineryperth.com.au, 1 +timberkel.com, 1 +timbers.space, 1 +timbishopartist.com, 1 +timbrado.com, 1 +timbrust.de, 1 +timchanhxe.com, 0 +timco.cloud, 1 +timdebruijn.nl, 1 +timdemisch.com, 1 +timdemisch.de, 1 +timdemisch.email, 1 +timdemisch.eu, 1 +timdemisch.online, 1 +timdoug.com, 1 +time-business.tk, 1 +time-hotel.cf, 1 +time-killers.tk, 1 +time.gov, 1 +time2060.ru, 1 +time2choose.com, 1 +time4writing.com, 1 +timeai.io, 1 +timeauction.hk, 1 +timebookings.cf, 1 +timebox.tk, 1 +timebutler.de, 1 +timecaptis.com, 1 +timecheck.tk, 1 +timefor.tk, 1 +timeforcoffe.eu, 1 +timeglass.de, 1 +timeharmony.pl, 1 +timelapsetv.tk, 1 +timeless-photostudio.com, 1 +timeless-spirit.com, 1 +timelesstreasures.tk, 1 +timelimit.io, 1 +timelyapp.com, 1 +timepassengers.tk, 1 +timepro.sk, 1 +timer.fit, 0 +timerace.ml, 1 +timeroll.ml, 1 +timersuite.com, 1 +timesedlen.dk, 1 +timeserver0.de, 1 +timeserver1.de, 1 +timeserver2.de, 1 +timeserver3.de, 1 +timesheetcomics.com, 1 +timespace.eu.org, 1 +timespowerofprint.com, 1 +timespreader.com, 1 +timeswiki.org, 1 +timetab.org, 1 +timetastic.co.uk, 1 +timetotrade.com, 1 +timetrade.com, 1 +timewasters.nl, 1 +timfiedler.net, 1 +timgame.tk, 1 +timhieuthuoc.com, 1 +timi-matik.hu, 1 +timich.ga, 1 +timilion.tk, 1 +timing.com.br, 1 +timjk.de, 0 +timmerbedrijfpauel.nl, 1 +timmermansadministratie.nl, 1 +timmersgems.com, 0 +timmy.ws, 1 +timmyrs.de, 1 +timnash.co.uk, 1 +timniclasdemisch.de, 1 +timniclasdemisch.eu, 1 +timonengelke.de, 1 +timonenko.cf, 1 +timosfoodbar.nl, 1 +timoso.de, 1 +timotheeduran.com, 1 +timothy.tk, 1 +timowi.de, 1 +timoxbrow.com, 1 +timqueen.com, 1 +timroes.de, 1 +timsayedmd.com, 1 +timscheuermann.ddns.net, 1 +timseverien.com, 1 +timstoffel.net, 0 +timtaubert.de, 1 +timtelfer.com, 1 +timvandekamp.nl, 1 +timvandenborre.be, 1 +timvivian.ca, 1 +timweb.ca, 1 +timwestdesigns.com, 1 +timx.uk, 1 +timysewyn.be, 0 +tina-zander.de, 0 +tina.media, 1 +tinaarenaweb.tk, 1 +tinakay-photography.com, 1 +tinandthyme.uk, 1 +tinapoethe.com, 0 +tinastahlschmidt.de, 1 +tinclip.com, 1 +tindallriley.co.uk, 1 +tinderphotos.ga, 1 +tinekevanurk.nl, 1 +tinf.de, 1 +tinf15b4.de, 1 +tinfoleak.com, 1 +tinhchattrangda.vn, 1 +tinhlai.gq, 1 +tink.network, 1 +tinka.tk, 1 +tinker.career, 1 +tinker.fyi, 1 +tinkerbeast.com, 1 +tinkerboard.org, 1 +tinkerers-trunk.co.za, 1 +tinkmai.com, 1 +tinlc.org, 1 +tinlook.com, 1 +tinmarin.org, 1 +tinminnow.me, 1 +tinnhanhvietnam.tk, 1 +tintamas.tk, 1 +tintariau.com, 1 +tinte24.de, 1 +tintenfix.net, 1 +tintenfux.de, 1 +tintenland.de, 1 +tintenprofi.de, 1 +tintoria.roma.it, 1 +tinturanaturale.it, 1 +tiny-house.ro, 1 +tiny-img.com, 1 +tiny-tattoos.tk, 1 +tiny.ee, 1 +tiny777.com, 1 +tinycat99.ws, 1 +tinychen.com, 1 +tinycrm.pl, 1 +tinyemily.com, 1 +tinyfont.ml, 1 +tinyhousebarat.com, 1 +tinyhousebarat.de, 1 +tinyhousefinance.com.au, 1 +tinylan.com, 1 +tinylink.cf, 1 +tinyproxy.ga, 1 +tinysol.com.au, 1 +tinyspeck.com, 1 +tinyssh.com, 1 +tinyssh.org, 1 +tinyurl.com, 1 +tinyvpn.net, 1 +tinyvpn.org, 1 +tio.run, 1 +tioat.net, 1 +tiogacountyny.gov, 1 +tipaki.gr, 1 +tipe.io, 0 +tiphar.com, 1 +tipiakers.club, 1 +tiplanet.org, 1 +tipnews.tk, 1 +tipo01.tk, 1 +tipocloud.cf, 1 +tipoftheday.tips, 1 +tipplist.com, 1 +tipps-fuer-den-haushalt.de, 1 +tippspiel.cc, 1 +tippytoad.com, 1 +tipranks.com, 1 +tips4india.tk, 1 +tipsacademicos.com, 1 +tipscesarlopez.com, 1 +tipsdebellezaysalud.com, 1 +tipsfinal.tk, 1 +tipskanalen.cf, 1 +tipslab.info, 1 +tipslifetimefitness.ga, 1 +tipsmake.com, 1 +tipsoftech.tk, 1 +tipsplants.com, 1 +tipstersweb.com, 1 +tipsypresent.com, 1 +tiptoptransmissions.com, 1 +tipulnagish.co.il, 1 +tipwho.com, 1 +tiqets.com, 1 +tir-mauperthuis.fr, 1 +tirana-chat.tk, 1 +tirandoalplato.tk, 1 +tiraspol.tk, 1 +tircentrale.net, 0 +tirebichon.eu, 1 +tirgul-vertiujeni.tk, 1 +tirion.network, 0 +tirion.org, 0 +tirionnetwork.de, 1 +tirlins.com, 1 +tiroler-kupferschmiede.com, 1 +tirs4ne.ch, 0 +tirteafuera.tk, 1 +tirupatinightwear.co.in, 1 +tis-mark.ru, 1 +tis.ph, 1 +tischlerei-geher.at, 1 +tischlerei-klettke.de, 1 +tisec.info, 1 +tisgroup.com.my, 1 +tism.in, 1 +tisparking.com, 1 +tissot-mayenfisch.com, 0 +tissus-paris.com, 1 +tisvapo.it, 1 +tit-cdn.de, 1 +tit-dev.de, 1 +tit-dns.de, 1 +tit-mail.de, 1 +tit.systems, 1 +titanandco.com, 1 +titandirect.co.uk, 1 +titanforged.net, 0 +titanicauto.ro, 1 +titaniumangel.com, 1 +titansized.com, 1 +titantax.com, 1 +titanwaterproofing.com.au, 1 +titelseite.ch, 1 +titiansgirl.com, 1 +titina.tk, 1 +titleboxing.com, 1 +titli.fr, 1 +titouan.co, 0 +titrespresse.com, 1 +titser.ph, 1 +tittelbach.at, 1 +titusetcompagnies.net, 0 +tivido.nl, 1 +tiwag.at, 1 +tiwilandcouncil.com, 1 +tixeconsulting.com, 1 +tixel.com, 1 +tixify.com, 1 +tixtips.com, 1 +tizen-ru.tk, 1 +tjampoer.com, 1 +tjcuk.co.uk, 1 +tjenestetorvet.dk, 1 +tjian.info, 1 +tjl.rocks, 1 +tjongeling.tk, 1 +tjp.ch, 0 +tju.me, 1 +tjupt.org, 1 +tjxxzy.com, 1 +tjzzz.com, 1 +tk-its.net, 1 +tk-smart.ru, 1 +tk2net.com, 1 +tkacz.pro, 1 +tkanemoto.com, 0 +tkat.ch, 1 +tkcafe.net, 1 +tkgpm.com, 1 +tkhirianov.tk, 1 +tkirch.de, 1 +tkita.kr, 1 +tkjg.fi, 1 +tkmr-gyouseishosi.com, 1 +tkn.me, 1 +tkrn.de, 1 +tksainc.com, 1 +tkts.cl, 1 +tkusano.jp, 1 +tkw01536.de, 0 +tkwhongkong.tk, 1 +tl.gg, 1 +tlach.cz, 1 +tlanyan.pp.ua, 1 +tlca.org, 1 +tlcbynature.com.au, 1 +tlcnet.info, 1 +tlctrades.com, 1 +tld-list.com, 1 +tldplaza.com, 1 +tldtattoo.com, 1 +tlehseasyads.com, 1 +tleng.de, 1 +tlesptyltd.com.au, 1 +tlicycling.com, 1 +tlo.xyz, 1 +tloschinski.de, 1 +tloxygen.com, 1 +tlroadmap.io, 1 +tls-proxy.de, 1 +tls.builders, 1 +tls.care, 1 +tlsrobot.se, 1 +tlthings.net, 1 +tlumaczenie.com, 1 +tlys.de, 0 +tm-t.ca, 1 +tm80plus.com, 1 +tmachinery.cz, 1 +tmadev.com.au, 1 +tmas.dk, 1 +tmbcloud.duckdns.org, 1 +tmberg.cf, 1 +tmberg.eu.org, 1 +tmberg.ml, 1 +tmberg.se.eu.org, 1 +tmberg.tk, 1 +tmbergtmberg.cf, 1 +tmbergtmberg.ga, 1 +tmbergtmberg.gq, 1 +tmbergtmberg.ml, 1 +tmbergtmberg.tk, 1 +tmc.com.ar, 1 +tmc.com.mt, 1 +tmcjobs.com, 1 +tmcreationweb.com, 1 +tmdb.biz, 1 +tmechen.me, 1 +tmf.ru, 1 +tmf22.ru, 1 +tmhanoi.com, 1 +tmheatingcooling.com, 1 +tmhr.moe, 1 +tmi-products.eu, 1 +tmi-produkter.se, 1 +tmi.news, 1 +tmin.cf, 1 +tmm.cx, 1 +tmp.sx, 1 +tmpraider.net, 1 +tmpsantos.com.br, 1 +tmsdiesel.com, 1 +tmstats.fr, 1 +tmtopup.com, 0 +tn-bb.com, 1 +tn0.club, 1 +tnb-plattform.de, 1 +tncentro.com, 1 +tndentalwellness.com, 1 +tnes.dk, 1 +tnonline.net, 1 +tnosha.gov, 1 +tnrealid.gov, 1 +tnsolutions.ro, 1 +tnt.construction, 1 +tntmobi.com, 1 +tntware.com, 1 +tnusedoil.gov, 1 +tnutoys.com, 1 +tnved2013-narod.tk, 1 +tnwgrc.com, 1 +tnwildlandfire.gov, 1 +tnwioa.gov, 1 +tny.link, 0 +to-med.ru, 1 +to.gt, 1 +to.md, 1 +toad.ga, 1 +toast.al, 0 +toastmasters.tk, 1 +toaw.de, 1 +tob-rulez.de, 1 +tobacco-shop.co.uk, 1 +tobacco.gov, 1 +tobaccolocker.com, 1 +tobbro-trans.de, 1 +tobdesignfirm.com, 1 +tobedo.net, 1 +tober-cpag.de, 1 +tobevictorious.com, 1 +tobeyvorus.com, 1 +tobi-mayer.de, 1 +tobi-server.goip.de, 1 +tobi-videos.goip.de, 1 +tobiaalberti.com, 1 +tobias-bauer.de, 1 +tobias-bauer.eu, 1 +tobias-bauer.fr, 1 +tobias-bauer.net, 1 +tobias-haenel.de, 1 +tobias-kleinmann.de, 1 +tobias-kluge.de, 1 +tobias-picha.de, 1 +tobias-weidhase.de, 1 +tobias.gr, 1 +tobias4.ddns.net, 1 +tobiasbergius.se, 1 +tobiasbrunner.net, 1 +tobiasconradi.com, 1 +tobiase.de, 1 +tobiasfischer.info, 1 +tobiashorvath.com, 1 +tobiashorvath.de, 1 +tobiaskorf.de, 1 +tobiaspahlings.de, 1 +tobiassachs.cf, 1 +tobiassachs.de, 1 +tobiassachs.tk, 1 +tobiassattler.com, 1 +tobiaswiese.com, 1 +tobiaswiese.eu, 1 +tobiaswiese.net, 1 +tobiaswiese.org, 1 +tobiaswiese.work, 1 +tobiefornerod.ch, 1 +tobis-rundfluege.de, 1 +tobis.cloud, 1 +tobischo.de, 1 +tobisworld.ch, 1 +tobostop.de, 1 +tobtennis.tk, 1 +toby.website, 1 +tobyalden.com, 1 +tobyschrapel.com, 0 +tobyslawn.com, 1 +tobyx.cc, 1 +tobyx.co, 1 +tobyx.com, 1 +tobyx.de, 1 +tobyx.eu, 1 +tobyx.is, 1 +tobyx.me, 1 +tobyx.net, 1 +tobyx.org, 1 +tobyx.xyz, 1 +tocasoft.co.uk, 1 +toccoig.com, 1 +tochi-urikata.net, 1 +todacarreira.com, 1 +todaciencia.com, 1 +todamateria.com.br, 1 +todapolitica.com, 1 +todasaslojas.com.br, 1 +todaslascafeteras.com, 1 +today.ng, 1 +todayfinance.news, 1 +todayfinancial.news, 1 +todaylearn.tk, 1 +todaymeow.com, 1 +todaysbestinsurance.com, 1 +todayupdates.ga, 1 +toddcullumresearch.com, 1 +toddexler.com, 1 +toddfry.com, 1 +toddlerleaf.com, 1 +toddmath.com, 1 +toddmclauchlin.cf, 1 +toddmissiontx.gov, 1 +todo-anime.com, 1 +todo-securitywerkstuk.azurewebsites.net, 1 +todobien.club, 1 +todocracy.com, 1 +todocruces.com, 1 +todoereaders.com, 1 +todoescaperooms.com, 1 +todoescine.com, 1 +todoist.com, 1 +todoist.net, 1 +todolex.tk, 1 +todon.fr, 1 +todoporjesus.net, 1 +todoscheduler.de, 1 +todoscheduler.org, 1 +todoscomciro.com, 1 +todoseaprende.com, 1 +todosrv.com, 1 +todotiendas.tk, 1 +toeglhofer.at, 1 +toeightycountries.com, 1 +toekomstperspectief.be, 1 +toepferei-langerwehe.de, 1 +toepferwerk.de, 1 +toerschaatsenknsb.nl, 1 +toest.bg, 1 +toetsplatform.be, 1 +tofa-koeln.de, 1 +tofe.io, 1 +tofilmhub.com, 1 +tofinovacationrentals.ca, 1 +tofliving.nl, 1 +tofu.cf, 1 +tofuixi.com, 1 +tog.pw, 1 +togetter.com, 1 +togglename.ml, 1 +togoweed.co, 1 +togtider.dk, 1 +toheb.de, 0 +tohfalaya.com, 1 +tohofc.co.jp, 1 +tohokinemakan.tk, 1 +tohoku-fukushi.com, 1 +tohokufd.com, 1 +toila.best, 1 +toileobscure.fr, 1 +toirereform.com, 1 +tojannah.com, 0 +tok4.com, 1 +tokaido-kun.jp, 1 +tokaido.com, 1 +tokainafb.net, 1 +tokelaunso.tk, 1 +tokens.net, 1 +tokfun.com, 1 +toki-doki.tk, 1 +tokic.hr, 0 +tokimeko.jp, 1 +tokinoha.net, 1 +tokinokakehashi.com, 1 +tokio.fi, 1 +tokiohotel-world.tk, 1 +tokitover.com, 1 +tokka.com, 1 +tokke.dk, 1 +tokkee.org, 1 +tokky.be, 1 +tokky.eu, 1 +tokky.fr, 1 +tokobungadilampung.com, 1 +tokoindo.top, 1 +tokopedia.ga, 1 +tokoplugin.com, 1 +tokugai.com, 1 +tokyo-onkyo.jp, 1 +tokyo-powerstation.com, 1 +tokyo.dating, 1 +tokyoadultguide.com, 1 +tokyodenmarkweek.com, 1 +tokyomakino.com, 1 +tokyotimeline.com, 1 +tokyotoptentravel.com, 1 +tokyovipper.com, 1 +tolbertmgmt.com, 1 +tolboe.com, 1 +toldositajuba.com, 0 +toledo.tk, 1 +toledotrabaja.com, 1 +toledotrainday.org, 1 +tolerance-zero.tk, 1 +toleressea.fr, 1 +toles-sur-mesure.fr, 1 +tolkienfans.tk, 1 +tolkienmusic.tk, 1 +tolkienwiki.ml, 1 +tolkovanie-sna.tk, 1 +tolle-wolke.de, 1 +tollerunterricht.com, 1 +tollfreeproxy.com, 1 +tollmanz.com, 0 +tolmaidis.com, 1 +tolman.nl, 1 +tolmandrywall.com, 1 +tolnavar.hu, 1 +tolstoevsky.tk, 1 +tolucreaciones.com, 1 +tom-geiger.de, 1 +tom-hanks.tk, 1 +tom-kunze.de, 1 +tom-kurka.cz, 1 +tom.center, 1 +tom.horse, 1 +tom.je, 1 +tom.ro, 1 +tom94.net, 1 +tomabrafix.de, 1 +tomacino.de, 1 +tomahawk.ca, 1 +toman-vzv.cz, 1 +tomandmara.com, 1 +tomandshirley.com, 1 +tomandsonya.net, 1 +tomandsonya.org, 1 +tomarnarede.pt, 1 +tomartv.pt, 1 +tomasdrtina.cz, 1 +tomashouzvicka.pl, 1 +tomasjacik.cz, 1 +tomaskavalek.cz, 0 +tomasmatulevicius.lt, 1 +tomasmoberg.org, 1 +tomaspatera.cz, 1 +tomasvecera.cz, 1 +tomasz.com, 1 +tomaszdwornicki.net, 1 +tomatenaufdenaugen.de, 1 +tomatis-nantes.com, 1 +tomatofrogs.com, 1 +tomaz.eu, 1 +tombaker.me, 1 +tombeantx.gov, 1 +tomberek.info, 1 +tomboonen.tk, 1 +tomboy.org, 1 +tombrossman.com, 1 +tombu.biz, 1 +tombu.info, 1 +tombu.org, 1 +tombu.xyz, 1 +tomchen.org, 1 +tomco-corporation.tk, 1 +tomd.ai, 1 +tomend.es, 1 +tomershemesh.me, 1 +tomfisher.eu, 1 +tomgaechter.ch, 1 +tomharling.co.uk, 1 +tomharling.uk, 1 +tomhiddlestonspain.tk, 1 +tomi.cc, 1 +tomik.cloud, 1 +tomik.space, 1 +tomikoyco.com, 1 +tomiler.com, 1 +tomiubezpiecz.pl, 1 +tomjans.nl, 1 +tomjepp.uk, 1 +tomjn.com, 1 +tomkempers.nl, 1 +tomkunze.de, 1 +tomkwok.com, 0 +tomli.blog, 1 +tomlowenthal.com, 1 +tomm.yt, 1 +tommic.eu, 1 +tommihynynen.com, 1 +tommy-bordas.fr, 0 +tommycarrauto.com, 1 +tommyemo.com, 1 +tommymoya.tv, 1 +tommyphotographie.com, 0 +tomnatt.com, 1 +tomo.gr, 0 +tomodachi.tk, 1 +tomoko-clinic.jp, 1 +tomoradexpert.ro, 1 +tomorrow-traxx.tk, 1 +tomorrowhealth.com, 1 +tomorrowx.com, 1 +tomosm.net, 1 +tomphenix.com, 1 +tomphill.co.uk, 0 +tomradtke.de, 1 +tomravinmd.com, 1 +tomrei.com, 1 +tomrichards.net, 1 +tomrunting.pro, 1 +toms.ovh, 1 +tomschlick.com, 1 +tomsdevsn.me, 1 +tomservo.net, 1 +tomsick.it, 1 +tomsk.cf, 1 +tomsk.ml, 1 +tomsk24.tk, 1 +tomsk365.ga, 1 +tomsknet.tk, 1 +tomsknews.tk, 1 +tomslawadvice.com, 1 +tomsoft.hr, 1 +tomspdblog.com, 1 +tomssite.tk, 1 +tomssl.com, 1 +tomstew.art, 1 +tomthorogood.co.uk, 1 +tomthorogood.uk, 0 +tomticket.com, 1 +tomudding.nl, 1 +tomvanlaer.be, 1 +tomvote.com, 1 +tomvst.net, 1 +tomwassenberg.com, 1 +tomwassenberg.nl, 1 +tomwellington.design, 1 +tomwilson.io, 0 +tomyork.net, 1 +tonabor.ru, 1 +tonage.de, 1 +tonalaw.com, 1 +tonarinoliusan.com, 1 +tonarinoliusan.net, 1 +tonburi.jp, 0 +toncusters.nl, 1 +tondles.com, 1 +tone.tw, 1 +toneelverenigingnutengenoegen.nl, 1 +tonegidoarchief.nl, 1 +toner24.at, 1 +toner24.co.uk, 1 +toner24.es, 1 +toner24.fr, 1 +toner24.it, 1 +toner24.nl, 1 +toner24.pl, 1 +tonerdepot.de, 1 +tonerjet.at, 1 +tonerjet.co.uk, 1 +tonerklick.de, 1 +tonerkurier.de, 1 +tonermaus.de, 1 +tonermonster.de, 1 +tonex.de, 1 +tonex.nl, 1 +tongjistudents.org, 1 +tongli.eu.org, 1 +tonguetechnology.com, 1 +toni-dis.ch, 0 +tonifarres.net, 1 +tonight.de, 1 +tonkayagran.com, 1 +tonkayagran.ru, 1 +tonkinson.com, 1 +tonnycat.com, 1 +tonnygaric.com, 1 +tono.us, 1 +tonorosario.tk, 1 +tonshaiza.tk, 1 +tonsit.com, 1 +tonsit.org, 0 +tontonnews.net, 1 +tontonroger.org, 1 +tonyandskye.com, 1 +tonyarcieri.com, 1 +tonyburns.xyz, 1 +tonydaquin.com, 1 +tonyhagerlund.tk, 1 +tonymanning.com, 1 +tonysantos.tk, 1 +tonytan.cn, 1 +tonytan.io, 1 +tonytron.com.br, 1 +tonyw.xyz, 1 +tonywebster.com, 1 +too.com.ua, 1 +too.tl, 1 +toobug.net, 1 +tookhan.tk, 1 +tool.lu, 1 +toolbox-bodensee.de, 1 +toolbox.ninja, 0 +toolboxsoftware.tk, 1 +toolineo.de, 1 +toolip.gr, 1 +toolkits.design, 1 +toolroomrecords.com, 1 +tools.pro, 1 +toolsense.io, 1 +toolset.com, 1 +toolsharing.jp, 1 +toolshero.com, 0 +toolspain.tk, 1 +toolsu.com, 1 +toom.io, 1 +toomy.ddns.net, 1 +toomy.pri.ee, 1 +toon.style, 1 +toondergroup.com, 1 +toonmate.tk, 1 +toonpool.com, 1 +toonsburgh.com, 1 +toontown.team, 1 +toontownrewritten.com, 1 +toool.nl, 1 +toool.nyc, 1 +toool.org, 1 +toopita.com, 1 +toopopular.ga, 1 +toorfor.com, 1 +toot.center, 1 +toot.koeln, 1 +tootbitco.ml, 1 +toothdoc.ca, 1 +toothless.tk, 1 +toothpique.tk, 1 +tootl.org, 1 +top-avis.fr, 1 +top-beauty.cf, 1 +top-cena.ru, 1 +top-credit.tk, 1 +top-drop.tk, 1 +top-electronics.ru, 1 +top-frog.com, 1 +top-info.ga, 1 +top-kuwait.com, 1 +top-mining.tk, 1 +top-obaly.cz, 1 +top-opakowania.pl, 1 +top-rensner.de, 1 +top-rezepte.de, 1 +top-russian.tk, 1 +top-schools.tk, 1 +top-secret.tk, 1 +top-service.ml, 1 +top-skins.ml, 1 +top-zdrave.bg, 1 +top-zentr.tk, 1 +top10.digital, 1 +top10.tk, 1 +top100games.ml, 1 +top10antivirus.review, 1 +top10media.tk, 1 +top10mountainbikes.info, 1 +top4c.com, 1 +top4shop.de, 1 +top6casinos.com, 1 +top9.fr, 1 +topan.tk, 1 +topanimecharacters.com, 1 +topanlage.de, 1 +toparkinfo.hu, 1 +topas.tk, 1 +topaxi.ch, 1 +topaxi.codes, 1 +topb.vn, 1 +topbestsellerproduct.com, 1 +topbookmarking.cf, 1 +topbouncycastles.co.uk, 1 +topbrainscience.com, 1 +topbrasilnews.tk, 1 +topbrunchspots.com, 1 +topbusinessnews.today, 1 +topbussines.tk, 1 +topcameras.tk, 1 +topcarcasas.com, 1 +topcarehvac.ca, 1 +topciderska-crkva.rs, 1 +topclassfun.ie, 1 +topdesk.net, 1 +topdetoxcleanse.com, 1 +topdevbox.net, 1 +topdocumentaryfilms.com, 1 +topdogsinflatables.co.uk, 1 +topdomainsandhosting.com, 1 +topdosug.ml, 1 +topdroneusa.com, 1 +topeducationhelp.co, 1 +topekafoundationpros.com, 1 +toperadigital.com, 1 +topfd.net, 1 +topferta.com, 1 +topfivepercent.co.uk, 1 +topgallant.gq, 1 +topgrading.com, 1 +topgshop.ru, 1 +toph.co, 1 +tophat.studio, 1 +tophatpuffin.com, 0 +tophighnorldiet.gq, 1 +tophr.kz, 0 +topicalnet.de, 1 +topicdesk.com, 1 +topicit.net, 1 +topicpoint.tk, 1 +topicpulse.tk, 1 +topicv.com, 1 +topideipodarkov.ru, 1 +topinjust.com, 1 +topirishcasinos.com, 1 +topjeans.ga, 1 +topjobs.ch, 1 +topkek.ml, 1 +topknot.gq, 1 +topkorea.ml, 1 +toplevel.mx, 1 +toplifesaudaveis.com.br, 1 +toplink.co.il, 1 +toplist.cz, 1 +toplist.eu, 1 +toplist.sk, 1 +toplistforum.tk, 1 +toplockshop.com, 1 +topmagazinewire.com, 1 +topmarketplace.com.br, 1 +topmejores.org, 1 +topmmogames.org, 1 +topmoods.com, 1 +topmotoric.com, 1 +topmuzic.tk, 1 +topmuzika.cz, 1 +topnaz.com, 1 +topnet.tk, 1 +topnewsscoop.com, 1 +topnlist.com, 1 +topnotchendings.com, 1 +topnotchsociety.com, 0 +topnotepad.com, 1 +topo.com.ro, 1 +topodin.com, 1 +topofertas.tk, 1 +topofficesupplies.tk, 1 +topofmind.co.za, 1 +topographic.tk, 1 +toponlinecasinosites.co.uk, 1 +toponlinemarketing.tk, 1 +topophile.net, 1 +topotom.tk, 1 +toppercan.es, 1 +toppillars.com, 1 +topporn.me, 1 +topprice.ua, 1 +topproductidea.com, 1 +topproductsanalysis.com, 1 +toppropertypattaya.com, 1 +topradiosbrasil.tk, 1 +toprci.com.br, 1 +toprelatos.com, 1 +topsailtechnologies.com, 1 +topservercccam.com, 1 +topservercccam.tv, 1 +topservers.ga, 1 +topshelf.tech, 1 +topshelfcommercial.com, 1 +topshop.tk, 1 +topshoptools.com, 1 +topsnow.ru, 1 +topspace.tk, 1 +topspani.cz, 1 +topspin.tk, 1 +topsteroidsonline.com, 1 +topsvet.ru, 1 +toptec.net.br, 1 +toptechs.com.br, 1 +topteen.tk, 1 +topten.com.co, 1 +toptenthebest.com, 1 +toptexture.com, 1 +toptheto.com, 1 +toptiernetworks.tk, 1 +toptranslation.com, 1 +toptravelgram.com, 1 +toptur.tk, 1 +topupandearn.com, 1 +topurls.tk, 1 +topvertimai.lt, 1 +topviet.ga, 1 +topvision.es, 1 +topvision.se, 1 +topwin.la, 1 +topwindowcleaners.co.uk, 1 +topwonders.tk, 1 +topwoodltd.co.uk, 1 +topyachts-shop.com.ua, 1 +topyachts.com.ua, 1 +topzarabotok.ml, 1 +toquechic.com, 1 +tor2web.org, 1 +toracon.org, 1 +toranjchap.com, 1 +torba.tk, 1 +torbay.ga, 1 +torbe.es, 1 +torchantifa.org, 1 +torchbearer.tk, 1 +toreni.us, 1 +toretame.jp, 1 +toretfaction.net, 1 +torg-room.ru, 1 +torgopt.tk, 1 +toriko-official.ml, 1 +tork.news, 1 +torkware.com, 1 +torlinnhe.com, 1 +torlock.com, 1 +torlock.host, 1 +torlock.icu, 1 +torlock.pw, 1 +torlock2.com, 1 +tormakristof.eu, 1 +tormentedradio.com, 0 +tormox.ml, 1 +tornadoarchiv.ml, 1 +tornadodetector.ga, 1 +tornadotwistar.com, 1 +torngalaxy.com, 1 +tornos.site, 1 +torogroups.com, 1 +torondor.tk, 1 +torontoaccesscontrol.com, 1 +torontocorporatelimo.services, 1 +torontogid.cf, 1 +torontonews.tk, 1 +torontoscrapcarremoval.ca, 1 +torontostarts.com, 1 +torontotransit.tk, 1 +toros.co, 1 +torproject.org, 0 +torproject.ovh, 1 +torprojects.com, 1 +torquemada.tk, 1 +torrance.gq, 1 +torrba.tk, 1 +torrecilladelaabadesa.tk, 1 +torreconta.pt, 1 +torrededonmiguel.tk, 1 +torremarsalou.com, 1 +torrent.fedoraproject.org, 1 +torrent.is, 1 +torrent.tm, 1 +torrentbd.com, 1 +torrentbd.me, 1 +torrentbd.net, 1 +torrentdownload.gq, 1 +torrentfunk.com, 1 +torrentfunk.host, 1 +torrentfunk.icu, 1 +torrentfunk.pw, 1 +torrentfunk2.com, 1 +torrentgalaxy.to, 1 +torrenttop100.net, 1 +torrentz2.al, 1 +torresdealbanchez.tk, 1 +torresdocaribe.com.br, 1 +torresdocariberesidence.com.br, 1 +torresjaen.tk, 1 +torresshop.es, 1 +torretzalam.com, 1 +torservers.net, 1 +torsten-frenzel.de, 1 +torsten-schmitz.net, 1 +torsten-werner.info, 1 +torstens-buecherecke.de, 1 +torstensenf.de, 1 +tortak.ml, 1 +torte.roma.it, 1 +torticollisexplained.com, 1 +tortillas-duras.cf, 1 +tortocan.com, 1 +tortoises-turtles.com, 1 +tortuga.ga, 1 +tortugan.com.br, 1 +torwart-jugend.de, 1 +tosainu.com.br, 1 +tosatopsicologabologna.com, 1 +toscer.me, 0 +toschool.com.br, 1 +toshen.com, 1 +toshik.tk, 1 +toshkov.com, 1 +tosolini.info, 1 +tosostav.cz, 1 +tosshi-life.com, 1 +tossitaway.tk, 1 +tosteberg.se, 1 +tostu.de, 1 +totaku.ru, 0 +total-destruction.tk, 1 +totalaccessnicaragua.co, 1 +totalbike.com.br, 1 +totalcarcheck.co.uk, 1 +totalchecklist.com, 1 +totalclean.co.uk, 1 +totalconceptnh.com, 1 +totalemaiildelivery.com, 1 +totalemaiilldelivery.com, 1 +totalemaildeliivery.com, 1 +totalemaildelivery.com, 1 +totalemaildellivery.com, 1 +totalemailldeliivery.com, 1 +totalemailldelivery.com, 1 +totalengineering.club, 1 +totalforcegym.com, 0 +totalhomecareinc.com, 1 +totalhost.gq, 1 +totalinfo.in, 1 +totalintegratedtherapy.com, 1 +totalityservices.co.uk, 1 +totalleedee.com, 1 +totallemaiildelivery.com, 1 +totallemaildelivery.com, 1 +totallovingcareservice.com, 1 +totally-awesome.xyz, 1 +totally-dakota.tk, 1 +totallylegitimatehosting.ru, 1 +totallynotaserver.com, 1 +totallystocks.ga, 1 +totalmdplan.com, 1 +totalofficeclean.co.uk, 1 +totalpackers.com, 1 +totalparts.com.au, 1 +totalsport-bg.com, 1 +totaltriathlon.com, 1 +totalwebboost.nl, 1 +totalwebmedia.nl, 1 +totalzen.ga, 1 +totch.de, 1 +totem-international.com, 1 +totemgames.tk, 1 +tothetopmentoring.com, 1 +totkamassage.com, 1 +totobetty.com, 1 +totodil.es, 1 +totolabs.com, 1 +totoro.pub, 1 +tottoya.com, 1 +totvs.com, 1 +toucan-informatique.fr, 1 +touch-up-net.com, 1 +touch.facebook.com, 0 +touch.mail.ru, 1 +touch2ship.com, 1 +touchable.gq, 1 +touchboobs.ml, 1 +touchdown.co, 1 +touchezlebouddha.com, 1 +touchinformatica.com, 0 +touchka.ga, 1 +touchoflife.in, 1 +touchscreentills.com, 1 +touchtable.nl, 1 +touchweb.be, 1 +touchweb.ch, 1 +touchweb.fr, 1 +touchwoodtrees.com.au, 1 +tougetu.com, 1 +tough.email, 1 +toughcodes.com, 1 +toughvps.com, 1 +touhou.ac.cn, 1 +touhou.cc, 1 +touhou.fm, 1 +touhou.tw, 1 +touhouwiki.net, 1 +toujour.top, 1 +toujours-actif.com, 1 +toulis.net, 1 +toumeitech.com, 1 +tour-japan.ml, 1 +tour-vietnam.tk, 1 +touray-enterprise.ch, 1 +tourbryansk.tk, 1 +tourdatenarchiv.de, 1 +tourdewestwoud.nl, 1 +tourfunnels.com, 1 +tourgest.net, 1 +tourguideagent.com, 1 +tourism-exegetai.tk, 1 +tourismpskov.tk, 1 +tourismtrain.tk, 1 +tourispo.com, 1 +touristanalyst.ga, 1 +tournamentmgr.com, 1 +tournaments.tk, 1 +tournevis.ch, 0 +tours-in-petersburg.tk, 1 +tours.co.th, 1 +toursandtransfers.it, 1 +toursencancun.com, 1 +toursinvietnam.tk, 1 +tourtransferitaly.it, 1 +tourtrektrip.com, 1 +tourx.co.nz, 1 +tous-travaux.ch, 0 +tousei.tokyo.jp, 1 +toushi-return.xyz, 1 +toushi-shakkin.com, 1 +touslesdrivers.com, 1 +tout-a-fait.fr, 1 +tout-art.ch, 1 +toutankamon.tk, 1 +toutart.ch, 1 +toutelathailande.fr, 1 +toutenmusic.fr, 1 +toutmonexam.fr, 1 +toutvendre.be, 1 +toutvendre.ch, 1 +toutvendre.cm, 1 +toutvendre.es, 1 +toutvendre.fr, 1 +toutvendre.lu, 1 +toutvendre.pics, 1 +toutvendre.uk, 1 +toutvendre.us, 1 +touwhalster.tk, 1 +tovaglioli-di-carta.it, 1 +tovare.com, 1 +tovari-rukodeliya.tk, 1 +tovarypochtoj.tk, 1 +toverland-tickets.nl, 1 +tovp.org, 1 +tovse.com, 1 +towandalibrary.org, 1 +towaway.ru, 1 +towellconstruction.ca, 1 +tower.land, 1 +towerdefence.tk, 1 +towers-kolomna.tk, 1 +towessi.tk, 1 +town-night.jp, 1 +townforge.net, 1 +townhouseregister.com.au, 1 +townifi.ga, 1 +townofbridgewater.ca, 1 +townofgoldenmeadow-la.gov, 1 +townofhulbertok.gov, 1 +townofmineral.net, 1 +townofpolk-wi.gov, 1 +townofruthnc.gov, 1 +townofsweetwater.com, 1 +townoftaycheedahwi.gov, 1 +townresults.ga, 1 +townshipofthenorthshore.ca, 1 +towsonpediatrics.com, 1 +towsonroofers.com, 1 +towtruck.website, 0 +towywebdesigns.uk, 1 +towzone.co.uk, 1 +tox21.gov, 1 +toxicboot.com, 1 +toxicip.com, 1 +toycollection.com.br, 1 +toycu.de, 1 +toyduck.ga, 1 +toymagazine.com.br, 1 +toymania.de, 1 +toymarket.tk, 1 +toyokawa-fan.com, 1 +toyopac.com, 1 +toyota-kinenkan.com, 1 +toyota.com.my, 1 +toyota.com.sg, 1 +toyota.nagoya, 1 +toyotasp.ru, 1 +toyouiv.org, 1 +toypoodlepet.com, 1 +toypro.com, 1 +toys-robots.cf, 1 +toys4education.com.au, 1 +toyschina.cf, 1 +toysearcher.ml, 1 +toysperiod.com, 1 +toysplace.ml, 1 +toystory3.ga, 1 +tozdev.com, 1 +tp-iryuubun.com, 1 +tp-kabushiki.com, 1 +tp-kyouyufudousan.com, 1 +tp-law.jp, 1 +tpark.jp, 1 +tpastream.com, 1 +tpbproxy.co, 1 +tpbunblocked.org, 1 +tpci.biz, 1 +tpiada.tk, 1 +tpidg.us, 1 +tpk-parma.ru, 1 +tpk.wtf, 1 +tpnky.com, 1 +tpolemis.com, 1 +tpp.chat, 1 +tppleague.me, 0 +tpress.tk, 1 +tpro.rocks, 1 +tproger.ru, 1 +tpue.de, 1 +tq.rs, 1 +tqdev.com, 1 +tql.plus, 1 +tqm1.sk, 1 +tr.search.yahoo.com, 0 +tr0n.net, 1 +tr34.ro, 1 +tra-tra.be, 1 +traas.org, 1 +trabajaenvitamina.cl, 1 +trabajarenremoto.com, 1 +trabajarytrabajar.com, 1 +trabajoenmx.com, 1 +trabajouniversitario.tk, 1 +trabbel.org, 1 +trabia.com, 1 +trace.guru, 1 +trace.moe, 1 +traceflix.com, 1 +traceheatinguk.co.uk, 1 +traceroute.guru, 1 +traceroute.link, 1 +traceroute.network, 1 +traces.ml, 1 +tracesteps.ga, 1 +tracetracker.com, 1 +tracetracker.no, 1 +traceur-france.fr, 1 +tracewind.top, 1 +track.plus, 1 +trackchair.com, 1 +tracker-knigi.gq, 1 +tracker.com.ar, 1 +trackerx.ga, 1 +trackeye.dk, 1 +trackify.tk, 1 +tracking-app.tk, 1 +tracking.best, 1 +trackingencomendas.com, 1 +tracknetsports.com, 1 +trackntack.com, 1 +trackrecord.net, 1 +trackrecordpro.co.uk, 1 +trackulo.us, 1 +trackyourlogs.com, 1 +tractarimvbcluj.ro, 1 +tractor-pulling.fr, 1 +tractorfan.nl, 1 +tractorpumps.com, 1 +trad-n-vo.com, 1 +tradagars.se, 1 +tradavenue.com, 1 +trade-arcade.com, 1 +trade-bot.cf, 1 +trade-platform.tk, 1 +trade.gov, 1 +trade247.exchange, 1 +trade360solutions.com, 1 +tradebotcompany.ml, 1 +tradecloud.sg, 1 +tradedesk.co.za, 1 +tradedigital.co, 1 +tradees.com, 1 +tradeinvent.co.uk, 1 +tradelink.cf, 1 +trademarkregistration-coimbatore.com, 1 +trademen.ga, 1 +tradeonfx.com, 1 +traderbot.com.br, 1 +traderepublic.com, 1 +traderinside.ga, 1 +traderjoe-cloud.de, 1 +traderoots.com, 1 +tradersclub.com.br, 1 +tradersport.tk, 1 +tradersrank.ga, 1 +tradeshift.com, 1 +tradeshowfreightservices.com, 1 +tradesoeasy.com, 1 +tradesrenovations.ca, 1 +tradewithestonia.com, 1 +tradezlist.tk, 1 +tradie.com, 1 +tradik.com, 1 +tradinews.com, 1 +tradinews.fr, 1 +tradinghelper.be, 1 +tradingtag.ga, 1 +tradingview.com, 1 +tradingyourownway.com, 1 +tradition-immobilier.com, 1 +traditions.nl, 1 +traditionskapperscollege.nl, 1 +traditionsvivantesenimages.ch, 1 +tradlost-natverk.se, 1 +tradreams.com, 1 +traducir.win, 1 +tradymoney.com, 1 +traefik.io, 0 +traf-bonus.tk, 1 +trafarm.ro, 1 +trafas.nl, 1 +traff1k.net, 1 +trafficgazelles.com, 1 +trafficgenerator.ga, 1 +trafficmanager.com, 1 +trafficmanager.ltd, 1 +trafficmanager.xxx, 1 +trafficmgr.cn, 1 +trafficmgr.net, 1 +trafficologyblueprint.com, 1 +trafficpixel.tk, 0 +trafficsafetymarketing.gov, 1 +trafficsale.cf, 1 +traffixdevices.com, 1 +trafic-wap.tk, 1 +traficmusik.net, 1 +trafik.tk, 1 +trafplus.tk, 1 +tragaver.ga, 1 +tragicallytrumped.com, 1 +tragicempire.tk, 1 +tragmi.ch, 1 +traha.org, 1 +trahnisoseda.tk, 1 +traiectum.es, 1 +trail.pink, 1 +trailblazercommunitygroups.com, 1 +trailblazers.tk, 1 +trailcloud.ink, 1 +trailerparty.com, 1 +trailforks.com, 1 +trainable.cf, 1 +trainex.org, 1 +trainhornforums.com, 0 +trainiac.com.au, 1 +training-eca.eu, 1 +trainingcentral.cf, 1 +traininghamburg.de, 1 +traininglife.org, 1 +trainingminds.nl, 1 +trainingproviderresults.gov, 1 +trainings-handschuhe-test.de, 1 +trainingsalicante.tk, 1 +trainingsecke.de, 1 +trainingswiese.at, 1 +trainline.at, 0 +trainline.cn, 0 +trainline.com.br, 0 +trainline.com.pt, 0 +trainline.cz, 0 +trainline.de, 0 +trainline.dk, 0 +trainline.es, 0 +trainline.eu, 0 +trainline.io, 1 +trainline.it, 0 +trainline.nl, 0 +trainline.no, 0 +trainline.pl, 0 +trainline.se, 0 +trainmagazine.be, 1 +trainmagazine.de, 1 +trainmagazine.nl, 1 +trainme.nl, 1 +trainoclock.com, 1 +trainplaza.be, 1 +trainplaza.net, 1 +trainplaza.nl, 1 +trains.sexy, 1 +trainsgoodplanesbad.com, 0 +traintimes.be, 1 +traintimes.ch, 1 +traintimes.dk, 1 +traintimes.fi, 1 +traintimes.ie, 1 +traintimes.lu, 1 +traintimes.nl, 1 +traintimes.se, 1 +traintowin.tv, 1 +trainwiki.tk, 1 +trainyourtribe.com.au, 1 +traista.ru, 1 +traitement-arthrose.fr, 1 +traiteur-laporte.fr, 1 +traiteurpapillonevents.be, 1 +trajano.net, 1 +trajectfoto.nl, 1 +trajectvideo.nl, 1 +trakid.com, 1 +trakkr.tk, 0 +trakteren.tk, 1 +traktor-troubadour.tk, 1 +tralios.de, 1 +tramadol.ga, 1 +tramadolhcl.ga, 1 +tramclub-basel.ch, 1 +tramikshop.ml, 1 +tran.pw, 1 +trance-heal.com, 1 +trance-heal.de, 1 +trance-heal.me, 1 +trance-zone.tk, 1 +tranceheal.com, 1 +tranceheal.me, 1 +trancehost.com, 1 +trancendances.fr, 1 +trancetronic.com, 1 +trancity.nl, 1 +trandanhland.com, 1 +trangcongnghe.com, 1 +trangell.com, 1 +tranquilityselfcatering.co.za, 1 +tranquillity.se, 1 +tranquilpet.com, 1 +trans-aliyans.tk, 1 +transacid.de, 1 +transaminasas.com, 1 +transappealrights.com, 1 +transcend.org, 1 +transcendmotor.sg, 1 +transcoalition.net, 1 +transcontrol.com.ua, 1 +transcricentro.pt, 1 +transcriptionwave.com, 1 +transdev.blog, 1 +transdevbus.co.uk, 1 +transdyne.com, 1 +transes.com.tr, 1 +transeshairtransplant.com, 1 +transfer.pw, 1 +transferagent.co, 1 +transferbags.com, 1 +transferserver.at, 1 +transfersummit.com, 1 +transfersw.com, 1 +transferwise.jobs, 1 +transferwiseturkiye.com.tr, 1 +transfigurewizard.com, 1 +transfile.fr, 1 +transforleren.nl, 1 +transformaniatime.com, 1 +transformations-magazin.com, 1 +transformersmmdb.tk, 1 +transforumation.com, 1 +transfur.online, 0 +transfurrmation.town, 1 +transgendergedenkdag.nl, 1 +transgenderinfo.nl, 1 +transgendernetwerk.nl, 1 +transgendernetwerk.org, 1 +transglobaltravel.com, 1 +transhumanism.co.uk, 1 +transhumanist.co.uk, 1 +transhumanist.com, 1 +transhumanist.net, 1 +transhumanist.org, 1 +transhumanist.uk, 0 +transito.tk, 1 +transitownplaza.com, 1 +transitpoint.us, 1 +translate-polish.com, 1 +translate.googleapis.com, 1 +translation-services.ga, 1 +translationge.com, 1 +translationsfirm.tk, 1 +translatorall.tk, 1 +translatoruk.co.uk, 0 +translit-net.tk, 1 +translit.ga, 1 +translit.ru, 1 +transmarttouring.com, 1 +transmisjeonline.pl, 1 +transmitit.pl, 1 +transmoni.vn, 1 +transmutatie.nl, 1 +transnexus.com, 1 +transoil.co.uk, 1 +transpak-cn.com, 1 +transparency.cf, 1 +transparencyinadmissions.org, 1 +transparencynj.com, 1 +transparent.cf, 1 +transparentpng.com, 1 +transport-gura-portitei.com, 1 +transporta.it, 1 +transportcomparator.com, 1 +transporterlock.com, 1 +transportfeverfrance.fr, 1 +transportnews.tk, 1 +transservice.net.ua, 1 +transsexualpantyhose.com, 1 +transsrit.tk, 1 +transtrack.net, 1 +transumption.com, 1 +transwank.com, 1 +tranzron.ga, 1 +trapkitchen.ml, 1 +trappednerve.org, 1 +trappersoutfitters.tk, 1 +trapz.xyz, 1 +trarch.com, 1 +trasandino.tk, 1 +trasatsatelital.com.ar, 1 +trash2treasurecreations.co.za, 1 +trashcraft.tk, 1 +trashexpert.ru, 1 +trashnothing.com, 1 +trashwagon.club, 1 +trashylingerie.ga, 1 +trask.no, 1 +traslocare.roma.it, 1 +traslocatore.roma.it, 1 +traslochi-trasporti-facchinaggio.it, 1 +trasloco.milano.it, 1 +trastornoevitacion.com, 1 +trastornolimite.com, 1 +tratamentoparacelulite.net, 1 +tratamientodelvitiligo.es, 1 +trattamenti.biz, 1 +trattamento-cotto.it, 1 +trattamentocotto.roma.it, 1 +trauer-beileid.de, 1 +trauerbegleitung-kudla.de, 1 +trauertexte.info, 1 +traumaheilung.net, 1 +traumarecoverysupport.com, 1 +traumfaenger.tk, 1 +traumschwingen.de, 1 +traumwerker.com, 1 +traut.cloud, 1 +travador.com, 1 +travel-cube.ml, 1 +travel-dealz.de, 1 +travel-rus-club.tk, 1 +travel-to-cuba.tk, 1 +travel101.tk, 1 +travel2macedonia.com, 1 +travel2macedonia.com.mk, 1 +travel2macedonia.mk, 1 +travel365.it, 1 +traveladdiction.tk, 1 +travelamm.com, 1 +travelarmenia.org, 1 +travelassist.us.com, 1 +travelback.ga, 1 +travelbags.be, 1 +travelbags.nl, 1 +travelbangladesh.ga, 1 +travelbiz.cf, 1 +travelcenter.tk, 1 +travelclinic.ml, 1 +travelcompany.tk, 1 +traveleets.com, 1 +travelemy.com, 1 +travelenviro.com, 1 +travelepoch.com, 1 +travelerofcharleston.com, 1 +travelexbiz.com, 1 +travelexinternational.com, 1 +travelfield.org, 1 +travelfoot.com, 1 +travelfriend.tk, 1 +travelgirlsclub.com, 1 +travelholicworld.com, 1 +travelhuge.com, 0 +traveling-thailand.info, 1 +travelinsurance.co.nz, 1 +travelinsurance.ga, 1 +travelix.io, 1 +traveljunkie.tips, 1 +travelknowledge.org, 1 +travellers.dating, 1 +travellets.tk, 1 +travellovers.fr, 1 +travelmademedoit.com, 1 +travelmexico42.com, 1 +travelmontenegro.tk, 1 +travelnews.cf, 1 +travelogue.jp, 1 +travelongravel.tk, 1 +travelook.ml, 1 +travelphilippines.tk, 1 +travelphoto.cc, 1 +travelphotographycourse.com, 1 +travelplugcolombia.com, 1 +travelrefund.com, 1 +travelround.io, 1 +travelsets.com, 1 +travelshack.com, 1 +travelshelper.com, 1 +travelspassion.com, 1 +travelstation.tk, 1 +travelstrokes.com, 1 +travelsuperapp.com, 1 +traveltains.com, 1 +traveltalk.tk, 1 +traveltomachupichu.com, 1 +traveltourist.tk, 1 +traveltovietnam.ga, 1 +travelunicorns.com, 1 +travelus.nl, 1 +travelvisit.cf, 1 +travelwell.io, 1 +travelwithbender.com, 1 +travelwithlocalspecialists.com, 1 +travelwithsearats.com, 1 +travelzoneshop.com, 1 +traverse.com.ua, 1 +travi.org, 1 +travin.tk, 1 +travis.nl, 1 +travisec.com, 1 +travisf.net, 1 +travisforte.io, 1 +travisfranck.com, 1 +travishenning.com, 1 +travkolyl.gq, 1 +travler.net, 1 +travnik24.tk, 1 +travotion.com, 1 +trayvonren.top, 1 +trazodoneonline.tk, 1 +trazodononline.gq, 1 +trbanka.com, 1 +treaslockbox.gov, 1 +treasuredinheritanceministry.com, 1 +treasureislandbeads.ga, 1 +treasurydirect.gov, 1 +treasuryhunt.gov, 1 +treasuryscams.gov, 1 +treatment.org, 1 +treatmentindiana.com, 1 +treatyoself.com.au, 1 +trebek.club, 1 +trebilfoundationsystems.com, 1 +trebnie.nl, 1 +trechosemilhas.com.br, 1 +tree0.xyz, 1 +treebaglia.xyz, 1 +treefeelingsandton.co.za, 1 +treefelling-durban.co.za, 1 +treehole.life, 0 +treehorn.nl, 1 +treehousebydesign.com, 1 +treehouseresort.nl, 1 +treemadeiras.com.br, 1 +treeremovalspretoria.co.za, 1 +treering.com, 1 +treeschat.com, 1 +treestarmarketing.com, 1 +treestumpgrindingnearme.com, 1 +treevectors.com, 1 +treeworkbyjtec.com, 1 +treezone.net, 1 +trefcon.cz, 1 +trefle.io, 1 +trefpuntdemeent.nl, 1 +treinaweb.com.br, 0 +treinmagazine.be, 1 +treinmagazine.nl, 1 +treinonerd.com, 1 +treinonline.tk, 1 +treintijden.com, 1 +trek-planet.ru, 1 +treker.us, 1 +trekfriend.com, 1 +trekintel.com, 1 +trekking-friends.ch, 1 +trekmeshes.ch, 1 +trekonbh.com, 1 +trelki.de, 1 +treml-sturm.com, 1 +tremol-spedition.com, 1 +trendingaffords.com, 1 +trendingdeals.ga, 1 +trendingeducation.tk, 1 +trendkraft.de, 1 +trendme.ga, 1 +trendntech.com, 1 +trendocracy.cf, 1 +trendparty.net, 1 +trendreportdeals.com, 1 +trends-news.tk, 1 +trends2day.com, 1 +trendsettersre.com, 1 +trendsuites.co, 1 +trendus.no, 1 +trendycrowds.com, 1 +trendydips.com, 1 +trendyindi.com, 1 +trendykids.cz, 1 +trenorario.it, 1 +trenta.fr, 1 +trentinogenealogy.com, 1 +trentonmakesnews.com, 1 +trentonoh.gov, 1 +trenztec.ml, 1 +trepare.com, 1 +tresen-demo.com, 1 +tresmaistres.com.br, 1 +tresor.it, 1 +tresorit.com, 1 +tresorsecurity.com, 1 +trespassing.com, 1 +trespedia.com, 1 +tresredatores.tk, 1 +tretail.net, 1 +tretkowski.de, 1 +treurtransport.tk, 1 +trevacez.com, 1 +trevo-lotofacil.com.br, 0 +trevsanders.co.uk, 1 +trezor.io, 1 +trezy.me, 1 +trezy.net, 1 +trhastane.com, 1 +triage.ai, 1 +triage.clinic, 1 +triage.com, 1 +triage.md, 1 +triageclinic.com, 1 +triageforensic.com, 1 +trial-server.tk, 1 +trialandsuccess.nl, 1 +trialbyfire.tk, 1 +trialcentralnet.com, 1 +trialmock.com, 1 +trials.tk, 1 +triangela.com, 1 +triangela.se, 1 +triangle-energie.com, 1 +trianglecastles.co.uk, 1 +trianglelawngames.com, 1 +trianglepwh.com, 1 +trianon.xyz, 1 +tribac.de, 1 +tribaldos.com, 0 +tribaljusticeandsafety.gov, 1 +triballi.com.br, 1 +tribalwarsstyles.tk, 1 +tribalzone.tk, 1 +tribe.rs, 1 +tribealive.com, 1 +tribeoftomorrow.co, 1 +tribetrails.com, 1 +tribistovo.tk, 1 +tribly.de, 1 +tribunalinternacional.tk, 1 +tribut.de, 1 +tributh.cf, 1 +tributh.ga, 1 +tributh.gq, 1 +tributh.ml, 1 +tributh.net, 1 +tributh.tk, 1 +tributoconsuegra.tk, 1 +tricare.mil, 1 +tricefy4.com, 1 +tricetirisad.me, 1 +trichdanhay.com, 1 +triciaree.com, 1 +tricitiesprinter.com, 1 +tricityhelpline.com, 1 +trickedguys.com, 1 +trickle.works, 1 +tricksforgreeks.com, 1 +trico-pigmentazione.it, 1 +tricolortotal.tk, 1 +tricordmedia.ca, 1 +tricountyathome.com, 1 +tricountyheatingcooling.com, 1 +triddi.com, 1 +tridena.com, 1 +trident-online.de, 1 +trident1000logoi.gr, 1 +tridentmedia.gq, 1 +tridnice.eu, 1 +triedandtruebytrista.com, 1 +triefenbach.com, 1 +triefenbach.eu, 1 +trietment.com, 0 +trifence.ch, 1 +trigardon-rg.de, 1 +trigate.io, 1 +triggeredpaintz.com, 1 +trigi.net, 1 +trigraph.net, 1 +trigular.de, 1 +trihedron.tk, 1 +trihunter6000.com, 1 +trik-komputer.tk, 1 +trik.es, 0 +triker.tk, 1 +trilithsolutions.com, 1 +trillian.im, 1 +trilliumvacationrentals.ca, 1 +trilogyforce.com, 1 +triluxds.com, 1 +trim-a-slab.com, 1 +trim21.cn, 1 +trimage.org, 1 +trimental.de, 1 +trimtone.com, 1 +trinary.ca, 0 +trinary.tk, 1 +trindonball.com, 1 +trineco.cloud, 1 +trineco.com, 1 +trineco.fi, 1 +trinetus.com, 1 +tringavillasyala.com, 1 +trinhtrongson.tk, 1 +trinitasgyor.hu, 1 +trinitycore.org, 1 +trinitycorporateservices.com, 1 +trinityny.org, 1 +trinityradioandvideo.org, 1 +trinitysurfaces.com, 1 +trink-und-partyspiele.de, 1 +trinnes.net, 1 +trinstadab.se, 1 +trio.online, 1 +triop.se, 1 +triozon.hu, 1 +trip.my, 1 +tripartie.com, 1 +triplejprints.com, 1 +triplekeys.net, 1 +triplepointliquidity.com, 1 +triplesixdesigns.com, 1 +triplethreatband.tk, 1 +triplevision.nl, 1 +triplicate.gq, 1 +triploqal.com, 1 +tripolinews.tk, 1 +tripolistars.com, 1 +tripomanija.tk, 1 +tripoutside.com, 1 +tripp.xyz, 1 +trippen.travel, 1 +tripsided.com, 1 +tripsinc.com, 1 +tripsvia.com, 1 +tripsweet.com, 1 +triptnyc.com, 1 +trisect.uk, 1 +trish-mcevoy.ru, 1 +trisha.tk, 1 +trissiethehusky.rocks, 1 +tristanfarkas.one, 1 +tristanhager.i234.me, 1 +trit.pro, 1 +tritium.cf, 1 +tritiumdisposal.com, 1 +trixati.org.ua, 1 +trixiebooru.org, 1 +triz.co.uk, 1 +trizone.com.au, 1 +trkhosting.ga, 1 +trkpuls.tk, 1 +trmgo.de, 1 +troc.co.il, 1 +trockendock.ch, 1 +trodat.cf, 1 +trodniescis.gq, 1 +troedel-trolle.de, 1 +troedelhannes.at, 1 +troi.de, 1 +troiaconsultoria.com.br, 1 +troianet.com.br, 1 +trojan-e.org, 1 +trojanchronicles.tk, 1 +trojanherring.com, 1 +trok.co.il, 1 +troll-gaming.tk, 1 +trollbox.fun, 1 +trolldesign.cf, 1 +trolldi.eu.org, 1 +trollforums.gq, 1 +trollhanttan.tk, 1 +trolling.gq, 1 +trollingeffects.org, 1 +trollmoa.se, 1 +trollolo.tk, 1 +trollos.cf, 1 +trollos.ga, 1 +trollos.gq, 1 +trollscave.xyz, 1 +trommelwirbel.com, 1 +tronghoanggia.vn, 1 +tronika.no, 1 +tronlaserarena.cz, 1 +tronmeo.com, 1 +tronnews.best, 1 +tronnews.co, 1 +tronnews.global, 1 +tronnews.life, 1 +tronnews.live, 1 +tronnews.me, 1 +tronnews.net, 1 +tronnews.news, 1 +tronnews.world, 1 +tronnews.xyz, 1 +troomcafe.com, 1 +troop89medfield.org, 1 +troopaid.info, 1 +trophcomplewin.ml, 1 +trophee-discount.com, 1 +trophies.de, 1 +trophy-discount.com, 1 +trophykoi.tk, 1 +trophyshopinc.com, 1 +tropicalserver.com, 1 +tropicalticket.ml, 1 +tropicaltravelco.com, 1 +tropikdeniz.com.tr, 1 +tropiweb.tk, 1 +troplo.com, 1 +troqueladoras.online, 1 +trosell.net, 1 +trosinenko.com, 1 +tross.tk, 1 +trotec.com, 1 +trotina.cz, 1 +trotter.cf, 1 +trottnersauto.com, 1 +troubles.ru, 1 +troubleshooter.xyz, 1 +troupcountyga.gov, 1 +trousers.co.uk, 1 +trouver-son-chemin.com, 1 +trouvons.org, 1 +trouweninoverijssel.nl, 1 +trovaprezzi.it, 1 +troxal.com, 1 +troyfawkes.com, 1 +troyhunt.com, 1 +troyhuntstress.com, 1 +troyhuntstressed.com, 1 +troyhuntsucks.com, 1 +troyjanda.com, 1 +trpa.gov, 1 +trpg.wiki, 1 +trpl.host, 1 +trs.tn, 1 +tru.ltd, 1 +trubmet.tk, 1 +trubos.com.ua, 1 +trucchibellezza.com, 1 +trucchibellezza.it, 1 +truccoshop.com, 1 +truckercheckin.com, 1 +truckerjobusa.com, 1 +truckersmp.com, 1 +truckscout24.at, 1 +truckscout24.be, 1 +truckscout24.com, 1 +truckscout24.cz, 1 +truckscout24.de, 1 +truckscout24.es, 1 +truckscout24.fr, 1 +truckscout24.hu, 1 +truckscout24.it, 1 +truckscout24.nl, 1 +truckscout24.pl, 1 +truckscout24.ru, 1 +truckshina-plus.com.ua, 1 +trucosdescargas.com, 1 +true-360.com, 1 +true-itk.de, 1 +trueachievements.com, 1 +trueassignmenthelp.co.uk, 1 +truebluedriver.com, 1 +truecosmeticbeauty.com, 0 +truecosmos.com, 1 +truedarkness.tk, 1 +trueduality.net, 1 +truegunvalue.com, 1 +truehealthreport.com, 1 +truekey.com, 1 +truelovesakuya.info, 1 +trueminecraft.com, 1 +truendo.com, 1 +truenorthseedbank.com, 1 +truentumvet.it, 1 +trueproxy.net, 1 +truereligionjeanstore.tk, 1 +truerizm.ru, 1 +trueseeing.com, 1 +truessl.shop, 1 +truesteamachievements.com, 1 +truestor.com, 1 +truetraveller.com, 1 +truetrophies.com, 1 +truewateraustralia.com, 1 +trueweb.es, 1 +trufflemonkey.co.uk, 1 +trufflepig-forensics.com, 1 +truhlarstvi-fise.cz, 1 +trulock.tk, 1 +truly-madly-happiness.de, 1 +trulycharmed.tk, 1 +trumanlibrary.gov, 1 +trumanlibrary.org, 1 +trumk.com, 1 +trummer.xyz, 1 +trumplibrary.gov, 1 +trumppresidency.org, 1 +trumptragedy.com, 1 +trumptragic.com, 1 +trumpwhitehouse.gov, 1 +trumtrimun.com, 1 +truncus-encephali.co.uk, 1 +trundr.com, 1 +trungvien.vn, 1 +trunk-show.net, 1 +truong.fi, 1 +truphaegourmet.com, 1 +truqu.com, 1 +truserve.org, 1 +trusifan.tk, 1 +trusitio.com, 1 +trussgenius.com, 1 +trust-btc.ml, 1 +trustcase.com, 1 +trustcert.net, 1 +trustcert.org, 1 +trustech.co.in, 0 +trustednetworks.nl, 1 +trustedtoolbox.com, 1 +trustee.deals, 1 +trustees.org, 1 +trustfield.ch, 0 +trusthook.tk, 1 +trustnet.co.il, 1 +trustology.io, 1 +trustserv.de, 1 +trustvox.com.br, 1 +truten.tk, 1 +truth.tk, 1 +truthdancer.com, 1 +truthlost.com, 1 +truthmessages.pw, 1 +truthsayer.tk, 1 +truthserum.co, 1 +trutopoffer.com, 1 +truvayangin.tk, 1 +truvisory.com, 1 +truxton.tk, 1 +truyenfull.vn, 1 +trw-reseller.com, 1 +trxnews.today, 1 +try2admin.pw, 1 +try2hack.it, 1 +try2services.cm, 1 +try2services.vc, 1 +trybabyschoice.com, 1 +trybooking.com, 1 +trycaviar.com, 1 +trychameleon.com, 1 +trydoggo.com, 1 +tryfabulousdiet.com, 1 +tryfabulousskincream.com, 1 +tryfabulousskinserum.com, 1 +tryfrontline.cloud, 1 +trygarciniaslimdiet.com, 1 +tryhard.cz, 1 +tryhexadecimal.com, 1 +tryin.cz, 1 +tryingtotakeoversweden.tk, 1 +tryingtotakeovertheworld.tk, 1 +tryitonline.net, 1 +tryk.tk, 1 +tryknow.com, 1 +trymegadrol.com, 1 +tryndraze.com, 1 +trynowrinkleseyeserum.com, 1 +trynta.com, 1 +trynta.net, 1 +tryonnc.gov, 1 +trypathnow.com, 1 +trypenspinning.com, 1 +tryplo.ca, 1 +tryplo.com, 1 +tryplo.io, 1 +tryplo.net, 1 +tryplo.org, 1 +tryplo.xyz, 1 +trypt.am, 1 +tryptamine.tk, 1 +tryreason.com, 1 +tryti.me, 1 +tryupdates.com, 1 +trywesayyes.com, 1 +trz.cz, 1 +ts-folienmontage.de, 1 +ts-public.tk, 1 +ts-publishers.com, 1 +ts3-legenda.tech, 1 +ts3.gs, 0 +ts3.ink, 0 +ts5server.eu, 1 +tsa-sucks.com, 1 +tsacareer.com, 1 +tsacbttest.com, 1 +tsachs.eu, 1 +tsacloud.ml, 1 +tsahf.com, 1 +tsai.com.de, 1 +tsakalian.gr, 1 +tsakanakis.tk, 1 +tsaro.io, 1 +tsatestprep.com, 1 +tschuermans.be, 0 +tscinsurance.com, 1 +tscomputers.net.pe, 1 +tscripts.com, 1 +tsdom.net, 1 +tsedryk.ca, 1 +tsentrobuv.tk, 1 +tsenv.net, 1 +tsgbit.net, 1 +tsgkc1.com, 1 +tshirtgenerator.ga, 1 +tshirtmemoryquilts.com, 1 +tshirtscapetown.com, 1 +tsicons.com, 1 +tsigaradiko.com, 1 +tsiolakisfurs.com, 1 +tsironis-olivenoel.de, 1 +tsja.tk, 1 +tsk.ovh, 1 +tsla.nu, 1 +tslcontractors.co.uk, 1 +tsmgroup2.biz, 1 +tsmost.cz, 1 +tsontes.online, 1 +tsp.gov, 1 +tspdrits.xyz, 1 +tsproesasac.com, 1 +tsr.best, 1 +tsriggingequipment.com, 1 +tsrv.pw, 0 +tss.am, 1 +tstrubberstamp.com, 0 +tsu.re, 1 +tsueri.cloud, 1 +tsukhani.com, 1 +tsukuba.style, 0 +tsumegumi.com, 1 +tsumi.it, 1 +tsumi.moe, 1 +tsunami.gov, 1 +tsunamic.cf, 1 +tsundere.moe, 1 +tsura.org, 1 +tsurai.work, 1 +tsurimap.com, 1 +tsuruhime.tk, 1 +tsutawal.com, 1 +tsutsumi-kogyo.jp, 1 +tsuyuzakihiroyuki.com, 1 +tt-hardware.com, 1 +tt0766.com, 1 +tt0966.com, 1 +tt2866.com, 1 +tt2966.com, 1 +tt3666.com, 1 +tt3699.com, 1 +tt3766.com, 1 +tt3999.com, 1 +tt5197.co, 1 +tt6729.co, 1 +tt6729.com, 1 +tt6957.co, 1 +tt7199.com, 1 +tt7299.com, 1 +tt7399.com, 1 +tt8166.com, 1 +tt8266.com, 1 +tt8366.com, 1 +tt918.com, 1 +tt9297.co, 1 +tt9397.com, 1 +tt9721.com, 1 +tt9728.co, 1 +tt9799.com, 1 +ttb.gov, 1 +ttbonline.gov, 1 +ttc-birkenfeld.de, 1 +ttcaarberg.ch, 1 +ttcak.ddns.net, 1 +ttcf.ca, 1 +ttchan.org, 1 +ttclub.fr, 1 +ttcmed.com, 1 +ttfin.ch, 1 +ttja.ee, 1 +ttlet.com, 1 +ttlg.io, 1 +ttnmpls.org, 1 +ttp-shop.com.ua, 1 +ttr-home.com, 1 +ttrade.ga, 1 +tts-assessments.com, 1 +tts.co.nz, 0 +ttscompliancesuite.com, 1 +ttsoft.pl, 1 +ttspttsp.com, 1 +ttsuaevisas.com, 1 +ttsweb.org, 1 +ttt-networks.com, 1 +ttuwiki.ee, 1 +ttuwiki.org, 1 +ttwoee.com, 1 +ttwt.com, 1 +ttwtrader.com, 1 +tty.space, 1 +tty1.net, 1 +ttyystudio.com, 1 +ttz.im, 1 +tu-immoprojekt.at, 1 +tu6.pm, 1 +tualiadaenlimpieza.com, 1 +tuang-tuang.com, 1 +tuasaude.com, 1 +tubach.org, 1 +tubanten.nl, 1 +tube.tools, 1 +tubebegana.com, 1 +tubedesire.com, 1 +tubejack.nl, 1 +tubeju.com, 1 +tubepornmovies.net, 1 +tubepro.de, 1 +tubepro.net, 1 +tubeview.ga, 1 +tubing.cf, 1 +tubs4fun.co.uk, 1 +tubul.net, 1 +tubus.tk, 1 +tubuscadordeempleo.com, 1 +tucarora.tk, 1 +tucasacanadevi.com.mx, 1 +tucepihotelalga.com, 1 +tucidi.net, 1 +tucker.wales, 1 +tuckhayward.art, 1 +tuckmeintebo.com, 1 +tucnak.eu, 1 +tucny.com, 1 +tucoladaperfecta.es, 1 +tucsonfcu.com, 1 +tucsonpcrepair.com, 1 +tucuatro.com, 1 +tucuxi.org, 1 +tudorproject.org, 1 +tudorrosesamplerguild.com, 1 +tudosobrehost.com.br, 1 +tuempleosolucion.com, 1 +tueplay.host, 1 +tuerkei-immobilien.tk, 1 +tuestilo.nl, 1 +tuev-hessen.de, 1 +tufelicitacion.info, 1 +tuffclassified.com, 1 +tuffmail.com, 1 +tuffmail.net, 1 +tuffsruffs.se, 1 +tufilo.com, 0 +tugafm.eu.org, 1 +tugesha.com, 1 +tuimprenta.com.ar, 1 +tuinaportugal.com, 1 +tuincentersnaet.be, 1 +tuinenvermeiren.be, 1 +tuingereedschappen.net, 0 +tuitle.com, 1 +tuja.hu, 1 +tujardin.casa, 1 +tujunfang.com, 1 +tukaraokeonline.com, 1 +tukdesigns.com, 1 +tukebab.com, 1 +tuketicihaklari.net, 1 +tula-city.tk, 1 +tula-news.ga, 1 +tulana.ga, 1 +tulevaisuusdemarit.fi, 1 +tuliha.ga, 1 +tulikajain.cf, 1 +tulippublishing.com.au, 1 +tuller.tk, 1 +tully.co.uk, 1 +tulocura.tk, 1 +tulsameetingroom.com, 1 +tulsaworkshop.org, 1 +tulumplayarealestate.com, 1 +tumagiri.net, 1 +tumarcafe.com, 1 +tumbaga.world, 1 +tumblenet.tk, 1 +tumblr.com, 1 +tumedico.es, 1 +tumelum.de, 1 +tumen.cf, 1 +tumen.gq, 1 +tumen.ml, 1 +tumen.tk, 1 +tumentorweb.com.mx, 1 +tumult-productions.tk, 1 +tun.bible, 1 +tunaut.com, 1 +tune-web.de, 1 +tunefish-entertainment.de, 1 +tunen.cf, 1 +tunenet.ml, 1 +tuneotune.com, 1 +tuner.cloud, 1 +tungstenworld.com, 1 +tuning-parts24.de, 1 +tuning-werkstatt-nuernberg.de, 1 +tuningblog.eu, 0 +tunisiadefnews.ga, 1 +tunisiangamers.tk, 1 +tunisiapress.tk, 1 +tunnelbear.com, 1 +tunnelblick.net, 1 +tunnelbroker.net, 1 +tunnelstore.net, 1 +tunnelventilation.pro, 1 +tunnelwatch.com, 1 +tunningcars.tk, 1 +tunochebuena.com, 1 +tuntitili.fi, 1 +tuol-sleng.tk, 1 +tuoni.ga, 1 +tuotteet.org, 1 +tuou.xyz, 0 +tupa-germania.ru, 1 +tupahost.net.br, 1 +tupass.pw, 1 +tupatane.gq, 1 +tupeuxpastest.ch, 0 +tupianku.com, 1 +tupizm.com, 1 +tupoema.info, 1 +tuppenceworth.ie, 1 +tupperwaresalamanca.com, 1 +turadionline.cf, 1 +turalt.com, 1 +turanga.tk, 1 +turbaza.tk, 1 +turbinelectricity.ga, 1 +turbo.az, 1 +turbo24.com, 1 +turbohostingcolombia.com, 1 +turbomag.pl, 1 +turbotube.ga, 1 +turbowheels.biz, 1 +turboworld.tk, 1 +turciya.cf, 1 +turdnagel.com, 1 +turf-experts.com, 1 +turfirm.tk, 1 +turi.space, 1 +turigum.com, 1 +turiscar.pt, 1 +turismodubrovnik.com, 1 +turismogdl.com, 1 +turismoliliana.tk, 1 +turismonochile.com, 1 +turismonochile.com.br, 1 +turizm.gq, 1 +turizm.tk, 1 +turizmsektoru.tk, 1 +turkana.tk, 1 +turkcechat.tk, 1 +turkey-portal.tk, 1 +turkeyfiles.tk, 1 +turkface.tk, 1 +turkgrafik.tk, 1 +turkhalkmuzigi.tk, 1 +turkiet.guide, 1 +turkish.dating, 1 +turkishhackers.tk, 1 +turkishyatirim.com, 1 +turkist.tk, 1 +turkistan-rap.tk, 1 +turkkarate.tk, 1 +turkmanbox.tk, 1 +turkmannews.tk, 1 +turkmans.tk, 1 +turkmen.news, 1 +turkmenbusiness.tk, 1 +turkmenistanairlines.tm, 1 +turkmistress.tk, 1 +turkrap.tk, 1 +turkreno.com, 1 +turkrock.com, 1 +turksite.tk, 1 +turksiteleri.tk, 1 +turkteam.tk, 1 +turktelekomarenagolleri.tk, 1 +turkup.ml, 1 +turl.pl, 1 +turlewicz.pl, 1 +turn-sticks.com, 1 +turnbacktogod.com, 1 +turncircles.com, 1 +turnet.tk, 1 +turnierplanung.com, 1 +turnningpoint.xyz, 1 +turnoffthelights.com, 1 +turnoffthelights.video, 1 +turnonsocial.com, 1 +turnosinscripcionchascomus.site, 1 +turnout.rocks, 1 +turnover.cf, 1 +turobot.casa, 1 +turpinpesage.fr, 1 +tursiae.org, 1 +turteka.com, 1 +turtledigital.co.uk, 1 +turtleduckstudios.com, 1 +turtlehead.tk, 1 +turtlepay.io, 1 +turtles.ga, 1 +turtunis.ml, 1 +turul.tk, 1 +turunculevye.com, 1 +turystyczny-system.pl, 1 +tus-kikishinkyo.jp, 1 +tusar.ga, 1 +tusas.com, 1 +tuscanyleather.it, 0 +tusconsultorex.com, 1 +tusfinanzas.ec, 1 +tusharwalaskar.com, 1 +tusi.co, 1 +tusierra.com, 1 +tusksol.com, 1 +tusmedicamentos.com, 1 +tusociofinanciero.com, 1 +tusoluciondeempleo.com, 1 +tuspiscinas.com, 1 +tusupermercado.pe, 1 +tut-kino.tk, 1 +tuta.pm, 1 +tutamail.com, 1 +tutanota.com, 1 +tutanota.de, 1 +tutdevki.tk, 1 +tutiendadebdsm.com, 1 +tutierra.net, 1 +tutima.com, 1 +tuto-craft.com, 1 +tutoragency.org, 1 +tutorcruncher.com, 1 +tutorial90.cf, 1 +tutorialcoding.ga, 1 +tutorialcoding.tk, 1 +tutorialdb.tk, 1 +tutorialehtml.com, 1 +tutorialforest.com, 1 +tutorialinux.com, 1 +tutorialitmalaysia.tk, 1 +tutorialphotoshop.tk, 1 +tutorialseo.com.br, 1 +tutorio.ga, 1 +tutormedia.net, 1 +tutorsheetstore.com, 1 +tuts4you.com, 1 +tuttimundi.org, 0 +tuttonotizie.eu, 1 +tutu.green, 1 +tutu.ro, 1 +tuulialaine.com, 1 +tuvankinhdoanhonline.com, 1 +tuversionplus.com, 1 +tuvingaynay.com, 1 +tuwaner.com, 1 +tuxcloud.net, 1 +tuxflow.de, 0 +tuxforums.com, 1 +tuxgeo.com, 0 +tuxhound.org, 1 +tuxie.com, 1 +tuxlife.net, 1 +tuxmobil.cf, 1 +tuxpeliculas.com, 1 +tuxpi.com, 1 +tuxplace.nl, 1 +tuxsoul.com, 1 +tuxsrv.com, 1 +tuxtimo.me, 1 +tuza.com.au, 1 +tuzaginside.com, 1 +tuzagtcs.com, 1 +tuzaijidi.com, 1 +tuzlasite.tk, 1 +tuzor.com, 1 +tv-mainzlar.de, 1 +tv-programme.be, 1 +tv-programme.com, 1 +tv-sports.fr, 1 +tv-tuners.cf, 1 +tv-zone.tk, 1 +tv.kg, 1 +tv2vie.org, 0 +tvabullarbro.tk, 1 +tvaerialsmanchester.com, 1 +tvbaratas.net, 1 +tvbracketman.co.uk, 1 +tvcal.net, 1 +tvchannelslive.tk, 1 +tvcmarketing.com, 1 +tvdate.ru, 1 +tvdates.info, 1 +tvenligne.tk, 1 +tver-msk.ru, 1 +tver2000.tk, 1 +tver69.tk, 1 +tveronline.tk, 1 +tves.gob.ve, 1 +tvfans.tk, 1 +tvfcu.com, 1 +tvhshop.be, 1 +tview.co.uk, 1 +tvipper.com, 1 +tvlanguedoc.com, 1 +tvleaks.se, 1 +tvmice.tk, 1 +tvmounting-houston.com, 1 +tvnow.de, 1 +tvoedelo.ml, 1 +tvoia-dietka.tk, 1 +tvoistatusy.tk, 1 +tvoistili.ml, 1 +tvoyaknighka.ga, 1 +tvoysad.ru, 0 +tvplusiptv.com, 1 +tvquot.es, 1 +tvrestyler.eu, 1 +tvreviewer.tk, 1 +tvs-virtual.cz, 1 +tvseasons.tk, 1 +tvseries.info, 1 +tvsheerenhoek.nl, 1 +tvtorcedor.com.br, 1 +tvzahist.com.ua, 1 +tvzr.com, 1 +tw.search.yahoo.com, 0 +twaddler.cf, 1 +twainhartehotels.com, 1 +twakkensi.cf, 1 +twatspot.com, 1 +twb.berlin, 1 +twd2.me, 1 +twd2.net, 0 +twdreview.com, 1 +twdtulelo.hu, 1 +tweak.group, 1 +tweakers.com.au, 1 +tweakers.net, 1 +tweakersbadge.nl, 1 +tweaktown.com, 1 +tweaktownforum.com, 1 +tweekshow.tk, 1 +tweeple.ga, 1 +tweetfinity.com, 1 +tweetfinityapp.com, 1 +twelve.rocks, 1 +twelve.today, 1 +twelvecolonies.tk, 1 +twelvecornerspediatrics.com, 1 +twem.ddns.net, 1 +twfwd.email, 1 +twidy.jp, 1 +twidy.uk, 1 +twigandolive.com, 1 +twilightcookies.ca, 1 +twilightningzone.tk, 1 +twilightscans.com, 1 +twilite.co.uk, 1 +twilite.uk, 1 +twilleys.com, 1 +twilo-host.de, 1 +twilo.de, 1 +twincitynissantxparts.com, 1 +twinfield-apps.nl, 1 +twinkseason.com, 1 +twinztech.com, 1 +twiri.net, 1 +twisata.com, 1 +twistdevelopment.co.uk, 1 +twisted-brains.org, 1 +twistedwave.com, 1 +twistertech.com.br, 1 +twistfix.co.uk, 1 +twistgeschenken.nl, 1 +twisto.cz, 1 +twisto.pl, 1 +twit-guide.com, 1 +twitchplaysleaderboard.info, 1 +twitcker.com, 1 +twittelzie.nl, 1 +twitter.ax, 1 +twitter.com, 0 +twitterdriver.io, 1 +twitteroauth.com, 1 +twizzle.net, 1 +twjeih.com, 1 +twl-clan.tk, 1 +twlan.org, 1 +twlitek.com.tw, 1 +twmartin.codes, 1 +two-step-verification.solutions, 1 +twoandahalfvan.eu, 1 +twoanime.com, 1 +twobitbusker.com, 1 +twocatsinacaravan.xyz, 1 +twocornertiming.com, 1 +twodadsgames.com, 1 +twoef.co.uk, 1 +twohuo.com, 1 +twojajurata.pl, 1 +twojapogoda.pl, 1 +twojfaktum.pl, 1 +twolinesmedia.eu, 1 +twonodes.games, 0 +tworaz.net, 1 +twotube.ie, 1 +twtr.email, 1 +twtremind.com, 1 +twun.io, 1 +twwd.de, 1 +tx299.com, 1 +tx577.com, 1 +txcap.org, 1 +txdivorce.org, 1 +txferretrescue.org, 1 +txi.su, 1 +txlocksmiththewoodlands.com, 1 +txlrs.org, 1 +txm.pl, 1 +txpi.nsupdate.info, 1 +txtd.io, 1 +txtdb.com, 1 +txtdirect.com, 1 +txtdirect.dev, 1 +txtdirect.io, 1 +txtdirect.link, 1 +txtdirect.me, 1 +txtdirect.org, 1 +txtentertainment.ga, 1 +txtfile.eu, 1 +txtnovel.me, 1 +txtnovel.net, 1 +txurologist.com, 1 +txwriterstudio.com, 1 +txyz.xyz, 1 +ty0m.com, 1 +ty513.com, 1 +ty529.com, 1 +ty561.com, 1 +ty573.com, 1 +ty583.com, 1 +ty587.com, 1 +ty593.com, 1 +ty5998.com, 1 +ty613.com, 1 +ty637.com, 1 +ty650.com, 1 +ty679.com, 1 +ty705.com, 1 +ty715.com, 1 +ty716.com, 1 +ty723.com, 1 +ty736.com, 1 +ty739.com, 1 +ty756.com, 1 +ty7788.cc, 1 +ty783.com, 1 +ty785.com, 1 +ty791.com, 1 +ty793.com, 1 +ty812.com, 1 +ty835.com, 1 +ty853.com, 1 +ty857.com, 1 +ty927.com, 1 +ty935.com, 1 +ty937.com, 1 +ty953.com, 1 +ty962.com, 1 +ty965.com, 1 +ty980.com, 1 +tyc001.cc, 1 +tyc009.cc, 1 +tyc923.com, 1 +tyche.io, 1 +tycho.org, 1 +tycho.tk, 1 +tychoverstraete.be, 1 +tycyc88.com, 1 +tycycles.co.uk, 1 +tygochrum.se, 1 +tyinnovations.com, 1 +tykeplay.com, 1 +tykoon.com, 1 +tyl.io, 1 +tyler.rs, 1 +tylerdavies.net, 1 +tylerdurden.ml, 1 +tylerharcourt.ca, 1 +tylerharcourt.com, 1 +tylerharcourt.net, 1 +tylerharcourt.org, 1 +tylermade.net, 1 +tyleromeara.com, 1 +tylerschmidtke.com, 1 +tylertysdal.com, 1 +tylervigario.com, 1 +tylko-wazne.tk, 1 +tymoch.pl, 1 +tynefm.tk, 1 +tyni-goc.gq, 1 +tyni-gof.gq, 1 +tyojyu.or.jp, 1 +type1joe.com, 1 +type1joe.net, 1 +type1joe.org, 1 +typeblog.net, 1 +typecheck.io, 1 +typecho.site, 1 +typeclasses.com, 1 +typecodes.com, 1 +typehub.net, 1 +typeof.pw, 1 +typeonejoe.com, 1 +typeonejoe.net, 1 +typeonejoe.org, 1 +typeria.net, 1 +typesofdogs.info, 1 +typetwodiabetesexplained.com, 1 +typewolf.com, 1 +typica.com.tw, 1 +typing.com, 1 +typingcheck.ga, 1 +typist.tech, 1 +typo3.com, 1 +tyr0wl.com, 1 +tyraga.ga, 1 +tyrannize.us, 1 +tyre-search.ga, 1 +tyree.tech, 1 +tyres-price.com, 1 +tyrkey.tk, 1 +tyroola.com.au, 1 +tyroremotes.co.uk, 1 +tyroremotes.es, 1 +tyroremotes.eu, 1 +tyroremotes.fr, 1 +tyroremotes.nl, 1 +tyroremotes.no, 1 +tyroremotes.pt, 1 +tyroremotes.se, 1 +tysox.de, 1 +tysukakorrekt.ga, 1 +tysye.ca, 1 +tytixazo.tk, 1 +tytod.com, 1 +tyumen.ga, 1 +tyuning-avto.tk, 1 +tyva.gq, 1 +tyva.ml, 1 +tyva.tk, 1 +tzifas.com, 1 +tziyona.net, 1 +tzonevrakis.gr, 1 +tzsec.com, 1 +tzunami.tk, 1 +tzunamiblog.tk, 1 +tzwe.com, 1 +tzyingshi.com, 0 +u-chan.com, 1 +u-grow.gr, 1 +u-he.com, 1 +u-page.nl, 1 +u.nu, 1 +u00228.com, 1 +u0070.com, 1 +u03.fr, 1 +u1100.com, 1 +u1144.com, 1 +u175.com, 1 +u29dc.com, 0 +u2b.eu, 1 +u2fanlife.com, 1 +u2fsecuritykeys.com, 1 +u30365.com, 1 +u36533.com, 1 +u4.re, 1 +u4mh-dev-accesscontroller.azurewebsites.net, 1 +u4mh-dev-portal.azurewebsites.net, 1 +u5.re, 1 +u51365.com, 1 +u5197.co, 1 +u5b.de, 0 +u5r.nl, 1 +u6729.co, 1 +u6729.com, 1 +u6957.co, 1 +u6957.com, 1 +u81365.com, 1 +u82365.com, 1 +u9297.co, 1 +u9397.com, 1 +u9721.com, 1 +u9728.co, 1 +u9yy.net, 1 +ua-autonews.tk, 1 +ua-news.tk, 1 +ua.search.yahoo.com, 0 +ua5v.com, 1 +uachemlabs.com, 1 +uae-company-service.com, 1 +ualove.tk, 1 +uamxsociologia.tk, 1 +uanews.tk, 1 +uapp.win, 1 +uareferat.tk, 1 +uasmi.com, 1 +uat-activesg.com, 1 +uat-mypfp.co.uk, 1 +uateach.tk, 1 +uatgootax.ru, 0 +uatx.mx, 1 +uawoptout.com, 1 +ub3rk1tten.com, 0 +ub889.com, 1 +uba-tra.tk, 1 +ubanks.com.ua, 1 +ubanquity.com, 0 +ubberup.dk, 1 +ubcani.com, 1 +ubcutah.com, 1 +uber-work.tk, 1 +uberactivist.com, 1 +uberalles.live, 1 +uberboxen.net, 1 +ubereatsprinters.com, 1 +uberestimator.com, 1 +uberhorny.tk, 1 +uberi.fi, 1 +ubermail.me, 1 +uberpedia.co.uk, 1 +uberpromocodes.us, 1 +ubertt.org, 1 +uberwald.ws, 1 +ubetoo.com, 1 +ubezpieczeniazyciowe.pl, 1 +ubezpieczenie.com.pl, 1 +ubezpieczeniedomu.pl, 1 +ubezpieczeniemieszkania.pl, 1 +ubezpieczenienanarty.pl, 1 +ubezpieczenienarciarskie.pl, 1 +ubezpieczenienazycie.net.pl, 1 +ubezpieczeniepsa.com, 1 +ubezpieczenieturystyczne.com.pl, 1 +ubezpieczeniezycia.pl, 1 +ubezpieczeniezyciowe.pl, 1 +ubezpieczonamama.pl, 1 +ubezpieczonedziecko.pl, 1 +ubi.gg, 1 +ubicaciones-vitamina.cl, 1 +ubicv.com, 1 +ubis.group, 1 +ubits.mx, 1 +ubiurbe.com, 1 +ublaboo.org, 1 +ubntleaks.com, 1 +ubonit.pl, 1 +uboratz.org, 1 +uborcare.com, 1 +uborka-812.ru, 1 +uborka-kvartir-moskva.gq, 1 +uborka-snega.ga, 1 +ubsolutions.hu, 0 +ubun.kr, 1 +ubun.net, 1 +ubunlog.com, 1 +ubuntu-tr.net, 1 +ubuntu18.com, 1 +ubutovo.ga, 1 +ubytovanihyncice.cz, 1 +uc4h.com, 1 +ucabinet.ru, 1 +ucac.nz, 0 +ucangiller.com, 1 +ucasa.org.au, 1 +ucb.com, 1 +ucc.edu.gh, 1 +ucch.be, 0 +uccisme.net.ua, 1 +ucdap.com, 1 +ucero.tk, 1 +ucfirst.nl, 1 +uchargeapp.com, 1 +ucheba.gq, 1 +uchiha.ml, 1 +ucibt.com, 1 +uciplasticsurgery.com, 1 +uclf.de, 1 +uclip.club, 1 +ucmatedeveloper.gq, 1 +ucmjlawyers.com, 1 +ucngame.com, 1 +ucphotography.net.au, 1 +ucppe.org, 1 +ucreate.bg, 1 +ucstrike.com, 1 +uctarna.online, 1 +ucybodyinc.com, 1 +udancy.com, 1 +udaneprzepisy.pl, 1 +udbina.tk, 1 +uddate-linthdcp-3345app.com, 1 +uddate-linthdcp-567app.com, 1 +uddi.ng, 1 +uddin.io, 1 +udemydownload.com, 1 +udemypaidcourse.com, 1 +udid.fyi, 1 +udien.tk, 1 +udiregelverk.no, 1 +udiutv.no, 1 +udmarbella.tk, 1 +udmurtia.tk, 1 +udo-luetkemeier.de, 1 +udomain.net, 1 +udp.sh, 0 +udrop.com, 1 +udruga-point.hr, 1 +udsocial.com, 1 +udvoukocek.eu, 1 +ue30.fun, 1 +ueba1085.jp, 1 +ueberdosis.io, 1 +uebersetzungscenter.ch, 1 +ueberwachungspaket.at, 1 +uedaviolin.com, 1 +uel-thompson-okanagan.ca, 1 +ueni.com, 1 +uesc.org, 1 +uesociedadlimitada.com, 1 +uestc.icu, 1 +uevan.com, 1 +uf-ace.com, 1 +ufa-soft.tk, 1 +ufacesign.in, 1 +ufanisi.mx, 1 +uffserver.ml, 1 +ufindme.at, 1 +ufo-blogger.com, 1 +ufo.moe, 0 +ufob.edu.br, 1 +ufocentre.com, 1 +ufoch.com, 0 +ufologiahistorica.tk, 1 +ufologiaweb.tk, 1 +ufone.com, 1 +ufone.net, 1 +ufopaedia.org, 1 +ufplanets.com, 1 +ufroo.com, 1 +ufuq.de, 1 +ugameclub.com, 1 +ugb-verlag.de, 0 +ugcdn.com, 1 +ugeek.tk, 1 +uggedal.com, 1 +ugirlx.com, 1 +uglycat.com, 1 +uglycat.eu, 1 +uglycat.net, 1 +uglycat.org, 1 +ugmtc.org, 1 +ugolovnyj-advokat.cf, 1 +ugolsibiri.ru, 1 +ugrod.ru, 1 +ugtdigiteldocumentos.es, 1 +ugx-mods.com, 1 +ugy.es, 1 +uhappy85.com, 1 +uhasseltctf.be, 1 +uhasseltctf.ga, 1 +uhc.gg, 1 +uhcuhcas.cf, 1 +uhcuhcas.ga, 1 +uhcuhcas.gq, 1 +uhcuhcas.ml, 1 +uhcuhcas.tk, 1 +uhl.site, 1 +uhlhosting.ch, 1 +uhlturf.com, 1 +uhm.io, 0 +uhost.cyou, 1 +uhrenlux.de, 1 +uhuc.de, 1 +uhurl.net, 1 +ui8.net, 1 +uiberlay.cz, 1 +uicchy.com, 1 +uid0.pl, 1 +uidrafter.com, 1 +uiharu.top, 1 +uinst.tk, 1 +uiop.link, 1 +uiterwijk.org, 1 +uitgeverij-deviant.nl, 1 +uitingent.be, 1 +uitliefde.shop, 1 +uitvaartvrouwenfriesland.nl, 1 +uj2008.com, 1 +ujiyasu.com, 1 +ujob.com.cn, 1 +ujvary.eu, 1 +uk.dating, 1 +uk.kg, 1 +uk.search.yahoo.com, 0 +ukari.hokkaido.jp, 0 +ukb.sch.id, 0 +ukbc.london, 1 +ukc2.com, 1 +ukcarers.tk, 1 +ukdefencejournal.org.uk, 1 +ukfoodbox.co.nz, 1 +ukhas.net, 1 +ukimmigration.law, 1 +ukitbs.com, 1 +ukmeetandgreet.com, 1 +ukmortgagecompare.co.uk, 1 +uknews.ga, 1 +uknewsroom.tk, 1 +ukooku.com, 1 +ukozliku.cz, 1 +ukpr.group, 1 +ukpropertyrescue.com, 1 +ukpts.org, 1 +ukrainians.ch, 1 +ukrainskie-konstrukcii.com.ua, 1 +ukrapak.com.ua, 1 +ukriate.com, 1 +ukrigging.net, 1 +ukrn.io, 1 +ukrnet.co.uk, 1 +ukrtabletki.tk, 1 +uksb.net, 1 +ukta.tk, 1 +uktw.co.uk, 0 +ukuchordnamer.com, 1 +ukunlocks.com, 1 +ukutabs.com, 1 +ukvoipforums.com, 1 +ukwct.org.uk, 1 +ul-fluglehrer.de, 1 +ulabox.com, 1 +ulax.tk, 1 +uldsh.de, 1 +uleenucks.de, 1 +ulement.com, 1 +ulen.me, 1 +ulezcar.com, 1 +ulfsciences.com, 1 +ulgaipbox.online, 1 +uli-eckhardt.de, 1 +ulickaprozivot.cz, 1 +ulike123.com, 1 +ulitroyo.com, 1 +ullah.se, 1 +ulli.ml, 1 +uloztoasdilej.cz, 1 +ulrik.moe, 1 +ulrike-sichert-schuster.de, 1 +uls.by, 1 +ulsters.cf, 1 +ultima-ratio.at, 1 +ultimadivisao.com.br, 1 +ultimasword.tk, 1 +ultimate-fireworks.tk, 1 +ultimate-uk.com, 1 +ultimateanu.com, 1 +ultimatebabyshowergifts.ga, 1 +ultimatebattle.tk, 1 +ultimatefilmpromotion.com, 1 +ultimategaming.tk, 1 +ultimatehalo.tk, 1 +ultimatelifesupport.ga, 1 +ultimatemafia.net, 1 +ultimatemapping.tk, 1 +ultimatepaleoguide.com, 1 +ultimateparts.nl, 1 +ultimatepatrol.de, 1 +ultortech.com, 1 +ultra-pro.ga, 1 +ultracentr.ml, 1 +ultrafine.cf, 1 +ultralife.cf, 1 +ultraly.com.au, 1 +ultraman.tk, 1 +ultramax.biz, 1 +ultramcworld.ml, 1 +ultramookie.com, 1 +ultraonline.ml, 1 +ultraporn.biz, 1 +ultras-venlo.tk, 1 +ultrasdesign.co.uk, 1 +ultrasite.tk, 1 +ultrasocial.ml, 1 +ultrasteam.net, 1 +ultrasvargon.tk, 1 +ultratechlp.com, 1 +ultravendas.com.br, 1 +ultravip.com.br, 1 +ultreya.tk, 1 +ultrixus.rocks, 1 +ulyanovsk-73.tk, 1 +ulyanovsk73.tk, 1 +ulyanovskcity.tk, 1 +ulys.ch, 1 +ulyssesenergy.it, 1 +um-sachsen-pictures.de, 1 +um.es, 0 +umagoyal.com, 1 +umaimagazine.com, 1 +umanews.net, 1 +umanityracing.com, 1 +umanupszn.gov.ua, 1 +umartina.eu, 1 +umaru.gq, 1 +umas.tk, 1 +umasstransit.org, 1 +umbertheprussianblue.com, 1 +umbrellaye.online, 1 +umbricht.li, 1 +umcpc.org, 0 +umenlisam.com, 1 +umisonoda.com, 1 +umity.com.ua, 1 +umlcode.com, 1 +ummati.com, 1 +ummiabi.id, 1 +umniah.com, 0 +umniy-dom.tk, 1 +umnugobi.tk, 1 +umo.ci, 1 +umount.net, 1 +umsapi.com, 1 +umton.cz, 1 +umwandeln-online.de, 1 +umwelt-galerie.de, 1 +umweltgalerie.de, 1 +umzuege-berlin.com, 1 +umzuege-hannover.net, 1 +umzug-fuer-muenchen.de, 1 +umzugsunternehmenberlin.eu, 1 +un-framed.co.za, 1 +un-zero-un.fr, 1 +unadonna.it, 1 +unae.fr, 1 +unaffectedsound.tk, 1 +unai-yus.tk, 1 +unanaciounaseleccio.tk, 1 +unapp.me, 1 +unataly.gq, 1 +unataz.tk, 1 +unatco.noip.me, 1 +unausa.com.br, 1 +unautreregard.tk, 1 +unbelievableplaces.de, 1 +unblock-zh.org, 1 +unblocked.at, 1 +unblocked.bet, 1 +unblocked.bid, 1 +unblocked.cam, 1 +unblocked.cx, 1 +unblocked.dk, 1 +unblocked.earth, 1 +unblocked.gdn, 1 +unblocked.ink, 1 +unblocked.krd, 1 +unblocked.lat, 1 +unblocked.lc, 1 +unblocked.live, 1 +unblocked.llc, 1 +unblocked.ltda, 1 +unblocked.mx, 1 +unblocked.nz, 1 +unblocked.one, 1 +unblocked.pet, 1 +unblocked.pl, 1 +unblocked.pro, 1 +unblocked.pub, 1 +unblocked.sh, 1 +unblocked.uno, 1 +unblocked.vc, 1 +unblocked.vet, 1 +unblocked.vip, 1 +unblocked.win, 1 +unblockedgames.live, 1 +unblockit.bid, 1 +unblockit.biz, 1 +unblockit.ca, 1 +unblockit.id, 1 +unblockit.lat, 1 +unblockit.ltd, 1 +unblockit.me, 1 +unblockit.one, 1 +unblockit.pro, 1 +unblockit.pw, 1 +unblockit.red, 1 +unblockit.top, 1 +unblockit.win, 1 +unbolt.cf, 1 +unboundmoney.com, 1 +unboxed.cf, 1 +unboxforteams.work, 1 +unboxinspector.com, 1 +unboxrobotics.com, 1 +unboxyou.com, 1 +uncadeaupour.fr, 1 +uncarved.com, 1 +uncensoreddns.dk, 1 +uncensoreddns.org, 1 +uncinema.cf, 1 +unclebens-specials.gr, 1 +uncorporate.cf, 1 +uncuteyes.tk, 1 +undeadbrains.de, 1 +undeadwalking.com, 1 +undecidable.de, 1 +undeductive.media, 1 +undef.in, 0 +undemocracy.cf, 1 +under-wears.tk, 1 +under15.ml, 1 +underbridgeleisure.co.uk, 1 +undercliff.tk, 1 +undercovercondoms.com, 1 +undercoverxp.tk, 1 +undercucho.tk, 1 +underfloorheating-uk.co.uk, 1 +undergrounder.ga, 1 +undergroundmusic.tk, 1 +underlined.fr, 1 +undernet.uy, 0 +underskatten.tk, 1 +understandmaths.co.za, 1 +understrap.com, 1 +undertow.ga, 1 +underwaterasia.info, 1 +underwearoffer.com, 1 +underwood.tk, 1 +underwoodpatents.com, 1 +underworlds.tk, 1 +underwriting.ai, 1 +undev.co, 1 +undiepatrol.tk, 1 +undo.co.il, 1 +undp.lt, 1 +une-bonne-nouvelle.fr, 1 +une-femme-dhonneur.tk, 1 +unearaigneeauplafond.fr, 1 +unece-deta.eu, 1 +unefleur.be, 1 +unefuite.ch, 0 +unepierrepourlui.fr, 1 +unerosesurlalune.fr, 0 +unescoclub.tk, 1 +unetyr.gq, 1 +unexpected.nu, 1 +unexplored-belarus.tk, 1 +unexplored-moscow.tk, 1 +unfallrechtler.de, 1 +unfamousrecords.tk, 1 +unfathomable.blue, 1 +unfc.nl, 1 +unferno.tech, 1 +unfettered.net, 0 +unfollow.today, 1 +unfriend.tk, 1 +unga.dk, 1 +ungaeuropeer.se, 1 +ungainlybeast.com, 1 +ungegamere.dk, 1 +unghie.com, 1 +ungnyo.org, 1 +ungooglize.org, 1 +ungrafakta.gq, 1 +uni-cleaner.com, 1 +uni-watch.com, 1 +uni2share.com, 1 +uniaofraternalraulcury.com.br, 1 +unibev.net, 1 +unibo.com, 1 +unibolsit.com, 1 +unicef.pl, 1 +unicefcards.cz, 1 +unicefcards.gr, 1 +unicefcards.it, 1 +unicefcards.nl, 1 +unicefcards.sk, 1 +unicefcestitke.rs, 1 +unicefkartkidlafirm.pl, 1 +unicefkepeslapok.hu, 1 +unicefvoscilnice.si, 1 +unicintas.com.br, 1 +unicioushop.com, 1 +unicode.gq, 1 +unicode.link, 1 +unicolabo.jp, 1 +unicool.tk, 1 +unicorn-systems.net, 1 +unicorn.io, 1 +unicorn.li, 1 +unicorn.melbourne, 1 +unicorncloud.org, 1 +unicorndesign.ninja, 1 +unicorntooling.eu, 1 +unicrack.cf, 1 +unicredit.ba, 1 +unicredit.ro, 1 +unicreditbank.hu, 1 +unicreditbank.rs, 1 +unicreditbank.ru, 0 +unicreditbulbank.info, 1 +unicycle.ga, 1 +unidevgroup.ru, 1 +unidostransportes.com.br, 1 +unieducar.org.br, 1 +uniekglas.nl, 1 +unifashion.ro, 1 +unifestal.com, 1 +unifiednetwork.me, 1 +uniforcele.com, 1 +uniform-agri.com, 1 +uniformebateriasheliar.com.br, 1 +uniformesdreamleaguesoccer.com, 1 +unify.id, 1 +unikainfocom.in, 1 +unikoingold.com, 1 +unikrn.com, 1 +unikrnb2b.com, 1 +unila.edu.br, 1 +unilinkgroup.com, 1 +unimarijo.com, 1 +unimax.com.tw, 1 +unimbalr.com, 1 +unimeias.com.br, 1 +uninutri.com.br, 1 +unioncountyncelections.gov, 1 +uniondeterapeutas.com, 1 +unionhoster.ml, 1 +unionlife-net.com, 1 +unionmagdalena.tk, 1 +unionplat.ru, 1 +unionreports.gov, 1 +unionstreetskateboards.com, 1 +uniontestprep.com, 1 +unionvilleheating.com, 1 +unipart.digital, 0 +unipass.ga, 1 +unipig.de, 0 +uniq.site, 1 +uniqsys.eu, 1 +unique-news.tk, 1 +unique-tutorials.info, 1 +unique-urls.tk, 1 +uniquepathways.ch, 0 +uniquepress.biz, 1 +uniqueworks.tk, 1 +uniresbajdas.ml, 1 +uniritter.edu.br, 1 +unis-pour-la-planete.com, 1 +unis-pour-le-climat.com, 1 +uniswapnews.com, 1 +unisyssecurity.com, 1 +unit3d.site, 1 +unit7jazz.com, 1 +unit7jazz.org, 1 +unitanzania.com, 1 +unitasinternational.org, 1 +unite-ka.de, 1 +uniteasia.org, 1 +united-coders.com, 1 +united-dm.ml, 1 +united-schools.net, 1 +united-trainers-league.tk, 1 +united.com, 0 +unitedadmins.com, 1 +unitedbaby.fr, 1 +unitedbusinessbank.com, 1 +unitedcarremoval.com.au, 1 +unitedcyberdevelopment.com, 1 +unitedfitness.com.au, 1 +unitedkingdoms-guild.com, 1 +unitedlisbon.school, 1 +unitedmethodistchurch.tk, 1 +unitedpsychological.com, 1 +unitedrestorationfl.com, 1 +unitedsafetynet.com, 0 +unitedstables.tk, 1 +unitedwedream.org, 1 +uniteforrecovery.govt.nz, 1 +unitefortherecovery.govt.nz, 1 +unitehelivy.be, 1 +uniteinhealth.org, 1 +unitel2000.de, 0 +unitencup.tk, 1 +unitir.gq, 1 +unityconsciousnessbooks.com, 1 +unityvox.com, 1 +unium.uz, 1 +uniuni.info, 1 +univ-segou.ml, 1 +univaservizi.academy, 1 +univate.berlin, 1 +univercite.ch, 0 +univeril.com, 0 +univerkeys.com, 1 +univerpack.net, 1 +universal-credit.com, 1 +universal-happiness.com, 1 +universal-mail.ml, 1 +universal-techno.com, 1 +universal-tutorial.com, 1 +universal-village.org, 1 +universal.at, 1 +universalcircus.tk, 1 +universalcredit.com, 1 +universalmedia.tk, 1 +universalpaymentgateway.com, 1 +universalplant.com, 1 +universalspf.org, 1 +universdejeff.com, 1 +universe.horse, 1 +universedragonball.com, 0 +universehk.tk, 1 +universeinform.com, 1 +universeit.mx, 1 +universellafredsdanser.se, 1 +universidadcatolica.tk, 1 +universidadperu.com, 1 +universiteplatformu.com, 1 +universitesegou.ml, 1 +universityhousemates.co.uk, 1 +universityhousemates.uk, 1 +universityofedinburgh.org.uk, 1 +universityofnarowal.ga, 1 +universitywafer.com, 1 +universocaballo.top, 1 +universogay.com, 1 +universoscuola.it, 1 +universrumbacongolaise.com, 1 +universus.tk, 1 +univet-veterinaire.com, 0 +univitale.fr, 0 +unix.lu, 1 +unix.se, 1 +unixadm.org, 1 +unixapp.ml, 1 +unixattic.com, 1 +unixer.tk, 1 +unixforum.org, 1 +unixfox.eu, 1 +unixhost.ga, 1 +unixteam.de, 1 +unixtime.date, 1 +unja.ac.id, 0 +unkn0wncat.net, 1 +unknown-player.com, 1 +unknown.kyoto, 0 +unknownbreakup.com, 0 +unknownhacks.tk, 1 +unknownmasses.tk, 1 +unknownnet.tk, 1 +unko.cz, 1 +unkrn.com, 1 +unlax.com, 1 +unleashyouridentity.com, 1 +unli.xyz, 1 +unlimiteddsl.ga, 1 +unlimitedheatingcooling.com, 1 +unlock-my-sprint.mobi, 1 +unlockauthority.com, 1 +unlockblackberryfree.co.uk, 1 +unlockboot.com, 0 +unlocken.nl, 1 +unlockerboss.com, 1 +unlocks.co.uk, 1 +unlocktalent.gov, 1 +unlocktechs.com, 1 +unluco.com, 1 +unmarkdocs.co, 1 +unmonito.red, 1 +unn-edu.info, 1 +unnamed.download, 1 +unnas.ca, 1 +uno.fi, 1 +uno.uk, 1 +unobet-partners.com, 1 +unobrindes.com.br, 1 +unoccupyabq.org, 1 +unofficialbpb.tk, 1 +unosconotros.com, 1 +unovosti.tk, 1 +unp.me, 1 +unpaismejor.es, 1 +unpause.io, 1 +unpkg.com, 1 +unpleasant.tk, 1 +unpluggedjuice.dk, 1 +unplugstore.it, 1 +unpossible.xyz, 1 +unpr.dk, 1 +unprovided.cf, 1 +unreal.dk, 1 +unrealircd.org, 1 +unrelated.net.au, 1 +unrepentant.cf, 1 +unrestricted.ga, 1 +unric.org, 1 +unripple.com, 1 +unruh.fr, 0 +uns.vn, 1 +unsee.cc, 1 +unseeliefilms.com, 1 +unseeliepress.com, 1 +unseen.is, 1 +unseen.tw, 1 +unser-gartenforum.de, 1 +unsereins.me, 1 +unsourirealecole.fr, 1 +unstable.network, 1 +unstablewormhole.ltd, 1 +unstamps.org, 1 +unstockd.org, 1 +unstoppable.money, 1 +unstoppableever.com.br, 1 +unstoppableunits.com, 1 +unsuspicious.click, 1 +unterhaltungsbox.com, 1 +unternehmensbewertung.pro, 1 +unternehmer-radio.de, 1 +unternehmerrat-hagen.de, 1 +unternimmteam.de, 1 +untethereddog.com, 1 +unti.me, 1 +untvweb.com, 1 +unusedrooms.com, 1 +unusualhatclub.com, 1 +unusualworldd.com, 1 +unveiledgnosis.com, 1 +unvoyageenvelo.com, 1 +unwa.tk, 1 +unworthy.ml, 1 +unx.dk, 1 +unxicdellum.cat, 1 +uoe.com, 1 +up-ai.com, 1 +up-obmen.ml, 1 +up-stage.jp, 1 +up.com.au, 1 +up2mark.com, 0 +up2staff.com, 1 +upacores.com, 1 +upakovka-podarkov.tk, 1 +upakweship.ca, 1 +upakweship.com, 1 +upakweship.eu.com, 1 +upakweship.uk.com, 1 +upandrunningtutorials.com, 1 +upawg.ca, 1 +upay.ru, 1 +upbad.com, 1 +upbatangan.tk, 1 +upbeatrobot.com, 1 +upbeatrobot.email, 1 +upbeatrobot.eu, 1 +upbeatrobot.net, 1 +upbeatrobot.nl, 1 +upbeatrobot.org, 1 +upbound.io, 0 +upbtrbt.com, 1 +upbtrbt.eu, 1 +upbtrbt.net, 1 +upbtrbt.nl, 1 +upbtrbt.org, 1 +upc-point.ch, 1 +upcambio.com, 1 +upcloud.cz, 1 +upd.jp, 1 +update-linthdcp-567app1.com, 1 +updoze.com, 1 +upengo.com, 1 +upfurniture.tk, 1 +upgamerengine.com, 1 +upgamerengine.com.br, 1 +upgamerengine.net, 1 +upgauged.com, 1 +upgrade.com, 1 +uphabit.io, 1 +upholsterycleanerslondon.co.uk, 1 +upholsterydesign.com.au, 1 +upitnik.rs, 1 +uplaqui.com.br, 1 +uplead.com, 1 +upliftingappalachia.org, 1 +uplinklabs.net, 1 +upload.facebook.com, 0 +uploadbeta.com, 1 +uploadbro.com, 1 +uploadcare.com, 1 +uploadscript.tk, 1 +uploadyourtestament.com, 1 +uplr.it, 1 +upmail.ml, 1 +upmchealthsecurity.us, 1 +upmon.com, 1 +upnext.io, 1 +upnext.tk, 1 +uportal.tk, 1 +upperbeaconsfield.org.au, 1 +uppercloud.cf, 1 +upperlimbco.com, 1 +upperroommission.ca, 1 +upperskagittribe-nsn.gov, 1 +uppfinnarenc.tk, 1 +upplevelse.com, 1 +uppsala.tk, 1 +upr.com.ua, 1 +upr.llc, 1 +upr.si, 1 +uprint.it, 1 +upropay.com, 1 +ups-yahweh.com, 1 +upscope.io, 1 +upsdelperu.com.pe, 1 +upsettunnel.com, 1 +upsihologa.com.ua, 0 +upsilonsigmaphi.us, 1 +upskilllearning.ml, 1 +upskirtmania.tk, 1 +upstairs.one, 1 +upstart.com, 1 +uptech.biz.id, 1 +uptech.vn, 1 +uptechbrasil.com.br, 1 +uptimed.com, 1 +uptional.gq, 1 +uptodateinteriors.com, 1 +uptoon.jp, 1 +uptoplay.ovh, 1 +uptotechs.com, 1 +uptownbabe.com, 1 +uptownlocators.com, 1 +uptrends.com, 1 +uptrends.de, 1 +uptrex.co.uk, 1 +upturn.com.eg, 1 +upturn.org, 1 +upundit.com, 1 +upvoted.net, 1 +upwardcreative.com, 1 +upwardtraining.co.uk, 1 +upwork.com, 1 +uq1k.com, 1 +uqschool.com, 1 +ur-lauber.de, 1 +ur.nl, 1 +ur2.pw, 1 +urabain.com, 1 +uradisam.rs, 1 +uradvd.best, 1 +uradvd.town, 1 +uraimo.com, 1 +ural-emal.ga, 1 +ural-travel.ml, 1 +ural.cf, 1 +ural.ga, 1 +ural.tk, 1 +uralec.tk, 1 +uralsite.cf, 1 +uralsk.ml, 1 +uralskaya-garmon.tk, 1 +uralspravka.cf, 1 +urang-kurai.tk, 1 +uraniborg.net, 1 +uraniumhost.ga, 1 +uranius.eu, 1 +uranmoney.ml, 1 +uranus.cf, 1 +urbackups.com, 1 +urbalex.ch, 0 +urban-culture.fr, 1 +urban-news.tk, 1 +urban.melbourne, 1 +urbanagriculturesummit.cf, 1 +urbanarcana.tk, 1 +urbanbageecha.com, 1 +urbanbikeweamr.ga, 1 +urbanbooks.tk, 1 +urbancoffee.com.mx, 1 +urbancreators.dk, 1 +urbanesecurity.com, 1 +urbanguerillas.de, 1 +urbangymfirenze.com, 1 +urbanhotbed.eu, 1 +urbanietz-immobilien.de, 1 +urbanility.com, 1 +urbanindustriecoiffure-auray.fr, 1 +urbanism.xyz, 1 +urbanlounge.tk, 1 +urbanmic.com, 1 +urbanmsp.com, 1 +urbanmuslim.tk, 1 +urbannewsservice.com, 1 +urbanon.cz, 1 +urbansparrow.in, 1 +urbanstylestaging.com, 1 +urbanusonline.tk, 1 +urbanwaters.gov, 1 +urbanwave.co.za, 1 +urbanwildlifealliance.org, 0 +urbanxdevelopment.com, 1 +urbanxhome.com, 1 +urbanyshop.com, 1 +urbest.io, 1 +urbexdk.nl, 1 +urbexing.eu, 1 +urbizoroofing.com, 1 +urcentral.com, 1 +urcentral.eu, 1 +urcentral.net, 1 +urcentral.nl, 1 +urcentral.org, 1 +ureka.org, 1 +urep.us, 1 +urfayazar.com, 1 +urfreecon.tk, 1 +urge55.com, 1 +urgences-valais.ch, 1 +urgent-notice.ml, 1 +urgentcaresouthaven.com, 1 +urion.com.br, 1 +uriport.com, 1 +uriports.com, 1 +uripura.de, 1 +urist1011.ru, 1 +urka.tk, 1 +urke.tk, 1 +urko.shop, 1 +urkonsultant.tk, 1 +urkult.se, 0 +url.fi, 1 +url.fm, 1 +url.kg, 1 +url.rw, 1 +urlakite.com, 1 +urlaub-busreisen.de, 1 +urlaub-leitner.at, 1 +urlendecoder.tk, 1 +urlfly.tk, 1 +urlgoo.ga, 1 +urlive.ga, 1 +urljournal.tk, 1 +urlscan.io, 1 +urlsimple.tk, 1 +urltell.com, 1 +urltodomain.com, 1 +urlwing.tk, 1 +urlz.tk, 1 +urmikron.tk, 1 +urnes.org, 1 +urocentre.ga, 1 +uroki.tk, 1 +urokoff.net, 1 +urology.wiki, 1 +urologyoklahoma.com, 1 +urologyspecialistspc.com, 1 +urologywi.com, 1 +urown.net, 1 +urrestarazuserranoabogados.com, 1 +ursa-minor-beta.org, 1 +ursonatefanzine.tk, 1 +urspringer.de, 1 +urstore.ga, 1 +ursula-gadalka.tk, 1 +ursuslibris.hu, 1 +urth.org, 1 +uruguay-experience.com, 1 +uruharushia.com, 1 +urukproject.org, 1 +uruslugi.tk, 1 +us-10.cc, 1 +us-10.com, 1 +us-igloopreview.com, 1 +us-immigration.com, 1 +us.ax, 1 +us.gov, 1 +us.kg, 1 +us10.net, 1 +us2uplumbing.com.au, 1 +usa-10.com, 1 +usa-10.net, 1 +usa-10.us, 1 +usa-greencard.eu, 1 +usa-reisetipps.net, 1 +usa.gov, 1 +usa250.gov, 1 +usaa.com, 0 +usaattorneyblog.com, 1 +usabackground.com, 1 +usability.com.gr, 1 +usability.gov, 1 +usacarry.com, 1 +usadba.net.ru, 1 +usadf.gov, 1 +usadirectory.tk, 1 +usaestaonline.com, 1 +usage.be, 1 +usagexchange.com, 1 +usagi-ku.ga, 1 +usagm.gov, 1 +usagov.gov, 1 +usahealthwebapps.com, 1 +usajobs.com, 1 +usajobs.gov, 1 +usalearning.gov, 1 +usamale.cf, 1 +usamdt.com, 1 +usamultimeters.com, 1 +usanewsposts.ga, 1 +usanewstrends.ga, 1 +usap.gov, 0 +usapublicrecords.com, 1 +usarp.org, 1 +usaseanconnect.gov, 1 +usastaffing.gov, 1 +usaweblist.tk, 1 +usawireguard.com, 1 +usb-lock-rp.com, 1 +usbcompatible.com, 1 +usbevents.co.uk, 1 +usbr.gov, 1 +uscis.gov, 1 +uscitizenship.info, 1 +uscloud.nl, 1 +uscp8.com, 1 +usctt.org, 1 +uscurrency.gov, 1 +uscveteranspark.org, 1 +usd.de, 1 +usd.ooo, 1 +usdfc.gov, 1 +usdoj.gov, 1 +usdoscloud.gov, 1 +usds.gov, 1 +usdwellhouse.com, 1 +use.be, 1 +usebosin.gq, 1 +usecamisetas.com, 1 +used255.xyz, 1 +usedu.us, 1 +usenet.tk, 1 +usenetpirate.co.uk, 1 +useon.com, 1 +useon.ru, 1 +user-agent.ga, 1 +user-agent.ml, 1 +user-re.com, 0 +userbase.com, 1 +usercompare.tk, 1 +userhelp.tk, 1 +username.nz, 1 +userra.gov, 1 +userstation.de, 1 +usespetaculo.com.br, 1 +usetypo3.com, 1 +useworkshop.com, 1 +useyourloaf.com, 1 +usgande.com, 1 +ushandbookapp.com, 1 +ushare.ch, 1 +ushealthpharma.com, 1 +usherwoodexecutivetravel.com, 1 +ushi808.com, 1 +usicecenter.gov, 1 +usidfc.gov, 1 +usimmigration.us, 1 +usitcolours.bg, 1 +usjunkyardsnearme.com, 1 +usk-clan.tk, 1 +uskaonline.tk, 1 +uskaria.com, 1 +usleep.net, 1 +usleravnekrog.dk, 1 +uslugi-advokata.ga, 1 +uslugi-online.pl, 1 +uslugi-voronezh.tk, 1 +usmammy.com.tw, 1 +usmiddleclass.net, 1 +usmint.gov, 1 +usnews-new.tk, 1 +usninosnikrcni.eu, 1 +usnti.com, 1 +uspaacc.com, 1 +usparklodging.com, 1 +uspeh62.tk, 1 +uspeli.ml, 1 +uspesnyprvnacek-demo.herokuapp.com, 1 +uspesnyprvnacek-staging.herokuapp.com, 1 +uspesnyprvnacek-testing.herokuapp.com, 1 +uspesnyprvnacek.cz, 1 +uspesnyprvnacek.herokuapp.com, 1 +usphs.gov, 0 +uspib.info, 1 +usportsgo.com, 1 +usrspace.at, 1 +uss-atlas.de, 1 +ussemiquincentennial.gov, 1 +ussm.gov, 0 +ussm.tk, 1 +ussst.org, 1 +ussst.org.in, 1 +ustaywell.com, 1 +ustensiles-cuisine.boutique, 1 +ustr.gov, 0 +ustugov.kiev.ua, 1 +ustugova.kiev.ua, 1 +usu.org.ua, 1 +usualbeings.com, 1 +usuan.net, 1 +usweme.info, 1 +uswitch.com, 1 +usyfawovad.gq, 1 +ut-jobs.net, 1 +ut5s.com, 1 +utahblackplate.com, 1 +utahblackplates.com, 1 +utahcanyons.org, 1 +utahdebtcare.com, 1 +utahdentalcrowns.com, 1 +utahfanclub.org, 1 +utahhydrographics.com, 1 +utahrealestatepodcast.com, 1 +utahtravelcenter.com, 1 +utaowan.com, 0 +utavatu.mk, 1 +utazas-nyaralas.info, 1 +utazine.com, 1 +utbabogados.com, 1 +utbosbeekhuuske.tk, 1 +utcast-mate.com, 1 +utduc.com, 1 +uteasybooki.com, 1 +utensil.org, 1 +utevai.tk, 1 +utgifter.no, 1 +utiars.com, 1 +uticagravel.com, 1 +utilia.tools, 1 +utilitarian.com, 1 +utilitarian.net, 1 +utilitarian.org, 1 +utilitarianism.com, 1 +utilitarianism.org, 1 +utilitarismo.com, 1 +utilitronium.com, 1 +utilityapi.com, 1 +utitreatment.com, 1 +utleg.gov, 1 +utloperadora.com.br, 1 +utodyg.ga, 1 +utonia.ch, 1 +utopialgb.org.uk, 1 +utopian-institute.tk, 1 +utopiancapitalism.tk, 1 +utopianrealms.org, 1 +utopicestudios.com, 1 +utopique.net, 1 +utos.ws, 1 +utrace.me, 1 +utrantor.org, 1 +uttama.ga, 1 +utterberry.io, 1 +uttnetgroup.fr, 1 +utural.tk, 1 +utw.me, 1 +utwente.io, 1 +utzon.net, 1 +uu5197.co, 1 +uu6729.co, 1 +uu6729.com, 1 +uu6957.co, 1 +uu9297.co, 1 +uu939.com, 1 +uu9397.com, 1 +uu9721.com, 1 +uu9728.co, 1 +uuit.nl, 1 +uurl.ga, 1 +uuznn.cn, 1 +uuzsama.me, 1 +uv.uy, 1 +uvc.com.ua, 1 +uvcleanfrance.com, 1 +uvenuse.cz, 1 +uvlamp.ee, 1 +uvocorp.com, 1 +uvpress.com, 1 +uvseh.com, 1 +uvt.com.co, 1 +uvtcinemas.com, 1 +uvx.io, 1 +uwac.co.uk, 0 +uwat.cc, 1 +uwat.cf, 1 +uwe-arzt.de, 0 +uwe-r.com, 1 +uwe-reimold.de, 1 +uwe.training, 1 +uwereimold.de, 1 +uwesander.de, 1 +uwfreelanceopticien.nl, 1 +uwsalonboot.nl, 1 +uwsoftware.be, 1 +uwu.lgbt, 1 +uwu.nu, 1 +uwvloereruit.nl, 1 +uwwsb.com, 1 +ux-designers.nl, 1 +ux-solution.de, 1 +uxdesignerjobs.nl, 1 +uxpressia.com, 1 +uxsto.com, 1 +uxtag.com, 1 +uxteam.com, 1 +uy.search.yahoo.com, 0 +uyen.party, 1 +uygindir.ml, 1 +uyuniscooterluggage.com, 1 +uyz.me, 1 +uz-yulduzlar.tk, 1 +uz.search.yahoo.com, 0 +uzagmozemunk.ga, 1 +uzagmozemunk.ml, 1 +uzay.org, 1 +uzayliyiz.biz, 1 +uzbaza.tk, 1 +uzbek-soft.tk, 1 +uzbekistan24.tk, 1 +uzbekkizlari.ml, 1 +uzbekkizlari.tk, 1 +uzbektumblers.tk, 1 +uzbwap.tk, 1 +uze-mobility.at, 1 +uze-mobility.ch, 1 +uze-mobility.co, 1 +uze-mobility.com, 1 +uze-mobility.group, 1 +uze-mobility.info, 1 +uze-mobility.io, 1 +uze-mobility.net, 1 +uze-mobility.org, 1 +uze-store.com, 1 +uze.mobi, 1 +uzemobility.com, 1 +uzemobility.de, 1 +uzemobility.eu, 1 +uzemobility.org, 1 +uzhas-uzhasny.ml, 1 +uzidesign.com, 1 +uziregister.nl, 0 +uzmansorusu.com, 1 +uzone.uk, 1 +uzsvm.cz, 1 +uztop.ml, 1 +uzzamari.com, 1 +v-d-p.net, 1 +v-gornom.ga, 1 +v-horus.cloud, 1 +v-horus.com, 0 +v-jo.com, 1 +v-kurgane.tk, 1 +v-m-shop.ru, 1 +v-media.tk, 1 +v-news.tk, 1 +v-novosibirske.tk, 1 +v-phoenix.tk, 1 +v-spin.cz, 1 +v-tek.fi, 1 +v-u-z.ru, 1 +v.pn, 1 +v.ps, 1 +v0ctor.me, 1 +v0i.de, 1 +v0v.cc, 1 +v1.dk, 1 +v10006.com, 1 +v10008.com, 1 +v1081.com, 1 +v139.com, 1 +v1sit0r.ru, 1 +v2.pw, 1 +v2bv.net, 1 +v2bv.win, 1 +v2ex.com, 1 +v2mcdev.com, 1 +v2raytech.com, 1 +v2x.sk, 1 +v2xxoo.com, 1 +v3025.com, 1 +v30365.com, 1 +v33v33.com, 1 +v36533.com, 1 +v44v44.com, 1 +v4f.com, 1 +v5017.com, 0 +v5075.com, 1 +v51365.com, 1 +v5197.co, 1 +v55565.com, 0 +v55580.com, 0 +v55593.com, 0 +v55v55.com, 1 +v5658.com, 1 +v5ray.top, 1 +v6004.com, 1 +v6021.com, 1 +v6170.com, 1 +v6350.com, 1 +v6506.com, 1 +v66255.com, 0 +v66557.com, 0 +v6729.co, 1 +v6752.com, 1 +v6791.com, 0 +v6957.co, 1 +v700a.com, 1 +v700bb.com, 1 +v700cc.com, 1 +v700dd.com, 1 +v700ee.com, 1 +v700w.com, 1 +v7090.com, 1 +v81365.com, 1 +v82365.com, 1 +v88158.com, 1 +v88511.com, 0 +v8abc.com.br, 1 +v8builder.com, 1 +v9037.com, 1 +v9285.com, 0 +v9297.co, 1 +v9728.co, 1 +v9728.com, 1 +v9820.com, 1 +va-reitartikel.com, 1 +va.gov, 0 +va11hal.la, 1 +va11halla.ddns.net, 1 +va1der.ca, 1 +vaabogados.legal, 1 +vaaddress.co, 1 +vaaes.org, 0 +vaan-arbeidsrecht.nl, 1 +vaartjesboten.nl, 1 +vaat.io, 1 +vabusinesses.org, 1 +vacacionesenlinea.com, 1 +vacacionestours.com, 1 +vacancyfiller.com, 1 +vacatecleaning.melbourne, 1 +vacati0n.tk, 1 +vacation-croatia.com, 1 +vacation-in-pisak.tk, 1 +vacationfund.co, 1 +vaccineskill.biz, 1 +vaccinestats.net, 1 +vackor.tk, 1 +vaclan.tk, 1 +vaclavambroz.eu, 1 +vacpas.com, 1 +vacuumreviewcenter.com, 1 +vadasztanyabuk.hu, 1 +vademekum.com, 1 +vader.news, 1 +vadiar-angola.tk, 1 +vadik.me, 1 +vadillodelasierra.tk, 1 +vaeplatform.com, 1 +vaew.com, 1 +vagabond.film, 1 +vagabond.fr, 1 +vagabondages.tk, 1 +vagabondgal.com, 1 +vagabundos.tk, 1 +vagaerg.com, 1 +vagaerg.net, 1 +vaganciatechnology.com, 0 +vagasdeempregos.ga, 1 +vaginalrejuvenationkentucky.com, 1 +vagmour.eu, 1 +vagpartsdb.com, 1 +vagrantbits.com, 1 +vagrantcloud.com, 1 +vagrantup.com, 0 +vahl.blue, 1 +vahoshop.cz, 1 +vaibhavchatarkar.com, 0 +vaidikapriya.pub, 1 +vaindil.com, 1 +vaioswolke.xyz, 0 +vairuok.lt, 1 +vaisselle-nature.fr, 1 +vak-pobeda.ru, 1 +vakantiedetective.nl, 1 +vakantiehuisschellinkhout.nl, 1 +vakantieinfo.tk, 1 +vakita.fi, 1 +vakuutuskanava.fi, 1 +vakwinkeldemo.nl, 1 +val-sec.com, 1 +valagrovoce.com, 1 +valaphee.com, 1 +valasi.eu, 1 +valcano-krd.ru, 1 +valcano.ru, 1 +valdecaballeros.tk, 1 +valdelcubo.tk, 1 +valdicass.com, 1 +valecnatechnika.cz, 1 +valek.net, 1 +valemountchamber.com, 1 +valemountmuseum.ca, 1 +valenciadevops.me, 1 +valenciaescatala.tk, 1 +valencianisme.tk, 1 +valencianistas.tk, 1 +valencraft.ca, 1 +valencraft.com, 1 +valenhub.com, 1 +valenhub.es, 1 +valeniidemunte.tk, 1 +valentin-dederer.de, 1 +valentin-ochs.de, 1 +valentin.app, 1 +valentinaquino.com, 1 +valentinarosamilia.ch, 1 +valentinarosamilia.com, 1 +valentinberclaz.com, 0 +valentineapparel.com, 1 +valentinemom.cf, 1 +valentinesongs.com, 1 +valentinoduval.fr, 1 +valentinog.com, 1 +valentinritz.com, 0 +valentinstag.ga, 1 +valentinvesa.ro, 1 +valeravi.tk, 1 +valerian.tk, 1 +valeriansaliou.name, 1 +valeriapanarina.com, 1 +valerieadolff.com, 1 +valerieorsoni.com, 1 +valescaind.com.br, 1 +valhallastrengthsthbne.com.au, 1 +valiakhmetov.tk, 1 +valiant.finance, 1 +validatis.com, 1 +validator.nu, 1 +validbrands.com, 1 +validius.fi, 1 +validius.net, 1 +valigate.com, 1 +valika.ee, 1 +valimised.ee, 1 +valkohalla.dk, 1 +valkohattu.fi, 1 +valkoi-konyvtar.hu, 1 +valkoi-ksk.tk, 1 +valkova.net, 1 +valkyriecloud.com, 1 +valledeleresma.tk, 1 +vallei-veluwe.nl, 1 +vallenar.tk, 1 +valleyautofair.com, 1 +valleycode.net, 1 +valleydalecottage.com.au, 1 +valleyofdeath.tk, 1 +valleyshop.ca, 1 +valleystories.ga, 1 +valleywidetvrepair.ml, 1 +valoan.me, 1 +valopv.be, 1 +valor-host.ml, 1 +valorantpicker.com, 0 +valorantpornhentai.com, 1 +valordolarblue.com.ar, 1 +valordotrabalho.com.br, 1 +valorem-tax.ch, 0 +valoremtax.ch, 0 +valoremtax.com, 0 +valoriashard.tk, 1 +valorizofficial.com, 1 +valparaiso.tk, 1 +valpareso.tk, 1 +valphenn.blue, 1 +valpovo-online.tk, 1 +valsanfox.pe, 1 +valshamar.is, 1 +valsk.is, 0 +valskis.lt, 1 +valsorey.ch, 1 +valtherperron.nl, 1 +valtlai.fi, 1 +valtoaho.com, 1 +valtool.uk, 1 +valudo.st, 1 +valuecashhomes.com, 1 +valuecashoffers.com, 1 +valuechain.me, 1 +valuehost.com.br, 1 +valuemyhome.co.uk, 1 +valuemyhome.uk, 1 +valuemywebsite.net, 1 +valueng.com, 1 +valueofblog.com, 1 +valueourmind.com, 1 +valueourminds.com, 1 +valueourminds.org, 1 +valuepenguin.com, 1 +valueseed.net, 1 +valunet.co.za, 1 +valuskills.co.za, 1 +valuta-tools.nl, 1 +valutienda.com, 1 +valuuttamuunnin.com, 1 +valvulasvaneo.com, 1 +valx.jp, 1 +vam-podarok.tk, 1 +vamonospaportugal.tk, 1 +vamosbets.com, 1 +vamosbien.com, 1 +vamosfalardesaude.pt, 1 +vampire-studios.tk, 1 +vampire142.fr, 1 +vampireapocalypsesurvival.com, 1 +vampiresdawn.org, 1 +vampyrium.com, 0 +vampyrium.net, 0 +van-brandevoort.tk, 1 +van11y.net, 1 +vanadrighem.eu, 1 +vanasperenschoenen.nl, 1 +vanbalen.be, 1 +vanboven.nl, 1 +vanbruchem.tk, 1 +vanburencountyiowa.gov, 1 +vancityconcerts.com, 1 +vancoevents.com, 1 +vancouverchess.com, 1 +vancouvercosmeticsurgery.ca, 1 +vancouverwebsitedesigns.com, 1 +vandalfsen.me, 1 +vandals.ml, 1 +vandam.io, 1 +vandemeent.eu, 1 +vandenbroeck-usedcars.be, 0 +vander-vegt.nl, 1 +vanderbeekonline.nl, 1 +vanderbiltcisa.org, 1 +vanderkley.it, 1 +vanderkrieken.org, 1 +vandermeer.frl, 1 +vanderrijt.nl, 0 +vanderstraeten.dynv6.net, 1 +vanderziel.org, 1 +vandijkmaatwerk.nl, 1 +vandommelenart.com, 1 +vandoornmiddenzeeland.nl, 1 +vandortgroep.nl, 1 +vandrielschoenen.nl, 1 +vandyhacks.org, 1 +vanecketfs.nl, 1 +vanesaleiro.tk, 1 +vanessaamorosi.tk, 1 +vanessabalibridal.com, 1 +vanessarivas.com, 1 +vanetv.com, 1 +vaneurology.com, 1 +vaneyckexpo.be, 1 +vaneyckwashere.be, 1 +vaneyckwashere.com, 1 +vaneyckwashere.eu, 1 +vaneyckwashere.gent, 1 +vangest.pt, 1 +vangoghcoaching.nl, 1 +vanhaos.com, 1 +vanhatten.com, 1 +vanhelsing.ml, 1 +vanhelsing.tk, 1 +vanhoudt-usedcars.be, 0 +vanhoutte.be, 0 +vanhove.biz, 1 +vanillacoder.co.za, 1 +vaniola.com, 1 +vanisha.co, 1 +vanityfairnapkins.com, 1 +vanjeveren.nl, 1 +vanmalland.com, 1 +vanna-mechti.tk, 1 +vannaos.com, 1 +vannaos.net, 1 +vannoordgouda.nl, 1 +vanouwerkerk.net, 1 +vanquish.tk, 1 +vanspa.vn, 1 +vanss.org, 1 +vanstoftotleven.nl, 1 +vantagepointpreneed.com, 1 +vante.me, 1 +vantien.com, 1 +vantru.is, 1 +vanuithartenziel.nl, 1 +vanvanlines.com, 1 +vanveenendaaladvies.info, 1 +vanwa.ch, 1 +vanwertcountyohio.gov, 1 +vanwoensei.xyz, 1 +vanwoensel.cloud, 1 +vanwoensel.directory, 1 +vanwoensel.xyz, 1 +vanwort.de, 1 +vanwunnik.com, 1 +vap.llc, 0 +vapecom-shop.com, 1 +vapecrunch.com, 1 +vapehour.com, 1 +vapeking.co.za, 1 +vapekingusa.com, 1 +vapemania.eu, 1 +vapemate.co.uk, 1 +vapensiero.co.uk, 1 +vaperion.me, 1 +vapesense.co.uk, 1 +vapetaclope.cf, 1 +vapex.pl, 1 +vapezone.com.au, 1 +vaphone.co, 1 +vapingdaily.com, 1 +vapocial.com, 1 +vapolik.fr, 1 +vapor.cloud, 0 +vapordepot.jp, 1 +vaporquest.tk, 1 +vapourtown.com, 1 +vapteke.ru, 1 +varcare.jp, 1 +varda.nl, 1 +vardenafilhcl.gq, 1 +vareillefoundation.fr, 0 +vareillefoundation.org, 0 +varela-electricite.fr, 1 +varelaloca.tk, 1 +varghese.de, 1 +variable.agency, 0 +variable.dk, 1 +variablyconstant.com, 1 +variag-montazh.ru, 0 +varied.ga, 1 +varimedoma.com, 1 +variomedia.de, 1 +variusunum.com, 1 +varizh.by, 1 +varjo.tk, 1 +varlex.cl, 1 +varna-airport.bg, 1 +varney.tk, 1 +varnish.ga, 1 +varonahairrestoration.com, 1 +varoscak.de, 1 +varrogepcentrum.hu, 1 +varshathacker.com, 1 +varun-rajeshwari.tk, 1 +varvitra20mg.ga, 1 +varyrentacar.com, 1 +varztupasaulis.com, 1 +varztupasaulis.eu, 1 +varztupasaulis.lt, 1 +varztupasaulis.net, 1 +vas.ae, 1 +vasanth.org, 0 +vasaprilezitost.eu, 1 +vasaprilezitost.sk, 1 +vascomm.co.id, 1 +vasconcellos.xyz, 1 +vase-eroticke-povidky.cz, 1 +vasectomias.cl, 1 +vasel.de, 1 +vasel.eu, 1 +vash-doctor.tk, 1 +vash-dom.tk, 1 +vashdohod.ml, 1 +vashel.us, 1 +vasheradio.tk, 1 +vashmatrass.ru, 1 +vashprazdnik.tk, 1 +vasi.ro, 1 +vasileruscior.ro, 1 +vasilevo.tk, 1 +vasilikieleftheriou.com, 1 +vasilisa-volodina.cf, 1 +vasilisa-volodina.ga, 1 +vasilisa-volodina.gq, 1 +vasilisa-volodina.ml, 1 +vasilisa-volodina.tk, 1 +vaskulitis-info.de, 1 +vasports.com.au, 1 +vastenotaris.nl, 1 +vastgoed-lidl.nl, 1 +vasthe.in, 1 +vasya-com.tk, 1 +vasya-odyag.tk, 1 +vasyaka.ga, 1 +vasyharan.com, 1 +vat-eu.com, 1 +vat.direct, 1 +vatav.eu, 1 +vatav.tk, 1 +vatikantour.tk, 1 +vato.nl, 1 +vats.im, 1 +vattulainen.fi, 1 +vauceri.hr, 1 +vaugarnier.fr, 1 +vaughanrisher.com, 1 +vault.investments, 1 +vault.spdns.eu, 1 +vault81.de, 1 +vaultlegal.com.au, 1 +vaultproject.io, 0 +vaur.fr, 1 +vaurio.tk, 1 +vavada.com, 1 +vave.men, 1 +vavel.com, 1 +vavra.us, 1 +vawebsite.co, 1 +vawlt.io, 1 +vawomenshealth.com, 1 +vaxbook.com, 1 +vaxxwatch.org, 1 +vayaport.com, 1 +vayaprecio.es, 1 +vayavotarcolorado.gov, 1 +vaygren.com, 1 +vazgaming.com, 0 +vazovia.com, 1 +vb.media, 1 +vbabe.tube, 0 +vbazile.com, 1 +vbelgorode.tk, 1 +vbestproduct.com, 1 +vbestseller.com, 1 +vbezhenar.com, 1 +vbql.me, 1 +vbsoft.cz, 1 +vburyatii.ml, 1 +vbwinery.com, 1 +vc.gg, 0 +vcacursus.nl, 1 +vcanederland.nl, 1 +vccmurah.net, 1 +vcelin-na-doliku.cz, 1 +vcf.gov, 1 +vchelyabinske.tk, 1 +vcm.ru, 1 +vcmi.download, 1 +vconcept.ch, 1 +vconcept.me, 1 +vconstruct.com, 1 +vcps.com, 1 +vcraftaudio.com, 1 +vcsjones.codes, 1 +vcsjones.com, 1 +vcsource.tk, 1 +vcti.cloud, 1 +vctor.net, 1 +vcz.fr, 1 +vczk.me, 1 +vd42.net, 1 +vda.li, 1 +vdagestan.tk, 1 +vdb-it.com, 1 +vdbongard.com, 1 +vdcomp.cz, 0 +vddruckwerk.de, 1 +vdemuzere.be, 1 +vdesc.com, 1 +vdheyden.net, 1 +vdisk24.de, 1 +vdlegal.com, 1 +vdmeij.com, 1 +vdo-webshop.nl, 1 +vdocapp.com, 1 +vdolg2000rub.ga, 1 +vdolg2000rub.ml, 1 +vdolg8000rub.cf, 1 +vdolg8000rub.ga, 1 +vdolg8000rub.gq, 1 +vdolg8000rub.ml, 1 +vdolg8000rub.tk, 1 +vdownloader.com, 1 +vdrpro.com, 1 +vdw-instruments.com, 1 +ve.search.yahoo.com, 0 +ve3oat.ca, 1 +ve3zsh.ca, 0 +vebbankir-zajm-onlajn.gq, 1 +vebdengi.tk, 1 +veblr.com, 1 +veca.tk, 1 +vecchiofornobarletta.it, 1 +vechainstats.com, 1 +vecherka.tk, 1 +vechersky.tk, 1 +vectomatic.org, 1 +vectops.com, 1 +vectorcardiometry.tk, 1 +vectordtg.com, 0 +vectormagnetics.com, 1 +vectorsiriushockeyclub.com, 1 +vectortrack.com.au, 1 +vectorwish.com, 1 +vectro.me, 1 +vectrum.cf, 1 +vecturagames.com, 1 +vedatkarabacak.av.tr, 1 +vedev.io, 1 +vedika.site, 1 +vedma-praktik.com, 1 +vedshastradata.in, 1 +veeculinary.com, 1 +veegish.com, 1 +veessen.tk, 1 +veg-leiden.nl, 1 +veg.lv, 0 +vega-diva.com, 1 +vega-rumia.com.pl, 1 +vega-rumia.pl, 0 +vegabuhar.net, 1 +vegalitarian.org, 1 +vegan-pratique.fr, 1 +vegandelivery.cz, 1 +vegane-proteine.com, 1 +veganenumbers.com, 1 +vegangaymer.blog, 1 +veganism.co.uk, 1 +veganism.com, 1 +veganmasterrace.com, 1 +veganoos.com, 1 +veganrecipereviews.com, 1 +vegardit.com, 1 +vegascasino.news, 1 +vegasluxuryestates.com, 1 +vegavio.com, 1 +vegculinary.com, 1 +vege-tables.fr, 1 +vegekoszyk.pl, 1 +vegepa.com, 1 +vegetabio.com, 0 +vegetariantokyo.net, 1 +vegetarier-sind-moerder.tk, 1 +veggie-einhorn.de, 1 +veggies.tk, 1 +vegoresto.fr, 1 +vegornonveg.com, 1 +vegtelenchat.tk, 1 +vehicleenquiry.service.gov.uk, 1 +vehiclematsuk.com, 1 +vehicletax.service.gov.uk, 1 +vehicletransportservices.co, 1 +veii.de, 1 +veikkosimpanen.fi, 1 +veil-framework.com, 1 +veilofsecurity.com, 1 +veincenterbrintonlake.com, 1 +veinexpertspa.com, 1 +vejanoticias.com.br, 1 +vejas2004.tk, 1 +vejersferie.de, 1 +vejersferie.dk, 1 +vekashka.gq, 1 +vekenz.com, 1 +vektlofting.tk, 1 +vektor.tk, 1 +vektorparts.ru, 1 +velacartagena.tk, 1 +velasense.com, 1 +velassoltas.com, 1 +velassoltas.pt, 1 +velen.io, 1 +velforo.com, 1 +velikijhutir.cherkassy.ua, 1 +velis.tk, 1 +vellingetaxi.se, 1 +velo-volga.tk, 1 +velobar.plus, 1 +velocitycu.com, 1 +velocityfiber.com, 1 +velocitygames.tk, 1 +velocompany.com, 1 +velocompany.de, 1 +velonustraduction.com, 1 +velorail01.fr, 1 +veloroute.hamburg, 1 +velosipedi.tk, 1 +veluwerally2002.tk, 1 +velvet-tarantula.tk, 1 +velvetempire.tk, 1 +velvetia.no, 1 +venacifuentes.tk, 1 +venali.tk, 1 +venalytics.com, 1 +venbraca.com, 1 +venclave.com, 1 +vendasdealbunsbrasil.tk, 1 +vendela.tk, 1 +vendermicasarapido.com.mx, 1 +vendi.it, 1 +vendigital.com, 1 +venditorepoa.com.br, 1 +vendorconnect.nyc, 1 +vendorpedia.com, 1 +vendreacheter.be, 1 +vendreacheter.net, 1 +vendserve.eu, 1 +veneerssandiego.com, 1 +venenum.org, 1 +venera-magik.tk, 1 +venesuela.cf, 1 +venetkaarsenovart.com, 1 +venev.com, 1 +venev.name, 1 +venezia.ga, 1 +venezuelachat.tk, 1 +venezuelalibre.tk, 1 +venga.tk, 1 +vengriya.tk, 1 +venicecakes.ga, 1 +venicecomputerrepair.com, 1 +venicefl.gov, 1 +venicefloridawebsitedesign.com, 1 +venicerealdeal.com, 1 +venlafaxine.gq, 1 +venmail.net, 1 +vennaccounts.com, 1 +vennprime.com, 1 +venomapps.com, 1 +venomxsecurity.com, 1 +venstar.com, 1 +ventajasdesventajas.com, 1 +ventana.kz, 1 +ventassantillan.com, 1 +venti-athens.gr, 1 +ventilateurs-plafond.com, 1 +ventizo.com, 1 +ventnose.com, 1 +ventolin-hfa.tk, 1 +ventolin.ga, 1 +ventosurf.nl, 1 +ventriloservers.biz, 1 +venturavwparts.com, 1 +venture-ridge.com, 1 +venturebanners.co.uk, 1 +venturebum.net, 1 +ventures.lgbt, 1 +ventureslgbt.com, 1 +venturum.com, 1 +venturum.de, 1 +venturum.eu, 1 +venturum.net, 1 +venuedriver.com, 1 +venusbeautyproducts.in, 1 +venzagroup.com, 1 +venzocrm.com, 0 +veosvending.com, 1 +veply.com, 1 +verakoubova.net, 1 +veramagazine.jp, 0 +verasani.ch, 1 +verasani.com, 1 +verata.co, 0 +verberne.nu, 1 +verbier-lechable.com, 1 +verbierfestival.com, 0 +verbio.com, 1 +verbmaestro.com, 1 +verboom.co.nz, 1 +verbzilla.com, 1 +vercel.co, 1 +vercel.com, 1 +vercel.email, 1 +vercel.org, 1 +vercel.sh, 1 +vercettipropiedades.cl, 1 +vercopy.com, 1 +verdeandco.co.uk, 1 +verdensflag.dk, 1 +verdeplus.net, 1 +verdesfoundation.org, 1 +verdict.gg, 1 +verduccies.com, 1 +verdugosxerecistas.tk, 1 +veredadelaestrella.tk, 1 +verein-kiekin.de, 1 +verein-zur-pflege-der-geselligkeit.de, 1 +vereinlandwege.de, 1 +vereinscheck.de, 1 +vereinswahl.online, 1 +verena.gallery, 1 +verepeliculashd.com, 1 +vereshagino.tk, 1 +verfassungsklage.at, 1 +verge.capital, 1 +vergeaccessories.com, 1 +vergelijksimonly.nl, 1 +vergelijkwitgoed.nl, 1 +vergessen.cn, 1 +vergraal.tk, 1 +verhaltenstherapie-weiden.de, 1 +verhaslaw.com, 1 +verhovs.ky, 0 +veri2.com, 1 +verifalia.com, 1 +verified.eu, 1 +verifiedjoseph.com, 1 +verifiny.com, 1 +verifyos.com, 1 +verifyyourip.com, 1 +veriomed.com, 1 +veripn.com, 1 +veritafineviolins.com, 1 +veritas-data.de, 1 +veritashomeschoolers.org, 1 +veritasinvestmentwealth.com, 1 +verius.io, 1 +verizonconnect.com, 0 +verizonguidelines.com, 0 +verkeer.gent, 1 +verkeersschoolrichardschut.nl, 1 +verkiezingsuitslagen.nl, 1 +verkkovalmentajat.fi, 1 +verkossa.tk, 1 +verksampsykologi.com, 1 +verlag-lq.at, 1 +verlag-lq.ch, 1 +verlag-lq.com, 1 +verlag-lq.de, 1 +verlag-lq.net, 1 +verlagdrkovac.de, 0 +verlaglq.com, 1 +verlete.com, 1 +verliebt-in-bw.de, 1 +verliebt-in-niedersachsen.de, 1 +verliefde-jongens.nl, 1 +verloskundigepraktijktolmiea.nl, 1 +vermaeckbouw.nl, 1 +vermageringsdieetpillen.gq, 1 +vermeerdealers.com, 1 +vermellcollection.com, 1 +vermiliontaxiservice.com, 1 +vermogeninkaart.nl, 1 +vermouth.cf, 1 +vermuetje.nl, 1 +vernaeve-usedcars.be, 0 +vernis-marins.com, 1 +vernonfigureskatingclub.com, 1 +vernonfilmsociety.bc.ca, 1 +vernonreinike.com, 1 +vernonsecureselfstorage.ca, 1 +vernonspeedskatingclub.com, 1 +vernonwintercarnival.com, 1 +veronic.hu, 1 +veronique-huon-photographe.fr, 1 +veronique-schmitz.de, 1 +veros-volejbal.tk, 1 +verrerie-mousseline.org, 0 +verry.org, 1 +vers.one, 1 +versagercloud.de, 1 +versalhost.nl, 1 +versallesin.com, 1 +versatek.com, 1 +versbesteld.nl, 1 +verschoren.com, 1 +verschurendegroot.nl, 1 +verses.space, 1 +versfin.net, 1 +versicherungen-werner-hahn.de, 1 +verso.money, 1 +verspai.de, 0 +verstaanwiskunde.co.za, 1 +verstka.cf, 1 +verstraetenusedcars.be, 0 +vertaxaccountants.co.uk, 1 +vertebrates.com, 1 +verteilergetriebe.info, 1 +vertexlife.ml, 1 +vertexlife.tk, 1 +vertexventures.co.il, 1 +vertexventures.sg, 1 +verticesedge.com, 1 +vertichost.com, 1 +verticrew.com, 1 +vertigo.name, 0 +vertikal.tk, 1 +vertrauen.site, 1 +vertretungsplan.io, 1 +vertrieb-strategie.de, 1 +verustracking.com, 1 +vervewellness.co.nz, 1 +verwandlung.org, 1 +verwayen.com, 1 +verwer-infra.nl, 1 +veryapt.com, 1 +verybin.com, 1 +veryestate.com, 1 +verygoodwebsite.ca, 1 +veryhappy.ru, 0 +veryhome.com.pe, 1 +verymelon.de, 1 +verymetal.nl, 1 +verysmartbrothas.com, 1 +veryssl.com, 1 +veryswing.com, 1 +verzekerdbijhema.nl, 1 +verzekeringsacties.nl, 1 +verzekerjebeter.nl, 1 +verzi.ru, 1 +verzick.com, 1 +vesaviljanen.fi, 1 +vescudero.net, 1 +veseleruska.sk, 1 +veselka.tk, 1 +veselyjpovar.gq, 1 +vesinhcongnghiepttchome.com, 1 +vespacascadia.com, 1 +vestacp.top, 1 +vestakassa-online.cf, 1 +vestasib.ru, 1 +vestberry.com, 1 +vestd.com, 1 +vestibtech.com, 1 +vestibular.science, 1 +vestibulartechnologies.com, 1 +vestiizhevska.cf, 1 +vestingbar.nl, 1 +vestlundbolargen.tk, 1 +vestnik24.cf, 1 +vestum.ru, 1 +vesuvio.tk, 1 +vet4life.co.uk, 1 +vetapp.net, 1 +vetbits.com, 0 +vetcard.info, 1 +vetch.ga, 1 +vetcpd.co.uk, 1 +veteranreservecorps.com, 1 +veteransadvantage.com, 1 +veterinario.milano.it, 1 +veterinario.roma.it, 1 +veterinarioaltea.com, 1 +veterinary-colleges.com, 1 +veterinaryhelp.cf, 1 +veterinarylabsupply.com, 1 +veterinaryvision.co.uk, 1 +veteriner.name.tr, 1 +vetinte.eu, 1 +vetitus-teatro.tk, 1 +vetmedstat.com, 1 +vetnet.info, 1 +veto.fish, 1 +vetofish.com, 1 +vetosh.tk, 1 +vetputten.nl, 1 +vetren.tk, 1 +vets.gov, 1 +vetscore.co.za, 1 +vetsmarketing.co.za, 1 +vettenburg.eu, 1 +vetustainversion.com, 1 +vetvim.com, 1 +vetwebsuccess.com, 1 +veules-les-roses.fr, 1 +veverusak.cz, 1 +vezirecenzii.ro, 1 +vfdworld.com, 1 +vfmc.vic.gov.au, 1 +vfmg.ch, 1 +vfn-nrw.de, 1 +vfr-oc.com, 1 +vfwauxiliary.org, 1 +vfxstudy.com, 1 +vg-store.ir, 1 +vgatest.nl, 1 +vgchat.us, 1 +vgcheat.com, 1 +vgerak.com, 1 +vglist.co, 1 +vgolos.zt.ua, 1 +vgopilot.azurewebsites.net, 1 +vgorcum.com, 1 +vgpu.vladimir.ru, 1 +vgropp.de, 1 +vgywm.com, 1 +vhasurvey.org, 1 +vhproductions.tk, 1 +vhs-bad-wurzach.de, 1 +vhummel.nl, 1 +via-shire-krug.ru, 0 +viacation.co, 1 +viacdn.org, 1 +viacheslavpleshkov.com, 1 +viafinance.cz, 0 +viaggio-in-cina.it, 1 +viaggivistos.com.br, 1 +viagra4men.com, 1 +viagratop.tk, 1 +viagusto.pl, 1 +viajandoporelmundo.com.ar, 1 +viajantesturismo.com, 1 +viajaramsterdam.com, 1 +viaje-a-china.com, 1 +vialibido.com.br, 1 +viamilitaris.net, 1 +vianetz.com, 1 +viaprinto.de, 1 +vias-ferratas.tk, 1 +viasinc.com, 0 +viasun.ru, 1 +viato.fr, 1 +viatvperu.com, 1 +viaura.biz, 1 +vibetribe.co.za, 1 +vibgyorhigh.com, 1 +vibgyorrise.com, 1 +vibgyyor.com, 1 +vibraagenciadigital.com.br, 1 +vibramycin100mg.tk, 1 +vibrant-america.com, 1 +vibrato1-kutikomi.com, 1 +vicarious.cf, 1 +vicenage.com, 1 +vicenez.agency, 1 +vicentaburon.tk, 1 +vicentediaz.mx, 1 +vicentejr.com.br, 1 +vicenterodriguez81.tk, 1 +vicentico.tk, 1 +vicescorts.ga, 1 +viceversa.co.il, 1 +vichama.pe, 1 +vichiya.com, 1 +vician.cz, 1 +vicicode.com, 1 +vicioanimal.pt, 1 +viciousflora.com, 1 +vicjuwelen-annelore.be, 1 +vickyflipfloptravels.com, 0 +vickylarraz.tk, 1 +vickyoliver.tk, 1 +victora.com, 1 +victorblomberg.se, 1 +victorbuch.cf, 1 +victorcalvez.com, 1 +victorcanera.com, 1 +victorcarrasco.tk, 1 +victorcarwasher.com, 1 +victoreriksson.ch, 1 +victoreriksson.co, 1 +victoreriksson.es, 1 +victoreriksson.eu, 1 +victoreriksson.info, 1 +victoreriksson.me, 1 +victoreriksson.net, 1 +victoreriksson.nu, 1 +victoreriksson.org, 1 +victoreriksson.se, 1 +victoreriksson.us, 1 +victoreriksson.xyz, 1 +victorhawk.com, 1 +victorhorta.tk, 1 +victoria-legis.ru, 1 +victoria.associates, 1 +victoriaartist.ru, 1 +victorianosaez.tk, 1 +victoriastudio.ru, 1 +victorique.moe, 1 +victorjacobs.com, 0 +victornet.de, 1 +victoroilpress.com, 1 +victorpelletmill.com, 1 +victorricemill.com, 1 +victorrodriguez.ml, 1 +victorunix.com, 1 +victory.radio, 1 +victoryalliance.us, 1 +victoryaveu.com, 1 +victorychurch.org.tw, 1 +victusrp.gq, 1 +vicugna.nl, 1 +vicyu.com, 1 +vid-eo.click, 1 +vid.me, 0 +vidadu.com, 1 +vidaforanea.com.mx, 1 +vidanuevaparaelmundo.net, 1 +vidapositiva.tk, 1 +vidarity.com, 1 +vidasanayfitness.com, 1 +vidassemfronteiras.com, 1 +vidatantrica.com, 1 +vidawichi.tk, 1 +vidaxp.com, 1 +vidb.me, 1 +vidbooster.com, 0 +vidbuchanan.co.uk, 1 +vide-dressing.org, 0 +vide-greniers.org, 0 +vide-maisons.org, 0 +videferre.tk, 1 +videoarcadia.cf, 1 +videobola.win, 1 +videobrochuresmarketing.com, 1 +videocall.guide, 1 +videochums.com, 1 +videoconferencing.guide, 1 +videoebook.tk, 1 +videogamer.com, 1 +videogamerreader.tk, 1 +videogamesartwork.com, 1 +videograb.ml, 1 +videojuegos.com, 1 +videokaufmann.at, 1 +videoload.co, 1 +videomail.io, 1 +videomaniya.ml, 1 +videonika.tk, 1 +videopornoitaliana.com, 1 +videoprikol.cf, 1 +videoprikoly.ga, 1 +videoremote.tk, 1 +videosdiversosdatv.com, 1 +videoseriesbiblicas.com, 1 +videoseyredin.net, 1 +videoskaseros.com, 1 +videoskazka.tk, 1 +videosparatodos.com, 1 +videosporno.life, 1 +videosqr.com, 1 +videostop.asia, 1 +videot.tk, 1 +videotehnika.tk, 1 +videoueberwachung-set.de, 1 +videouroki.ml, 1 +videov.tk, 1 +videovt.tk, 1 +videownload.com, 1 +videozv.tk, 1 +videt-son.cf, 1 +vidimte.eu, 1 +vidiobokep.xyz, 1 +vidiproject.com, 1 +vidister.de, 0 +viditour-golf.nl, 1 +viditour-zorg.nl, 1 +vidkovaomara.si, 1 +vidlyoficial.com, 1 +vidmia.com, 1 +vidracariaespelhosbh.com.br, 1 +vidsify.co.uk, 1 +vidyabhavanam.org, 1 +vidyamonk.com, 1 +vieaw.com, 1 +viega.be, 1 +viega.ca, 1 +viega.com, 1 +viega.com.au, 1 +viega.cz, 1 +viega.es, 1 +viega.fr, 1 +viega.hr, 1 +viega.in, 1 +viega.sk, 1 +viega.us, 1 +viekelis.lt, 0 +viemeister.com, 1 +viemontante.be, 0 +viennadancecrew.at, 1 +vientos.coop, 0 +viepixel.at, 1 +viera.pe, 1 +vierdaagsehotel.nl, 1 +vieref.eu, 1 +viereview.com, 1 +vierna.ga, 1 +vierpfeile.de, 1 +vierpluseins.wtf, 1 +vietnam-lifer.com, 1 +vietnam-tours.tk, 1 +vietnamese.dating, 1 +vietnamhairs.com, 1 +vietnamholic.vn, 1 +vietnamhost.vn, 0 +vietnamluxurytravelagency.com, 1 +vietnamphotoblog.com, 0 +vietnamtravelmart.com.vn, 1 +vietnamwomenveterans.org, 1 +vieux.pro, 1 +vievolution.tk, 1 +view-page-source.com, 1 +viewbook.com, 1 +vieweb.tk, 1 +viewer.ga, 1 +viewey.com, 1 +viewflix.win, 1 +viewing.nyc, 1 +viewmythoughts.com, 1 +viewpointsfromfacebook.com, 1 +viewsea.com, 1 +viewzipcode.com, 1 +vifranco.cl, 1 +vifsoft.com, 1 +vigilanciatotal.com, 1 +vigilanciaysalud.com, 1 +vigilantesporcolombia.org, 1 +vigilantnow.com, 0 +vigira.com.ar, 1 +vigliano.com, 1 +vignaud.fr, 1 +vigneshkumar.com, 1 +vignoblesdeletat.ch, 1 +vigo-krankenversicherung.de, 1 +vigo-select.de, 1 +vigoinvestments.com, 1 +vigorspa.it, 1 +vigoxatelier.tech, 0 +vigrey.com, 1 +vigridpartiet.tk, 1 +vihotar.com, 1 +viikko.cf, 1 +viikko.eu, 1 +viikko.ga, 1 +viikko.gq, 1 +viikko.ml, 1 +viilup.com, 1 +vijay-international.com, 1 +vijayam.ml, 1 +vijaymishra.tk, 1 +vijoe.org, 1 +vijverbenodigdheden.nl, 1 +vik.im, 1 +vikalbino.com.br, 1 +vikalpgupta.com, 1 +vikapaula.com, 1 +vikashkumar.me, 1 +vikaviktoria.com, 1 +viking-style.ru, 1 +vikramkulkarni.com, 1 +vikrammaheshwari.com, 1 +viktor-chin-kon-sung.com, 1 +viktor-chin-kon-sung.nl, 1 +viktor-chin-kon-sung.online, 1 +viktor-chin-kon-sung.site, 1 +viktor-chin.com, 1 +viktor-chin.nl, 1 +viktor-chin.online, 1 +viktor-chin.site, 1 +viktorbarzin.me, 1 +viktorchin.com, 1 +viktorchin.nl, 1 +viktorchin.online, 1 +viktorchin.site, 1 +viktorchinkonsung.com, 1 +viktorchinkonsung.nl, 1 +viktorchinkonsung.online, 1 +viktorchinkonsung.site, 1 +viktoria-goo.com, 1 +viktorovi.cz, 1 +viktorprevaric.eu, 1 +viku.fi, 1 +vila-eden.cz, 1 +vilabiamodas.com.br, 1 +vilafloridacapivari.com.br, 1 +vilamarija.tk, 1 +vilantice.cz, 1 +vilaydin.com, 1 +vildlaithailand.cf, 1 +vilgain.com, 1 +vilhe.com, 1 +vilhe.fi, 1 +vilhelmjunnila.fi, 1 +vilife.tk, 1 +viliravnjak.tk, 1 +viljatori.fi, 1 +villa-gockel.de, 1 +villa-luna.it, 1 +villa-romantica-zillertal.at, 1 +villa-toscana.berlin, 1 +villablino.tk, 1 +villacarralon.tk, 1 +villadelprado.tk, 1 +villaditirano.tk, 1 +villaespanola.tk, 1 +villafiore.com.br, 1 +villagecardshop.co.uk, 1 +villagecenterpediatrics.com, 1 +villagemagazines.co.uk, 1 +villagenscamuria.it, 1 +villageoftikiisland.gov, 1 +villagephysicians.com, 1 +villageunique.com.br, 1 +villagockel.de, 1 +villainsclothing.com.au, 1 +villaismaelcortinas.uy, 1 +villakarma.at, 1 +villalmanzo.tk, 1 +villamariaamalfi.it, 1 +villamenty.com, 1 +villanew.tk, 1 +villasdelbosque.com.gt, 1 +villasenor.online, 1 +villasfinistere.fr, 1 +villasforsale-bali.com, 1 +villaumbrales.tk, 1 +villavaltava.fi, 1 +villavasco.ovh, 1 +villaville.com, 1 +villawirz.it, 1 +ville-aime.fr, 1 +villehardouin.fr, 1 +villek.fi, 1 +villekaaria.eu, 0 +villekautto.com, 1 +villenavedornon.fr, 1 +villenvinkit.com, 1 +villerez.fr, 1 +villers-ecalles.fr, 1 +villesalonen.fi, 1 +villisek.fr, 1 +villitalia.nl, 1 +villu.ga, 1 +villu.stream, 1 +viltsu.net, 1 +vim.cx, 1 +vim.ge, 1 +vima.ch, 0 +vimeo.com, 1 +vimeosucks.nyc, 1 +vimium.com, 1 +vimka.gq, 1 +vimoksa.com, 1 +vimworld.com, 1 +vinarstvimodryhrozen.cz, 1 +vinaygakhar.tk, 1 +vinaygarg.com, 1 +vinc.me, 1 +vinc.name.tr, 1 +vincehut.top, 1 +vincent-haupert.de, 1 +vincentcox.com, 0 +vincenticosmeticsurgery.tk, 1 +vincentiliano.tk, 1 +vincentpo.tk, 1 +vincentsimon.de, 1 +vincentwolsink.nl, 1 +vinceracing.tk, 1 +vincexpertconsulting.fr, 1 +vincible.space, 1 +vinciconps4.it, 1 +vincie.net, 1 +vinciladislessia.it, 1 +vincitraining.com, 1 +vindafrid.com, 1 +vindafrid.nu, 1 +vindafrid.se, 1 +vindipoker.dk, 1 +vineethavarma.com, 1 +vinesauce.info, 1 +vineta.tk, 1 +vinetalk.net, 1 +vinetech.co.nz, 1 +vingt.me, 1 +vinicius.sl, 0 +viniciuscosta.tk, 1 +vinigas.com, 1 +vinilosdecorativos.net, 1 +vinistas.com, 1 +vinit.tk, 1 +vinktwebdesign.nl, 0 +vinmmo.com, 1 +vinner.com.au, 1 +vinnie.gq, 1 +vinnyandchristina.com, 1 +vinnyvidivici.com, 1 +vinodoc.cz, 1 +vinohradiv.tk, 1 +vinokurov.tk, 1 +vinolli.de, 1 +vinorossoconero.com, 1 +vinoshipper.com, 1 +vinovum.net, 1 +vinsation.com, 1 +vinsetchampagne.fr, 0 +vinsonconsulting.cl, 1 +vinsonfinancials.tk, 1 +vinstafood.com, 1 +vintagebandfestival.org, 1 +vintagecarparts.co.uk, 1 +vintagecaskandbarrel.com, 1 +vintagecommerce.it, 1 +vintagejeeps.net, 1 +vintagemakeupguide.com, 1 +vintageportgifts.co.uk, 1 +vintagesouthernpicks.com, 1 +vintagetoydepot.tk, 1 +vintagetrailerbuyers.com, 1 +vintazh.net, 1 +vinticom.ch, 0 +vinumenu.com, 1 +vinyl-digital.com, 1 +vinylfencestlouis.com, 1 +vinzer.tk, 1 +vinzite.com, 1 +viocleannettoyage.com, 1 +violarenate.com, 1 +violetfairy.tk, 1 +violetraven.co.uk, 1 +violettecleaning.be, 1 +violin4fun.nl, 1 +vionicbeach.com, 1 +vionicshoes.co.uk, 1 +vionicshoes.com, 1 +viosey.com, 1 +vip-agency-escort.com, 1 +vip-banner.tk, 1 +vip-moda.ga, 1 +vip-soski.tk, 1 +vip-ssl.com, 1 +vip.de, 1 +vip00228.com, 1 +vip11018.com, 1 +vip22884.com, 1 +vip22994.com, 1 +vip4553.com, 1 +vip6132.com, 1 +vip77018.com, 1 +vip8522.com, 1 +vipass.ca, 1 +vipcards.top, 1 +vipd88.net, 1 +vipdirektolog.ru, 1 +vipenvia.com.br, 1 +viperperformance.co.uk, 1 +vipesball.net, 1 +vipf88.com, 1 +vipfitter.com, 1 +viphackers.tk, 1 +vipi.es, 1 +vipkit.com, 1 +vipku.ru, 1 +viplata-mgnovenno.ml, 1 +viplc4.com, 1 +viplc6.com, 1 +viplc68.com, 1 +viplc98.net, 1 +vipllcnj.com, 1 +vipmdh.com.ua, 1 +vipom.com.ua, 1 +viporiflame.tk, 1 +vippclub.be, 1 +vips.pl, 1 +vipsauna.gq, 1 +vipshop.ga, 1 +vipsibir.cf, 1 +viptamol.com, 1 +viptravel.tk, 1 +vipturismo-europa.com, 1 +vipw66.com, 1 +vipw6600.com, 1 +vipw6603.com, 1 +vipw6606.com, 1 +vipw6608.com, 1 +viqo.pl, 1 +vir-tec.eu, 0 +vir2.me, 1 +viral32111.com, 1 +virala.tk, 1 +viralboombox.xyz, 1 +viralhua.com, 1 +viralinsurance.ga, 1 +viraljobs.ga, 1 +viraloffer.ga, 1 +viralpop.it, 0 +viralsv.com, 1 +viraltech.cf, 1 +viralted.ml, 1 +viraltube.my, 1 +viralvids.gq, 1 +virazh58.tk, 1 +vircloud.net, 1 +virgi.tk, 1 +virginiaabc.gov, 1 +virginiabeachcoolsculpting.com, 1 +virginiedelmas.fr, 1 +virgontech.tk, 1 +viridis-milites.cz, 1 +viris.si, 1 +viroc.in, 1 +virostack.com, 1 +virtbaza.cf, 1 +virtit.fr, 1 +virtlinux.eu, 1 +virtola.ml, 1 +virtool.ca, 1 +virtual-webcam.com, 1 +virtual.hk, 0 +virtualbrands.com, 0 +virtualbrestby.tk, 1 +virtualbruges.tk, 1 +virtualcitehuallaga.com, 1 +virtualcloud.ddns.net, 1 +virtualcommodities.org, 1 +virtualcomputer.ml, 1 +virtualdesignmedia.com, 1 +virtualgovernance.tk, 1 +virtuality4d.com, 1 +virtuallifestyle.nl, 1 +virtuallypilates.com, 1 +virtualmachine.tk, 1 +virtualmemento.tk, 1 +virtualmt2.pl, 1 +virtualprom.tk, 1 +virtualroad.org, 1 +virtualsanity.com, 1 +virtualscoutschool.com, 1 +virtualspeech.com, 1 +virtualtabletop.io, 1 +virtualvaults.com, 1 +virtualvitrine.com, 1 +virtualx.de, 1 +virtubox.net, 1 +virtubox.xyz, 1 +virtus-group.com, 1 +virtusaero.com, 1 +virtwen.com, 1 +virus.pm, 1 +virusah1n1.com, 1 +viruscare.info, 1 +virusdelebola.com, 1 +visa-master.tk, 1 +visabuddy.in, 1 +visadaifu.com, 1 +visadoparausa.com, 1 +visafruit.com, 1 +visalist.io, 1 +visalogy.com, 1 +visaop.com, 1 +visapourailleurs.fr, 0 +visarewardprogramplatform.com, 1 +visasofoz.com, 1 +visatitans.ae, 1 +visatitans.ca, 1 +visatitans.com, 1 +visaya.com.co, 1 +viscoelastico.com.br, 1 +visconapp.com, 1 +viscondedemaua.com.br, 1 +viscopic.com, 1 +viserproject.com, 0 +viseum.co.uk, 1 +vishenka.tk, 1 +vishnujyothi.co.uk, 1 +vishwashantiyoga.com, 1 +visibleone.com, 1 +visibox.nl, 1 +visikom.de, 1 +vision-painting.com, 1 +vision2005.tk, 1 +visionacademy.info, 1 +visionarymedia.nl, 1 +visiondetails.ru, 1 +visiondigitalpe.com, 1 +visiondigitalsog.com, 1 +visionduweb.fr, 1 +visionexpresscareers.com, 1 +visiongamestudios.com, 1 +visionless.me, 0 +visionnissancanandaiguaparts.com, 1 +visionnocturne.tk, 1 +visionthroughknowledge.com, 1 +visiontree-beta.eu, 1 +visionwow.ai, 1 +visionxcreative.gq, 1 +visit-thailand.tk, 1 +visitationbvm.net, 1 +visitbangkoktravel.com, 1 +visitbeulah.com, 1 +visitcambridgeshirefens.org, 1 +visiter-tunis.tk, 1 +visitgent.be, 1 +visitgent.eu, 1 +visitghent.be, 1 +visitghent.eu, 1 +visitislandpond.com, 1 +visitkangaroovalley.com.au, 1 +visitmaine.com, 1 +visitorguard.com, 1 +visitorsguide.is, 1 +visitorslist.com, 1 +visitrainscounty.com, 1 +visits.ga, 1 +visits.tk, 1 +visituzbekistan.tk, 1 +visitvalenca.com, 0 +visma-apps.com, 1 +visor.ph, 1 +visordown.com, 1 +visoundcloud.com, 1 +vissanum.com, 1 +visscher.codes, 1 +vista-calculator.ru, 1 +vistacampus.gov, 1 +vistastylebuilder.com, 0 +vistb.me, 1 +vistec-support.de, 1 +visto.cl, 1 +visual-cockpit.com, 0 +visual-concept.net, 1 +visual-design.cf, 1 +visualdrone.co, 1 +visualgnome.com, 1 +visualgrafix.com.mx, 1 +visualideas.org, 1 +visualiti.co, 1 +visualized.tech, 1 +visualizing.info, 1 +visuall.be, 1 +visualmarketingdeals.com, 1 +visualmasters.nl, 1 +visualstories.com, 1 +visudira.com, 1 +visuri.de, 1 +visvolunteers.com, 1 +visware.com, 1 +visyeva.hu, 1 +vitaalfitcoaching.nl, 1 +vitabsolu.fr, 1 +vitaen.nl, 1 +vitahook.pw, 1 +vitahost.ml, 1 +vitakov.tk, 1 +vital-pack.com, 1 +vital-tel.co.uk, 1 +vitalamin.at, 1 +vitalamin.ch, 1 +vitalamin.com, 1 +vitalastin-sport.de, 1 +vitalhealthandbeauty.co.uk, 1 +vitalia.cz, 1 +vitalismaatjes.nl, 1 +vitalium-therme.de, 1 +vitaliyshepotkov.tk, 1 +vitalos.com.br, 1 +vitalshop.tk, 1 +vitalthings.de, 1 +vitalware.com, 1 +vitalyzhukphoto.com, 1 +vitamaxxi.com.br, 1 +vitamed.ca, 1 +vitamina.cl, 1 +vitamina.com, 1 +vitaminka.tk, 1 +vitaminmovie.ga, 1 +vitaminoutlet.net, 1 +vitanayura.es, 1 +vitanyi.de, 1 +vitapingu.de, 1 +vitario.eu, 1 +vitastic.nl, 1 +vitavista.health, 1 +vitavista.io, 1 +viteoscrm.ch, 0 +viterboonair.tk, 1 +vitkausk.as, 1 +vitlproducts.com, 1 +vitoye.com, 1 +vitra-showrooms.co.uk, 1 +vitra-vcare.co.uk, 1 +vitrade.de, 1 +vitrado.de, 1 +vitrinachasov.cf, 1 +vitromex.tk, 1 +vitron.ru, 1 +vitsoft.by, 1 +vitta.ml, 1 +vitto.tk, 1 +vitus-meppen.de, 1 +viva.ua, 1 +viva2000.com, 1 +vivablogger.com, 1 +vivabraslav.ga, 1 +vivachile.tk, 1 +vivaio.roma.it, 1 +vivaiocolombo.com, 1 +vivalajack.de, 1 +vivaldi.club, 1 +vivaldi.com, 1 +vivaldi.net, 1 +vivamortgage.tk, 1 +vivanosports.com.br, 0 +vivantstays.com, 1 +vivapharma.net, 1 +vivas.gq, 1 +vivates.tk, 1 +vivatv.com.tw, 1 +vivavox.tk, 1 +vive.com, 0 +vive.link, 1 +viveconsalud.club, 1 +vivediabetes-sanamente.com, 1 +vivekanandaspokenenglish.com, 1 +vivelawir.eu, 1 +vivemedialab.com, 1 +vivemercadosaludable.com, 1 +vivendi.de, 1 +viveport.com, 1 +viveportal.com, 1 +viveras.ch, 1 +vivesaludableconomnilife.com, 1 +vivetoluca.com, 1 +vivi.fyi, 1 +vivi.zone, 1 +vivian.tk, 1 +vivianadavila.com, 1 +vivianmaier.cn, 1 +vivichannel.tk, 1 +vivid-academy.com, 1 +vivide.re, 1 +vividinflatables.co.uk, 1 +viviennelinettevandenassem.tk, 1 +viviennevandenbos.nl, 1 +vivirenelmundo.com, 1 +vivirenelpoblado.com, 1 +vivo.cam, 1 +vivo.sx, 1 +vivo.vn, 1 +vivoitaliankitchen.com, 1 +vivoregularizafacil.com.br, 1 +vivreenisrael.com, 1 +vivy.com, 1 +viwsec.com.br, 1 +vixrapedia.org, 1 +viyf.org, 1 +vizantia.tk, 1 +vize.ai, 0 +vizedia.ga, 1 +vizierdata.ca, 1 +vizija-nepremicnine.si, 1 +vizion.com, 1 +vizional.com, 1 +vizionnetwork.co.uk, 1 +vizit-obmen.tk, 1 +vizitfree.ml, 1 +vizitnik.tk, 1 +vizualbits.com, 1 +vjeff.com, 1 +vjeff.net, 1 +vjhfoundation.org, 1 +vjshi.xyz, 1 +vk-agent.ru, 1 +vk-k.com, 1 +vk-random.ml, 1 +vk1fj.net, 1 +vkarpaty.tk, 1 +vkavkaz.tk, 1 +vkb-remont.ru, 1 +vkennke.org, 1 +vkh-online.de, 1 +vkidsindia.com, 1 +vkikaku.com, 0 +vkino.com, 0 +vkirichenko.name, 1 +vkirienko.com, 1 +vkolledzhe.tk, 1 +vkox.com, 1 +vkr2020.herokuapp.com, 1 +vkrutilca.tk, 1 +vksportphoto.com, 1 +vkstream.tk, 1 +vkulagin.ru, 1 +vkusnyashka.tk, 1 +vkwebsite.ru, 1 +vl-grafikdesign.de, 1 +vlaamsegemeenschap.tk, 1 +vlaamsetollers.tk, 1 +vladgazeta.gq, 1 +vladikavkaz-city.tk, 1 +vladimir-chanaev.pro, 1 +vladimir.ml, 1 +vladimirbatrakov.tk, 1 +vladimirchernyshov.ml, 1 +vladimirkarpets.tk, 1 +vladimiroff.org, 1 +vladimirovka.ml, 1 +vladimirpenev.tk, 1 +vladislavstoyanov.com, 1 +vladivostok-city.tk, 1 +vladivostok.cf, 1 +vladivostok.tk, 1 +vladivostokportal.tk, 1 +vladsfads.com, 1 +vlaggen-landen.nl, 1 +vlajo.org, 1 +vlakem.net, 1 +vlance.gq, 1 +vlaser.es, 1 +vlasov.ml, 1 +vlasova-sova.ml, 1 +vlcentre.org, 1 +vldkn.net, 1 +vldz.co, 1 +vleesbesteld.nl, 1 +vleij.com, 0 +vleij.family, 1 +vleij.se, 1 +vleo.me, 1 +vliegensvlug.online, 1 +vliegensvlug.services, 1 +vlike.ml, 1 +vlinkinfo.com, 1 +vlissingse-oratoriumvereniging.nl, 1 +vlndc.org, 1 +vloeck.de, 1 +vloggerfaire.com, 1 +vlora.city, 1 +vlovgr.se, 1 +vlqnc.com, 0 +vlvvl.com, 1 +vlzbazar.ru, 1 +vm-0.com, 1 +vm-co.ch, 0 +vm0.eu, 1 +vmagadane.tk, 1 +vmagz.ir, 1 +vmautorajkot.com, 1 +vmc.co.id, 1 +vmccnc.com, 1 +vmem.jp, 0 +vmf365.tk, 1 +vmgirls.com, 1 +vmhomedesign.com, 0 +vmhydro.ru, 0 +vmis.nl, 1 +vmlze.cz, 1 +vmoagents.com, 0 +vmonetke.ru, 1 +vmsurgery.org, 1 +vmug.pl, 1 +vmurmanske.tk, 1 +vn.search.yahoo.com, 0 +vnctdj.fr, 1 +vnd.cloud, 1 +vndb.org, 1 +vneftekamske.tk, 1 +vnetboard.com, 1 +vnikolaev.tk, 1 +vnlfrk.com, 1 +vnministries.org, 1 +vnovosibirske.tk, 1 +vnpem.com, 1 +vnpem.store, 1 +vns168.vip, 1 +vns377c.com, 0 +vns377d.com, 0 +vns377e.com, 0 +vns377f.com, 0 +vns377g.com, 0 +vns377h.com, 0 +vns377i.com, 0 +vns377j.com, 0 +vns3780.com, 1 +vns5151.com, 0 +vns5353.com, 0 +vns5656.com, 1 +vns5757.com, 0 +vns5858.vip, 1 +vns5959.com, 0 +vns6161.com, 0 +vns6262.com, 1 +vns6363.com, 0 +vns6565.com, 1 +vns6767.com, 0 +vns68611.com, 0 +vns68655.com, 1 +vns68669.com, 1 +vns6868.com, 0 +vns6868.vip, 1 +vns68722.com, 1 +vns6969.com, 0 +vns89386.com, 1 +vnsc.org, 1 +vnvisa.ru, 1 +vobe.io, 1 +vocab.guru, 1 +vocaloid.my, 1 +vocalviews.com, 1 +vocationnetwork.org, 1 +vocescruzadasbcs.mx, 1 +vocus.aero, 1 +vocustest.aero, 1 +voda.org.ru, 1 +vodadombay.cf, 1 +vodafone.com.gh, 1 +vodavoda.tk, 1 +vodb.org, 1 +voddinteriors.com, 1 +vodicak.info, 1 +vodicaknapocitac.sk, 1 +vodpay.com, 1 +vodpay.net, 1 +vodpay.org, 1 +voetbalclubinfo.tk, 1 +voetbalforum.tk, 1 +voetbalindestad.be, 1 +voetfit47.nl, 1 +voeux.io, 0 +voevm.at, 1 +vofy.cz, 1 +vofy.tech, 0 +vogelbus.ch, 1 +vogler.name, 1 +vogonderzoek.nl, 1 +vogt.tech, 1 +vogue.co.uk, 1 +vogue.cz, 1 +voguefrontier.tk, 1 +voice-of-design.com, 1 +voicebrew.com, 1 +voicedata.tk, 1 +voiceofcricket.tk, 1 +voiceofserbia.tk, 1 +voicesoflabor.com, 1 +voicesofspirit.at, 1 +voicr.nl, 1 +voicu.ch, 0 +voidancerecords.com, 1 +voidbot.ai, 1 +voidbot.tk, 1 +voidcore.org, 1 +voidge.cf, 1 +voidi.ca, 1 +voidma.in, 1 +voidnya.com, 1 +voidpay.net, 1 +voidpay.org, 1 +voidptr.eu, 1 +voidx.top, 1 +voinuocsago.com, 1 +voinuocthienmy.com, 1 +voipsun.com, 1 +voix-bien-etre.com, 0 +vojenshandicap.dk, 1 +vojtat.cz, 1 +vokabl.io, 1 +vokalayedadgostary.com, 1 +vokativy.cz, 1 +vokeapp.com, 1 +vokrug.ga, 1 +vokurka.net, 1 +vokzalkursk.ru, 1 +vokzalperm.ru, 1 +volatile.pw, 1 +volatilesystems.org, 1 +volatilethunk.com, 1 +volatiliza.ga, 1 +volatimer.com, 1 +volcain.io, 1 +volcanconcretos.com, 1 +volcano-kazan.ru, 1 +volcano-spb.ru, 1 +volcano-ug.ru, 1 +volcano-vts.ru, 1 +volcano-x.ru, 1 +volcano.lt, 1 +volcano24.ru, 1 +volcano75.ru, 1 +volcanov.ru, 1 +volchara.tk, 1 +volga.us, 1 +volgavibes.ru, 0 +volgograd-34.tk, 1 +volgograd-privolzskiy.ga, 1 +volgograd34.tk, 1 +volha.tk, 1 +volin.tk, 1 +volk.ga, 1 +volk.gq, 1 +volkanyilmaz.com.tr, 1 +volker-gropp.de, 1 +volkergropp.de, 1 +volkerwesselstransfer.nl, 0 +volki.ga, 1 +volki.ml, 1 +volkov.ga, 1 +volksvorschlagpmar.ch, 1 +volkswagengolf.tk, 1 +volkswagenmiennam.com.vn, 1 +volkswurst.de, 1 +vollans.id.au, 0 +volleyballnews.tk, 1 +volleyfreaks.tk, 1 +volleypatos.tk, 1 +vollmondstollen.de, 1 +volochaevskiy.tk, 1 +volochisk.tk, 1 +voloevents.com, 1 +vologda-city.ga, 1 +vologda-city.tk, 1 +volosi.cf, 1 +volosi.tk, 1 +voloskova.ru, 1 +volosnet.tk, 1 +volqanic.com, 1 +volreinsistemas.com, 1 +voltageelectricity.tk, 1 +voltahurt.pl, 1 +voltainsite.com, 1 +voltarengelprice.tk, 1 +voltcloud.net, 1 +volto.io, 1 +volubilisplus.fr, 1 +volunka.ml, 1 +volunteeringmatters.org.uk, 1 +volunteers.tk, 1 +volvo1800es.tk, 1 +volvoconnect.com, 1 +vomitb.in, 1 +vomitoxin.ga, 1 +vonauw.com, 0 +vondelhof.com, 1 +vondenstein.com, 0 +vongdeophongthuy.com, 1 +vongerlach.at, 1 +vonimus.com, 1 +vonkuenheim.de, 1 +vonniehudson.com, 1 +vonpawn.com, 1 +vonski.pl, 1 +voodoobeginner.com, 1 +voodoocat.cf, 1 +voodoochile.at, 1 +voodoocomedy.com, 1 +voodooshaman.com, 1 +vooreenveiligthuis.nl, 0 +voorjou.com, 1 +voornaam-at-achternaam.be, 1 +vooxia.xyz, 1 +vop.li, 1 +voprosnik.gq, 1 +voprosownet.tk, 1 +vorbrodt.blog, 1 +vorderklier.de, 1 +vorkbaard.nl, 1 +vorlage-musterbriefe.de, 1 +vorlage-mustervertrag.de, 1 +vorlagen-geburtstagsgruesse.de, 1 +vorlonempire.org, 1 +vorm2.com, 1 +vorona.tk, 1 +vortari.tk, 1 +vortexhosting.ga, 1 +vos-fleurs.ch, 1 +vos-fleurs.com, 1 +vos-systems.com, 1 +vos-systems.es, 1 +vos-systems.eu, 1 +vos-systems.net, 1 +vos-systems.org, 1 +vos.directory, 1 +vosges-tourisme.net, 1 +vosgym.jp, 1 +voshod.org, 1 +vosjesweb.nl, 1 +vosk-cream.tk, 1 +vosky.fr, 1 +vosn.de, 1 +voss-klinik.com, 1 +voss-zaehne.com, 1 +voss-zaehne.de, 1 +vosselaer.com, 1 +vossenack.nrw, 1 +vosser.de, 1 +vostok-zapad54.ru, 1 +vostronet.com, 1 +vot-tak-vot.tk, 1 +votan.cf, 1 +vote.gov, 1 +vote.nz, 1 +vote.org, 1 +vote2019.appspot.com, 1 +vote4.hk, 1 +votebrevard.gov, 1 +votebymail.gov, 1 +votecitrus.gov, 1 +votehamiltoncountyohio.gov, 1 +votelevy.gov, 1 +votemarion.gov, 1 +votemate.org, 1 +votemoore.us, 1 +voteokaloosa.gov, 1 +voter-info.uk, 1 +voteurl.cf, 1 +votewa.gov, 1 +votoot.com, 1 +votre-agence-web.com, 1 +votre-avenir.com, 0 +votre-hotel.com, 1 +votresiteweb.ch, 0 +votrespace.ca, 1 +vous-etre-utile-ceidf.fr, 1 +vous-les-jeunnes.tk, 1 +vov.cloud, 1 +vov.furniture, 1 +vovac.tk, 1 +vovachka.tk, 1 +vovkamagazine.tk, 1 +vovladikavkaze.ru, 1 +vovo4ka.tk, 1 +vowsy.club, 0 +vox.de, 1 +voxel.sh, 1 +voxengo.com, 1 +voxfilmeonline.net, 1 +voxpopuli.com, 1 +voxsiren.net, 1 +voya.ga, 0 +voyage-evasion.com, 1 +voyage-martinique.fr, 1 +voyageat.com, 0 +voyageforum.com, 1 +voyageofyume.com, 1 +voyagesaufildespages.be, 0 +voyageschine.com, 1 +voyagewd.world, 1 +voyagewiki.com, 1 +voyagewiki.org, 1 +voyagewonders.com, 1 +voyancedanslenord.com, 1 +vozami.com, 1 +vozbudim.tk, 1 +vozdux.tk, 1 +vozhatik.cf, 1 +vozhuo.cf, 1 +vparilke.su, 1 +vpc-display.com, 1 +vpinball.com, 1 +vpn.black, 1 +vpn.ht, 1 +vpn4free.ga, 1 +vpnaustralianow.org, 1 +vpnboss.com.au, 1 +vpnemail.com, 1 +vpnguvnor.co.uk, 1 +vpnhongkong.gq, 1 +vpnmag.fr, 1 +vpnpro.com, 1 +vpnservice.nl, 1 +vpnstreamer.com.au, 1 +vponline.com.br, 1 +vprotect.ga, 1 +vps.hosting, 1 +vps.management, 1 +vpsao.org, 1 +vpsboard.com, 1 +vpsce.com, 1 +vpsdream.dk, 1 +vpsgongyi.com, 1 +vpsou.com, 1 +vpsport.ch, 1 +vpsproj.dynu.net, 1 +vpsrussia.com, 1 +vpstrial.net, 1 +vpsvz.cloud, 1 +vpsvz.net, 1 +vpsvz.ninja, 1 +vpswebs.tk, 1 +vqcymsa.com, 1 +vqebizconsulting.com, 1 +vqeg.org, 1 +vqn.se, 1 +vr-tops.ir, 1 +vr3marcas.com.br, 1 +vrachi.online, 1 +vractive.pl, 1 +vragenvanproust.nl, 1 +vrallart.com, 1 +vrandopulo.ru, 1 +vrba.org, 1 +vrbr.ch, 1 +vrcinvestigations.com, 1 +vrcprofile.com, 1 +vrcsearch.com, 1 +vredesregister.be, 1 +vredesregister.gent, 1 +vreeken-selfstorage.tk, 1 +vreeman.com, 1 +vremyachko.tk, 1 +vremyapervyih-hd.tk, 1 +vretmaskin.se, 1 +vreviewbestseller.com, 1 +vrfoodchannel.com, 1 +vrgamecritic.com, 1 +vrgametrailers.net, 1 +vriendenkring-klassiekers.tk, 1 +vriesdonkow.be, 0 +vrifox.cc, 1 +vrij-links.nl, 1 +vrijgezellen-feest.com, 1 +vrijgezellenfeestzwolle.com, 1 +vrikshamindia.com, 1 +vrimcas.com, 1 +vrisak-generacije.tk, 1 +vrjetpackgame.com, 1 +vrlaid.com, 0 +vrnhn.nl, 1 +vroedvrouwella.be, 1 +vros.co.id, 1 +vrostove.tk, 1 +vrsgames.com.mx, 0 +vrsystem.com.br, 1 +vrtouring.org, 1 +vrzl.pro, 1 +vs1177.com, 0 +vs1717.com, 0 +vs2277.com, 0 +vs2828.com, 0 +vs303.com, 1 +vs5050.com, 0 +vs5151.com, 0 +vs603.com, 1 +vs6060.com, 0 +vs6161.com, 0 +vs7711.com, 0 +vs8899.com, 1 +vs9911.com, 0 +vs9977.com, 0 +vsactivity.com, 1 +vsamsonov.com, 1 +vsaratove.tk, 1 +vsatke.tk, 1 +vsc-don-stocksport.de, 1 +vscale.io, 1 +vscm888.com, 1 +vscodownloader.net, 1 +vsd.sk, 1 +vse-bolezni.tk, 1 +vse-dlya-fermera.tk, 1 +vse-dlya-jinok.tk, 1 +vse-dlya-texniki.tk, 1 +vse-novosti.tk, 1 +vse-potolki.ml, 1 +vse-prosto.tk, 1 +vsean.net, 1 +vsec.co.il, 1 +vsekulinar.ru, 1 +vsem-privet.tk, 1 +vsenovosti.cf, 1 +vseostile.ml, 1 +vserisuem.ga, 1 +vserus.com, 1 +vserver-preis-vergleich.de, 1 +vseserialy.tk, 1 +vsesrazu-raiffeisen.ru, 1 +vsestoki.com, 1 +vsevkusno.tk, 1 +vshop.ir, 1 +vsl-defi.ch, 0 +vsl.de, 1 +vsoy.co.th, 1 +vspin.cz, 1 +vsportage.com, 1 +vss-clan.ml, 1 +vssnederland.nl, 1 +vstavropole.tk, 1 +vstgnstickers.dk, 1 +vstrikovaci-lisy.cz, 1 +vsund.de, 1 +vsx.ch, 1 +vsz.me, 1 +vtanki.tk, 1 +vtaxi.se, 1 +vtbs.moe, 1 +vthebest9.com, 1 +vtipe-vylez.cz, 0 +vtivision.com, 1 +vttnordisere.fr, 1 +vtuber-schedule.info, 1 +vtuber.art, 1 +vtul.io, 1 +vtupro.com, 1 +vuakhuyenmai.vn, 1 +vuasinhly.com, 1 +vubey.yt, 1 +vucdn.com, 1 +vuelacaruru.com, 1 +vuelosabajoprecio.net, 1 +vuilelakens.be, 1 +vulcancycling.ga, 1 +vuldb.com, 1 +vulgar-teens.tk, 1 +vuljespaarpot.nl, 1 +vulkanprotektor.rs, 1 +vulkanruhe.com, 1 +vulkanruhe.de, 1 +vullriede-multimedia.de, 0 +vulndetect.com, 1 +vulnerability.ch, 1 +vulnerabilityscans.nl, 1 +vulners.com, 1 +vulns.sexy, 1 +vulnscan.org, 1 +vulpine.club, 1 +vulpr.com, 1 +vultrhxl.com, 1 +vulyk-medu.com.ua, 1 +vunn.com, 1 +vuonthotuanh.com, 1 +vuotila.eu, 1 +vuoto.fi, 1 +vusdigital.com, 1 +vutruso.com, 1 +vutumusic.com, 1 +vuvanhon.com, 1 +vux.li, 1 +vuzi.fr, 1 +vv1234.cn, 1 +vv5197.co, 1 +vv6729.co, 1 +vv6729.com, 1 +vv6957.co, 1 +vv9297.co, 1 +vv9397.com, 1 +vv9721.com, 1 +vv9728.co, 1 +vvactivia.nl, 1 +vvcasteren.nl, 1 +vvdbronckhorst.nl, 1 +vveactiefbeheer.nl, 0 +vvg-vermietung.de, 1 +vvlen.com, 1 +vvoip.org.uk, 1 +vvs.spb.ru, 1 +vvsochenergiteknik.se, 1 +vvvvbrest.tk, 1 +vvw-8522.com, 1 +vvzero.cf, 1 +vvzero.com, 1 +vw-touranclub.cz, 1 +vwfsrentacar.co.uk, 1 +vwh-kunden.de, 1 +vwittich.de, 1 +vwo.com, 0 +vwoforangeparts.com, 1 +vwsoft.de, 1 +vwt-event.nl, 1 +vww-8522.com, 1 +vx.hn, 1 +vxapps.com, 1 +vxl.sh, 1 +vxm.se, 1 +vxst.org, 1 +vxz.me, 1 +vybavzahradu.cz, 1 +vybeministry.org, 1 +vyber-odhadce.cz, 1 +vyberodhadce.cz, 1 +vygeja.lt, 1 +vyplnto.cz, 1 +vyresimeonline.cz, 1 +vyroba.site, 1 +vyshivanochka.in.ua, 1 +vyshivki.net, 1 +vysko.cz, 1 +vyskocil.com, 1 +vyskocil.eu, 1 +vysokij-istochnik.tk, 1 +vysokoe.tk, 1 +vysotka.tk, 1 +vysvetluju.cz, 1 +vyuticonsulting.in, 1 +vyvod-iz-zapoya.online, 1 +vyzner.cz, 1 +vz.al, 1 +vzce.cn, 1 +vzemiseo.com, 1 +vzemisite.com, 1 +vztekloun.cz, 1 +vzwregent.be, 1 +vzyatonlinezaim.ga, 1 +vzyatonlinezaim.gq, 1 +vzyatonlinezaim.ml, 1 +vzyatonlinezaim.tk, 1 +vzyatzaimonline.cf, 1 +vzyatzaimonline.ga, 1 +vzyatzaimonline.gq, 1 +vzyatzaimonline.ml, 1 +vzyatzaimonline.tk, 1 +vzzjoias.com.br, 1 +w-architectes.com, 1 +w-oasis.co.jp, 1 +w-p-k.de, 1 +w-spotlight.appspot.com, 1 +w-surgeryhospital.com, 1 +w-w-auto.de, 1 +w-ws.ga, 1 +w.wiki, 1 +w000999.com, 1 +w00228.com, 1 +w0102.com, 1 +w0185.com, 1 +w0189.com, 1 +w0250.com, 1 +w045w.com, 1 +w0fw.com, 1 +w1010w.com, 1 +w10club.com, 0 +w123.co, 1 +w123123.com, 1 +w1n73r.de, 1 +w1nter.xyz, 1 +w234234.com, 1 +w2929w.com, 1 +w2design.eu, 1 +w2me.ru, 1 +w2n.me, 1 +w30365.com, 1 +w3330.com, 1 +w365.vip, 0 +w36533.com, 1 +w3app.nl, 1 +w3ctag.com, 1 +w3ctag.org, 1 +w3d.io, 1 +w3n.org, 1 +w3n14izy.cf, 1 +w3n14izy.ga, 1 +w3n14izy.gq, 1 +w3n14izy.ml, 1 +w3n14izy.tk, 1 +w3punkt.de, 1 +w3scan.nl, 1 +w3squad.com, 1 +w4.no, 1 +w456456.com, 1 +w4b.in, 1 +w4eg.de, 1 +w4nvu.org, 1 +w4r.nl, 1 +w4solutions.de, 1 +w4tec.de, 1 +w50.co.uk, 0 +w5050w.com, 1 +w51365.com, 1 +w5197.co, 1 +w555.com, 1 +w567567.com, 1 +w5gfe.org, 1 +w61516.com, 1 +w61518.com, 1 +w61611.net, 1 +w61616.com, 1 +w66001.com, 1 +w6603.com, 1 +w661122.net, 1 +w6612.net, 1 +w66133.com, 1 +w66133.net, 1 +w66136.com, 1 +w66136.net, 1 +w66138.net, 1 +w6616.com, 1 +w66161.com, 1 +w661616.com, 1 +w6619.com, 1 +w66191.com, 1 +w66191.net, 1 +w6631.com, 1 +w6637.com, 1 +w663w.com, 1 +w6648.com, 1 +w666.com, 1 +w66655.com, 1 +w6671.com, 1 +w66816.com, 1 +w6684.com, 1 +w668686.com, 1 +w668866.net, 1 +w668899.com, 1 +w668989.com, 1 +w66918.com, 1 +w66918.net, 1 +w66919.net, 1 +w66938.com, 1 +w6698.com, 1 +w66hao.net, 1 +w66w66.com, 1 +w6729.co, 1 +w6729.com, 1 +w678678.com, 1 +w6808.com, 1 +w6829.com, 1 +w6832.com, 1 +w6880.com, 1 +w6886.com, 1 +w692w.com, 1 +w6957.co, 1 +w6957.com, 1 +w6969.com, 1 +w696w.com, 0 +w789789.com, 1 +w7k.de, 1 +w80010.com, 0 +w8093.com, 1 +w8094.com, 1 +w81365.com, 1 +w81518.com, 1 +w81519.com, 1 +w82365.com, 1 +w84.it, 1 +w8605.com, 1 +w8628.com, 1 +w8659.com, 1 +w888022.com, 1 +w888033.com, 1 +w888044.com, 1 +w888066.com, 1 +w888077.com, 1 +w888088.com, 1 +w888099.com, 1 +w889-line.com, 1 +w889-line.net, 1 +w889889.com, 1 +w889889.net, 1 +w889vip.com, 1 +w88info.com, 1 +w88info.win, 1 +w88xinxi.com, 1 +w8less.nl, 1 +w8wat.com, 1 +w9196.com, 1 +w9297.co, 1 +w9297.com, 1 +w9397.com, 1 +w95.pw, 1 +w9710.com, 1 +w9720.com, 1 +w9721.com, 1 +w9728.co, 1 +w9730.com, 1 +w9740.com, 1 +w9750.com, 1 +w97a.com, 1 +w97aa.com, 1 +w97app.com, 1 +w97app2.com, 1 +w97app3.com, 1 +w97bb.com, 1 +w97cc.com, 1 +w99w99.com, 1 +wa-stromerzeuger.de, 0 +wa.me, 1 +waagen.tk, 1 +waaifu.com, 1 +waalsekrook.be, 1 +waavit.com, 1 +waays.eu, 1 +waays.fr, 1 +waayz.eu, 1 +waayz.fr, 1 +wabatam.com, 1 +wabbel.sa.com, 1 +wabifoggynuts.com, 1 +wachter.biz, 1 +wacken666.com, 1 +wacky-science.com, 1 +wacky.one, 1 +wackys.com, 1 +wade.gdn, 1 +wadebet.com, 1 +wadidi.com, 1 +wadsworth.gallery, 1 +wadvisor.com, 1 +waehlefamilie.de, 1 +waeldertexas.gov, 1 +waelisch.de, 1 +waelti.xxx, 1 +waf.hk, 1 +waf.ninja, 1 +waf.sexy, 1 +wafa4hw.com, 1 +wafelland.be, 1 +waffarcash.com, 1 +waffeln.jetzt, 1 +waffle-backend-sanggyu.shop, 1 +waffle-sanggyu.tk, 1 +waffleindex.com, 1 +wafflemachine.org, 1 +wafflemakers.ca, 1 +wafni.com, 1 +wafuton.com, 1 +wage-feeg.gc.ca, 1 +wagenmanswonen.nl, 1 +wageverify.com, 1 +wagn3r.de, 1 +wagnervineyards.com, 1 +wagspuzzle.space, 1 +wahhoi.net, 0 +wahine.gq, 1 +wahminda.tk, 1 +wahrnehmungswelt.de, 1 +wahrnehmungswelten.de, 1 +wai-in.com, 1 +waidfrau.de, 1 +waifu-technologies.com, 1 +waifu-technologies.moe, 1 +waifuist.pro, 1 +waikatowebdesigners.com, 1 +wail.net, 1 +waimanu.io, 1 +wains.be, 1 +waiomizik.re, 1 +wait.jp, 1 +waits.io, 1 +waiwaisw.com, 1 +waixingrenfuli.vip, 1 +wajtc.com, 1 +wak.io, 1 +waka-mono.com, 1 +wakamiyasumiyosi.com, 1 +wakandasun.com, 1 +wakarandroid.com, 1 +wakastream.cc, 1 +wakatime.com, 1 +wake.net, 1 +wakecountynorthcarolina.ml, 1 +wakeofthepredator.tk, 1 +wakeupworld.ml, 1 +wakf123.net, 1 +wakf456.com, 1 +wakiminblog.com, 1 +wakpamnilake-nsn.gov, 1 +wakuwakustudyworld.co.jp, 1 +wala-floor.de, 1 +walaamohamed.com, 1 +walden-interiors.com, 1 +waldenwritingcenter.ml, 1 +waldgourmet.de, 1 +waldo.tk, 1 +waldparkerwoelfe.tk, 1 +waldur.nl, 1 +waldvogel.family, 1 +walent.in, 1 +walentin.co, 1 +walhal.la, 1 +waligorska.pl, 0 +walk.onl, 1 +walker-foundation.org, 1 +walkera-fans.de, 1 +walkercountydemocrats.org, 1 +walkfordogs2017.nl, 1 +walkingandcycling.org.uk, 1 +walkingranada.com, 1 +walkingrehabilitation.com, 1 +walkinweb.com, 1 +walklocal.be, 1 +walklocal.gent, 1 +walkman.cloud, 1 +walkman.io, 1 +walksedona.com, 1 +walksfourpaws.co.uk, 1 +wall-banners.tk, 1 +wallabag.org, 1 +wallabet.fr, 1 +wallabies.org, 1 +wallabywallaroo.com, 1 +wallace-group.net, 1 +wallacealvesdigital.com.br, 1 +wallacehigh.org.uk, 1 +wallada.tk, 1 +wallbanksweb.net, 1 +walldisplaysapp.com, 1 +wallduck.com, 1 +wallendair.com, 1 +wallet.google.com, 1 +wallet.pp.ua, 1 +walletconnector.cz, 1 +walletfox.com, 1 +wallethub.com, 0 +wallett.gq, 1 +wallhost.tk, 1 +wallinger-online.at, 1 +wallingford.cc, 1 +wallinvogue.com, 1 +wallis-inside.ch, 1 +wallisch.pro, 1 +wallisdiervoeding.nl, 0 +wallmarketing.cz, 1 +wallnot.dk, 1 +wallpapers.pub, 0 +wallpaperup.com, 1 +wallrgb.com, 1 +walls.de, 1 +wallsauce.com, 1 +walltime.info, 1 +wallumai.com.au, 1 +wally4000.tk, 1 +wallysmasterblaster.com.au, 1 +walma.re, 1 +walnus.com, 1 +walnutgaming.com, 1 +walnutis.net, 0 +walpu.ski, 1 +walpuski.com, 1 +walravensax.nl, 1 +walruscode.com, 1 +walruses.org, 1 +walshbanks.com, 1 +walskifilm.com, 1 +waltellis.com, 1 +walter.lc, 1 +waltercedric.ch, 1 +waltercedric.com, 1 +waltervictor.com, 0 +waltravis.com, 1 +waltzmanplasticsurgery.com, 1 +walutomat.pl, 1 +walvi.nl, 1 +wamm.chat, 1 +wammu.eu, 1 +wan.pp.ua, 0 +wanabka.tk, 1 +wanashi.com, 1 +wanda.ch, 1 +wanda76.com, 1 +wanda79.com, 1 +wanda97.com, 1 +wanda98.com, 1 +wandelreizen.eu, 1 +wander.al, 1 +wanderersfc.tk, 1 +wanderfost.com, 1 +wanderinghiker.com, 1 +wandervoll.ch, 1 +wanderzoom.co, 1 +wandystan.eu, 1 +wane.co, 1 +wanekat.fr, 1 +wang.by, 1 +wangbangyu.cf, 1 +wangbangyu.ga, 1 +wangbangyu.gq, 1 +wangbangyu.ml, 1 +wangdaijin.com, 1 +wangjiatun.com.tw, 1 +wangluoyunying.com, 1 +wangqiliang.cn, 1 +wangqiliang.com, 1 +wangqiliang.org, 1 +wangql.cn, 1 +wangql.net, 1 +wangqr.org, 1 +wangqr.tk, 1 +wangriwu.com, 1 +wangshengze.com, 1 +wangtanzhang.com, 1 +wangwill.me, 1 +wangyubao.cn, 1 +wangyue.blog, 1 +wangzhan777.com, 1 +wangzhe100.xyz, 1 +wangzuan168.cc, 1 +wanlieyan.cc, 1 +wanlieyan.com, 1 +wannaknow.tk, 1 +wannapopularnews.cf, 1 +wannaridecostarica.com, 1 +wantocode.com, 1 +wanybug.cf, 1 +wanybug.cn, 1 +wanybug.gq, 1 +wanybug.tk, 1 +waonui.io, 1 +wap-umbrella.tk, 1 +wapa.gov, 1 +wapasrd.com, 1 +wapazewddamcdocmanui6001.azurewebsites.net, 1 +wapazewrdamcdocmanui6001.azurewebsites.net, 1 +wapbd.ga, 1 +wapflash.ml, 1 +wapgame.gq, 1 +wapgu.cc, 1 +wapheat.tk, 1 +wapkarma.tk, 1 +wapkat.tk, 1 +waplumber.com.au, 1 +wapnepal.com.np, 1 +wapnews.tk, 1 +wapoolandspa.com, 1 +wappie.tk, 1 +wapplerbrewing.com, 1 +wapspaces.tk, 1 +waptransfer.tk, 1 +wapveil.ml, 1 +waqood.tech, 1 +war-requiem.com, 1 +waranistudios.com, 1 +warbox.ga, 1 +warcraftjournal.org, 1 +ward.nl, 1 +ward2u.com, 1 +wardemons.tk, 1 +warden.navy, 1 +wardogz.tk, 1 +wardonat.tk, 1 +wardow.com, 1 +wardpieters.nl, 1 +wardslager.com, 1 +warebouncycastles.co.uk, 1 +warehost.de, 0 +warekit.io, 1 +warekon.com, 1 +warekon.dk, 1 +warenghem.com, 1 +warenhuisvandijk.nl, 1 +warenits.at, 0 +warenmedia.com, 1 +warezbook.org, 1 +warezoom.com, 1 +warfarina.com, 1 +warfield.org.uk, 1 +wargameexclusive.com, 1 +wargov.tk, 1 +wargun.ml, 1 +warispak.tk, 1 +warking.ml, 1 +warlions.info, 0 +warlords.cf, 1 +warmestwishes.ca, 1 +warmlyyours.com, 1 +warmservers.com, 1 +warmsquirrel.com, 1 +warmtepomp.express, 1 +warmteshop.com, 1 +warn-usa.com, 1 +waroengkoe-shop.com, 1 +waroengkopigazebo.net, 1 +warofelements.de, 1 +waronbrain.com, 1 +warp-radio.com, 1 +warp-radio.net, 1 +warp-radio.tv, 1 +warr.ath.cx, 1 +warrantycontracts.ga, 1 +warrantynowvoid.com, 1 +warrencountyga.gov, 1 +warrenhousevets.co.uk, 1 +warringtonkidsbouncycastles.co.uk, 1 +warrioronewgw.com, 1 +wars.cat, 1 +warschild.org, 1 +warsh.moe, 1 +warszawa-pranie-dywanow.pl, 1 +warszawa19115.pl, 1 +warteg.com, 1 +warteg.net, 1 +warthog.ml, 1 +wartimecontracting.gov, 1 +wartorngalaxy.com, 1 +wartraining.com.br, 1 +warupu.com, 1 +warworld.ml, 1 +wasabiwallet.co, 1 +wasabiwallet.io, 1 +waschmaschinen-dienst.de, 1 +waschpark-hantschel.de, 1 +wasd.ms, 1 +wasdestek.tk, 1 +wasema.com, 1 +wasfestes.de, 1 +wasfuereintheater.com, 1 +wasgehtheute.in, 1 +wasgigant.nl, 1 +wash-house.tk, 1 +washa.tv, 1 +washabich.ch, 1 +washburnenglishschool.tk, 1 +washcowi.gov, 1 +washcowisco.gov, 1 +washerrepairaustin.com, 1 +washingmachinesguide.in, 1 +washingtoncountyar.gov, 1 +washingtoncountywi.gov, 1 +washingtonnewsz.com, 1 +washingtonregisteredagent.com, 1 +washingtonregisteredagent.io, 1 +washingtonviews.com, 1 +washingtonwatchdog.org, 1 +washoedems.org, 1 +washsolucoesemlimpeza.com.br, 1 +washup.tk, 1 +wasi-net.de, 1 +wasido.com, 1 +wasielewski.com.de, 1 +wasithard.com, 1 +waskesiuapparel.com, 1 +wass.ga, 1 +wassenaar.org, 1 +wassibauer.com, 1 +wassim.is, 1 +wastafelmarkt.nl, 1 +wasteman.com, 1 +wastewaterservicesltd.co.uk, 1 +wastrel.ch, 1 +watari-bg.com, 1 +watashi.bid, 1 +watboeithet.nl, 1 +watch-host.ga, 1 +watch-wiki.org, 1 +watchcom.org.za, 1 +watchcow.org, 0 +watchdogs.tk, 1 +watchersrealm.tk, 1 +watchface.watch, 1 +watchfreeonline.co.uk, 1 +watchhentai.co, 1 +watchinventory.com, 1 +watchmetech.com, 1 +watchmoviesgallery.com, 1 +watchparts-and-tools-okayama.co.jp, 1 +watchstyle.com, 1 +watchtogether.ch, 1 +watchtolearn.co, 1 +watchweasel.com, 1 +watco.group, 1 +water-addict.com, 1 +water-filters.tk, 1 +water-net.ru, 1 +water-polo.tk, 1 +water-valley.tk, 1 +water.com, 1 +waterbrook.com.au, 1 +waterdamagehouston.us, 1 +waterdamageindiana.com, 1 +waterdogsmokedfish.com, 1 +waterdownmedia.co.uk, 1 +waterdrop.tk, 1 +waterfedpole.com, 0 +waterfrontonlakeoconee.com, 1 +waterheaterirvingtx.com, 1 +waterheaterleaguecity.com, 1 +waterleeftinbeek.nl, 1 +waterlemons2k.com, 1 +waterlemons2k.top, 1 +waterliteracy.tk, 1 +watermarkly.com, 1 +watermission.org, 1 +watermitigationspecialists.com, 1 +watermonitor.gov, 1 +wateroutlook.com, 1 +waterpoint.tk, 1 +waterpolosantona.tk, 1 +waterpolospain.tk, 1 +waterschaplimburg.nl, 1 +waterside-residents.org.uk, 1 +watersky.tk, 1 +watersoul.com, 1 +watersource.ga, 1 +waterstreetloft.com, 1 +watersview.co.uk, 1 +watertorenstraat.tk, 1 +watertownmn.gov, 1 +watertrails.io, 1 +watervillewomenscare.com, 1 +waterworkscondos.com, 1 +watestsite.ovh, 1 +watfordjc.uk, 1 +watgroeitwaar.com, 1 +watgroeitwaar.eu, 1 +watgroeitwaar.net, 1 +watgroeitwaar.nl, 1 +watgroeitwaar.org, 1 +watismijnbandenspanning.nl, 1 +watobi.jp, 1 +watoo.tech, 1 +watsonsurplus.com, 1 +wattmaedchen.de, 1 +watvindtnederland.com, 1 +watzijnmijnkerntalenten.nl, 1 +waukeect.com, 1 +waukeshairon.com, 0 +wav-productions.com, 1 +wav.tv, 1 +wave.is, 1 +wave.red, 1 +waveburst.net, 1 +wavee-plus.com, 1 +wavengine.com, 1 +waveous.com, 1 +wavered.cf, 1 +waverlypa.gov, 1 +waverlytn.gov, 1 +wavesboardshop.com, 1 +wavesite.tk, 1 +wawak.pl, 1 +wawapuquy.com, 1 +wawarsingny.gov, 1 +waxdramatic.com, 1 +waxlrs.com, 1 +waycoolmail.tk, 1 +waycraze.com, 1 +wayfair.ca, 1 +wayfair.co.uk, 1 +wayfair.com, 1 +wayfair.de, 1 +wayfairertravel.com, 1 +wayficdesign.com, 1 +waynecountyne.gov, 1 +waynecountyoh.gov, 1 +waynefranklin.com, 1 +wayneo.tk, 1 +wayohoo.com, 1 +wayohoo.net, 1 +waysandlore.consulting, 1 +waysandlore.fr, 1 +waysthat.com, 0 +waytofreedom.tk, 1 +waytt.cf, 1 +wayuanma.com, 0 +waze.com, 1 +wb-cw.tech, 1 +wb256.com, 1 +wba.or.at, 1 +wbbauth.de, 1 +wbbwbwebweb.cf, 1 +wbca.ca, 1 +wbcasaverde.co, 1 +wbci.us, 0 +wbclink.io, 1 +wbcme.co.uk, 0 +wbg.li, 1 +wbh.im, 1 +wbinnssmith.com, 1 +wblinks.com, 1 +wbookcompany.com, 1 +wbsogids.nl, 1 +wbt-solutions.ch, 1 +wbt-solutions.net, 1 +wbudd.com, 1 +wbut.ml, 1 +wbvb.nl, 1 +wby.by, 1 +wby.gd, 1 +wby.tw, 1 +wc-is.com, 1 +wc3modding.ml, 1 +wc64.org, 1 +wca.link, 1 +wcally.com, 1 +wcbook.ru, 0 +wcei.com.au, 0 +wcfauth.de, 1 +wcit2010.com, 1 +wck.com, 1 +wcloud.pro, 1 +wcn.life, 0 +wcrca.org, 1 +wctsite.tk, 1 +wcwcg.net, 1 +wd-api.com, 1 +wd-img.com, 1 +wd-ljt.com, 1 +wd36.cc, 1 +wd627.com, 1 +wd63.cc, 1 +wd976.com, 0 +wdambv.nl, 1 +wdesign.cl, 1 +wdesk.com, 1 +wdf.ink, 1 +wdic.org, 1 +wdmcheng.cn, 1 +wdmg.com.ua, 1 +wdmleds.com, 1 +wdmpa.org, 1 +wdnmd.online, 1 +wdntcr.com, 1 +wdodelta.nl, 0 +wdol.gov, 0 +wdpapi.io, 1 +wdpui.io, 1 +wdrl.info, 0 +wdt.cz, 0 +we-bb.com, 1 +we-run-linux.de, 1 +we-use-linux.de, 1 +we.serveftp.net, 1 +we.tc, 1 +we168168.com, 1 +we5688.net, 1 +we88fun.com, 1 +we9988.net, 1 +weacceptbitcoin.gr, 1 +wealthadvisorsmf.com, 1 +wealthcreationsolutions.ga, 1 +wealthprojector.com, 1 +wealthprojector.com.au, 1 +wealthreport.com.au, 1 +wealthsetsyoufree.com, 1 +wealthsuccess.edu.vn, 1 +wealthyspeakerschool.com, 1 +weaponsinhebrew.blog, 1 +wear-largesizes.tk, 1 +wear-referrals.co.uk, 1 +wearandcare.net, 1 +weare1inspirit.com, 1 +wearebase.com, 1 +wearebfi.co.uk, 1 +wearedevs.net, 1 +wearefrantic.com, 1 +wearegenki.com, 1 +wearehackerone.com, 1 +weareincognito.org, 1 +wearekiwi.com, 1 +weareoffstage.com, 1 +wearepapermill.co, 1 +wearepapermill.com, 1 +wearereasonablepeople.com, 1 +wearereasonablepeople.nl, 1 +wearesouthafricans.com, 1 +wearesuma.com, 1 +wearetravellers.nl, 1 +wearetuzag.com, 1 +wearewithyou.org, 1 +wearvintage.ml, 1 +wearvr.com, 1 +weather-schools.com, 1 +weather.gov, 1 +weather.gov.mo, 1 +weatherbuzzmedia.com, 1 +weatherforyou.com, 1 +weathermelon.io, 1 +weathermyway.rocks, 1 +weatherproduct.ga, 1 +weavers.space, 1 +web-3.ru, 1 +web-advisor.co.uk, 1 +web-apps.tech, 1 +web-aps.tk, 1 +web-art.cz, 1 +web-connected.com, 1 +web-cpv.ru, 1 +web-create.ml, 1 +web-creato.tk, 1 +web-demarche.com, 1 +web-design-india.com, 1 +web-design.co.il, 1 +web-desing.com.ua, 1 +web-disaster.tk, 1 +web-format.tk, 1 +web-hotel.gr, 1 +web-info.ir, 1 +web-it-entwicklung.de, 1 +web-jive.com, 1 +web-lab.ml, 1 +web-mastery.tk, 1 +web-odyssey.com, 1 +web-online.cf, 1 +web-ross.gq, 1 +web-ross.tk, 1 +web-siena.it, 1 +web-smart.com, 1 +web-space.design, 1 +web-studio-kzo.ml, 1 +web-test.gq, 1 +web-town.tk, 1 +web-wakakusa.jp, 1 +web-warrior.de, 1 +web-worker.cn, 1 +web.bzh, 1 +web.cc, 0 +web.de, 1 +web1212.top, 1 +web1n.com, 0 +web2033.com, 1 +web22.eu, 1 +web22.ro, 1 +web2ldap.de, 1 +web2screen.tv, 1 +web404.net, 1 +web74.ga, 1 +web76.tk, 1 +webaccio.com, 1 +webadiccion.net, 1 +webadicta.net, 1 +webadicto.net, 1 +webaeon.org, 1 +webaholic.co.in, 1 +webais.ru, 1 +webambacht.nl, 1 +webandmore.de, 1 +webandsun.com, 1 +webanet.eu, 1 +webannonces.tk, 1 +webanyti.me, 1 +webapky.cz, 1 +webappky.cz, 1 +webapplay.com, 1 +webaro.cloud, 1 +webart-factory.de, 1 +webartex.ru, 1 +webarxsecurity.com, 1 +webauthnlogin.com, 1 +webbanquyen.com, 1 +webbhuset.se, 0 +webbiz.co.uk, 1 +webbolivia.tk, 1 +webbricks.ru, 1 +webbuilder.de, 1 +webcam-lisa.ml, 1 +webcam-model.tk, 1 +webcamera-online.tk, 1 +webcamrunetki.ga, 1 +webcams4date.com, 1 +webcamtoy.com, 1 +webcaptive.com, 1 +webcaptive.net, 1 +webcarroseletricos.ga, 1 +webcase.tk, 1 +webcatchers.nl, 0 +webcatechism.com, 0 +webce.de, 1 +webceo.se, 1 +webcheck.pt, 1 +webclimbers.ch, 0 +webclymber.com, 1 +webcoins.tk, 1 +webcollect.org.uk, 1 +webcollector.ga, 1 +webcontentserver.com, 1 +webcontentspinning.com, 1 +webcontrol.tk, 1 +webconverge.nl, 1 +webcookies.org, 1 +webcreativa.tk, 1 +webcrm.com, 1 +webcurtaincall.com, 1 +webdaddyit.ga, 1 +webdemaestrias.com, 1 +webdesign-kall.de, 1 +webdesign-note.jp, 1 +webdesignagency.cf, 1 +webdesignersinchennai.tk, 1 +webdesignfenua.tk, 1 +webdesigngc.com, 1 +webdesignlabor.ch, 1 +webdesignplay.com, 1 +webdesignplayground.io, 1 +webdesignrodgau.de, 1 +webdesignsandiego.com, 1 +webdesignzarin.ir, 1 +webdev-cw.me, 1 +webdev-cw.tk, 1 +webdev.solutions, 1 +webdevelop.ninja, 1 +webdevinsider.pl, 1 +webdevoo.com, 1 +webdevxp.com, 1 +webdieta.tk, 1 +webdl.org, 1 +webdoctors.com, 1 +webdollarvpn.io, 1 +webduck.nl, 0 +webeast.eu, 1 +webeau.com, 1 +webeditors.com, 1 +webehurt.com, 1 +webelement.sk, 0 +webenglish.se, 1 +webera.pro, 1 +webergrillrestaurant.com, 1 +webers-webdesign.de, 1 +webexample.win, 0 +webexp.biz, 1 +webexperts.tk, 1 +webexpertsdirect.com.au, 1 +webfeifei.tk, 1 +webfence.pt, 1 +webfilings-eu-mirror.appspot.com, 1 +webfilings-eu.appspot.com, 1 +webfilings-mirror-hrd.appspot.com, 1 +webfilings.appspot.com, 1 +webfiredesigns.ca, 1 +webfixers.nl, 1 +webforce.pt, 1 +webformula.in, 1 +webfun.tk, 1 +webgap.io, 1 +webgarten.ch, 1 +webgears.com, 1 +webgeneric.com, 1 +webgeneric.in, 1 +webgentleman.tk, 1 +webhackspro.com, 1 +webharvest.gov, 1 +webheads.co.kr, 1 +webhelyesarcu.hu, 1 +webhoffmann.de, 1 +webhooks.stream, 1 +webhopp.com, 1 +webhost.guide, 1 +webhosting-erfahrungen.de, 1 +webhosting4u.email, 1 +webhostingblackfriday.deals, 1 +webhostingpros.ml, 1 +webhostingshop.ca, 1 +webhostingspace.net, 1 +webhostingzzp.nl, 1 +webhostplan.info, 1 +webhotelli.website, 1 +webhotels.tk, 1 +webhotelsoversigt.dk, 1 +webhr.co, 1 +webia.in.th, 1 +webika.site, 1 +webimagina.tk, 1 +webinator.tk, 1 +webinformer.tk, 1 +webini.co, 1 +webinnovation.ie, 1 +webinstit.net, 1 +webionite.com, 1 +webiroha.com, 1 +webisle.com, 1 +webissues.de, 1 +webitentwicklung.de, 1 +webjobposting.com, 1 +webkam-sex.com, 1 +webkeks.org, 1 +webkindergarten.net, 1 +webkitchen.kiev.ua, 1 +webkorobka.tk, 1 +weblagalera.tk, 1 +weblate.com, 1 +weblate.cz, 1 +weblate.org, 1 +weblead.vip, 1 +webleedpixels.com, 0 +weblegend.xyz, 1 +webliberty.ru, 1 +weblibrary.cf, 1 +weblights.ml, 1 +webline.ch, 1 +weblistposting.com, 1 +weblogia.tk, 1 +weblogzwolle.nl, 1 +webmail.ee, 1 +webmail.gigahost.dk, 0 +webmail.info, 0 +webmail.onlime.ch, 0 +webmail.schokokeks.org, 0 +webmanagement.berlin, 1 +webmandat.fr, 1 +webmandesign.eu, 1 +webmarcosmarquez.tk, 1 +webmarketing.hr, 1 +webmarketingfestival.it, 1 +webmaster-infographiste-lyon.fr, 1 +webmaster16.ml, 1 +webmediaprint.at, 1 +webmediums.com, 1 +webmedpharmacy.co.uk, 1 +webmenedzser.hu, 1 +webmetallica.tk, 1 +webmetering.at, 1 +webmethod.ir, 1 +webminders.it, 1 +webmining.gq, 1 +webministeriet.net, 1 +webmixseo.com, 1 +webmotelli.fi, 1 +webmr.de, 1 +webmyhealth.com, 1 +webnames.ca, 1 +webnancy.tk, 1 +webnetmail4u.com, 1 +webneuch.ch, 0 +webneuch.com, 0 +webneuch.eu, 0 +webneuch.fr, 0 +webneuch.info, 0 +webneuch.swiss, 0 +webnexty.com, 1 +webnm.com, 1 +webnoob.net, 1 +webo.agency, 1 +webo.pl, 1 +weboflies.tk, 1 +webofthingsmarwane.xyz, 1 +weboperater.com, 1 +weboperater.rs, 1 +webpagetest.org, 1 +webpakken.dk, 1 +webparallax.cf, 1 +webparallevar.com, 1 +webpc.com.ua, 1 +webpcstudio.com, 1 +webperformance.io, 1 +webpiar.tk, 1 +webpinoytv.info, 1 +webpitarque.tk, 1 +webpixelia.com, 1 +webplatform.news, 1 +webportail.tk, 1 +webpostingmart.com, 1 +webpostingpro.com, 1 +webpostingreviews.com, 1 +webprostitutki.tk, 1 +webpublishing.tk, 1 +webpubsub.com, 1 +webpunk.tk, 1 +webqualitat.com.br, 1 +webrabbit.at, 1 +webranking.tk, 1 +webranko.tk, 1 +webrebels.org, 0 +webregion.tk, 1 +webrentcars.com, 0 +webreport.fr, 1 +webrepresalia.tk, 1 +webs4all.ro, 0 +websanlamuerte.tk, 1 +websec.nu, 1 +websectools.com, 1 +websecurity.is, 1 +webseitendesigner.com, 0 +webseitenserver.com, 0 +websenat.de, 1 +webseptimus.com, 1 +webseptimus.eu, 1 +webshan.ir, 0 +webshaped.de, 1 +websharks.org, 1 +webshop.nl, 1 +website-engineering.co.za, 0 +website-traffic.shop, 1 +website.builders, 1 +websiteboost.nl, 1 +websitecalifornia.cf, 1 +websitecenter.tk, 1 +websitecyber.com, 1 +websitedesignersmalappuram.ga, 1 +websitedesignprice.ga, 1 +websitedown.io, 1 +websiteenergizers.com, 1 +websiteforstudents.com, 1 +websiteforyou.nl, 1 +websitelearners.cf, 1 +websitelia.com, 1 +websitemarketers.tk, 1 +websiteout.ca, 1 +websiteout.net, 1 +websitepromotion.ml, 1 +websiterent.ca, 1 +websites4business.ca, 1 +websitesbybruce.com, 1 +websitesbymark.co.uk, 1 +websitesbywordpress.com, 1 +websitesdallas.com, 1 +websitesdemos.tk, 1 +websiteservice.pro, 1 +websitesmiths.com, 1 +websitesseller.com, 1 +websitesthatwork.biz, 1 +websiteurl.org, 1 +websize.me, 1 +webslate.co.nz, 1 +websoftba.gq, 1 +websol.biz, 1 +websouthdesign.com, 1 +websphere.tk, 1 +webspiral.jp, 1 +webspire.tech, 1 +webspotter.nl, 1 +webssupport.ga, 1 +webstaff.xyz, 1 +webstamil.com, 1 +webstart.nl, 1 +webstats.tk, 1 +webstreamworld.com, 1 +webstu.be, 1 +webstudio-n.com, 1 +webstylemedia.com, 1 +websubmissions.tk, 1 +websuccess.co.za, 1 +websupporten.no, 1 +websvetaines.lt, 1 +webszolgaltatas.hu, 1 +webtasarim.pw, 1 +webtaxi.cf, 1 +webtechnicom.net, 0 +webtek.nu, 1 +webtobesocial.de, 1 +webtomsk.tk, 1 +webtools-eqt.co.nz, 1 +webtoro.com, 1 +webtorrent.io, 1 +webtostore.fr, 1 +webtransfers.ml, 1 +webtrek.ch, 1 +webtrh.cz, 1 +webtropia.com, 0 +webuildsite.ga, 1 +webukhost.com, 1 +webullreview.co, 1 +webuniverse.ml, 1 +webunix.ga, 1 +webusage.xyz, 1 +webvampiro.tk, 1 +webvenezuela.tk, 1 +webverdienst.tk, 1 +webviewcams.com, 1 +webwednesday.nl, 1 +webwelearn.com, 1 +webwinkelexploitatie.nl, 1 +webwinkelkeur.nl, 1 +webwinkelwestland.nl, 1 +webwit.nl, 1 +webworkerswinners.com, 1 +webworkshop.ltd, 1 +webx5.pro, 0 +webxo.com, 1 +webxr.today, 1 +webyazilim.biz.tr, 1 +webyazilimankara.com, 1 +webz.one, 1 +webzanem.com, 1 +wecanvisit.com, 1 +wechatify.com, 1 +weck.alsace, 1 +wecleanbins.com, 1 +wecobble.com, 1 +wecomm.fr, 0 +wed.pw, 1 +weda.cf, 1 +wedding-e-dress.tk, 1 +wedding-page.ga, 1 +wedding-page.tk, 1 +wedding-ua.tk, 1 +weddingalbumsdesign.com, 1 +weddingdays.tv, 1 +weddingfantasy.ru, 1 +weddinghotographers.tk, 1 +weddingideas.gq, 1 +weddingsbynoon.co.uk, 1 +weddingtrunks.tk, 1 +weddingwire.ca, 1 +weddingwire.co.uk, 1 +weddingwire.com, 1 +weddingwire.in, 1 +wedefendcharities.org, 1 +wedeliverdavao.com, 1 +wedelrahill.com, 1 +wedg.uk, 1 +wednesday.one, 1 +wedontcaregroup.com, 1 +wedooper.com, 1 +wedplay.host, 1 +wedshoots.com, 1 +weeaboo.ml, 1 +weeb.us, 1 +weebl.me, 1 +weeblr.com, 1 +weecarepreschool.ca, 1 +weed.ren, 1 +weedgranadagrowshop.com, 1 +weedlife.com, 1 +weednews.co, 0 +weedupdate.com, 1 +weedypedia.de, 1 +weekdone.com, 1 +weekendcandy.com, 1 +weekendinitaly.com, 1 +weekendplayers.tk, 1 +weekly-residence.com, 1 +weeklydcoupgen.com, 1 +weektegenarmoede.be, 1 +weemake.fr, 0 +weemakers.fr, 0 +weenvio.com, 1 +weepycat.com, 1 +weerda.fr, 1 +weerstationgiethoorn.nl, 1 +weerstatistieken.nl, 1 +weewoo.net, 1 +wefact.nl, 1 +wefillgood.com, 1 +wefitboilers.com, 1 +wefixmd.com, 1 +weforgood.org.tw, 1 +wefound.com.tw, 1 +wefound.se, 1 +wegethitched.co.uk, 1 +weggeweest.nl, 1 +wegiveloans.com, 1 +wegner.no, 1 +wego.ca, 1 +wegonnagetsued.org, 1 +wegotcookies.com, 1 +wegrzynek.org, 1 +wegrzynek.pl, 1 +wegvielfalt.de, 1 +wehealasone.gov.ph, 1 +wehostdnn.com, 1 +weibohan.com, 1 +weibomiaopai.com, 1 +weideheuvel.org, 1 +weidmannfibertechnology.com, 0 +weien.org, 1 +weigelia.nl, 1 +weighed.ga, 1 +weightlift.ml, 1 +weightlosseasy.cf, 1 +weightlossoutcome.com, 1 +weightprogram.cf, 1 +weihnachten-schenken.de, 1 +weiler.xyz, 0 +weiling.clinic, 1 +weils.net, 1 +weiltoast.de, 1 +weimaranerdogcare.com, 1 +weiming.ddns.net, 1 +weimz.com, 1 +wein.cc, 1 +wein.co.kr, 1 +weinbergerlawgroup.com, 1 +weinboxbuilders.co.nz, 1 +weinfuse.com, 1 +weingut-bernd-klein.de, 1 +weinhandel-preissler.de, 1 +weinholtzglass.com, 1 +weinundsein.com, 1 +weiran.org.cn, 1 +weirdesigns.com, 1 +weirdserver.com, 1 +weirdware.tech, 1 +weis.bz, 1 +weissman.agency, 1 +weiterbildung-vdz.de, 1 +weitergedacht.eu, 1 +weitsolutions.nl, 1 +weitweg.xyz, 1 +weixiaojun.org, 0 +weizenke.im, 1 +wejdmark.com, 1 +wekibe.de, 1 +wekipedia.com, 1 +weknowhowtodoit.com, 1 +weladee.com, 1 +welches-kinderfahrrad.de, 1 +welcome-tahiti.com, 0 +welcome-to-the.wedding, 1 +welcome-werkstatt.com, 1 +welcome26.ch, 0 +welcomepowayan.tk, 1 +weld.io, 1 +weldersnet.tk, 1 +weldonconstruction.com.au, 1 +welfareness.icu, 1 +well-you.com, 1 +well.bayern, 1 +wella-download-center.de, 1 +wellandwealthy.org, 1 +wellbalancedhealth.ie, 1 +wellbeing360.com.au, 1 +wellbutrinxlgeneric.cf, 1 +wellcom.co.il, 1 +wellcomemdhealth.com, 1 +wellensteyn.ru, 1 +weller.pm, 1 +wellforlifenow.com, 1 +wellgreece.com, 1 +wellington-fields.de, 1 +wellist.com, 1 +wellness-bonbon.de, 1 +wellness-gutschein.de, 1 +wellnesscheck.net, 1 +wellnessever.com, 1 +wellsolveit.com, 0 +wellspringsga.com, 1 +wellsprung.net, 1 +wellti.com, 1 +wellzapness.com, 1 +welmo.fr, 1 +welom.tk, 1 +welovecatsandkittens.com, 1 +weloveliving.it, 1 +welovemail.com, 1 +welovemaira.com, 1 +welovemugs.co.uk, 1 +welp-mail.de, 1 +welpen-rucphen.tk, 1 +welpo.me, 1 +welshccf.org.uk, 1 +welshterrier.tk, 1 +welshyak.tk, 1 +welt-flaggen.de, 1 +weltderangebote.de, 0 +welteneroberer.de, 1 +weltengilde.de, 1 +weltenhueter.de, 1 +weltmeister.de, 0 +weltumradler.tk, 1 +weltverschwoerung.de, 1 +welty.cc, 1 +welty.co, 1 +welty.io, 1 +welty.me, 1 +welzijnkoggenland.nl, 1 +wem.hr, 1 +wemajin.com, 1 +wemakebookkeepingeasy.com, 1 +wemakemenus.com, 0 +wemakemx.mx, 1 +wemakeonlinereviews.com, 1 +wemediate.info, 1 +wemovemountains.co.uk, 1 +wenceslas.org.uk, 1 +wenchieh.com, 1 +wendepunkt-betreuung.de, 1 +wendlberger.net, 1 +wendu.me, 1 +wendycityblossoms.com, 1 +wenge-murphy.com, 1 +wenger-shop.ch, 1 +wenhelpdesk.tk, 1 +wenjs.me, 1 +wenjulebu.cc, 1 +wenta-computerservice.net, 1 +wenta.de, 1 +wentu.ml, 1 +wentyl.tk, 1 +wenzelarifiandi.com, 0 +wepa.pe, 1 +wepay.com, 0 +wepay.in.th, 1 +wepbiz.com, 1 +wepkk.com, 1 +weplaynaked.dk, 1 +weple.gq, 1 +wer-kommt-her.de, 1 +werally.com, 1 +werbe-sonnenbrillen.de, 0 +werbeagentur.de, 1 +werbedesign-tauber.de, 1 +werbefotograf-leitner.de, 1 +werbefotografie-leitner.de, 1 +werbetopshop.de, 1 +werbewelt-tv.de, 1 +werbezentrum-stiebler.de, 1 +werbik.at, 1 +wercat.net, 1 +werd.pw, 0 +werehub.org, 1 +wereldkoffie.eu, 1 +wereldplanner.nl, 1 +wereoutthere.nl, 1 +werhatunsverraten.eu, 1 +werk-34.de, 1 +werken-bij-inwork.nl, 1 +werkenbijdfzs.nl, 0 +werkenbijsanitairwinkel.be, 1 +werkenbijsanitairwinkel.nl, 1 +werkenbijsherpa.nl, 1 +werkenbijsidekix.nl, 1 +werkenbijvanderventions.com, 1 +werkenbijvanderventions.nl, 1 +werkenbijwierda.nl, 1 +werkeninwesterveld.nl, 1 +werkgroepderdewereld.nl, 1 +werkgroeppaleisparkhetloo.nl, 1 +werkinc.de, 1 +werkinholland.com, 0 +werkkrew.xyz, 1 +werkslimreisslim.nl, 1 +werkstattkinder.de, 1 +werlabs.se, 1 +wermeester.be, 1 +wermeester.com, 1 +werner-ema.de, 1 +wernicke-it.de, 1 +werpo.com.ar, 1 +wertheimer-burgrock.de, 1 +wertpapiertreuhand.de, 1 +wervingenselectieamsterdam.nl, 1 +werwolf-live.de, 1 +werxa.cz, 1 +werxus.eu, 1 +weryfikacjapodatnika.pl, 1 +weschool.id, 1 +wesecom.com, 1 +wesell.asia, 1 +weserv.nl, 1 +wesleycabus.be, 1 +wesleywarnell.com, 1 +wesoco.de, 1 +wespeakgeek.co.za, 1 +wesreportportal.com, 1 +wessalicious.com, 1 +wessner.co, 1 +west-contemporary.com, 1 +west-nerica.de, 1 +west-raptors.tk, 1 +west-wind.net, 1 +westaf-edit.com, 1 +westafricatradehub.com, 1 +westcanal.net, 1 +westcarrollton.org, 1 +westcentenaryscouts.org.au, 1 +westcentralaor.org, 1 +westcoastaggregate.com, 1 +westcoastcastles.com, 1 +westcoastheatingair.com, 1 +westcoastmarineadvisor.com, 1 +westcoastmotors.co.uk, 1 +westcode.de, 1 +westcommunitycu.org, 1 +westcountrystalking.com, 1 +westendwifi.net, 1 +westerdraai.tk, 1 +westernfrontierins.com, 1 +westernpadermatologist.com, 1 +westernparts.com, 1 +westernstairlifts.com, 1 +westeros.hu, 1 +westhighlandwhiteterrier.com.br, 1 +westhillselectrical.com, 1 +westhotel.com.au, 1 +westlab.ch, 1 +westlakehills.gov, 1 +westlakevillageelectric.com, 1 +westlakevillageelectrical.com, 1 +westlakevillageelectrician.com, 1 +westlakevillageexteriorlighting.com, 1 +westlakevillagelandscapelighting.com, 1 +westlakevillagelighting.com, 1 +westlakevillageoutdoorlighting.com, 1 +westlander-nostalgie.tk, 1 +westlandplacestudios.com, 1 +westline.com.tr, 1 +westlinntowncar.com, 1 +westlogistic.com, 1 +westlondoncarpetcleaners.co.uk, 1 +westmead.org, 1 +westmeadapartments.com.au, 1 +westmidlandsbouncycastlehire.co.uk, 1 +westmidlandsinflatables.co.uk, 1 +westmidlandslettings.com, 1 +westondenning.com, 1 +westonma.gov, 1 +westplains.gov, 1 +westpointrealtors.com, 1 +westshoresrealty.com, 1 +westside-pediatrics.com, 1 +westsidechildrenstherapy.com, 1 +westsuburbanbank.com, 1 +westwings.tk, 1 +wesupportthebadge.org, 1 +weswitch4u.com, 1 +wetofu.top, 1 +wetpussylipsex.com, 1 +wetravel.company, 1 +wetrepublic.com, 1 +wettbonus.info, 1 +wetter.de, 1 +wetthost.com, 1 +wevenues.com, 1 +wevg.org, 1 +wew881.com, 1 +wew882.com, 1 +wew888.com, 1 +wewin88.com, 1 +wewin88.net, 1 +wewin889.com, 1 +wewitro.de, 1 +wewitro.net, 1 +weworkjpn.com, 1 +wexfly.com, 1 +wexfordbouncycastles.ie, 1 +wexilapp.com, 1 +weyhmueller.de, 0 +weyland-yutani.org, 1 +weyoui.de, 1 +wezl.net, 1 +wf-bigsky-master.appspot.com, 1 +wf-demo-eu.appspot.com, 1 +wf-demo-hrd.appspot.com, 1 +wf-dogfood-hrd.appspot.com, 1 +wf-hosting.de, 1 +wf-pentest.appspot.com, 1 +wf-staging-hr.appspot.com, 1 +wf-training-hrd.appspot.com, 1 +wf-training-master.appspot.com, 1 +wf-trial-hrd.appspot.com, 1 +wf336.com, 1 +wfcom-98-wf-www.pantheonsite.io, 1 +wfcp1010.com, 1 +wfh.ovh, 1 +wfh.se, 1 +wforum.nl, 1 +wfschicago.com, 1 +wfsrecruit.com.au, 1 +wft-portfolio.nl, 1 +wg-tools.de, 1 +wg3k.us, 1 +wgcaobgyn.com, 1 +wgdp.gov, 0 +wge-feg.gc.ca, 1 +wgec-fegc.gc.ca, 1 +wget.cool, 1 +wgom.org, 0 +wgplatform.co.uk, 1 +wgraphics.ru, 1 +wgrfoods.co.uk, 1 +wgrlc.vic.gov.au, 1 +wgrstudio.com, 1 +wgsh.de, 1 +wgsuyi.cf, 1 +wgtrm.com, 1 +wgyt.cf, 1 +wgyt.tk, 1 +wh-guide.de, 1 +wh1tedrvg0n.es, 1 +whafs.de, 1 +whaleapp.co, 1 +whaletail.ai, 0 +whaller.com, 1 +whanau.org, 0 +what-do-kittens-need-to-eat.tk, 1 +what-does-kittens-need.ml, 1 +what-wood.servehttp.com, 1 +what.tf, 1 +whatabout.tk, 1 +whataboutjonbuckland.tk, 1 +whataboutjoshua.tk, 1 +whatagreatwebsite.net, 1 +whatanime.ga, 1 +whatarepatentsfor.com, 1 +whatclinic.co.uk, 1 +whatclinic.com, 1 +whatclinic.com.ph, 1 +whatclinic.de, 1 +whatclinic.ie, 1 +whatclinic.ru, 1 +whatdevshouldknow.pl, 1 +whatevents.tk, 1 +whatevername.tk, 1 +whateverzone.ml, 1 +whatgrowswhere.com, 1 +whatgrowswhere.eu, 1 +whatgrowswhere.net, 1 +whatgrowswhere.nl, 1 +whatgrowswhere.org, 1 +whatiexpose.com, 1 +whatimissed.news, 1 +whatisapassword.com, 1 +whatiscss.tk, 1 +whatisinternetsecurity.net, 1 +whatisipfix.com, 1 +whatisl.ovh, 1 +whatismycountry.com, 1 +whatismyip.net, 0 +whatismyipaddress.ca, 1 +whatismyipv6.info, 1 +whatismypublicip.com, 1 +whatisnetflow.com, 1 +whatissflow.com, 1 +whatisthe.cloud, 1 +whatisthisapp.com, 1 +whatnext.limited, 1 +whatnot.ai, 1 +whatsahoy.com, 1 +whatsapp.com, 1 +whatsapp.net, 1 +whatsapp.ru, 1 +whatsmychaincert.com, 1 +whatsmysuggestion.com, 1 +whatsthisword.com, 1 +whatsupgold.com.tw, 1 +whatsupgold.net, 1 +whatsupoutdoor.com, 0 +whatswrong.blog, 1 +whattheactual.nyc, 1 +whatthefile.info, 1 +whatthefoxhat.com, 1 +whatthingsweigh.com, 1 +whattodo.com, 0 +whattominingrigrentals.com, 1 +whatusb.com, 1 +whatwebcando.today, 1 +whatwg.org, 1 +whd-guide.de, 1 +whdpc.gov, 1 +wheatgra.in, 1 +wheelchair.gq, 1 +wheeler.kiwi.nz, 0 +wheelspin.ga, 1 +wheelwide.co.uk, 1 +wheelwork.org, 0 +wheelycool.tech, 1 +wheelycoolgear.com, 1 +wheelyking.tk, 1 +when-release.com, 1 +when-release.ru, 1 +when.fm, 0 +where2trip.com, 1 +whereapp.social, 1 +wheredoi.click, 1 +wherefish.com, 1 +whereicode.org, 1 +whereisjason.com, 1 +whereismyorigin.cf, 1 +whereiszakir.com, 1 +wheresbuzz.com.au, 1 +whereuare.se, 1 +whexit.nl, 1 +whey-protein.ch, 1 +wheyteck.com, 1 +which-reviews.co.uk, 1 +whichdoctor.com, 1 +whichgender.today, 1 +whiff-of-grape.ca, 1 +whigfieldspain.tk, 1 +whilsttraveling.com, 1 +whing.org, 1 +whipnic.com, 1 +whirlpool-luboss.de, 1 +whirlpool.net.au, 1 +whishart.cf, 1 +whiskersandtails.co.za, 1 +whiskey.com.my, 1 +whiskey.money, 1 +whiskey.my, 1 +whisky-circle.info, 1 +whisky.com.my, 1 +whisky.money, 1 +whisky.my, 1 +whiskydb.de, 1 +whiskymy.com, 1 +whiskynerd.ca, 0 +whiskyshop.com.my, 1 +whiskyshop.my, 1 +whisp.ly, 0 +whispeer.de, 1 +whisper-net.de, 1 +whisperinghoperanch.org, 1 +whisperlab.org, 1 +whistleblower.gov, 1 +whistleblowing.it, 1 +whistlingdog.media, 0 +whitdoit.tk, 1 +white-ibiza.com, 1 +white-info.tk, 1 +white-noise.tk, 1 +white-skull.tk, 1 +whitealps.at, 0 +whitealps.be, 0 +whitealps.ch, 0 +whitealps.de, 0 +whitealps.fr, 0 +whitealps.net, 0 +whiteantelopeinteriors.com, 1 +whitebear.cloud, 1 +whitebox.ga, 1 +whitecleatbeat.com, 1 +whitefm.ch, 0 +whiteglovemoving.us, 1 +whitehathackers.com.br, 1 +whitehats.nl, 1 +whitehorse.ga, 1 +whitehouse.gov, 1 +whitehouse.org, 1 +whitehouseconferenceonaging.gov, 1 +whitehousedrugpolicy.gov, 1 +whiteink.com, 1 +whitejaguars.com, 1 +whitekings.tk, 1 +whiteknightsafelockinc.com, 1 +whitelabeltickets.com, 0 +whitelotuscyp.com, 1 +whitelynx.co, 1 +whitemetalperu.tk, 1 +whitemountainnaturalcreations.com, 1 +whitepages.ml, 1 +whitepen.tk, 1 +whitepharmacy.co.uk, 1 +whitepinetn.gov, 1 +whiterabbit.group, 1 +whiterabbit.nl, 1 +whiterabbit.org, 1 +whiterose.goip.de, 1 +whiteshadowimperium.com, 1 +whitesoxbestteaminbaseball.com, 1 +whitespace.se, 1 +whitestarlegacy.tk, 1 +whitevpn.cz, 1 +whitewebhosting.com, 1 +whitewinterwolf.com, 1 +whitkirk.com, 1 +whitkirkchurch.org.uk, 1 +whittome.com, 1 +whitworth.nyc, 1 +whizzzbang.co.uk, 1 +whm.gc.ca, 1 +whnpa.org, 1 +who-calledme.com, 1 +who.pm, 0 +whoami.io, 1 +whocalld.com, 1 +whocalled.us, 1 +whocalledme.xyz, 1 +whocrushonme.com, 1 +whodatdish.com, 1 +whoiscuter.ml, 1 +whoiscutest.ml, 1 +whoiswho.tk, 1 +wholesale.cf, 1 +wholesalediamonds.tk, 1 +wholesomeharvestbread.com, 0 +wholevood.com, 1 +wholevood.de, 1 +whoneedstobeprimaried.today, 1 +whonix.org, 1 +whoopee.my, 0 +whoownsmyavailability.com, 1 +whoreofwallstreet.tk, 1 +whorepresentsme.us, 1 +whosyourdaddy.ml, 1 +whoturgled.com, 1 +whowherewhen.net, 1 +whqqq.com, 1 +whqtravel.org, 0 +wht.one, 1 +whta.eu, 1 +whta.se, 1 +whtcsj.com, 1 +whub.io, 0 +why-brexit.uk, 1 +why918.com, 1 +whychoosebob.net.au, 1 +whyfeedthegreed.com, 1 +whymps.com, 1 +whynohttps.com, 1 +whyopencomputing.ch, 0 +whyopencomputing.com, 0 +whysoslow.co.uk, 1 +whytls.com, 1 +whyworldhot.com, 1 +whyy.eu.org, 1 +whyzeroturn.com, 1 +wi-wi.co.jp, 1 +wiadomosci-lodz.pl, 1 +wiagencies.com, 1 +wiapply.com, 1 +wibbe.link, 1 +wiberg.nu, 1 +wibness.com, 1 +wibuw.com, 1 +wicamb.com, 1 +wicca-witchcraft.com, 1 +wiccansupplies.ga, 1 +wicharypawel.com, 1 +wichitafoundationpros.com, 1 +wick-machinery.com, 1 +wickbot.com, 1 +wickedsick.tk, 1 +wickelfischfrance.fr, 1 +wickerliving.com, 1 +wickersmith.com, 1 +wickerwoman.com, 1 +wickrath.net, 1 +wicksandwonders.com.au, 1 +widatcp.gov, 1 +widderplasticsurgery.com, 1 +wideboxmacau.com, 0 +widecontrol.it, 1 +widegab.com, 0 +wideinfo.org, 1 +widejeans.tk, 1 +widely.io, 1 +widemann.de, 1 +widememory.com, 1 +widenews.org, 1 +wideweb.host, 1 +wideworks.agency, 1 +widgetmaker.co.uk, 1 +widmer.bz, 1 +widoj.gov, 1 +widsl.de, 1 +widwap.net, 1 +wiebel.org, 1 +wiebetaaltdat.nl, 1 +wieckiewicz.org, 1 +wiedemeier.space, 1 +wiedmeyer.de, 1 +wiedu.net, 1 +wiegedaten.de, 1 +wiehenkrug.de, 1 +wiek.net, 1 +wieloswiat.pl, 1 +wielrenbond.ml, 1 +wielrennen-in-zeeland.tk, 1 +wien52.at, 1 +wieneck-bauelemente.de, 1 +wiener.hr, 1 +wienergyjobs.com, 1 +wieobensounten.de, 1 +wiewiorjonasz.pl, 1 +wifi-hack.com, 0 +wifi-names.com, 1 +wificafehosting.com, 1 +wificonnect.cc, 1 +wifimb.cz, 1 +wifinube.com, 1 +wifipineapple.com, 1 +wifirst.net, 1 +wifishing.tk, 1 +wifree.lv, 1 +wigelsworth.io, 1 +wigggle.it, 1 +wigglestudio.com, 1 +wigle.net, 1 +wigmore-hall.org.uk, 1 +wigos.ru, 1 +wigwam.design, 1 +wiiaam.com, 1 +wiikipedia.com, 1 +wiimotion.de, 1 +wiipo.com, 1 +wiisas.fi, 1 +wijaya.net, 1 +wijaya2u.com, 1 +wijewick.com, 1 +wijkbudget.gent, 1 +wijkstation.nl, 1 +wijnbesteld.nl, 1 +wijnlandkroatie.nl, 1 +wijnservices.nl, 0 +wijsaantwerk.be, 1 +wijseuropa.gent, 1 +wijwillendit.nl, 1 +wijzeweters.gent, 1 +wijzijnwolf.nl, 1 +wikalin.ski, 1 +wikelia.com, 1 +wikepedia.org, 1 +wiki-books.ga, 1 +wiki-pedia.org, 1 +wiki-play.ru, 1 +wiki.python.org, 1 +wiki.voyage, 1 +wiki24.ru, 1 +wikibook.com, 1 +wikibooks.org, 1 +wikibooks.pt, 1 +wikibulz.com, 1 +wikibuy.com, 1 +wikicooking.tk, 1 +wikidata.org, 1 +wikidpedia.org, 1 +wikidsystems.com, 0 +wikiehelp.com, 0 +wikiepdia.com, 1 +wikiepdia.org, 1 +wikifamily.ga, 1 +wikifamily.tk, 1 +wikihelp.in, 1 +wikihistory.tk, 1 +wikihow.com, 1 +wikihow.com.tr, 1 +wikihow.cz, 1 +wikihow.fitness, 1 +wikihow.it, 1 +wikihow.jp, 1 +wikihow.life, 1 +wikihow.mom, 1 +wikihow.pet, 1 +wikihow.tech, 1 +wikihow.vn, 1 +wikijunior.com, 1 +wikijunior.net, 1 +wikijunior.org, 1 +wikileaks.ch, 1 +wikileaks.com, 1 +wikileaks.org, 1 +wikilibrary.tk, 1 +wikilink.cf, 1 +wikilinux.xyz, 1 +wikimania.com, 1 +wikimania.org, 1 +wikimedia.biz, 1 +wikimedia.com, 1 +wikimedia.com.pt, 1 +wikimedia.community, 1 +wikimedia.is, 1 +wikimedia.jp.net, 1 +wikimedia.lt, 1 +wikimedia.org, 1 +wikimedia.us, 1 +wikimedia.xyz, 1 +wikimediacommons.co.uk, 1 +wikimediacommons.info, 1 +wikimediacommons.jp.net, 1 +wikimediacommons.mobi, 1 +wikimediacommons.net, 1 +wikimediacommons.org, 1 +wikimediafoundation.com, 1 +wikimediafoundation.info, 1 +wikimediafoundation.net, 1 +wikimediafoundation.org, 1 +wikimilk.org, 1 +wikimir.tk, 1 +wikimirror.org, 1 +wikinews.com, 1 +wikinews.de, 1 +wikinews.org, 1 +wikinews.pt, 1 +wikipaedia.net, 1 +wikipedia-mirror.org, 1 +wikipedia.bg, 1 +wikipedia.co.il, 1 +wikipedia.co.uk, 1 +wikipedia.co.za, 1 +wikipedia.com, 1 +wikipedia.com.ar, 1 +wikipedia.ee, 1 +wikipedia.es, 1 +wikipedia.fi, 1 +wikipedia.id, 1 +wikipedia.info, 1 +wikipedia.is, 1 +wikipedia.lt, 1 +wikipedia.net, 1 +wikipedia.org, 1 +wikipedia.org.il, 1 +wikipedia.sk, 1 +wikipediafoundation.org, 1 +wikipedial.org, 1 +wikipediazero.org, 1 +wikipeter.nl, 1 +wikipiedi.it, 1 +wikiquote.com, 1 +wikiquote.net, 1 +wikiquote.org, 1 +wikiquote.pt, 1 +wikiquotes.info, 1 +wikirace.tk, 1 +wikisaur.tk, 1 +wikiskripta.eu, 1 +wikisorg.tk, 1 +wikisource.com, 1 +wikisource.org, 1 +wikisource.pl, 1 +wikisource.pt, 1 +wikispecies.com, 1 +wikispecies.net, 1 +wikispecies.org, 1 +wikispiel.de, 1 +wikitech.tk, 1 +wikitransporte.tk, 1 +wikiversity.com, 1 +wikiversity.org, 1 +wikiversity.pt, 1 +wikiversus.com, 1 +wikivisually.com, 1 +wikivoyage.com, 1 +wikivoyage.de, 1 +wikivoyage.eu, 1 +wikivoyage.net, 1 +wikivoyage.org, 1 +wikivoyager.de, 1 +wikivoyager.org, 1 +wikiwp.org, 1 +wikizip.ga, 1 +wikjpedia.org, 1 +wikkelweb.nl, 1 +wikpa.com, 1 +wikpedia.org, 1 +wikproduccions.tk, 1 +wiktionary.com, 1 +wiktionary.eu, 1 +wiktionary.org, 1 +wiktionary.pl, 1 +wiktionary.pt, 1 +wiktor-imbierski.com, 1 +wilane.org, 1 +wilbrinkdesign.nl, 0 +wilco-s.nl, 1 +wilcodeboer.me, 1 +wild-emotion-events.de, 1 +wild-turtles.com, 1 +wildanalysis.ga, 1 +wildandisle.com, 1 +wildandwonderfulbodycare.com, 1 +wildandwonderfulketo.com, 1 +wildbergh.tk, 1 +wildberries.cf, 1 +wildbirds.dk, 1 +wildbox.net, 1 +wildcard.hu, 1 +wildcardfederal.net, 1 +wildcatprotection.org, 1 +wildcove.ca, 1 +wildcraft.com, 1 +wildeco.se, 1 +wildercerron.com, 1 +wilderky.gov, 1 +wildewood.ca, 1 +wildfilm.tv, 1 +wildfirechain.xyz, 1 +wildfoxlady.com, 1 +wildfoxosteopathy.com, 1 +wildhelper.com, 1 +wildlifeadaptationstrategy.gov, 1 +wildmine.su, 1 +wildnisfamilie.net, 1 +wildrideproject.tk, 1 +wildsafety.com, 1 +wildtrip.blog, 0 +wildwildtravel.com, 1 +wildwind.world, 1 +wildwoodpolice-fl.gov, 1 +wildwoodrockers.tk, 1 +wildzap.ml, 1 +wildzoopark.co.uk, 1 +wildzoopark.com, 1 +wilf1rst.com, 1 +wilfrid-calixte.fr, 0 +wilgo.ga, 1 +wilhelm-nathan.de, 1 +wili.li, 1 +wiliquet.net, 0 +wilk.tech, 1 +wilkebouwer.nl, 1 +wilkipedia.org, 1 +wilkushka.com, 1 +wilkushka.net, 1 +will-lash.com, 1 +willalex.com, 1 +willbarnesphotography.co.uk, 1 +willberg.bayern, 1 +willdropphoto.co.uk, 1 +willekeinden.nl, 1 +willenberg.family, 1 +willetlaw.com, 1 +willfarrell.ca, 1 +willflies.com, 1 +willi-graf-gymnasium.de, 1 +willi-graf-os.de, 1 +william.gg, 1 +williamarias.tk, 1 +williamboulton.co.uk, 1 +williamboundsltd.com, 1 +williamfeely.info, 1 +williamgoldberg.cf, 1 +williamjohngauthier.net, 1 +williamk.ga, 0 +williamle.com, 1 +williampuckering.com, 1 +williamsalexander.com, 1 +williamscomposer.com, 1 +williamscountyoh.gov, 1 +williamsflintlocks.com, 0 +williamshomeheat.co.uk, 1 +williamsonshore.com, 1 +williamsroom.com, 1 +williamtai.moe, 1 +williamtm.com, 1 +williamvds.me, 1 +willich.tk, 1 +williejackson.com, 1 +willighp.de, 1 +willlewis.co.uk, 1 +willmage.com, 1 +willnorris.com, 1 +willocks.nl, 1 +willosagiede.com, 1 +willow.technology, 1 +willowdalechurch.ca, 1 +willowpassdentalcare.com, 1 +wills.co.tt, 1 +willstamper.name, 1 +willsthebest.co.uk, 1 +willstocks.co.uk, 1 +willtc.co.uk, 1 +willtc.uk, 1 +willvision.com, 1 +willwilkins.com, 1 +willywangstory.com, 1 +willywangstory.com.tw, 1 +willywangstory.org, 1 +wilmingtonzen.tk, 1 +wiloca.it, 1 +wilomark.com, 1 +wils.jp, 1 +wilseyrealty.com, 1 +wilsonovi.com, 1 +wilsonvilleoregon.gov, 1 +wiltrovira.com, 1 +wimachtendienk.com, 1 +wimbledonmusicfestival.co.uk, 1 +wimlanphen.nl, 1 +wimmer-software.de, 1 +wimmer-software.eu, 1 +wimmersoftware.de, 1 +wimmersoftware.eu, 1 +wimtec.net, 1 +win-fortuna.ml, 1 +win-rar.com, 1 +win.gg, 1 +win365.com, 1 +win7stylebuilder.com, 0 +win8.am, 1 +win88-line.com, 1 +win88-line.net, 1 +winall8.com, 1 +winampnederlands.tk, 1 +winancreekbarn.com, 1 +winario.de, 1 +winautomate.com, 1 +winball.ml, 1 +winbignow.click, 1 +winbuzzer.com, 1 +wincasinosmoney.com, 1 +wincasinowin.click, 1 +winch-center.de, 1 +winchat365.com, 1 +winckelmann2020.com, 1 +wind-riders.cf, 1 +wind.moe, 0 +windelnkaufen24.de, 1 +windev.com, 0 +windev.es, 0 +windforme.com, 1 +windictus.net, 1 +windmillart.net, 1 +windmyroof.com, 1 +windowreplacement.net, 1 +windows-support.nu, 1 +windows-support.se, 1 +windows311.org, 1 +windowsdoors.it, 1 +windowseatwanderer.com, 1 +windowsforum.com, 1 +windowslatest.com, 1 +windowsnerd.com, 1 +windowsnoticias.com, 1 +windowwellsupply.com, 1 +windrich-werkzeugmaschinen.de, 1 +windroide.net, 1 +windrunner.se, 1 +windscribe.com, 1 +windsock-app.com, 1 +windsorite.ca, 1 +windsorrealtysvs.com, 1 +windsorspi.com, 1 +windwoodmedia.com, 1 +windycitylawgroup.com, 1 +wine-route.net, 1 +wine-tapa.com, 1 +wine.com.my, 1 +wine.money, 1 +winebid.com, 1 +winebrasil.com.br, 1 +wineforhelp.cz, 1 +wineparis.com, 1 +wineworksonline.com, 1 +winfar.co.za, 1 +winfieldchen.me, 1 +winfilestorage.tk, 1 +winfuture.de, 1 +winfuture.mobi, 1 +wing-tsun.ga, 1 +wing-tsun.gq, 1 +wingchun.edu.au, 1 +wingchunboxtribe.com, 1 +winghill.com, 0 +wingify.com, 1 +wingmin.net, 1 +wings.com.pk, 1 +wingsofacow.com, 1 +wingspatagonia.com, 1 +winhistory-forum.net, 1 +wini.my.id, 0 +winkelcentrumputten.nl, 1 +winkelvanmorgen.nl, 1 +winkli.ddns.net, 1 +winktonsibo.tk, 1 +winmix.nl, 1 +winmodels.org, 1 +winmodels.ru, 1 +winner.ua, 1 +winners.bet, 1 +winners.net, 1 +winnersaffiliate.com, 1 +winning.gq, 1 +winningattitudeawards.org, 1 +winnipegcomputerguy.tk, 1 +winphonemetro.com, 1 +winrss.com, 1 +winsabayi.tk, 1 +winserver.ne.jp, 1 +winsposure.com, 1 +winsufi.biz, 1 +wint.global, 1 +wintark.com, 1 +wintechlab.com, 1 +winter-auszeit.de, 1 +winter-elektro.de, 1 +winter-leak.ml, 1 +winterbergwebcams.com, 1 +wintercam.nl, 1 +winterfeldt.de, 1 +winterhavenobgyn.com, 1 +winterhillbank.com, 1 +winteringent.be, 1 +wintermeyer-consulting.de, 1 +wintermeyer.de, 1 +winteromeo.tk, 1 +wintersportscompany.com, 1 +winterstudies.ga, 1 +winterstyle.com, 1 +winterzine.cf, 1 +wintodoor.com, 1 +winwares.com, 1 +winwitharval.co.uk, 1 +winxpclub.tk, 1 +wiocha.pl, 1 +wipa.tk, 1 +wippie.se, 1 +wippy.tk, 1 +wir-bewegen.sh, 1 +wir-do.de, 1 +wir-machen-druck.de, 1 +wirbsinglereview.com, 1 +wircon-int.net, 1 +wire.com, 1 +wired.co.uk, 1 +wiredmedia.co.uk, 1 +wireheading.com, 1 +wirekeep.com, 1 +wireless-emergency-stop.com, 1 +wireless-kill-switch.com, 1 +wirelessbelgie.tk, 1 +wirelessthief.ga, 1 +wireshark.org, 1 +wireshocks.com, 1 +wiretap.cf, 1 +wiretime.de, 1 +wiretransaction.ga, 1 +wirhabenspass.de, 1 +wirkaufendeinau.to, 1 +wirkstoffreich.de, 1 +wirkungs-forschung.at, 1 +wirkungs-forschung.ch, 1 +wirkungs-forschung.com, 1 +wirkungs-forschung.de, 1 +wirkungs-forschung.net, 1 +wirmicode.com, 1 +wirsberg-studios.de, 1 +wirtanen.tk, 1 +wis.moe, 1 +wis.no, 1 +wisak.me, 1 +wisal.org, 1 +wisatabagus.com, 1 +wischu.com, 1 +wiscon.co, 1 +wisconsinhomemaker.com, 1 +wisdomcue.com, 1 +wisdomgeek.com, 1 +wisdomize.me, 1 +wisdomteethonly.com, 1 +wisdotplans.gov, 1 +wise.wtf, 1 +wiseadvicetravelling.com, 0 +wisecountytx.gov, 1 +wiseemergency.com.au, 1 +wisehome.dk, 1 +wiseinternational.org, 1 +wisekidscollect.org, 1 +wisemen.digital, 1 +wisemoney.com.vc, 1 +wisenederland.nl, 1 +wisenetalarm.com, 1 +wiseradiology.com.au, 1 +wisereshape.com, 1 +wisersp.com, 1 +wisetechglobal.com, 1 +wisetoken.net, 1 +wiseupcorp.com, 1 +wishingyou.co.uk, 1 +wishlisotr.gq, 1 +wishlist.net, 1 +wishlog.fun, 1 +wishmail.cf, 1 +wiska.cn, 1 +wiska.co.kr, 1 +wiska.co.uk, 1 +wiska.com, 1 +wiska.com.br, 1 +wiska.es, 1 +wiska.in, 1 +wiska.lat, 1 +wiskundeonderzoek.tk, 1 +wism.io, 1 +wisnuadi.com, 1 +wispmaeksmusic.tk, 1 +wispsuperfoods.com, 1 +wispyon.com, 1 +wiss.co.uk, 1 +wissamnr.be, 1 +wisselink.tk, 1 +wissen-a5.de, 1 +wissena5.de, 1 +wisv.ch, 1 +wisweb.no, 1 +wit-creations.fr, 1 +wit.ai, 1 +witae.com, 1 +witch-anastasia.com, 1 +witch-spells.com, 1 +witcher.tk, 1 +witchthicktits.tk, 1 +with-environment.com, 1 +with-planning.co.jp, 1 +wither.cf, 1 +withextraveg.net, 1 +withfoundation.org, 1 +withgentlent.com, 1 +withgoogle.com, 1 +withheld.xyz, 1 +withinsecurity.com, 1 +withlocals.com, 0 +withsunglasses.co.uk, 1 +withyoutube.com, 1 +witneywaterpolo.org.uk, 1 +witrey.com, 1 +witt-international.co.uk, 1 +witte.cloud, 1 +wittepapaver.nl, 1 +wittgen-kfz-technik.de, 1 +witting.co, 0 +wittoy.com, 1 +wittu.fi, 1 +witway.nl, 0 +wivcfinancialservices.com, 1 +wivoc.nl, 1 +wiwi.nl, 1 +wiz.at, 1 +wiz.biz, 1 +wiz.farm, 1 +wizadjournal.com, 1 +wizard.gov, 1 +wizardbouncycastles.co.uk, 1 +wizardmeow.xin, 1 +wizardofvegas.com, 1 +wizardroofingexperts.com, 1 +wizardschool.tk, 1 +wizardwiz.com, 1 +wizathon.com, 1 +wizbot.tk, 1 +wizdomonwheels.com, 1 +wizzair.com, 1 +wizzley.com, 1 +wizznab.tk, 1 +wjb.marketing, 1 +wjbolles.com, 1 +wjci.com, 1 +wje-online.de, 1 +wjg.ca, 1 +wjg.dk, 1 +wjg.se, 1 +wjglerum.nl, 0 +wjr.io, 1 +wjsh.com, 1 +wjssl.com, 0 +wjtje.ga, 1 +wjwieland.dvrdns.org, 0 +wk.pl, 1 +wk577.com, 1 +wk99.net, 1 +wkberg.nl, 1 +wkennington.com, 1 +wkv.com, 1 +wkymenshealth.com, 1 +wkz.io, 1 +wlaws.com, 1 +wlci.gov, 1 +wlilai.com, 1 +wlmhtrecoverycollege.co.uk, 1 +wlmq10086.cn, 1 +wlog.it, 1 +wlombard.ru, 1 +wlpvzfilmy-onlajnmlawq.tk, 1 +wlt.ca, 0 +wltix.com, 0 +wlwlwx.com, 0 +wm-access.com, 1 +wm-access.de, 1 +wm-referrals.com, 1 +wm-talk.net, 0 +wmaccess.com, 1 +wmaccess.de, 1 +wmasphaltservices.com, 1 +wmataoig.gov, 1 +wmbey.com, 1 +wmccancercenter.com, 1 +wmcns.net, 1 +wmcpaphysicians.com, 1 +wmcroboticsurgery.com, 1 +wmcuk.net, 1 +wmfusercontent.org, 1 +wmi4.com, 1 +wmie.it, 1 +wmkowa.de, 1 +wmmkf.com, 1 +wmmks.com, 1 +wmnrj.com, 1 +wmphonline.com, 1 +wmphvacations.com, 1 +wmsndorgen.cf, 1 +wmsndorgen.ga, 1 +wmsndorgen.gq, 1 +wmsndorgen.ml, 1 +wmsndorgen.tk, 1 +wmspropertyportal.co.uk, 1 +wnark.com, 1 +wnmed.com.au, 1 +wns68123.com, 1 +wns6852.com, 1 +wns6862.com, 1 +wns68622.com, 1 +wns6865.com, 1 +wns68666.com, 1 +wns6872.com, 1 +wnsr3970.com, 1 +wo-ist-elvira.net, 1 +wo25.net, 1 +wo2forum.nl, 1 +woah.how, 1 +woaiuhd.com, 1 +wobako.pl, 1 +wobble.ninja, 1 +wobblywotnotz.co.uk, 1 +wobker.co, 1 +woblex.cz, 1 +wochennummern.de, 1 +wocup.ga, 1 +wod-stavby.cz, 1 +wodax.dk, 1 +wodboss.com, 1 +wodinaz.com, 1 +wodka-division.de, 1 +woelfer.com, 1 +wofflesoft.com, 1 +wofford-ecs.org, 0 +woffs.de, 1 +wofox.com, 1 +wogo.org, 1 +woheni.de, 1 +wohlgemuth.rocks, 1 +wohlpa.de, 1 +wohnsitz-ausland.com, 1 +wohnungsbau-ludwigsburg.de, 1 +woi.vision, 1 +wois.info, 1 +wojak.xyz, 1 +wojciechowka.pl, 1 +wokeanda.com, 1 +wokfilms.pt, 1 +wokinghammotorhomes.com, 1 +woktoss.com, 1 +wolf-advies.nl, 1 +wolfachtal-alpaka.de, 1 +wolfarth.info, 1 +wolfcrow.com, 1 +wolfdig.com.br, 1 +wolfeco.net, 1 +wolfermann.org, 1 +wolferstetterkeller.de, 1 +wolfflabs.com, 1 +wolfgang-kerschbaumer.at, 1 +wolfgang-kerschbaumer.com, 1 +wolfgang-kerschbaumer.net, 1 +wolfgang-kloke.de, 1 +wolfgang-ziegler.com, 1 +wolfhowl.me, 1 +wolflabs.co.uk, 1 +wolflambert.tk, 1 +wolfram.io, 1 +wolfsburgwest.com, 1 +wolfsden.cz, 1 +wolfshoehle.eu, 1 +wolfshuegelturm.de, 1 +wolfteam.tk, 1 +wolfvideoproductions.com, 1 +wolfwings.us, 1 +wolfy.design, 1 +wolfy1339.com, 1 +wolkanca.com.tr, 1 +wolke7.wtf, 1 +wolkenspeicher.org, 1 +wolkjehosting.nl, 1 +wolkoopjes.nl, 1 +wolkowitz.com, 1 +wollekorb.de, 1 +wollongongbaptist.hopto.org, 1 +wollwerk.org, 1 +wolrdwidessl.net, 1 +wolszon.me, 1 +woltauth.de, 1 +woltlab-demo.com, 1 +wolvesbanemanor.com, 1 +womanbusinessnetwork.com, 1 +womb.city, 1 +wombatalla.com.au, 1 +wombatnet.com, 1 +wombats.net, 1 +wombere.org, 1 +womcom.nl, 1 +women-femmes.gc.ca, 1 +women-only.net, 0 +women.gc.ca, 1 +womenbusinessfromhome.com, 1 +womenfashionshirt.tk, 1 +womenofwhatcom.com, 1 +womenonboardskenya.co.ke, 1 +womens-suits.tk, 1 +womensalespros.com, 1 +womensbiz.tk, 1 +womenshealth.gov, 1 +womensmedassoc.com, 1 +womensshelterofhope.com, 1 +womenswellnessobgyn.com, 1 +wompenriebler.tk, 1 +woms.top, 1 +womywomwoo.com, 1 +wondeerful.farm, 0 +wonderbill.com, 1 +wonderbits.net, 1 +wonderbox.ml, 1 +wonderchat.tk, 1 +wondercorner.ca, 1 +wondercris.com, 1 +wonderfuleducation.eu, 1 +wonderfuleducation.nl, 1 +wonderfulworldofwalliams.tk, 1 +wondergorilla.com, 1 +wonderhost.info, 1 +wonderhowto.com, 1 +wonderkind.de, 1 +wonderlab.ml, 1 +wonderland.com.ua, 1 +wonderlandmovies.de, 1 +wonderlangkawi.com, 1 +wonderleaks.gq, 1 +wondermags.com, 1 +wondersonlineshop.com, 1 +wondium.nl, 1 +wonghome.net, 1 +wongu.tech, 1 +woning-verfspuiten.be, 1 +woning-verfspuiten.com, 1 +woning-verfspuiten.nl, 1 +woningent.gent, 1 +woningverfspuiten.be, 1 +woningverfspuiten.com, 1 +wonko-vs-trader.de, 1 +woo-jiho.tk, 1 +wooblr.com, 1 +wooby.tk, 1 +wooc.org, 1 +wood-crafted.co.uk, 1 +wood-crafted.uk, 1 +woodbornekitchens.co.uk, 1 +woodbornekitchens.com, 1 +woodbridgegrp.com, 1 +woodbury.io, 1 +woodcat.net, 1 +woodcock.cloud, 1 +woodcoin.org, 1 +woodconditioningonline.com, 1 +woodcountywi.gov, 1 +woodcraftind.com, 1 +woodenson.com, 1 +woodev.us, 1 +woodfarm2020.com, 1 +woodfencestlouis.com, 1 +woodfordcountyky.gov, 1 +woodinvillesepticservice.net, 1 +woodlandboys.com, 1 +woodlandexterior.com, 1 +woodlandhillselectrical.com, 1 +woodlandsiding.com, 1 +woodlandsunrooms.com, 1 +woodlandsunroomsandenclosures.com, 1 +woodlandsvale.uk, 1 +woodlandwindows.com, 1 +woodlandwindows.net, 1 +woodminsterrealty.com, 1 +woodomat.com, 1 +woodridgeil.gov, 1 +woodsidepottery.ca, 1 +woodstocksupply.com, 1 +woodtrust.com, 1 +woodward-vets.co.uk, 1 +woodwicker.cl, 1 +woodwo.se, 1 +woodwormtreatment.com, 1 +woodyallen.tk, 1 +woodyworld.com, 1 +woof.gq, 1 +woofsbakery.com, 1 +woohay.com, 1 +woohooyeah.nl, 1 +woolyss.com, 1 +woomu.me, 1 +woonboulevardvolendam.nl, 1 +woontegelwinkel.nl, 1 +woopie.com, 1 +wooplagaming.com, 1 +woothelpdesk.com, 1 +wootkit.tk, 1 +wootware.co.za, 1 +wopr.network, 1 +wops.cc, 1 +worca.de, 1 +worcade.com, 1 +worcesterbouncycastlehire.co.uk, 1 +worcesterbouncycastles.co.uk, 1 +worcesterfestival.co.uk, 1 +worcesterpethydrotherapy.com, 1 +worcestervets.co.uk, 1 +worcestervetsreferrals.com, 1 +word-grabber.com, 1 +wordadmin.com, 1 +wordcounter.net, 1 +wordher.com, 1 +wordlessecho.com, 1 +wordnietvindbaar.nl, 1 +wordops.eu, 1 +wordops.io, 1 +wordops.net, 1 +wordplay.one, 1 +wordpress-szakerto.hu, 1 +wordpress.com, 0 +wordpressabi.com, 1 +wordpressarequipa.com, 1 +wordpressbot.tk, 1 +wordpressdevelopment.ml, 1 +wordpressfalcon.com, 1 +wordpresshelpmaster.com, 1 +wordpresssetup.org, 1 +wordprix.com, 1 +wordregistrar.ga, 1 +words.codes, 1 +wordsearchwhiz.com, 1 +wordsmart.it, 1 +wordsofamaster.com, 1 +wordspam.ga, 1 +wordspy.com, 1 +wordwidessl.net, 1 +wordxtra.net, 1 +worf.in, 1 +worg.pl, 1 +worgtest.pl, 1 +work-at-home.ga, 1 +work-at-home.gq, 1 +work-in-progress.website, 1 +work-shift.work, 1 +workahealthic.de, 1 +workaholics.tk, 1 +workaround.run, 1 +workat.tech, 1 +workatclever.com, 1 +workatclever.us, 1 +workatclevyr.us, 1 +workathomenoscams.com, 1 +workcelerator.com, 1 +workcheck.bz, 1 +workclaims.org, 1 +workcloud.jp, 1 +workcost.me, 1 +workemy.com, 1 +worker.gov, 1 +workeria-personal.de, 1 +workermess.tk, 1 +workers-iran.org, 1 +workerselforganisation.cf, 1 +workfromhomebusinessopportunities.cf, 1 +workfromhomelegitjob.com, 1 +workfromhomemom.cf, 1 +workfromhomesites.ga, 1 +workinestonia.com, 1 +workingclassmedia.com, 1 +workinghardinit.work, 1 +workinginsync.co.uk, 1 +workingmachine.info, 1 +workinnorway.no, 1 +worklinepc.com, 1 +worklizard.com, 1 +workmart.mx, 1 +worknrby.com, 1 +workplace.com, 1 +workplace.tools, 1 +workraw.com, 1 +workreveal.biz, 1 +workreview10.com, 1 +works-ginan.jp, 1 +worksheets-to-print.com, 1 +workshop.men, 1 +workshopengine.com.au, 1 +workshopszwolle.nl, 1 +workshopzwolle.com, 1 +worksindev.com, 1 +worksitevr.com, 1 +workspace.pt, 1 +worktefa.tk, 1 +workthings.de, 1 +workupapp.com, 1 +workwelltoday.net, 1 +workwithgo.com, 0 +worky.ph, 1 +world-avto.fun, 1 +world-citizen-report.com, 1 +world-documentary.ml, 1 +world-education-association.org, 1 +world-lolo.com, 1 +world-of-tes.tk, 1 +world-politics.tk, 1 +world-tanks.tk, 1 +worldaccord.org, 1 +worldarmy.tk, 1 +worldarticles.ru, 1 +worldcarding.tk, 1 +worldcharteronline.ga, 1 +worldchess.london, 1 +worldcigars.com.br, 1 +worldclassfriend.com, 1 +worldconsultingchile.tk, 1 +worldcubeassociation.org, 1 +worldessays.com, 1 +worldeventscalendars.com, 1 +worldfinancenews.org, 1 +worldfoodfestival.nl, 1 +worldfootball.tk, 1 +worldgun.ml, 1 +worldhairtrends.com, 1 +worldhosting.cf, 1 +worldintercontinental.cf, 1 +worldix.cf, 1 +worldix.gq, 1 +worldix.ml, 1 +worldix.tk, 1 +worldjobs.tk, 1 +worldmeetings.com, 1 +worldnetone.com, 1 +worldnewsinbox.ga, 1 +worldnewsphoto.tk, 1 +worldofbelia.de, 1 +worldofghibli.id, 1 +worldofheroes.ml, 1 +worldoflegion.ml, 1 +worldofparties.co.uk, 1 +worldofvnc.net, 1 +worldofwobble.co.uk, 1 +worldonwheels.net, 1 +worldpeacetechnology.com, 1 +worldplayerx.com, 1 +worldpolitics.cf, 1 +worldrallyforum.tk, 1 +worldranking.tk, 1 +worldrecipes.eu, 1 +worldrism.com, 1 +worldscoop.org, 1 +worldsfree4u.ga, 1 +worldsgreatestazuredemo.com, 1 +worldsinperil.it, 1 +worldskills.ph, 1 +worldsms.tk, 1 +worldsport.cf, 1 +worldstone777.com, 1 +worldstyles.cf, 1 +worldstyling.com, 1 +worldsy.com, 1 +worldtalk.de, 1 +worldtourismgroup.com, 1 +worldtrandingnews.ml, 1 +worldtravelmagazine.tk, 1 +worldtreechocolate.ca, 1 +worldturkmans.tk, 1 +worldupdatereviews.com, 1 +worldvisa.tk, 1 +worldvisionsummerfest.com, 1 +worldwidessl.net, 1 +worldwinesweb.be, 1 +wormate.io, 1 +wormburners.tk, 1 +wormbytes.ca, 1 +wormdisk.net, 1 +wormhol.org, 1 +wormhole.ga, 1 +wormholevpn.net, 1 +wormincorporated.tk, 1 +wormpress.com, 1 +worms-cowclan.tk, 1 +worongarymedical.com.au, 1 +worpswede.eu, 1 +worst.horse, 0 +wort-suchen.de, 1 +wort.lu, 1 +worthcountyiowa.gov, 1 +worthless.company, 1 +worthlessingratitudecq.cf, 1 +worthlessingratitudecq.gq, 1 +worthlessingratitudecq.ml, 1 +worthlydeals.com, 1 +worthwritingfor.com, 1 +worthygo.com, 1 +worzo.tk, 1 +woshiluo.com, 1 +woshiluo.site, 1 +wossl.com, 1 +wossl.net, 1 +wot-tudasbazis.hu, 1 +wot-zadrot.com, 1 +wotcheats.ru, 1 +woti.dedyn.io, 1 +wotmods.org, 0 +wotsunduk.ru, 1 +wotzadrot.com, 1 +woudenberg.nl, 0 +woudenbergsedrukkerij.nl, 1 +wound-doc.co.uk, 1 +woutergeraedts.nl, 1 +wouterslop.com, 1 +wouterslop.eu, 1 +wouterslop.nl, 1 +woutervdb.com, 1 +woutiscoding.be, 1 +wow-dsg.ch, 1 +wow-foederation.de, 1 +wow-screenshots.net, 1 +wow-serbia.tk, 1 +wowaffixes.info, 1 +wowarcaim.ml, 1 +wowbouncycastles.co.uk, 1 +wowcinema.tk, 1 +wowede.com, 1 +wowgraphic.in, 1 +wowhelp.it, 1 +wowi-ffo.de, 1 +wowjs.co.uk, 1 +wowjs.org, 1 +wowjs.uk, 1 +wowkia.com, 1 +wowlegacy.ml, 1 +wowlove.tk, 1 +wownmedia.com, 1 +wownskportal.tk, 1 +wowonini.com, 1 +wowpolisa.pl, 1 +wowqueboda.com, 1 +wows-mods.tk, 1 +wozalapha.com, 1 +wozwebdesign.com.br, 1 +wp-bootstrap.org, 1 +wp-bundle.co, 0 +wp-cloud.fi, 0 +wp-fastsearch.de, 1 +wp-master.org, 1 +wp-mix.com, 1 +wp-securehosting.com, 1 +wp-speed.com, 1 +wp-stack.pro, 1 +wp-tao.com, 1 +wp-tmg.com, 1 +wp-webagentur.de, 1 +wp2static.com, 1 +wpandup.org, 1 +wpautolistings.com, 1 +wpbeter.nl, 1 +wpboot.com, 1 +wpbox.cc, 0 +wpboys.com, 0 +wpcanban.com, 0 +wpcc.io, 1 +wpccu-cdn.org, 1 +wpcdn.bid, 1 +wpcepat.com, 1 +wpcharged.nz, 1 +wpcheck.io, 1 +wpcrs.org, 1 +wpcs.pro, 1 +wpdepo.com, 1 +wpdublin.com, 1 +wpen.ru, 1 +wpexplorer.com, 1 +wpformation.com, 1 +wpforum.tk, 1 +wpfullpackage.com, 1 +wpfy.me, 1 +wpfy.org, 1 +wpg-verwaltungen.de, 1 +wpgoblin.com, 1 +wphaxor.com, 1 +wphelpwithhomework.tk, 1 +wpherc.com, 0 +wphlive.tv, 1 +wphosting.ovh, 1 +wphostingblog.nl, 1 +wpinfos.de, 0 +wpinter.com, 1 +wpjakarta.com, 1 +wplan.io, 1 +wpldn.uk, 1 +wpletter.de, 1 +wplibrary.net, 1 +wplistings.pro, 1 +wpmeetup-berlin.de, 1 +wpml.org, 1 +wpmu-tutorials.de, 1 +wpnesia.id, 1 +wpnews.ga, 1 +wpnews.gq, 1 +wpno.com, 0 +wpnovice.tk, 1 +wpnuvem.com, 1 +wpoptimalizace.cz, 1 +wpostats.com, 0 +wppeeps.com, 1 +wpresscoder.com, 1 +wprodevs.com, 1 +wpscholar.com, 1 +wpsermons.com, 1 +wpserp.com, 1 +wpsharks.com, 1 +wpsite.dk, 1 +wpsitemovers.com, 1 +wpslimseo.com, 1 +wpsmackdown.com, 1 +wpspeedking.com, 1 +wpspeedmatters.com, 1 +wpspeedmetrix.com, 1 +wpsuites.com, 1 +wptangtoc.com, 1 +wpthaiuser.com, 1 +wpthemearchive.com, 1 +wpthemecloud.com, 1 +wptorium.com, 1 +wptotal.com, 1 +wptrigone.net, 1 +wpuse.ru, 1 +wq.ro, 1 +wqaw3.tk, 1 +wr.su, 1 +wrap.in.ua, 1 +wrapit.hu, 1 +wrapitup.co.uk, 1 +wrara.org, 1 +wrathofgeek.com, 1 +wrbunderwriting.com, 0 +wrc-results.com, 1 +wrd48.net, 1 +wrdcfiles.ca, 1 +wrdx.io, 1 +wrecked.cf, 1 +wrenwrites.com, 1 +wrestling.net.au, 0 +wrestlingnewssource.com, 1 +wrfalimentos.com.br, 1 +wrglzd.com, 1 +wrgms.com, 1 +wringer.ga, 1 +wristreview.com, 1 +write-right.net, 1 +writeandedit-for-you.com, 1 +writemyessay.today, 1 +writemyessays.com, 1 +writemypaperhub.com, 1 +writemytermpapers.com, 1 +writeoff.me, 1 +writepro.net, 1 +writer24.ru, 1 +writerecommendations.ga, 1 +writereditor.com, 1 +writerimranc.ca, 1 +writers-club.tk, 1 +writersblock.tk, 1 +writesafer.com, 1 +writestreak.team, 1 +writing-expert.com, 1 +writingapps.ga, 1 +writingcities.net, 1 +writingpapersonlineformoney.ga, 1 +writingtoserve.net, 1 +writtenandrecorded.com, 1 +writtenworld.bg, 1 +wrkflowmedia.de, 1 +wrmea.org, 1 +wrn.sh, 1 +wrnck.cloud, 1 +wroclawguide.com, 1 +wrong.wang, 1 +wrozbyonline.pl, 1 +wrp.gov, 1 +ws159.com, 1 +ws5.ru, 1 +wsa.org.nz, 1 +wsa.poznan.pl, 1 +wsadek.ovh, 1 +wsave.be, 1 +wsb-immo.at, 1 +wsb-immobilien.at, 1 +wsb.onl, 1 +wsb.pl, 1 +wsbhvac.com, 1 +wscales.com, 0 +wscauth.de, 1 +wscbiolo.id, 1 +wscore.me, 1 +wsdcap.com, 1 +wsdcapital.com, 1 +wselektro.de, 1 +wseo.kz, 1 +wsetech.com, 1 +wsg127.com, 0 +wsgvet.com, 1 +wsiaca.org, 1 +wsjf.org, 1 +wsl.sh, 1 +wsldp.com, 1 +wso.gr, 1 +wso01.com, 1 +wsrn.de, 1 +wss.com.ve, 1 +wsspalluto.de, 1 +wssv.ch, 0 +wstudio.ch, 0 +wstx.com, 1 +wsv-pfeffingen.de, 1 +wsyy.info, 1 +wszystkocokocham.com, 1 +wt-server3.de, 1 +wtccc.org.uk, 1 +wtfbryan.com, 0 +wtfcripto.com, 1 +wtfindonesia.tk, 1 +wtfnope.org, 1 +wth.in, 1 +wtp.co.jp, 1 +wtpdive.jp, 1 +wtpmj.com, 1 +wtup.net, 0 +wtw.io, 1 +wuchipc.com, 1 +wuchoamoveis.com.br, 1 +wucke13.de, 1 +wuerfel.wf, 1 +wuerfelmail.de, 1 +wuergler-consulting.ch, 1 +wuestenbergs.tk, 1 +wufupay.com, 1 +wug.fun, 0 +wug.jp, 1 +wug.news, 1 +wui.fan, 1 +wuifan.com, 1 +wuifan.in, 1 +wuji.cz, 1 +wuki.li, 1 +wuknet.com, 1 +wuknet.net, 1 +wulala.us, 1 +wulel.cn, 0 +wulfrun-invicta.tk, 1 +wum.me, 1 +wumai-p.cn, 1 +wumbo.co.nz, 1 +wumbo.ga, 1 +wumbo.kiwi, 1 +wumbo.ml, 1 +wumbo.tk, 1 +wuminhao.com, 1 +wunder.io, 1 +wunderkarten.de, 1 +wunderlist.com, 1 +wundernas.ch, 1 +wundi.net, 1 +wunschpreisauto.de, 1 +wunschzettel.de, 1 +wuppertal-2018.de, 0 +wurmannsquick.bayern, 1 +wurmannsquick.de, 1 +wurzelkanal.de, 1 +wuupz.com, 1 +wuxian.ml, 0 +wuyuan.io, 1 +wuyue.photo, 1 +wuzigackl.de, 1 +wv-n.de, 1 +wvg.myds.me, 1 +wvhin.org, 1 +wvpbs.ml, 1 +wvv-8522.com, 1 +wvw-8522.com, 1 +ww-design.ch, 1 +ww00228.com, 1 +ww0512.com, 1 +ww5197.co, 1 +ww6729.co, 1 +ww6729.com, 1 +ww6957.co, 1 +ww8989.com, 1 +ww9297.co, 1 +ww9397.com, 1 +ww9721.com, 1 +ww9728.co, 1 +wwa-clan.tk, 1 +wwads.cn, 1 +wwbsb.xyz, 1 +wwc.ren, 1 +wweforums.net, 0 +wweichen.com.cn, 0 +wwgc2011.se, 1 +wwin818.com, 1 +wwjd.dynu.net, 1 +wwv-8522.com, 1 +wwv-8722.com, 1 +wwvip88.com, 1 +www-33445.com, 1 +www-38978.com, 1 +www-49889.com, 1 +www-5287.com, 1 +www-68277.com, 1 +www-8225.com, 1 +www-8522.am, 1 +www-8522.com, 1 +www-8722.com, 1 +www-8887999.com, 0 +www-9822.com, 1 +www-fwt.com, 1 +www-pheromone.com, 1 +www-pheromones.com, 1 +www-railto.com, 1 +www.aclu.org, 0 +www.amazon.ca, 1 +www.amazon.cn, 1 +www.amazon.co.jp, 1 +www.amazon.co.uk, 1 +www.amazon.com, 1 +www.amazon.com.au, 1 +www.amazon.com.br, 1 +www.amazon.com.mx, 1 +www.amazon.de, 1 +www.amazon.es, 1 +www.amazon.fr, 1 +www.amazon.in, 1 +www.amazon.it, 1 +www.amazon.nl, 1 +www.banking.co.at, 0 +www.braintreepayments.com, 0 +www.capitainetrain.com, 0 +www.cnet.com, 1 +www.dropbox.com, 1 +www.dropcam.com, 0 +www.edu.tw, 1 +www.entropia.de, 0 +www.eternalgoth.co.uk, 1 +www.etsy.com, 1 +www.evernote.com, 0 +www.facebook.com, 0 +www.fastmail.com, 1 +www.ft.com, 1 +www.g.co, 0 +www.gamesdepartment.co.uk, 1 +www.getcloak.com, 0 +www.gmail.com, 0 +www.googlemail.com, 0 +www.gov.pl, 1 +www.gov.scot, 1 +www.gov.uk, 0 +www.govt.nz, 1 +www.grc.com, 0 +www.healthcare.gov, 0 +www.heliosnet.com, 1 +www.history.pe, 1 +www.honeybadger.io, 0 +www.hyatt.com, 1 +www.icann.org, 0 +www.irccloud.com, 0 +www.lookout.com, 0 +www.messenger.com, 1 +www.mylookout.com, 0 +www.noisebridge.net, 1 +www.opsmate.com, 1 +www.org.gg, 1 +www.paypal.com, 1 +www.python.org, 1 +www.re, 1 +www.rememberthemilk.com, 0 +www.rme.li, 0 +www.sb, 1 +www.simbolo.co.uk, 0 +www.simple.com, 0 +www.techrepublic.com, 1 +www.theguardian.com, 1 +www.therapynotes.com, 1 +www.tinfoilsecurity.com, 1 +www.torproject.org, 0 +www.tumblr.com, 0 +www.twitter.com, 0 +www.united.com, 1 +www.usaa.com, 0 +www.viasinc.com, 0 +www.wepay.com, 0 +www.wordpress.com, 0 +www.zdnet.com, 1 +www00228a.com, 1 +www00228b.com, 1 +www00228c.com, 1 +www00228d.com, 1 +www00228e.com, 1 +www63605.com, 1 +www68277.com, 1 +wwwclan.tk, 1 +wwweb.be, 1 +wwwhackeronecom.com, 1 +wwwindows.co.uk, 1 +wwwithcarrie.com, 1 +wwwn888.com, 1 +wwwrailto.com, 1 +wwww.is, 1 +wwwwnews.tk, 1 +wx37.ac.cn, 1 +wx6688.cc, 1 +wxcafe.net, 1 +wxdisco.com, 1 +wxforums.com, 1 +wxh.jp, 1 +wxhbts.com, 1 +wxkxsw.com, 1 +wxlog.cn, 1 +wxrlab.com, 1 +wxservices.tk, 1 +wxster.com, 1 +wxw.moe, 1 +wxxcxd88.com, 1 +wxzm.sx, 1 +wy188.cc, 1 +wyam.io, 1 +wyatttauber.com, 1 +wybar.uk, 1 +wycena.ga, 1 +wyckoff.pro, 1 +wyckoff.vip, 1 +wycombetoday.com, 0 +wyczaruj.pl, 1 +wyday.com, 1 +wygibanki.pl, 1 +wygodnie.pl, 1 +wyhuesli.ch, 1 +wykop.pl, 1 +wyldfiresignage.com, 1 +wylog.ph, 1 +wyo.cam, 1 +wyomingmi.gov, 1 +wyomingurology.com, 1 +wyregisteredagent.net, 1 +wyrickstaxidermy.com, 1 +wyrihaximus.net, 1 +wyrimaps.net, 1 +wyssmuller.ch, 0 +wysz.com, 1 +wywabmnie.pl, 1 +wyydsb.cn, 1 +wyydsb.com, 1 +wyydsb.xin, 1 +wyzphoto.nl, 1 +wyzwaniemilosci.com, 1 +wz8.info, 1 +wzajemnie.org.pl, 1 +wzrd.in, 1 +wzxaini9.com, 1 +wzyboy.org, 1 +x-6.pl, 1 +x-charge.uk, 1 +x-embed.com, 1 +x-iweb.ru, 1 +x-lan.be, 1 +x-net24.pl, 1 +x-one.co.jp, 1 +x-pertservice.com, 1 +x-way.org, 1 +x.io, 1 +x.st, 1 +x00228.com, 1 +x00701.com, 1 +x00708.com, 1 +x00738.com, 1 +x00776.com, 1 +x00786.com, 1 +x0r.be, 1 +x13.com, 1 +x13.net, 1 +x1616.tk, 1 +x17.cafe, 1 +x1be.win, 0 +x2816.com, 1 +x2d2.de, 0 +x2ox.com, 1 +x36533.com, 1 +x378.ch, 1 +x3803.com, 1 +x3816.com, 1 +x3828.com, 1 +x509.io, 1 +x5197.co, 1 +x58f.com, 1 +x58p.com, 1 +x58t.com, 1 +x5901.com, 1 +x5902.com, 1 +x5903.com, 1 +x5904.com, 1 +x5905.com, 1 +x5906.com, 1 +x5907.com, 1 +x5908.com, 1 +x5910.com, 1 +x59988.com, 1 +x64architecture.com, 1 +x6729.co, 1 +x69.biz, 1 +x6957.co, 1 +x7008.com, 0 +x7713.com, 1 +x7718.com, 1 +x7719.com, 1 +x7782.com, 1 +x7785.com, 1 +x7795.com, 1 +x77dd.com, 1 +x77ee.com, 1 +x77hh.com, 1 +x77jj.com, 1 +x77kk.com, 1 +x77mm.com, 1 +x77nn.com, 1 +x77pp.com, 1 +x77qq.com, 1 +x77ww.com, 1 +x7plus.com, 1 +x8100000.com, 1 +x8111111.com, 1 +x8122222.com, 1 +x8133333.com, 1 +x81365.com, 1 +x8144444.com, 1 +x8155555.com, 1 +x8166666.com, 1 +x8177777.com, 1 +x8188888.com, 1 +x8199999.com, 1 +x81vv.com, 1 +x82365.com, 1 +x9016.com, 1 +x9297.co, 1 +x9721.com, 1 +x9728.co, 1 +x98t.com, 1 +x98v.com, 1 +x98y.com, 1 +x98z.com, 1 +xa.search.yahoo.com, 0 +xa1.uk, 1 +xab199.com, 1 +xab678.com, 1 +xaba.tk, 1 +xabifk.com, 1 +xacker.tk, 1 +xaffit.com, 1 +xahbspl.com, 1 +xajh.org, 1 +xakep-slon.tk, 1 +xakepctbo.tk, 1 +xamax.co.uk, 1 +xanadu-auto.cz, 1 +xanadu-catering.cz, 1 +xanadu-golf.cz, 1 +xanadu-taxi.cz, 1 +xanadu-trans.cz, 1 +xanderbron.tech, 1 +xanhdecor.com, 1 +xants.de, 1 +xanyl.de, 1 +xanzhu.com, 1 +xarangallomangallo.tk, 1 +xarmenta.tk, 1 +xatr0z.org, 0 +xaudiobooks.com, 1 +xav.ie, 1 +xavi.re, 1 +xavier.is, 1 +xavierdmello.com, 1 +xavio-design.com, 1 +xavio.in, 1 +xaxax.ru, 1 +xaydungnamcuong.com, 1 +xaynhachothue.vn, 1 +xb008.com, 1 +xb052.com, 1 +xb053.com, 1 +xb056.com, 1 +xb057.com, 1 +xb058.com, 1 +xb1001.com, 1 +xb2002.com, 1 +xb201.com, 1 +xb3008.com, 1 +xb306.com, 1 +xb380.com, 1 +xb3888.com, 1 +xb6008.com, 1 +xb601.com, 1 +xb6610.com, 1 +xb6616.com, 1 +xb6632.com, 1 +xb6636.com, 1 +xb6638.com, 1 +xb6639.com, 1 +xb6656.com, 1 +xb6673.com, 1 +xb6676.com, 1 +xb6679.com, 1 +xb6680.com, 1 +xb6683.com, 1 +xb6689.com, 1 +xb6692.com, 1 +xb6696.com, 1 +xb6806.com, 1 +xb6808.com, 1 +xb6866.com, 1 +xb6880.com, 1 +xb7001.com, 1 +xb7077.com, 1 +xb7676.com, 1 +xb780.com, 1 +xb8006.com, 1 +xb8018.com, 1 +xb836.com, 1 +xb83studio.ch, 1 +xb851.com, 1 +xb852.com, 1 +xb853.com, 1 +xb856.com, 1 +xb857.com, 1 +xb859.com, 1 +xb8606.com, 1 +xb862.com, 1 +xb865.com, 1 +xb871.com, 1 +xb872.com, 1 +xb873.com, 1 +xb8801.com, 1 +xb8806.com, 1 +xb8808.com, 1 +xb8861.com, 1 +xb891.com, 1 +xb893.com, 1 +xb896.com, 1 +xb9009.com, 1 +xb901.com, 1 +xb906.com, 1 +xb913.com, 1 +xb917.com, 1 +xb925.com, 1 +xb927.com, 1 +xb935.com, 1 +xb936.com, 1 +xb937.com, 1 +xb951.com, 1 +xb952.com, 1 +xb953.com, 1 +xb957.com, 1 +xb961.com, 1 +xb962.com, 1 +xb963.com, 1 +xb965.com, 1 +xb967.com, 1 +xb971.com, 1 +xb972.com, 1 +xb976.com, 1 +xb980.com, 1 +xb982.com, 1 +xb983.com, 1 +xbanner.tk, 1 +xbb.hk, 1 +xbb.li, 1 +xbblog.com, 1 +xbc.nz, 1 +xbdmov.com, 1 +xbertschy.com, 1 +xbjt11.com, 1 +xbjt2.com, 1 +xbjt3.com, 1 +xbjt33.com, 1 +xbjt66.com, 1 +xbjt666.com, 1 +xbjt77.com, 1 +xblau.com, 1 +xbots.tk, 1 +xbox-mag.net, 1 +xboxachievements.com, 1 +xboxdownloadthat.com, 1 +xbrl.online, 1 +xbrlsuccess.appspot.com, 1 +xbros.cz, 1 +xbt.co, 1 +xbtce.com, 1 +xbtmusic.org, 0 +xbvip.net, 1 +xbvip99.com, 1 +xbyl.xn--fiqs8s, 1 +xbyl15.com, 1 +xbyl16.com, 1 +xbyl17.com, 1 +xbyl18.com, 1 +xbyl21.com, 1 +xbyl23.com, 1 +xbyl26.com, 1 +xbyl28.com, 1 +xbyl39.com, 1 +xbyl60.com, 1 +xbyl62.com, 1 +xbyl63.com, 1 +xbyl67.com, 1 +xbyl68.com, 1 +xbyl69.com, 1 +xbyl71.com, 1 +xbyl73.com, 1 +xbyl78.com, 1 +xbyl82.com, 1 +xbyl85.com, 1 +xbyl86.com, 1 +xbyl89.com, 1 +xbyl91.com, 1 +xc9988.cc, 1 +xcafe.com, 1 +xceedgaming.com, 1 +xchangeinfo.com, 1 +xcharge.uk, 1 +xclirion-support.de, 1 +xcompany.one, 1 +xcorpsolutions.com, 1 +xcraftsumulator.ru, 1 +xcspy.org, 1 +xcvb.xyz, 1 +xd.cm, 1 +xd.gov, 1 +xdawn.cn, 1 +xdeftor.com, 1 +xdesigns.biz, 1 +xdos.io, 1 +xdtag.com, 1 +xdty.org, 1 +xdwhat.tech, 1 +xebeche.nl, 1 +xecure.zone, 1 +xecureit.com, 1 +xeerpa.com, 1 +xega.org, 1 +xehost.com, 1 +xeiropraktiki.gr, 1 +xelesante.jp, 1 +xemxx.tv, 1 +xencor.com, 1 +xendo.net, 1 +xenical-online.ga, 1 +xenical-online.tk, 1 +xenical.tk, 1 +xenicalonline.gq, 1 +xenicalorlistat.tk, 1 +xenicalpills.tk, 1 +xenocide.tk, 1 +xenomedia.nl, 1 +xenomorph.tk, 1 +xenon.cloud, 1 +xenoncloud.net, 1 +xenophile.name, 1 +xenosphere.tk, 1 +xenotropegames.com, 1 +xenoworld.de, 1 +xenox-rp.ru, 1 +xenrox.net, 1 +xentho.net, 1 +xentox.com, 1 +xeonlab.com, 1 +xeonlab.de, 1 +xerbisworks.com, 1 +xerbo.net, 0 +xerdeso.tk, 1 +xerezdeportivo.tk, 1 +xerhost.de, 0 +xerkus.pro, 1 +xerowaste.ca, 1 +xerownia.eu, 1 +xeryus.nl, 1 +xetnghiemadndanang.vn, 1 +xetown.com, 1 +xfce.space, 1 +xfcy.me, 1 +xfd3.de, 1 +xferion.com, 0 +xfinityapparel.com, 1 +xfive.de, 1 +xfix.pw, 1 +xford.tech, 1 +xfrag-networks.com, 1 +xftp.ml, 1 +xfzhao.com, 1 +xg-printonline.co.uk, 1 +xgadget.de, 1 +xgame.com.tr, 1 +xgclan.com, 1 +xgeni.us, 1 +xgn.es, 1 +xgndx.ru, 1 +xgwap.com, 1 +xgys.net, 1 +xgzepto.cn, 1 +xh7eee.com, 1 +xh7qqq.com, 1 +xhadius.de, 1 +xhanster.gq, 1 +xhcmnews.com, 1 +xhily.com, 1 +xhmikosr.io, 1 +xho.me, 1 +xi.ht, 1 +xia.de, 1 +xia100.xyz, 1 +xiamenshipbuilding.com, 1 +xiamuzi.com, 1 +xiangblog.com, 1 +xianguocy.com, 1 +xiangweiqing.co.uk, 1 +xianjianruishiyouyiyuan.com, 1 +xiao-sheng.gq, 1 +xiaobai.pro, 0 +xiaocg.xyz, 1 +xiaodingyi.cn, 1 +xiaohui.love, 1 +xiaojiyoupin.com, 1 +xiaolan.me, 1 +xiaolanglang.net, 0 +xiaolong.link, 1 +xiaomao.tk, 1 +xiaomibarato.com, 1 +xiaomionline24.pl, 1 +xiaoneijun.cn, 1 +xiaoneimao.cn, 1 +xiaoniaoyou.com, 0 +xiaowutou.com, 1 +xiaowuzhaji.com, 1 +xiaoxia.li, 1 +xiarain.com, 1 +xiashali.me, 1 +xiaxuejin.cn, 1 +xiazhanjian.com, 0 +xibilus.com, 1 +xice.cf, 1 +xice.wang, 1 +xichuangke.com, 0 +xicreative.net, 1 +xiecongan.org, 1 +xier.ch, 1 +xif.at, 1 +xifrem.com, 1 +xight.org, 1 +xiidraiinsider.com, 1 +xile.ml, 1 +xilef.org, 1 +xilegames.com, 1 +xilkoi.net, 0 +xilo.net, 1 +ximes.com, 1 +ximeshosted.com, 1 +ximiko.eus, 1 +xin365.com, 1 +xinbo010.com, 1 +xinbo016.com, 1 +xinbo018.com, 1 +xinbo019.com, 1 +xinbo020.com, 1 +xinbo026.com, 1 +xinbo028.com, 1 +xinbo030.com, 1 +xinbo038.com, 1 +xinbo050.com, 1 +xinbo056.com, 1 +xinbo059.com, 1 +xinbo060.com, 1 +xinbo066.com, 1 +xinbo068.com, 1 +xinbo069.com, 1 +xinbo070.com, 1 +xinbo076.com, 1 +xinbo078.com, 1 +xinbo079.com, 1 +xinbo080.com, 1 +xinbo086.com, 1 +xinbo088.com, 1 +xinbo089.com, 1 +xinbo090.com, 1 +xinbo096.com, 1 +xinbo098.com, 1 +xinbo099.com, 1 +xinbo120.com, 1 +xinbo129.com, 1 +xinbo130.com, 1 +xinbo138.com, 1 +xinbo150.com, 1 +xinbo156.com, 1 +xinbo158.com, 1 +xinbo160.com, 1 +xinbo170.com, 1 +xinbo178.com, 1 +xinbo179.com, 1 +xinbo180.com, 1 +xinbo186.com, 1 +xinbo189.com, 1 +xinbo190.com, 1 +xinbo196.com, 1 +xinbo198.com, 1 +xinbo200.com, 1 +xinbo218.com, 1 +xinbo238.com, 1 +xinbo256.com, 1 +xinbo258.com, 1 +xinbo260.com, 1 +xinbo266.com, 1 +xinbo268.com, 1 +xinbo269.com, 1 +xinbo270.com, 1 +xinbo276.com, 1 +xinbo278.com, 1 +xinbo279.com, 1 +xinbo280.com, 1 +xinbo286.com, 1 +xinbo290.com, 1 +xinbo296.com, 1 +xinbo298.com, 1 +xinbo299.com, 1 +xinbo306.com, 1 +xinbo308.com, 1 +xinbo316.com, 1 +xinbo318.com, 1 +xinbo326.com, 1 +xinbo338.com, 1 +xinbo350.com, 1 +xinbo356.com, 1 +xinbo359.com, 1 +xinbo369.com, 1 +xinbo376.com, 1 +xinbo378.com, 1 +xinbo379.com, 1 +xinbo38.com, 1 +xinbo380.com, 1 +xinbo386.com, 1 +xinbo389.com, 1 +xinbo390.com, 1 +xinbo396.com, 1 +xinbo398.com, 1 +xinbo399.com, 1 +xinbo400.com, 1 +xinbo401.com, 1 +xinbo406.com, 1 +xinbo407.com, 1 +xinbo466.com, 1 +xinbo468.com, 1 +xinbo478.com, 1 +xinbo480.com, 1 +xinbo496.com, 1 +xinbo498.com, 1 +xinbo506.com, 1 +xinbo508.com, 1 +xinbo516.com, 1 +xinbo526.com, 1 +xinbo528.com, 1 +xinbo536.com, 1 +xinbo538.com, 1 +xinbo556.com, 1 +xinbo566.com, 1 +xinbo570.com, 1 +xinbo576.com, 1 +xinbo578.com, 1 +xinbo580.com, 1 +xinbo586.com, 1 +xinbo590.com, 1 +xinbo600.com, 1 +xinbo608.com, 1 +xinbo609.com, 1 +xinbo610.com, 1 +xinbo676.com, 1 +xinebf.com, 0 +xing.ml, 1 +xingyu1993.cn, 1 +xinja.com.au, 1 +xinlandm.com, 1 +xinmeiti168.cn, 1 +xinmeiti365.cn, 1 +xinnermedia.nl, 1 +xinnixdeuren-shop.be, 1 +xinpujing198.com, 0 +xinpujing200.com, 0 +xinpujing518.com, 0 +xinpujing918.com, 0 +xinsane.com, 1 +xinsto.com, 1 +xinu.xyz, 1 +xinuurl.com, 1 +xinxin.pl, 1 +xinyitour.tw, 1 +xion.nu, 1 +xiphwork.de, 1 +xiqonline.com, 1 +xirion.net, 1 +xitin.tk, 1 +xiumu.org, 1 +xiyu.moe, 0 +xjd.vision, 1 +xjf6.com, 1 +xjjeeps.com, 1 +xjpvictor.info, 1 +xkblog.xyz, 1 +xkcd.pw, 1 +xkviz.net, 1 +xkwy2018.cn, 1 +xlan.be, 1 +xlange.com, 1 +xlaw.com.br, 1 +xldl.ml, 1 +xlem.cn, 1 +xlfilippou.com, 1 +xlhdh.vip, 0 +xlink.com.pl, 1 +xlmnews.today, 1 +xloud.cf, 1 +xluxes.jp, 1 +xlyingyuan.com, 0 +xm.digital, 1 +xmag.pl, 1 +xmedius.ca, 0 +xmedius.com, 1 +xmedius.eu, 1 +xmenrevolution.com, 1 +xmflyrk.com, 1 +xmgspace.me, 1 +xminds.net, 1 +xmiui.com, 1 +xmlbeam.org, 1 +xmp3.net, 1 +xmpp.dk, 0 +xmppwocky.net, 1 +xmr.to, 1 +xmr.wiki, 1 +xmusic.live, 1 +xmv.cz, 1 +xmyy.com, 1 +xn------7cdabibmbihbgykn8elfdbfgbeqxmlc3a.tk, 1 +xn------7cdbfcbc0ab6akhadmzphmbibhebcc7b0ahshon.tk, 1 +xn-----6kcbb0cahbiskdv1bcj5c7g.tk, 1 +xn-----6kcbjcgl1atjj7aadbkxfxfe7a9yia.xn--p1ai, 1 +xn-----7kcbhdpr0asllefq0bjk.com, 1 +xn-----7kcgqqeagtqecgbhc3aginaie1hwh.tk, 1 +xn-----8kcdcb4bffibpgkpbdbcc5cedihs.tk, 1 +xn-----8kcgbo2bmdgkdacthvjf.xn--p1ai, 1 +xn----7sbabexseekfke3cifnf3b4r.tk, 1 +xn----7sbabrwauchevq0ba.xn--p1ai, 1 +xn----7sbarcdvrtr1be.org, 1 +xn----7sbbagp2bcfwdeee1afm.xn--p1ai, 1 +xn----7sbbak4cyaoedjf3m.xn--p1ai, 1 +xn----7sbbfsshjvgyde8g3c.xn--p1ai, 1 +xn----7sbbgbr0arxb4a4exa.com.ua, 1 +xn----7sbbhzfbdo6dnf.tk, 1 +xn----7sbbncaddj9a9b6am9p.tk, 1 +xn----7sbbq5b0a1c.com, 1 +xn----7sbedlbhv2azb6a.xn--j1amh, 1 +xn----7sbfl2alf8a.xn--p1ai, 1 +xn----7sblrfhjjgq8g.xn--p1ai, 1 +xn----7sbmucgqdbgwwc5e9b.xn--p1ai, 1 +xn----7sbq4auch5b4b.xn--p1ai, 1 +xn----8hcdn2ankm1bfq.com, 1 +xn----8sbfkobhgmxahfmmhe8b8c6ff.xn--p1ai, 1 +xn----9sbkdigdao0de1a8g.com, 1 +xn----dtbfemantkhdczc.tk, 1 +xn----dtbfemmqjdddczc.tk, 1 +xn----dtbhcpoeofgcvoic1s.xn--p1ai, 1 +xn----etba6agm4a9a.xn--p1ai, 1 +xn----etbqa2alia5i.tk, 1 +xn----ncfb.ws, 1 +xn---35-6cdk1dnenygj.xn--p1ai, 1 +xn--0kq33cbsi8bk6d417b.com, 1 +xn--0kq33cz5c8wmwrqqw1d.com, 1 +xn--12c3bpr6bsv7c.com, 1 +xn--12cg9bnm5ci2ag9hbcs17a.com, 1 +xn--13-6kc0bufl.xn--p1ai, 1 +xn--158h.ml, 0 +xn--15tx89ctvm.xn--6qq986b3xl, 1 +xn--1yst51avkr.ga, 1 +xn--1yst51avkr.xn--6qq986b3xl, 1 +xn--24-6kc5agehpdf5a.xn--p1ai, 1 +xn--24-6kch4bfqee.xn--p1ai, 1 +xn--24-glcia8dc.xn--p1ai, 1 +xn--2i0bo6pvvy.com, 1 +xn--2i0bo6pvvy.kr, 1 +xn--2i0bo6pvvy.net, 1 +xn--2i0bo6pvvy.org, 1 +xn--2sxs9ol7o.com, 1 +xn--36-dlcdun7abo4a.xn--p1ai, 1 +xn--3lqp21gwna.cn, 1 +xn--3st814ec8r.cn, 1 +xn--3stv82k.hk, 1 +xn--3stv82k.tw, 1 +xn--41a.ml, 1 +xn--43-6kc4be0fbz.xn--p1ai, 1 +xn--4brt03c.xn--io0a7i, 1 +xn--4kro7fswi.xn--6qq986b3xl, 1 +xn--4pv80kkz8auzf.jp, 1 +xn--54-6kc3btfht.xn--p1ai, 1 +xn--57h.ml, 0 +xn--5dbkjqb0d.com, 1 +xn--5dbkjqb0d.net, 1 +xn--6kru6im1lczj.com, 1 +xn--6m1a86p.com, 1 +xn--6n2ao17b.com, 0 +xn--6o8h.cf, 1 +xn--6qq52xuogcjfw8pwqp.ga, 1 +xn--6qq62xsogfjfs8p1qp.ga, 1 +xn--6x6a.life, 1 +xn--79q87uvkclvgd56ahq5a.net, 1 +xn--7ca.co, 1 +xn--7or43h.jp, 1 +xn--7xa.google.com, 1 +xn--80a1a8b.tk, 1 +xn--80a6a1b.tk, 1 +xn--80a6aq.tk, 1 +xn--80aaa3bgsbbm.tk, 1 +xn--80aaa5ajbrzqd.tk, 1 +xn--80aaaane9bk7bh.tk, 1 +xn--80aaacqdkdv7b0a.tk, 1 +xn--80aaagbtu3bfbullc1c.xn--80asehdb, 1 +xn--80aaaptltzqd.tk, 1 +xn--80aabn5d9h.xn--90a3ac, 1 +xn--80aafaxhj3c.xn--p1ai, 1 +xn--80aanbkcescrdedmxzcl4pmc.xn--p1acf, 1 +xn--80ab1bse.tk, 1 +xn--80abb4bp.tk, 1 +xn--80abmghlx4ajd.tk, 1 +xn--80abwhtbgbedcy6h.com, 1 +xn--80ace6be.tk, 1 +xn--80acghh.xn--p1ai, 1 +xn--80achgm7d.tk, 1 +xn--80acqgkhcn.tk, 1 +xn--80acubre5k.tk, 1 +xn--80adb4aeode.xn--p1ai, 1 +xn--80adbevek3air0ee9b8d.com, 1 +xn--80adbvdjzhptl1be6j.com, 1 +xn--80ae7bafe4d.tk, 1 +xn--80aebbkaqx6at.xn--p1ai, 1 +xn--80aejhvi0at.xn--90ais, 1 +xn--80aejljbfwxn.xn--p1ai, 1 +xn--80afdc7a1a8m.kyiv.ua, 1 +xn--80affa6ai0a.tk, 1 +xn--80ageukloel.xn--p1ai, 1 +xn--80ah4f.xn--p1ai, 1 +xn--80ahclcaoccacrhfebi0dcn5c1jh.xn--p1ai, 1 +xn--80ahcnlhmh.xn--p1ai, 1 +xn--80ahjdhy.tk, 1 +xn--80ahnefiifo0g.xn--p1ai, 1 +xn--80aihgal0apt.xn--p1ai, 1 +xn--80akjfhoqm2h2a.xn--p1ai, 1 +xn--80aknjgrv.tk, 1 +xn--80ancacgircb8q.xn--p1ai, 1 +xn--80anogxed.xn--p1ai, 1 +xn--80aocgsfei.xn--p1ai, 1 +xn--80aod6g.tk, 1 +xn--80aqlihiyv.xn--p1acf, 1 +xn--80axad8esa.tk, 1 +xn--80azep.tk, 1 +xn--8bi.gq, 0 +xn--8n2am80a.tech, 1 +xn--90accgba6bldkcbb7a.xn--p1acf, 1 +xn--90acjfgylpnm.xn--90ais, 1 +xn--90agmsorb.tk, 1 +xn--90aij9af3f.com.ua, 1 +xn--90aimoos.tk, 1 +xn--90aizn.tk, 1 +xn--95q32l0t6b9cb17l.cn, 1 +xn--98jm6m.jp, 1 +xn--9wy4jw3llnh.com, 1 +xn--9xa.fun, 1 +xn--agncia-4ua.cat, 1 +xn--allgu-biker-o8a.de, 1 +xn--anyd-7na.at, 1 +xn--aviao-dra1a.pt, 1 +xn--avocai-timioara-kmf1a.ro, 1 +xn--b1aa9b.tk, 1 +xn--b1agcgqrei7i.tk, 1 +xn--b1ayb.tk, 1 +xn--b3c4f.xn--o3cw4h, 1 +xn--baron-bonzenbru-elb.com, 1 +xn--bckerei-wohlgemuth-ltb.de, 1 +xn--ben-bank-8za.dk, 1 +xn--benbank-dxa.dk, 1 +xn--bersetzung-8db.cc, 1 +xn--bersetzungen-beglaubigt-bpc.de, 1 +xn--berwachungspaket-izb.at, 1 +xn--betwinnerespaa-2nb.com, 1 +xn--blusastlacotalpeas-20b.online, 1 +xn--bm3bl9r.com, 1 +xn--brneruhr-0za.ch, 1 +xn--c1aaulbdc.tk, 1 +xn--c1adqibibm8i.com, 1 +xn--c1aehtaetb.xn--p1ai, 1 +xn--c1aid4ap8e.tk, 1 +xn--c1aolabgdj.tk, 1 +xn--c5w032d4vi.xn--fiqs8s, 1 +xn--c5w27q.ml, 1 +xn--cck4ax91r.com, 1 +xn--cck7f515h.com, 1 +xn--cckdrt0kwb4g3cnh.com, 1 +xn--cckvb1cwa0c5br5e2d2711k.net, 1 +xn--cctsgy36bnvprwpekc.com, 1 +xn--circul-gva.cc, 1 +xn--circul-u3a.cc, 1 +xn--cisowcy-pjb5t.pl, 1 +xn--contrasea-s6a.cl, 1 +xn--d1aca2a5al.tk, 1 +xn--d1acalaltdk2d.xn--p1ai, 1 +xn--d1acfdr6h.com.ua, 1 +xn--d1acj9c.xn--90ais, 0 +xn--d1aczdsdn4d.tk, 1 +xn--d1awi.tk, 1 +xn--dcko6fsa5b1a8gyicbc.biz, 1 +xn--dckya4a0bya6x.com, 1 +xn--dckya4a0bya6x.jp, 1 +xn--dej-3oa.lv, 1 +xn--detrkl13b9sbv53j.com, 1 +xn--detrkl13b9sbv53j.org, 1 +xn--dfirtrning-i6a.dk, 1 +xn--diseadorwebmallorca-y3b.com, 1 +xn--dk8haaa.ws, 1 +xn--dmontaa-9za.com, 1 +xn--dragni-g1a.de, 1 +xn--dragni-g1a.eu, 1 +xn--dtursfest-72a.dk, 1 +xn--durhre-yxa.de, 1 +xn--duzy3f.com, 1 +xn--duzy3f.world, 1 +xn--dviz-5qa.com, 1 +xn--e--0g4aiy1b8rmfg3o.jp, 1 +xn--e--4h4axau6ld4lna0g.com, 1 +xn--e--ig4a4c3f6bvc5et632i.com, 1 +xn--e--k83a5h244w54gttk.xyz, 1 +xn--e1aaavheew.xn--p1ai, 1 +xn--e1aaavheewr.xn--p1ai, 1 +xn--e1aahuqbk6f.tk, 1 +xn--e1adlfhcdo7h.xn--p1ai, 1 +xn--e1agokg6a9a.tk, 1 +xn--e1aoahhqgn.xn--p1ai, 1 +xn--e1aoddhq.gq, 1 +xn--ecki0cd0bu9a4nsjb.com, 1 +xn--eebao6b.com, 1 +xn--eebao6b.net, 1 +xn--eglujemy-23b.net, 1 +xn--ehqw04eq6e.jp, 1 +xn--elsignificadodesoar-c4b.com, 1 +xn--eo5aaa.eu.org, 1 +xn--erban-e9b.ro, 1 +xn--erklderbarenben-slbh.dk, 1 +xn--et8h.cf, 0 +xn--ex-1b4auld4fn3u3ck2069g.com, 1 +xn--f1ai7a.tk, 1 +xn--f9jh4f4b4993b66s.tokyo, 1 +xn--fakovcov-gza74b.eu, 1 +xn--fakovec-k6a.eu, 1 +xn--familie-pppinghaus-l3b.de, 1 +xn--feuerlscher-arten-4zb.de, 1 +xn--flordepia-s6a.com, 1 +xn--fp8h58f.ws, 1 +xn--frankierknig-djb.de, 1 +xn--fretagsfinanser-8sb.se, 1 +xn--fs5ak3f.com, 1 +xn--gfrr-7qa.li, 1 +xn--gfrrli-yxa.ch, 1 +xn--ggle-qoaa.com, 1 +xn--gi8h6v.ml, 1 +xn--gmq92k.nagoya, 1 +xn--grnderlehrstuhl-0vb.de, 1 +xn--grnstrm-r1ae.nu, 1 +xn--gstehaus-leipzig-vnb.de, 1 +xn--h1aarew7ct.tk, 1 +xn--h1ahbcdb8g.xn--p1ai, 1 +xn--heilendehnde-ocb.de, 1 +xn--hfk-allgu-schwaben-stb.de, 1 +xn--hgbk4a00a.com, 1 +xn--hllrigl-90a.at, 0 +xn--hnse-gra.net, 1 +xn--hsers-kva.de, 1 +xn--i2ru8q2qg.com, 1 +xn--ikketenkpdet-1cb.no, 1 +xn--imker-in-nrnberg-szb.de, 1 +xn--int-ru8ea.xn--6qq986b3xl, 1 +xn--internetlnen-1cb.com, 1 +xn--ionunica-29c.ro, 1 +xn--irr.xn--fiqs8s, 1 +xn--is8h6d.gq, 0 +xn--j1afcdm4f.xn--p1ai, 1 +xn--j1agcso.xn--p1ai, 1 +xn--j4h.cf, 1 +xn--j8se.com, 1 +xn--jda.tk, 1 +xn--jp8hx8f.ws, 1 +xn--kckd0bd4a8tp27yee2e.com, 1 +xn--kda.tk, 1 +xn--keditr-0xa.biz, 1 +xn--kkcon-fwab.nz, 1 +xn--kl-oja.is, 1 +xn--klmek-0sa.com, 1 +xn--ktha-kamrater-pfba.se, 1 +xn--l8js6h476m.xn--q9jyb4c, 1 +xn--labanskllermark-ftb.se, 1 +xn--laclas-n0a.ro, 1 +xn--lfv405c.com, 1 +xn--ll-yka.de, 1 +xn--lna-2000-9za.nu, 1 +xn--lna-4000-9za.nu, 1 +xn--lnakuten-9za.com, 1 +xn--losolivareos-jhb.com, 1 +xn--love-un4c7e0d4a.com, 1 +xn--lsaupp-iua.se, 1 +xn--lskieradio-3gb44h.pl, 1 +xn--lti-3qa.lv, 1 +xn--m1aba.tk, 1 +xn--manuela-stsser-psb.de, 1 +xn--marn-8ra.eu, 1 +xn--martnvillalba-zib.com, 1 +xn--martnvillalba-zib.net, 1 +xn--mein-kchenhelfer-ozb.de, 1 +xn--mensenges-o1a8c.gq, 1 +xn--mensengesss-t8a.gq, 1 +xn--mentaltraining-fr-musiker-uwc.ch, 1 +xn--mgbbh2a9fub.xn--ngbc5azd, 0 +xn--mgbmmp7eub.com, 1 +xn--mgbpkc7fz3awhe.com, 1 +xn--mgbqq.com, 1 +xn--mgbuq0c.net, 1 +xn--mgi-qla.life, 1 +xn--mhringen-65a.de, 1 +xn--mllerhesszimmerli-22b.ch, 1 +xn--mntsamling-0cb.dk, 1 +xn--myrepubic-wub.net, 1 +xn--myrepublc-x5a.net, 1 +xn--n1aeexs.net, 1 +xn--nicieri-b4a.ro, 1 +xn--nidar-tib.org, 1 +xn--nide-loa.ee, 1 +xn--nordlicht-hrnum-jtb.de, 1 +xn--nrrdetval-v2ab.se, 1 +xn--o38h.tk, 1 +xn--o77hka.ga, 1 +xn--obt757c.com, 1 +xn--oiqt18e8e2a.eu.org, 1 +xn--oj-uu2c9c422w3mh.com, 1 +xn--okra.xn--6qq986b3xl, 1 +xn--or3bkpg7h2qs.io, 1 +xn--p3t555glxhnwa.com, 1 +xn--p8j9a0d9c9a.xn--q9jyb4c, 1 +xn--pascal-klsch-cjb.de, 1 +xn--pbt947am3ab71g.com, 1 +xn--pckl4ji.ml, 1 +xn--pckqk6xk43lunk.net, 1 +xn--pe-bka.ee, 1 +xn--pn1am9c.com, 1 +xn--pq1a637b.xn--6qq986b3xl, 1 +xn--prfontaine-c7a.name, 1 +xn--qckss0j.tk, 1 +xn--qfun83b.ga, 1 +xn--r77hya.ga, 1 +xn--r8jzaf7977b09e.com, 1 +xn--rb-fka.it, 1 +xn--rdiger-kuhlmann-zvb.de, 1 +xn--registriertesexualstraftter-ykc.de, 1 +xn--reisebro-herrsching-bbc.de, 1 +xn--rlcus7b3d.xn--xkc2dl3a5ee0h, 1 +xn--roselire-60a.ch, 0 +xn--roselire-60a.com, 0 +xn--rt-cja.eu, 1 +xn--rt-cja.ie, 1 +xn--rtter-kva.eu, 1 +xn--ruanmller-u9a.com, 1 +xn--s-0fa.fi, 1 +xn--s-1gaa.fi, 1 +xn--s1r71tg0o30bxm52odlvspdop4b.cn, 1 +xn--sb-lka.org, 1 +xn--schcke-yxa.de, 1 +xn--schlerzeitung-ideenlos-ulc.de, 1 +xn--schpski-c1a.de, 1 +xn--schsischer-christstollen-qbc.shop, 1 +xn--schwedischezahnrztin-pzb.de, 1 +xn--skmotoroptimering-zzb.site, 1 +xn--solidaritt-am-ort-yqb.de, 1 +xn--soloatrapasueos-brb.online, 1 +xn--spenijmazania-yhc.pl, 1 +xn--spiraphnix-olb.xyz, 1 +xn--srenpind-54a.dk, 1 +xn--strandhaus-hinter-der-dne-1wc.de, 1 +xn--svezavaukuu-ulb08i.rs, 1 +xn--sz8h.ml, 1 +xn--t-oha.lv, 1 +xn--t8j4aa4nkg1h9bwcvud.com, 1 +xn--t8j4aa4nzg3a5euoxcwee.xyz, 1 +xn--t8jo9k1b.com, 1 +xn--tagungssttte-usedom-owb.de, 1 +xn--tagungssttte-zinnowitz-84b.de, 1 +xn--tgstationen-x8a.se, 1 +xn--thorme-6uaf.ca, 1 +xn--tigreray-i1a.org, 1 +xn--trdler-xxa.xyz, 1 +xn--u8jwd.ga, 1 +xn--u9j920h4sbt5ex10f.online, 1 +xn--u9jv84l7ea468b.com, 1 +xn--u9jy16ncfao19mo8i.nagoya, 1 +xn--uasacrilicas-9gb.net, 1 +xn--ugt.cc, 0 +xn--ukasik-2db.pl, 1 +xn--underux-0za.eu, 1 +xn--v-wfa35g.ro, 1 +xn--v4q.ml, 1 +xn--v6q426ishax2a.xyz, 1 +xn--vck8crc010pu14e.biz, 1 +xn--vck8crcu789ajtaj92eura.xyz, 1 +xn--wby9t.xyz, 0 +xn--whlefamilie-l8a.de, 1 +xn--woistdermlleimer-rzb.de, 1 +xn--wp9ha.ws, 1 +xn--wq9h.ml, 0 +xn--xft85up3jca.ga, 1 +xn--xwqa8512b.eu.org, 1 +xn--xz1a.jp, 1 +xn--y-5ga.com, 1 +xn--y8j148r.xn--q9jyb4c, 0 +xn--y8j2eb5631a4qf5n0h.com, 1 +xn--y8ja6lb.xn--q9jyb4c, 1 +xn--y8jarb5hca.jp, 1 +xn--yj8h0m.ws, 1 +xn--ykrp42k.com, 1 +xn--yrvp1ac68c.xn--6qq986b3xl, 1 +xn--z1tq4ldt4b.com, 1 +xn--zettlmeil-n1a.de, 1 +xn--zr9h.cf, 1 +xn--zr9h.ga, 1 +xn--zr9h.ml, 1 +xn--zr9h.tk, 1 +xn--zsr042b.fun, 1 +xn5.de, 1 +xnaas.info, 1 +xnativi.pl, 1 +xnet-x.net, 1 +xnetwork.ml, 1 +xninja.xyz, 1 +xnix.tk, 1 +xno-sys.de, 1 +xnode.org, 0 +xnoe.moe, 1 +xnopyt.com, 1 +xntrik.wtf, 1 +xnu.kr, 1 +xo.tc, 1 +xoan.cf, 1 +xoatickets.com, 1 +xobotun.com, 1 +xoda.pw, 1 +xoffy.com, 0 +xogum.email, 1 +xoh.at, 1 +xolotto.com, 1 +xolphin.nl, 1 +xombitgames.com, 1 +xombitmusic.com, 1 +xomyak.tk, 1 +xone.cz, 0 +xonet.cz, 1 +xonobixa.tk, 1 +xor.cat, 1 +xormatic.com, 1 +xosh.fr, 1 +xotictrends.com, 1 +xotika.tv, 1 +xoxo.news, 1 +xp.nsupdate.info, 1 +xp2.de, 1 +xpbytes.com, 1 +xpd.se, 1 +xpenology-fr.net, 1 +xperiacode.com, 1 +xperidia.com, 1 +xperience.social, 1 +xpert-designs.com, 1 +xpertairctx.com, 1 +xpertairtx.com, 1 +xpertairwaco.com, 1 +xpertcenter.ch, 1 +xpertcube.com, 1 +xpertsunlimited.com, 1 +xpj090.com, 1 +xpj678678.com, 1 +xpj90.com, 1 +xpj909.cc, 1 +xpj909.com, 1 +xpj909.in, 1 +xpj909.me, 1 +xpj909.vip, 1 +xpj919.in, 1 +xpj919.me, 1 +xpj919.vip, 1 +xpjab.com, 1 +xpjce.com, 1 +xpjcu.com, 1 +xpjdi.com, 1 +xpjei.com, 1 +xpjfan.com, 1 +xpjiosapp.com, 1 +xpjmd.com, 1 +xpjtop.com, 1 +xpjwa.com, 1 +xpjwb.com, 1 +xpjwc.com, 1 +xpjwd.com, 1 +xpletus.nl, 1 +xplo.it, 1 +xplozion.tk, 1 +xpoc.pro, 1 +xpods.sg, 1 +xpornoizle.net, 1 +xportxpert.com, 1 +xposedornot.com, 1 +xposure.ae, 1 +xpressable.com, 1 +xpresswifi.network, 1 +xprometheus.com, 1 +xps-auto.com, 1 +xps3dp.com, 1 +xpsauto.com, 1 +xpsautomation.com, 1 +xpwn.cz, 0 +xq.com, 1 +xqin.net, 1 +xqk7.com, 1 +xr.cx, 1 +xr1s.me, 1 +xrak.tk, 1 +xrayreview.ml, 1 +xrbox.me, 1 +xrg.cz, 1 +xrippedhd.com, 1 +xrockx.de, 1 +xrp.pp.ua, 1 +xrpnews.info, 1 +xrpscan.com, 1 +xrwracing-france.com, 1 +xs00228.com, 1 +xs2a.no, 1 +xsapp.co, 1 +xscancun.com, 1 +xsden.info, 1 +xsec.me, 1 +xsenya74hram.tk, 1 +xserownia.cloud, 1 +xserownia.com.pl, 1 +xserownia.eu, 1 +xserownia.info, 1 +xserownia.net, 1 +xserownia.pl, 1 +xsole.net, 1 +xsolla.com, 1 +xss.name, 1 +xss.sk, 1 +xssi.uk, 1 +xsstime.nl, 1 +xsteam.eu, 1 +xstreamable.com, 1 +xsuper.net, 1 +xsz.jp, 1 +xtaboo3d.com, 1 +xtarget.ru, 1 +xtechkr.com, 1 +xtensio.com, 1 +xtips.us, 1 +xtom.africa, 1 +xtom.al, 1 +xtom.amsterdam, 1 +xtom.ax, 1 +xtom.be, 1 +xtom.bg, 1 +xtom.by, 1 +xtom.ch, 1 +xtom.co.uk, 1 +xtom.com, 1 +xtom.com.de, 1 +xtom.com.ee, 1 +xtom.com.hk, 1 +xtom.cy, 1 +xtom.cz, 1 +xtom.de, 1 +xtom.dk, 1 +xtom.ee, 1 +xtom.es, 1 +xtom.eu, 1 +xtom.fi, 1 +xtom.fo, 1 +xtom.fr, 1 +xtom.ge, 1 +xtom.gg, 1 +xtom.gmbh, 1 +xtom.gr, 1 +xtom.hr, 1 +xtom.hu, 1 +xtom.im, 1 +xtom.is, 1 +xtom.it, 1 +xtom.je, 1 +xtom.li, 1 +xtom.limited, 1 +xtom.london, 1 +xtom.lt, 1 +xtom.ltd, 1 +xtom.lu, 1 +xtom.lv, 1 +xtom.md, 1 +xtom.me, 1 +xtom.mk, 1 +xtom.moscow, 1 +xtom.nl, 1 +xtom.no, 1 +xtom.nu, 1 +xtom.paris, 1 +xtom.pl, 1 +xtom.pt, 1 +xtom.ro, 1 +xtom.ru, 1 +xtom.si, 1 +xtom.sk, 1 +xtom.su, 1 +xtom.support, 1 +xtom.uk, 1 +xtom.wiki, 1 +xtournois.com, 1 +xtrainsights.com, 1 +xtravans.com, 1 +xtreamfire.tk, 1 +xtreme-cs.tk, 1 +xtreme-servers.eu, 1 +xtremealaskainsulation.com, 1 +xtremebouncepartyhire.com.au, 1 +xtremecoatingtechnologies.com, 1 +xtremegaming.it, 1 +xtremotivation.com, 1 +xtremyblog.com, 1 +xtronics.com, 1 +xts.bike, 1 +xts3636.net, 1 +xtu2.com, 1 +xtzone.be, 1 +xuab.net, 1 +xuann.wang, 1 +xubo666.com, 1 +xuc.me, 1 +xucha.ml, 1 +xueanquan.com, 1 +xuedianshang.com, 1 +xuehao.net.cn, 1 +xuehao.tech, 1 +xuehuang666.cn, 1 +xuesoska.ga, 1 +xuexi.icu, 0 +xujan.com, 1 +xuming.studio, 1 +xumm.community, 1 +xumm.me, 1 +xun3708855.com, 1 +xunki.cc, 0 +xunmengdu.com, 1 +xunn.io, 1 +xuntaosms.com, 1 +xuntier.ch, 1 +xurl.gq, 1 +xuwei.de, 1 +xvaldezendocrino.com, 1 +xvii.pl, 1 +xviimusic.com, 1 +xvix.eu, 1 +xvmmod.com, 1 +xvpn.io, 1 +xvt-blog.tk, 1 +xwalck.se, 1 +xwaretech.info, 1 +xwf.fyi, 1 +xwfwrestling.tk, 1 +xwm.ru, 1 +xx.gl, 1 +xx0r.eu, 1 +xx6729.co, 1 +xx6729.com, 1 +xx6957.co, 1 +xx9297.co, 1 +xx9397.com, 1 +xx9721.com, 1 +xx9728.co, 1 +xxffo.com, 1 +xxgalgame.com, 1 +xxiz.com, 1 +xxl-bonus.tk, 1 +xxl.tax, 1 +xxoo.best, 1 +xxxbunker.com, 1 +xxxfreepornclip.com, 1 +xxxite.me, 1 +xxxoopz.com, 1 +xxxpornohub.net, 1 +xxxred.net, 1 +xxxsuper.net, 1 +xxxuno.com, 1 +xxxvids.mobi, 1 +xxxvids.tv, 1 +xxzacg.com, 0 +xy.ax, 1 +xy1919.com, 1 +xy366.cc, 1 +xy369.cc, 1 +xy6161.com, 1 +xy6262.com, 1 +xy6363.com, 1 +xy6729.com, 1 +xy6957.com, 1 +xy7171.com, 1 +xy7272.com, 1 +xy7373.com, 1 +xybabyshop.com, 1 +xyenon.bid, 1 +xyfun.net, 0 +xylerfox.ca, 1 +xyloefarmoges.gr, 1 +xyndrac.net, 0 +xynta.ch, 1 +xyquadrat.ch, 1 +xyrexwolf-sebastien-izambard.tk, 1 +xywap.org, 1 +xywing.com, 1 +xyz.blue, 1 +xyz.ng, 1 +xyzemails.com, 1 +xyzulu.hosting, 1 +xyzxyx.com, 1 +xyzyz.xyz, 1 +xyzzy.earth, 1 +xyzzyyyz.com, 1 +xz0.de, 1 +xzclip.cn, 1 +xzibits.com, 1 +xzqy.net, 1 +xztech.co, 1 +y-nas.tk, 1 +y-syouten.com, 1 +y.gy, 1 +y09a.com, 0 +y09app.com, 0 +y09app.vip, 0 +y09j.com, 0 +y0bet.com, 1 +y11n.net, 1 +y2bet.com, 1 +y30365.com, 1 +y3451.com, 1 +y3650.com, 1 +y36500.com, 1 +y3651.com, 1 +y36511.com, 1 +y365188.com, 1 +y3653.com, 1 +y36533.com, 1 +y3654.com, 1 +y3656.com, 1 +y36577.com, 1 +y3bet.com, 1 +y4bet.com, 1 +y5197.co, 1 +y5bet.com, 1 +y6180.com, 1 +y6729.co, 1 +y6729.com, 1 +y68aa.com, 1 +y68cc.com, 1 +y68dd.com, 1 +y68ee.com, 1 +y68ff.com, 1 +y68gg.com, 1 +y68gl.com, 1 +y68hh.com, 1 +y68ii.com, 1 +y68jj.com, 1 +y68jn.com, 1 +y68ll.com, 1 +y68oo.com, 1 +y68pp.com, 1 +y68qq.com, 1 +y68rr.com, 1 +y68sc.com, 1 +y68sz.com, 1 +y68tt.com, 1 +y68uu.com, 1 +y68yy.com, 1 +y68zz.com, 1 +y6957.co, 1 +y6bet.com, 1 +y70101.com, 1 +y70102.com, 1 +y70103.com, 1 +y70104.com, 1 +y70105.com, 1 +y70301.com, 1 +y70302.com, 1 +y70303.com, 1 +y7091.com, 1 +y7092.com, 1 +y7093.com, 1 +y7bet.com, 1 +y81365.com, 1 +y82365.com, 1 +y890000.com, 0 +y891111.com, 0 +y892222.com, 0 +y893333.com, 0 +y894444.com, 0 +y895555.com, 0 +y896666.com, 0 +y897777.com, 0 +y898888.com, 0 +y89a.com, 0 +y89a.net, 1 +y89aaa.com, 0 +y89b.com, 0 +y89b.net, 1 +y89bbb.com, 0 +y89c.com, 1 +y89c.net, 1 +y89ccc.com, 0 +y89d.com, 0 +y89d.net, 0 +y89dd.com, 1 +y89ddd.com, 1 +y89e.com, 0 +y89e.net, 0 +y89ee.com, 1 +y89eee.com, 1 +y89f.com, 0 +y89f.net, 0 +y89fff.com, 0 +y89g.com, 0 +y89g.net, 1 +y89gg.com, 1 +y89h.net, 1 +y89hh.com, 1 +y89hhh.com, 0 +y89i.com, 0 +y89i.net, 1 +y89ii.com, 1 +y89iii.com, 1 +y89j.com, 1 +y89j.net, 1 +y89jj.com, 1 +y89jjj.com, 0 +y89k.com, 0 +y89kk.com, 1 +y89l.com, 0 +y89ll.com, 1 +y89m.com, 1 +y89n.com, 1 +y89o.com, 1 +y89p.com, 0 +y89q.com, 0 +y89r.com, 0 +y89s.com, 0 +y89t.com, 0 +y89u.com, 0 +y89v.com, 1 +y89ww.com, 0 +y89z.com, 0 +y89zz.com, 0 +y9297.co, 1 +y9297.com, 1 +y9728.co, 1 +ya-hudeu.tk, 1 +ya-hudeyu.gq, 1 +ya-hudeyu.ml, 1 +ya-hudeyu.tk, 1 +ya-madina.tk, 1 +ya-radio.tk, 1 +ya-stroynaya.tk, 1 +ya-zdorova.tk, 1 +ya.mk, 1 +yaay.com.br, 1 +yaay.today, 1 +yabuisha.jp, 1 +yacca.co.uk, 1 +yacca.uk, 1 +yachigoya.com, 1 +yachta.kiev.ua, 1 +yachtbuyer.com, 1 +yachtcharterfleet.com, 1 +yachtcita.com, 1 +yachtfolio.com, 1 +yachtfolio1.com, 1 +yachting-home.com, 1 +yachtlettering.com, 1 +yachtmarket.com.ua, 1 +yacobo.com, 1 +yacostasolutions.com, 1 +yadakjo.ir, 1 +yadameshop.ir, 1 +yaencasa.net, 1 +yafull.com, 1 +yafuoku.ru, 1 +yageys.com, 1 +yagihiro.tech, 1 +yagizhan.me, 1 +yagliyurt.com, 1 +yagmursoft.tk, 1 +yagoda-malina.tk, 1 +yagotour.cf, 1 +yah-music.com, 1 +yahan.tv, 1 +yaharu.ru, 1 +yahav.co.il, 1 +yahlab.de, 1 +yahoo.ax, 1 +yahvehyireh.com, 1 +yahzah.com, 1 +yak-host.tk, 1 +yak-soap.co, 1 +yak.is, 1 +yakitofisi.com, 1 +yakkifamirie.tk, 1 +yakmade.com, 1 +yakmail.tech, 1 +yakmoo.se, 1 +yakovmanshin.com, 1 +yakutia.tk, 1 +yakutianews.tk, 1 +yakutsk-city.tk, 1 +yakutsk.ml, 1 +yalacoins.com, 1 +yalb.tech, 1 +yalcinkaya.ninja, 0 +yalecleaners.com, 1 +yallamotor.com, 1 +yamadaya.tv, 1 +yamal-online.ml, 1 +yamal159263.ml, 1 +yamanami.tokyo, 1 +yamashita-clinic.org, 1 +yame2.com, 1 +yamei1.com, 1 +yamei1188.com, 1 +yamei2233.com, 1 +yamei6688.com, 1 +yamei6699.com, 1 +yamei8.com, 1 +yamei88.com, 1 +yamei8866.com, 1 +yamei98.com, 1 +yamei99.com, 1 +yamei9911.com, 1 +yamei9955.com, 1 +yami.world, 1 +yamilafeinart.de, 1 +yamm.io, 1 +yamobila.tk, 1 +yan.lt, 1 +yana-co.ir, 1 +yanaduday.com, 1 +yananikitina.site, 1 +yanbao.xyz, 1 +yande.re, 1 +yandong.tk, 1 +yangfamily.tw, 1 +yangjingwen.cn, 1 +yangjingwen.com, 1 +yangmao.info, 1 +yangmaodang.org, 0 +yangmi.blog, 1 +yangruixin.com, 1 +yanhongming.net, 1 +yanik.info, 1 +yanlongli.com, 1 +yann.tw, 1 +yanngraf.ch, 0 +yannic.world, 0 +yannick.cloud, 1 +yannickb.de, 1 +yannickkordel.de, 1 +yannickvdvelde.tk, 1 +yanniclandsmann.de, 1 +yannikbloscheck.com, 1 +yannyann.com, 1 +yanovich.net, 1 +yanovosibirsk.ml, 1 +yanqiyu.info, 1 +yans.io, 1 +yanservices.be, 1 +yansurachman.web.id, 1 +yantox.com, 1 +yanwo.com.tw, 1 +yao28.com, 1 +yaodownload.com, 1 +yaoge123.com, 1 +yap26.cc, 1 +yapan008.com, 1 +yapan1.com, 1 +yapan10.com, 1 +yapan11.com, 1 +yapan2.com, 1 +yapan22.com, 1 +yapan222.com, 1 +yapan3.com, 1 +yapan33.com, 1 +yapan333.com, 1 +yapan365.net, 1 +yapan4.com, 1 +yapan44.com, 1 +yapan444.com, 1 +yapan5.com, 1 +yapan55.com, 1 +yapan555.com, 1 +yapan6.com, 1 +yapan66.com, 1 +yapan666.com, 1 +yapan7.com, 1 +yapan77.com, 1 +yapan777.com, 1 +yapan8.com, 1 +yapan888.com, 1 +yapan9.com, 1 +yapan99.com, 1 +yapan999.com, 1 +yapanwang.com, 1 +yapbreak.fr, 1 +yapeal.ch, 1 +yappy.com, 1 +yarahmad.ir, 1 +yarapilates.com.br, 1 +yarcevostom.ru, 1 +yarcom.ru, 0 +yardandgardenguru.com, 1 +yardesign.tk, 1 +yardley.digital, 1 +yardthyme.com, 1 +yarlesac.com, 1 +yarnandy.com, 1 +yarnsub.com, 1 +yarogneva.ru, 1 +yaroslavova.tk, 1 +yarowork.jp, 1 +yarplast.tk, 1 +yarravilletownhouses.com.au, 1 +yaru.one, 1 +yarygin.tk, 1 +yasam.co.uk, 1 +yaseiblog.org, 1 +yaseminuzumcu.com, 1 +yash.com, 1 +yashinstore.com, 1 +yasic.net, 1 +yasmingarcia.tk, 1 +yasraiting.tk, 1 +yasrating.tk, 1 +yassine-ayari.com, 1 +yassinesmael.tk, 1 +yasudaseiki.cn, 1 +yasukevicious.com, 1 +yatai18.com, 1 +yatesun.com, 1 +yatorie.net, 1 +yatsat.com, 1 +yatstudios.com, 1 +yatsuenpoon.com, 1 +yauatcha.com, 1 +yaucy.win, 1 +yaup.tk, 1 +yavapaiaz.gov, 1 +yavin4.cf, 1 +yavip8088.com, 1 +yavorivanov.com, 1 +yavuzatasoy.tk, 1 +yawen.me, 1 +yawnbox.com, 1 +yaws.cf, 1 +yaxim.org, 1 +yay-btcl.work, 1 +yay.cam, 1 +yayart.club, 1 +yayl888.com, 1 +yayou.ag, 1 +yazichestvo.tk, 1 +ybdh88.com, 1 +ybin.me, 1 +yblaccounting.com, 1 +ybos.nl, 1 +ybrcelikyapi.com, 1 +ybresson.com, 1 +ybscareers.co.uk, 1 +ybsul.com, 1 +ybti.net, 1 +ybzhao.com, 1 +yc1820.com, 1 +ycb.fr, 1 +ycbmdevelopment.com, 1 +ycbmstaging.com, 1 +ych.art, 1 +ycherbonnel.fr, 1 +ychon.com, 1 +yclan.net, 1 +ycnrg.org, 1 +yd163.cc, 1 +yd169.cc, 1 +ydiversa.com, 1 +ydraulikos.top, 1 +yduc.net, 1 +ydyy99.com, 1 +yeah-shop.com.ua, 1 +yeapdata.com, 1 +yearend.com, 1 +yearli.com, 1 +yeartracker.ga, 1 +yecl.net, 1 +yeesker.com, 1 +yekaterinburg-city.tk, 1 +yekpayamak.com, 1 +yellowcar.website, 1 +yellowfish.top, 1 +yellowhawk.nl, 1 +yellowpages.ee, 1 +yellowsource.org, 1 +yellowsquid.co.uk, 1 +yellowsquid.uk, 1 +yellowstone.nsupdate.info, 1 +yellowstonecountymt.gov, 1 +yellowtaillasvegas.com, 1 +yellowtails.co.jp, 1 +yellowtrace.net.au, 1 +yellowtree.co.za, 1 +yelp.at, 1 +yelp.be, 1 +yelp.ca, 1 +yelp.ch, 1 +yelp.cl, 1 +yelp.co.jp, 1 +yelp.co.nz, 1 +yelp.co.uk, 1 +yelp.com, 1 +yelp.com.ar, 1 +yelp.com.au, 1 +yelp.com.br, 1 +yelp.com.hk, 1 +yelp.com.mx, 1 +yelp.com.ph, 1 +yelp.com.sg, 1 +yelp.com.tr, 1 +yelp.com.tw, 1 +yelp.cz, 1 +yelp.de, 1 +yelp.dk, 1 +yelp.es, 1 +yelp.fi, 1 +yelp.fr, 1 +yelp.ie, 1 +yelp.it, 1 +yelp.my, 1 +yelp.nl, 1 +yelp.no, 1 +yelp.pl, 1 +yelp.pt, 1 +yelp.se, 1 +yeltsin.tech, 1 +yemalu.com, 1 +yemekbaz.az, 1 +yemektarifinet.com, 1 +yemektarifleri.com, 1 +yemenat.tk, 1 +yemenlink.tk, 1 +yenbainet.tk, 1 +yenibilgi.net, 1 +yeniexpo.com, 1 +yennhi.co, 1 +yenpape.com, 1 +yep-pro.ch, 0 +yepbitcoin.com, 1 +yeptechnology.store, 1 +yeram.org, 1 +yerbasbuenas.tk, 1 +yert.pink, 1 +yes-money.cf, 1 +yes-money.ga, 1 +yes-money.gq, 1 +yes.com, 1 +yesapp.tk, 1 +yescareer.ga, 1 +yescool.cn, 1 +yesfone.com.br, 1 +yesh.lk, 1 +yesiammaisey.me, 1 +yesildiyetisyen.com, 1 +yesilliforum.tk, 1 +yesjobs.ga, 1 +yesmirov.ga, 1 +yesod.in, 1 +yesogovinpetcare.com, 1 +yestees.com, 1 +yesterford.com, 1 +yesterplay.net, 1 +yesteryear-chronicle.cf, 1 +yeswecan.co.bw, 1 +yeswehack.com, 1 +yetahost.com, 1 +yeti.gq, 1 +yetii.net, 1 +yetishirt.com, 0 +yetivisite.ch, 1 +yetzt.me, 0 +yeu.io, 1 +yewtu.be, 1 +yex.nz, 1 +yex.trade, 1 +yeyi.site, 1 +yezi.ga, 1 +yezishurb.site, 1 +yf128.cc, 1 +yfengs.moe, 1 +yfooz.com, 1 +yg-crew.eu, 1 +ygets.com, 1 +yggdar.ga, 1 +ygm.org.uk, 1 +ygobbs.com, 1 +ygrene.com, 1 +yh12366.com, 1 +yh56787.com, 1 +yh599.cc, 1 +yh64678.com, 1 +yh66689.com, 1 +yh811.com, 1 +yh88890.com, 1 +yh98768.com, 1 +yhaupenthal.org, 1 +yhb.io, 1 +yhe.me, 1 +yhenke.de, 0 +yhfou.com, 1 +yhn.sh, 1 +yhndnzj.com, 1 +yhong.me, 1 +yhori.xyz, 1 +yhrd.org, 1 +yhs.kr, 1 +yhsh.xyz, 1 +yhwj.top, 0 +yibaoweilong.top, 1 +yibei-original.com, 1 +yicipick.com, 1 +yicivideo.com, 1 +yicknam.my, 1 +yiff.forsale, 1 +yiff.media, 1 +yiff.rocks, 1 +yify.online, 1 +yigelangzi.com, 1 +yigit.shop, 1 +yigujin.cn, 1 +yiheng.moe, 1 +yihome.com.tw, 1 +yihome.tw, 1 +yihouse.tw, 1 +yijia.support, 1 +yikeyong.com, 1 +yilconstruction.ca, 1 +yimgo.fr, 0 +yin8888.tv, 0 +yinfor.com, 1 +ying.gift, 1 +ying299.com, 1 +ying299.net, 1 +yingatech.com, 1 +yinglinda.love, 1 +yingmei.jp, 1 +yingshu.hopto.org, 1 +yingyj.com, 1 +yinlei.org, 1 +yinyang.jp, 1 +yips.org.za, 1 +yiyuanzhong.com, 1 +yiz96.com, 1 +yizhihuang.org, 1 +yj4p.com, 1 +yjav.tv, 1 +yjav8.com, 1 +yjav9.com, 1 +yjdevtech.com, 1 +yjsoft.me, 1 +yjsp.tv, 1 +yjst.cn, 1 +yjsw.sh.cn, 1 +ykdlb.cn, 0 +ykgli.cn, 1 +ykhut.com, 1 +ykn.fr, 1 +ykqpw.com, 1 +yksityisyydensuoja.fi, 1 +yl366.cc, 1 +yl369.cc, 1 +yl8.com, 1 +ylde.de, 1 +ylinternal.com, 1 +ylk.de, 1 +ylk.io, 1 +ym069.com, 1 +ym1199.com, 1 +ym14.com, 1 +ym181.am, 1 +ym181.com, 1 +ym6699.com, 1 +ym966.com, 1 +ym966.net, 1 +ymarion.de, 1 +ymashop.com, 1 +ymatyt.com, 1 +ymeadows.com, 1 +ymm18.com, 1 +ymm234.com, 1 +ymoah.nl, 1 +ymtsonline.org, 1 +ymy.zone, 1 +yn.org.nz, 1 +ynode.com, 1 +yoa.st, 1 +yoast.com, 1 +yoba.co.uk, 1 +yoba.systems, 1 +yobai-grouprec.jp, 1 +yobasystems.co.uk, 1 +yobda.tk, 1 +yobniyulyu.tk, 1 +yobst.tk, 1 +yocoboard.com, 1 +yocto.xyz, 1 +yodababy.com.tw, 1 +yoduzw.com, 1 +yoga-alliance-teacher-training.com, 1 +yoga-bad-toelz.de, 1 +yoga-bien-etre.com, 1 +yoga-good.fr, 1 +yoga-in-aying.de, 1 +yoga-prive.de, 1 +yoga-school.xyz, 1 +yoga-zentrum-narayani.de, 1 +yoga.is-an-engineer.com, 1 +yogaangels.ga, 1 +yogacentric.co.uk, 1 +yogaecology.org, 1 +yogaemmental.ch, 1 +yogagadgets.ga, 1 +yogahealsinc.org, 1 +yogahome.com, 1 +yogamarlene.ch, 1 +yogamaya9.com, 1 +yogamea.school, 1 +yogananda-roma.org, 1 +yogaprague.com, 1 +yogaschoolrishikesh.com, 1 +yogaschule-herzraum.de, 1 +yogasolution.tk, 1 +yogatherapykosha.com, 1 +yogaworld.tk, 1 +yogies.shop, 1 +yogstation.net, 1 +yogularm.de, 1 +yogunet.de, 1 +yohanesmario.com, 1 +yoitoko.city, 1 +yoitsu.moe, 1 +yokoda.okinawa, 1 +yokohama-legaloffice.jp, 1 +yokone3-kutikomi.com, 1 +yolandgao.me, 1 +yolo-csgo.com, 1 +yolo.jetzt, 1 +yolo.vn, 1 +yolobert.de, 1 +yoloboatrentals.com, 1 +yolocamgirls.com, 1 +yolocast.wtf, 1 +yolops.net, 1 +yolosh.se, 1 +yoloyolo.top, 0 +yombo.net, 1 +yomena.in, 1 +yomiren.co.jp, 1 +yon.co.il, 1 +yoneda-paint.com, 1 +yonema.com, 1 +yongbin.org, 1 +yonkersdentalspa.com, 1 +yoogirls.com, 1 +yoonas.com, 1 +yooomu.com, 1 +yooooex.com, 1 +yooptopian.com, 1 +yooread.net, 1 +yoozapi.com, 1 +yoppoy.com, 1 +yoramvandevelde.net, 1 +yorcom.nl, 0 +yorcool.nl, 1 +yordanisp.tk, 1 +yorkieloverdiy.com, 1 +yorkiepooexpert.com, 1 +yorkshiredalesinflatables.co.uk, 1 +yorkshiregardensheds.co.uk, 1 +yorkshireinflatables.co.uk, 1 +yorkshireterrier.com.br, 1 +yorkshireterrier.dog, 1 +yorkshireterrieraspets.com, 1 +yorname.ml, 0 +yornik.nl, 1 +yosakoinight.com, 1 +yosbeda.com, 1 +yosemo.de, 1 +yosheenetwork.fr, 1 +yoshibaworks.com, 1 +yoshitsugu.net, 1 +yoshkar-ola-city.tk, 1 +yosida-dental.com, 1 +yosida95.com, 1 +yospos.org, 1 +yoticonnections.com, 1 +yotilabs.com, 1 +yotta-zetta.com, 1 +yotubaiotona.net, 1 +you.com.br, 1 +you15iv.com, 1 +you2you.fr, 1 +you52iv.com, 1 +youareme.ca, 0 +youarethelight.pl, 1 +youbehero.com, 1 +youber.cz, 1 +youc.ir, 1 +youcanfinance.com.au, 1 +youcanfuckoff.xyz, 1 +youcanhelp.tk, 1 +youcanmakeit.at, 1 +youdamom.com, 1 +youdungoofd.com, 1 +youenglish.school, 1 +youftp.tk, 1 +yougee.ml, 1 +yougene.me, 1 +yougot.pw, 1 +youhabitat.es, 1 +youhacked.me, 1 +youhavewords.com, 1 +youhs.top, 0 +youhua.ru, 1 +youiv.co, 1 +youiv.info, 1 +youiv.pw, 1 +youiv.tv, 1 +youiv1.com, 1 +youiv2.com, 1 +youivc.com, 1 +youivh.com, 1 +youivk.com, 1 +youivr.com, 1 +youivx.com, 1 +youivz.com, 1 +youjizz.bz, 1 +youkaryote.com, 1 +youkaryote.org, 1 +youked.com, 1 +youla.cf, 1 +youla.gq, 1 +youlikehookups.com, 1 +youliketwinks.com, 1 +youlovehers.com, 1 +youmiracle.com, 1 +youmonit.me, 1 +youms.de, 1 +younameit.ru, 1 +youneedfame.com, 1 +young-brahmousin.com, 0 +young-celebrities.tk, 1 +young-sheldon.com, 1 +young-zy.com, 1 +youngart.hu, 1 +youngdevotion.net, 1 +youngguns.club, 1 +younglions.cf, 1 +youngmodelsagency.tk, 1 +youngpeopleunited.co.uk, 1 +youngsigncompany.com, 1 +youngsook.com, 1 +youngsook.org, 1 +youngsoulstudios.com, 1 +youngvoicesmatter.org, 1 +younl.net, 1 +youpark.no, 1 +youpickfarms.org, 1 +your-dns.run, 1 +your-erotic-stories.com, 1 +your-fitness-coach.ch, 1 +your-forum.tk, 1 +your-greece.ga, 1 +your-idc.tk, 1 +your-melody.ru, 1 +your-out.com, 1 +your.best, 1 +your28days.com, 1 +youracnepro.com, 1 +youran.me, 1 +yourantiquarian.com, 1 +yourazbraces.com, 1 +yourbetterkitchen.com, 1 +yourbind.com, 1 +yourbittorrent.com, 1 +yourbittorrent.icu, 1 +yourbittorrent.pw, 1 +yourbittorrent2.com, 1 +yourblazeguard.com, 1 +yourbodyknows.dk, 1 +yourbodyknows.is, 1 +yourbonus.click, 0 +yourbookmark.tech, 1 +yourbreakfast.tk, 1 +yourbusinesscommunity.co.uk, 1 +yourcareerhost.com, 1 +yourcfo.co.in, 1 +yourciso.com, 1 +yourcleaningcompany.net, 1 +yourconscious.life, 1 +yourcopywriter.it, 1 +yourcrypto.tax, 1 +yourdailyalerts.net, 1 +yourdemowebsite.ml, 1 +yourdomain.host, 1 +yourdrive.tk, 1 +youreallyneedthis.co, 1 +youregeeks.com, 1 +youreitbranding.com, 1 +youreward.ga, 1 +yourforex.org, 1 +yourfriendlytech.com, 1 +yourfuntrivia.com, 1 +yourfuturestrategy.com.au, 1 +yourgadget.ro, 1 +yourgames.tv, 1 +yourgift.in, 1 +yourhair.net, 1 +yourhealthcommunity.com, 1 +yourhumandesign.ch, 1 +yourivanopdorp.nl, 1 +yourkit.com, 1 +yourkrabivilla.com, 1 +yourlanguages.de, 1 +yourloan.gq, 1 +yourlovesong.com.mx, 1 +yourlscgroup.com, 1 +yourmagicstory.tk, 1 +yourmobility.ga, 1 +yourms.com, 1 +yourname.xyz, 1 +yournextagency.com, 1 +yourown.xyz, 1 +yourpalmbeachcountyrealtor.com, 1 +yourpalstore.com, 1 +yourpersonalfrance.com, 1 +yourrenaissancemedspa.com, 1 +yourscotlandtour.co.uk, 1 +yourskin.nl, 1 +yoursoul.gq, 1 +yoursoulmate.tk, 1 +yourstage.nl, 1 +yourstake.org, 1 +yourtests.tk, 1 +yourticketbooking.com, 1 +yourtime.tv, 1 +yourtwojugs.com, 1 +youruseragent.info, 1 +yourvoice.nl, 1 +yourwatchdesign.co.uk, 1 +yourworlds.cf, 1 +yourznc.com, 1 +yousee.cf, 1 +yousei.ne.jp, 1 +youservice.it, 1 +youshouldbealiberal.com, 1 +yousite.by, 1 +youstyleski.it, 1 +yousuforg.ga, 1 +youth-for-life.tk, 1 +youth.gov, 1 +youth2009.org, 1 +youthclothing.tk, 1 +youthingovernment.com, 1 +youthink.jp, 1 +youthnews.tk, 1 +youthopportunitieshub.com, 1 +youthrules.gov, 1 +youtous.me, 1 +youtube, 1 +youtube.com, 1 +youtubedownloader.com, 1 +youtubekids.com, 1 +youtubelet.com, 1 +youtuberis.lt, 1 +youtuberus.tk, 1 +youwatchporn.com, 1 +youyifans.com, 1 +youyoulemon.com, 1 +youyuan.rocks, 1 +youyuandesign.top, 1 +yovko.net, 0 +yoxall.me.uk, 1 +yoyoost.duckdns.org, 1 +yoyoost.ga, 1 +yoys.ae, 1 +yozakura.me, 1 +ypart.eu, 1 +ypea.info, 1 +ypfr.fr, 1 +ypgnews.tk, 1 +ypid.de, 1 +yplanapp.com, 1 +ypopovych.tk, 1 +yporti.net, 1 +ypse.com.br, 1 +yq5.de, 1 +yqjf68.com, 1 +yr.sa, 1 +yr166166.com, 1 +yr8.com, 1 +yrcc878.com, 1 +yrjanheikki.com, 1 +yrx.me, 1 +yryz.net, 1 +ys633.cc, 1 +ysds.com, 0 +ysearc.tk, 1 +ysicing.me, 1 +ysicorp.com, 1 +yslocksandkeys.com, 1 +ysoft.cloud, 1 +yspa.tv, 1 +yspertal.party, 1 +ystream.tv, 1 +ysun.xyz, 1 +ysuna.xyz, 1 +yt129.com, 1 +yt220.com, 1 +yt605.com, 1 +yt606.com, 1 +yt629.com, 1 +yt675.com, 1 +yt818.com, 1 +yt881.com, 1 +yt962.com, 1 +yt972.com, 1 +ytcount.com, 1 +ytec.ca, 1 +ytegiadinhmilo.com, 1 +ytexa.tk, 1 +ytpak.pk, 1 +ytreza.fr, 1 +ytsdownload.com, 1 +ytuquelees.net, 1 +ytvideosaver.com, 1 +ytvwld.de, 0 +ytx588.com, 1 +yu-dkc.com, 1 +yu-mug.jp, 1 +yu.vc, 1 +yuan.ga, 0 +yuan.nctu.me, 1 +yuanandyuan.info, 1 +yuanandyuan.me, 1 +yuanben.io, 1 +yuanbenlian.com, 1 +yuandan.cf, 1 +yuanjiazhao.com, 1 +yuanjiazhao.tk, 1 +yuansecard.me, 1 +yubanmei.com, 1 +yubi.co, 0 +yubicloud.io, 1 +yubico.ae, 1 +yubico.at, 1 +yubico.be, 1 +yubico.biz, 1 +yubico.cloud, 1 +yubico.co.in, 1 +yubico.co.kr, 1 +yubico.co.uk, 1 +yubico.com, 1 +yubico.com.ar, 1 +yubico.cz, 1 +yubico.dk, 1 +yubico.es, 1 +yubico.fi, 1 +yubico.in, 1 +yubico.info, 1 +yubico.io, 1 +yubico.mobi, 1 +yubico.mx, 1 +yubico.net, 1 +yubico.online, 1 +yubico.org, 1 +yubico.pe, 1 +yubico.se, 1 +yubico.sg, 1 +yubico.tv, 1 +yubico.uk, 1 +yubico.us, 1 +yubicodemo.com, 1 +yubikey.ae, 1 +yubikey.asia, 1 +yubikey.at, 1 +yubikey.cl, 1 +yubikey.co, 1 +yubikey.co.uk, 1 +yubikey.com, 1 +yubikey.com.ar, 1 +yubikey.com.au, 1 +yubikey.dk, 1 +yubikey.fi, 1 +yubikey.io, 1 +yubikey.mx, 1 +yubikey.org, 1 +yubikey.pe, 1 +yubikey.se, 1 +yubikey.sg, 1 +yubikey.uk, 1 +yubikey.us, 1 +yubikeys.net, 1 +yubikeys.org, 1 +yubikeyservices.eu, 1 +yubiking.com, 1 +yucca.cf, 1 +yuccaschidigera.co.uk, 1 +yuce518.com, 1 +yude.ml, 1 +yue.la, 1 +yue2.net, 1 +yuema.net.cn, 1 +yuer.sytes.net, 1 +yuexiangzs.com, 1 +yugami-lab.com, 1 +yugasun.com, 1 +yugege.cf, 1 +yugodi.com, 1 +yugohome.com, 1 +yuharahisako.cf, 1 +yuharahisako.ga, 1 +yuhindo.com, 1 +yuho.vn, 1 +yuimarukitchen.com, 1 +yuina.cn, 1 +yuisyo.ml, 1 +yuji.ne.jp, 1 +yujixr.net, 1 +yuka.one, 1 +yukari.cafe, 1 +yuki-nagato.com, 1 +yuki.xyz, 1 +yukiblog.tw, 1 +yukict.com, 1 +yukieda.com, 1 +yukimiu.cf, 1 +yukimochi.com, 1 +yukimochi.io, 1 +yukimochi.jp, 1 +yukimochi.me, 1 +yukimochi.net, 1 +yukina.blog, 0 +yukina.kr, 0 +yukinarita.com, 1 +yukonconnector.com, 1 +yukonlip.com, 1 +yukoslibrary.ga, 1 +yuksinau.co.id, 1 +yula.cf, 1 +yulaiz.com, 1 +yule.hk, 1 +yuleyule88game.com, 1 +yulsn.com, 1 +yum0.cn, 1 +yumechi.jp, 1 +yumeconcert.com, 1 +yumepolo.com, 1 +yumiandryan.com, 1 +yumli.net, 1 +yumm.menu, 1 +yummydrool.com, 1 +yun-bao.co, 1 +yuna.love, 1 +yuna.tg, 0 +yuncaioo.com, 1 +yunhu365.com, 1 +yunity.org, 1 +yunjishou.pro, 1 +yunloc.com, 1 +yunnet.ru, 1 +yuntong.tw, 0 +yunzhu.li, 0 +yuqi.me, 1 +yura.cf, 1 +yuricarlenzoli.it, 1 +yurikirin.me, 1 +yurimoens.be, 1 +yurinet.org, 1 +yurisora.com, 1 +yurist-vopros.gq, 1 +yurisviridov.com, 1 +yusa.me, 1 +yushanfang.recipes, 1 +yusu.org, 1 +yusukesakai.com, 1 +yutakato.net, 1 +yutangyun.com, 1 +yutaron.tokyo, 0 +yuth.in, 0 +yuucchi.com, 1 +yuuki0xff.jp, 1 +yuuta.moe, 1 +yuuwa-service.com, 1 +yuvaindia.co.in, 1 +yuweetek.com, 0 +yuwei.org, 1 +yuweiyang.xyz, 1 +yux.fr, 1 +yuxiangyuan.com, 1 +yuxuan.org, 1 +yuy.info, 1 +yuyantang.club, 1 +yuyiyang.eu.org, 1 +yuyo.com, 1 +yuzei.ml, 1 +yuzei.tk, 1 +yuzu.tk, 1 +yuzulia.com, 1 +yuzurisa.com, 1 +yvb.moe, 1 +yvcr.com, 0 +yveslegendre.fr, 0 +yvesx.com, 1 +yvonne-stingel.de, 1 +yvonnethomet.ch, 1 +yvonnewilhelmi.com, 1 +yw.com, 1 +ywyz.tech, 0 +yxbet43.com, 1 +yxt521.com, 1 +yxzero.xyz, 1 +yy-s.net, 1 +yy153.com, 1 +yy366.cc, 1 +yy369.cc, 1 +yy393.com, 1 +yy5197.co, 1 +yy6729.co, 1 +yy6729.com, 1 +yy6957.co, 1 +yy9297.co, 1 +yy9297.com, 1 +yy9721.com, 1 +yy9728.co, 1 +yya.men, 1 +yyc.city, 1 +yycbike.info, 1 +yyr.im, 1 +yyrss.com, 0 +yyy116.com, 1 +yyy608.com, 1 +yz86.cc, 1 +yzal.io, 0 +yzarul.com, 1 +yzddd.com, 1 +yzer.club, 1 +yzervast-heestert.be, 1 +yzh8.cc, 1 +yzh8.net, 1 +yzh8.vip, 1 +yzimroni.net, 1 +yzy6666.com, 1 +yzydo.com, 1 +yzzy.cc, 0 +z-cert.nl, 1 +z-coder.com, 1 +z-konzept-nutrition.ru, 1 +z-pc.net, 1 +z-rejstejna.cz, 1 +z-vector.com, 1 +z.ai, 1 +z.cash, 1 +z.is, 1 +z.tl, 1 +z00228.com, 1 +z0rro.net, 1 +z1h.de, 1 +z2a4.com, 1 +z30365.com, 0 +z36533.com, 1 +z3s.nl, 1 +z3u5.net, 1 +z3ven.nl, 1 +z4-forum.com, 1 +z4k.de, 1 +z5197.co, 1 +z6.com, 1 +z6121.com, 1 +z6151.com, 1 +z6181.com, 1 +z6182.com, 1 +z6192.com, 1 +z6218.com, 1 +z6252.com, 1 +z6278.com, 1 +z6281.com, 1 +z6285.com, 1 +z6289.com, 1 +z6323.com, 1 +z6325.com, 1 +z6353.com, 1 +z6359.com, 1 +z6371.com, 1 +z6373.com, 1 +z6375.com, 1 +z6381.com, 1 +z6382.com, 1 +z6385.com, 1 +z6398.com, 1 +z6512.com, 1 +z6519.com, 1 +z6523.com, 1 +z6527.com, 1 +z6529.com, 1 +z6539.com, 1 +z6571.com, 1 +z6573.com, 1 +z6579.com, 1 +z6581.com, 1 +z6587.com, 1 +z6591.com, 1 +z6592.com, 1 +z6616.com, 1 +z6729.co, 1 +z6729.com, 1 +z6751.com, 1 +z6753.com, 1 +z6757.com, 1 +z6758.com, 1 +z6759.com, 1 +z6791.com, 1 +z6812.com, 1 +z6823.com, 1 +z6827.com, 1 +z6837.com, 1 +z6852.com, 1 +z6882.com, 1 +z6883.com, 1 +z6893.com, 1 +z6897.com, 1 +z6925.com, 1 +z6957.co, 1 +z6957.com, 1 +z6wang.com, 1 +z8010.com, 1 +z8011.com, 1 +z8012.com, 1 +z8013.com, 1 +z8015.com, 1 +z8017.com, 1 +z8019.com, 1 +z8020.com, 1 +z8021.com, 1 +z8023.com, 1 +z8025.com, 1 +z8026.com, 1 +z8027.com, 1 +z8028.com, 1 +z8029.com, 1 +z8031.com, 1 +z8032.com, 1 +z8036.com, 1 +z8038.com, 1 +z8039.com, 1 +z8051.com, 1 +z8052.com, 1 +z8053.com, 1 +z8057.com, 1 +z8059.com, 1 +z8060.com, 1 +z8061.com, 1 +z8062.com, 1 +z8063.com, 1 +z8066.com, 1 +z8068.com, 1 +z8070.com, 1 +z8071.com, 1 +z8073.com, 1 +z8075.com, 1 +z8077.com, 1 +z8078.com, 1 +z8079.com, 1 +z8081.com, 1 +z8082.com, 1 +z8083.com, 1 +z8085.com, 1 +z8086.com, 1 +z8087.com, 1 +z8089.com, 1 +z8092.com, 1 +z8095.com, 1 +z8096.com, 1 +z8097.com, 1 +z8099.com, 1 +z8102.com, 1 +z8106.com, 1 +z8109.com, 1 +z8113.com, 1 +z8116.com, 1 +z8120.com, 1 +z8121.com, 1 +z8125.com, 1 +z8127.com, 1 +z8129.com, 1 +z8130.com, 1 +z8132.com, 1 +z8133.com, 1 +z81365.com, 1 +z8137.com, 1 +z8139.com, 1 +z8150.com, 1 +z8151.com, 1 +z8162.com, 1 +z8165.com, 1 +z8168.com, 1 +z8170.com, 1 +z8171.com, 1 +z8172.com, 1 +z8173.com, 1 +z8176.com, 1 +z8177.com, 1 +z8178.com, 1 +z8179.com, 1 +z8182.com, 1 +z8187.com, 1 +z8190.com, 1 +z8193.com, 1 +z8195.com, 1 +z8196.com, 1 +z8200.com, 1 +z8201.com, 1 +z8202.com, 1 +z8203.com, 1 +z8205.com, 1 +z8206.com, 1 +z8207.com, 1 +z8208.com, 1 +z8209.com, 1 +z8210.com, 1 +z8212.com, 1 +z8213.com, 1 +z8215.com, 1 +z8217.com, 1 +z8218.com, 1 +z8219.com, 1 +z8225.com, 1 +z8226.com, 1 +z8230.com, 1 +z8231.com, 1 +z8232.com, 1 +z8233.com, 1 +z82365.com, 1 +z8251.com, 1 +z8817.com, 1 +z8821.com, 1 +z8826.com, 1 +z8829.com, 1 +z8851.com, 1 +z8852.com, 1 +z8856.com, 1 +z8857.com, 1 +z8860.com, 1 +z8861.com, 1 +z8862.com, 1 +z8865.com, 1 +z8870.com, 1 +z8871.com, 1 +z8872.com, 1 +z8875.com, 1 +z8876.com, 1 +z8879.com, 1 +z8891.com, 1 +z8895.com, 1 +z8905.com, 1 +z8906.com, 1 +z8907.com, 1 +z8908.com, 1 +z8909.com, 1 +z8917.com, 1 +z8918.com, 1 +z8920.com, 1 +z8922.com, 1 +z8925.com, 1 +z8926.com, 1 +z8927.com, 1 +z9297.co, 1 +z9397.com, 1 +z9721.com, 1 +z9728.co, 1 +z99944x.xyz, 1 +za.search.yahoo.com, 0 +zaagbaak.nl, 1 +zabatsai-sam.tk, 1 +zabbix-monitoring.tk, 1 +zabbix.tips, 1 +zabszk.net, 1 +zabukovnik.net, 1 +zac.cy, 1 +zacarias.com.ar, 1 +zacchaeus.co.uk, 1 +zacco.site, 1 +zach.vip, 0 +zacharopoulos.eu, 1 +zacharopoulos.me, 0 +zacharopoulos.org, 0 +zacharydubois.me, 1 +zacharyschneider.ca, 1 +zacharyschneider.com, 1 +zacharyseguin.ca, 1 +zachaysan.com, 1 +zachbolinger.com, 1 +zachborboa.com, 1 +zachgibbens.org, 1 +zachhay.es, 1 +zachschneider.ca, 1 +zaci.xyz, 1 +zack.today, 1 +zackiarfan.ml, 1 +zaclys.com, 0 +zadania.wiki, 1 +zadrot.tk, 1 +zadroweb.com, 1 +zaelkids.it, 1 +zaem.tv, 1 +zaffit.com, 0 +zaffke.co, 1 +zagadki-cosmosa.tk, 1 +zaghyr.org, 1 +zagorod.spb.ru, 1 +zagruz.tk, 1 +zahe.me, 1 +zahirdanzavila.com, 1 +zahnarzt-backfisch.de, 1 +zahnarzt-duempten.de, 1 +zahnarzt-hofer.de, 1 +zahnarzt-kramer.ch, 1 +zahnarzt-kruft.de, 1 +zahnarzt-seidenstuecker.de, 1 +zahnmedizinzentrum.com, 0 +zahrowski.com, 1 +zaidan.de, 1 +zaidan.eu, 1 +zaidanfood.com, 1 +zaidanfood.eu, 1 +zaidanlebensmittelhandel.de, 1 +zaija.tk, 1 +zaim-best.ml, 1 +zaim15min.cf, 1 +zaimdengi.tk, 1 +zaimexpress.cf, 1 +zaimi.ml, 1 +zaimin.ga, 1 +zaimlime.ga, 1 +zaimponuj.pl, 1 +zaimvkredit2.gq, 1 +zaimvkredit3.ga, 1 +zaimvkredit3.gq, 1 +zaimvkredit3.ml, 1 +zaimvkredit4.ml, 1 +zain-hasan.ml, 1 +zaitaiguo.com, 1 +zaixsp.com, 1 +zaizaia.cc, 1 +zajazd.biz, 1 +zajm-bez-otkaza.gq, 1 +zajm-bez-poruchitelej.cf, 1 +zajm-bez-spravok.tk, 1 +zajm-cherez-sms.ml, 1 +zajm-ehkspress.ml, 1 +zajm-na-kartu.tk, 1 +zajm-na-kivi.cf, 1 +zajm-pod-raspisku.cf, 1 +zajm-pod-zalog.ga, 1 +zajm-pod-zalog.gq, 1 +zajmy-contact.cf, 1 +zajmy-contact.ga, 1 +zajmy-contact.gq, 1 +zajmy-contact.tk, 1 +zak.co.at, 1 +zak.org.pl, 1 +zakaria.website, 1 +zakariya.blog, 1 +zakarotta.ga, 1 +zakaz.cf, 1 +zakazat-dizayn-interyera.ru, 1 +zakbk.xyz, 1 +zakcutner.com, 1 +zakcutner.uk, 1 +zakelijketaalcursus.nl, 1 +zakladam.cz, 1 +zakladki.tk, 1 +zakmccrac.de, 1 +zakojifarm.jp, 1 +zakononline.cf, 1 +zakonu.net.ru, 1 +zakpex.com, 1 +zakr.es, 1 +zakrentus-ostrus.space, 1 +zakspartiesandevents.com, 1 +zala.ml, 1 +zalain.ru, 1 +zalamea.ph, 1 +zalan.do, 1 +zalaxx.ddns.net, 1 +zaledia.com, 1 +zalihvoch.ga, 1 +zaloghaz.ro, 1 +zalohovaniburian.cz, 1 +zaltv.com, 1 +zalure.com, 1 +zalvus.com, 1 +zam0th.tk, 1 +zamalektoday.com, 1 +zamarax.com, 1 +zambianewsforum.tk, 1 +zambranopublicidadvideo.com, 1 +zamecnikkladno.cz, 1 +zamenim.tk, 1 +zamok-love.tk, 1 +zamok.cf, 1 +zamokservis.com, 1 +zamor.com.br, 1 +zamos.ru, 1 +zamow.co, 0 +zamtech.co.jp, 1 +zananta.com, 1 +zandcell.com, 1 +zander.dk, 1 +zandra.cf, 1 +zanellidesigns.co.uk, 1 +zango.com.au, 1 +zanjirzanane-shanbeghazan.ir, 1 +zanotti.io, 1 +zanquan.net, 1 +zanshinkankarate.com, 1 +zanthra.com, 1 +zanzariere.roma.it, 1 +zanzo.cz, 1 +zaoext.com, 1 +zap-mag.ru, 1 +zapamini.ml, 1 +zapaska.tk, 1 +zapier.com, 1 +zaplano.tk, 1 +zapmaster14.com, 1 +zappbuildapps.com, 0 +zappingarahal.tk, 1 +zappy.ml, 1 +zappy.wtf, 1 +zapreaders.cf, 1 +zaprefy.com, 1 +zarabiaj.com, 1 +zarabotki-v-internete.tk, 1 +zarabotok-v-internete.ga, 1 +zarabotok2017.tk, 1 +zarabotoker.tk, 1 +zarabotoklaif.tk, 1 +zarabotokvseti.tk, 1 +zaracraft.tk, 1 +zaratan.fr, 0 +zaraweb.net, 1 +zarbis.tk, 1 +zardain.tk, 1 +zargescases.co.uk, 1 +zarjadnik.tk, 1 +zarla.com, 1 +zarobotok-forum.gq, 1 +zarobotok-forum.ml, 1 +zaroktv.krd, 1 +zaruhi.ml, 1 +zary.me, 1 +zaschtnik.ga, 1 +zastenchivost.tk, 1 +zatsepin.by, 1 +zaufanatrzeciastrona.pl, 1 +zavarkin.tk, 1 +zavca.com, 1 +zavec.com.ec, 0 +zavedu.org, 1 +zawo-electric.de, 1 +zayats.tk, 1 +zaym.tk, 1 +zaympodzalog.cf, 1 +zaympodzalog.ga, 1 +zaympodzalog.gq, 1 +zaympodzalog.ml, 1 +zaympodzalog.tk, 1 +zayzoh.com, 1 +zazaradio.tk, 1 +zbanks.cn, 1 +zberger.com, 1 +zbetcheck.in, 1 +zbib.org, 1 +zbozbo.net, 1 +zbrane-doplnky.cz, 1 +zbsj.pl, 1 +zbuilderz-lb.com, 1 +zbut.bg, 1 +zby.io, 1 +zbyga.cz, 1 +zbyte.it, 1 +zcarot.com, 1 +zcarrot.com, 1 +zchuyot.co.il, 1 +zcompany.ga, 1 +zcompany.tk, 1 +zcon.nl, 1 +zcore.org, 1 +zcr.ca, 1 +zcrypto.ml, 1 +zcwtl.com, 1 +zczc.cz, 1 +zd1010.com, 1 +zd1515.com, 1 +zd209.com, 1 +zd235.com, 1 +zd236.com, 1 +zd2727.com, 1 +zd273.com, 1 +zd275.com, 1 +zd279.com, 1 +zd280.com, 1 +zd297.com, 1 +zd302.com, 1 +zd303.com, 1 +zd307.com, 1 +zd3434.com, 1 +zd4848.com, 1 +zd623.com, 1 +zd632.com, 1 +zd635.com, 1 +zd6464.com, 1 +zd652.com, 1 +zd6565.com, 1 +zd673.com, 1 +zd6862.com, 1 +zd6866.com, 1 +zd6867.com, 1 +zd6879.com, 1 +zd6880.com, 1 +zd6883.com, 1 +zd6885.com, 1 +zd6886.com, 1 +zd6889.com, 1 +zd6893.com, 1 +zd6896.com, 1 +zd6898.com, 1 +zd692.com, 1 +zd693.com, 1 +zd697.com, 1 +zd723.com, 1 +zd726.com, 1 +zd732.com, 1 +zd736.com, 1 +zd753.com, 1 +zd7575.com, 1 +zd759.com, 1 +zd762.com, 1 +zd792.com, 1 +zd793.com, 1 +zd796.com, 1 +zd803.com, 1 +zd805.com, 1 +zd806.com, 1 +zd823.com, 1 +zd826.com, 1 +zd827.com, 1 +zd8826.com, 1 +zd8828.com, 1 +zd8829.com, 1 +zd8832.com, 1 +zd8835.com, 1 +zd8838.com, 1 +zd8839.com, 1 +zd8852.com, 1 +zd8853.com, 1 +zd8858.com, 1 +zd8865.com, 1 +zd8869.com, 1 +zd8878.com, 1 +zd8882.com, 1 +zd8883.com, 1 +zd8898.com, 1 +zd9090.com, 1 +zd9797.com, 1 +zdbl.de, 1 +zdenek-hejl.com, 1 +zdenekpasek.com, 1 +zdenekpasek.cz, 1 +zdenekspacek.cz, 1 +zdenekvecera.cz, 1 +zdorov-blog.gq, 1 +zdorov.by, 1 +zdorovayasimya.com, 1 +zdorovcentr.ga, 1 +zdrave-konzultace.cz, 1 +zdravekonzultace.cz, 1 +zdravesteny.cz, 1 +zdravotnikurzy.cz, 1 +zdravystul.cz, 1 +zdrojak.cz, 1 +zdrowezywienie.edu.pl, 1 +zdymak.by, 1 +ze3kr.com, 1 +zeadaniel.com, 1 +zeal-and.jp, 1 +zeal-interior.com, 1 +zealandia.games, 1 +zealworks.jp, 1 +zeanweb.tk, 1 +zeb.fun, 1 +zebbra.ro, 1 +zebraguide.com, 1 +zebratee.com, 1 +zeckenhilfe.de, 0 +zecuur.nl, 1 +zedeko.pl, 1 +zeds-official.com, 1 +zeedroom.be, 0 +zeegers.family, 1 +zeel.com, 1 +zeetoppers.nl, 1 +zegarkidlakazdego.pl, 1 +zegluje.net, 1 +zeglujemy.net, 1 +zegriesalmansa.tk, 1 +zeguigui.com, 1 +zegwaardrioolontstopping.nl, 1 +zehdenick-bleibt-bunt.de, 1 +zehka.net, 1 +zehkae.net, 1 +zehnegira.ir, 0 +zehrailkeakyildiz.com, 0 +zeibekiko-souvlaki.gr, 1 +zeidlertechnik.de, 1 +zeihetecumre.cf, 1 +zeihetecumre.gq, 1 +zeihsel.com, 1 +zeilenmethans.nl, 1 +zeilenvoorondernemers.nl, 1 +zeilenwind.com, 1 +zeilles.nu, 1 +zeit.co, 1 +zeit.sh, 1 +zeitgitter.org, 1 +zeitoununiversity.org, 1 +zeitpunkt-kulturmagazin.de, 1 +zeitzer-turngala.de, 1 +zekerheidvanparcelinternational.nl, 1 +zekesnider.com, 1 +zekinteractive.com, 1 +zeldaliberty.tk, 1 +zelena-armija.tk, 1 +zelendoma.ml, 1 +zelezny.uk, 0 +zeliard.tk, 1 +zelkor.ml, 1 +zell-mbc.com, 1 +zeloz.xyz, 1 +zelt.in, 1 +zelvar.cz, 1 +zeman-fireworks.cz, 1 +zemli.tk, 1 +zemlova.cz, 1 +zemlyaki.ga, 1 +zen-diez.de, 1 +zen-solutions.io, 1 +zen-zone.tk, 1 +zen3tech.com, 1 +zenassociates.com, 1 +zenavita.com, 1 +zenchain.com, 1 +zendarhunters.tk, 1 +zenfusion.fr, 1 +zengdong.ren, 1 +zenghuanmin.cn, 1 +zengold.com, 1 +zenideen.com, 1 +zenidees.com, 1 +zenisi.com, 1 +zenithappliance.co.uk, 1 +zenithars-ledger.de, 1 +zenithmedia.ca, 1 +zenitkft.hu, 1 +zenk-security.com, 1 +zenki-manga.tk, 1 +zenlogic.com, 1 +zenluxuryliving.com, 1 +zenmail.ga, 1 +zenmate.com.tr, 1 +zeno-dev.com, 1 +zenofa.co.id, 1 +zenrtal-online-russia.ml, 1 +zenspace.us, 1 +zenstore.it, 1 +zenti-im-zug.de, 1 +zenti.cloud, 1 +zentoy.club, 1 +zentrumfuerchemie.de, 1 +zenvideocloud.com, 1 +zenvite.com, 1 +zenways.io, 1 +zeocax.com, 0 +zephyrbk.com, 1 +zephyrbookkeeping.com, 1 +zephyretcoraline.com, 1 +zeplin.io, 1 +zepter.cf, 1 +zepter.ga, 1 +zepter.gq, 1 +zepter.ml, 1 +zer0-day.pw, 1 +zer0.de, 0 +zercutie.com, 1 +zerg.uk, 1 +zerium.ml, 1 +zerm.eu, 1 +zero-knigi.ml, 1 +zero-skill.net, 1 +zero-sum.xyz, 1 +zeroanarchy.com, 1 +zerobounce.net, 1 +zerocalc.be, 1 +zerocash.msk.ru, 1 +zerocms.fr, 1 +zerocool.io, 1 +zerocz.eu, 0 +zerodeathsmd.gov, 1 +zerodhareview.co, 1 +zeroerrordev.com, 1 +zerofogmask.com, 1 +zerofy.de, 1 +zeroknowledge.me, 1 +zerolab.org, 1 +zeromedia.co.id, 1 +zeromoment.marketing, 1 +zeronet.io, 1 +zeropoint.bg, 1 +zerosector.io, 1 +zeroseteatacado.com.br, 1 +zerosource.net, 1 +zerosync.com, 1 +zerotoone.de, 1 +zerotoone.studio, 1 +zerotwo.ga, 1 +zerowastesonoma.gov, 1 +zerox-security.online, 1 +zeroz.gq, 1 +zerozero.gq, 1 +zertif.info, 1 +zerty.de, 1 +zeryn.net, 1 +zesgoes.nl, 1 +zespia.tw, 1 +zestadionu.pl, 1 +zeta.co.za, 1 +zeta.hk, 1 +zetamode.com, 1 +zetasystem.jp, 1 +zetorzeszow.pl, 0 +zettahertz.com, 1 +zettaplan.ru, 1 +zettel.io, 1 +zettlmeissl.de, 1 +zety.com, 1 +zety.es, 1 +zety.fr, 1 +zeus.gent, 1 +zeuscorp.ga, 1 +zeusec.co.jp, 1 +zevelev.net, 1 +zevenbergenbos.tk, 1 +zewtie.com, 1 +zezov.com, 1 +zfast.com.br, 1 +zfg.li, 1 +zfj.hk, 1 +zfj.la, 0 +zfly.me, 1 +zfo.gg, 0 +zfree.co.nz, 1 +zfxhzc.blog, 1 +zfyl8.com, 1 +zg-dyw.net, 1 +zgan.ga, 1 +zgndh.com, 1 +zgrep.org, 1 +zh.fyi, 1 +zh.search.yahoo.com, 0 +zhabababa.gq, 1 +zhabagly.com, 1 +zhainanyouhuo.com, 1 +zhamolov.tk, 1 +zhan.moe, 1 +zhang-hao.com, 1 +zhang.fm, 1 +zhang.ge, 1 +zhang.nz, 1 +zhangcheng.org, 0 +zhangda.xyz, 1 +zhangfangzhou.com, 1 +zhangge.net, 1 +zhanghao.me, 1 +zhanghao.org, 1 +zhanglizhi.ml, 1 +zhangshuqiao.org, 1 +zhangwendao.com, 1 +zhangyuhao.com, 1 +zhanxiangyang.com, 1 +zhanzhangb.com, 1 +zhaochen.xyz, 1 +zhaodao.ai, 1 +zhaoeq.com, 1 +zhaofeng.li, 1 +zhaopage.com, 1 +zhaostephen.com, 1 +zhaoxixiangban.cc, 1 +zhattyt.com, 1 +zhcexo.com, 1 +zhdun.tk, 1 +zhelanie.ml, 1 +zheldor-dance.ga, 1 +zheldorinform.ga, 1 +zhen-chen.com, 1 +zhendre.com, 1 +zhenggangzhao.org, 1 +zhengjie.com, 1 +zhengouwu.com, 1 +zhengzihan.com, 1 +zhenic.ir, 1 +zhenn.fr, 1 +zhenyan.org, 1 +zhestokiemechtyi.tk, 1 +zhestokijavtor.tk, 1 +zhf.io, 1 +zhi.ci, 1 +zhidkiy-kashtan.ga, 1 +zhih.me, 1 +zhihua-lai.com, 1 +zhiin.net, 0 +zhikin.com, 1 +zhiku8.com, 1 +zhima.io, 1 +zhimajk.com, 1 +zhimingwang.org, 1 +zhis.eu, 1 +zhis.ltd, 1 +zhitanska.com, 1 +zhiwei.me, 1 +zhiyulife.pp.ua, 1 +zhl123.cn, 1 +zhl123.com, 1 +zhodino.ga, 1 +zhome.info, 1 +zhongxigo.com, 1 +zhongzicili.ws, 1 +zhouba.cz, 1 +zhoujianghan.com, 0 +zhoujiashu.com, 1 +zhoujunlawer.ml, 1 +zhoushuo.me, 0 +zhoutiancai.cn, 1 +zhouzhi.me, 1 +zhovner.com, 1 +zhstar.win, 1 +zhthings.com, 1 +zhuihoude.com, 1 +zhuji.com, 1 +zhuji.com.cn, 1 +zhuji.org, 1 +zhuji5.com, 1 +zhujicaihong.com, 1 +zhujiceping.com, 1 +zhuktrans.msk.ru, 1 +zhunlink.com, 1 +zhurnalyu.ga, 1 +zhy.us, 1 +zi.is, 1 +zi5.net, 1 +ziad87.net, 0 +zidanpainting.com, 1 +ziegenhagel.com, 1 +ziegler-heizung-frankfurt.de, 1 +zielonakarta.com, 1 +ziemlich-zackig.de, 1 +ziemlichzackig.de, 1 +ziendo.com, 1 +zifb.in, 1 +zifoapptest.com, 1 +zigao.info, 0 +zigarn.com, 1 +ziggletech.com, 1 +zighinetto.org, 1 +zigi.io, 1 +zigottos.fr, 1 +zigsphere.com, 1 +zigzagmart.com, 1 +zihao.me, 0 +zihari.com, 1 +zihun.club, 1 +zii.bz, 1 +ziin.de, 1 +zijemvedu.sk, 1 +zijinbor.com, 1 +zikinf.com, 1 +zikipedia.ml, 1 +zikirakhirzaman.com, 1 +ziledelaultimagafaavioricai.ro, 1 +ziliotti.com.br, 1 +zilla-sushi.tk, 1 +zillertaleralpen.net, 1 +zilon.com.co, 1 +zilore.com, 1 +zilsen.com, 1 +zilsoft.net, 0 +zilv.life, 1 +zilver.nl, 1 +zima-lito.tk, 1 +zima.io, 1 +zimaaplus.com, 1 +zimaoxy.com, 1 +zimiao.moe, 1 +zimmer-voss.de, 1 +zimperium.com, 1 +zinabnews.tk, 1 +zinchenko.gq, 1 +zindan.tk, 1 +zindec.com, 1 +zinewords.com, 1 +zingarastore.com, 1 +zinglix.xyz, 1 +zings.eu, 1 +zinniazorgverlening.nl, 1 +zinnowitzer-ferienwohnung.de, 1 +zinoui.com, 1 +zion-craft.tk, 1 +ziondrive.com.br, 1 +zionnationalpark.net, 1 +zionsvillelocksmiths.com, 1 +zionvps.com, 0 +zipfworks.com, 1 +zipkey.de, 1 +zippo-days.me, 1 +zippyshare.com, 1 +ziprecruiter.com, 1 +ziqijiang.com, 0 +zir-online.com, 1 +zircode.com, 1 +zirka24.net, 1 +ziroh.be, 1 +ziron.com, 1 +ziroux.net, 1 +zirrka.de, 1 +zirtual.com, 1 +zistemo.com, 1 +zitadel.ch, 1 +zithromaxstrepthroat.gq, 1 +zitseng.com, 1 +zitstabureau24.nl, 1 +zivava.ge, 1 +zivimexico.com, 1 +zivot.org, 1 +zivver.be, 1 +zivver.co.uk, 1 +zivver.com, 1 +zivver.de, 1 +zivver.eu, 1 +zivver.info, 1 +zivver.nl, 1 +zivver.uk, 1 +zivyruzenec.cz, 1 +zixiao.wang, 1 +zixin.com, 1 +ziz.exchange, 0 +zizcollections.com, 1 +zizibook.ml, 1 +zjateaucafe.be, 1 +zjawa.pro, 1 +zjc3.com, 1 +zju.tv, 1 +zjuqsc.com, 1 +zjy7722.ml, 1 +zjyifa.cn, 1 +zk.gd, 1 +zk9.nl, 1 +zklcdc.top, 1 +zklokotskehory.cz, 1 +zkontrolujsiauto.cz, 1 +zkwolf.top, 1 +zkzone.net, 1 +zl-19.com, 1 +zl-29.com, 1 +zl-59.com, 1 +zl-69.com, 1 +zl-79.com, 1 +zl-89.com, 1 +zl0101.com, 1 +zl0707.com, 1 +zl071.com, 1 +zl0909.com, 1 +zl0iu.com, 1 +zl0sz.com, 1 +zl1010.com, 1 +zl1212.com, 1 +zl1515.com, 1 +zl1616.com, 1 +zl2020.com, 1 +zl2020.vip, 1 +zl2121.com, 1 +zl2727.com, 1 +zl2929.com, 1 +zl335.com, 1 +zl3737.com, 1 +zl4231.com, 1 +zl4290.com, 1 +zl5050.com, 1 +zl5151.com, 1 +zl6161.com, 1 +zl6464.com, 1 +zl6767.com, 1 +zl6868.com, 1 +zl6969.com, 1 +zl6xw.com, 1 +zl7070.com, 1 +zl7077.com, 1 +zl7171.com, 1 +zl738.com, 1 +zl7979.com, 1 +zl8181.com, 1 +zl8383.com, 1 +zl850.com, 1 +zl861.com, 1 +zl8686.com, 1 +zl8787.com, 1 +zl8824.com, 1 +zl8849.com, 1 +zl8861.com, 1 +zl8870.com, 1 +zl9191.com, 1 +zl969.com, 1 +zl9696.com, 1 +zl9898.com, 1 +zlarin.tk, 1 +zlatakus.cz, 1 +zlatan-ibrahimovic.tk, 1 +zlatanonline.tk, 1 +zlatograd.bg, 1 +zlatom.ru, 1 +zlatosnadno.cz, 1 +zlaty-tyden.cz, 1 +zlatytyden.cz, 1 +zlavomat.sk, 1 +zlhgc.com, 1 +zlhuodong.vip, 1 +zlima12.com, 1 +zlong6.com, 1 +zlong6.net, 1 +zlonov.ru, 1 +zlotykameleon.tk, 1 +zlotyslawecin.tk, 1 +zloybot.tk, 1 +zltymacau.com, 1 +zlypi.com, 1 +zmaloveane.pl, 1 +zmarta.de, 1 +zmarta.dk, 1 +zmarta.fi, 1 +zmarta.no, 1 +zmarta.org, 1 +zmarta.se, 1 +zmartagroup.com, 1 +zmartagroup.fi, 1 +zmartagroup.no, 1 +zmartagroup.se, 1 +zmc.com.sa, 1 +zmeya.tk, 1 +zmiguel.me, 1 +zmk.fr, 0 +zmy.im, 1 +zmy666.com, 1 +znachenie-sna.ga, 1 +znaj.ua, 1 +znakcomstva.ru, 1 +znakomim.cf, 1 +znakomstva-2013.tk, 1 +znakomstva.gq, 1 +znakomstvablogs.tk, 1 +znakomstvatochka.tk, 1 +znanie-sila.tk, 1 +znaniya.cf, 1 +znanje.gq, 1 +znation.nl, 1 +znbr.com, 1 +znd.jp, 1 +zngay.com, 1 +znhglobalresources.com, 1 +znich.tk, 1 +znidar.org, 1 +zning.net.cn, 1 +znn.co.jp, 1 +znti.de, 1 +znwvw.net, 1 +zobraz.cz, 1 +zobworks.com, 1 +zochowskiplasticsurgery.com, 1 +zockenbiszumumfallen.de, 1 +zodgame.fun, 0 +zodiacohouses.com, 1 +zodiak.tk, 1 +zodian-research.ro, 0 +zoedale.co.uk, 1 +zoefmasters.be, 1 +zoepolitics.cf, 1 +zof.kh.ua, 1 +zoflora.co.uk, 1 +zofran-medication.cf, 1 +zofran.ga, 1 +zofrancost.ga, 1 +zofrangeneric.ga, 1 +zofranprice.ga, 1 +zofrex.com, 0 +zofzpcb.com, 1 +zogatest.tk, 1 +zogevikst.nl, 1 +zohar.wang, 1 +zohra.ninja, 1 +zoigl.club, 1 +zoisfinefood.fr, 1 +zojadravai.com, 1 +zok-ambicija.tk, 1 +zoki.art, 1 +zoko.tk, 1 +zokoo.es, 1 +zollernalbtour.de, 1 +zoloft-medication.ml, 1 +zoloftmedication.gq, 1 +zoloftpills.tk, 1 +zoloftprice.cf, 1 +zolokar.xyz, 1 +zolotie-ptichki.tk, 1 +zolotistyi-kofe.gq, 1 +zolotoioasis.ml, 1 +zolotoy-standart.com.ua, 1 +zolushka-1950.tk, 1 +zom.bi, 1 +zombie-40th.com, 1 +zombie-apocalypse-survival.com, 1 +zombie.cam, 1 +zombiemix.tk, 1 +zombiesecured.com, 1 +zombmage.tk, 1 +zomerschoen.nl, 1 +zomiac.pp.ua, 1 +zona-bellepop.tk, 1 +zonadetestes.com, 1 +zonadigital.co, 1 +zonagratisan.ga, 1 +zonaperu.tk, 1 +zonatelevision.tk, 1 +zondervanacademic.com, 1 +zone-5.de, 1 +zone-de-confiance.fr, 1 +zone39.com, 1 +zonecb.com, 1 +zoneface.com, 1 +zonehomesolutions.com, 1 +zonemaster.fr, 1 +zonemaster.net, 1 +zonesec.org, 1 +zonewatcher.com, 1 +zongboao.com, 1 +zonglovani.info, 1 +zonky.cz, 1 +zonky.de, 1 +zontractors.com, 1 +zooforum.tk, 1 +zoogbook.ml, 1 +zooish.net, 1 +zook.systems, 1 +zook.tk, 1 +zookri.com, 1 +zoola.io, 1 +zoological-gardens.eu, 1 +zoom.earth, 1 +zoomative.com, 1 +zoomcar.pro, 1 +zoomek.com, 1 +zoomgov.com, 1 +zooom.azurewebsites.net, 1 +zooom2.azurewebsites.net, 1 +zoop.ml, 0 +zooparadies.eu, 1 +zoopix.ir, 1 +zooplankton.no, 1 +zootime.net, 1 +zootime.org, 1 +zoowiki.us, 1 +zooxdata.com, 1 +zoptiks.com, 0 +zopyx.com, 1 +zor.com, 1 +zorasvobodova.cz, 1 +zorgclustertool.nl, 1 +zorgenvoorandrea.be, 1 +zorgenvoorherena.be, 1 +zorgenvoorjean.be, 1 +zorgenvoormaria.be, 1 +zorghuys-steenbergen.nl, 1 +zorghuys.nl, 1 +zorgvanoranje.nl, 1 +zorig.ch, 1 +zorium.org, 0 +zormeloandassociates.com, 1 +zornica.tk, 1 +zorntt.fr, 1 +zorox.org, 0 +zorox.sex, 1 +zorz.info, 1 +zoske.it, 1 +zoso.ro, 0 +zotan.email, 1 +zotan.network, 1 +zotan.photography, 1 +zotan.photos, 1 +zotan.pictures, 1 +zotan.pw, 1 +zotan.services, 1 +zotan.stream, 1 +zotan.studio, 1 +zotero.org, 1 +zottika.com, 1 +zouaouitransport.fr, 1 +zouk.info, 1 +zouyaoji.top, 1 +zova.io, 1 +zovirax-cream.ml, 1 +zovovo.com, 1 +zowe.ru, 1 +zoyride.com, 1 +zoznamrealit.sk, 1 +zozzle.co.uk, 1 +zp.do, 1 +zp25.ninja, 1 +zpider.cloud, 1 +zporno.porn, 1 +zporno.sex, 1 +zq789.com, 1 +zqwqz.org, 1 +zqzx.xyz, 1 +zravyobrazky.cz, 1 +zravypapir.cz, 1 +zrejstejna.cz, 1 +zrgmedical.com, 1 +zrinski.tk, 1 +zrkhosting.com, 1 +zrkr.de, 1 +zrniecka-pre-sny.sk, 1 +zrnieckapresny.sk, 1 +zrobysama.com.ua, 1 +zrs-meissen.de, 1 +zs6688.cc, 1 +zsbd.xyz, 1 +zscales.com, 0 +zsdublovice.cz, 1 +zselicivt.hu, 1 +zserver.fr, 1 +zsien.cn, 1 +zskomenskeho.cz, 1 +zskomenskeho.eu, 1 +zsoltbereczki.tk, 1 +zsoltsandor.me, 1 +zsq.im, 1 +zsrbcs.com, 1 +zstgmnachod.cz, 1 +zsyaolong.com, 0 +zten.org, 1 +zthc.nl, 1 +ztickerz.nl, 0 +ztn.sh, 1 +zuan-in.com, 1 +zuan-in.net, 1 +zubar.bg, 1 +zubby.com, 1 +zubel.it, 0 +zubilo-perm.ru, 1 +zubr.net, 1 +zubro.net, 1 +zudomc.me, 1 +zuefle.net, 1 +zuehlcke.de, 1 +zuffel.com, 1 +zug-anwalt.de, 0 +zugfahrplan.com, 1 +zuhausejobs.at, 1 +zuiacg.com, 1 +zuim.de, 1 +zuitaotu.com, 1 +zuiverjegeest.nl, 1 +zukify.com, 1 +zukix.com, 1 +zukonar.ru, 1 +zukunft-mobilitaet.net, 1 +zula.africa, 1 +zulaoyun.ml, 1 +zulihome.vn, 1 +zulu.ro, 1 +zuluconnect.net, 1 +zum-baur.de, 1 +zum-ziegenhainer.de, 1 +zumba-oostende.be, 1 +zumba.com, 1 +zumberak.tk, 1 +zumtaedanceschool.co.za, 1 +zumub.com, 1 +zund-app.com, 1 +zundapp.one, 1 +zundapp529.nl, 1 +zundappachterhoek.nl, 1 +zunlong0.com, 1 +zuolan.me, 1 +zup.me, 1 +zupago.pe, 1 +zupit.it, 1 +zuppy.pm, 1 +zurgl.com, 1 +zurlin.de, 1 +zurmas-design.tk, 1 +zuru.com, 1 +zusammen-grossartig.de, 1 +zusjesvandenbos.nl, 1 +zuss.tk, 1 +zusterjansen.nl, 1 +zuviel.space, 1 +zuyzi.com, 1 +zuzannastrycharska.pl, 0 +zuzumba.es, 1 +zvejonys.lt, 1 +zverskij-site.tk, 1 +zvezdy-porno.ml, 1 +zvive.com, 1 +zvps.uk, 1 +zvxr.net, 1 +zvz.im, 1 +zwartendijkstalling.nl, 1 +zwemclub-rob.nl, 1 +zwergenfeste.ch, 1 +zwergenfreiheit.at, 1 +zwerimex.com, 1 +zwilla.de, 1 +zwk.de, 1 +zwofroue.ch, 1 +zwollemag.nl, 1 +zwollemagazine.nl, 1 +zwy.ch, 0 +zwyr157wwiu6eior.com, 1 +zx6rninja.de, 1 +zx7r.de, 1 +zxe.com.br, 1 +zxfiles.tk, 1 +zxity.co.uk, 1 +zxity.ltd, 1 +zxity.uk, 1 +zxtcode.com, 1 +zy.md, 1 +zy.si, 1 +zybbo.com, 1 +zycao.com, 0 +zycie.news, 1 +zyciedirect.pl, 1 +zyciedogorynogami.pl, 1 +zyciepl.com, 1 +zydu4.com, 1 +zyex.vip, 1 +zygfrydadamski.tk, 1 +zygozoon.com, 1 +zylai.com, 1 +zylai.net, 1 +zymmm.com, 1 +zypern-firma.com, 1 +zypr.pw, 1 +zyria.de, 1 +zyrillezuno.com, 1 +zythromax.ga, 1 +zyul.ddns.net, 1 +zyx3d.tk, 1 +zyzardx.com, 1 +zyzsdy.com, 1 +zz.gy, 1 +zz017.com, 1 +zz204.com, 1 +zz284.com, 1 +zz342.com, 1 +zz5197.co, 1 +zz606.com, 1 +zz6729.co, 1 +zz6729.com, 1 +zz6957.co, 1 +zz772.com, 1 +zz9297.co, 1 +zz9397.com, 1 +zz9721.com, 1 +zz9728.co, 1 +zz993.com, 1 +zzcc.de, 0 +zzekj.net, 1 +zzf.red, 1 +zzgtech.com, 1 +zzops.eu, 1 +zzops.net, 1 +zzops.nl, 1 +zzops.org, 1 +zzpd.nl, 0 +zzpwoerden.nl, 1 +zzsec.org, 1 +zzw.ca, 1 +zzzz365.com, 0 +%% diff --git a/security/manager/ssl/nsSecureBrowserUI.cpp b/security/manager/ssl/nsSecureBrowserUI.cpp new file mode 100644 index 0000000000..b4de1a331f --- /dev/null +++ b/security/manager/ssl/nsSecureBrowserUI.cpp @@ -0,0 +1,162 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "nsSecureBrowserUI.h" + +#include "mozilla/Assertions.h" +#include "mozilla/Logging.h" +#include "mozilla/Unused.h" +#include "mozilla/dom/Document.h" +#include "nsContentUtils.h" +#include "nsIChannel.h" +#include "nsDocShell.h" +#include "nsIDocShellTreeItem.h" +#include "nsGlobalWindow.h" +#include "nsIInterfaceRequestorUtils.h" +#include "nsITransportSecurityInfo.h" +#include "nsIWebProgress.h" +#include "nsNetUtil.h" +#include "mozilla/dom/CanonicalBrowsingContext.h" +#include "mozilla/dom/WindowGlobalParent.h" +#include "mozilla/dom/Element.h" +#include "nsIBrowser.h" + +using namespace mozilla; +using namespace mozilla::dom; + +LazyLogModule gSecureBrowserUILog("nsSecureBrowserUI"); + +nsSecureBrowserUI::nsSecureBrowserUI(CanonicalBrowsingContext* aBrowsingContext) + : mState(0) { + MOZ_ASSERT(NS_IsMainThread()); + + // The BrowsingContext will own the SecureBrowserUI object, we keep a weak + // ref. + mBrowsingContextId = aBrowsingContext->Id(); +} + +NS_IMPL_ISUPPORTS(nsSecureBrowserUI, nsISecureBrowserUI, + nsISupportsWeakReference) + +NS_IMETHODIMP +nsSecureBrowserUI::GetState(uint32_t* aState) { + MOZ_ASSERT(NS_IsMainThread()); + NS_ENSURE_ARG(aState); + + MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, + ("GetState %p mState: %x", this, mState)); + *aState = mState; + return NS_OK; +} + +void nsSecureBrowserUI::RecomputeSecurityFlags() { + // Our BrowsingContext either has a new WindowGlobalParent, or the + // existing one has mutated its security state. + // Recompute our security state and fire notifications to listeners + + RefPtr win = GetCurrentWindow(); + mState = nsIWebProgressListener::STATE_IS_INSECURE; + + // Only https is considered secure (it is possible to have e.g. an http URI + // with a channel that has a securityInfo that indicates the connection is + // secure - e.g. h2/alt-svc or by visiting an http URI over an https proxy). + nsCOMPtr securityInfo; + if (win && win->GetIsSecure()) { + securityInfo = win->GetSecurityInfo(); + if (securityInfo) { + MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, + (" we have a security info %p", securityInfo.get())); + + nsresult rv = securityInfo->GetSecurityState(&mState); + + // If the security state is STATE_IS_INSECURE, the TLS handshake never + // completed. Don't set any further state. + if (NS_SUCCEEDED(rv) && + mState != nsIWebProgressListener::STATE_IS_INSECURE) { + MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, + (" set mTopLevelSecurityInfo")); + bool isEV; + rv = securityInfo->GetIsExtendedValidation(&isEV); + if (NS_SUCCEEDED(rv) && isEV) { + MOZ_LOG(gSecureBrowserUILog, LogLevel::Debug, (" is EV")); + mState |= nsIWebProgressListener::STATE_IDENTITY_EV_TOPLEVEL; + } + } + } + } + + // Add upgraded-state flags when request has been + // upgraded with HTTPS-Only Mode + if (win) { + // Check if top-level load has been upgraded + uint32_t httpsOnlyStatus = win->HttpsOnlyStatus(); + if (!(httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_UNINITIALIZED) && + !(httpsOnlyStatus & nsILoadInfo::HTTPS_ONLY_EXEMPT)) { + mState |= nsIWebProgressListener::STATE_HTTPS_ONLY_MODE_UPGRADED; + } + // Add the secruity flags from the window + mState |= win->GetSecurityFlags(); + } + + // If we have loaded mixed content and this is a secure page, + // then clear secure flags and add broken instead. + static const uint32_t kLoadedMixedContentFlags = + nsIWebProgressListener::STATE_LOADED_MIXED_DISPLAY_CONTENT | + nsIWebProgressListener::STATE_LOADED_MIXED_ACTIVE_CONTENT; + if (win && win->GetIsSecure() && (mState & kLoadedMixedContentFlags)) { + // reset state security flag + mState = mState >> 4 << 4; + // set state security flag to broken, since there is mixed content + mState |= nsIWebProgressListener::STATE_IS_BROKEN; + } + + RefPtr ctx = + CanonicalBrowsingContext::Get(mBrowsingContextId); + if (!ctx) { + return; + } + + if (ctx->GetDocShell()) { + nsDocShell* nativeDocShell = nsDocShell::Cast(ctx->GetDocShell()); + nativeDocShell->nsDocLoader::OnSecurityChange(nullptr, mState); + } else if (ctx->GetWebProgress()) { + ctx->GetWebProgress()->OnSecurityChange(nullptr, nullptr, mState); + } +} + +NS_IMETHODIMP +nsSecureBrowserUI::GetIsSecureContext(bool* aIsSecureContext) { + MOZ_ASSERT(NS_IsMainThread()); + NS_ENSURE_ARG(aIsSecureContext); + + if (WindowGlobalParent* parent = GetCurrentWindow()) { + *aIsSecureContext = parent->GetIsSecureContext(); + } else { + *aIsSecureContext = false; + } + return NS_OK; +} + +NS_IMETHODIMP +nsSecureBrowserUI::GetSecInfo(nsITransportSecurityInfo** result) { + MOZ_ASSERT(NS_IsMainThread()); + NS_ENSURE_ARG_POINTER(result); + + if (WindowGlobalParent* parent = GetCurrentWindow()) { + *result = parent->GetSecurityInfo(); + } + NS_IF_ADDREF(*result); + + return NS_OK; +} + +WindowGlobalParent* nsSecureBrowserUI::GetCurrentWindow() { + RefPtr ctx = + CanonicalBrowsingContext::Get(mBrowsingContextId); + if (!ctx) { + return nullptr; + } + return ctx->GetCurrentWindowGlobal(); +} diff --git a/security/manager/ssl/nsSecureBrowserUI.h b/security/manager/ssl/nsSecureBrowserUI.h new file mode 100644 index 0000000000..a71d9ebde4 --- /dev/null +++ b/security/manager/ssl/nsSecureBrowserUI.h @@ -0,0 +1,53 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#ifndef nsSecureBrowserUIImpl_h +#define nsSecureBrowserUIImpl_h + +#include "nsCOMPtr.h" +#include "nsISecureBrowserUI.h" +#include "nsITransportSecurityInfo.h" +#include "nsIWebProgressListener.h" +#include "nsWeakReference.h" + +class nsITransportSecurityInfo; +class nsIChannel; + +namespace mozilla { +namespace dom { +class Document; +class WindowGlobalParent; +class CanonicalBrowsingContext; +} // namespace dom +} // namespace mozilla + +#define NS_SECURE_BROWSER_UI_CID \ + { \ + 0xcc75499a, 0x1dd1, 0x11b2, { \ + 0x8a, 0x82, 0xca, 0x41, 0x0a, 0xc9, 0x07, 0xb8 \ + } \ + } + +class nsSecureBrowserUI : public nsISecureBrowserUI, + public nsSupportsWeakReference { + public: + explicit nsSecureBrowserUI( + mozilla::dom::CanonicalBrowsingContext* aBrowsingContext); + + NS_DECL_ISUPPORTS + NS_DECL_NSISECUREBROWSERUI + + void RecomputeSecurityFlags(); + + protected: + virtual ~nsSecureBrowserUI() = default; + + mozilla::dom::WindowGlobalParent* GetCurrentWindow(); + + uint32_t mState; + uint64_t mBrowsingContextId; +}; + +#endif // nsSecureBrowserUIImpl_h diff --git a/security/manager/ssl/nsSecurityHeaderParser.cpp b/security/manager/ssl/nsSecurityHeaderParser.cpp new file mode 100644 index 0000000000..d9d9d48bc0 --- /dev/null +++ b/security/manager/ssl/nsSecurityHeaderParser.cpp @@ -0,0 +1,206 @@ +/* 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/. */ + +#include "nsSecurityHeaderParser.h" +#include "mozilla/Logging.h" + +// The character classes in this file are informed by [RFC2616], Section 2.2. +// signed char is a signed data type one byte (8 bits) wide, so its value can +// never be greater than 127. The following implicitly makes use of this. + +// A token is one or more CHAR except CTLs or separators. +// A CHAR is any US-ASCII character (octets 0 - 127). +// A CTL is any US-ASCII control character (octets 0 - 31) and DEL (127). +// A separator is one of ()<>@,;:\"/[]?={} as well as space and +// horizontal-tab (32 and 9, respectively). +// So, this returns true if chr is any octet 33-126 except ()<>@,;:\"/[]?={} +bool IsTokenSymbol(signed char chr) { + if (chr < 33 || chr == 127 || chr == '(' || chr == ')' || chr == '<' || + chr == '>' || chr == '@' || chr == ',' || chr == ';' || chr == ':' || + chr == '"' || chr == '/' || chr == '[' || chr == ']' || chr == '?' || + chr == '=' || chr == '{' || chr == '}' || chr == '\\') { + return false; + } + return true; +} + +// A quoted-string consists of a quote (") followed by any amount of +// qdtext or quoted-pair, followed by a quote. +// qdtext is any TEXT except a quote. +// TEXT is any 8-bit octet except CTLs, but including LWS. +// quoted-pair is a backslash (\) followed by a CHAR. +// So, it turns out, \ can't really be a qdtext symbol for our purposes. +// This returns true if chr is any octet 9,10,13,32-126 except <"> or "\" +bool IsQuotedTextSymbol(signed char chr) { + return ((chr >= 32 && chr != '"' && chr != '\\' && chr != 127) || + chr == 0x9 || chr == 0xa || chr == 0xd); +} + +// The octet following the "\" in a quoted pair can be anything 0-127. +bool IsQuotedPairSymbol(signed char chr) { return (chr >= 0); } + +static mozilla::LazyLogModule sSHParserLog("nsSecurityHeaderParser"); + +#define SHPARSERLOG(args) MOZ_LOG(sSHParserLog, mozilla::LogLevel::Debug, args) + +nsSecurityHeaderParser::nsSecurityHeaderParser(const nsCString& aHeader) + : mCursor(aHeader.get()), mDirective(nullptr), mError(false) {} + +nsSecurityHeaderParser::~nsSecurityHeaderParser() { + nsSecurityHeaderDirective* directive; + while ((directive = mDirectives.popFirst())) { + delete directive; + } +} + +mozilla::LinkedList* +nsSecurityHeaderParser::GetDirectives() { + return &mDirectives; +} + +nsresult nsSecurityHeaderParser::Parse() { + MOZ_ASSERT(mDirectives.isEmpty()); + SHPARSERLOG(("trying to parse '%s'", mCursor)); + + Header(); + + // if we didn't consume the entire input, we were unable to parse it => error + if (mError || *mCursor) { + return NS_ERROR_FAILURE; + } else { + return NS_OK; + } +} + +bool nsSecurityHeaderParser::Accept(char aChr) { + if (*mCursor == aChr) { + Advance(); + return true; + } + + return false; +} + +bool nsSecurityHeaderParser::Accept(bool (*aClassifier)(signed char)) { + if (aClassifier(*mCursor)) { + Advance(); + return true; + } + + return false; +} + +void nsSecurityHeaderParser::Expect(char aChr) { + if (*mCursor != aChr) { + mError = true; + } else { + Advance(); + } +} + +void nsSecurityHeaderParser::Advance() { + // Technically, 0 is valid in quoted-pair, but we were handed a + // null-terminated const char *, so this doesn't handle that. + if (*mCursor) { + mOutput.Append(*mCursor); + mCursor++; + } else { + mError = true; + } +} + +void nsSecurityHeaderParser::Header() { + Directive(); + while (Accept(';')) { + Directive(); + } +} + +void nsSecurityHeaderParser::Directive() { + mDirective = new nsSecurityHeaderDirective(); + LWSMultiple(); + DirectiveName(); + LWSMultiple(); + if (Accept('=')) { + LWSMultiple(); + DirectiveValue(); + LWSMultiple(); + } + mDirectives.insertBack(mDirective); + SHPARSERLOG(("read directive name '%s', value '%s'", mDirective->mName.Data(), + mDirective->mValue.Data())); +} + +void nsSecurityHeaderParser::DirectiveName() { + mOutput.Truncate(0); + Token(); + mDirective->mName.Assign(mOutput); +} + +void nsSecurityHeaderParser::DirectiveValue() { + mOutput.Truncate(0); + if (Accept(IsTokenSymbol)) { + Token(); + mDirective->mValue.Assign(mOutput); + } else if (Accept('"')) { + // Accept advances the cursor if successful, which appends a character to + // mOutput. The " is not part of what we want to capture, so truncate + // mOutput again. + mOutput.Truncate(0); + QuotedString(); + mDirective->mValue.Assign(mOutput); + Expect('"'); + } +} + +void nsSecurityHeaderParser::Token() { + while (Accept(IsTokenSymbol)) + ; +} + +void nsSecurityHeaderParser::QuotedString() { + while (true) { + if (Accept(IsQuotedTextSymbol)) { + QuotedText(); + } else if (Accept('\\')) { + QuotedPair(); + } else { + break; + } + } +} + +void nsSecurityHeaderParser::QuotedText() { + while (Accept(IsQuotedTextSymbol)) + ; +} + +void nsSecurityHeaderParser::QuotedPair() { Accept(IsQuotedPairSymbol); } + +void nsSecurityHeaderParser::LWSMultiple() { + while (true) { + if (Accept('\r')) { + LWSCRLF(); + } else if (Accept(' ') || Accept('\t')) { + LWS(); + } else { + break; + } + } +} + +void nsSecurityHeaderParser::LWSCRLF() { + Expect('\n'); + if (!(Accept(' ') || Accept('\t'))) { + mError = true; + } + LWS(); +} + +void nsSecurityHeaderParser::LWS() { + // Note that becaue of how we're called, we don't have to check for + // the mandatory presense of at least one of SP or HT. + while (Accept(' ') || Accept('\t')) + ; +} diff --git a/security/manager/ssl/nsSecurityHeaderParser.h b/security/manager/ssl/nsSecurityHeaderParser.h new file mode 100644 index 0000000000..5cb50d425a --- /dev/null +++ b/security/manager/ssl/nsSecurityHeaderParser.h @@ -0,0 +1,78 @@ +/* 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/. */ + +#ifndef nsSecurityHeaderParser_h +#define nsSecurityHeaderParser_h + +#include "mozilla/LinkedList.h" +#include "nsCOMPtr.h" +#include "nsString.h" + +// Utility class for handing back parsed directives and (optional) values +class nsSecurityHeaderDirective + : public mozilla::LinkedListElement { + public: + nsCString mName; + nsCString mValue; +}; + +// This class parses security-related HTTP headers like +// Strict-Transport-Security. The Augmented Backus-Naur Form syntax for this +// header is reproduced below, for reference: +// +// Strict-Transport-Security = "Strict-Transport-Security" ":" +// [ directive ] *( ";" [ directive ] ) +// +// directive = directive-name [ "=" directive-value ] +// directive-name = token +// directive-value = token | quoted-string +// +// where: +// +// token = +// quoted-string = / +// +// For further reference, see [RFC6797], Section 6.1 + +class nsSecurityHeaderParser { + public: + // The input to this class must be null-terminated, and must have a lifetime + // greater than or equal to the lifetime of the created + // nsSecurityHeaderParser. + explicit nsSecurityHeaderParser(const nsCString& aHeader); + ~nsSecurityHeaderParser(); + + // Only call Parse once. + nsresult Parse(); + // The caller does not take ownership of the memory returned here. + mozilla::LinkedList* GetDirectives(); + + private: + bool Accept(char aChr); + bool Accept(bool (*aClassifier)(signed char)); + void Expect(char aChr); + void Advance(); + void Header(); // header = [ directive ] *( ";" [ directive ] ) + void Directive(); // directive = directive-name [ "=" directive-value ] + void DirectiveName(); // directive-name = token + void DirectiveValue(); // directive-value = token | quoted-string + void Token(); // token = 1* + void QuotedString(); // quoted-string = (<"> *( qdtext | quoted-pair ) <">) + void QuotedText(); // qdtext = and "\"> + void QuotedPair(); // quoted-pair = "\" CHAR + + // LWS = [CRLF] 1*( SP | HT ) + void LWSMultiple(); // Handles *( LWS ) + void LWSCRLF(); // Handles the [CRLF] part of LWS + void LWS(); // Handles the 1*( SP | HT ) part of LWS + + mozilla::LinkedList mDirectives; + const char* mCursor; + nsSecurityHeaderDirective* mDirective; + + nsCString mOutput; + bool mError; +}; + +#endif // nsSecurityHeaderParser_h diff --git a/security/manager/ssl/nsSiteSecurityService.cpp b/security/manager/ssl/nsSiteSecurityService.cpp new file mode 100644 index 0000000000..6f8f327b7f --- /dev/null +++ b/security/manager/ssl/nsSiteSecurityService.cpp @@ -0,0 +1,1195 @@ +/* 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/. */ + +#include "nsSiteSecurityService.h" + +#include "PublicKeyPinningService.h" +#include "mozilla/Assertions.h" +#include "mozilla/Base64.h" +#include "mozilla/LinkedList.h" +#include "mozilla/Logging.h" +#include "mozilla/Preferences.h" +#include "mozilla/Tokenizer.h" +#include "mozilla/dom/PContent.h" +#include "mozilla/dom/ToJSValue.h" +#include "nsArrayEnumerator.h" +#include "nsCOMArray.h" +#include "nsIScriptSecurityManager.h" +#include "nsISocketProvider.h" +#include "nsITransportSecurityInfo.h" +#include "nsIURI.h" +#include "nsNSSComponent.h" +#include "nsNetUtil.h" +#include "nsPromiseFlatString.h" +#include "nsReadableUtils.h" +#include "nsSecurityHeaderParser.h" +#include "nsThreadUtils.h" +#include "nsVariant.h" +#include "nsXULAppAPI.h" +#include "prnetdb.h" + +// A note about the preload list: +// When a site specifically disables HSTS by sending a header with +// 'max-age: 0', we keep a "knockout" value that means "we have no information +// regarding the HSTS state of this host" (any ancestor of "this host" can still +// influence its HSTS status via include subdomains, however). +// This prevents the preload list from overriding the site's current +// desired HSTS status. +#include "nsSTSPreloadListGenerated.inc" + +using namespace mozilla; +using namespace mozilla::psm; + +static LazyLogModule gSSSLog("nsSSService"); + +#define SSSLOG(args) MOZ_LOG(gSSSLog, mozilla::LogLevel::Debug, args) + +const char kHSTSKeySuffix[] = ":HSTS"; + +//////////////////////////////////////////////////////////////////////////////// + +NS_IMPL_ISUPPORTS(SiteHSTSState, nsISiteSecurityState, nsISiteHSTSState) + +namespace { + +class SSSTokenizer final : public Tokenizer { + public: + explicit SSSTokenizer(const nsACString& source) : Tokenizer(source) {} + + [[nodiscard]] bool ReadBool(/*out*/ bool& value) { + uint8_t rawValue; + if (!ReadInteger(&rawValue)) { + return false; + } + + if (rawValue != 0 && rawValue != 1) { + return false; + } + + value = (rawValue == 1); + return true; + } + + [[nodiscard]] bool ReadState(/*out*/ SecurityPropertyState& state) { + uint32_t rawValue; + if (!ReadInteger(&rawValue)) { + return false; + } + + state = static_cast(rawValue); + switch (state) { + case SecurityPropertyKnockout: + case SecurityPropertyNegative: + case SecurityPropertySet: + case SecurityPropertyUnset: + break; + default: + return false; + } + + return true; + } + + [[nodiscard]] bool ReadSource(/*out*/ SecurityPropertySource& source) { + uint32_t rawValue; + if (!ReadInteger(&rawValue)) { + return false; + } + + source = static_cast(rawValue); + switch (source) { + case SourceUnknown: + case SourcePreload: + case SourceOrganic: + break; + default: + return false; + } + + return true; + } +}; + +// Parses a state string like "1500918564034,1,1" into its constituent parts. +bool ParseHSTSState(const nsCString& stateString, + /*out*/ PRTime& expireTime, + /*out*/ SecurityPropertyState& state, + /*out*/ bool& includeSubdomains, + /*out*/ SecurityPropertySource& source) { + SSSTokenizer tokenizer(stateString); + SSSLOG(("Parsing state from %s", stateString.get())); + + if (!tokenizer.ReadInteger(&expireTime)) { + return false; + } + + if (!tokenizer.CheckChar(',')) { + return false; + } + + if (!tokenizer.ReadState(state)) { + return false; + } + + if (!tokenizer.CheckChar(',')) { + return false; + } + + if (!tokenizer.ReadBool(includeSubdomains)) { + return false; + } + + source = SourceUnknown; + if (tokenizer.CheckChar(',')) { + if (!tokenizer.ReadSource(source)) { + return false; + } + } + + return tokenizer.CheckEOF(); +} + +} // namespace + +SiteHSTSState::SiteHSTSState(const nsCString& aHost, + const OriginAttributes& aOriginAttributes, + const nsCString& aStateString) + : mHostname(aHost), + mOriginAttributes(aOriginAttributes), + mHSTSExpireTime(0), + mHSTSState(SecurityPropertyUnset), + mHSTSIncludeSubdomains(false), + mHSTSSource(SourceUnknown) { + bool valid = ParseHSTSState(aStateString, mHSTSExpireTime, mHSTSState, + mHSTSIncludeSubdomains, mHSTSSource); + if (!valid) { + SSSLOG(("%s is not a valid SiteHSTSState", aStateString.get())); + mHSTSExpireTime = 0; + mHSTSState = SecurityPropertyUnset; + mHSTSIncludeSubdomains = false; + mHSTSSource = SourceUnknown; + } +} + +SiteHSTSState::SiteHSTSState(const nsCString& aHost, + const OriginAttributes& aOriginAttributes, + PRTime aHSTSExpireTime, + SecurityPropertyState aHSTSState, + bool aHSTSIncludeSubdomains, + SecurityPropertySource aSource) + + : mHostname(aHost), + mOriginAttributes(aOriginAttributes), + mHSTSExpireTime(aHSTSExpireTime), + mHSTSState(aHSTSState), + mHSTSIncludeSubdomains(aHSTSIncludeSubdomains), + mHSTSSource(aSource) {} + +void SiteHSTSState::ToString(nsCString& aString) { + aString.Truncate(); + aString.AppendInt(mHSTSExpireTime); + aString.Append(','); + aString.AppendInt(mHSTSState); + aString.Append(','); + aString.AppendInt(static_cast(mHSTSIncludeSubdomains)); + aString.Append(','); + aString.AppendInt(mHSTSSource); +} + +NS_IMETHODIMP +SiteHSTSState::GetHostname(nsACString& aHostname) { + aHostname = mHostname; + return NS_OK; +} + +NS_IMETHODIMP +SiteHSTSState::GetExpireTime(int64_t* aExpireTime) { + NS_ENSURE_ARG(aExpireTime); + *aExpireTime = mHSTSExpireTime; + return NS_OK; +} + +NS_IMETHODIMP +SiteHSTSState::GetSecurityPropertyState(int16_t* aSecurityPropertyState) { + NS_ENSURE_ARG(aSecurityPropertyState); + *aSecurityPropertyState = mHSTSState; + return NS_OK; +} + +NS_IMETHODIMP +SiteHSTSState::GetIncludeSubdomains(bool* aIncludeSubdomains) { + NS_ENSURE_ARG(aIncludeSubdomains); + *aIncludeSubdomains = mHSTSIncludeSubdomains; + return NS_OK; +} + +NS_IMETHODIMP +SiteHSTSState::GetOriginAttributes( + JSContext* aCx, JS::MutableHandle aOriginAttributes) { + if (!ToJSValue(aCx, mOriginAttributes, aOriginAttributes)) { + return NS_ERROR_FAILURE; + } + return NS_OK; +} + +const uint64_t kSixtyDaysInSeconds = 60 * 24 * 60 * 60; + +nsSiteSecurityService::nsSiteSecurityService() + : mUsePreloadList(true), mPreloadListTimeOffset(0), mDafsa(kDafsa) {} + +nsSiteSecurityService::~nsSiteSecurityService() = default; + +NS_IMPL_ISUPPORTS(nsSiteSecurityService, nsIObserver, nsISiteSecurityService) + +nsresult nsSiteSecurityService::Init() { + // Don't access Preferences off the main thread. + if (!NS_IsMainThread()) { + MOZ_ASSERT_UNREACHABLE("nsSiteSecurityService initialized off main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + + mUsePreloadList = mozilla::Preferences::GetBool( + "network.stricttransportsecurity.preloadlist", true); + mozilla::Preferences::AddStrongObserver( + this, "network.stricttransportsecurity.preloadlist"); + mPreloadListTimeOffset = + mozilla::Preferences::GetInt("test.currentTimeOffsetSeconds", 0); + mozilla::Preferences::AddStrongObserver(this, + "test.currentTimeOffsetSeconds"); + mSiteStateStorage = + mozilla::DataStorage::Get(DataStorageClass::SiteSecurityServiceState); + mPreloadStateStorage = + mozilla::DataStorage::Get(DataStorageClass::SecurityPreloadState); + nsresult rv = mSiteStateStorage->Init(nullptr); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + rv = mPreloadStateStorage->Init(nullptr); + if (NS_WARN_IF(NS_FAILED(rv))) { + return rv; + } + + return NS_OK; +} + +nsresult nsSiteSecurityService::GetHost(nsIURI* aURI, nsACString& aResult) { + nsCOMPtr innerURI = NS_GetInnermostURI(aURI); + if (!innerURI) { + return NS_ERROR_FAILURE; + } + + nsAutoCString host; + nsresult rv = innerURI->GetAsciiHost(host); + if (NS_FAILED(rv)) { + return rv; + } + + aResult.Assign(PublicKeyPinningService::CanonicalizeHostname(host.get())); + if (aResult.IsEmpty()) { + return NS_ERROR_UNEXPECTED; + } + + return NS_OK; +} + +static void SetStorageKey(const nsACString& hostname, uint32_t aType, + const OriginAttributes& aOriginAttributes, + /*out*/ nsAutoCString& storageKey) { + storageKey = hostname; + + // Don't isolate by userContextId. + OriginAttributes originAttributesNoUserContext = aOriginAttributes; + originAttributesNoUserContext.mUserContextId = + nsIScriptSecurityManager::DEFAULT_USER_CONTEXT_ID; + nsAutoCString originAttributesSuffix; + originAttributesNoUserContext.CreateSuffix(originAttributesSuffix); + storageKey.Append(originAttributesSuffix); + switch (aType) { + case nsISiteSecurityService::HEADER_HSTS: + storageKey.AppendASCII(kHSTSKeySuffix); + break; + default: + MOZ_ASSERT_UNREACHABLE("SSS:SetStorageKey got invalid type"); + } +} + +// Expire times are in millis. Since Headers max-age is in seconds, and +// PR_Now() is in micros, normalize the units at milliseconds. +static int64_t ExpireTimeFromMaxAge(uint64_t maxAge) { + return (PR_Now() / PR_USEC_PER_MSEC) + ((int64_t)maxAge * PR_MSEC_PER_SEC); +} + +nsresult nsSiteSecurityService::SetHSTSState( + uint32_t aType, const char* aHost, int64_t maxage, bool includeSubdomains, + uint32_t flags, SecurityPropertyState aHSTSState, + SecurityPropertySource aSource, const OriginAttributes& aOriginAttributes) { + nsAutoCString hostname(aHost); + bool isPreload = (aSource == SourcePreload); + // If max-age is zero, the host is no longer considered HSTS. If the host was + // preloaded, we store an entry indicating that this host is not HSTS, causing + // the preloaded information to be ignored. + if (maxage == 0) { + return MarkHostAsNotHSTS(aType, hostname, flags, isPreload, + aOriginAttributes); + } + + MOZ_ASSERT( + (aHSTSState == SecurityPropertySet || + aHSTSState == SecurityPropertyNegative), + "HSTS State must be SecurityPropertySet or SecurityPropertyNegative"); + if (isPreload && aOriginAttributes != OriginAttributes()) { + return NS_ERROR_INVALID_ARG; + } + + int64_t expiretime = ExpireTimeFromMaxAge(maxage); + RefPtr siteState = + new SiteHSTSState(hostname, aOriginAttributes, expiretime, aHSTSState, + includeSubdomains, aSource); + nsAutoCString stateString; + siteState->ToString(stateString); + SSSLOG(("SSS: setting state for %s", hostname.get())); + bool isPrivate = flags & nsISocketProvider::NO_PERMANENT_STORAGE; + mozilla::DataStorageType storageType = isPrivate + ? mozilla::DataStorage_Private + : mozilla::DataStorage_Persistent; + nsAutoCString storageKey; + SetStorageKey(hostname, aType, aOriginAttributes, storageKey); + nsresult rv; + if (isPreload) { + SSSLOG(("SSS: storing entry for %s in dynamic preloads", hostname.get())); + rv = mPreloadStateStorage->Put(storageKey, stateString, + mozilla::DataStorage_Persistent); + } else { + SSSLOG(("SSS: storing HSTS site entry for %s", hostname.get())); + nsCString value = mSiteStateStorage->Get(storageKey, storageType); + RefPtr curSiteState = + new SiteHSTSState(hostname, aOriginAttributes, value); + if (curSiteState->mHSTSState != SecurityPropertyUnset && + curSiteState->mHSTSSource != SourceUnknown) { + // don't override the source + siteState->mHSTSSource = curSiteState->mHSTSSource; + siteState->ToString(stateString); + } + rv = mSiteStateStorage->Put(storageKey, stateString, storageType); + } + NS_ENSURE_SUCCESS(rv, rv); + + return NS_OK; +} + +// Helper function to mark a host as not HSTS. In the general case, we can just +// remove the HSTS state. However, for preloaded entries, we have to store an +// entry that indicates this host is not HSTS to prevent the implementation +// using the preloaded information. +nsresult nsSiteSecurityService::MarkHostAsNotHSTS( + uint32_t aType, const nsAutoCString& aHost, uint32_t aFlags, + bool aIsPreload, const OriginAttributes& aOriginAttributes) { + // This only applies to HSTS. + if (aType != nsISiteSecurityService::HEADER_HSTS) { + return NS_ERROR_INVALID_ARG; + } + if (aIsPreload && aOriginAttributes != OriginAttributes()) { + return NS_ERROR_INVALID_ARG; + } + + bool isPrivate = aFlags & nsISocketProvider::NO_PERMANENT_STORAGE; + mozilla::DataStorageType storageType = isPrivate + ? mozilla::DataStorage_Private + : mozilla::DataStorage_Persistent; + nsAutoCString storageKey; + SetStorageKey(aHost, aType, aOriginAttributes, storageKey); + + nsCString value = + mPreloadStateStorage->Get(storageKey, mozilla::DataStorage_Persistent); + RefPtr dynamicState = + new SiteHSTSState(aHost, aOriginAttributes, value); + if (GetPreloadStatus(aHost) || + dynamicState->mHSTSState != SecurityPropertyUnset) { + SSSLOG(("SSS: storing knockout entry for %s", aHost.get())); + RefPtr siteState = + new SiteHSTSState(aHost, aOriginAttributes, 0, SecurityPropertyKnockout, + false, SourceUnknown); + nsAutoCString stateString; + siteState->ToString(stateString); + nsresult rv; + if (aIsPreload) { + rv = mPreloadStateStorage->Put(storageKey, stateString, + mozilla::DataStorage_Persistent); + } else { + rv = mSiteStateStorage->Put(storageKey, stateString, storageType); + } + NS_ENSURE_SUCCESS(rv, rv); + } else { + SSSLOG(("SSS: removing entry for %s", aHost.get())); + if (aIsPreload) { + mPreloadStateStorage->Remove(storageKey, mozilla::DataStorage_Persistent); + } else { + mSiteStateStorage->Remove(storageKey, storageType); + } + } + + return NS_OK; +} + +NS_IMETHODIMP +nsSiteSecurityService::ResetState(uint32_t aType, nsIURI* aURI, uint32_t aFlags, + JS::HandleValue aOriginAttributes, + JSContext* aCx, uint8_t aArgc) { + if (!XRE_IsParentProcess()) { + MOZ_CRASH( + "Child process: no direct access to " + "nsISiteSecurityService::ResetState"); + } + if (!aURI) { + return NS_ERROR_INVALID_ARG; + } + + OriginAttributes originAttributes; + if (aArgc > 0) { + // OriginAttributes were passed in. + if (!aOriginAttributes.isObject() || + !originAttributes.Init(aCx, aOriginAttributes)) { + return NS_ERROR_INVALID_ARG; + } + } + + return ResetStateInternal(aType, aURI, aFlags, originAttributes); +} + +// Helper function to reset stored state of the given type for the host +// identified by the given URI. If there is preloaded information for the host, +// that information will be used for future queries. C.f. MarkHostAsNotHSTS, +// which will store a knockout entry for preloaded HSTS hosts that have sent a +// header with max-age=0 (meaning preloaded information will then not be used +// for that host). +nsresult nsSiteSecurityService::ResetStateInternal( + uint32_t aType, nsIURI* aURI, uint32_t aFlags, + const OriginAttributes& aOriginAttributes) { + if (!aURI) { + return NS_ERROR_INVALID_ARG; + } + if (aType != nsISiteSecurityService::HEADER_HSTS) { + return NS_ERROR_INVALID_ARG; + } + nsAutoCString hostname; + nsresult rv = GetHost(aURI, hostname); + if (NS_FAILED(rv)) { + return rv; + } + nsAutoCString storageKey; + SetStorageKey(hostname, aType, aOriginAttributes, storageKey); + bool isPrivate = aFlags & nsISocketProvider::NO_PERMANENT_STORAGE; + mozilla::DataStorageType storageType = isPrivate + ? mozilla::DataStorage_Private + : mozilla::DataStorage_Persistent; + mSiteStateStorage->Remove(storageKey, storageType); + return NS_OK; +} + +static bool HostIsIPAddress(const nsCString& hostname) { + PRNetAddr hostAddr; + PRErrorCode prv = PR_StringToNetAddr(hostname.get(), &hostAddr); + return (prv == PR_SUCCESS); +} + +NS_IMETHODIMP +nsSiteSecurityService::ProcessHeaderScriptable( + uint32_t aType, nsIURI* aSourceURI, const nsACString& aHeader, + nsITransportSecurityInfo* aSecInfo, uint32_t aFlags, uint32_t aSource, + JS::HandleValue aOriginAttributes, uint64_t* aMaxAge, + bool* aIncludeSubdomains, uint32_t* aFailureResult, JSContext* aCx, + uint8_t aArgc) { + OriginAttributes originAttributes; + if (aArgc > 0) { + if (!aOriginAttributes.isObject() || + !originAttributes.Init(aCx, aOriginAttributes)) { + return NS_ERROR_INVALID_ARG; + } + } + return ProcessHeader(aType, aSourceURI, aHeader, aSecInfo, aFlags, aSource, + originAttributes, aMaxAge, aIncludeSubdomains, + aFailureResult); +} + +NS_IMETHODIMP +nsSiteSecurityService::ProcessHeader( + uint32_t aType, nsIURI* aSourceURI, const nsACString& aHeader, + nsITransportSecurityInfo* aSecInfo, uint32_t aFlags, uint32_t aHeaderSource, + const OriginAttributes& aOriginAttributes, uint64_t* aMaxAge, + bool* aIncludeSubdomains, uint32_t* aFailureResult) { + // Child processes are not allowed direct access to this. + if (!XRE_IsParentProcess()) { + MOZ_CRASH( + "Child process: no direct access to " + "nsISiteSecurityService::ProcessHeader"); + } + + if (aFailureResult) { + *aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN; + } + NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS, + NS_ERROR_NOT_IMPLEMENTED); + SecurityPropertySource source = + static_cast(aHeaderSource); + switch (source) { + case SourceUnknown: + case SourcePreload: + case SourceOrganic: + break; + default: + return NS_ERROR_INVALID_ARG; + } + + NS_ENSURE_ARG(aSecInfo); + return ProcessHeaderInternal(aType, aSourceURI, PromiseFlatCString(aHeader), + aSecInfo, aFlags, source, aOriginAttributes, + aMaxAge, aIncludeSubdomains, aFailureResult); +} + +nsresult nsSiteSecurityService::ProcessHeaderInternal( + uint32_t aType, nsIURI* aSourceURI, const nsCString& aHeader, + nsITransportSecurityInfo* aSecInfo, uint32_t aFlags, + SecurityPropertySource aSource, const OriginAttributes& aOriginAttributes, + uint64_t* aMaxAge, bool* aIncludeSubdomains, uint32_t* aFailureResult) { + if (aFailureResult) { + *aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN; + } + // Only HSTS is supported at the moment. + NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS, + NS_ERROR_NOT_IMPLEMENTED); + + if (aMaxAge != nullptr) { + *aMaxAge = 0; + } + + if (aIncludeSubdomains != nullptr) { + *aIncludeSubdomains = false; + } + + if (aSecInfo) { + bool tlsIsBroken = false; + bool trustcheck; + nsresult rv; + rv = aSecInfo->GetIsDomainMismatch(&trustcheck); + NS_ENSURE_SUCCESS(rv, rv); + tlsIsBroken = tlsIsBroken || trustcheck; + + rv = aSecInfo->GetIsNotValidAtThisTime(&trustcheck); + NS_ENSURE_SUCCESS(rv, rv); + tlsIsBroken = tlsIsBroken || trustcheck; + + rv = aSecInfo->GetIsUntrusted(&trustcheck); + NS_ENSURE_SUCCESS(rv, rv); + tlsIsBroken = tlsIsBroken || trustcheck; + if (tlsIsBroken) { + SSSLOG(("SSS: discarding header from untrustworthy connection")); + if (aFailureResult) { + *aFailureResult = + nsISiteSecurityService::ERROR_UNTRUSTWORTHY_CONNECTION; + } + return NS_ERROR_FAILURE; + } + } + + nsAutoCString host; + nsresult rv = GetHost(aSourceURI, host); + NS_ENSURE_SUCCESS(rv, rv); + if (HostIsIPAddress(host)) { + /* Don't process headers if a site is accessed by IP address. */ + return NS_OK; + } + + switch (aType) { + case nsISiteSecurityService::HEADER_HSTS: + rv = ProcessSTSHeader(aSourceURI, aHeader, aFlags, aSource, + aOriginAttributes, aMaxAge, aIncludeSubdomains, + aFailureResult); + break; + default: + MOZ_CRASH("unexpected header type"); + } + return rv; +} + +static uint32_t ParseSSSHeaders(uint32_t aType, const nsCString& aHeader, + bool& foundIncludeSubdomains, bool& foundMaxAge, + bool& foundUnrecognizedDirective, + uint64_t& maxAge) { + // "Strict-Transport-Security" ":" OWS + // STS-d *( OWS ";" OWS STS-d OWS) + // + // ; STS directive + // STS-d = maxAge / includeSubDomains + // + // maxAge = "max-age" "=" delta-seconds v-ext + // + // includeSubDomains = [ "includeSubDomains" ] + // + // The order of the directives is not significant. + // All directives must appear only once. + // Directive names are case-insensitive. + // The entire header is invalid if a directive not conforming to the + // syntax is encountered. + // Unrecognized directives (that are otherwise syntactically valid) are + // ignored, and the rest of the header is parsed as normal. + + constexpr auto max_age_var = "max-age"_ns; + constexpr auto include_subd_var = "includesubdomains"_ns; + + nsSecurityHeaderParser parser(aHeader); + nsresult rv = parser.Parse(); + if (NS_FAILED(rv)) { + SSSLOG(("SSS: could not parse header")); + return nsISiteSecurityService::ERROR_COULD_NOT_PARSE_HEADER; + } + mozilla::LinkedList* directives = + parser.GetDirectives(); + + for (nsSecurityHeaderDirective* directive = directives->getFirst(); + directive != nullptr; directive = directive->getNext()) { + SSSLOG(("SSS: found directive %s\n", directive->mName.get())); + if (directive->mName.Length() == max_age_var.Length() && + directive->mName.EqualsIgnoreCase(max_age_var.get(), + max_age_var.Length())) { + if (foundMaxAge) { + SSSLOG(("SSS: found two max-age directives")); + return nsISiteSecurityService::ERROR_MULTIPLE_MAX_AGES; + } + + SSSLOG(("SSS: found max-age directive")); + foundMaxAge = true; + + Tokenizer tokenizer(directive->mValue); + if (!tokenizer.ReadInteger(&maxAge)) { + SSSLOG(("SSS: could not parse delta-seconds")); + return nsISiteSecurityService::ERROR_INVALID_MAX_AGE; + } + + if (!tokenizer.CheckEOF()) { + SSSLOG(("SSS: invalid value for max-age directive")); + return nsISiteSecurityService::ERROR_INVALID_MAX_AGE; + } + + SSSLOG(("SSS: parsed delta-seconds: %" PRIu64, maxAge)); + } else if (directive->mName.Length() == include_subd_var.Length() && + directive->mName.EqualsIgnoreCase(include_subd_var.get(), + include_subd_var.Length())) { + if (foundIncludeSubdomains) { + SSSLOG(("SSS: found two includeSubdomains directives")); + return nsISiteSecurityService::ERROR_MULTIPLE_INCLUDE_SUBDOMAINS; + } + + SSSLOG(("SSS: found includeSubdomains directive")); + foundIncludeSubdomains = true; + + if (directive->mValue.Length() != 0) { + SSSLOG(("SSS: includeSubdomains directive unexpectedly had value '%s'", + directive->mValue.get())); + return nsISiteSecurityService::ERROR_INVALID_INCLUDE_SUBDOMAINS; + } + } else { + SSSLOG(("SSS: ignoring unrecognized directive '%s'", + directive->mName.get())); + foundUnrecognizedDirective = true; + } + } + return nsISiteSecurityService::Success; +} + +nsresult nsSiteSecurityService::ProcessSTSHeader( + nsIURI* aSourceURI, const nsCString& aHeader, uint32_t aFlags, + SecurityPropertySource aSource, const OriginAttributes& aOriginAttributes, + uint64_t* aMaxAge, bool* aIncludeSubdomains, uint32_t* aFailureResult) { + if (aFailureResult) { + *aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN; + } + SSSLOG(("SSS: processing HSTS header '%s'", aHeader.get())); + + const uint32_t aType = nsISiteSecurityService::HEADER_HSTS; + bool foundMaxAge = false; + bool foundIncludeSubdomains = false; + bool foundUnrecognizedDirective = false; + uint64_t maxAge = 0; + nsTArray unusedSHA256keys; // Required for sane internal interface + + uint32_t sssrv = + ParseSSSHeaders(aType, aHeader, foundIncludeSubdomains, foundMaxAge, + foundUnrecognizedDirective, maxAge); + if (sssrv != nsISiteSecurityService::Success) { + if (aFailureResult) { + *aFailureResult = sssrv; + } + return NS_ERROR_FAILURE; + } + + // after processing all the directives, make sure we came across max-age + // somewhere. + if (!foundMaxAge) { + SSSLOG(("SSS: did not encounter required max-age directive")); + if (aFailureResult) { + *aFailureResult = nsISiteSecurityService::ERROR_NO_MAX_AGE; + } + return NS_ERROR_FAILURE; + } + + nsAutoCString hostname; + nsresult rv = GetHost(aSourceURI, hostname); + NS_ENSURE_SUCCESS(rv, rv); + + // record the successfully parsed header data. + rv = SetHSTSState(aType, hostname.get(), maxAge, foundIncludeSubdomains, + aFlags, SecurityPropertySet, aSource, aOriginAttributes); + if (NS_FAILED(rv)) { + SSSLOG(("SSS: failed to set STS state")); + if (aFailureResult) { + *aFailureResult = nsISiteSecurityService::ERROR_COULD_NOT_SAVE_STATE; + } + return rv; + } + + if (aMaxAge != nullptr) { + *aMaxAge = maxAge; + } + + if (aIncludeSubdomains != nullptr) { + *aIncludeSubdomains = foundIncludeSubdomains; + } + + return foundUnrecognizedDirective ? NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA + : NS_OK; +} + +NS_IMETHODIMP +nsSiteSecurityService::IsSecureURIScriptable(uint32_t aType, nsIURI* aURI, + uint32_t aFlags, + JS::HandleValue aOriginAttributes, + bool* aCached, uint32_t* aSource, + JSContext* aCx, uint8_t aArgc, + bool* aResult) { + OriginAttributes originAttributes; + if (aArgc > 0) { + if (!aOriginAttributes.isObject() || + !originAttributes.Init(aCx, aOriginAttributes)) { + return NS_ERROR_INVALID_ARG; + } + } + return IsSecureURI(aType, aURI, aFlags, originAttributes, aCached, aSource, + aResult); +} + +NS_IMETHODIMP +nsSiteSecurityService::IsSecureURI(uint32_t aType, nsIURI* aURI, + uint32_t aFlags, + const OriginAttributes& aOriginAttributes, + bool* aCached, uint32_t* aSource, + bool* aResult) { + // Child processes are not allowed direct access to this. + if (!XRE_IsParentProcess() && aType != nsISiteSecurityService::HEADER_HSTS) { + MOZ_CRASH( + "Child process: no direct access to " + "nsISiteSecurityService::IsSecureURI for non-HSTS entries"); + } + + NS_ENSURE_ARG(aURI); + NS_ENSURE_ARG(aResult); + + // Only HSTS and static pinning are supported. + NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS || + aType == nsISiteSecurityService::STATIC_PINNING, + NS_ERROR_NOT_IMPLEMENTED); + + nsAutoCString hostname; + nsresult rv = GetHost(aURI, hostname); + NS_ENSURE_SUCCESS(rv, rv); + /* An IP address never qualifies as a secure URI. */ + if (HostIsIPAddress(hostname)) { + *aResult = false; + return NS_OK; + } + + SecurityPropertySource* source = + BitwiseCast(aSource); + + return IsSecureHost(aType, hostname, aFlags, aOriginAttributes, aCached, + source, aResult); +} + +// Checks if the given host is in the preload list. +// +// @param aHost The host to match. Only does exact host matching. +// @param aIncludeSubdomains Out, optional. Indicates whether or not to include +// subdomains. Only set if the host is matched and this function returns +// true. +// +// @return True if the host is matched, false otherwise. +bool nsSiteSecurityService::GetPreloadStatus(const nsACString& aHost, + bool* aIncludeSubdomains) const { + const int kIncludeSubdomains = 1; + bool found = false; + + PRTime currentTime = PR_Now() + (mPreloadListTimeOffset * PR_USEC_PER_SEC); + if (mUsePreloadList && currentTime < gPreloadListExpirationTime) { + int result = mDafsa.Lookup(aHost); + found = (result != mozilla::Dafsa::kKeyNotFound); + if (found && aIncludeSubdomains) { + *aIncludeSubdomains = (result == kIncludeSubdomains); + } + } + + return found; +} + +// Allows us to determine if we have an HSTS entry for a given host (and, if +// so, what that state is). The return value says whether or not we know +// anything about this host (true if the host has an HSTS entry). aHost is +// the host which we wish to deteming HSTS information on, +// aRequireIncludeSubdomains specifies whether we require includeSubdomains +// to be set on the entry (with the other parameters being as per IsSecureHost). +bool nsSiteSecurityService::HostHasHSTSEntry( + const nsAutoCString& aHost, bool aRequireIncludeSubdomains, uint32_t aFlags, + const OriginAttributes& aOriginAttributes, bool* aResult, bool* aCached, + SecurityPropertySource* aSource) { + if (aSource) { + *aSource = SourceUnknown; + } + if (aCached) { + *aCached = false; + } + // First we check for an entry in site security storage. If that entry exists, + // we don't want to check in the preload lists. We only want to use the + // stored value if it is not a knockout entry, however. + // Additionally, if it is a knockout entry, we want to stop looking for data + // on the host, because the knockout entry indicates "we have no information + // regarding the security status of this host". + bool isPrivate = aFlags & nsISocketProvider::NO_PERMANENT_STORAGE; + mozilla::DataStorageType storageType = isPrivate + ? mozilla::DataStorage_Private + : mozilla::DataStorage_Persistent; + nsAutoCString storageKey; + SSSLOG(("Seeking HSTS entry for %s", aHost.get())); + SetStorageKey(aHost, nsISiteSecurityService::HEADER_HSTS, aOriginAttributes, + storageKey); + nsAutoCString preloadKey; + SetStorageKey(aHost, nsISiteSecurityService::HEADER_HSTS, OriginAttributes(), + preloadKey); + nsCString value = mSiteStateStorage->Get(storageKey, storageType); + RefPtr siteState = + new SiteHSTSState(aHost, aOriginAttributes, value); + if (siteState->mHSTSState != SecurityPropertyUnset) { + SSSLOG(("Found HSTS entry for %s", aHost.get())); + bool expired = siteState->IsExpired(nsISiteSecurityService::HEADER_HSTS); + if (!expired) { + SSSLOG(("Entry for %s is not expired", aHost.get())); + if (siteState->mHSTSState == SecurityPropertySet) { + *aResult = aRequireIncludeSubdomains ? siteState->mHSTSIncludeSubdomains + : true; + if (aCached) { + // Only set cached if this includes subdomains + *aCached = aRequireIncludeSubdomains + ? siteState->mHSTSIncludeSubdomains + : true; + } + if (aSource) { + *aSource = siteState->mHSTSSource; + } + return true; + } else if (siteState->mHSTSState == SecurityPropertyNegative) { + *aResult = false; + if (aCached) { + // if it's negative, it is always cached + SSSLOG(("Marking HSTS as as cached (SecurityPropertyNegative)")); + *aCached = true; + } + if (aSource) { + *aSource = siteState->mHSTSSource; + } + return true; + } + } + + if (expired) { + SSSLOG(("Entry %s is expired - checking for preload state", aHost.get())); + // If the entry is expired and is not in either the static or dynamic + // preload lists, we can remove it. + // First, check the dynamic preload list. + value = mPreloadStateStorage->Get(preloadKey, + mozilla::DataStorage_Persistent); + RefPtr dynamicState = + new SiteHSTSState(aHost, aOriginAttributes, value); + if (dynamicState->mHSTSState == SecurityPropertyUnset) { + SSSLOG(("No dynamic preload - checking for static preload")); + // Now check the static preload list. + if (!GetPreloadStatus(aHost)) { + SSSLOG(("No static preload - removing expired entry")); + mSiteStateStorage->Remove(storageKey, storageType); + } + } + } + return false; + } + + // Next, look in the dynamic preload list. + value = + mPreloadStateStorage->Get(preloadKey, mozilla::DataStorage_Persistent); + RefPtr dynamicState = + new SiteHSTSState(aHost, aOriginAttributes, value); + if (dynamicState->mHSTSState != SecurityPropertyUnset) { + SSSLOG(("Found dynamic preload entry for %s", aHost.get())); + bool expired = dynamicState->IsExpired(nsISiteSecurityService::HEADER_HSTS); + if (!expired) { + if (dynamicState->mHSTSState == SecurityPropertySet) { + *aResult = aRequireIncludeSubdomains + ? dynamicState->mHSTSIncludeSubdomains + : true; + if (aCached) { + // Only set cached if this includes subdomains + *aCached = aRequireIncludeSubdomains + ? dynamicState->mHSTSIncludeSubdomains + : true; + } + if (aSource) { + *aSource = dynamicState->mHSTSSource; + } + return true; + } else if (dynamicState->mHSTSState == SecurityPropertyNegative) { + *aResult = false; + if (aCached) { + // if it's negative, it is always cached + *aCached = true; + } + if (aSource) { + *aSource = dynamicState->mHSTSSource; + } + return true; + } + } else { + // if a dynamic preload has expired and is not in the static preload + // list, we can remove it. + if (!GetPreloadStatus(aHost)) { + mPreloadStateStorage->Remove(preloadKey, + mozilla::DataStorage_Persistent); + } + } + return false; + } + + bool includeSubdomains = false; + + // Finally look in the static preload list. + if (siteState->mHSTSState == SecurityPropertyUnset && + dynamicState->mHSTSState == SecurityPropertyUnset && + GetPreloadStatus(aHost, &includeSubdomains)) { + SSSLOG(("%s is a preloaded HSTS host", aHost.get())); + *aResult = aRequireIncludeSubdomains ? includeSubdomains : true; + if (aCached) { + // Only set cached if this includes subdomains + *aCached = aRequireIncludeSubdomains ? includeSubdomains : true; + } + if (aSource) { + *aSource = SourcePreload; + } + return true; + } + + return false; +} + +nsresult nsSiteSecurityService::IsSecureHost( + uint32_t aType, const nsACString& aHost, uint32_t aFlags, + const OriginAttributes& aOriginAttributes, bool* aCached, + SecurityPropertySource* aSource, bool* aResult) { + // Child processes are not allowed direct access to this. + if (!XRE_IsParentProcess() && aType != nsISiteSecurityService::HEADER_HSTS) { + MOZ_CRASH( + "Child process: no direct access to " + "nsISiteSecurityService::IsSecureHost for non-HSTS entries"); + } + + NS_ENSURE_ARG(aResult); + + // Only HSTS and static pinning are supported. + NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS || + aType == nsISiteSecurityService::STATIC_PINNING, + NS_ERROR_NOT_IMPLEMENTED); + + // set default in case if we can't find any STS information + *aResult = false; + + /* An IP address never qualifies as a secure URI. */ + const nsCString& flatHost = PromiseFlatCString(aHost); + if (HostIsIPAddress(flatHost)) { + return NS_OK; + } + + if (aType == nsISiteSecurityService::STATIC_PINNING) { + RefPtr certVerifier(GetDefaultCertVerifier()); + if (!certVerifier) { + return NS_ERROR_FAILURE; + } + if (certVerifier->mPinningMode == + CertVerifier::PinningMode::pinningDisabled) { + return NS_OK; + } + bool enforceTestMode = certVerifier->mPinningMode == + CertVerifier::PinningMode::pinningEnforceTestMode; + return PublicKeyPinningService::HostHasPins( + flatHost.get(), mozilla::pkix::Now(), enforceTestMode, + aOriginAttributes, *aResult); + } + + nsAutoCString host( + PublicKeyPinningService::CanonicalizeHostname(flatHost.get())); + + // First check the exact host. + if (HostHasHSTSEntry(host, false, aFlags, aOriginAttributes, aResult, aCached, + aSource)) { + return NS_OK; + } + + SSSLOG(("no HSTS data for %s found, walking up domain", host.get())); + const char* subdomain; + + uint32_t offset = 0; + for (offset = host.FindChar('.', offset) + 1; offset > 0; + offset = host.FindChar('.', offset) + 1) { + subdomain = host.get() + offset; + + // If we get an empty string, don't continue. + if (strlen(subdomain) < 1) { + break; + } + + // Do the same thing as with the exact host except now we're looking at + // ancestor domains of the original host and, therefore, we have to require + // that the entry includes subdomains. + nsAutoCString subdomainString(subdomain); + + if (HostHasHSTSEntry(subdomainString, true, aFlags, aOriginAttributes, + aResult, aCached, aSource)) { + break; + } + + SSSLOG(("no HSTS data for %s found, walking up domain", subdomain)); + } + + // Use whatever we ended up with, which defaults to false. + return NS_OK; +} + +NS_IMETHODIMP +nsSiteSecurityService::ClearAll() { + // Child processes are not allowed direct access to this. + if (!XRE_IsParentProcess()) { + MOZ_CRASH( + "Child process: no direct access to nsISiteSecurityService::ClearAll"); + } + + return mSiteStateStorage->Clear(); +} + +NS_IMETHODIMP +nsSiteSecurityService::ClearPreloads() { + // Child processes are not allowed direct access to this. + if (!XRE_IsParentProcess()) { + MOZ_CRASH( + "Child process: no direct access to " + "nsISiteSecurityService::ClearPreloads"); + } + + return mPreloadStateStorage->Clear(); +} + +NS_IMETHODIMP +nsSiteSecurityService::SetHSTSPreload(const nsACString& aHost, + bool aIncludeSubdomains, int64_t aExpires, + /*out*/ bool* aResult) { + // Child processes are not allowed direct access to this. + if (!XRE_IsParentProcess()) { + MOZ_CRASH( + "Child process: no direct access to " + "nsISiteSecurityService::SetHSTSPreload"); + } + + NS_ENSURE_ARG_POINTER(aResult); + + SSSLOG(("Top of SetHSTSPreload")); + + const nsCString& flatHost = PromiseFlatCString(aHost); + nsAutoCString host( + PublicKeyPinningService::CanonicalizeHostname(flatHost.get())); + return SetHSTSState(nsISiteSecurityService::HEADER_HSTS, host.get(), aExpires, + aIncludeSubdomains, 0, SecurityPropertySet, SourcePreload, + OriginAttributes()); +} + +NS_IMETHODIMP +nsSiteSecurityService::Enumerate(uint32_t aType, + nsISimpleEnumerator** aEnumerator) { + NS_ENSURE_ARG(aEnumerator); + + nsAutoCString keySuffix; + switch (aType) { + case nsISiteSecurityService::HEADER_HSTS: + keySuffix.AssignASCII(kHSTSKeySuffix); + break; + default: + return NS_ERROR_INVALID_ARG; + } + + nsTArray items; + mSiteStateStorage->GetAll(&items); + + nsCOMArray states; + for (const mozilla::psm::DataStorageItem& item : items) { + if (!StringEndsWith(item.key(), keySuffix)) { + // The key does not end with correct suffix, so is not the type we want. + continue; + } + + nsCString origin( + StringHead(item.key(), item.key().Length() - keySuffix.Length())); + nsAutoCString hostname; + OriginAttributes originAttributes; + if (!originAttributes.PopulateFromOrigin(origin, hostname)) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr state; + switch (aType) { + case nsISiteSecurityService::HEADER_HSTS: + state = new SiteHSTSState(hostname, originAttributes, item.value()); + break; + default: + MOZ_ASSERT_UNREACHABLE("SSS:Enumerate got invalid type"); + } + + states.AppendObject(state); + } + + NS_NewArrayEnumerator(aEnumerator, states, NS_GET_IID(nsISiteSecurityState)); + return NS_OK; +} + +//------------------------------------------------------------ +// nsSiteSecurityService::nsIObserver +//------------------------------------------------------------ + +NS_IMETHODIMP +nsSiteSecurityService::Observe(nsISupports* /*subject*/, const char* topic, + const char16_t* /*data*/) { + // Don't access Preferences off the main thread. + if (!NS_IsMainThread()) { + MOZ_ASSERT_UNREACHABLE("Preferences accessed off main thread"); + return NS_ERROR_NOT_SAME_THREAD; + } + + if (strcmp(topic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { + mUsePreloadList = mozilla::Preferences::GetBool( + "network.stricttransportsecurity.preloadlist", true); + mPreloadListTimeOffset = + mozilla::Preferences::GetInt("test.currentTimeOffsetSeconds", 0); + } + + return NS_OK; +} diff --git a/security/manager/ssl/nsSiteSecurityService.h b/security/manager/ssl/nsSiteSecurityService.h new file mode 100644 index 0000000000..00256b6cf3 --- /dev/null +++ b/security/manager/ssl/nsSiteSecurityService.h @@ -0,0 +1,165 @@ +/* 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/. */ + +#ifndef __nsSiteSecurityService_h__ +#define __nsSiteSecurityService_h__ + +#include "mozilla/BasePrincipal.h" +#include "mozilla/Dafsa.h" +#include "mozilla/DataStorage.h" +#include "mozilla/RefPtr.h" +#include "nsCOMPtr.h" +#include "nsIObserver.h" +#include "nsISiteSecurityService.h" +#include "nsString.h" +#include "nsTArray.h" +#include "mozpkix/pkixtypes.h" +#include "prtime.h" + +class nsIURI; +class nsITransportSecurityInfo; + +using mozilla::OriginAttributes; + +// {16955eee-6c48-4152-9309-c42a465138a1} +#define NS_SITE_SECURITY_SERVICE_CID \ + { \ + 0x16955eee, 0x6c48, 0x4152, { \ + 0x93, 0x09, 0xc4, 0x2a, 0x46, 0x51, 0x38, 0xa1 \ + } \ + } + +/** + * SecurityPropertyState: A utility enum for representing the different states + * a security property can be in. + * SecurityPropertySet and SecurityPropertyUnset correspond to indicating + * a site has or does not have the security property in question, respectively. + * SecurityPropertyKnockout indicates a value on a preloaded list is being + * overridden, and the associated site does not have the security property + * in question. + */ +enum SecurityPropertyState { + SecurityPropertyUnset = nsISiteSecurityState::SECURITY_PROPERTY_UNSET, + SecurityPropertySet = nsISiteSecurityState::SECURITY_PROPERTY_SET, + SecurityPropertyKnockout = nsISiteSecurityState::SECURITY_PROPERTY_KNOCKOUT, + SecurityPropertyNegative = nsISiteSecurityState::SECURITY_PROPERTY_NEGATIVE, +}; + +enum SecurityPropertySource { + SourceUnknown = nsISiteSecurityService::SOURCE_UNKNOWN, + SourcePreload = nsISiteSecurityService::SOURCE_PRELOAD_LIST, + SourceOrganic = nsISiteSecurityService::SOURCE_ORGANIC_REQUEST, +}; + +/** + * SiteHSTSState: A utility class that encodes/decodes a string describing + * the security state of a site. Currently only handles HSTS. + * HSTS state consists of: + * - Hostname (nsCString) + * - Origin attributes (OriginAttributes) + * - Expiry time (PRTime (aka int64_t) in milliseconds) + * - A state flag (SecurityPropertyState, default SecurityPropertyUnset) + * - An include subdomains flag (bool, default false) + */ +class SiteHSTSState : public nsISiteHSTSState { + public: + NS_DECL_ISUPPORTS + NS_DECL_NSISITEHSTSSTATE + NS_DECL_NSISITESECURITYSTATE + + SiteHSTSState(const nsCString& aHost, + const OriginAttributes& aOriginAttributes, + const nsCString& aStateString); + SiteHSTSState(const nsCString& aHost, + const OriginAttributes& aOriginAttributes, + PRTime aHSTSExpireTime, SecurityPropertyState aHSTSState, + bool aHSTSIncludeSubdomains, SecurityPropertySource aSource); + + nsCString mHostname; + OriginAttributes mOriginAttributes; + PRTime mHSTSExpireTime; + SecurityPropertyState mHSTSState; + bool mHSTSIncludeSubdomains; + SecurityPropertySource mHSTSSource; + + bool IsExpired(uint32_t aType) { + // If mHSTSExpireTime is 0, this entry never expires (this is the case for + // knockout entries). + if (mHSTSExpireTime == 0) { + return false; + } + + PRTime now = PR_Now() / PR_USEC_PER_MSEC; + if (now > mHSTSExpireTime) { + return true; + } + + return false; + } + + void ToString(nsCString& aString); + + protected: + virtual ~SiteHSTSState() = default; +}; + +struct nsSTSPreload; + +class nsSiteSecurityService : public nsISiteSecurityService, + public nsIObserver { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSIOBSERVER + NS_DECL_NSISITESECURITYSERVICE + + nsSiteSecurityService(); + nsresult Init(); + + protected: + virtual ~nsSiteSecurityService(); + + private: + nsresult GetHost(nsIURI* aURI, nsACString& aResult); + nsresult SetHSTSState(uint32_t aType, const char* aHost, int64_t maxage, + bool includeSubdomains, uint32_t flags, + SecurityPropertyState aHSTSState, + SecurityPropertySource aSource, + const OriginAttributes& aOriginAttributes); + nsresult ProcessHeaderInternal( + uint32_t aType, nsIURI* aSourceURI, const nsCString& aHeader, + nsITransportSecurityInfo* aSecInfo, uint32_t aFlags, + SecurityPropertySource aSource, const OriginAttributes& aOriginAttributes, + uint64_t* aMaxAge, bool* aIncludeSubdomains, uint32_t* aFailureResult); + nsresult ProcessSTSHeader(nsIURI* aSourceURI, const nsCString& aHeader, + uint32_t flags, SecurityPropertySource aSource, + const OriginAttributes& aOriginAttributes, + uint64_t* aMaxAge, bool* aIncludeSubdomains, + uint32_t* aFailureResult); + nsresult MarkHostAsNotHSTS(uint32_t aType, const nsAutoCString& aHost, + uint32_t aFlags, bool aIsPreload, + const OriginAttributes& aOriginAttributes); + nsresult ResetStateInternal(uint32_t aType, nsIURI* aURI, uint32_t aFlags, + const OriginAttributes& aOriginAttributes); + bool HostHasHSTSEntry(const nsAutoCString& aHost, + bool aRequireIncludeSubdomains, uint32_t aFlags, + const OriginAttributes& aOriginAttributes, + bool* aResult, bool* aCached, + SecurityPropertySource* aSource); + bool GetPreloadStatus( + const nsACString& aHost, + /*optional out*/ bool* aIncludeSubdomains = nullptr) const; + nsresult IsSecureHost(uint32_t aType, const nsACString& aHost, + uint32_t aFlags, + const OriginAttributes& aOriginAttributes, + bool* aCached, SecurityPropertySource* aSource, + bool* aResult); + + bool mUsePreloadList; + int64_t mPreloadListTimeOffset; + RefPtr mSiteStateStorage; + RefPtr mPreloadStateStorage; + const mozilla::Dafsa mDafsa; +}; + +#endif // __nsSiteSecurityService_h__ diff --git a/security/manager/ssl/nsTLSSocketProvider.cpp b/security/manager/ssl/nsTLSSocketProvider.cpp new file mode 100644 index 0000000000..0ce5c534ff --- /dev/null +++ b/security/manager/ssl/nsTLSSocketProvider.cpp @@ -0,0 +1,47 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#include "mozilla/BasePrincipal.h" +#include "nsTLSSocketProvider.h" +#include "nsNSSIOLayer.h" +#include "nsError.h" + +using mozilla::OriginAttributes; + +nsTLSSocketProvider::nsTLSSocketProvider() = default; + +nsTLSSocketProvider::~nsTLSSocketProvider() = default; + +NS_IMPL_ISUPPORTS(nsTLSSocketProvider, nsISocketProvider) + +NS_IMETHODIMP +nsTLSSocketProvider::NewSocket(int32_t family, const char* host, int32_t port, + nsIProxyInfo* proxy, + const OriginAttributes& originAttributes, + uint32_t flags, uint32_t tlsFlags, + PRFileDesc** _result, + nsISupports** securityInfo) { + nsresult rv = + nsSSLIOLayerNewSocket(family, host, port, proxy, originAttributes, + _result, securityInfo, true, flags, tlsFlags); + + return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK; +} + +// Add the SSL IO layer to an existing socket +NS_IMETHODIMP +nsTLSSocketProvider::AddToSocket(int32_t family, const char* host, int32_t port, + nsIProxyInfo* proxy, + const OriginAttributes& originAttributes, + uint32_t flags, uint32_t tlsFlags, + PRFileDesc* aSocket, + nsISupports** securityInfo) { + nsresult rv = + nsSSLIOLayerAddToSocket(family, host, port, proxy, originAttributes, + aSocket, securityInfo, true, flags, tlsFlags); + + return (NS_FAILED(rv)) ? NS_ERROR_SOCKET_CREATE_FAILED : NS_OK; +} diff --git a/security/manager/ssl/nsTLSSocketProvider.h b/security/manager/ssl/nsTLSSocketProvider.h new file mode 100644 index 0000000000..eeed0ae40c --- /dev/null +++ b/security/manager/ssl/nsTLSSocketProvider.h @@ -0,0 +1,31 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef _NSTLSSOCKETPROVIDER_H_ +#define _NSTLSSOCKETPROVIDER_H_ + +#include "nsISocketProvider.h" + +#define NS_STARTTLSSOCKETPROVIDER_CID \ + { /* b9507aec-1dd1-11b2-8cd5-c48ee0c50307 */ \ + 0xb9507aec, 0x1dd1, 0x11b2, { \ + 0x8c, 0xd5, 0xc4, 0x8e, 0xe0, 0xc5, 0x03, 0x07 \ + } \ + } + +class nsTLSSocketProvider : public nsISocketProvider { + public: + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSISOCKETPROVIDER + + // nsTLSSocketProvider methods: + nsTLSSocketProvider(); + + protected: + virtual ~nsTLSSocketProvider(); +}; + +#endif /* _NSTLSSOCKETPROVIDER_H_ */ diff --git a/security/manager/ssl/nsVerificationJob.h b/security/manager/ssl/nsVerificationJob.h new file mode 100644 index 0000000000..377cfabb73 --- /dev/null +++ b/security/manager/ssl/nsVerificationJob.h @@ -0,0 +1,48 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- + * + * 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/. */ + +#ifndef _INC_NSVERIFICATIONJOB_H +#define _INC_NSVERIFICATIONJOB_H + +#include "nspr.h" + +#include "nsIX509Cert.h" +#include "nsProxyRelease.h" + +class nsBaseVerificationJob { + public: + virtual ~nsBaseVerificationJob() {} + virtual void Run() = 0; +}; + +class nsCertVerificationJob : public nsBaseVerificationJob { + public: + nsCOMPtr mCert; + nsMainThreadPtrHandle mListener; + + void Run(); +}; + +class nsCertVerificationResult : public nsICertVerificationResult { + public: + nsCertVerificationResult(); + + NS_DECL_THREADSAFE_ISUPPORTS + NS_DECL_NSICERTVERIFICATIONRESULT + + protected: + virtual ~nsCertVerificationResult(); + + private: + nsresult mRV; + uint32_t mVerified; + uint32_t mCount; + char16_t** mUsages; + + friend class nsCertVerificationJob; +}; + +#endif diff --git a/security/manager/ssl/osclientcerts/Cargo.toml b/security/manager/ssl/osclientcerts/Cargo.toml new file mode 100644 index 0000000000..bb3dd58c07 --- /dev/null +++ b/security/manager/ssl/osclientcerts/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "osclientcerts-static" +version = "0.1.4" +authors = ["Dana Keeler "] +edition = "2018" +description = "Platform-specific support for client authentication certificates in Firefox" +repository = "https://github.com/mozkeeler/osclientcerts" +license = "MPL-2.0" + +[dependencies] +byteorder = "1.3" +env_logger = {version = "0.8", default-features = false } # disable `regex` to reduce code size +lazy_static = "1" +log = "0.4" +pkcs11 = "0.4" +sha2 = "0.8" + +[target."cfg(target_os = \"macos\")".dependencies.core-foundation] +version = "0.9" + +[target."cfg(target_os = \"macos\")".dependencies.libloading] +version = "0.5" + +[target."cfg(target_os = \"macos\")".dependencies.rental] +version = "0.5" + +[target."cfg(target_os = \"windows\")".dependencies.winapi] +version = "0.3" +features = ["wincrypt"] + +[lib] +crate-type = ["staticlib"] diff --git a/security/manager/ssl/osclientcerts/dynamic-library/moz.build b/security/manager/ssl/osclientcerts/dynamic-library/moz.build new file mode 100644 index 0000000000..e68546c8c6 --- /dev/null +++ b/security/manager/ssl/osclientcerts/dynamic-library/moz.build @@ -0,0 +1,30 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +USE_LIBS += ["osclientcerts-static"] + +UNIFIED_SOURCES += [ + "stub.cpp", +] + +if CONFIG["OS_ARCH"] == "WINNT": + OS_LIBS += [ + "crypt32", + "kernel32", + "ncrypt", + "userenv", + "ws2_32", + ] + +if CONFIG["OS_ARCH"] == "Darwin": + OS_LIBS += [ + "-framework Security", + ] + +SharedLibrary("osclientcerts") + +NoVisibilityFlags() +SYMBOLS_FILE = "osclientcerts.symbols" diff --git a/security/manager/ssl/osclientcerts/dynamic-library/osclientcerts.symbols b/security/manager/ssl/osclientcerts/dynamic-library/osclientcerts.symbols new file mode 100644 index 0000000000..562ecea21d --- /dev/null +++ b/security/manager/ssl/osclientcerts/dynamic-library/osclientcerts.symbols @@ -0,0 +1 @@ +C_GetFunctionList diff --git a/security/manager/ssl/osclientcerts/dynamic-library/stub.cpp b/security/manager/ssl/osclientcerts/dynamic-library/stub.cpp new file mode 100644 index 0000000000..bd20c15c4f --- /dev/null +++ b/security/manager/ssl/osclientcerts/dynamic-library/stub.cpp @@ -0,0 +1,8 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +// This is an intentionally empty file. It is necessary for the build system to +// successfully convert a static rust library into a dynamic library on +// Windows. diff --git a/security/manager/ssl/osclientcerts/moz.build b/security/manager/ssl/osclientcerts/moz.build new file mode 100644 index 0000000000..fa484af6a4 --- /dev/null +++ b/security/manager/ssl/osclientcerts/moz.build @@ -0,0 +1,9 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +DIRS += ["dynamic-library"] + +RustLibrary("osclientcerts-static") diff --git a/security/manager/ssl/osclientcerts/src/backend_macos.rs b/security/manager/ssl/osclientcerts/src/backend_macos.rs new file mode 100644 index 0000000000..9d1f1a6b72 --- /dev/null +++ b/security/manager/ssl/osclientcerts/src/backend_macos.rs @@ -0,0 +1,967 @@ +/* -*- Mode: rust; rust-indent-offset: 4 -*- */ +/* 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/. */ + +#![allow(non_upper_case_globals)] + +use libloading::{Library, Symbol}; +use pkcs11::types::*; +use sha2::{Digest, Sha256}; +use std::collections::BTreeMap; +use std::convert::TryInto; +use std::os::raw::c_void; + +use core_foundation::array::*; +use core_foundation::base::*; +use core_foundation::boolean::*; +use core_foundation::data::*; +use core_foundation::dictionary::*; +use core_foundation::error::*; +use core_foundation::number::*; +use core_foundation::string::*; + +// Normally we would generate this with a build script, but macos is +// cross-compiled on linux, and we'd have to figure out e.g. include paths, +// etc.. This is easier. +include!("bindings_macos.rs"); + +use crate::manager::SlotType; +use crate::util::*; + +#[repr(C)] +pub struct __SecIdentity(c_void); +pub type SecIdentityRef = *const __SecIdentity; +declare_TCFType!(SecIdentity, SecIdentityRef); +impl_TCFType!(SecIdentity, SecIdentityRef, SecIdentityGetTypeID); + +#[repr(C)] +pub struct __SecCertificate(c_void); +pub type SecCertificateRef = *const __SecCertificate; +declare_TCFType!(SecCertificate, SecCertificateRef); +impl_TCFType!(SecCertificate, SecCertificateRef, SecCertificateGetTypeID); + +#[repr(C)] +pub struct __SecKey(c_void); +pub type SecKeyRef = *const __SecKey; +declare_TCFType!(SecKey, SecKeyRef); +impl_TCFType!(SecKey, SecKeyRef, SecKeyGetTypeID); + +#[repr(C)] +pub struct __SecPolicy(c_void); +pub type SecPolicyRef = *const __SecPolicy; +declare_TCFType!(SecPolicy, SecPolicyRef); +impl_TCFType!(SecPolicy, SecPolicyRef, SecPolicyGetTypeID); + +#[repr(C)] +pub struct __SecTrust(c_void); +pub type SecTrustRef = *const __SecTrust; +declare_TCFType!(SecTrust, SecTrustRef); +impl_TCFType!(SecTrust, SecTrustRef, SecTrustGetTypeID); + +type SecKeyCreateSignatureType = + unsafe extern "C" fn(SecKeyRef, SecKeyAlgorithm, CFDataRef, *mut CFErrorRef) -> CFDataRef; +type SecKeyCopyAttributesType = unsafe extern "C" fn(SecKeyRef) -> CFDictionaryRef; +type SecKeyCopyExternalRepresentationType = + unsafe extern "C" fn(SecKeyRef, *mut CFErrorRef) -> CFDataRef; +type SecCertificateCopyNormalizedIssuerSequenceType = + unsafe extern "C" fn(SecCertificateRef) -> CFDataRef; +type SecCertificateCopyNormalizedSubjectSequenceType = + unsafe extern "C" fn(SecCertificateRef) -> CFDataRef; +type SecCertificateCopyKeyType = unsafe extern "C" fn(SecCertificateRef) -> SecKeyRef; +type SecTrustEvaluateWithErrorType = + unsafe extern "C" fn(trust: SecTrustRef, error: *mut CFErrorRef) -> bool; + +#[derive(Ord, Eq, PartialOrd, PartialEq)] +enum SecStringConstant { + // These are available in macOS 10.12 + SecKeyAlgorithmECDSASignatureDigestX962SHA1, + SecKeyAlgorithmECDSASignatureDigestX962SHA256, + SecKeyAlgorithmECDSASignatureDigestX962SHA384, + SecKeyAlgorithmECDSASignatureDigestX962SHA512, + SecKeyAlgorithmRSASignatureDigestPKCS1v15Raw, + SecAttrKeyTypeECSECPrimeRandom, + // These are available in macOS 10.13 + SecKeyAlgorithmRSASignatureDigestPSSSHA1, + SecKeyAlgorithmRSASignatureDigestPSSSHA256, + SecKeyAlgorithmRSASignatureDigestPSSSHA384, + SecKeyAlgorithmRSASignatureDigestPSSSHA512, +} + +// NB: This is not meant to be used outside of this module. It has to be made public because +// `RentedSecurityFramework` must be public in the rental declaration. +pub struct SecurityFrameworkFunctions<'a> { + sec_key_create_signature: Symbol<'a, SecKeyCreateSignatureType>, + sec_key_copy_attributes: Symbol<'a, SecKeyCopyAttributesType>, + sec_key_copy_external_representation: Symbol<'a, SecKeyCopyExternalRepresentationType>, + sec_certificate_copy_normalized_issuer_sequence: + Symbol<'a, SecCertificateCopyNormalizedIssuerSequenceType>, + sec_certificate_copy_normalized_subject_sequence: + Symbol<'a, SecCertificateCopyNormalizedSubjectSequenceType>, + sec_certificate_copy_key: Symbol<'a, SecCertificateCopyKeyType>, + sec_trust_evaluate_with_error: Symbol<'a, SecTrustEvaluateWithErrorType>, + sec_string_constants: BTreeMap, +} + +rental! { + mod rent_libloading { + use super::*; + + #[rental] + pub struct RentedSecurityFramework { + library: Box, // Library needs to be StableDeref, hence the Box + functions: SecurityFrameworkFunctions<'library>, + } + } +} + +/// This implementation uses security framework functions and constants that +/// are not provided by the version of the SDK we build with. To work around +/// this, we attempt to open and dynamically load these functions and symbols +/// at runtime. Unfortunately this does mean that if a user is not on a new +/// enough version of macOS, they will not be able to use client certificates +/// from their keychain in Firefox until they upgrade. +struct SecurityFramework { + rental: Option, +} + +impl SecurityFramework { + fn new() -> SecurityFramework { + let library = match Library::new("/System/Library/Frameworks/Security.framework/Security") { + Ok(library) => library, + Err(_) => return SecurityFramework { rental: None }, + }; + match rent_libloading::RentedSecurityFramework::try_new::<_, ()>( + Box::new(library), + |library| unsafe { + let sec_key_create_signature = library + .get::(b"SecKeyCreateSignature\0") + .map_err(|_| ())?; + let sec_key_copy_attributes = library + .get::(b"SecKeyCopyAttributes\0") + .map_err(|_| ())?; + let sec_key_copy_external_representation = library + .get::( + b"SecKeyCopyExternalRepresentation\0", + ) + .map_err(|_| ())?; + let sec_certificate_copy_normalized_issuer_sequence = library + .get::( + b"SecCertificateCopyNormalizedIssuerSequence\0", + ) + .map_err(|_| ())?; + let sec_certificate_copy_normalized_subject_sequence = library + .get::( + b"SecCertificateCopyNormalizedSubjectSequence\0", + ) + .map_err(|_| ())?; + let sec_certificate_copy_key = library + .get::(b"SecCertificateCopyKey\0") + .map_err(|_| ())?; + let sec_trust_evaluate_with_error = library + .get::(b"SecTrustEvaluateWithError\0") + .map_err(|_| ())?; + let mut sec_string_constants = BTreeMap::new(); + let strings_to_load = vec![ + ( + b"kSecKeyAlgorithmECDSASignatureDigestX962SHA1\0".as_ref(), + SecStringConstant::SecKeyAlgorithmECDSASignatureDigestX962SHA1, + ), + ( + b"kSecKeyAlgorithmECDSASignatureDigestX962SHA256\0".as_ref(), + SecStringConstant::SecKeyAlgorithmECDSASignatureDigestX962SHA256, + ), + ( + b"kSecKeyAlgorithmECDSASignatureDigestX962SHA384\0".as_ref(), + SecStringConstant::SecKeyAlgorithmECDSASignatureDigestX962SHA384, + ), + ( + b"kSecKeyAlgorithmECDSASignatureDigestX962SHA512\0".as_ref(), + SecStringConstant::SecKeyAlgorithmECDSASignatureDigestX962SHA512, + ), + ( + b"kSecKeyAlgorithmRSASignatureDigestPKCS1v15Raw\0".as_ref(), + SecStringConstant::SecKeyAlgorithmRSASignatureDigestPKCS1v15Raw, + ), + ( + b"kSecKeyAlgorithmRSASignatureDigestPSSSHA1\0".as_ref(), + SecStringConstant::SecKeyAlgorithmRSASignatureDigestPSSSHA1, + ), + ( + b"kSecKeyAlgorithmRSASignatureDigestPSSSHA256\0".as_ref(), + SecStringConstant::SecKeyAlgorithmRSASignatureDigestPSSSHA256, + ), + ( + b"kSecKeyAlgorithmRSASignatureDigestPSSSHA384\0".as_ref(), + SecStringConstant::SecKeyAlgorithmRSASignatureDigestPSSSHA384, + ), + ( + b"kSecKeyAlgorithmRSASignatureDigestPSSSHA512\0".as_ref(), + SecStringConstant::SecKeyAlgorithmRSASignatureDigestPSSSHA512, + ), + ( + b"kSecAttrKeyTypeECSECPrimeRandom\0".as_ref(), + SecStringConstant::SecAttrKeyTypeECSECPrimeRandom, + ), + ]; + for (symbol_name, sec_string_constant) in strings_to_load { + let cfstring_symbol = library + .get::<*const CFStringRef>(symbol_name) + .map_err(|_| ())?; + let cfstring = CFString::wrap_under_create_rule(**cfstring_symbol); + sec_string_constants.insert(sec_string_constant, cfstring.to_string()); + } + Ok(SecurityFrameworkFunctions { + sec_key_create_signature, + sec_key_copy_attributes, + sec_key_copy_external_representation, + sec_certificate_copy_normalized_issuer_sequence, + sec_certificate_copy_normalized_subject_sequence, + sec_certificate_copy_key, + sec_trust_evaluate_with_error, + sec_string_constants, + }) + }, + ) { + Ok(rental) => SecurityFramework { + rental: Some(rental), + }, + Err(_) => SecurityFramework { rental: None }, + } + } + + /// SecKeyCreateSignature is available in macOS 10.12 + fn sec_key_create_signature( + &self, + key: &SecKey, + algorithm: SecKeyAlgorithm, + data_to_sign: &CFData, + ) -> Result { + match &self.rental { + Some(rental) => rental.rent(|framework| unsafe { + let mut error = std::ptr::null_mut(); + let result = (framework.sec_key_create_signature)( + key.as_concrete_TypeRef(), + algorithm, + data_to_sign.as_concrete_TypeRef(), + &mut error, + ); + if result.is_null() { + let error = CFError::wrap_under_create_rule(error); + error!("SecKeyCreateSignature failed: {}", error); + return Err(()); + } + Ok(CFData::wrap_under_create_rule(result)) + }), + None => Err(()), + } + } + + /// SecKeyCopyAttributes is available in macOS 10.12 + fn sec_key_copy_attributes(&self, key: &SecKey) -> Result, ()> { + match &self.rental { + Some(rental) => rental.rent(|framework| unsafe { + let result = (framework.sec_key_copy_attributes)(key.as_concrete_TypeRef()); + if result.is_null() { + error!("SecKeyCopyAttributes failed"); + return Err(()); + } + Ok(CFDictionary::wrap_under_create_rule(result)) + }), + None => Err(()), + } + } + + /// SecKeyCopyExternalRepresentation is available in macOS 10.12 + fn sec_key_copy_external_representation(&self, key: &SecKey) -> Result { + match &self.rental { + Some(rental) => rental.rent(|framework| unsafe { + let mut error = std::ptr::null_mut(); + let result = (framework.sec_key_copy_external_representation)( + key.as_concrete_TypeRef(), + &mut error, + ); + if result.is_null() { + let error = CFError::wrap_under_create_rule(error); + error!("SecKeyCopyExternalRepresentation failed: {}", error); + return Err(()); + } + Ok(CFData::wrap_under_create_rule(result)) + }), + None => Err(()), + } + } + + /// SecCertificateCopyNormalizedIssuerSequence is available in macOS 10.12.4 + fn sec_certificate_copy_normalized_issuer_sequence( + &self, + certificate: &SecCertificate, + ) -> Result { + match &self.rental { + Some(rental) => rental.rent(|framework| unsafe { + let result = (framework.sec_certificate_copy_normalized_issuer_sequence)( + certificate.as_concrete_TypeRef(), + ); + if result.is_null() { + error!("SecCertificateCopyNormalizedIssuerSequence failed"); + return Err(()); + } + Ok(CFData::wrap_under_create_rule(result)) + }), + None => Err(()), + } + } + + /// SecCertificateCopyNormalizedSubjectSequence is available in macOS 10.12.4 + fn sec_certificate_copy_normalized_subject_sequence( + &self, + certificate: &SecCertificate, + ) -> Result { + match &self.rental { + Some(rental) => rental.rent(|framework| unsafe { + let result = (framework.sec_certificate_copy_normalized_subject_sequence)( + certificate.as_concrete_TypeRef(), + ); + if result.is_null() { + error!("SecCertificateCopyNormalizedSubjectSequence failed"); + return Err(()); + } + Ok(CFData::wrap_under_create_rule(result)) + }), + None => Err(()), + } + } + + /// SecCertificateCopyKey is available in macOS 10.14 + fn sec_certificate_copy_key(&self, certificate: &SecCertificate) -> Result { + match &self.rental { + Some(rental) => rental.rent(|framework| unsafe { + let result = + (framework.sec_certificate_copy_key)(certificate.as_concrete_TypeRef()); + if result.is_null() { + error!("SecCertificateCopyKey failed"); + return Err(()); + } + Ok(SecKey::wrap_under_create_rule(result)) + }), + None => Err(()), + } + } + + /// SecTrustEvaluateWithError is available in macOS 10.14 + fn sec_trust_evaluate_with_error(&self, trust: &SecTrust) -> Result { + match &self.rental { + Some(rental) => rental.rent(|framework| unsafe { + Ok((framework.sec_trust_evaluate_with_error)( + trust.as_concrete_TypeRef(), + std::ptr::null_mut(), + )) + }), + None => Err(()), + } + } + + fn get_sec_string_constant( + &self, + sec_string_constant: SecStringConstant, + ) -> Result { + match &self.rental { + Some(rental) => rental.rent(|framework| { + match framework.sec_string_constants.get(&sec_string_constant) { + Some(string) => Ok(CFString::new(string)), + None => Err(()), + } + }), + None => Err(()), + } + } +} + +lazy_static! { + static ref SECURITY_FRAMEWORK: SecurityFramework = SecurityFramework::new(); +} + +fn sec_identity_copy_certificate(identity: &SecIdentity) -> Result { + let mut certificate = std::ptr::null(); + let status = + unsafe { SecIdentityCopyCertificate(identity.as_concrete_TypeRef(), &mut certificate) }; + if status != errSecSuccess { + error!("SecIdentityCopyCertificate failed: {}", status); + return Err(()); + } + if certificate.is_null() { + error!("couldn't get certificate from identity?"); + return Err(()); + } + Ok(unsafe { SecCertificate::wrap_under_create_rule(certificate) }) +} + +fn sec_certificate_copy_subject_summary(certificate: &SecCertificate) -> Result { + let result = unsafe { SecCertificateCopySubjectSummary(certificate.as_concrete_TypeRef()) }; + if result.is_null() { + error!("SecCertificateCopySubjectSummary failed"); + return Err(()); + } + Ok(unsafe { CFString::wrap_under_create_rule(result) }) +} + +fn sec_certificate_copy_data(certificate: &SecCertificate) -> Result { + let result = unsafe { SecCertificateCopyData(certificate.as_concrete_TypeRef()) }; + if result.is_null() { + error!("SecCertificateCopyData failed"); + return Err(()); + } + Ok(unsafe { CFData::wrap_under_create_rule(result) }) +} + +fn sec_identity_copy_private_key(identity: &SecIdentity) -> Result { + let mut key = std::ptr::null(); + let status = unsafe { SecIdentityCopyPrivateKey(identity.as_concrete_TypeRef(), &mut key) }; + if status != errSecSuccess { + error!("SecIdentityCopyPrivateKey failed: {}", status); + return Err(()); + } + if key.is_null() { + error!("SecIdentityCopyPrivateKey didn't set key?"); + return Err(()); + } + Ok(unsafe { SecKey::wrap_under_create_rule(key) }) +} + +pub struct Cert { + class: Vec, + token: Vec, + id: Vec, + label: Vec, + value: Vec, + issuer: Vec, + serial_number: Vec, + subject: Vec, +} + +impl Cert { + fn new_from_identity(identity: &SecIdentity) -> Result { + let certificate = sec_identity_copy_certificate(identity)?; + Cert::new_from_certificate(&certificate) + } + + fn new_from_certificate(certificate: &SecCertificate) -> Result { + let label = sec_certificate_copy_subject_summary(certificate)?; + let der = sec_certificate_copy_data(certificate)?; + let der = der.bytes().to_vec(); + let id = Sha256::digest(&der).to_vec(); + let issuer = + SECURITY_FRAMEWORK.sec_certificate_copy_normalized_issuer_sequence(certificate)?; + let serial_number = read_encoded_serial_number(&der)?; + let subject = + SECURITY_FRAMEWORK.sec_certificate_copy_normalized_subject_sequence(certificate)?; + Ok(Cert { + class: serialize_uint(CKO_CERTIFICATE)?, + token: serialize_uint(CK_TRUE)?, + id, + label: label.to_string().into_bytes(), + value: der, + issuer: issuer.bytes().to_vec(), + serial_number, + subject: subject.bytes().to_vec(), + }) + } + + fn class(&self) -> &[u8] { + &self.class + } + + fn token(&self) -> &[u8] { + &self.token + } + + pub fn id(&self) -> &[u8] { + &self.id + } + + fn label(&self) -> &[u8] { + &self.label + } + + fn value(&self) -> &[u8] { + &self.value + } + + fn issuer(&self) -> &[u8] { + &self.issuer + } + + fn serial_number(&self) -> &[u8] { + &self.serial_number + } + + fn subject(&self) -> &[u8] { + &self.subject + } + + fn matches(&self, attrs: &[(CK_ATTRIBUTE_TYPE, Vec)]) -> bool { + for (attr_type, attr_value) in attrs { + let comparison = match *attr_type { + CKA_CLASS => self.class(), + CKA_TOKEN => self.token(), + CKA_LABEL => self.label(), + CKA_ID => self.id(), + CKA_VALUE => self.value(), + CKA_ISSUER => self.issuer(), + CKA_SERIAL_NUMBER => self.serial_number(), + CKA_SUBJECT => self.subject(), + _ => return false, + }; + if attr_value.as_slice() != comparison { + return false; + } + } + true + } + + fn get_attribute(&self, attribute: CK_ATTRIBUTE_TYPE) -> Option<&[u8]> { + let result = match attribute { + CKA_CLASS => self.class(), + CKA_TOKEN => self.token(), + CKA_LABEL => self.label(), + CKA_ID => self.id(), + CKA_VALUE => self.value(), + CKA_ISSUER => self.issuer(), + CKA_SERIAL_NUMBER => self.serial_number(), + CKA_SUBJECT => self.subject(), + _ => return None, + }; + Some(result) + } +} + +#[derive(Clone, Copy, Debug)] +pub enum KeyType { + EC(usize), + RSA, +} + +enum SignParams { + EC(CFString), + RSA(CFString), +} + +impl SignParams { + fn new( + key_type: KeyType, + data_len: usize, + params: &Option, + ) -> Result { + match key_type { + KeyType::EC(_) => SignParams::new_ec_params(data_len), + KeyType::RSA => SignParams::new_rsa_params(params), + } + } + + fn new_ec_params(data_len: usize) -> Result { + let algorithm_id = match data_len { + 20 => SecStringConstant::SecKeyAlgorithmECDSASignatureDigestX962SHA1, + 32 => SecStringConstant::SecKeyAlgorithmECDSASignatureDigestX962SHA256, + 48 => SecStringConstant::SecKeyAlgorithmECDSASignatureDigestX962SHA384, + 64 => SecStringConstant::SecKeyAlgorithmECDSASignatureDigestX962SHA512, + _ => { + error!( + "Unexpected digested signature input length for ECDSA: {}", + data_len + ); + return Err(()); + } + }; + let algorithm = SECURITY_FRAMEWORK.get_sec_string_constant(algorithm_id)?; + Ok(SignParams::EC(algorithm)) + } + + fn new_rsa_params(params: &Option) -> Result { + let pss_params = match params { + Some(pss_params) => pss_params, + None => { + return Ok(SignParams::RSA( + SECURITY_FRAMEWORK.get_sec_string_constant( + SecStringConstant::SecKeyAlgorithmRSASignatureDigestPKCS1v15Raw, + )?, + )); + } + }; + let algorithm = { + let algorithm_id = match pss_params.hashAlg { + CKM_SHA_1 => SecStringConstant::SecKeyAlgorithmRSASignatureDigestPSSSHA1, + CKM_SHA256 => SecStringConstant::SecKeyAlgorithmRSASignatureDigestPSSSHA256, + CKM_SHA384 => SecStringConstant::SecKeyAlgorithmRSASignatureDigestPSSSHA384, + CKM_SHA512 => SecStringConstant::SecKeyAlgorithmRSASignatureDigestPSSSHA512, + _ => { + error!( + "unsupported algorithm to use with RSA-PSS: {}", + unsafe_packed_field_access!(pss_params.hashAlg) + ); + return Err(()); + } + }; + SECURITY_FRAMEWORK.get_sec_string_constant(algorithm_id)? + }; + Ok(SignParams::RSA(algorithm)) + } + + fn get_algorithm(&self) -> SecKeyAlgorithm { + match self { + SignParams::EC(algorithm) => algorithm.as_concrete_TypeRef(), + SignParams::RSA(algorithm) => algorithm.as_concrete_TypeRef(), + } + } +} + +pub struct Key { + identity: SecIdentity, + class: Vec, + token: Vec, + id: Vec, + private: Vec, + key_type: Vec, + modulus: Option>, + ec_params: Option>, + key_type_enum: KeyType, +} + +impl Key { + fn new(identity: &SecIdentity) -> Result { + let certificate = sec_identity_copy_certificate(identity)?; + let der = sec_certificate_copy_data(&certificate)?; + let id = Sha256::digest(der.bytes()).to_vec(); + let key = SECURITY_FRAMEWORK.sec_certificate_copy_key(&certificate)?; + let key_type: CFString = get_key_attribute(&key, unsafe { kSecAttrKeyType })?; + let key_size_in_bits: CFNumber = get_key_attribute(&key, unsafe { kSecAttrKeySizeInBits })?; + let mut modulus = None; + let mut ec_params = None; + let sec_attr_key_type_ec = SECURITY_FRAMEWORK + .get_sec_string_constant(SecStringConstant::SecAttrKeyTypeECSECPrimeRandom)?; + let (key_type_enum, key_type_attribute) = + if key_type.as_concrete_TypeRef() == unsafe { kSecAttrKeyTypeRSA } { + let public_key = SECURITY_FRAMEWORK.sec_key_copy_external_representation(&key)?; + let modulus_value = read_rsa_modulus(public_key.bytes())?; + modulus = Some(modulus_value); + (KeyType::RSA, CKK_RSA) + } else if key_type == sec_attr_key_type_ec { + // Assume all EC keys are secp256r1, secp384r1, or secp521r1. This + // is wrong, but the API doesn't seem to give us a way to determine + // which curve this key is on. + // This might not matter in practice, because it seems all NSS uses + // this for is to get the signature size. + let key_size_in_bits = match key_size_in_bits.to_i64() { + Some(value) => value, + None => return Err(()), + }; + match key_size_in_bits { + 256 => ec_params = Some(OID_BYTES_SECP256R1.to_vec()), + 384 => ec_params = Some(OID_BYTES_SECP384R1.to_vec()), + 521 => ec_params = Some(OID_BYTES_SECP521R1.to_vec()), + _ => { + error!("unsupported EC key"); + return Err(()); + } + } + let coordinate_width = (key_size_in_bits as usize + 7) / 8; + (KeyType::EC(coordinate_width), CKK_EC) + } else { + error!("unsupported key type"); + return Err(()); + }; + + Ok(Key { + identity: identity.clone(), + class: serialize_uint(CKO_PRIVATE_KEY)?, + token: serialize_uint(CK_TRUE)?, + id, + private: serialize_uint(CK_TRUE)?, + key_type: serialize_uint(key_type_attribute)?, + modulus, + ec_params, + key_type_enum, + }) + } + + fn class(&self) -> &[u8] { + &self.class + } + + fn token(&self) -> &[u8] { + &self.token + } + + pub fn id(&self) -> &[u8] { + &self.id + } + + fn private(&self) -> &[u8] { + &self.private + } + + fn key_type(&self) -> &[u8] { + &self.key_type + } + + fn modulus(&self) -> Option<&[u8]> { + match &self.modulus { + Some(modulus) => Some(modulus.as_slice()), + None => None, + } + } + + fn ec_params(&self) -> Option<&[u8]> { + match &self.ec_params { + Some(ec_params) => Some(ec_params.as_slice()), + None => None, + } + } + + fn matches(&self, attrs: &[(CK_ATTRIBUTE_TYPE, Vec)]) -> bool { + for (attr_type, attr_value) in attrs { + let comparison = match *attr_type { + CKA_CLASS => self.class(), + CKA_TOKEN => self.token(), + CKA_ID => self.id(), + CKA_PRIVATE => self.private(), + CKA_KEY_TYPE => self.key_type(), + CKA_MODULUS => { + if let Some(modulus) = self.modulus() { + modulus + } else { + return false; + } + } + CKA_EC_PARAMS => { + if let Some(ec_params) = self.ec_params() { + ec_params + } else { + return false; + } + } + _ => return false, + }; + if attr_value.as_slice() != comparison { + return false; + } + } + true + } + + fn get_attribute(&self, attribute: CK_ATTRIBUTE_TYPE) -> Option<&[u8]> { + match attribute { + CKA_CLASS => Some(self.class()), + CKA_TOKEN => Some(self.token()), + CKA_ID => Some(self.id()), + CKA_PRIVATE => Some(self.private()), + CKA_KEY_TYPE => Some(self.key_type()), + CKA_MODULUS => self.modulus(), + CKA_EC_PARAMS => self.ec_params(), + _ => None, + } + } + + pub fn get_signature_length( + &self, + data: &[u8], + params: &Option, + ) -> Result { + // Unfortunately we don't have a way of getting the length of a signature without creating + // one. + let dummy_signature_bytes = self.sign(data, params)?; + Ok(dummy_signature_bytes.len()) + } + + // The input data is a hash. What algorithm we use depends on the size of the hash. + pub fn sign( + &self, + data: &[u8], + params: &Option, + ) -> Result, ()> { + let key = sec_identity_copy_private_key(&self.identity)?; + let sign_params = SignParams::new(self.key_type_enum, data.len(), params)?; + let signing_algorithm = sign_params.get_algorithm(); + let data = CFData::from_buffer(data); + let signature = + SECURITY_FRAMEWORK.sec_key_create_signature(&key, signing_algorithm, &data)?; + let signature_value = match self.key_type_enum { + KeyType::EC(coordinate_width) => { + // We need to convert the DER Ecdsa-Sig-Value to the + // concatenation of r and s, the coordinates of the point on + // the curve. r and s must be 0-padded to be coordinate_width + // total bytes. + let (r, s) = read_ec_sig_point(signature.bytes())?; + if r.len() > coordinate_width || s.len() > coordinate_width { + return Err(()); + } + let mut signature_value = Vec::with_capacity(2 * coordinate_width); + let r_padding = vec![0; coordinate_width - r.len()]; + signature_value.extend(r_padding); + signature_value.extend_from_slice(r); + let s_padding = vec![0; coordinate_width - s.len()]; + signature_value.extend(s_padding); + signature_value.extend_from_slice(s); + signature_value + } + KeyType::RSA => signature.bytes().to_vec(), + }; + Ok(signature_value) + } +} + +pub enum Object { + Cert(Cert), + Key(Key), +} + +impl Object { + pub fn matches(&self, slot_type: SlotType, attrs: &[(CK_ATTRIBUTE_TYPE, Vec)]) -> bool { + // The modern/legacy slot distinction in theory enables differentiation + // between keys that are from modules that can use modern cryptography + // (namely EC keys and RSA-PSS signatures) and those that cannot. + // However, the function that would enable this + // (SecKeyIsAlgorithmSupported) causes a password dialog to appear on + // our test machines, so this backend pretends that everything supports + // modern crypto for now. + if slot_type != SlotType::Modern { + return false; + } + match self { + Object::Cert(cert) => cert.matches(attrs), + Object::Key(key) => key.matches(attrs), + } + } + + pub fn get_attribute(&self, attribute: CK_ATTRIBUTE_TYPE) -> Option<&[u8]> { + match self { + Object::Cert(cert) => cert.get_attribute(attribute), + Object::Key(key) => key.get_attribute(attribute), + } + } +} + +pub const SUPPORTED_ATTRIBUTES: &[CK_ATTRIBUTE_TYPE] = &[ + CKA_CLASS, + CKA_TOKEN, + CKA_LABEL, + CKA_ID, + CKA_VALUE, + CKA_ISSUER, + CKA_SERIAL_NUMBER, + CKA_SUBJECT, + CKA_PRIVATE, + CKA_KEY_TYPE, + CKA_MODULUS, + CKA_EC_PARAMS, +]; + +fn get_key_attribute(key: &SecKey, attr: CFStringRef) -> Result { + let attributes: CFDictionary = SECURITY_FRAMEWORK.sec_key_copy_attributes(&key)?; + match attributes.find(attr as *const _) { + Some(value) => Ok((*value).clone()), + None => Err(()), + } +} + +// Given a SecIdentity, attempts to build as much of a path to a trust anchor as possible, gathers +// the CA certificates from that path, and returns them. The purpose of this function is not to +// validate the given certificate but to find CA certificates that gecko may need to do path +// building when filtering client certificates according to the acceptable CA list sent by the +// server during client authentication. +fn get_issuers(identity: &SecIdentity) -> Result, ()> { + let certificate = sec_identity_copy_certificate(identity)?; + let policy = unsafe { SecPolicyCreateSSL(false, std::ptr::null()) }; + if policy.is_null() { + error!("SecPolicyCreateSSL failed"); + return Err(()); + } + let policy = unsafe { SecPolicy::wrap_under_create_rule(policy) }; + let mut trust = std::ptr::null(); + // Each of SecTrustCreateWithCertificates' input arguments can be either single items or an + // array of items. Since we only want to specify one of each, we directly specify the arguments. + let status = unsafe { + SecTrustCreateWithCertificates( + certificate.as_concrete_TypeRef(), + policy.as_concrete_TypeRef(), + &mut trust, + ) + }; + if status != errSecSuccess { + error!("SecTrustCreateWithCertificates failed: {}", status); + return Err(()); + } + if trust.is_null() { + error!("trust is null?"); + return Err(()); + } + let trust = unsafe { SecTrust::wrap_under_create_rule(trust) }; + // Disable AIA fetching so that SecTrustEvaluateWithError doesn't result in network I/O. + let status = unsafe { SecTrustSetNetworkFetchAllowed(trust.as_concrete_TypeRef(), 0) }; + if status != errSecSuccess { + error!("SecTrustSetNetworkFetchAllowed failed: {}", status); + return Err(()); + } + // We ignore the return value here because we don't care if the certificate is trusted or not - + // we're only doing this to build its issuer chain as much as possible. + let _ = SECURITY_FRAMEWORK.sec_trust_evaluate_with_error(&trust)?; + let certificate_count = unsafe { SecTrustGetCertificateCount(trust.as_concrete_TypeRef()) }; + let mut certificates = Vec::with_capacity(certificate_count.try_into().map_err(|_| ())?); + for i in 1..certificate_count { + let certificate = unsafe { SecTrustGetCertificateAtIndex(trust.as_concrete_TypeRef(), i) }; + if certificate.is_null() { + error!("SecTrustGetCertificateAtIndex returned null certificate?"); + continue; + } + let certificate = unsafe { SecCertificate::wrap_under_get_rule(certificate) }; + certificates.push(certificate); + } + Ok(certificates) +} + +pub fn list_objects() -> Vec { + let mut objects = Vec::new(); + let identities = unsafe { + let class_key = CFString::wrap_under_get_rule(kSecClass); + let class_value = CFString::wrap_under_get_rule(kSecClassIdentity); + let return_ref_key = CFString::wrap_under_get_rule(kSecReturnRef); + let return_ref_value = CFBoolean::wrap_under_get_rule(kCFBooleanTrue); + let match_key = CFString::wrap_under_get_rule(kSecMatchLimit); + let match_value = CFString::wrap_under_get_rule(kSecMatchLimitAll); + let vals = vec![ + (class_key.as_CFType(), class_value.as_CFType()), + (return_ref_key.as_CFType(), return_ref_value.as_CFType()), + (match_key.as_CFType(), match_value.as_CFType()), + ]; + let dict = CFDictionary::from_CFType_pairs(&vals); + let mut result = std::ptr::null(); + let status = SecItemCopyMatching(dict.as_CFTypeRef() as CFDictionaryRef, &mut result); + if status != errSecSuccess { + error!("SecItemCopyMatching failed: {}", status); + return objects; + } + if result.is_null() { + debug!("no client certs?"); + return objects; + } + CFArray::::wrap_under_create_rule(result as CFArrayRef) + }; + for identity in identities.get_all_values().iter() { + let identity = unsafe { SecIdentity::wrap_under_get_rule(*identity as SecIdentityRef) }; + let cert = Cert::new_from_identity(&identity); + let key = Key::new(&identity); + if let (Ok(cert), Ok(key)) = (cert, key) { + objects.push(Object::Cert(cert)); + objects.push(Object::Key(key)); + } else { + continue; + } + if let Ok(issuers) = get_issuers(&identity) { + for issuer in issuers { + if let Ok(cert) = Cert::new_from_certificate(&issuer) { + objects.push(Object::Cert(cert)); + } + } + } + } + objects +} diff --git a/security/manager/ssl/osclientcerts/src/backend_windows.rs b/security/manager/ssl/osclientcerts/src/backend_windows.rs new file mode 100644 index 0000000000..a422d2e2bc --- /dev/null +++ b/security/manager/ssl/osclientcerts/src/backend_windows.rs @@ -0,0 +1,933 @@ +/* -*- Mode: rust; rust-indent-offset: 4 -*- */ +/* 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/. */ + +#![allow(non_camel_case_types)] + +use pkcs11::types::*; +use sha2::{Digest, Sha256}; +use std::convert::TryInto; +use std::ffi::{c_void, CStr, CString}; +use std::ops::Deref; +use std::slice; +use winapi::shared::bcrypt::*; +use winapi::shared::minwindef::{DWORD, PBYTE}; +use winapi::um::errhandlingapi::GetLastError; +use winapi::um::ncrypt::*; +use winapi::um::wincrypt::{HCRYPTHASH, HCRYPTPROV, *}; + +use crate::manager::SlotType; +use crate::util::*; + +// winapi has some support for ncrypt.h, but not for this function. +extern "system" { + fn NCryptSignHash( + hKey: NCRYPT_KEY_HANDLE, + pPaddingInfo: *mut c_void, + pbHashValue: PBYTE, + cbHashValue: DWORD, + pbSignature: PBYTE, + cbSignature: DWORD, + pcbResult: *mut DWORD, + dwFlags: DWORD, + ) -> SECURITY_STATUS; +} + +/// Given a `CERT_INFO`, tries to return the bytes of the subject distinguished name as formatted by +/// `CertNameToStrA` using the flag `CERT_SIMPLE_NAME_STR`. This is used as the label for the +/// certificate. +fn get_cert_subject_dn(cert_info: &CERT_INFO) -> Result, ()> { + let mut cert_info_subject = cert_info.Subject; + let subject_dn_len = unsafe { + CertNameToStrA( + X509_ASN_ENCODING, + &mut cert_info_subject, + CERT_SIMPLE_NAME_STR, + std::ptr::null_mut(), + 0, + ) + }; + // subject_dn_len includes the terminating null byte. + let mut subject_dn_string_bytes: Vec = vec![0; subject_dn_len as usize]; + let subject_dn_len = unsafe { + CertNameToStrA( + X509_ASN_ENCODING, + &mut cert_info_subject, + CERT_SIMPLE_NAME_STR, + subject_dn_string_bytes.as_mut_ptr() as *mut i8, + subject_dn_string_bytes.len().try_into().map_err(|_| ())?, + ) + }; + if subject_dn_len as usize != subject_dn_string_bytes.len() { + return Err(()); + } + Ok(subject_dn_string_bytes) +} + +/// Represents a certificate for which there exists a corresponding private key. +pub struct Cert { + /// PKCS #11 object class. Will be `CKO_CERTIFICATE`. + class: Vec, + /// Whether or not this is on a token. Will be `CK_TRUE`. + token: Vec, + /// An identifier unique to this certificate. Must be the same as the ID for the private key. + id: Vec, + /// The bytes of a human-readable label for this certificate. Will be the subject DN. + label: Vec, + /// The DER bytes of the certificate. + value: Vec, + /// The DER bytes of the issuer distinguished name of the certificate. + issuer: Vec, + /// The DER bytes of the serial number of the certificate. + serial_number: Vec, + /// The DER bytes of the subject distinguished name of the certificate. + subject: Vec, + /// Which slot this certificate should be exposed on. + slot_type: SlotType, +} + +impl Cert { + fn new(cert_context: PCCERT_CONTEXT) -> Result { + let cert = unsafe { &*cert_context }; + let cert_info = unsafe { &*cert.pCertInfo }; + let value = + unsafe { slice::from_raw_parts(cert.pbCertEncoded, cert.cbCertEncoded as usize) }; + let value = value.to_vec(); + let id = Sha256::digest(&value).to_vec(); + let label = get_cert_subject_dn(&cert_info)?; + let issuer = unsafe { + slice::from_raw_parts(cert_info.Issuer.pbData, cert_info.Issuer.cbData as usize) + }; + let issuer = issuer.to_vec(); + let serial_number = read_encoded_serial_number(&value)?; + let subject = unsafe { + slice::from_raw_parts(cert_info.Subject.pbData, cert_info.Subject.cbData as usize) + }; + let subject = subject.to_vec(); + Ok(Cert { + class: serialize_uint(CKO_CERTIFICATE)?, + token: serialize_uint(CK_TRUE)?, + id, + label, + value, + issuer, + serial_number, + subject, + slot_type: SlotType::Modern, + }) + } + + fn class(&self) -> &[u8] { + &self.class + } + + fn token(&self) -> &[u8] { + &self.token + } + + pub fn id(&self) -> &[u8] { + &self.id + } + + fn label(&self) -> &[u8] { + &self.label + } + + fn value(&self) -> &[u8] { + &self.value + } + + fn issuer(&self) -> &[u8] { + &self.issuer + } + + fn serial_number(&self) -> &[u8] { + &self.serial_number + } + + fn subject(&self) -> &[u8] { + &self.subject + } + + fn matches(&self, slot_type: SlotType, attrs: &[(CK_ATTRIBUTE_TYPE, Vec)]) -> bool { + if slot_type != self.slot_type { + return false; + } + for (attr_type, attr_value) in attrs { + let comparison = match *attr_type { + CKA_CLASS => self.class(), + CKA_TOKEN => self.token(), + CKA_LABEL => self.label(), + CKA_ID => self.id(), + CKA_VALUE => self.value(), + CKA_ISSUER => self.issuer(), + CKA_SERIAL_NUMBER => self.serial_number(), + CKA_SUBJECT => self.subject(), + _ => return false, + }; + if attr_value.as_slice() != comparison { + return false; + } + } + true + } + + fn get_attribute(&self, attribute: CK_ATTRIBUTE_TYPE) -> Option<&[u8]> { + let result = match attribute { + CKA_CLASS => self.class(), + CKA_TOKEN => self.token(), + CKA_LABEL => self.label(), + CKA_ID => self.id(), + CKA_VALUE => self.value(), + CKA_ISSUER => self.issuer(), + CKA_SERIAL_NUMBER => self.serial_number(), + CKA_SUBJECT => self.subject(), + _ => return None, + }; + Some(result) + } +} + +struct CertContext(PCCERT_CONTEXT); + +impl CertContext { + fn new(cert: PCCERT_CONTEXT) -> CertContext { + CertContext(unsafe { CertDuplicateCertificateContext(cert) }) + } +} + +impl Drop for CertContext { + fn drop(&mut self) { + unsafe { + CertFreeCertificateContext(self.0); + } + } +} + +impl Deref for CertContext { + type Target = PCCERT_CONTEXT; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +enum KeyHandle { + NCrypt(NCRYPT_KEY_HANDLE), + CryptoAPI(HCRYPTPROV, DWORD), +} + +impl KeyHandle { + fn from_cert(cert: &CertContext) -> Result { + let mut key_handle = 0; + let mut key_spec = 0; + let mut must_free = 0; + unsafe { + if CryptAcquireCertificatePrivateKey( + **cert, + CRYPT_ACQUIRE_PREFER_NCRYPT_KEY_FLAG, + std::ptr::null_mut(), + &mut key_handle, + &mut key_spec, + &mut must_free, + ) != 1 + { + error!( + "CryptAcquireCertificatePrivateKey failed: 0x{:x}", + GetLastError() + ); + return Err(()); + } + } + if must_free == 0 { + error!("CryptAcquireCertificatePrivateKey returned shared key handle"); + return Err(()); + } + if key_spec == CERT_NCRYPT_KEY_SPEC { + Ok(KeyHandle::NCrypt(key_handle as NCRYPT_KEY_HANDLE)) + } else { + Ok(KeyHandle::CryptoAPI(key_handle as HCRYPTPROV, key_spec)) + } + } + + fn sign( + &self, + data: &[u8], + params: &Option, + do_signature: bool, + key_type: KeyType, + ) -> Result, ()> { + match &self { + KeyHandle::NCrypt(ncrypt_handle) => { + sign_ncrypt(ncrypt_handle, data, params, do_signature, key_type) + } + KeyHandle::CryptoAPI(hcryptprov, key_spec) => { + sign_cryptoapi(hcryptprov, key_spec, data, params, do_signature) + } + } + } +} + +impl Drop for KeyHandle { + fn drop(&mut self) { + match self { + KeyHandle::NCrypt(ncrypt_handle) => unsafe { + let _ = NCryptFreeObject(*ncrypt_handle); + }, + KeyHandle::CryptoAPI(hcryptprov, _) => unsafe { + let _ = CryptReleaseContext(*hcryptprov, 0); + }, + } + } +} + +fn sign_ncrypt( + ncrypt_handle: &NCRYPT_KEY_HANDLE, + data: &[u8], + params: &Option, + do_signature: bool, + key_type: KeyType, +) -> Result, ()> { + let mut sign_params = SignParams::new(key_type, params)?; + let params_ptr = sign_params.params_ptr(); + let flags = sign_params.flags(); + let mut data = data.to_vec(); + let mut signature_len = 0; + // We call NCryptSignHash twice: the first time to get the size of the buffer we need to + // allocate and then again to actually sign the data, if `do_signature` is `true`. + let status = unsafe { + NCryptSignHash( + *ncrypt_handle, + params_ptr, + data.as_mut_ptr(), + data.len().try_into().map_err(|_| ())?, + std::ptr::null_mut(), + 0, + &mut signature_len, + flags, + ) + }; + // 0 is "ERROR_SUCCESS" (but "ERROR_SUCCESS" is unsigned, whereas SECURITY_STATUS is signed) + if status != 0 { + error!( + "NCryptSignHash failed trying to get signature buffer length, {}", + status + ); + return Err(()); + } + let mut signature = vec![0; signature_len as usize]; + if !do_signature { + return Ok(signature); + } + let mut final_signature_len = signature_len; + let status = unsafe { + NCryptSignHash( + *ncrypt_handle, + params_ptr, + data.as_mut_ptr(), + data.len().try_into().map_err(|_| ())?, + signature.as_mut_ptr(), + signature_len, + &mut final_signature_len, + flags, + ) + }; + if status != 0 { + error!("NCryptSignHash failed signing data {}", status); + return Err(()); + } + if final_signature_len != signature_len { + error!( + "NCryptSignHash: inconsistent signature lengths? {} != {}", + final_signature_len, signature_len + ); + return Err(()); + } + Ok(signature) +} + +fn sign_cryptoapi( + hcryptprov: &HCRYPTPROV, + key_spec: &DWORD, + data: &[u8], + params: &Option, + do_signature: bool, +) -> Result, ()> { + if params.is_some() { + error!("non-None signature params cannot be used with CryptoAPI"); + return Err(()); + } + // data will be an encoded DigestInfo, which specifies the hash algorithm and bytes of the hash + // to sign. However, CryptoAPI requires directly specifying the bytes of the hash, so it must + // be extracted first. + let hash_bytes = read_digest(data)?; + let hash = HCryptHash::new(hcryptprov, hash_bytes)?; + let mut signature_len = 0; + if unsafe { + CryptSignHashW( + *hash, + *key_spec, + std::ptr::null_mut(), + 0, + std::ptr::null_mut(), + &mut signature_len, + ) + } != 1 + { + error!( + "CryptSignHash failed trying to get signature buffer length: 0x{:x}", + unsafe { GetLastError() } + ); + return Err(()); + } + let mut signature = vec![0; signature_len as usize]; + if !do_signature { + return Ok(signature); + } + let mut final_signature_len = signature_len; + if unsafe { + CryptSignHashW( + *hash, + *key_spec, + std::ptr::null_mut(), + 0, + signature.as_mut_ptr(), + &mut final_signature_len, + ) + } != 1 + { + error!("CryptSignHash failed signing data: 0x{:x}", unsafe { + GetLastError() + }); + return Err(()); + } + if final_signature_len != signature_len { + error!( + "CryptSignHash: inconsistent signature lengths? {} != {}", + final_signature_len, signature_len + ); + return Err(()); + } + // CryptoAPI returns the signature with the most significant byte last (little-endian), + // whereas PKCS#11 expects the most significant byte first (big-endian). + signature.reverse(); + Ok(signature) +} + +struct HCryptHash(HCRYPTHASH); + +impl HCryptHash { + fn new(hcryptprov: &HCRYPTPROV, hash_bytes: &[u8]) -> Result { + let alg = match hash_bytes.len() { + 20 => CALG_SHA1, + 32 => CALG_SHA_256, + 48 => CALG_SHA_384, + 64 => CALG_SHA_512, + _ => { + error!( + "HCryptHash::new: invalid hash of length {}", + hash_bytes.len() + ); + return Err(()); + } + }; + let mut hash: HCRYPTHASH = 0; + if unsafe { CryptCreateHash(*hcryptprov, alg, 0, 0, &mut hash) } != 1 { + error!("CryptCreateHash failed: 0x{:x}", unsafe { GetLastError() }); + return Err(()); + } + if unsafe { CryptSetHashParam(hash, HP_HASHVAL, hash_bytes.as_ptr(), 0) } != 1 { + error!("CryptSetHashParam failed: 0x{:x}", unsafe { + GetLastError() + }); + return Err(()); + } + Ok(HCryptHash(hash)) + } +} + +impl Drop for HCryptHash { + fn drop(&mut self) { + unsafe { + CryptDestroyHash(self.0); + } + } +} + +impl Deref for HCryptHash { + type Target = HCRYPTHASH; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +// In some cases, the ncrypt API takes a pointer to a null-terminated wide-character string as a way +// of specifying an algorithm. The "right" way to do this would be to take the corresponding +// &'static str constant provided by the winapi crate, create an OsString from it, encode it as wide +// characters, and collect it into a Vec. However, since the implementation that provides this +// functionality isn't constant, we would have to manage the memory this creates and uses. Since +// rust structures generally can't be self-referrential, this memory would have to live elsewhere, +// and the nice abstractions we've created for this implementation start to break down. It's much +// simpler to hard-code the identifiers we support, since there are only four of them. +// The following arrays represent the identifiers "SHA1", "SHA256", "SHA384", and "SHA512", +// respectively. +const SHA1_ALGORITHM_STRING: &[u16] = &[83, 72, 65, 49, 0]; +const SHA256_ALGORITHM_STRING: &[u16] = &[83, 72, 65, 50, 53, 54, 0]; +const SHA384_ALGORITHM_STRING: &[u16] = &[83, 72, 65, 51, 56, 52, 0]; +const SHA512_ALGORITHM_STRING: &[u16] = &[83, 72, 65, 53, 49, 50, 0]; + +enum SignParams { + EC, + RSA_PKCS1(BCRYPT_PKCS1_PADDING_INFO), + RSA_PSS(BCRYPT_PSS_PADDING_INFO), +} + +impl SignParams { + fn new(key_type: KeyType, params: &Option) -> Result { + // EC is easy, so handle that first. + match key_type { + KeyType::EC => return Ok(SignParams::EC), + KeyType::RSA => {} + } + // If `params` is `Some`, we're doing RSA-PSS. If it is `None`, we're doing RSA-PKCS1. + let pss_params = match params { + Some(pss_params) => pss_params, + None => { + // The hash algorithm should be encoded in the data to be signed, so we don't have to + // (and don't want to) specify a particular algorithm here. + return Ok(SignParams::RSA_PKCS1(BCRYPT_PKCS1_PADDING_INFO { + pszAlgId: std::ptr::null(), + })); + } + }; + let algorithm_string = match pss_params.hashAlg { + CKM_SHA_1 => SHA1_ALGORITHM_STRING, + CKM_SHA256 => SHA256_ALGORITHM_STRING, + CKM_SHA384 => SHA384_ALGORITHM_STRING, + CKM_SHA512 => SHA512_ALGORITHM_STRING, + _ => { + error!( + "unsupported algorithm to use with RSA-PSS: {}", + unsafe_packed_field_access!(pss_params.hashAlg) + ); + return Err(()); + } + }; + Ok(SignParams::RSA_PSS(BCRYPT_PSS_PADDING_INFO { + pszAlgId: algorithm_string.as_ptr(), + cbSalt: pss_params.sLen, + })) + } + + fn params_ptr(&mut self) -> *mut std::ffi::c_void { + match self { + SignParams::EC => std::ptr::null_mut(), + SignParams::RSA_PKCS1(params) => { + params as *mut BCRYPT_PKCS1_PADDING_INFO as *mut std::ffi::c_void + } + SignParams::RSA_PSS(params) => { + params as *mut BCRYPT_PSS_PADDING_INFO as *mut std::ffi::c_void + } + } + } + + fn flags(&self) -> u32 { + match self { + &SignParams::EC => 0, + &SignParams::RSA_PKCS1(_) => NCRYPT_PAD_PKCS1_FLAG, + &SignParams::RSA_PSS(_) => NCRYPT_PAD_PSS_FLAG, + } + } +} + +/// A helper enum to identify a private key's type. We support EC and RSA. +#[derive(Clone, Copy, Debug)] +pub enum KeyType { + EC, + RSA, +} + +/// Represents a private key for which there exists a corresponding certificate. +pub struct Key { + /// A handle on the OS mechanism that represents the certificate for this key. + cert: CertContext, + /// PKCS #11 object class. Will be `CKO_PRIVATE_KEY`. + class: Vec, + /// Whether or not this is on a token. Will be `CK_TRUE`. + token: Vec, + /// An identifier unique to this key. Must be the same as the ID for the certificate. + id: Vec, + /// Whether or not this key is "private" (can it be exported?). Will be CK_TRUE (it can't be + /// exported). + private: Vec, + /// PKCS #11 key type. Will be `CKK_EC` for EC, and `CKK_RSA` for RSA. + key_type: Vec, + /// If this is an RSA key, this is the value of the modulus as an unsigned integer. + modulus: Option>, + /// If this is an EC key, this is the DER bytes of the OID identifying the curve the key is on. + ec_params: Option>, + /// An enum identifying this key's type. + key_type_enum: KeyType, + /// Which slot this key should be exposed on. + slot_type: SlotType, +} + +impl Key { + fn new(cert_context: PCCERT_CONTEXT) -> Result { + let cert = unsafe { *cert_context }; + let cert_der = + unsafe { slice::from_raw_parts(cert.pbCertEncoded, cert.cbCertEncoded as usize) }; + let id = Sha256::digest(cert_der).to_vec(); + let id = id.to_vec(); + let cert_info = unsafe { &*cert.pCertInfo }; + let mut modulus = None; + let mut ec_params = None; + let spki = &cert_info.SubjectPublicKeyInfo; + let algorithm_oid = unsafe { CStr::from_ptr(spki.Algorithm.pszObjId) } + .to_str() + .map_err(|_| ())?; + let (key_type_enum, key_type_attribute) = if algorithm_oid == szOID_RSA_RSA { + if spki.PublicKey.cUnusedBits != 0 { + return Err(()); + } + let public_key_bytes = unsafe { + std::slice::from_raw_parts(spki.PublicKey.pbData, spki.PublicKey.cbData as usize) + }; + let modulus_value = read_rsa_modulus(public_key_bytes)?; + modulus = Some(modulus_value); + (KeyType::RSA, CKK_RSA) + } else if algorithm_oid == szOID_ECC_PUBLIC_KEY { + let params = &spki.Algorithm.Parameters; + ec_params = Some( + unsafe { std::slice::from_raw_parts(params.pbData, params.cbData as usize) } + .to_vec(), + ); + (KeyType::EC, CKK_EC) + } else { + return Err(()); + }; + let cert = CertContext::new(cert_context); + Ok(Key { + cert, + class: serialize_uint(CKO_PRIVATE_KEY)?, + token: serialize_uint(CK_TRUE)?, + id, + private: serialize_uint(CK_TRUE)?, + key_type: serialize_uint(key_type_attribute)?, + modulus, + ec_params, + key_type_enum, + slot_type: SlotType::Modern, + }) + } + + fn class(&self) -> &[u8] { + &self.class + } + + fn token(&self) -> &[u8] { + &self.token + } + + pub fn id(&self) -> &[u8] { + &self.id + } + + fn private(&self) -> &[u8] { + &self.private + } + + fn key_type(&self) -> &[u8] { + &self.key_type + } + + fn modulus(&self) -> Option<&[u8]> { + match &self.modulus { + Some(modulus) => Some(modulus.as_slice()), + None => None, + } + } + + fn ec_params(&self) -> Option<&[u8]> { + match &self.ec_params { + Some(ec_params) => Some(ec_params.as_slice()), + None => None, + } + } + + fn matches(&self, slot_type: SlotType, attrs: &[(CK_ATTRIBUTE_TYPE, Vec)]) -> bool { + if slot_type != self.slot_type { + return false; + } + for (attr_type, attr_value) in attrs { + let comparison = match *attr_type { + CKA_CLASS => self.class(), + CKA_TOKEN => self.token(), + CKA_ID => self.id(), + CKA_PRIVATE => self.private(), + CKA_KEY_TYPE => self.key_type(), + CKA_MODULUS => { + if let Some(modulus) = self.modulus() { + modulus + } else { + return false; + } + } + CKA_EC_PARAMS => { + if let Some(ec_params) = self.ec_params() { + ec_params + } else { + return false; + } + } + _ => return false, + }; + if attr_value.as_slice() != comparison { + return false; + } + } + true + } + + fn get_attribute(&self, attribute: CK_ATTRIBUTE_TYPE) -> Option<&[u8]> { + match attribute { + CKA_CLASS => Some(self.class()), + CKA_TOKEN => Some(self.token()), + CKA_ID => Some(self.id()), + CKA_PRIVATE => Some(self.private()), + CKA_KEY_TYPE => Some(self.key_type()), + CKA_MODULUS => self.modulus(), + CKA_EC_PARAMS => self.ec_params(), + _ => None, + } + } + + pub fn get_signature_length( + &self, + data: &[u8], + params: &Option, + ) -> Result { + match self.sign_internal(data, params, false) { + Ok(dummy_signature_bytes) => Ok(dummy_signature_bytes.len()), + Err(()) => Err(()), + } + } + + pub fn sign( + &self, + data: &[u8], + params: &Option, + ) -> Result, ()> { + self.sign_internal(data, params, true) + } + + /// data: the data to sign + /// do_signature: if true, actually perform the signature. Otherwise, return a `Vec` of the + /// length the signature would be, if performed. + fn sign_internal( + &self, + data: &[u8], + params: &Option, + do_signature: bool, + ) -> Result, ()> { + // Acquiring a handle on the key can cause the OS to show some UI to the user, so we do this + // as late as possible (i.e. here). + let key = KeyHandle::from_cert(&self.cert)?; + key.sign(data, params, do_signature, self.key_type_enum) + } +} + +/// A helper enum that represents the two types of PKCS #11 objects we support: certificates and +/// keys. +pub enum Object { + Cert(Cert), + Key(Key), +} + +impl Object { + pub fn matches(&self, slot_type: SlotType, attrs: &[(CK_ATTRIBUTE_TYPE, Vec)]) -> bool { + match self { + Object::Cert(cert) => cert.matches(slot_type, attrs), + Object::Key(key) => key.matches(slot_type, attrs), + } + } + + pub fn get_attribute(&self, attribute: CK_ATTRIBUTE_TYPE) -> Option<&[u8]> { + match self { + Object::Cert(cert) => cert.get_attribute(attribute), + Object::Key(key) => key.get_attribute(attribute), + } + } +} + +struct CertStore { + handle: HCERTSTORE, +} + +impl Drop for CertStore { + fn drop(&mut self) { + if !self.handle.is_null() { + unsafe { + CertCloseStore(self.handle, 0); + } + } + } +} + +impl Deref for CertStore { + type Target = HCERTSTORE; + + fn deref(&self) -> &Self::Target { + &self.handle + } +} + +impl CertStore { + fn new(handle: HCERTSTORE) -> CertStore { + CertStore { handle } + } +} + +pub const SUPPORTED_ATTRIBUTES: &[CK_ATTRIBUTE_TYPE] = &[ + CKA_CLASS, + CKA_TOKEN, + CKA_LABEL, + CKA_ID, + CKA_VALUE, + CKA_ISSUER, + CKA_SERIAL_NUMBER, + CKA_SUBJECT, + CKA_PRIVATE, + CKA_KEY_TYPE, + CKA_MODULUS, + CKA_EC_PARAMS, +]; + +// Given a pointer to a CERT_CHAIN_CONTEXT, enumerates each chain in the context and each element +// in each chain to gather every CERT_CONTEXT pointed to by the CERT_CHAIN_CONTEXT. +// https://docs.microsoft.com/en-us/windows/win32/api/wincrypt/ns-wincrypt-cert_chain_context says +// that the 0th element of the 0th chain will be the end-entity certificate. This certificate (if +// present), will be the 0th element of the returned Vec. +fn gather_cert_contexts(cert_chain_context: *const CERT_CHAIN_CONTEXT) -> Vec<*const CERT_CONTEXT> { + let mut cert_contexts = Vec::new(); + if cert_chain_context.is_null() { + return cert_contexts; + } + let cert_chain_context = unsafe { &*cert_chain_context }; + let cert_chains = unsafe { + std::slice::from_raw_parts( + cert_chain_context.rgpChain, + cert_chain_context.cChain as usize, + ) + }; + for cert_chain in cert_chains { + // First dereference the borrow. + let cert_chain = *cert_chain; + if cert_chain.is_null() { + continue; + } + // Then dereference the pointer. + let cert_chain = unsafe { &*cert_chain }; + let chain_elements = unsafe { + std::slice::from_raw_parts(cert_chain.rgpElement, cert_chain.cElement as usize) + }; + for chain_element in chain_elements { + let chain_element = *chain_element; // dereference borrow + if chain_element.is_null() { + continue; + } + let chain_element = unsafe { &*chain_element }; // dereference pointer + cert_contexts.push(chain_element.pCertContext); + } + } + cert_contexts +} + +/// Attempts to enumerate certificates with private keys exposed by the OS. Currently only looks in +/// the "My" cert store of the current user. In the future this may look in more locations. +pub fn list_objects() -> Vec { + let mut objects = Vec::new(); + let location_flags = CERT_SYSTEM_STORE_CURRENT_USER // TODO: loop over multiple locations + | CERT_STORE_OPEN_EXISTING_FLAG + | CERT_STORE_READONLY_FLAG; + let store_name = match CString::new("My") { + Ok(store_name) => store_name, + Err(null_error) => { + error!("CString::new given input with a null byte: {}", null_error); + return objects; + } + }; + let store = CertStore::new(unsafe { + CertOpenStore( + CERT_STORE_PROV_SYSTEM_REGISTRY_A, + 0, + 0, + location_flags, + store_name.as_ptr() as *const winapi::ctypes::c_void, + ) + }); + if store.is_null() { + error!("CertOpenStore failed"); + return objects; + } + let find_params = CERT_CHAIN_FIND_ISSUER_PARA { + cbSize: std::mem::size_of::() as u32, + pszUsageIdentifier: std::ptr::null(), + dwKeySpec: 0, + dwAcquirePrivateKeyFlags: 0, + cIssuer: 0, + rgIssuer: std::ptr::null_mut(), + pfnFindCallback: None, + pvFindArg: std::ptr::null_mut(), + pdwIssuerChainIndex: std::ptr::null_mut(), + pdwIssuerElementIndex: std::ptr::null_mut(), + }; + let mut cert_chain_context: PCCERT_CHAIN_CONTEXT = std::ptr::null_mut(); + loop { + // CertFindChainInStore finds all certificates with private keys in the store. It also + // attempts to build a verified certificate chain to a trust anchor for each certificate. + // We gather and hold onto these extra certificates so that gecko can use them when + // filtering potential client certificates according to the acceptable CAs list sent by + // servers when they request client certificates. + cert_chain_context = unsafe { + CertFindChainInStore( + *store, + X509_ASN_ENCODING, + CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_FLAG + | CERT_CHAIN_FIND_BY_ISSUER_CACHE_ONLY_URL_FLAG, + CERT_CHAIN_FIND_BY_ISSUER, + &find_params as *const CERT_CHAIN_FIND_ISSUER_PARA as *const winapi::ctypes::c_void, + cert_chain_context, + ) + }; + if cert_chain_context.is_null() { + break; + } + let cert_contexts = gather_cert_contexts(cert_chain_context); + // The 0th CERT_CONTEXT is the end-entity (i.e. the certificate with the private key we're + // after). + match cert_contexts.get(0) { + Some(cert_context) => { + let key = match Key::new(*cert_context) { + Ok(key) => key, + Err(()) => continue, + }; + let cert = match Cert::new(*cert_context) { + Ok(cert) => cert, + Err(()) => continue, + }; + objects.push(Object::Cert(cert)); + objects.push(Object::Key(key)); + } + None => {} + }; + for cert_context in cert_contexts.iter().skip(1) { + if let Ok(cert) = Cert::new(*cert_context) { + objects.push(Object::Cert(cert)); + } + } + } + objects +} diff --git a/security/manager/ssl/osclientcerts/src/bindings_macos.rs b/security/manager/ssl/osclientcerts/src/bindings_macos.rs new file mode 100644 index 0000000000..14aff193b3 --- /dev/null +++ b/security/manager/ssl/osclientcerts/src/bindings_macos.rs @@ -0,0 +1,58 @@ +/* -*- Mode: rust; rust-indent-offset: 4 -*- */ +/* 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/. */ + +// This was originally generated by rust-bindgen at build time. Later in +// development it became clear that using bindgen for this library as part of +// mozilla-central would be difficult (if not impossible). So, this was +// converted to a static file and unused declarations were removed. Also, +// intermediate types added by rust-bindgen were removed for clarity. + +pub type OSStatus = i32; +pub const errSecSuccess: OSStatus = 0; + +pub type SecKeyAlgorithm = CFStringRef; + +extern "C" { + // Available starting macOS 10.3 + pub fn SecCertificateGetTypeID() -> CFTypeID; + pub fn SecTrustCreateWithCertificates( + certificates: SecCertificateRef, + policies: SecPolicyRef, + trust: *mut SecTrustRef, + ) -> OSStatus; + pub fn SecIdentityGetTypeID() -> CFTypeID; + pub fn SecIdentityCopyCertificate( + identityRef: SecIdentityRef, + certificateRef: *mut SecCertificateRef, + ) -> OSStatus; + pub fn SecIdentityCopyPrivateKey( + identityRef: SecIdentityRef, + privateKeyRef: *mut SecKeyRef, + ) -> OSStatus; + pub fn SecKeyGetTypeID() -> CFTypeID; + pub fn SecPolicyGetTypeID() -> CFTypeID; + pub fn SecTrustGetTypeID() -> CFTypeID; + + // Available starting macOS 10.6 + pub fn SecCertificateCopyData(certificate: SecCertificateRef) -> CFDataRef; + pub fn SecCertificateCopySubjectSummary(certificate: SecCertificateRef) -> CFStringRef; + pub fn SecItemCopyMatching(query: CFDictionaryRef, result: *mut CFTypeRef) -> OSStatus; + pub fn SecPolicyCreateSSL(server: bool, hostname: CFStringRef) -> SecPolicyRef; + pub static kSecClass: CFStringRef; + pub static kSecAttrKeyType: CFStringRef; + pub static kSecAttrKeySizeInBits: CFStringRef; + pub static kSecMatchLimit: CFStringRef; + pub static kSecMatchLimitAll: CFStringRef; + pub static kSecReturnRef: CFStringRef; + + // Available starting macOS 10.7 + pub fn SecTrustGetCertificateAtIndex(trust: SecTrustRef, ix: CFIndex) -> SecCertificateRef; + pub fn SecTrustGetCertificateCount(trust: SecTrustRef) -> CFIndex; + pub static kSecClassIdentity: CFStringRef; + pub static kSecAttrKeyTypeRSA: CFStringRef; + + // Available starting macOS 10.9 + pub fn SecTrustSetNetworkFetchAllowed(trust: SecTrustRef, allowFetch: Boolean) -> OSStatus; +} diff --git a/security/manager/ssl/osclientcerts/src/lib.rs b/security/manager/ssl/osclientcerts/src/lib.rs new file mode 100644 index 0000000000..f53f45f142 --- /dev/null +++ b/security/manager/ssl/osclientcerts/src/lib.rs @@ -0,0 +1,1208 @@ +/* -*- Mode: rust; rust-indent-offset: 4 -*- */ +/* 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/. */ + +#![allow(non_snake_case)] + +extern crate byteorder; +#[cfg(target_os = "macos")] +#[macro_use] +extern crate core_foundation; +extern crate env_logger; +#[macro_use] +extern crate lazy_static; +#[cfg(target_os = "macos")] +extern crate libloading; +#[macro_use] +extern crate log; +extern crate pkcs11; +#[cfg(target_os = "macos")] +#[macro_use] +extern crate rental; +extern crate sha2; +#[cfg(target_os = "windows")] +extern crate winapi; + +use pkcs11::types::*; +use std::sync::Mutex; +use std::thread; + +mod manager; +#[macro_use] +mod util; +#[cfg(target_os = "macos")] +mod backend_macos; +#[cfg(target_os = "windows")] +mod backend_windows; + +use manager::{ManagerProxy, SlotType}; + +lazy_static! { + /// The singleton `ManagerProxy` that handles state with respect to PKCS #11. Only one thread + /// may use it at a time, but there is no restriction on which threads may use it. However, as + /// OS APIs being used are not necessarily thread-safe (e.g. they may be using + /// thread-local-storage), the `ManagerProxy` forwards calls from any thread to a single thread + /// where the real `Manager` does the actual work. + static ref MANAGER_PROXY: Mutex> = Mutex::new(None); +} + +// Obtaining a handle on the manager proxy is a two-step process. First the mutex must be locked, +// which (if successful), results in a mutex guard object. We must then get a mutable refence to the +// underlying manager proxy (if set - otherwise we return an error). This can't happen all in one +// macro without dropping a reference that needs to live long enough for this to be safe. In +// practice, this looks like: +// let mut manager_guard = try_to_get_manager_guard!(); +// let manager = manager_guard_to_manager!(manager_guard); +macro_rules! try_to_get_manager_guard { + () => { + match MANAGER_PROXY.lock() { + Ok(maybe_manager_proxy) => maybe_manager_proxy, + Err(poison_error) => { + log_with_thread_id!( + error, + "previous thread panicked acquiring manager lock: {}", + poison_error + ); + return CKR_DEVICE_ERROR; + } + } + }; +} + +macro_rules! manager_guard_to_manager { + ($manager_guard:ident) => { + match $manager_guard.as_mut() { + Some(manager_proxy) => manager_proxy, + None => { + log_with_thread_id!(error, "manager expected to be set, but it is not"); + return CKR_DEVICE_ERROR; + } + } + }; +} + +// Helper macro to prefix log messages with the current thread ID. +macro_rules! log_with_thread_id { + ($log_level:ident, $($message:expr),*) => { + let message = format!($($message),*); + $log_level!("{:?} {}", thread::current().id(), message); + }; +} + +/// This gets called to initialize the module. For this implementation, this consists of +/// instantiating the `ManagerProxy`. +extern "C" fn C_Initialize(_pInitArgs: CK_C_INITIALIZE_ARGS_PTR) -> CK_RV { + // This will fail if this has already been called, but this isn't a problem because either way, + // logging has been initialized. + let _ = env_logger::try_init(); + let mut manager_guard = try_to_get_manager_guard!(); + match manager_guard.replace(ManagerProxy::new()) { + Some(_unexpected_previous_manager) => { + #[cfg(target_os = "macos")] + { + log_with_thread_id!(info, "C_Initialize: manager previously set (this is expected on macOS - replacing it)"); + } + #[cfg(target_os = "windows")] + { + log_with_thread_id!(warn, "C_Initialize: manager unexpectedly previously set (bravely continuing by replacing it)"); + } + } + None => {} + } + log_with_thread_id!(debug, "C_Initialize: CKR_OK"); + CKR_OK +} + +extern "C" fn C_Finalize(_pReserved: CK_VOID_PTR) -> CK_RV { + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + match manager.stop() { + Ok(()) => { + log_with_thread_id!(debug, "C_Finalize: CKR_OK"); + CKR_OK + } + Err(()) => { + log_with_thread_id!(error, "C_Finalize: CKR_DEVICE_ERROR"); + CKR_DEVICE_ERROR + } + } +} + +// The specification mandates that these strings be padded with spaces to the appropriate length. +// Since the length of fixed-size arrays in rust is part of the type, the compiler enforces that +// these byte strings are of the correct length. +const MANUFACTURER_ID_BYTES: &[u8; 32] = b"Mozilla Corporation "; +const LIBRARY_DESCRIPTION_BYTES: &[u8; 32] = b"OS Client Cert Module "; + +/// This gets called to gather some information about the module. In particular, this implementation +/// supports (portions of) cryptoki (PKCS #11) version 2.2. +extern "C" fn C_GetInfo(pInfo: CK_INFO_PTR) -> CK_RV { + if pInfo.is_null() { + log_with_thread_id!(error, "C_GetInfo: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + log_with_thread_id!(debug, "C_GetInfo: CKR_OK"); + let mut info = CK_INFO::default(); + info.cryptokiVersion.major = 2; + info.cryptokiVersion.minor = 2; + info.manufacturerID = *MANUFACTURER_ID_BYTES; + info.libraryDescription = *LIBRARY_DESCRIPTION_BYTES; + unsafe { + *pInfo = info; + } + CKR_OK +} + +/// This module has two slots. +const SLOT_COUNT: CK_ULONG = 2; +/// The slot with ID 1 supports modern mechanisms like RSA-PSS. +const SLOT_ID_MODERN: CK_SLOT_ID = 1; +/// The slot with ID 2 only supports legacy mechanisms. +const SLOT_ID_LEGACY: CK_SLOT_ID = 2; + +/// This gets called twice: once with a null `pSlotList` to get the number of slots (returned via +/// `pulCount`) and a second time to get the ID for each slot. +extern "C" fn C_GetSlotList( + _tokenPresent: CK_BBOOL, + pSlotList: CK_SLOT_ID_PTR, + pulCount: CK_ULONG_PTR, +) -> CK_RV { + if pulCount.is_null() { + log_with_thread_id!(error, "C_GetSlotList: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + if !pSlotList.is_null() { + if unsafe { *pulCount } < SLOT_COUNT { + log_with_thread_id!(error, "C_GetSlotList: CKR_BUFFER_TOO_SMALL"); + return CKR_BUFFER_TOO_SMALL; + } + unsafe { + *pSlotList = SLOT_ID_MODERN; + *pSlotList.offset(1) = SLOT_ID_LEGACY; + } + }; + unsafe { + *pulCount = SLOT_COUNT; + } + log_with_thread_id!(debug, "C_GetSlotList: CKR_OK"); + CKR_OK +} + +const SLOT_DESCRIPTION_MODERN_BYTES: &[u8; 64] = + b"OS Client Cert Slot (Modern) "; +const SLOT_DESCRIPTION_LEGACY_BYTES: &[u8; 64] = + b"OS Client Cert Slot (Legacy) "; + +/// This gets called to obtain information about slots. In this implementation, the tokens are +/// always present in the slots. +extern "C" fn C_GetSlotInfo(slotID: CK_SLOT_ID, pInfo: CK_SLOT_INFO_PTR) -> CK_RV { + if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || pInfo.is_null() { + log_with_thread_id!(error, "C_GetSlotInfo: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + let description = if slotID == SLOT_ID_MODERN { + SLOT_DESCRIPTION_MODERN_BYTES + } else { + SLOT_DESCRIPTION_LEGACY_BYTES + }; + let slot_info = CK_SLOT_INFO { + slotDescription: *description, + manufacturerID: *MANUFACTURER_ID_BYTES, + flags: CKF_TOKEN_PRESENT, + hardwareVersion: CK_VERSION::default(), + firmwareVersion: CK_VERSION::default(), + }; + unsafe { + *pInfo = slot_info; + } + log_with_thread_id!(debug, "C_GetSlotInfo: CKR_OK"); + CKR_OK +} + +const TOKEN_LABEL_MODERN_BYTES: &[u8; 32] = b"OS Client Cert Token (Modern) "; +const TOKEN_LABEL_LEGACY_BYTES: &[u8; 32] = b"OS Client Cert Token (Legacy) "; +const TOKEN_MODEL_BYTES: &[u8; 16] = b"osclientcerts "; +const TOKEN_SERIAL_NUMBER_BYTES: &[u8; 16] = b"0000000000000000"; + +/// This gets called to obtain some information about tokens. This implementation has two slots, +/// so it has two tokens. This information is primarily for display purposes. +extern "C" fn C_GetTokenInfo(slotID: CK_SLOT_ID, pInfo: CK_TOKEN_INFO_PTR) -> CK_RV { + if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || pInfo.is_null() { + log_with_thread_id!(error, "C_GetTokenInfo: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + let mut token_info = CK_TOKEN_INFO::default(); + let label = if slotID == SLOT_ID_MODERN { + TOKEN_LABEL_MODERN_BYTES + } else { + TOKEN_LABEL_LEGACY_BYTES + }; + token_info.label = *label; + token_info.manufacturerID = *MANUFACTURER_ID_BYTES; + token_info.model = *TOKEN_MODEL_BYTES; + token_info.serialNumber = *TOKEN_SERIAL_NUMBER_BYTES; + unsafe { + *pInfo = token_info; + } + log_with_thread_id!(debug, "C_GetTokenInfo: CKR_OK"); + CKR_OK +} + +/// This gets called to determine what mechanisms a slot supports. The modern slot supports ECDSA, +/// RSA PKCS, and RSA PSS. The legacy slot only supports RSA PKCS. +extern "C" fn C_GetMechanismList( + slotID: CK_SLOT_ID, + pMechanismList: CK_MECHANISM_TYPE_PTR, + pulCount: CK_ULONG_PTR, +) -> CK_RV { + if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || pulCount.is_null() { + log_with_thread_id!(error, "C_GetMechanismList: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + let mechanisms = if slotID == SLOT_ID_MODERN { + vec![CKM_ECDSA, CKM_RSA_PKCS, CKM_RSA_PKCS_PSS] + } else { + vec![CKM_RSA_PKCS] + }; + if !pMechanismList.is_null() { + if unsafe { *pulCount as usize } < mechanisms.len() { + log_with_thread_id!(error, "C_GetMechanismList: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + for i in 0..mechanisms.len() { + unsafe { + *pMechanismList.offset(i as isize) = mechanisms[i]; + } + } + } + unsafe { + *pulCount = mechanisms.len() as CK_ULONG; + } + log_with_thread_id!(debug, "C_GetMechanismList: CKR_OK"); + CKR_OK +} + +extern "C" fn C_GetMechanismInfo( + _slotID: CK_SLOT_ID, + _type: CK_MECHANISM_TYPE, + _pInfo: CK_MECHANISM_INFO_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_GetMechanismInfo: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_InitToken( + _slotID: CK_SLOT_ID, + _pPin: CK_UTF8CHAR_PTR, + _ulPinLen: CK_ULONG, + _pLabel: CK_UTF8CHAR_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_InitToken: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_InitPIN( + _hSession: CK_SESSION_HANDLE, + _pPin: CK_UTF8CHAR_PTR, + _ulPinLen: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_InitPIN: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_SetPIN( + _hSession: CK_SESSION_HANDLE, + _pOldPin: CK_UTF8CHAR_PTR, + _ulOldLen: CK_ULONG, + _pNewPin: CK_UTF8CHAR_PTR, + _ulNewLen: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_SetPIN: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +/// This gets called to create a new session. This module defers to the `ManagerProxy` to implement +/// this. +extern "C" fn C_OpenSession( + slotID: CK_SLOT_ID, + _flags: CK_FLAGS, + _pApplication: CK_VOID_PTR, + _Notify: CK_NOTIFY, + phSession: CK_SESSION_HANDLE_PTR, +) -> CK_RV { + if (slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY) || phSession.is_null() { + log_with_thread_id!(error, "C_OpenSession: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + let slot_type = if slotID == SLOT_ID_MODERN { + SlotType::Modern + } else { + SlotType::Legacy + }; + let session_handle = match manager.open_session(slot_type) { + Ok(session_handle) => session_handle, + Err(()) => { + log_with_thread_id!(error, "C_OpenSession: open_session failed"); + return CKR_DEVICE_ERROR; + } + }; + unsafe { + *phSession = session_handle; + } + log_with_thread_id!(debug, "C_OpenSession: CKR_OK"); + CKR_OK +} + +/// This gets called to close a session. This is handled by the `ManagerProxy`. +extern "C" fn C_CloseSession(hSession: CK_SESSION_HANDLE) -> CK_RV { + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + if manager.close_session(hSession).is_err() { + log_with_thread_id!(error, "C_CloseSession: CKR_SESSION_HANDLE_INVALID"); + return CKR_SESSION_HANDLE_INVALID; + } + log_with_thread_id!(debug, "C_CloseSession: CKR_OK"); + CKR_OK +} + +/// This gets called to close all open sessions at once. This is handled by the `ManagerProxy`. +extern "C" fn C_CloseAllSessions(slotID: CK_SLOT_ID) -> CK_RV { + if slotID != SLOT_ID_MODERN && slotID != SLOT_ID_LEGACY { + log_with_thread_id!(error, "C_CloseAllSessions: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + let slot_type = if slotID == SLOT_ID_MODERN { + SlotType::Modern + } else { + SlotType::Legacy + }; + match manager.close_all_sessions(slot_type) { + Ok(()) => { + log_with_thread_id!(debug, "C_CloseAllSessions: CKR_OK"); + CKR_OK + } + Err(()) => { + log_with_thread_id!(error, "C_CloseAllSessions: close_all_sessions failed"); + CKR_DEVICE_ERROR + } + } +} + +extern "C" fn C_GetSessionInfo(_hSession: CK_SESSION_HANDLE, _pInfo: CK_SESSION_INFO_PTR) -> CK_RV { + log_with_thread_id!(error, "C_GetSessionInfo: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_GetOperationState( + _hSession: CK_SESSION_HANDLE, + _pOperationState: CK_BYTE_PTR, + _pulOperationStateLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_GetOperationState: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_SetOperationState( + _hSession: CK_SESSION_HANDLE, + _pOperationState: CK_BYTE_PTR, + _ulOperationStateLen: CK_ULONG, + _hEncryptionKey: CK_OBJECT_HANDLE, + _hAuthenticationKey: CK_OBJECT_HANDLE, +) -> CK_RV { + log_with_thread_id!(error, "C_SetOperationState: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_Login( + _hSession: CK_SESSION_HANDLE, + _userType: CK_USER_TYPE, + _pPin: CK_UTF8CHAR_PTR, + _ulPinLen: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_Login: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +/// This gets called to log out and drop any authenticated resources. Because this module does not +/// hold on to authenticated resources, this module "implements" this by doing nothing and +/// returning a success result. +extern "C" fn C_Logout(_hSession: CK_SESSION_HANDLE) -> CK_RV { + log_with_thread_id!(debug, "C_Logout: CKR_OK"); + CKR_OK +} + +extern "C" fn C_CreateObject( + _hSession: CK_SESSION_HANDLE, + _pTemplate: CK_ATTRIBUTE_PTR, + _ulCount: CK_ULONG, + _phObject: CK_OBJECT_HANDLE_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_CreateObject: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_CopyObject( + _hSession: CK_SESSION_HANDLE, + _hObject: CK_OBJECT_HANDLE, + _pTemplate: CK_ATTRIBUTE_PTR, + _ulCount: CK_ULONG, + _phNewObject: CK_OBJECT_HANDLE_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_CopyObject: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DestroyObject(_hSession: CK_SESSION_HANDLE, _hObject: CK_OBJECT_HANDLE) -> CK_RV { + log_with_thread_id!(error, "C_DestroyObject: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_GetObjectSize( + _hSession: CK_SESSION_HANDLE, + _hObject: CK_OBJECT_HANDLE, + _pulSize: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_GetObjectSize: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +/// This gets called to obtain the values of a number of attributes of an object identified by the +/// given handle. This module implements this by requesting that the `ManagerProxy` find the object +/// and attempt to get the value of each attribute. If a specified attribute is not defined on the +/// object, the length of that attribute is set to -1 to indicate that it is not available. +/// This gets called twice: once to obtain the lengths of the attributes and again to get the +/// values. +extern "C" fn C_GetAttributeValue( + _hSession: CK_SESSION_HANDLE, + hObject: CK_OBJECT_HANDLE, + pTemplate: CK_ATTRIBUTE_PTR, + ulCount: CK_ULONG, +) -> CK_RV { + if pTemplate.is_null() { + log_with_thread_id!(error, "C_GetAttributeValue: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + let mut attr_types = Vec::with_capacity(ulCount as usize); + for i in 0..ulCount { + let attr = unsafe { &*pTemplate.offset(i as isize) }; + attr_types.push(attr.attrType); + } + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + let values = match manager.get_attributes(hObject, attr_types) { + Ok(values) => values, + Err(()) => { + log_with_thread_id!(error, "C_GetAttributeValue: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + }; + if values.len() != ulCount as usize { + log_with_thread_id!( + error, + "C_GetAttributeValue: manager.get_attributes didn't return the right number of values" + ); + return CKR_DEVICE_ERROR; + } + for i in 0..ulCount as usize { + let mut attr = unsafe { &mut *pTemplate.offset(i as isize) }; + // NB: the safety of this array access depends on the length check above + if let Some(attr_value) = &values[i] { + if attr.pValue.is_null() { + attr.ulValueLen = attr_value.len() as CK_ULONG; + } else { + let ptr: *mut u8 = attr.pValue as *mut u8; + if attr_value.len() != attr.ulValueLen as usize { + log_with_thread_id!(error, "C_GetAttributeValue: incorrect attr size"); + return CKR_ARGUMENTS_BAD; + } + unsafe { + std::ptr::copy_nonoverlapping(attr_value.as_ptr(), ptr, attr_value.len()); + } + } + } else { + attr.ulValueLen = (0 - 1) as CK_ULONG; + } + } + log_with_thread_id!(debug, "C_GetAttributeValue: CKR_OK"); + CKR_OK +} + +extern "C" fn C_SetAttributeValue( + _hSession: CK_SESSION_HANDLE, + _hObject: CK_OBJECT_HANDLE, + _pTemplate: CK_ATTRIBUTE_PTR, + _ulCount: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_SetAttributeValue: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +fn trace_attr(prefix: &str, attr: &CK_ATTRIBUTE) { + let typ = match unsafe_packed_field_access!(attr.attrType) { + CKA_CLASS => "CKA_CLASS".to_string(), + CKA_TOKEN => "CKA_TOKEN".to_string(), + CKA_LABEL => "CKA_LABEL".to_string(), + CKA_ID => "CKA_ID".to_string(), + CKA_VALUE => "CKA_VALUE".to_string(), + CKA_ISSUER => "CKA_ISSUER".to_string(), + CKA_SERIAL_NUMBER => "CKA_SERIAL_NUMBER".to_string(), + CKA_SUBJECT => "CKA_SUBJECT".to_string(), + CKA_PRIVATE => "CKA_PRIVATE".to_string(), + CKA_KEY_TYPE => "CKA_KEY_TYPE".to_string(), + CKA_MODULUS => "CKA_MODULUS".to_string(), + CKA_EC_PARAMS => "CKA_EC_PARAMS".to_string(), + _ => format!("0x{:x}", unsafe_packed_field_access!(attr.attrType)), + }; + let value = + unsafe { std::slice::from_raw_parts(attr.pValue as *const u8, attr.ulValueLen as usize) }; + log_with_thread_id!( + trace, + "{}CK_ATTRIBUTE {{ attrType: {}, pValue: {:?}, ulValueLen: {} }}", + prefix, + typ, + value, + unsafe_packed_field_access!(attr.ulValueLen) + ); +} + +/// This gets called to initialize a search for objects matching a given list of attributes. This +/// module implements this by gathering the attributes and passing them to the `ManagerProxy` to +/// start the search. +extern "C" fn C_FindObjectsInit( + hSession: CK_SESSION_HANDLE, + pTemplate: CK_ATTRIBUTE_PTR, + ulCount: CK_ULONG, +) -> CK_RV { + if pTemplate.is_null() { + log_with_thread_id!(error, "C_FindObjectsInit: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + let mut attrs = Vec::new(); + log_with_thread_id!(trace, "C_FindObjectsInit:"); + for i in 0..ulCount { + let attr = unsafe { &*pTemplate.offset(i as isize) }; + trace_attr(" ", &attr); + let slice = unsafe { + std::slice::from_raw_parts(attr.pValue as *const u8, attr.ulValueLen as usize) + }; + attrs.push((attr.attrType, slice.to_owned())); + } + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + match manager.start_search(hSession, attrs) { + Ok(()) => {} + Err(()) => { + log_with_thread_id!(error, "C_FindObjectsInit: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + } + log_with_thread_id!(debug, "C_FindObjectsInit: CKR_OK"); + CKR_OK +} + +/// This gets called after `C_FindObjectsInit` to get the results of a search. This module +/// implements this by looking up the search in the `ManagerProxy` and copying out the matching +/// object handles. +extern "C" fn C_FindObjects( + hSession: CK_SESSION_HANDLE, + phObject: CK_OBJECT_HANDLE_PTR, + ulMaxObjectCount: CK_ULONG, + pulObjectCount: CK_ULONG_PTR, +) -> CK_RV { + if phObject.is_null() || pulObjectCount.is_null() || ulMaxObjectCount == 0 { + log_with_thread_id!(error, "C_FindObjects: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + let handles = match manager.search(hSession, ulMaxObjectCount as usize) { + Ok(handles) => handles, + Err(()) => { + log_with_thread_id!(error, "C_FindObjects: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + }; + log_with_thread_id!(debug, "C_FindObjects: found handles {:?}", handles); + if handles.len() > ulMaxObjectCount as usize { + log_with_thread_id!(error, "C_FindObjects: manager returned too many handles"); + return CKR_DEVICE_ERROR; + } + unsafe { + *pulObjectCount = handles.len() as CK_ULONG; + } + for (index, handle) in handles.iter().enumerate() { + if index < ulMaxObjectCount as usize { + unsafe { + *(phObject.add(index)) = *handle; + } + } + } + log_with_thread_id!(debug, "C_FindObjects: CKR_OK"); + CKR_OK +} + +/// This gets called after `C_FindObjectsInit` and `C_FindObjects` to finish a search. The module +/// tells the `ManagerProxy` to clear the search. +extern "C" fn C_FindObjectsFinal(hSession: CK_SESSION_HANDLE) -> CK_RV { + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + // It would be an error if there were no search for this session, but we can be permissive here. + match manager.clear_search(hSession) { + Ok(()) => { + log_with_thread_id!(debug, "C_FindObjectsFinal: CKR_OK"); + CKR_OK + } + Err(()) => { + log_with_thread_id!(error, "C_FindObjectsFinal: clear_search failed"); + CKR_DEVICE_ERROR + } + } +} + +extern "C" fn C_EncryptInit( + _hSession: CK_SESSION_HANDLE, + _pMechanism: CK_MECHANISM_PTR, + _hKey: CK_OBJECT_HANDLE, +) -> CK_RV { + log_with_thread_id!(error, "C_EncryptInit: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_Encrypt( + _hSession: CK_SESSION_HANDLE, + _pData: CK_BYTE_PTR, + _ulDataLen: CK_ULONG, + _pEncryptedData: CK_BYTE_PTR, + _pulEncryptedDataLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_Encrypt: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_EncryptUpdate( + _hSession: CK_SESSION_HANDLE, + _pPart: CK_BYTE_PTR, + _ulPartLen: CK_ULONG, + _pEncryptedPart: CK_BYTE_PTR, + _pulEncryptedPartLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_EncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_EncryptFinal( + _hSession: CK_SESSION_HANDLE, + _pLastEncryptedPart: CK_BYTE_PTR, + _pulLastEncryptedPartLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_EncryptFinal: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DecryptInit( + _hSession: CK_SESSION_HANDLE, + _pMechanism: CK_MECHANISM_PTR, + _hKey: CK_OBJECT_HANDLE, +) -> CK_RV { + log_with_thread_id!(error, "C_DecryptInit: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_Decrypt( + _hSession: CK_SESSION_HANDLE, + _pEncryptedData: CK_BYTE_PTR, + _ulEncryptedDataLen: CK_ULONG, + _pData: CK_BYTE_PTR, + _pulDataLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_Decrypt: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DecryptUpdate( + _hSession: CK_SESSION_HANDLE, + _pEncryptedPart: CK_BYTE_PTR, + _ulEncryptedPartLen: CK_ULONG, + _pPart: CK_BYTE_PTR, + _pulPartLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_DecryptUpdate: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DecryptFinal( + _hSession: CK_SESSION_HANDLE, + _pLastPart: CK_BYTE_PTR, + _pulLastPartLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_DecryptFinal: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DigestInit(_hSession: CK_SESSION_HANDLE, _pMechanism: CK_MECHANISM_PTR) -> CK_RV { + log_with_thread_id!(error, "C_DigestInit: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_Digest( + _hSession: CK_SESSION_HANDLE, + _pData: CK_BYTE_PTR, + _ulDataLen: CK_ULONG, + _pDigest: CK_BYTE_PTR, + _pulDigestLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_Digest: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DigestUpdate( + _hSession: CK_SESSION_HANDLE, + _pPart: CK_BYTE_PTR, + _ulPartLen: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_DigestUpdate: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DigestKey(_hSession: CK_SESSION_HANDLE, _hKey: CK_OBJECT_HANDLE) -> CK_RV { + log_with_thread_id!(error, "C_DigestKey: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DigestFinal( + _hSession: CK_SESSION_HANDLE, + _pDigest: CK_BYTE_PTR, + _pulDigestLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_DigestFinal: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +/// This gets called to set up a sign operation. The module essentially defers to the +/// `ManagerProxy`. +extern "C" fn C_SignInit( + hSession: CK_SESSION_HANDLE, + pMechanism: CK_MECHANISM_PTR, + hKey: CK_OBJECT_HANDLE, +) -> CK_RV { + if pMechanism.is_null() { + log_with_thread_id!(error, "C_SignInit: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + // Presumably we should validate the mechanism against hKey, but the specification doesn't + // actually seem to require this. + let mechanism = unsafe { *pMechanism }; + log_with_thread_id!(debug, "C_SignInit: mechanism is {:?}", mechanism); + let mechanism_params = if mechanism.mechanism == CKM_RSA_PKCS_PSS { + if mechanism.ulParameterLen as usize != std::mem::size_of::() { + log_with_thread_id!( + error, + "C_SignInit: bad ulParameterLen for CKM_RSA_PKCS_PSS: {}", + unsafe_packed_field_access!(mechanism.ulParameterLen) + ); + return CKR_ARGUMENTS_BAD; + } + Some(unsafe { *(mechanism.pParameter as *const CK_RSA_PKCS_PSS_PARAMS) }) + } else { + None + }; + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + match manager.start_sign(hSession, hKey, mechanism_params) { + Ok(()) => {} + Err(()) => { + log_with_thread_id!(error, "C_SignInit: CKR_GENERAL_ERROR"); + return CKR_GENERAL_ERROR; + } + }; + log_with_thread_id!(debug, "C_SignInit: CKR_OK"); + CKR_OK +} + +/// NSS calls this after `C_SignInit` (there are more ways in the PKCS #11 specification to sign +/// data, but this is the only way supported by this module). The module essentially defers to the +/// `ManagerProxy` and copies out the resulting signature. +extern "C" fn C_Sign( + hSession: CK_SESSION_HANDLE, + pData: CK_BYTE_PTR, + ulDataLen: CK_ULONG, + pSignature: CK_BYTE_PTR, + pulSignatureLen: CK_ULONG_PTR, +) -> CK_RV { + if pData.is_null() || pulSignatureLen.is_null() { + log_with_thread_id!(error, "C_Sign: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + let data = unsafe { std::slice::from_raw_parts(pData, ulDataLen as usize) }; + if pSignature.is_null() { + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + match manager.get_signature_length(hSession, data.to_vec()) { + Ok(signature_length) => unsafe { + *pulSignatureLen = signature_length as CK_ULONG; + }, + Err(()) => { + log_with_thread_id!(error, "C_Sign: get_signature_length failed"); + return CKR_GENERAL_ERROR; + } + } + } else { + let mut manager_guard = try_to_get_manager_guard!(); + let manager = manager_guard_to_manager!(manager_guard); + match manager.sign(hSession, data.to_vec()) { + Ok(signature) => { + let signature_capacity = unsafe { *pulSignatureLen } as usize; + if signature_capacity < signature.len() { + log_with_thread_id!(error, "C_Sign: CKR_ARGUMENTS_BAD"); + return CKR_ARGUMENTS_BAD; + } + let ptr: *mut u8 = pSignature as *mut u8; + unsafe { + std::ptr::copy_nonoverlapping(signature.as_ptr(), ptr, signature.len()); + *pulSignatureLen = signature.len() as CK_ULONG; + } + } + Err(()) => { + log_with_thread_id!(error, "C_Sign: sign failed"); + return CKR_GENERAL_ERROR; + } + } + } + log_with_thread_id!(debug, "C_Sign: CKR_OK"); + CKR_OK +} + +extern "C" fn C_SignUpdate( + _hSession: CK_SESSION_HANDLE, + _pPart: CK_BYTE_PTR, + _ulPartLen: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_SignUpdate: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_SignFinal( + _hSession: CK_SESSION_HANDLE, + _pSignature: CK_BYTE_PTR, + _pulSignatureLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_SignFinal: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_SignRecoverInit( + _hSession: CK_SESSION_HANDLE, + _pMechanism: CK_MECHANISM_PTR, + _hKey: CK_OBJECT_HANDLE, +) -> CK_RV { + log_with_thread_id!(error, "C_SignRecoverInit: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_SignRecover( + _hSession: CK_SESSION_HANDLE, + _pData: CK_BYTE_PTR, + _ulDataLen: CK_ULONG, + _pSignature: CK_BYTE_PTR, + _pulSignatureLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_SignRecover: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_VerifyInit( + _hSession: CK_SESSION_HANDLE, + _pMechanism: CK_MECHANISM_PTR, + _hKey: CK_OBJECT_HANDLE, +) -> CK_RV { + log_with_thread_id!(error, "C_VerifyInit: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_Verify( + _hSession: CK_SESSION_HANDLE, + _pData: CK_BYTE_PTR, + _ulDataLen: CK_ULONG, + _pSignature: CK_BYTE_PTR, + _ulSignatureLen: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_Verify: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_VerifyUpdate( + _hSession: CK_SESSION_HANDLE, + _pPart: CK_BYTE_PTR, + _ulPartLen: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_VerifyUpdate: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_VerifyFinal( + _hSession: CK_SESSION_HANDLE, + _pSignature: CK_BYTE_PTR, + _ulSignatureLen: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_VerifyFinal: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_VerifyRecoverInit( + _hSession: CK_SESSION_HANDLE, + _pMechanism: CK_MECHANISM_PTR, + _hKey: CK_OBJECT_HANDLE, +) -> CK_RV { + log_with_thread_id!(error, "C_VerifyRecoverInit: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_VerifyRecover( + _hSession: CK_SESSION_HANDLE, + _pSignature: CK_BYTE_PTR, + _ulSignatureLen: CK_ULONG, + _pData: CK_BYTE_PTR, + _pulDataLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_VerifyRecover: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DigestEncryptUpdate( + _hSession: CK_SESSION_HANDLE, + _pPart: CK_BYTE_PTR, + _ulPartLen: CK_ULONG, + _pEncryptedPart: CK_BYTE_PTR, + _pulEncryptedPartLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_DigestEncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DecryptDigestUpdate( + _hSession: CK_SESSION_HANDLE, + _pEncryptedPart: CK_BYTE_PTR, + _ulEncryptedPartLen: CK_ULONG, + _pPart: CK_BYTE_PTR, + _pulPartLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_DecryptDigestUpdate: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_SignEncryptUpdate( + _hSession: CK_SESSION_HANDLE, + _pPart: CK_BYTE_PTR, + _ulPartLen: CK_ULONG, + _pEncryptedPart: CK_BYTE_PTR, + _pulEncryptedPartLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_SignEncryptUpdate: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DecryptVerifyUpdate( + _hSession: CK_SESSION_HANDLE, + _pEncryptedPart: CK_BYTE_PTR, + _ulEncryptedPartLen: CK_ULONG, + _pPart: CK_BYTE_PTR, + _pulPartLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_DecryptVerifyUpdate: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_GenerateKey( + _hSession: CK_SESSION_HANDLE, + _pMechanism: CK_MECHANISM_PTR, + _pTemplate: CK_ATTRIBUTE_PTR, + _ulCount: CK_ULONG, + _phKey: CK_OBJECT_HANDLE_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_GenerateKey: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_GenerateKeyPair( + _hSession: CK_SESSION_HANDLE, + _pMechanism: CK_MECHANISM_PTR, + _pPublicKeyTemplate: CK_ATTRIBUTE_PTR, + _ulPublicKeyAttributeCount: CK_ULONG, + _pPrivateKeyTemplate: CK_ATTRIBUTE_PTR, + _ulPrivateKeyAttributeCount: CK_ULONG, + _phPublicKey: CK_OBJECT_HANDLE_PTR, + _phPrivateKey: CK_OBJECT_HANDLE_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_GenerateKeyPair: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_WrapKey( + _hSession: CK_SESSION_HANDLE, + _pMechanism: CK_MECHANISM_PTR, + _hWrappingKey: CK_OBJECT_HANDLE, + _hKey: CK_OBJECT_HANDLE, + _pWrappedKey: CK_BYTE_PTR, + _pulWrappedKeyLen: CK_ULONG_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_WrapKey: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_UnwrapKey( + _hSession: CK_SESSION_HANDLE, + _pMechanism: CK_MECHANISM_PTR, + _hUnwrappingKey: CK_OBJECT_HANDLE, + _pWrappedKey: CK_BYTE_PTR, + _ulWrappedKeyLen: CK_ULONG, + _pTemplate: CK_ATTRIBUTE_PTR, + _ulAttributeCount: CK_ULONG, + _phKey: CK_OBJECT_HANDLE_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_UnwrapKey: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_DeriveKey( + _hSession: CK_SESSION_HANDLE, + _pMechanism: CK_MECHANISM_PTR, + _hBaseKey: CK_OBJECT_HANDLE, + _pTemplate: CK_ATTRIBUTE_PTR, + _ulAttributeCount: CK_ULONG, + _phKey: CK_OBJECT_HANDLE_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_DeriveKey: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_SeedRandom( + _hSession: CK_SESSION_HANDLE, + _pSeed: CK_BYTE_PTR, + _ulSeedLen: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_SeedRandom: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_GenerateRandom( + _hSession: CK_SESSION_HANDLE, + _RandomData: CK_BYTE_PTR, + _ulRandomLen: CK_ULONG, +) -> CK_RV { + log_with_thread_id!(error, "C_GenerateRandom: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_GetFunctionStatus(_hSession: CK_SESSION_HANDLE) -> CK_RV { + log_with_thread_id!(error, "C_GetFunctionStatus: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_CancelFunction(_hSession: CK_SESSION_HANDLE) -> CK_RV { + log_with_thread_id!(error, "C_CancelFunction: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +extern "C" fn C_WaitForSlotEvent( + _flags: CK_FLAGS, + _pSlot: CK_SLOT_ID_PTR, + _pRserved: CK_VOID_PTR, +) -> CK_RV { + log_with_thread_id!(error, "C_WaitForSlotEvent: CKR_FUNCTION_NOT_SUPPORTED"); + CKR_FUNCTION_NOT_SUPPORTED +} + +/// To be a valid PKCS #11 module, this list of functions must be supported. At least cryptoki 2.2 +/// must be supported for this module to work in NSS. +static mut FUNCTION_LIST: CK_FUNCTION_LIST = CK_FUNCTION_LIST { + version: CK_VERSION { major: 2, minor: 2 }, + C_Initialize: Some(C_Initialize), + C_Finalize: Some(C_Finalize), + C_GetInfo: Some(C_GetInfo), + C_GetFunctionList: None, + C_GetSlotList: Some(C_GetSlotList), + C_GetSlotInfo: Some(C_GetSlotInfo), + C_GetTokenInfo: Some(C_GetTokenInfo), + C_GetMechanismList: Some(C_GetMechanismList), + C_GetMechanismInfo: Some(C_GetMechanismInfo), + C_InitToken: Some(C_InitToken), + C_InitPIN: Some(C_InitPIN), + C_SetPIN: Some(C_SetPIN), + C_OpenSession: Some(C_OpenSession), + C_CloseSession: Some(C_CloseSession), + C_CloseAllSessions: Some(C_CloseAllSessions), + C_GetSessionInfo: Some(C_GetSessionInfo), + C_GetOperationState: Some(C_GetOperationState), + C_SetOperationState: Some(C_SetOperationState), + C_Login: Some(C_Login), + C_Logout: Some(C_Logout), + C_CreateObject: Some(C_CreateObject), + C_CopyObject: Some(C_CopyObject), + C_DestroyObject: Some(C_DestroyObject), + C_GetObjectSize: Some(C_GetObjectSize), + C_GetAttributeValue: Some(C_GetAttributeValue), + C_SetAttributeValue: Some(C_SetAttributeValue), + C_FindObjectsInit: Some(C_FindObjectsInit), + C_FindObjects: Some(C_FindObjects), + C_FindObjectsFinal: Some(C_FindObjectsFinal), + C_EncryptInit: Some(C_EncryptInit), + C_Encrypt: Some(C_Encrypt), + C_EncryptUpdate: Some(C_EncryptUpdate), + C_EncryptFinal: Some(C_EncryptFinal), + C_DecryptInit: Some(C_DecryptInit), + C_Decrypt: Some(C_Decrypt), + C_DecryptUpdate: Some(C_DecryptUpdate), + C_DecryptFinal: Some(C_DecryptFinal), + C_DigestInit: Some(C_DigestInit), + C_Digest: Some(C_Digest), + C_DigestUpdate: Some(C_DigestUpdate), + C_DigestKey: Some(C_DigestKey), + C_DigestFinal: Some(C_DigestFinal), + C_SignInit: Some(C_SignInit), + C_Sign: Some(C_Sign), + C_SignUpdate: Some(C_SignUpdate), + C_SignFinal: Some(C_SignFinal), + C_SignRecoverInit: Some(C_SignRecoverInit), + C_SignRecover: Some(C_SignRecover), + C_VerifyInit: Some(C_VerifyInit), + C_Verify: Some(C_Verify), + C_VerifyUpdate: Some(C_VerifyUpdate), + C_VerifyFinal: Some(C_VerifyFinal), + C_VerifyRecoverInit: Some(C_VerifyRecoverInit), + C_VerifyRecover: Some(C_VerifyRecover), + C_DigestEncryptUpdate: Some(C_DigestEncryptUpdate), + C_DecryptDigestUpdate: Some(C_DecryptDigestUpdate), + C_SignEncryptUpdate: Some(C_SignEncryptUpdate), + C_DecryptVerifyUpdate: Some(C_DecryptVerifyUpdate), + C_GenerateKey: Some(C_GenerateKey), + C_GenerateKeyPair: Some(C_GenerateKeyPair), + C_WrapKey: Some(C_WrapKey), + C_UnwrapKey: Some(C_UnwrapKey), + C_DeriveKey: Some(C_DeriveKey), + C_SeedRandom: Some(C_SeedRandom), + C_GenerateRandom: Some(C_GenerateRandom), + C_GetFunctionStatus: Some(C_GetFunctionStatus), + C_CancelFunction: Some(C_CancelFunction), + C_WaitForSlotEvent: Some(C_WaitForSlotEvent), +}; + +/// This is the only function this module exposes. NSS calls it to obtain the list of functions +/// comprising this module. +#[no_mangle] +pub extern "C" fn C_GetFunctionList(ppFunctionList: CK_FUNCTION_LIST_PTR_PTR) -> CK_RV { + if ppFunctionList.is_null() { + return CKR_ARGUMENTS_BAD; + } + unsafe { + *ppFunctionList = &mut FUNCTION_LIST; + } + CKR_OK +} + +#[cfg_attr(target_os = "macos", link(name = "Security", kind = "framework"))] +extern "C" {} diff --git a/security/manager/ssl/osclientcerts/src/manager.rs b/security/manager/ssl/osclientcerts/src/manager.rs new file mode 100644 index 0000000000..de4be1272a --- /dev/null +++ b/security/manager/ssl/osclientcerts/src/manager.rs @@ -0,0 +1,614 @@ +/* -*- Mode: rust; rust-indent-offset: 4 -*- */ +/* 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/. */ + +use pkcs11::types::*; +use std::collections::{BTreeMap, BTreeSet}; + +#[cfg(target_os = "macos")] +use crate::backend_macos as backend; +#[cfg(target_os = "windows")] +use crate::backend_windows as backend; +use crate::util::*; +use backend::*; + +use std::sync::mpsc::{channel, Receiver, Sender}; +use std::thread; +use std::thread::JoinHandle; +use std::time::{Duration, Instant}; + +/// Helper enum to differentiate between sessions on the modern slot and sessions on the legacy +/// slot. The former is for EC keys and RSA keys that can be used with RSA-PSS whereas the latter is +/// for RSA keys that cannot be used with RSA-PSS. +#[derive(Clone, Copy, PartialEq)] +pub enum SlotType { + Modern, + Legacy, +} + +/// Helper type for sending `ManagerArguments` to the real `Manager`. +type ManagerArgumentsSender = Sender; +/// Helper type for receiving `ManagerReturnValue`s from the real `Manager`. +type ManagerReturnValueReceiver = Receiver; + +/// Helper enum that encapsulates arguments to send from the `ManagerProxy` to the real `Manager`. +/// `ManagerArguments::Stop` is a special variant that stops the background thread and drops the +/// `Manager`. +enum ManagerArguments { + OpenSession(SlotType), + CloseSession(CK_SESSION_HANDLE), + CloseAllSessions(SlotType), + StartSearch(CK_SESSION_HANDLE, Vec<(CK_ATTRIBUTE_TYPE, Vec)>), + Search(CK_SESSION_HANDLE, usize), + ClearSearch(CK_SESSION_HANDLE), + GetAttributes(CK_OBJECT_HANDLE, Vec), + StartSign( + CK_SESSION_HANDLE, + CK_OBJECT_HANDLE, + Option, + ), + GetSignatureLength(CK_SESSION_HANDLE, Vec), + Sign(CK_SESSION_HANDLE, Vec), + Stop, +} + +/// Helper enum that encapsulates return values from the real `Manager` that are sent back to the +/// `ManagerProxy`. `ManagerReturnValue::Stop` is a special variant that indicates that the +/// `Manager` will stop. +enum ManagerReturnValue { + OpenSession(Result), + CloseSession(Result<(), ()>), + CloseAllSessions(Result<(), ()>), + StartSearch(Result<(), ()>), + Search(Result, ()>), + ClearSearch(Result<(), ()>), + GetAttributes(Result>>, ()>), + StartSign(Result<(), ()>), + GetSignatureLength(Result), + Sign(Result, ()>), + Stop(Result<(), ()>), +} + +/// Helper macro to implement the body of each public `ManagerProxy` function. Takes a +/// `ManagerProxy` instance (should always be `self`), a `ManagerArguments` representing the +/// `Manager` function to call and the arguments to use, and the qualified type of the expected +/// `ManagerReturnValue` that will be received from the `Manager` when it is done. +macro_rules! manager_proxy_fn_impl { + ($manager:ident, $argument_enum:expr, $return_type:path) => { + match $manager.proxy_call($argument_enum) { + Ok($return_type(result)) => result, + Ok(_) => { + error!("unexpected return value from manager"); + Err(()) + } + Err(()) => Err(()), + } + }; +} + +/// `ManagerProxy` synchronously proxies calls from any thread to the `Manager` that runs on a +/// single thread. This is necessary because the underlying OS APIs in use are not guaranteed to be +/// thread-safe (e.g. they may use thread-local storage). Using it should be identical to using the +/// real `Manager`. +pub struct ManagerProxy { + sender: ManagerArgumentsSender, + receiver: ManagerReturnValueReceiver, + thread_handle: Option>, +} + +impl ManagerProxy { + pub fn new() -> ManagerProxy { + let (proxy_sender, manager_receiver) = channel(); + let (manager_sender, proxy_receiver) = channel(); + let thread_handle = thread::spawn(move || { + let mut real_manager = Manager::new(); + loop { + let arguments = match manager_receiver.recv() { + Ok(arguments) => arguments, + Err(e) => { + error!("error recv()ing arguments from ManagerProxy: {}", e); + break; + } + }; + let results = match arguments { + ManagerArguments::OpenSession(slot_type) => { + ManagerReturnValue::OpenSession(real_manager.open_session(slot_type)) + } + ManagerArguments::CloseSession(session_handle) => { + ManagerReturnValue::CloseSession(real_manager.close_session(session_handle)) + } + ManagerArguments::CloseAllSessions(slot_type) => { + ManagerReturnValue::CloseAllSessions( + real_manager.close_all_sessions(slot_type), + ) + } + ManagerArguments::StartSearch(session, attrs) => { + ManagerReturnValue::StartSearch(real_manager.start_search(session, &attrs)) + } + ManagerArguments::Search(session, max_objects) => { + ManagerReturnValue::Search(real_manager.search(session, max_objects)) + } + ManagerArguments::ClearSearch(session) => { + ManagerReturnValue::ClearSearch(real_manager.clear_search(session)) + } + ManagerArguments::GetAttributes(object_handle, attr_types) => { + ManagerReturnValue::GetAttributes( + real_manager.get_attributes(object_handle, attr_types), + ) + } + ManagerArguments::StartSign(session, key_handle, params) => { + ManagerReturnValue::StartSign( + real_manager.start_sign(session, key_handle, params), + ) + } + ManagerArguments::GetSignatureLength(session, data) => { + ManagerReturnValue::GetSignatureLength( + real_manager.get_signature_length(session, &data), + ) + } + ManagerArguments::Sign(session, data) => { + ManagerReturnValue::Sign(real_manager.sign(session, &data)) + } + ManagerArguments::Stop => { + debug!("ManagerArguments::Stop received - stopping Manager thread."); + ManagerReturnValue::Stop(Ok(())) + } + }; + let stop_after_send = match &results { + &ManagerReturnValue::Stop(_) => true, + _ => false, + }; + match manager_sender.send(results) { + Ok(()) => {} + Err(e) => { + error!("error send()ing results from Manager: {}", e); + break; + } + } + if stop_after_send { + break; + } + } + }); + ManagerProxy { + sender: proxy_sender, + receiver: proxy_receiver, + thread_handle: Some(thread_handle), + } + } + + fn proxy_call(&self, args: ManagerArguments) -> Result { + match self.sender.send(args) { + Ok(()) => {} + Err(e) => { + error!("error send()ing arguments to Manager: {}", e); + return Err(()); + } + }; + let result = match self.receiver.recv() { + Ok(result) => result, + Err(e) => { + error!("error recv()ing result from Manager: {}", e); + return Err(()); + } + }; + Ok(result) + } + + pub fn open_session(&mut self, slot_type: SlotType) -> Result { + manager_proxy_fn_impl!( + self, + ManagerArguments::OpenSession(slot_type), + ManagerReturnValue::OpenSession + ) + } + + pub fn close_session(&mut self, session: CK_SESSION_HANDLE) -> Result<(), ()> { + manager_proxy_fn_impl!( + self, + ManagerArguments::CloseSession(session), + ManagerReturnValue::CloseSession + ) + } + + pub fn close_all_sessions(&mut self, slot_type: SlotType) -> Result<(), ()> { + manager_proxy_fn_impl!( + self, + ManagerArguments::CloseAllSessions(slot_type), + ManagerReturnValue::CloseAllSessions + ) + } + + pub fn start_search( + &mut self, + session: CK_SESSION_HANDLE, + attrs: Vec<(CK_ATTRIBUTE_TYPE, Vec)>, + ) -> Result<(), ()> { + manager_proxy_fn_impl!( + self, + ManagerArguments::StartSearch(session, attrs), + ManagerReturnValue::StartSearch + ) + } + + pub fn search( + &mut self, + session: CK_SESSION_HANDLE, + max_objects: usize, + ) -> Result, ()> { + manager_proxy_fn_impl!( + self, + ManagerArguments::Search(session, max_objects), + ManagerReturnValue::Search + ) + } + + pub fn clear_search(&mut self, session: CK_SESSION_HANDLE) -> Result<(), ()> { + manager_proxy_fn_impl!( + self, + ManagerArguments::ClearSearch(session), + ManagerReturnValue::ClearSearch + ) + } + + pub fn get_attributes( + &self, + object_handle: CK_OBJECT_HANDLE, + attr_types: Vec, + ) -> Result>>, ()> { + manager_proxy_fn_impl!( + self, + ManagerArguments::GetAttributes(object_handle, attr_types,), + ManagerReturnValue::GetAttributes + ) + } + + pub fn start_sign( + &mut self, + session: CK_SESSION_HANDLE, + key_handle: CK_OBJECT_HANDLE, + params: Option, + ) -> Result<(), ()> { + manager_proxy_fn_impl!( + self, + ManagerArguments::StartSign(session, key_handle, params), + ManagerReturnValue::StartSign + ) + } + + pub fn get_signature_length( + &self, + session: CK_SESSION_HANDLE, + data: Vec, + ) -> Result { + manager_proxy_fn_impl!( + self, + ManagerArguments::GetSignatureLength(session, data), + ManagerReturnValue::GetSignatureLength + ) + } + + pub fn sign(&mut self, session: CK_SESSION_HANDLE, data: Vec) -> Result, ()> { + manager_proxy_fn_impl!( + self, + ManagerArguments::Sign(session, data), + ManagerReturnValue::Sign + ) + } + + pub fn stop(&mut self) -> Result<(), ()> { + manager_proxy_fn_impl!(self, ManagerArguments::Stop, ManagerReturnValue::Stop)?; + let thread_handle = match self.thread_handle.take() { + Some(thread_handle) => thread_handle, + None => { + error!("stop should only be called once"); + return Err(()); + } + }; + match thread_handle.join() { + Ok(()) => {} + Err(e) => { + error!("manager thread panicked: {:?}", e); + return Err(()); + } + }; + Ok(()) + } +} + +// Determines if the attributes of a given search correspond to NSS looking for all certificates or +// private keys. Returns true if so, and false otherwise. +// These searches are of the form: +// { { type: CKA_TOKEN, value: [1] }, +// { type: CKA_CLASS, value: [CKO_CERTIFICATE or CKO_PRIVATE_KEY, as serialized bytes] } } +// (although not necessarily in that order - see nssToken_TraverseCertificates and +// nssToken_FindPrivateKeys) +fn search_is_for_all_certificates_or_keys( + attrs: &[(CK_ATTRIBUTE_TYPE, Vec)], +) -> Result { + if attrs.len() != 2 { + return Ok(false); + } + let token_bytes = vec![1 as u8]; + let mut found_token = false; + let cko_certificate_bytes = serialize_uint(CKO_CERTIFICATE)?; + let cko_private_key_bytes = serialize_uint(CKO_PRIVATE_KEY)?; + let mut found_certificate_or_private_key = false; + for (attr_type, attr_value) in attrs.iter() { + if attr_type == &CKA_TOKEN && attr_value == &token_bytes { + found_token = true; + } + if attr_type == &CKA_CLASS + && (attr_value == &cko_certificate_bytes || attr_value == &cko_private_key_bytes) + { + found_certificate_or_private_key = true; + } + } + Ok(found_token && found_certificate_or_private_key) +} + +/// The `Manager` keeps track of the state of this module with respect to the PKCS #11 +/// specification. This includes what sessions are open, which search and sign operations are +/// ongoing, and what objects are known and by what handle. +struct Manager { + /// A map of session to session type (modern or legacy). Sessions can be created (opened) and + /// later closed. + sessions: BTreeMap, + /// A map of searches to PKCS #11 object handles that match those searches. + searches: BTreeMap>, + /// A map of sign operations to a pair of the object handle and optionally some params being + /// used by each one. + signs: BTreeMap)>, + /// A map of object handles to the underlying objects. + objects: BTreeMap, + /// A set of certificate identifiers (not the same as handles). + cert_ids: BTreeSet>, + /// A set of key identifiers (not the same as handles). For each id in this set, there should be + /// a corresponding identical id in the `cert_ids` set, and vice-versa. + key_ids: BTreeSet>, + /// The next session handle to hand out. + next_session: CK_SESSION_HANDLE, + /// The next object handle to hand out. + next_handle: CK_OBJECT_HANDLE, + /// The last time the implementation looked for new objects in the backend. + /// The implementation does this search no more than once every 3 seconds. + last_scan_time: Option, +} + +impl Manager { + pub fn new() -> Manager { + let mut manager = Manager { + sessions: BTreeMap::new(), + searches: BTreeMap::new(), + signs: BTreeMap::new(), + objects: BTreeMap::new(), + cert_ids: BTreeSet::new(), + key_ids: BTreeSet::new(), + next_session: 1, + next_handle: 1, + last_scan_time: None, + }; + manager.maybe_find_new_objects(); + manager + } + + /// When a new `Manager` is created and when a new session is opened (provided at least 3 + /// seconds have elapsed since the last session was opened), this searches for certificates and + /// keys to expose. We de-duplicate previously-found certificates and keys by / keeping track of + /// their IDs. + fn maybe_find_new_objects(&mut self) { + let now = Instant::now(); + match self.last_scan_time { + Some(last_scan_time) => { + if now.duration_since(last_scan_time) < Duration::new(3, 0) { + return; + } + } + None => {} + } + self.last_scan_time = Some(now); + let objects = list_objects(); + debug!("found {} objects", objects.len()); + for object in objects { + match &object { + Object::Cert(cert) => { + if self.cert_ids.contains(cert.id()) { + continue; + } + self.cert_ids.insert(cert.id().to_vec()); + let handle = self.get_next_handle(); + self.objects.insert(handle, object); + } + Object::Key(key) => { + if self.key_ids.contains(key.id()) { + continue; + } + self.key_ids.insert(key.id().to_vec()); + let handle = self.get_next_handle(); + self.objects.insert(handle, object); + } + } + } + } + + pub fn open_session(&mut self, slot_type: SlotType) -> Result { + let next_session = self.next_session; + self.next_session += 1; + self.sessions.insert(next_session, slot_type); + Ok(next_session) + } + + pub fn close_session(&mut self, session: CK_SESSION_HANDLE) -> Result<(), ()> { + self.sessions.remove(&session).ok_or(()).map(|_| ()) + } + + pub fn close_all_sessions(&mut self, slot_type: SlotType) -> Result<(), ()> { + let mut to_remove = Vec::new(); + for (session, open_slot_type) in self.sessions.iter() { + if slot_type == *open_slot_type { + to_remove.push(*session); + } + } + for session in to_remove { + if self.sessions.remove(&session).is_none() { + return Err(()); + } + } + Ok(()) + } + + fn get_next_handle(&mut self) -> CK_OBJECT_HANDLE { + let next_handle = self.next_handle; + self.next_handle += 1; + next_handle + } + + /// PKCS #11 specifies that search operations happen in three phases: setup, get any matches + /// (this part may be repeated if the caller uses a small buffer), and end. This implementation + /// does all of the work up front and gathers all matching objects during setup and retains them + /// until they are retrieved and consumed via `search`. + pub fn start_search( + &mut self, + session: CK_SESSION_HANDLE, + attrs: &[(CK_ATTRIBUTE_TYPE, Vec)], + ) -> Result<(), ()> { + let slot_type = match self.sessions.get(&session) { + Some(slot_type) => *slot_type, + None => return Err(()), + }; + // If the search is for an attribute we don't support, no objects will match. This check + // saves us having to look through all of our objects. + for (attr, _) in attrs { + if !SUPPORTED_ATTRIBUTES.contains(attr) { + self.searches.insert(session, Vec::new()); + return Ok(()); + } + } + // When NSS wants to find all certificates or all private keys, it will perform a search + // with a particular set of attributes. This implementation uses these searches as an + // indication for the backend to re-scan for new objects from tokens that may have been + // inserted or certificates that may have been imported into the OS. Since these searches + // are relatively rare, this minimizes the impact of doing these re-scans. + if search_is_for_all_certificates_or_keys(attrs)? { + self.maybe_find_new_objects(); + } + let mut handles = Vec::new(); + for (handle, object) in &self.objects { + if object.matches(slot_type, attrs) { + handles.push(*handle); + } + } + self.searches.insert(session, handles); + Ok(()) + } + + /// Given a session and a maximum number of object handles to return, attempts to retrieve up to + /// that many objects from the corresponding search. Updates the search so those objects are not + /// returned repeatedly. `max_objects` must be non-zero. + pub fn search( + &mut self, + session: CK_SESSION_HANDLE, + max_objects: usize, + ) -> Result, ()> { + if max_objects == 0 { + return Err(()); + } + match self.searches.get_mut(&session) { + Some(search) => { + let split_at = if max_objects >= search.len() { + 0 + } else { + search.len() - max_objects + }; + let to_return = search.split_off(split_at); + if to_return.len() > max_objects { + error!( + "search trying to return too many handles: {} > {}", + to_return.len(), + max_objects + ); + return Err(()); + } + Ok(to_return) + } + None => Err(()), + } + } + + pub fn clear_search(&mut self, session: CK_SESSION_HANDLE) -> Result<(), ()> { + self.searches.remove(&session); + Ok(()) + } + + pub fn get_attributes( + &self, + object_handle: CK_OBJECT_HANDLE, + attr_types: Vec, + ) -> Result>>, ()> { + let object = match self.objects.get(&object_handle) { + Some(object) => object, + None => return Err(()), + }; + let mut results = Vec::with_capacity(attr_types.len()); + for attr_type in attr_types { + let result = match object.get_attribute(attr_type) { + Some(value) => Some(value.to_owned()), + None => None, + }; + results.push(result); + } + Ok(results) + } + + /// The way NSS uses PKCS #11 to sign data happens in two phases: setup and sign. This + /// implementation makes a note of which key is to be used (if it exists) during setup. When the + /// caller finishes with the sign operation, this implementation retrieves the key handle and + /// performs the signature. + pub fn start_sign( + &mut self, + session: CK_SESSION_HANDLE, + key_handle: CK_OBJECT_HANDLE, + params: Option, + ) -> Result<(), ()> { + if self.signs.contains_key(&session) { + return Err(()); + } + match self.objects.get(&key_handle) { + Some(Object::Key(_)) => {} + _ => return Err(()), + }; + self.signs.insert(session, (key_handle, params)); + Ok(()) + } + + pub fn get_signature_length( + &self, + session: CK_SESSION_HANDLE, + data: &[u8], + ) -> Result { + let (key_handle, params) = match self.signs.get(&session) { + Some((key_handle, params)) => (key_handle, params), + None => return Err(()), + }; + let key = match self.objects.get(&key_handle) { + Some(Object::Key(key)) => key, + _ => return Err(()), + }; + key.get_signature_length(data, params) + } + + pub fn sign(&mut self, session: CK_SESSION_HANDLE, data: &[u8]) -> Result, ()> { + // Performing the signature (via C_Sign, which is the only way we support) finishes the sign + // operation, so it needs to be removed here. + let (key_handle, params) = match self.signs.remove(&session) { + Some((key_handle, params)) => (key_handle, params), + None => return Err(()), + }; + let key = match self.objects.get(&key_handle) { + Some(Object::Key(key)) => key, + _ => return Err(()), + }; + key.sign(data, ¶ms) + } +} diff --git a/security/manager/ssl/osclientcerts/src/util.rs b/security/manager/ssl/osclientcerts/src/util.rs new file mode 100644 index 0000000000..fc176ee751 --- /dev/null +++ b/security/manager/ssl/osclientcerts/src/util.rs @@ -0,0 +1,463 @@ +/* -*- Mode: rust; rust-indent-offset: 4 -*- */ +/* 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/. */ + +use byteorder::{BigEndian, NativeEndian, ReadBytesExt, WriteBytesExt}; +use std::convert::TryInto; + +/// Accessing fields of packed structs is unsafe (it may be undefined behavior if the field isn't +/// aligned). Since we're implementing a PKCS#11 module, we already have to trust the caller not to +/// give us bad data, so normally we would deal with this by adding an unsafe block. If we do that, +/// though, the compiler complains that the unsafe block is unnecessary. Thus, we use this macro to +/// annotate the unsafe block to silence the compiler. +macro_rules! unsafe_packed_field_access { + ($e:expr) => {{ + #[allow(unused_unsafe)] + let tmp = unsafe { $e }; + tmp + }}; +} + +#[cfg(target_os = "macos")] +pub const OID_BYTES_SECP256R1: &[u8] = + &[0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07]; +#[cfg(target_os = "macos")] +pub const OID_BYTES_SECP384R1: &[u8] = &[0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22]; +#[cfg(target_os = "macos")] +pub const OID_BYTES_SECP521R1: &[u8] = &[0x06, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23]; + +// This is a helper function to take a value and lay it out in memory how +// PKCS#11 is expecting it. +pub fn serialize_uint>(value: T) -> Result, ()> { + let value_size = std::mem::size_of::(); + let mut value_buf = Vec::with_capacity(value_size); + let value_as_u64 = value.try_into().map_err(|_| ())?; + value_buf + .write_uint::(value_as_u64, value_size) + .map_err(|_| ())?; + Ok(value_buf) +} + +/// Given a slice of DER bytes representing an RSA public key, extracts the bytes of the modulus +/// as an unsigned integer. Also verifies that the public exponent is present (again as an +/// unsigned integer). Finally verifies that reading these values consumes the entirety of the +/// slice. +/// RSAPublicKey ::= SEQUENCE { +/// modulus INTEGER, -- n +/// publicExponent INTEGER -- e +/// } +pub fn read_rsa_modulus(public_key: &[u8]) -> Result, ()> { + let mut sequence = Sequence::new(public_key)?; + let modulus_value = sequence.read_unsigned_integer()?; + let _exponent = sequence.read_unsigned_integer()?; + if !sequence.at_end() { + return Err(()); + } + Ok(modulus_value.to_vec()) +} + +/// Given a slice of DER bytes representing a DigestInfo, extracts the bytes of the digest. +/// +/// DigestInfo ::= SEQUENCE { +/// digestAlgorithm DigestAlgorithmIdentifier, +/// digest Digest } +/// +/// DigestAlgorithmIdentifier ::= AlgorithmIdentifier +/// +/// AlgorithmIdentifier ::= SEQUENCE { +/// algorithm OBJECT IDENTIFIER, +/// parameters ANY DEFINED BY algorithm OPTIONAL } +/// +/// Digest ::= OCTET STRING +#[cfg(target_os = "windows")] +pub fn read_digest<'a>(digest_info: &'a [u8]) -> Result<&'a [u8], ()> { + let mut sequence = Sequence::new(digest_info)?; + let _ = sequence.read_sequence()?; + let digest = sequence.read_octet_string()?; + if !sequence.at_end() { + error!("read_digest: extra input"); + return Err(()); + } + Ok(digest) +} + +/// Given a slice of DER bytes representing an ECDSA signature, extracts the bytes of `r` and `s` +/// as unsigned integers. Also verifies that this consumes the entirety of the slice. +/// Ecdsa-Sig-Value ::= SEQUENCE { +/// r INTEGER, +/// s INTEGER } +#[cfg(target_os = "macos")] +pub fn read_ec_sig_point<'a>(signature: &'a [u8]) -> Result<(&'a [u8], &'a [u8]), ()> { + let mut sequence = Sequence::new(signature)?; + let r = sequence.read_unsigned_integer()?; + let s = sequence.read_unsigned_integer()?; + if !sequence.at_end() { + return Err(()); + } + Ok((r, s)) +} + +/// Given a slice of DER bytes representing an X.509 certificate, extracts the encoded serial +/// number. Does not verify that the remainder of the certificate is in any way well-formed. +/// Certificate ::= SEQUENCE { +/// tbsCertificate TBSCertificate, +/// signatureAlgorithm AlgorithmIdentifier, +/// signatureValue BIT STRING } +/// +/// TBSCertificate ::= SEQUENCE { +/// version [0] EXPLICIT Version DEFAULT v1, +/// serialNumber CertificateSerialNumber, +/// ... +/// +/// CertificateSerialNumber ::= INTEGER +pub fn read_encoded_serial_number(certificate: &[u8]) -> Result, ()> { + let mut certificate_sequence = Sequence::new(certificate)?; + let mut tbs_certificate_sequence = certificate_sequence.read_sequence()?; + let _version = tbs_certificate_sequence.read_tagged_value(0)?; + let serial_number = tbs_certificate_sequence.read_encoded_sequence_component(INTEGER)?; + Ok(serial_number) +} + +/// Helper macro for reading some bytes from a slice while checking the slice is long enough. +/// Returns a pair consisting of a slice of the bytes read and a slice of the rest of the bytes +/// from the original slice. +macro_rules! try_read_bytes { + ($data:ident, $len:expr) => {{ + if $data.len() < $len { + return Err(()); + } + $data.split_at($len) + }}; +} + +/// ASN.1 tag identifying an integer. +const INTEGER: u8 = 0x02; +/// ASN.1 tag identifying an octet string. +#[cfg(target_os = "windows")] +const OCTET_STRING: u8 = 0x04; +/// ASN.1 tag identifying a sequence. +const SEQUENCE: u8 = 0x10; +/// ASN.1 tag modifier identifying an item as constructed. +const CONSTRUCTED: u8 = 0x20; +/// ASN.1 tag modifier identifying an item as context-specific. +const CONTEXT_SPECIFIC: u8 = 0x80; + +/// A helper struct for reading items from a DER SEQUENCE (in this case, all sequences are +/// assumed to be CONSTRUCTED). +struct Sequence<'a> { + /// The contents of the SEQUENCE. + contents: Der<'a>, +} + +impl<'a> Sequence<'a> { + fn new(input: &'a [u8]) -> Result, ()> { + let mut der = Der::new(input); + let (_, _, sequence_bytes) = der.read_tlv(SEQUENCE | CONSTRUCTED)?; + // We're assuming we want to consume the entire input for now. + if !der.at_end() { + return Err(()); + } + Ok(Sequence { + contents: Der::new(sequence_bytes), + }) + } + + // TODO: we're not exhaustively validating this integer + fn read_unsigned_integer(&mut self) -> Result<&'a [u8], ()> { + let (_, _, bytes) = self.contents.read_tlv(INTEGER)?; + if bytes.is_empty() { + return Err(()); + } + // There may be a leading zero (we should also check that the first bit + // of the rest of the integer is set). + if bytes[0] == 0 && bytes.len() > 1 { + let (_, integer) = bytes.split_at(1); + Ok(integer) + } else { + Ok(bytes) + } + } + + #[cfg(target_os = "windows")] + fn read_octet_string(&mut self) -> Result<&'a [u8], ()> { + let (_, _, bytes) = self.contents.read_tlv(OCTET_STRING)?; + Ok(bytes) + } + + fn read_sequence(&mut self) -> Result, ()> { + let (_, _, sequence_bytes) = self.contents.read_tlv(SEQUENCE | CONSTRUCTED)?; + Ok(Sequence { + contents: Der::new(sequence_bytes), + }) + } + + fn read_tagged_value(&mut self, tag: u8) -> Result<&'a [u8], ()> { + let (_, _, tagged_value_bytes) = self + .contents + .read_tlv(CONTEXT_SPECIFIC | CONSTRUCTED | tag)?; + Ok(tagged_value_bytes) + } + + fn read_encoded_sequence_component(&mut self, tag: u8) -> Result, ()> { + let (tag, length, value) = self.contents.read_tlv(tag)?; + let mut encoded_component_bytes = length; + encoded_component_bytes.insert(0, tag); + encoded_component_bytes.extend_from_slice(value); + Ok(encoded_component_bytes) + } + + fn at_end(&self) -> bool { + self.contents.at_end() + } +} + +/// A helper struct for reading DER data. The contents are treated like a cursor, so its position +/// is updated as data is read. +struct Der<'a> { + contents: &'a [u8], +} + +impl<'a> Der<'a> { + fn new(contents: &'a [u8]) -> Der<'a> { + Der { contents } + } + + // In theory, a caller could encounter an error and try another operation, in which case we may + // be in an inconsistent state. As long as this implementation isn't exposed to code that would + // use it incorrectly (i.e. it stays in this module and we only expose a stateless API), it + // should be safe. + /// Given an expected tag, reads the next (tag, lengh, value) from the contents. Most + /// consumers will only be interested in the value, but some may want the entire encoded + /// contents, in which case the returned tuple can be concatenated. + fn read_tlv(&mut self, tag: u8) -> Result<(u8, Vec, &'a [u8]), ()> { + let contents = self.contents; + let (tag_read, rest) = try_read_bytes!(contents, 1); + if tag_read[0] != tag { + return Err(()); + } + let mut accumulated_length_bytes = Vec::with_capacity(4); + let (length1, rest) = try_read_bytes!(rest, 1); + accumulated_length_bytes.extend_from_slice(length1); + let (length, to_read_from) = if length1[0] < 0x80 { + (length1[0] as usize, rest) + } else if length1[0] == 0x81 { + let (length, rest) = try_read_bytes!(rest, 1); + accumulated_length_bytes.extend_from_slice(length); + if length[0] < 0x80 { + return Err(()); + } + (length[0] as usize, rest) + } else if length1[0] == 0x82 { + let (lengths, rest) = try_read_bytes!(rest, 2); + accumulated_length_bytes.extend_from_slice(lengths); + let length = (&mut &lengths[..]) + .read_u16::() + .map_err(|_| ())?; + if length < 256 { + return Err(()); + } + (length as usize, rest) + } else { + return Err(()); + }; + let (contents, rest) = try_read_bytes!(to_read_from, length); + self.contents = rest; + Ok((tag, accumulated_length_bytes, contents)) + } + + fn at_end(&self) -> bool { + self.contents.is_empty() + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn der_test_empty_input() { + let input = Vec::new(); + let mut der = Der::new(&input); + assert!(der.read_tlv(INTEGER).is_err()); + } + + #[test] + fn der_test_no_length() { + let input = vec![INTEGER]; + let mut der = Der::new(&input); + assert!(der.read_tlv(INTEGER).is_err()); + } + + #[test] + fn der_test_empty_sequence() { + let input = vec![SEQUENCE, 0]; + let mut der = Der::new(&input); + let read_result = der.read_tlv(SEQUENCE); + assert!(read_result.is_ok()); + let (tag, length, sequence_bytes) = read_result.unwrap(); + assert_eq!(tag, SEQUENCE); + assert_eq!(length, vec![0]); + assert_eq!(sequence_bytes.len(), 0); + assert!(der.at_end()); + } + + #[test] + fn der_test_not_at_end() { + let input = vec![SEQUENCE, 0, 1]; + let mut der = Der::new(&input); + let read_result = der.read_tlv(SEQUENCE); + assert!(read_result.is_ok()); + let (tag, length, sequence_bytes) = read_result.unwrap(); + assert_eq!(tag, SEQUENCE); + assert_eq!(length, vec![0]); + assert_eq!(sequence_bytes.len(), 0); + assert!(!der.at_end()); + } + + #[test] + fn der_test_wrong_tag() { + let input = vec![SEQUENCE, 0]; + let mut der = Der::new(&input); + assert!(der.read_tlv(INTEGER).is_err()); + } + + #[test] + fn der_test_truncated_two_byte_length() { + let input = vec![SEQUENCE, 0x81]; + let mut der = Der::new(&input); + assert!(der.read_tlv(SEQUENCE).is_err()); + } + + #[test] + fn der_test_truncated_three_byte_length() { + let input = vec![SEQUENCE, 0x82, 1]; + let mut der = Der::new(&input); + assert!(der.read_tlv(SEQUENCE).is_err()); + } + + #[test] + fn der_test_truncated_data() { + let input = vec![SEQUENCE, 20, 1]; + let mut der = Der::new(&input); + assert!(der.read_tlv(SEQUENCE).is_err()); + } + + #[test] + fn der_test_sequence() { + let input = vec![ + SEQUENCE, 20, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 0, 0, + ]; + let mut der = Der::new(&input); + let result = der.read_tlv(SEQUENCE); + assert!(result.is_ok()); + let (tag, length, value) = result.unwrap(); + assert_eq!(tag, SEQUENCE); + assert_eq!(length, vec![20]); + assert_eq!( + value, + [1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 0, 0] + ); + assert!(der.at_end()); + } + + #[test] + fn der_test_not_shortest_two_byte_length_encoding() { + let input = vec![SEQUENCE, 0x81, 1, 1]; + let mut der = Der::new(&input); + assert!(der.read_tlv(SEQUENCE).is_err()); + } + + #[test] + fn der_test_not_shortest_three_byte_length_encoding() { + let input = vec![SEQUENCE, 0x82, 0, 1, 1]; + let mut der = Der::new(&input); + assert!(der.read_tlv(SEQUENCE).is_err()); + } + + #[test] + fn der_test_indefinite_length_unsupported() { + let input = vec![SEQUENCE, 0x80, 1, 2, 3, 0x00, 0x00]; + let mut der = Der::new(&input); + assert!(der.read_tlv(SEQUENCE).is_err()); + } + + #[test] + fn der_test_input_too_long() { + // This isn't valid DER (the contents of the SEQUENCE are truncated), but it demonstrates + // that we don't try to read too much if we're given a long length (and also that we don't + // support lengths 2^16 and up). + let input = vec![SEQUENCE, 0x83, 0x01, 0x00, 0x01, 1, 1, 1, 1]; + let mut der = Der::new(&input); + assert!(der.read_tlv(SEQUENCE).is_err()); + } + + #[test] + fn empty_input_fails() { + let empty = Vec::new(); + assert!(read_rsa_modulus(&empty).is_err()); + #[cfg(target_os = "macos")] + assert!(read_ec_sig_point(&empty).is_err()); + assert!(read_encoded_serial_number(&empty).is_err()); + } + + #[test] + fn empty_sequence_fails() { + let empty = vec![SEQUENCE | CONSTRUCTED]; + assert!(read_rsa_modulus(&empty).is_err()); + #[cfg(target_os = "macos")] + assert!(read_ec_sig_point(&empty).is_err()); + assert!(read_encoded_serial_number(&empty).is_err()); + } + + #[test] + fn test_read_rsa_modulus() { + let rsa_key = include_bytes!("../test/rsa.bin"); + let result = read_rsa_modulus(rsa_key); + assert!(result.is_ok()); + let modulus = result.unwrap(); + assert_eq!(modulus, include_bytes!("../test/modulus.bin").to_vec()); + } + + #[test] + fn test_read_serial_number() { + let certificate = include_bytes!("../test/certificate.bin"); + let result = read_encoded_serial_number(certificate); + assert!(result.is_ok()); + let serial_number = result.unwrap(); + assert_eq!( + serial_number, + &[ + 0x02, 0x14, 0x3f, 0xed, 0x7b, 0x43, 0x47, 0x8a, 0x53, 0x42, 0x5b, 0x0d, 0x50, 0xe1, + 0x37, 0x88, 0x2a, 0x20, 0x3f, 0x31, 0x17, 0x20 + ] + ); + } + + #[test] + #[cfg(target_os = "windows")] + fn test_read_digest() { + // SEQUENCE + // SEQUENCE + // OBJECT IDENTIFIER 2.16.840.1.101.3.4.2.1 sha-256 + // NULL + // OCTET STRING 1A7FCDB9A5F649F954885CFE145F3E93F0D1FA72BE980CC6EC82C70E1407C7D2 + let digest_info = [ + 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x1, 0x65, 0x03, 0x04, 0x02, + 0x01, 0x05, 0x00, 0x04, 0x20, 0x1a, 0x7f, 0xcd, 0xb9, 0xa5, 0xf6, 0x49, 0xf9, 0x54, + 0x88, 0x5c, 0xfe, 0x14, 0x5f, 0x3e, 0x93, 0xf0, 0xd1, 0xfa, 0x72, 0xbe, 0x98, 0x0c, + 0xc6, 0xec, 0x82, 0xc7, 0x0e, 0x14, 0x07, 0xc7, 0xd2, + ]; + let result = read_digest(&digest_info); + assert!(result.is_ok()); + let digest = result.unwrap(); + assert_eq!( + digest, + &[ + 0x1a, 0x7f, 0xcd, 0xb9, 0xa5, 0xf6, 0x49, 0xf9, 0x54, 0x88, 0x5c, 0xfe, 0x14, 0x5f, + 0x3e, 0x93, 0xf0, 0xd1, 0xfa, 0x72, 0xbe, 0x98, 0x0c, 0xc6, 0xec, 0x82, 0xc7, 0x0e, + 0x14, 0x07, 0xc7, 0xd2 + ] + ); + } +} diff --git a/security/manager/ssl/osclientcerts/test/certificate.bin b/security/manager/ssl/osclientcerts/test/certificate.bin new file mode 100644 index 0000000000..01fbafb15c Binary files /dev/null and b/security/manager/ssl/osclientcerts/test/certificate.bin differ diff --git a/security/manager/ssl/osclientcerts/test/modulus.bin b/security/manager/ssl/osclientcerts/test/modulus.bin new file mode 100644 index 0000000000..a9b09ff53e --- /dev/null +++ b/security/manager/ssl/osclientcerts/test/modulus.bin @@ -0,0 +1,2 @@ +ºˆQ¨DŽÖAýn¶ˆ6=<Ùêä5J´ìõhWl${ÁÇ%¨àؽ±œ›n†òkâ¯Zukjdqz¥Z§E‡÷Õ$œ~ÍCüiÐ8 )“« ÃIäÛ¹LÂklí‚ñ~­i±Ó:‹*Aî§pà ýf +°$’¤}¹ˆay±W=Ò;Åà¸H¨7ÓˆCï'ØU·fZª~/:{€$Ìl—­–a[·â–Àu1£ ‘Ý´Ê÷ü­%Ó ï¹§há³{/"oiã´Š•aî&Ö%«‘N6Ë$,¿‹/åñ™1¸³þI#úrQÄ1Õ¬Ú +5í \ No newline at end of file diff --git a/security/manager/ssl/osclientcerts/test/rsa.bin b/security/manager/ssl/osclientcerts/test/rsa.bin new file mode 100644 index 0000000000..93ededb827 Binary files /dev/null and b/security/manager/ssl/osclientcerts/test/rsa.bin differ diff --git a/security/manager/ssl/tests/.eslintrc.js b/security/manager/ssl/tests/.eslintrc.js new file mode 100644 index 0000000000..379eabb2d0 --- /dev/null +++ b/security/manager/ssl/tests/.eslintrc.js @@ -0,0 +1,8 @@ +"use strict"; + +module.exports = { + rules: { + // Disallow non-top level |var| declarations. + "mozilla/var-only-at-top-level": "error", + }, +}; diff --git a/security/manager/ssl/tests/gtest/CertDBTest.cpp b/security/manager/ssl/tests/gtest/CertDBTest.cpp new file mode 100644 index 0000000000..310b0226e1 --- /dev/null +++ b/security/manager/ssl/tests/gtest/CertDBTest.cpp @@ -0,0 +1,52 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "gtest/gtest.h" +#include "nsCOMPtr.h" +#include "nsIPrefService.h" +#include "nsIX509Cert.h" +#include "nsIX509CertDB.h" +#include "nsServiceManagerUtils.h" + +TEST(psm_CertDB, Test) +{ + { + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + ASSERT_TRUE(prefs) + << "couldn't get nsIPrefBranch"; + + // When PSM initializes, it attempts to get some localized strings. + // As a result, Android flips out if this isn't set. + nsresult rv = prefs->SetBoolPref("intl.locale.matchOS", true); + ASSERT_TRUE(NS_SUCCEEDED(rv)) + << "couldn't set pref 'intl.locale.matchOS'"; + + nsCOMPtr certdb(do_GetService(NS_X509CERTDB_CONTRACTID)); + ASSERT_TRUE(certdb) + << "couldn't get certdb"; + + nsTArray> certList; + rv = certdb->GetCerts(certList); + ASSERT_TRUE(NS_SUCCEEDED(rv)) + << "couldn't get list of certificates"; + + bool foundBuiltIn = false; + for (const auto& cert : certList) { + ASSERT_TRUE(cert) + << "certlist shouldn't have null certificate"; + ASSERT_TRUE(NS_SUCCEEDED(cert->GetIsBuiltInRoot(&foundBuiltIn))) + << "GetIsBuiltInRoot failed"; + if (foundBuiltIn) { + break; + } + } + + ASSERT_TRUE(foundBuiltIn) + << "didn't load any built-in certificates"; + + printf("successfully loaded at least one built-in certificate\n"); + + } // this scopes the nsCOMPtrs +} diff --git a/security/manager/ssl/tests/gtest/CertListTest.cpp b/security/manager/ssl/tests/gtest/CertListTest.cpp new file mode 100644 index 0000000000..db4cec19e5 --- /dev/null +++ b/security/manager/ssl/tests/gtest/CertListTest.cpp @@ -0,0 +1,332 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "gtest/gtest.h" +#include "nsCOMPtr.h" +#include "nsIPrefService.h" +#include "nsIX509Cert.h" +#include "nsIX509CertDB.h" +#include "nsNSSCertificate.h" +#include "nsServiceManagerUtils.h" +#include "nsString.h" + +// certspec (for pycert.py) +// +// issuer:ca +// subject:ca +// extension:basicConstraints:cA, +// extension:keyUsage:cRLSign,keyCertSign +// serialNumber:1 +const char* kCaPem = + "-----BEGIN CERTIFICATE-----\n" + "MIICsjCCAZygAwIBAgIBATALBgkqhkiG9w0BAQswDTELMAkGA1UEAwwCY2EwIhgP\n" + "MjAxNTExMjgwMDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowDTELMAkGA1UEAwwCY2Ew\n" + "ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ\n" + "PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH\n" + "9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw\n" + "4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86\n" + "exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0\n" + "ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N\n" + "AgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAsGCSqGSIb3DQEB\n" + "CwOCAQEAchHf1yV+blE6fvS53L3DGmvxEpn9+t+xwOvWczBmLFEzUPdncakdaWlQ\n" + "v7q81BPyjBqkYbQi15Ws81hY3dnXn8LT1QktCL9guvc3z4fMdQbRjpjcIReCYt3E\n" + "PB22Jl2FCm6ii4XL0qDFD26WK3zMe2Uks6t55f8VeDTBGNoPp2JMsWY1Pi4vR6wK\n" + "AY96WoXS/qrYkmMEOgFu907pApeAeE8VJzXjqMLF6/W1VN7ISnGzWQ8zKQnlp3YA\n" + "mvWZQcD6INK8mvpZxIeu6NtHaKEXGw7tlGekmkVhapPtQZYnWcsXybRrZf5g3hOh\n" + "JFPl8kW42VoxXL11PP5NX2ylTsJ//g==\n" + "-----END CERTIFICATE-----"; + +// certspec (for pycert.py) +// +// issuer:ca +// subject:ca-intermediate +// extension:basicConstraints:cA, +// extension:keyUsage:cRLSign,keyCertSign +// serialNumber:2 +const char* kCaIntermediatePem = + "-----BEGIN CERTIFICATE-----\n" + "MIICvzCCAamgAwIBAgIBAjALBgkqhkiG9w0BAQswDTELMAkGA1UEAwwCY2EwIhgP\n" + "MjAxNTExMjgwMDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowGjEYMBYGA1UEAwwPY2Et\n" + "aW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR\n" + "qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv\n" + "WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+\n" + "rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv\n" + "JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5\n" + "Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6\n" + "clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB\n" + "BjALBgkqhkiG9w0BAQsDggEBAC0ys8UOmYgvH5rrTeV6u79ocHqdQFwdmR7/4d08\n" + "i3asC7b70dw0ehA5vi4cq5mwBvQOGZq4wvsR4jSJW0+0hjWL1dr2M6VxmCfjdqhU\n" + "NQHPlY6y7lLfYQbFfUHX99ZgygJjdmmm7H8MBP4UgPb8jl6Xq53FgYykiX/qPmfb\n" + "pzpOFHDi+Tk67DLCvPz03UUDYNx1H0OhRimj0DWhdYGUg2DHfLQkOEYvrYG4wYB8\n" + "AB/0hrG51yFsuXrzhYcinTKby11Qk6PjnOQ/aZvK00Jffep/RHs8lIOWty9SarMG\n" + "oNSECn+6I9AgStJdo6LuP1QPyrQe3DZtAHhRJAPAoU7BSqM=\n" + "-----END CERTIFICATE-----"; + +// certspec (for pycert.py) +// +// issuer:ca-intermediate +// subject:ca-second-intermediate +// extension:basicConstraints:cA, +// extension:keyUsage:cRLSign,keyCertSign +// serialNumber:3 +const char* kCaSecondIntermediatePem = + "-----BEGIN CERTIFICATE-----\n" + "MIIC0zCCAb2gAwIBAgIBAzALBgkqhkiG9w0BAQswGjEYMBYGA1UEAwwPY2EtaW50\n" + "ZXJtZWRpYXRlMCIYDzIwMTUxMTI4MDAwMDAwWhgPMjAxODAyMDUwMDAwMDBaMCEx\n" + "HzAdBgNVBAMMFmNhLXNlY29uZC1pbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEB\n" + "AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk\n" + "e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg\n" + "KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI\n" + "YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi\n" + "lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL\n" + "HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1Ud\n" + "EwQFMAMBAf8wCwYDVR0PBAQDAgEGMAsGCSqGSIb3DQEBCwOCAQEAaK6K7/0Y+PkG\n" + "MQJjumTlt6XUQjQ3Y6zuSOMlZ1wmJoBqWabYhJ4qXfcSMQiw+kZ+mQTFk+IdurGC\n" + "RHrAKwDGNRqmjnQ56qjwHNTTxhJozP09vBCgs3fIQQY/Nq/uISoQvOZmoIriFZf6\n" + "8czHMlj1vIC6zp4XHWdqkQ7aF4YFsTfM0kBPrm0Y6Nn0VKzWNdmaIs/X5OcR6ZAG\n" + "zGN9UZV+ZftcfdqI0XSVCVRAK5MeEa+twLr5PE/Nl7/Ig/tUJMWGSbcrWRZQTXQu\n" + "Rx7CSKcoatyMhJOd2YT4BvoijEJCxTKWMJzFe2uZAphQHUlVmE9IbUQM0T1N6RNd\n" + "1dH4o4UeuQ==\n" + "-----END CERTIFICATE-----"; + +// certspec (for pycert.py) +// +// issuer:ca-second-intermediate +// subject:ee +const char* kEePem = + "-----BEGIN CERTIFICATE-----\n" + "MIICujCCAaSgAwIBAgIUMy8NE67P/4jkaCra7rOVVvX4+GswCwYJKoZIhvcNAQEL\n" + "MCExHzAdBgNVBAMMFmNhLXNlY29uZC1pbnRlcm1lZGlhdGUwIhgPMjAxNTExMjgw\n" + "MDAwMDBaGA8yMDE4MDIwNTAwMDAwMFowDTELMAkGA1UEAwwCZWUwggEiMA0GCSqG\n" + "SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0\n" + "7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D\n" + "/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw\n" + "JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX\n" + "rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd\n" + "q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwCwYJ\n" + "KoZIhvcNAQELA4IBAQCE5V5YiFPtbb1dOCIMGC5X/6kfQkQmIfvEZIol0MRXmP4g\n" + "CsOPbTI+BNxYVNk5RHIlr+6e0d8TNiABem4FZK3kea4ugN8ez3IsK7ug7qdrooNA\n" + "MiHOvrLmAw2nQWexdDRf7OPeVj03BwELzGTOGPjAqDktTsK57OfXyFTm9nl75WQo\n" + "+EWX+CdV4L1o2rgABvSiMnMdycftCC73Hr/3ypADqY7nDrKpxYdrGgzAQvx3DjPv\n" + "b7nBKH/gXg3kzoWpeQmJYPl9Vd+DvGljS5i71oLbvCwlDX7ZswGcvb8pQ7Tni5HA\n" + "VYpAYLokxIDFnyVT9oCACJuJ5LvpBBrhd0+1uUPE\n" + "-----END CERTIFICATE-----"; + +class psm_CertList : public ::testing::Test { + protected: + void SetUp() override { + nsCOMPtr prefs(do_GetService(NS_PREFSERVICE_CONTRACTID)); + ASSERT_TRUE(prefs) + << "couldn't get nsIPrefBranch"; + + // When PSM initializes, it attempts to get some localized strings. + // As a result, Android flips out if this isn't set. + nsresult rv = prefs->SetBoolPref("intl.locale.matchOS", true); + ASSERT_TRUE(NS_SUCCEEDED(rv)) + << "couldn't set pref 'intl.locale.matchOS'"; + + nsCOMPtr certdb(do_GetService(NS_X509CERTDB_CONTRACTID)); + ASSERT_TRUE(certdb) + << "couldn't get certdb"; + } +}; + +static nsresult AddCertFromStringToList( + const char* aPem, nsTArray>& aCertList) { + RefPtr cert; + cert = + nsNSSCertificate::ConstructFromDER(const_cast(aPem), strlen(aPem)); + if (!cert) { + return NS_ERROR_FAILURE; + } + + aCertList.AppendElement(cert); + return NS_OK; +} + +TEST_F(psm_CertList, TestInvalidSegmenting) { + nsTArray> certList; + + nsCOMPtr rootCert; + nsTArray> intCerts; + nsCOMPtr eeCert; + nsresult rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, + intCerts, eeCert); + ASSERT_EQ(rv, NS_ERROR_INVALID_ARG) << "Empty lists can't be segmented"; + + rv = AddCertFromStringToList(kCaPem, certList); + ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; + + intCerts.Clear(); + rootCert = nullptr; + eeCert = nullptr; + + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); + ASSERT_EQ(rv, NS_ERROR_INVALID_ARG) << "Lists of one can't be segmented"; +} + +TEST_F(psm_CertList, TestValidSegmenting) { + nsTArray> certList; + + nsresult rv = AddCertFromStringToList(kEePem, certList); + ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; + rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList); + ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; + + nsCOMPtr rootCert; + nsTArray> intCerts; + nsCOMPtr eeCert; + + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); + ASSERT_EQ(rv, NS_OK) << "Should have segmented OK"; + ASSERT_TRUE(rootCert) + << "Root cert should be filled in"; + ASSERT_TRUE(eeCert) + << "End entity cert should be filled in"; + ASSERT_EQ(intCerts.Length(), static_cast(0)) + << "There should be no intermediates"; + + nsAutoString rootCn; + ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) + << "Getters should work."; + ASSERT_TRUE(rootCn.EqualsLiteral("ca-second-intermediate")) + << "Second Intermediate CN should match"; + + rv = AddCertFromStringToList(kCaIntermediatePem, certList); + ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; + + intCerts.Clear(); + rootCert = nullptr; + eeCert = nullptr; + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); + ASSERT_EQ(rv, NS_OK) << "Should have segmented OK"; + + ASSERT_TRUE(rootCert) + << "Root cert should be filled in"; + ASSERT_TRUE(eeCert) + << "End entity cert should be filled in"; + ASSERT_EQ(intCerts.Length(), static_cast(1)) + << "There should be one intermediate"; + + rv = AddCertFromStringToList(kCaPem, certList); + ASSERT_EQ(rv, NS_OK) << "Should have loaded OK"; + + intCerts.Clear(); + rootCert = nullptr; + eeCert = nullptr; + rv = nsNSSCertificate::SegmentCertificateChain(certList, rootCert, intCerts, + eeCert); + ASSERT_EQ(rv, NS_OK) << "Should have segmented OK"; + + ASSERT_TRUE(rootCert) + << "Root cert should be filled in"; + ASSERT_TRUE(eeCert) + << "End entity cert should be filled in"; + ASSERT_EQ(intCerts.Length(), static_cast(2)) + << "There should be two intermediates"; + + ASSERT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) + << "Getters should work."; + ASSERT_TRUE(rootCn.EqualsLiteral("ca")) + << "Root CN should match"; + + nsAutoString eeCn; + ASSERT_TRUE(NS_SUCCEEDED(eeCert->GetCommonName(eeCn))) + << "Getters should work."; + ASSERT_TRUE(eeCn.EqualsLiteral("ee")) + << "EE CN should match"; + + for (size_t i = 0; i < intCerts.Length(); ++i) { + nsAutoString cn; + const auto& cert = intCerts[i]; + rv = cert->GetCommonName(cn); + if (NS_FAILED(rv)) { + break; + } + + if (i < intCerts.Length() - 1) { + if (!cn.EqualsLiteral("ca-second-intermediate")) { + rv = NS_ERROR_FAILURE; + break; + } + } else { + if (!cn.EqualsLiteral("ca-intermediate")) { + rv = NS_ERROR_FAILURE; + break; + } + } + } + + ASSERT_EQ(rv, NS_OK) << "Should have looped OK."; +} + +TEST_F(psm_CertList, TestGetRootCertificateChainTwo) { + nsTArray> certList; + + nsresult rv = AddCertFromStringToList(kCaIntermediatePem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + rv = AddCertFromStringToList(kCaPem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + + nsCOMPtr rootCert; + rv = nsNSSCertificate::GetRootCertificate(certList, rootCert); + EXPECT_EQ(NS_OK, rv) << "Should have fetched the root OK"; + ASSERT_TRUE(rootCert) + << "Root cert should be filled in"; + + nsAutoString rootCn; + EXPECT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) + << "Getters should work."; + EXPECT_TRUE(rootCn.EqualsLiteral("ca")) << "Root CN should match"; + + // Re-fetch and ensure we get the same certificate. + nsCOMPtr rootCertRepeat; + rv = nsNSSCertificate::GetRootCertificate(certList, rootCertRepeat); + EXPECT_EQ(NS_OK, rv) << "Should have fetched the root OK the second time"; + ASSERT_TRUE(rootCertRepeat) + << "Root cert should still be filled in"; + + nsAutoString rootRepeatCn; + EXPECT_TRUE(NS_SUCCEEDED(rootCertRepeat->GetCommonName(rootRepeatCn))) + << "Getters should work."; + EXPECT_TRUE(rootRepeatCn.EqualsLiteral("ca")) << "Root CN should still match"; +} + +TEST_F(psm_CertList, TestGetRootCertificateChainFour) { + nsTArray> certList; + + nsresult rv = AddCertFromStringToList(kEePem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + rv = AddCertFromStringToList(kCaSecondIntermediatePem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + rv = AddCertFromStringToList(kCaIntermediatePem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + rv = AddCertFromStringToList(kCaPem, certList); + ASSERT_EQ(NS_OK, rv) << "Should have loaded OK"; + + nsCOMPtr rootCert; + rv = nsNSSCertificate::GetRootCertificate(certList, rootCert); + EXPECT_EQ(NS_OK, rv) << "Should have again fetched the root OK"; + ASSERT_TRUE(rootCert) + << "Root cert should be filled in"; + + nsAutoString rootCn; + EXPECT_TRUE(NS_SUCCEEDED(rootCert->GetCommonName(rootCn))) + << "Getters should work."; + EXPECT_TRUE(rootCn.EqualsLiteral("ca")) << "Root CN should match"; +} + +TEST_F(psm_CertList, TestGetRootCertificateChainEmpty) { + nsTArray> certList; + + nsCOMPtr rootCert; + nsresult rv = nsNSSCertificate::GetRootCertificate(certList, rootCert); + EXPECT_EQ(NS_ERROR_FAILURE, rv) + << "Should have returned NS_ERROR_FAILURE because certList was empty"; + EXPECT_FALSE(rootCert) << "Root cert should be empty"; +} diff --git a/security/manager/ssl/tests/gtest/CoseTest.cpp b/security/manager/ssl/tests/gtest/CoseTest.cpp new file mode 100644 index 0000000000..2f05cad3a7 --- /dev/null +++ b/security/manager/ssl/tests/gtest/CoseTest.cpp @@ -0,0 +1,756 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "ScopedNSSTypes.h" +#include "cosec.h" + +namespace mozilla { + +// "This is the content." +const uint8_t PAYLOAD[] = {84, 104, 105, 115, 32, 105, 115, 32, 116, 104, + 101, 32, 99, 111, 110, 116, 101, 110, 116, 46}; + +// This is a COSE signature generated with the cose rust library (see +// third-party/rust/cose). The payload is signed with the P256 key from +// pykey.py. +const uint8_t SIGNATURE[] = { + 0xd8, 0x62, 0x84, 0x59, 0x02, 0xa3, 0xa1, 0x04, 0x82, 0x59, 0x01, 0x4e, + 0x30, 0x82, 0x01, 0x4a, 0x30, 0x81, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x5f, 0x3f, 0xae, 0x90, 0x49, 0x30, 0x2f, 0x33, 0x6e, 0x95, + 0x23, 0xa7, 0xcb, 0x23, 0xd7, 0x65, 0x4f, 0xea, 0x3c, 0xf7, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x14, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, + 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, + 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, + 0x21, 0x00, 0xc2, 0xe4, 0xc1, 0xa8, 0xe2, 0x89, 0xdc, 0xa1, 0xbb, 0xe7, + 0xd5, 0x4f, 0x5c, 0x88, 0xad, 0xeb, 0xa4, 0x78, 0xa1, 0x19, 0xbe, 0x22, + 0x54, 0xc8, 0x9f, 0xef, 0xb8, 0x5d, 0xa2, 0x40, 0xd9, 0x8b, 0x59, 0x01, + 0x4c, 0x30, 0x82, 0x01, 0x48, 0x30, 0x81, 0xf0, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x43, 0x63, 0x59, 0xad, 0x04, 0x34, 0x56, 0x80, 0x43, + 0xec, 0x90, 0x6a, 0xd4, 0x10, 0x64, 0x7c, 0x7f, 0x38, 0x32, 0xe2, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, + 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, + 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, + 0x44, 0x02, 0x20, 0x63, 0x59, 0x02, 0x01, 0x89, 0xd7, 0x3e, 0x5b, 0xff, + 0xd1, 0x16, 0x4e, 0xe3, 0xe2, 0x0a, 0xe0, 0x4a, 0xd8, 0x75, 0xaf, 0x77, + 0x5c, 0x93, 0x60, 0xba, 0x10, 0x1f, 0x97, 0xdd, 0x27, 0x2d, 0x24, 0x02, + 0x20, 0x3d, 0x87, 0x0f, 0xac, 0x22, 0x4d, 0x16, 0xd9, 0xa1, 0x95, 0xbb, + 0x56, 0xe0, 0x21, 0x05, 0x93, 0xd1, 0x07, 0xb5, 0x25, 0x3b, 0xf4, 0x57, + 0x20, 0x87, 0x13, 0xa2, 0xf7, 0x78, 0x15, 0x30, 0xa7, 0xa0, 0xf6, 0x81, + 0x83, 0x59, 0x01, 0x33, 0xa2, 0x01, 0x26, 0x04, 0x59, 0x01, 0x2c, 0x30, + 0x82, 0x01, 0x28, 0x30, 0x81, 0xcf, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, + 0x14, 0x2f, 0xc3, 0x5f, 0x05, 0x80, 0xb4, 0x49, 0x45, 0x13, 0x92, 0xd6, + 0x93, 0xb7, 0x2d, 0x71, 0x19, 0xc5, 0x8c, 0x40, 0x39, 0x30, 0x0a, 0x06, + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, + 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, + 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, + 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x65, 0x65, 0x2d, 0x70, 0x32, + 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, + 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, 0x61, 0xe0, 0xf8, + 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, 0xec, 0x05, 0x0b, + 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, 0x79, 0x4b, 0x45, + 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, 0x11, 0x9d, 0x07, + 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, 0x99, 0x1b, 0x7b, + 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, 0x30, 0x0a, 0x06, + 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, + 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, + 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, + 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, + 0x02, 0x21, 0x00, 0xff, 0x81, 0xbe, 0xa8, 0x0d, 0x03, 0x36, 0x6b, 0x75, + 0xe2, 0x70, 0x6a, 0xac, 0x07, 0x2e, 0x4c, 0xdc, 0xf9, 0xc5, 0x89, 0xc1, + 0xcf, 0x88, 0xc2, 0xc8, 0x2a, 0x32, 0xf5, 0x42, 0x0c, 0xfa, 0x0b, 0xa0, + 0x58, 0x40, 0x1e, 0x6e, 0x08, 0xdf, 0x8f, 0x4f, 0xd6, 0xab, 0x23, 0xae, + 0x84, 0xaa, 0xf3, 0x43, 0x35, 0x9a, 0x53, 0xb9, 0x8b, 0xf9, 0x81, 0xa1, + 0xbc, 0x1e, 0x5c, 0x57, 0x5c, 0x0a, 0x20, 0x37, 0xf4, 0x3d, 0x11, 0x08, + 0xa0, 0x97, 0x4b, 0x68, 0xa4, 0x0f, 0x80, 0xe9, 0x96, 0x30, 0x04, 0x24, + 0x0e, 0x81, 0x3d, 0x2a, 0x8a, 0x64, 0x40, 0x61, 0x5a, 0x19, 0x00, 0xff, + 0x74, 0x40, 0x71, 0x82, 0x65, 0xe9}; + +// This is a COSE signature generated with the cose rust library (see +// third-party/rust/cose). The payload is signed twice; with the P256 and the +// RSA key from pykey.py. +const uint8_t SIGNATURE_ES256_PS256[] = { + 0xd8, 0x62, 0x84, 0x59, 0x08, 0x52, 0xa1, 0x04, 0x84, 0x59, 0x01, 0x4e, + 0x30, 0x82, 0x01, 0x4a, 0x30, 0x81, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x5f, 0x3f, 0xae, 0x90, 0x49, 0x30, 0x2f, 0x33, 0x6e, 0x95, + 0x23, 0xa7, 0xcb, 0x23, 0xd7, 0x65, 0x4f, 0xea, 0x3c, 0xf7, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x14, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, + 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, + 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, + 0x21, 0x00, 0xc2, 0xe4, 0xc1, 0xa8, 0xe2, 0x89, 0xdc, 0xa1, 0xbb, 0xe7, + 0xd5, 0x4f, 0x5c, 0x88, 0xad, 0xeb, 0xa4, 0x78, 0xa1, 0x19, 0xbe, 0x22, + 0x54, 0xc8, 0x9f, 0xef, 0xb8, 0x5d, 0xa2, 0x40, 0xd9, 0x8b, 0x59, 0x01, + 0x4c, 0x30, 0x82, 0x01, 0x48, 0x30, 0x81, 0xf0, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x43, 0x63, 0x59, 0xad, 0x04, 0x34, 0x56, 0x80, 0x43, + 0xec, 0x90, 0x6a, 0xd4, 0x10, 0x64, 0x7c, 0x7f, 0x38, 0x32, 0xe2, 0x30, + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, + 0x14, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, + 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, + 0x44, 0x02, 0x20, 0x63, 0x59, 0x02, 0x01, 0x89, 0xd7, 0x3e, 0x5b, 0xff, + 0xd1, 0x16, 0x4e, 0xe3, 0xe2, 0x0a, 0xe0, 0x4a, 0xd8, 0x75, 0xaf, 0x77, + 0x5c, 0x93, 0x60, 0xba, 0x10, 0x1f, 0x97, 0xdd, 0x27, 0x2d, 0x24, 0x02, + 0x20, 0x3d, 0x87, 0x0f, 0xac, 0x22, 0x4d, 0x16, 0xd9, 0xa1, 0x95, 0xbb, + 0x56, 0xe0, 0x21, 0x05, 0x93, 0xd1, 0x07, 0xb5, 0x25, 0x3b, 0xf4, 0x57, + 0x20, 0x87, 0x13, 0xa2, 0xf7, 0x78, 0x15, 0x30, 0xa7, 0x59, 0x02, 0xd5, + 0x30, 0x82, 0x02, 0xd1, 0x30, 0x82, 0x01, 0xbb, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x29, 0x6c, 0x1a, 0xd8, 0x20, 0xcd, 0x74, 0x6d, 0x4b, + 0x00, 0xf3, 0x16, 0x88, 0xd9, 0x66, 0x87, 0x5f, 0x28, 0x56, 0x6a, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x72, 0x6f, + 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, + 0xfd, 0x6e, 0xb6, 0x88, 0x06, 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, + 0xe4, 0x35, 0x4a, 0xb4, 0xec, 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, + 0xc7, 0x25, 0xa8, 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, + 0x1a, 0x86, 0xf2, 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, + 0x08, 0x7a, 0xa5, 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, + 0x02, 0x7e, 0xcd, 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, + 0xab, 0x20, 0xc3, 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, + 0xed, 0x15, 0x82, 0x0f, 0xf1, 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, + 0x3a, 0x8b, 0x2a, 0x41, 0xee, 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, + 0x66, 0x0b, 0x2b, 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, + 0x90, 0xb1, 0x57, 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, + 0xa8, 0x37, 0xd3, 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, + 0x5a, 0xaa, 0x7e, 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, + 0xcc, 0x1c, 0x6c, 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, + 0xc0, 0x75, 0x31, 0xa3, 0x0c, 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, + 0x1d, 0x25, 0xd3, 0x09, 0xef, 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, + 0x7b, 0x2f, 0x22, 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, + 0x26, 0xd6, 0x25, 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, + 0x04, 0x2c, 0xbf, 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, + 0xb8, 0xb3, 0xfe, 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, + 0xac, 0xda, 0x18, 0x0a, 0x35, 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0b, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x23, 0x2f, 0x9f, 0x72, 0xeb, 0x70, 0x6d, 0x9e, 0x3e, 0x9f, 0xd7, + 0x9c, 0xd9, 0x19, 0x7c, 0x99, 0x07, 0xc5, 0x5c, 0x9d, 0xf5, 0x66, 0x9f, + 0x28, 0x8d, 0xfe, 0x0e, 0x3f, 0x38, 0x75, 0xed, 0xee, 0x4e, 0x3f, 0xf6, + 0x6e, 0x35, 0xe0, 0x95, 0x3f, 0x08, 0x4a, 0x71, 0x5a, 0xf2, 0x4f, 0xc9, + 0x96, 0x61, 0x8d, 0x45, 0x4b, 0x97, 0x85, 0xff, 0xb0, 0xe3, 0xbb, 0xb5, + 0xd7, 0x7e, 0xfb, 0xd2, 0xfc, 0xec, 0xfe, 0x42, 0x9f, 0x4e, 0x7b, 0xbf, + 0x97, 0xbb, 0xb4, 0x3a, 0x93, 0x0b, 0x13, 0x61, 0x90, 0x0c, 0x3a, 0xce, + 0xf7, 0x8e, 0xef, 0x80, 0xf5, 0x4a, 0x92, 0xc5, 0xa5, 0x03, 0x78, 0xc2, + 0xee, 0xb8, 0x66, 0x60, 0x6b, 0x76, 0x4f, 0x32, 0x5a, 0x1a, 0xa2, 0x4b, + 0x7e, 0x2b, 0xa6, 0x1a, 0x89, 0x01, 0xe3, 0xbb, 0x55, 0x13, 0x7c, 0x4c, + 0xf4, 0x6a, 0x99, 0x94, 0xd1, 0xa0, 0x84, 0x1c, 0x1a, 0xc2, 0x7b, 0xb4, + 0xa0, 0xb0, 0x3b, 0xdc, 0x5a, 0x7b, 0xc7, 0xe0, 0x44, 0xb2, 0x1f, 0x46, + 0xd5, 0x8b, 0x39, 0x8b, 0xdc, 0x9e, 0xce, 0xa8, 0x7f, 0x85, 0x1d, 0x4b, + 0x63, 0x06, 0x1e, 0x8e, 0xe5, 0xe5, 0x99, 0xd9, 0xf7, 0x4d, 0x89, 0x0b, + 0x1d, 0x5c, 0x27, 0x33, 0x66, 0x21, 0xcf, 0x9a, 0xbd, 0x98, 0x68, 0x23, + 0x3a, 0x66, 0x9d, 0xd4, 0x46, 0xed, 0x63, 0x58, 0xf3, 0x42, 0xe4, 0x1d, + 0xe2, 0x47, 0x65, 0x13, 0x8d, 0xd4, 0x1f, 0x4b, 0x7e, 0xde, 0x11, 0x56, + 0xf8, 0x6d, 0x01, 0x0c, 0x99, 0xbd, 0x8d, 0xca, 0x8a, 0x2e, 0xe3, 0x8a, + 0x9c, 0x3d, 0x83, 0x8d, 0x69, 0x62, 0x8d, 0x05, 0xea, 0xb7, 0xf5, 0xa3, + 0x4b, 0xfc, 0x96, 0xcf, 0x18, 0x21, 0x0a, 0xc7, 0xf3, 0x23, 0x7e, 0x1c, + 0xab, 0xe2, 0xa2, 0xd1, 0x83, 0xc4, 0x25, 0x93, 0x37, 0x80, 0xca, 0xda, + 0xf0, 0xef, 0x7d, 0x94, 0xb5, 0x59, 0x02, 0xd4, 0x30, 0x82, 0x02, 0xd0, + 0x30, 0x82, 0x01, 0xba, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x07, + 0x10, 0xaf, 0xc4, 0x1a, 0x3a, 0x56, 0x4f, 0xd8, 0xc2, 0xcc, 0x46, 0xd7, + 0x5b, 0xdf, 0x1c, 0x4e, 0x2f, 0x49, 0x3a, 0x30, 0x0b, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x30, 0x13, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x31, + 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, 0x10, 0x30, 0x0e, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x69, 0x6e, 0x74, 0x2d, 0x72, 0x73, + 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, + 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, + 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xba, 0x88, + 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, 0xfd, 0x6e, 0xb6, 0x88, 0x06, + 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, 0xe4, 0x35, 0x4a, 0xb4, 0xec, + 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, 0xc7, 0x25, 0xa8, 0xe0, 0xd8, + 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, 0x1a, 0x86, 0xf2, 0x6b, 0xe2, + 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, 0x08, 0x7a, 0xa5, 0x5a, 0xa7, + 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, 0x02, 0x7e, 0xcd, 0x43, 0xfc, + 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, 0xab, 0x20, 0xc3, 0x49, 0xe4, + 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, 0xed, 0x15, 0x82, 0x0f, 0xf1, + 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, 0x3a, 0x8b, 0x2a, 0x41, 0xee, + 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, 0x66, 0x0b, 0x2b, 0xb0, 0x24, + 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, 0x90, 0xb1, 0x57, 0x90, 0x3d, + 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, 0xa8, 0x37, 0xd3, 0x88, 0x43, + 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, 0x5a, 0xaa, 0x7e, 0x02, 0x90, + 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, 0xcc, 0x1c, 0x6c, 0x97, 0xad, + 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, 0xc0, 0x75, 0x31, 0xa3, 0x0c, + 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, 0x1d, 0x25, 0xd3, 0x09, 0xef, + 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, 0x7b, 0x2f, 0x22, 0x6f, 0x69, + 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, 0x26, 0xd6, 0x25, 0x9d, 0xab, + 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, 0x04, 0x2c, 0xbf, 0x16, 0x8b, + 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, 0xb8, 0xb3, 0xfe, 0x49, 0x23, + 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, 0xac, 0xda, 0x18, 0x0a, 0x35, + 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x1d, 0x30, 0x1b, 0x30, + 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, + 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, + 0x01, 0x06, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, 0x00, 0x5e, 0xba, 0x69, 0x55, + 0x9f, 0xf8, 0xeb, 0x16, 0x21, 0x98, 0xde, 0xb7, 0x31, 0x3e, 0x66, 0xe1, + 0x3b, 0x0c, 0x29, 0xf7, 0x48, 0x73, 0x05, 0xd9, 0xce, 0x5e, 0x4c, 0xbe, + 0x03, 0xc4, 0x51, 0xd6, 0x21, 0x92, 0x40, 0x38, 0xaa, 0x5b, 0x28, 0xb5, + 0xa1, 0x10, 0x52, 0x57, 0xff, 0x91, 0x54, 0x82, 0x86, 0x9e, 0x74, 0xd5, + 0x3d, 0x82, 0x29, 0xee, 0xd1, 0xcf, 0x93, 0xb1, 0x24, 0x76, 0xbb, 0x95, + 0x41, 0x06, 0x7e, 0x40, 0x9b, 0xb4, 0xab, 0x44, 0x34, 0x10, 0x8f, 0xb1, + 0x51, 0x6f, 0xc0, 0x89, 0xd1, 0xa3, 0xc4, 0x9f, 0xb3, 0x48, 0xe1, 0xcd, + 0x73, 0xad, 0xff, 0x42, 0x5f, 0x76, 0x05, 0x60, 0xc5, 0xe0, 0x45, 0x79, + 0x18, 0xa1, 0x19, 0xb8, 0xa7, 0x3a, 0x64, 0xb3, 0x19, 0xba, 0x14, 0xa1, + 0xb5, 0xdc, 0x32, 0xec, 0x09, 0x39, 0x58, 0x54, 0x5b, 0x04, 0xdc, 0x1b, + 0x66, 0x0d, 0x1d, 0x0d, 0xce, 0x7f, 0xfa, 0x24, 0x52, 0x6a, 0xad, 0xe2, + 0xc8, 0x30, 0xaf, 0xf2, 0xaf, 0x63, 0xc5, 0xe2, 0xbf, 0xe2, 0x20, 0x1b, + 0x9e, 0xf9, 0x3d, 0xbc, 0xfb, 0x04, 0x8e, 0xda, 0x7a, 0x1a, 0x5d, 0xd3, + 0x13, 0xd7, 0x00, 0x8e, 0x9b, 0x5d, 0x85, 0x51, 0xda, 0xd3, 0x91, 0x25, + 0xf5, 0x67, 0x85, 0x3e, 0x25, 0x89, 0x5e, 0xcb, 0x89, 0x8a, 0xec, 0x8a, + 0xde, 0x8b, 0xf4, 0x33, 0x5f, 0x76, 0xdb, 0x3d, 0xfc, 0x6a, 0x05, 0x21, + 0x43, 0xb2, 0x41, 0xd8, 0x33, 0x8d, 0xfd, 0x05, 0x5c, 0x22, 0x0a, 0xf6, + 0x90, 0x65, 0x9c, 0x4f, 0x8c, 0x44, 0x9f, 0x2d, 0xca, 0xf3, 0x49, 0x9c, + 0x3a, 0x14, 0x88, 0xab, 0xe4, 0xce, 0xb7, 0xbc, 0x95, 0x22, 0x2e, 0xb1, + 0x82, 0x4c, 0xbf, 0x83, 0x3e, 0x49, 0x72, 0x03, 0x2a, 0x68, 0xe7, 0x2d, + 0xe5, 0x2d, 0x4b, 0x61, 0xb0, 0x8d, 0x0d, 0x0c, 0x87, 0xc6, 0x5c, 0x51, + 0xa0, 0xf6, 0x82, 0x83, 0x59, 0x01, 0x33, 0xa2, 0x01, 0x26, 0x04, 0x59, + 0x01, 0x2c, 0x30, 0x82, 0x01, 0x28, 0x30, 0x81, 0xcf, 0xa0, 0x03, 0x02, + 0x01, 0x02, 0x02, 0x14, 0x2f, 0xc3, 0x5f, 0x05, 0x80, 0xb4, 0x49, 0x45, + 0x13, 0x92, 0xd6, 0x93, 0xb7, 0x2d, 0x71, 0x19, 0xc5, 0x8c, 0x40, 0x39, + 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, + 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x69, 0x6e, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x65, 0x65, + 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, + 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, + 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, + 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, + 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, + 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, + 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, + 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, + 0x11, 0x50, 0xcd, 0x5d, 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, + 0xff, 0xb2, 0x73, 0x75, 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, + 0x0a, 0x70, 0xe6, 0x02, 0x21, 0x00, 0xff, 0x81, 0xbe, 0xa8, 0x0d, 0x03, + 0x36, 0x6b, 0x75, 0xe2, 0x70, 0x6a, 0xac, 0x07, 0x2e, 0x4c, 0xdc, 0xf9, + 0xc5, 0x89, 0xc1, 0xcf, 0x88, 0xc2, 0xc8, 0x2a, 0x32, 0xf5, 0x42, 0x0c, + 0xfa, 0x0b, 0xa0, 0x58, 0x40, 0xa3, 0xfb, 0x49, 0xe6, 0x45, 0x29, 0x64, + 0x76, 0xeb, 0x9d, 0xbd, 0xf5, 0x38, 0x56, 0xbe, 0x6e, 0x31, 0x57, 0x73, + 0xc1, 0x2d, 0x3e, 0xac, 0xee, 0xba, 0x55, 0x8e, 0x37, 0xd4, 0xea, 0x80, + 0x25, 0x31, 0x99, 0x9f, 0x4a, 0xb0, 0xf9, 0xd8, 0xb0, 0xed, 0x74, 0xfc, + 0x8c, 0x02, 0xf0, 0x9f, 0x95, 0xf1, 0xaa, 0x71, 0xcc, 0xd2, 0xe7, 0x1a, + 0x6d, 0xd4, 0xed, 0xff, 0xf2, 0x78, 0x09, 0x83, 0x7e, 0x83, 0x59, 0x02, + 0xbb, 0xa2, 0x01, 0x38, 0x24, 0x04, 0x59, 0x02, 0xb3, 0x30, 0x82, 0x02, + 0xaf, 0x30, 0x82, 0x01, 0x99, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, + 0x07, 0x1c, 0x3b, 0x71, 0x08, 0xbe, 0xd7, 0x9f, 0xfd, 0xaf, 0x26, 0xb6, + 0x08, 0xa3, 0x99, 0x06, 0x77, 0x69, 0x32, 0x7e, 0x30, 0x0b, 0x06, 0x09, + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x30, 0x12, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x69, 0x6e, + 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, 0x0f, 0x32, 0x30, 0x31, + 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, + 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, 0x31, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x11, 0x31, 0x0f, 0x30, 0x0d, 0x06, + 0x03, 0x55, 0x04, 0x03, 0x0c, 0x06, 0x65, 0x65, 0x2d, 0x72, 0x73, 0x61, + 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, + 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xba, 0x88, 0x51, + 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, 0xfd, 0x6e, 0xb6, 0x88, 0x06, 0x36, + 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, 0xe4, 0x35, 0x4a, 0xb4, 0xec, 0xf5, + 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, 0xc7, 0x25, 0xa8, 0xe0, 0xd8, 0x1f, + 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, 0x1a, 0x86, 0xf2, 0x6b, 0xe2, 0xaf, + 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, 0x08, 0x7a, 0xa5, 0x5a, 0xa7, 0x45, + 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, 0x02, 0x7e, 0xcd, 0x43, 0xfc, 0x1e, + 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, 0xab, 0x20, 0xc3, 0x49, 0xe4, 0xdb, + 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, 0xed, 0x15, 0x82, 0x0f, 0xf1, 0x7e, + 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, 0x3a, 0x8b, 0x2a, 0x41, 0xee, 0xa7, + 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, 0x66, 0x0b, 0x2b, 0xb0, 0x24, 0x92, + 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, 0x90, 0xb1, 0x57, 0x90, 0x3d, 0xd2, + 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, 0xa8, 0x37, 0xd3, 0x88, 0x43, 0xef, + 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, 0x5a, 0xaa, 0x7e, 0x02, 0x90, 0x2f, + 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, 0xcc, 0x1c, 0x6c, 0x97, 0xad, 0x96, + 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, 0xc0, 0x75, 0x31, 0xa3, 0x0c, 0x91, + 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, 0x1d, 0x25, 0xd3, 0x09, 0xef, 0xb9, + 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, 0x7b, 0x2f, 0x22, 0x6f, 0x69, 0xe3, + 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, 0x26, 0xd6, 0x25, 0x9d, 0xab, 0x91, + 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, 0x04, 0x2c, 0xbf, 0x16, 0x8b, 0x2f, + 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, 0xb8, 0xb3, 0xfe, 0x49, 0x23, 0xfa, + 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, 0xac, 0xda, 0x18, 0x0a, 0x35, 0xed, + 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x44, 0x92, 0xbb, 0x8e, 0x83, 0x58, 0x56, 0x2e, 0x7a, 0x86, 0xfa, 0x1d, + 0x77, 0x50, 0x3f, 0x45, 0x8d, 0x90, 0xc4, 0x62, 0x27, 0x21, 0x96, 0x5a, + 0xef, 0x51, 0x78, 0xd7, 0x7d, 0x0d, 0x02, 0x2d, 0x5a, 0x0e, 0x3c, 0x82, + 0x6f, 0x1d, 0x92, 0x87, 0xd5, 0x1a, 0x44, 0xae, 0xa7, 0x92, 0xd1, 0x8b, + 0xfa, 0x16, 0x53, 0x7f, 0xa3, 0x22, 0x96, 0x1a, 0x51, 0x8c, 0xeb, 0xa1, + 0xe6, 0xf6, 0x37, 0x11, 0xfe, 0x7d, 0x53, 0x3f, 0xae, 0xf0, 0x6b, 0xb9, + 0xb1, 0x7a, 0x73, 0x07, 0x14, 0xcf, 0x04, 0x05, 0x93, 0x9e, 0xe3, 0xd2, + 0x4d, 0x9d, 0x6d, 0x35, 0x68, 0xf9, 0x36, 0xe5, 0x10, 0x0a, 0x36, 0xd9, + 0x48, 0xb0, 0x83, 0xd0, 0xb9, 0x58, 0x74, 0x53, 0xb3, 0xbc, 0x99, 0xab, + 0xe1, 0x3e, 0xd5, 0x01, 0x8e, 0xcf, 0x3a, 0x69, 0x93, 0x9e, 0xa7, 0x88, + 0xd4, 0xad, 0x95, 0xf9, 0x2a, 0xb4, 0x7f, 0x95, 0x97, 0x86, 0x50, 0x38, + 0xb1, 0x04, 0x0a, 0xe4, 0x7a, 0xd5, 0x2d, 0x6c, 0xde, 0x3e, 0x1a, 0x47, + 0x17, 0x88, 0x63, 0x20, 0x9d, 0x21, 0x3e, 0x0c, 0x6f, 0xfd, 0x20, 0x54, + 0xd0, 0x67, 0xd2, 0x6b, 0x06, 0xfe, 0x60, 0x13, 0x42, 0x3d, 0xb7, 0xca, + 0xcb, 0xab, 0x7b, 0x5f, 0x5d, 0x01, 0x56, 0xd3, 0x99, 0x80, 0x0f, 0xde, + 0x7f, 0x3a, 0x61, 0x9c, 0xd3, 0x6b, 0x5e, 0xfe, 0xb5, 0xfc, 0x39, 0x8b, + 0x8e, 0xf0, 0x8c, 0x8b, 0x65, 0x46, 0x45, 0xff, 0x47, 0x8f, 0xd4, 0xdd, + 0xae, 0xc9, 0x72, 0xc7, 0x7f, 0x28, 0x86, 0xf1, 0xf7, 0x6e, 0xcb, 0x86, + 0x03, 0xeb, 0x0c, 0x46, 0xe5, 0xa0, 0x6b, 0xef, 0xd4, 0x5e, 0xa4, 0x0f, + 0x53, 0xe1, 0xbc, 0xb4, 0xc9, 0x37, 0x0e, 0x75, 0xdd, 0x93, 0xe8, 0x0f, + 0x18, 0x0a, 0x02, 0x83, 0x17, 0x74, 0xbb, 0x1a, 0x42, 0x5b, 0x63, 0x2c, + 0x80, 0x80, 0xa6, 0x84, 0xa0, 0x59, 0x01, 0x00, 0x51, 0xf4, 0xe6, 0x1c, + 0x18, 0x7b, 0x28, 0xa0, 0x1f, 0x63, 0xbf, 0xa5, 0xbd, 0x89, 0x9f, 0xd9, + 0x30, 0x46, 0x4b, 0x34, 0x9b, 0x9d, 0x0f, 0xb0, 0x33, 0x11, 0xf8, 0xaa, + 0x84, 0x4e, 0xb2, 0xca, 0x29, 0x83, 0x54, 0x28, 0x99, 0x2a, 0x43, 0x7f, + 0xe0, 0xe6, 0xd8, 0xdc, 0xd7, 0xf4, 0xb3, 0xd7, 0xf7, 0x39, 0xd5, 0xdc, + 0xde, 0xdc, 0x23, 0x78, 0xd7, 0x90, 0xc0, 0x52, 0xf5, 0xd2, 0x14, 0x6f, + 0xf9, 0x24, 0x48, 0xc8, 0x75, 0x4a, 0x9a, 0x4c, 0x61, 0x2f, 0x96, 0x4e, + 0xc8, 0x02, 0x95, 0x72, 0xef, 0xbc, 0x91, 0xae, 0xf8, 0x23, 0xfb, 0xba, + 0x9f, 0xfd, 0xe0, 0x1a, 0x8e, 0xa9, 0x03, 0x16, 0x76, 0xf4, 0xdb, 0x81, + 0x5a, 0x69, 0xeb, 0xf5, 0x55, 0xd7, 0x68, 0x28, 0xe4, 0xce, 0xde, 0x1b, + 0xb4, 0x90, 0xac, 0x97, 0x07, 0x15, 0xe0, 0xce, 0x5f, 0x3f, 0x89, 0xaf, + 0xc1, 0xb8, 0x46, 0x5e, 0x87, 0xa1, 0x8d, 0xa7, 0x44, 0x09, 0x02, 0x4e, + 0xbe, 0x6b, 0xfb, 0xab, 0xeb, 0x19, 0x62, 0x9e, 0xb0, 0xef, 0x0a, 0x6b, + 0xcf, 0xe0, 0x00, 0xa9, 0x68, 0x2a, 0x8e, 0xfe, 0x8a, 0xb9, 0x57, 0x52, + 0xb3, 0x08, 0x80, 0x5e, 0xa6, 0x88, 0x5f, 0x31, 0xd1, 0xe9, 0x6d, 0xf7, + 0x54, 0x4e, 0xf8, 0x17, 0xb0, 0x1c, 0xca, 0xa6, 0xa6, 0x80, 0xf8, 0xd8, + 0xf5, 0x94, 0xa4, 0xb2, 0xd0, 0x7e, 0xbb, 0x4f, 0xdb, 0x3a, 0x91, 0x5f, + 0xb3, 0xc1, 0xfa, 0x60, 0xe4, 0xce, 0xe3, 0xe5, 0x14, 0x1f, 0x9c, 0x01, + 0x60, 0xff, 0xe2, 0x09, 0xe6, 0x1a, 0x82, 0x69, 0xb6, 0xeb, 0x52, 0x1e, + 0x3d, 0xc7, 0xfd, 0x69, 0x9d, 0x2a, 0xa5, 0xdb, 0xc1, 0x6a, 0x5a, 0x7d, + 0x23, 0x2a, 0x00, 0xe4, 0x53, 0x16, 0x8e, 0xc1, 0x56, 0xf5, 0x5a, 0x8d, + 0x59, 0x1f, 0x7f, 0xff, 0x77, 0x6f, 0x92, 0xea, 0x5d, 0x31, 0xe9, 0x18}; + +// The RSA intermediate certificate that issued the EE cert used in the +// signature above. The certificate was generated with pycert.py +const uint8_t RSA_INT[] = { + 0x30, 0x82, 0x02, 0xd0, 0x30, 0x82, 0x01, 0xba, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x07, 0x10, 0xaf, 0xc4, 0x1a, 0x3a, 0x56, 0x4f, 0xd8, + 0xc2, 0xcc, 0x46, 0xd7, 0x5b, 0xdf, 0x1c, 0x4e, 0x2f, 0x49, 0x3a, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x12, 0x31, + 0x10, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x07, 0x69, 0x6e, + 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, + 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, + 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, + 0x01, 0x00, 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, 0xfd, + 0x6e, 0xb6, 0x88, 0x06, 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, 0xe4, + 0x35, 0x4a, 0xb4, 0xec, 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, 0xc7, + 0x25, 0xa8, 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, 0x1a, + 0x86, 0xf2, 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, 0x08, + 0x7a, 0xa5, 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, 0x02, + 0x7e, 0xcd, 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, 0xab, + 0x20, 0xc3, 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, 0xed, + 0x15, 0x82, 0x0f, 0xf1, 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, 0x3a, + 0x8b, 0x2a, 0x41, 0xee, 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, 0x66, + 0x0b, 0x2b, 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, 0x90, + 0xb1, 0x57, 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, 0xa8, + 0x37, 0xd3, 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, 0x5a, + 0xaa, 0x7e, 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, 0xcc, + 0x1c, 0x6c, 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, 0xc0, + 0x75, 0x31, 0xa3, 0x0c, 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, 0x1d, + 0x25, 0xd3, 0x09, 0xef, 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, 0x7b, + 0x2f, 0x22, 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, 0x26, + 0xd6, 0x25, 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, 0x04, + 0x2c, 0xbf, 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, 0xb8, + 0xb3, 0xfe, 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, 0xac, + 0xda, 0x18, 0x0a, 0x35, 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, + 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, + 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, + 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0b, 0x06, 0x09, 0x2a, 0x86, + 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, 0x00, + 0x5e, 0xba, 0x69, 0x55, 0x9f, 0xf8, 0xeb, 0x16, 0x21, 0x98, 0xde, 0xb7, + 0x31, 0x3e, 0x66, 0xe1, 0x3b, 0x0c, 0x29, 0xf7, 0x48, 0x73, 0x05, 0xd9, + 0xce, 0x5e, 0x4c, 0xbe, 0x03, 0xc4, 0x51, 0xd6, 0x21, 0x92, 0x40, 0x38, + 0xaa, 0x5b, 0x28, 0xb5, 0xa1, 0x10, 0x52, 0x57, 0xff, 0x91, 0x54, 0x82, + 0x86, 0x9e, 0x74, 0xd5, 0x3d, 0x82, 0x29, 0xee, 0xd1, 0xcf, 0x93, 0xb1, + 0x24, 0x76, 0xbb, 0x95, 0x41, 0x06, 0x7e, 0x40, 0x9b, 0xb4, 0xab, 0x44, + 0x34, 0x10, 0x8f, 0xb1, 0x51, 0x6f, 0xc0, 0x89, 0xd1, 0xa3, 0xc4, 0x9f, + 0xb3, 0x48, 0xe1, 0xcd, 0x73, 0xad, 0xff, 0x42, 0x5f, 0x76, 0x05, 0x60, + 0xc5, 0xe0, 0x45, 0x79, 0x18, 0xa1, 0x19, 0xb8, 0xa7, 0x3a, 0x64, 0xb3, + 0x19, 0xba, 0x14, 0xa1, 0xb5, 0xdc, 0x32, 0xec, 0x09, 0x39, 0x58, 0x54, + 0x5b, 0x04, 0xdc, 0x1b, 0x66, 0x0d, 0x1d, 0x0d, 0xce, 0x7f, 0xfa, 0x24, + 0x52, 0x6a, 0xad, 0xe2, 0xc8, 0x30, 0xaf, 0xf2, 0xaf, 0x63, 0xc5, 0xe2, + 0xbf, 0xe2, 0x20, 0x1b, 0x9e, 0xf9, 0x3d, 0xbc, 0xfb, 0x04, 0x8e, 0xda, + 0x7a, 0x1a, 0x5d, 0xd3, 0x13, 0xd7, 0x00, 0x8e, 0x9b, 0x5d, 0x85, 0x51, + 0xda, 0xd3, 0x91, 0x25, 0xf5, 0x67, 0x85, 0x3e, 0x25, 0x89, 0x5e, 0xcb, + 0x89, 0x8a, 0xec, 0x8a, 0xde, 0x8b, 0xf4, 0x33, 0x5f, 0x76, 0xdb, 0x3d, + 0xfc, 0x6a, 0x05, 0x21, 0x43, 0xb2, 0x41, 0xd8, 0x33, 0x8d, 0xfd, 0x05, + 0x5c, 0x22, 0x0a, 0xf6, 0x90, 0x65, 0x9c, 0x4f, 0x8c, 0x44, 0x9f, 0x2d, + 0xca, 0xf3, 0x49, 0x9c, 0x3a, 0x14, 0x88, 0xab, 0xe4, 0xce, 0xb7, 0xbc, + 0x95, 0x22, 0x2e, 0xb1, 0x82, 0x4c, 0xbf, 0x83, 0x3e, 0x49, 0x72, 0x03, + 0x2a, 0x68, 0xe7, 0x2d, 0xe5, 0x2d, 0x4b, 0x61, 0xb0, 0x8d, 0x0d, 0x0c, + 0x87, 0xc6, 0x5c, 0x51}; + +// The RSA root certificate that issued the RSA intermediate certificate above. +// The certificate was generated with pycert.py +const uint8_t RSA_ROOT[] = { + 0x30, 0x82, 0x02, 0xd1, 0x30, 0x82, 0x01, 0xbb, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x14, 0x29, 0x6c, 0x1a, 0xd8, 0x20, 0xcd, 0x74, 0x6d, 0x4b, + 0x00, 0xf3, 0x16, 0x88, 0xd9, 0x66, 0x87, 0x5f, 0x28, 0x56, 0x6a, 0x30, + 0x0b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + 0x30, 0x13, 0x31, 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, + 0x08, 0x72, 0x6f, 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x22, 0x18, + 0x0f, 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, + 0x33, 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, + 0x11, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x72, 0x6f, + 0x6f, 0x74, 0x2d, 0x72, 0x73, 0x61, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, + 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, + 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, + 0x01, 0x01, 0x00, 0xba, 0x88, 0x51, 0xa8, 0x44, 0x8e, 0x16, 0xd6, 0x41, + 0xfd, 0x6e, 0xb6, 0x88, 0x06, 0x36, 0x10, 0x3d, 0x3c, 0x13, 0xd9, 0xea, + 0xe4, 0x35, 0x4a, 0xb4, 0xec, 0xf5, 0x68, 0x57, 0x6c, 0x24, 0x7b, 0xc1, + 0xc7, 0x25, 0xa8, 0xe0, 0xd8, 0x1f, 0xbd, 0xb1, 0x9c, 0x06, 0x9b, 0x6e, + 0x1a, 0x86, 0xf2, 0x6b, 0xe2, 0xaf, 0x5a, 0x75, 0x6b, 0x6a, 0x64, 0x71, + 0x08, 0x7a, 0xa5, 0x5a, 0xa7, 0x45, 0x87, 0xf7, 0x1c, 0xd5, 0x24, 0x9c, + 0x02, 0x7e, 0xcd, 0x43, 0xfc, 0x1e, 0x69, 0xd0, 0x38, 0x20, 0x29, 0x93, + 0xab, 0x20, 0xc3, 0x49, 0xe4, 0xdb, 0xb9, 0x4c, 0xc2, 0x6b, 0x6c, 0x0e, + 0xed, 0x15, 0x82, 0x0f, 0xf1, 0x7e, 0xad, 0x69, 0x1a, 0xb1, 0xd3, 0x02, + 0x3a, 0x8b, 0x2a, 0x41, 0xee, 0xa7, 0x70, 0xe0, 0x0f, 0x0d, 0x8d, 0xfd, + 0x66, 0x0b, 0x2b, 0xb0, 0x24, 0x92, 0xa4, 0x7d, 0xb9, 0x88, 0x61, 0x79, + 0x90, 0xb1, 0x57, 0x90, 0x3d, 0xd2, 0x3b, 0xc5, 0xe0, 0xb8, 0x48, 0x1f, + 0xa8, 0x37, 0xd3, 0x88, 0x43, 0xef, 0x27, 0x16, 0xd8, 0x55, 0xb7, 0x66, + 0x5a, 0xaa, 0x7e, 0x02, 0x90, 0x2f, 0x3a, 0x7b, 0x10, 0x80, 0x06, 0x24, + 0xcc, 0x1c, 0x6c, 0x97, 0xad, 0x96, 0x61, 0x5b, 0xb7, 0xe2, 0x96, 0x12, + 0xc0, 0x75, 0x31, 0xa3, 0x0c, 0x91, 0xdd, 0xb4, 0xca, 0xf7, 0xfc, 0xad, + 0x1d, 0x25, 0xd3, 0x09, 0xef, 0xb9, 0x17, 0x0e, 0xa7, 0x68, 0xe1, 0xb3, + 0x7b, 0x2f, 0x22, 0x6f, 0x69, 0xe3, 0xb4, 0x8a, 0x95, 0x61, 0x1d, 0xee, + 0x26, 0xd6, 0x25, 0x9d, 0xab, 0x91, 0x08, 0x4e, 0x36, 0xcb, 0x1c, 0x24, + 0x04, 0x2c, 0xbf, 0x16, 0x8b, 0x2f, 0xe5, 0xf1, 0x8f, 0x99, 0x17, 0x31, + 0xb8, 0xb3, 0xfe, 0x49, 0x23, 0xfa, 0x72, 0x51, 0xc4, 0x31, 0xd5, 0x03, + 0xac, 0xda, 0x18, 0x0a, 0x35, 0xed, 0x8d, 0x02, 0x03, 0x01, 0x00, 0x01, + 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0b, 0x06, 0x09, 0x2a, + 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x03, 0x82, 0x01, 0x01, + 0x00, 0x23, 0x2f, 0x9f, 0x72, 0xeb, 0x70, 0x6d, 0x9e, 0x3e, 0x9f, 0xd7, + 0x9c, 0xd9, 0x19, 0x7c, 0x99, 0x07, 0xc5, 0x5c, 0x9d, 0xf5, 0x66, 0x9f, + 0x28, 0x8d, 0xfe, 0x0e, 0x3f, 0x38, 0x75, 0xed, 0xee, 0x4e, 0x3f, 0xf6, + 0x6e, 0x35, 0xe0, 0x95, 0x3f, 0x08, 0x4a, 0x71, 0x5a, 0xf2, 0x4f, 0xc9, + 0x96, 0x61, 0x8d, 0x45, 0x4b, 0x97, 0x85, 0xff, 0xb0, 0xe3, 0xbb, 0xb5, + 0xd7, 0x7e, 0xfb, 0xd2, 0xfc, 0xec, 0xfe, 0x42, 0x9f, 0x4e, 0x7b, 0xbf, + 0x97, 0xbb, 0xb4, 0x3a, 0x93, 0x0b, 0x13, 0x61, 0x90, 0x0c, 0x3a, 0xce, + 0xf7, 0x8e, 0xef, 0x80, 0xf5, 0x4a, 0x92, 0xc5, 0xa5, 0x03, 0x78, 0xc2, + 0xee, 0xb8, 0x66, 0x60, 0x6b, 0x76, 0x4f, 0x32, 0x5a, 0x1a, 0xa2, 0x4b, + 0x7e, 0x2b, 0xa6, 0x1a, 0x89, 0x01, 0xe3, 0xbb, 0x55, 0x13, 0x7c, 0x4c, + 0xf4, 0x6a, 0x99, 0x94, 0xd1, 0xa0, 0x84, 0x1c, 0x1a, 0xc2, 0x7b, 0xb4, + 0xa0, 0xb0, 0x3b, 0xdc, 0x5a, 0x7b, 0xc7, 0xe0, 0x44, 0xb2, 0x1f, 0x46, + 0xd5, 0x8b, 0x39, 0x8b, 0xdc, 0x9e, 0xce, 0xa8, 0x7f, 0x85, 0x1d, 0x4b, + 0x63, 0x06, 0x1e, 0x8e, 0xe5, 0xe5, 0x99, 0xd9, 0xf7, 0x4d, 0x89, 0x0b, + 0x1d, 0x5c, 0x27, 0x33, 0x66, 0x21, 0xcf, 0x9a, 0xbd, 0x98, 0x68, 0x23, + 0x3a, 0x66, 0x9d, 0xd4, 0x46, 0xed, 0x63, 0x58, 0xf3, 0x42, 0xe4, 0x1d, + 0xe2, 0x47, 0x65, 0x13, 0x8d, 0xd4, 0x1f, 0x4b, 0x7e, 0xde, 0x11, 0x56, + 0xf8, 0x6d, 0x01, 0x0c, 0x99, 0xbd, 0x8d, 0xca, 0x8a, 0x2e, 0xe3, 0x8a, + 0x9c, 0x3d, 0x83, 0x8d, 0x69, 0x62, 0x8d, 0x05, 0xea, 0xb7, 0xf5, 0xa3, + 0x4b, 0xfc, 0x96, 0xcf, 0x18, 0x21, 0x0a, 0xc7, 0xf3, 0x23, 0x7e, 0x1c, + 0xab, 0xe2, 0xa2, 0xd1, 0x83, 0xc4, 0x25, 0x93, 0x37, 0x80, 0xca, 0xda, + 0xf0, 0xef, 0x7d, 0x94, 0xb5}; + +// The P256 intermediate certificate that issued the EE cert used in the +// signatures above. The certificate was generated with pycert.py +const uint8_t P256_INT[] = { + 0x30, 0x82, 0x01, 0x48, 0x30, 0x81, 0xf0, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x43, 0x63, 0x59, 0xad, 0x04, 0x34, 0x56, 0x80, 0x43, 0xec, + 0x90, 0x6a, 0xd4, 0x10, 0x64, 0x7c, 0x7f, 0x38, 0x32, 0xe2, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x13, 0x31, 0x11, + 0x30, 0x0f, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x08, 0x69, 0x6e, 0x74, + 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, 0xbb, + 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, 0xe2, + 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, 0x4f, + 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, 0xc4, + 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, 0xd7, + 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, 0xc0, + 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, + 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, + 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, 0x2a, + 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, + 0x02, 0x20, 0x63, 0x59, 0x02, 0x01, 0x89, 0xd7, 0x3e, 0x5b, 0xff, 0xd1, + 0x16, 0x4e, 0xe3, 0xe2, 0x0a, 0xe0, 0x4a, 0xd8, 0x75, 0xaf, 0x77, 0x5c, + 0x93, 0x60, 0xba, 0x10, 0x1f, 0x97, 0xdd, 0x27, 0x2d, 0x24, 0x02, 0x20, + 0x3d, 0x87, 0x0f, 0xac, 0x22, 0x4d, 0x16, 0xd9, 0xa1, 0x95, 0xbb, 0x56, + 0xe0, 0x21, 0x05, 0x93, 0xd1, 0x07, 0xb5, 0x25, 0x3b, 0xf4, 0x57, 0x20, + 0x87, 0x13, 0xa2, 0xf7, 0x78, 0x15, 0x30, 0xa7}; + +// The P256 root certificate that issued the P256 intermediate certificate +// above. The certificate was generated with pycert.py +const uint8_t P256_ROOT[] = { + 0x30, 0x82, 0x01, 0x4a, 0x30, 0x81, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, + 0x02, 0x14, 0x5f, 0x3f, 0xae, 0x90, 0x49, 0x30, 0x2f, 0x33, 0x6e, 0x95, + 0x23, 0xa7, 0xcb, 0x23, 0xd7, 0x65, 0x4f, 0xea, 0x3c, 0xf7, 0x30, 0x0a, + 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x14, + 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, + 0x6f, 0x6f, 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x22, 0x18, 0x0f, + 0x32, 0x30, 0x31, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x30, 0x30, 0x30, + 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x32, 0x30, 0x32, 0x31, 0x31, 0x32, 0x33, + 0x31, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x30, 0x14, 0x31, 0x12, + 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x09, 0x72, 0x6f, 0x6f, + 0x74, 0x2d, 0x70, 0x32, 0x35, 0x36, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4f, 0xbf, 0xbb, + 0xbb, 0x61, 0xe0, 0xf8, 0xf9, 0xb1, 0xa6, 0x0a, 0x59, 0xac, 0x87, 0x04, + 0xe2, 0xec, 0x05, 0x0b, 0x42, 0x3e, 0x3c, 0xf7, 0x2e, 0x92, 0x3f, 0x2c, + 0x4f, 0x79, 0x4b, 0x45, 0x5c, 0x2a, 0x69, 0xd2, 0x33, 0x45, 0x6c, 0x36, + 0xc4, 0x11, 0x9d, 0x07, 0x06, 0xe0, 0x0e, 0xed, 0xc8, 0xd1, 0x93, 0x90, + 0xd7, 0x99, 0x1b, 0x7b, 0x2d, 0x07, 0xa3, 0x04, 0xea, 0xa0, 0x4a, 0xa6, + 0xc0, 0xa3, 0x1d, 0x30, 0x1b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, + 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, + 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0x06, 0x30, 0x0a, 0x06, 0x08, + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, + 0x45, 0x02, 0x20, 0x5c, 0x75, 0x51, 0x9f, 0x13, 0x11, 0x50, 0xcd, 0x5d, + 0x8a, 0xde, 0x20, 0xa3, 0xbc, 0x06, 0x30, 0x91, 0xff, 0xb2, 0x73, 0x75, + 0x5f, 0x31, 0x64, 0xec, 0xfd, 0xcb, 0x42, 0x80, 0x0a, 0x70, 0xe6, 0x02, + 0x21, 0x00, 0xc2, 0xe4, 0xc1, 0xa8, 0xe2, 0x89, 0xdc, 0xa1, 0xbb, 0xe7, + 0xd5, 0x4f, 0x5c, 0x88, 0xad, 0xeb, 0xa4, 0x78, 0xa1, 0x19, 0xbe, 0x22, + 0x54, 0xc8, 0x9f, 0xef, 0xb8, 0x5d, 0xa2, 0x40, 0xd9, 0x8b}; + +void check_hard_coded_certs(const uint8_t** cert_chain, size_t cert_chain_len, + const size_t* certs_len) { + // Very hacky and fragile check that the intermediate certs are correct. + switch (cert_chain_len) { + case 2: { + const uint8_t* cert = cert_chain[0]; + size_t cert_len = certs_len[0]; + ASSERT_EQ(cert_len, sizeof(P256_ROOT)); + ASSERT_EQ(0, memcmp(cert, P256_ROOT, cert_len)); + cert = cert_chain[1]; + cert_len = certs_len[1]; + ASSERT_EQ(cert_len, sizeof(P256_INT)); + ASSERT_EQ(0, memcmp(cert, P256_INT, cert_len)); + break; + } + case 4: { + const uint8_t* cert = cert_chain[0]; + size_t cert_len = certs_len[0]; + ASSERT_EQ(cert_len, sizeof(P256_ROOT)); + ASSERT_EQ(0, memcmp(cert, P256_ROOT, cert_len)); + cert = cert_chain[1]; + cert_len = certs_len[1]; + ASSERT_EQ(cert_len, sizeof(P256_INT)); + ASSERT_EQ(0, memcmp(cert, P256_INT, cert_len)); + cert = cert_chain[2]; + cert_len = certs_len[2]; + ASSERT_EQ(cert_len, sizeof(RSA_ROOT)); + ASSERT_EQ(0, memcmp(cert, RSA_ROOT, cert_len)); + cert = cert_chain[3]; + cert_len = certs_len[3]; + ASSERT_EQ(cert_len, sizeof(RSA_INT)); + ASSERT_EQ(0, memcmp(cert, RSA_INT, cert_len)); + break; + } + default: + // In this case something went wrong. + ASSERT_EQ(true, false); + } +} + +/* Verification function called from cose-rust. + * Returns true if everything goes well and the signature is good, false in any + * other case. */ +bool verify_callback(const uint8_t* payload, size_t payload_len, + const uint8_t** cert_chain, size_t cert_chain_len, + const size_t* certs_len, const uint8_t* ee_cert, + size_t ee_cert_len, const uint8_t* signature, + size_t signature_len, uint8_t signature_algorithm, + void* ctx) { + UniquePK11SlotInfo slot(PK11_GetInternalSlot()); + if (!slot) { + return false; + } + + CK_MECHANISM_TYPE mechanism; + SECOidTag oid; + uint32_t hash_length; + SECItem param = {siBuffer, nullptr, 0}; + CK_RSA_PKCS_PSS_PARAMS rsa_pss_params = {CKM_SHA256, CKG_MGF1_SHA256, + SHA256_LENGTH}; + switch (signature_algorithm) { + case (ES256): + mechanism = CKM_ECDSA; + oid = SEC_OID_SHA256; + hash_length = SHA256_LENGTH; + break; + case (PS256): + mechanism = CKM_RSA_PKCS_PSS; + oid = SEC_OID_SHA256; + hash_length = SHA256_LENGTH; + param = {siBuffer, reinterpret_cast(&rsa_pss_params), + sizeof(rsa_pss_params)}; + break; + default: + return false; + } + check_hard_coded_certs(cert_chain, cert_chain_len, certs_len); + + uint8_t hash_buf[HASH_LENGTH_MAX]; + SECStatus rv = PK11_HashBuf(oid, hash_buf, payload, payload_len); + if (rv != SECSuccess) { + return false; + } + SECItem hash_item = {siBuffer, hash_buf, hash_length}; + CERTCertDBHandle* db_handle = CERT_GetDefaultCertDB(); + if (!db_handle) { + return false; + } + SECItem der_cert = {siBuffer, const_cast(ee_cert), + static_cast(ee_cert_len)}; + UniqueCERTCertificate cert( + CERT_NewTempCertificate(db_handle, &der_cert, nullptr, false, true)); + if (!cert) { + return false; + } + UniqueSECKEYPublicKey key(CERT_ExtractPublicKey(cert.get())); + if (!key) { + return false; + } + SECItem signature_item = {siBuffer, const_cast(signature), + static_cast(signature_len)}; + rv = PK11_VerifyWithMechanism(key.get(), mechanism, ¶m, &signature_item, + &hash_item, nullptr); + if (rv != SECSuccess) { + return false; + } + + return true; +} + +class psm_COSE : public ::testing::Test {}; + +TEST_F(psm_COSE, CoseTestingSingleSignature) { + SECStatus rv = NSS_NoDB_Init(nullptr); + ASSERT_EQ(SECSuccess, rv); + bool result = + verify_cose_signature_ffi(PAYLOAD, sizeof(PAYLOAD), SIGNATURE, + sizeof(SIGNATURE), nullptr, verify_callback); + ASSERT_TRUE(result); +} + +TEST_F(psm_COSE, CoseTestingTwoSignatures) { + SECStatus rv = NSS_NoDB_Init(nullptr); + ASSERT_EQ(SECSuccess, rv); + bool result = verify_cose_signature_ffi( + PAYLOAD, sizeof(PAYLOAD), SIGNATURE_ES256_PS256, + sizeof(SIGNATURE_ES256_PS256), nullptr, verify_callback); + ASSERT_TRUE(result); +} + +TEST_F(psm_COSE, CoseTestingAlteredPayload) { + SECStatus rv = NSS_NoDB_Init(nullptr); + ASSERT_EQ(SECSuccess, rv); + uint8_t altered_payload[20] = {84, 104, 105, 115, 32, 104, 115, + 32, 116, 104, 101, 32, 99, 111, + 110, 116, 101, 110, 116, 46}; + bool result = verify_cose_signature_ffi( + altered_payload, sizeof(altered_payload), SIGNATURE_ES256_PS256, + sizeof(SIGNATURE_ES256_PS256), nullptr, verify_callback); + ASSERT_FALSE(result); +} + +} // namespace mozilla diff --git a/security/manager/ssl/tests/gtest/DataStorageTest.cpp b/security/manager/ssl/tests/gtest/DataStorageTest.cpp new file mode 100644 index 0000000000..791ef87f7d --- /dev/null +++ b/security/manager/ssl/tests/gtest/DataStorageTest.cpp @@ -0,0 +1,201 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "gtest/gtest.h" + +#include "mozilla/DataStorage.h" +#include "nsAppDirectoryServiceDefs.h" +#include "nsDirectoryServiceUtils.h" +#include "nsNetUtil.h" +#include "nsPrintfCString.h" +#include "nsStreamUtils.h" +#include "prtime.h" + +using namespace mozilla; + +class psm_DataStorageTest : public ::testing::Test { + protected: + void SetUp() override { + const ::testing::TestInfo* const testInfo = + ::testing::UnitTest::GetInstance()->current_test_info(); + NS_ConvertUTF8toUTF16 testName(testInfo->name()); + storage = DataStorage::GetFromRawFileName(testName); + storage->Init(nullptr); + } + + RefPtr storage; +}; + +constexpr auto testKey = "test"_ns; +constexpr auto testValue = "value"_ns; +constexpr auto privateTestValue = "private"_ns; + +TEST_F(psm_DataStorageTest, GetPutRemove) { + // Test Put/Get on Persistent data + EXPECT_EQ(NS_OK, storage->Put(testKey, testValue, DataStorage_Persistent)); + // Don't re-use testKey / testValue here, to make sure that this works as + // expected with objects that have the same semantic value but are not + // literally the same object. + nsCString result = storage->Get("test"_ns, DataStorage_Persistent); + EXPECT_STREQ("value", result.get()); + + // Get on Temporary/Private data with the same key should give nothing + result = storage->Get(testKey, DataStorage_Temporary); + EXPECT_TRUE(result.IsEmpty()); + result = storage->Get(testKey, DataStorage_Private); + EXPECT_TRUE(result.IsEmpty()); + + // Put with Temporary/Private data shouldn't affect Persistent data + constexpr auto temporaryTestValue = "temporary"_ns; + EXPECT_EQ(NS_OK, + storage->Put(testKey, temporaryTestValue, DataStorage_Temporary)); + EXPECT_EQ(NS_OK, + storage->Put(testKey, privateTestValue, DataStorage_Private)); + result = storage->Get(testKey, DataStorage_Temporary); + EXPECT_STREQ("temporary", result.get()); + result = storage->Get(testKey, DataStorage_Private); + EXPECT_STREQ("private", result.get()); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("value", result.get()); + + // Put of a previously-present key overwrites it (if of the same type) + constexpr auto newValue = "new"_ns; + EXPECT_EQ(NS_OK, storage->Put(testKey, newValue, DataStorage_Persistent)); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("new", result.get()); + + // Removal should work + storage->Remove(testKey, DataStorage_Temporary); + result = storage->Get(testKey, DataStorage_Temporary); + EXPECT_TRUE(result.IsEmpty()); + // But removing one type shouldn't affect the others + result = storage->Get(testKey, DataStorage_Private); + EXPECT_STREQ("private", result.get()); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("new", result.get()); + // Test removing the other types as well + storage->Remove(testKey, DataStorage_Private); + result = storage->Get(testKey, DataStorage_Private); + EXPECT_TRUE(result.IsEmpty()); + storage->Remove(testKey, DataStorage_Persistent); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_TRUE(result.IsEmpty()); +} + +TEST_F(psm_DataStorageTest, InputValidation) { + // Keys may not have tabs or newlines + EXPECT_EQ(NS_ERROR_INVALID_ARG, + storage->Put("key\thas tab"_ns, testValue, DataStorage_Persistent)); + nsCString result = storage->Get("key\thas tab"_ns, DataStorage_Persistent); + EXPECT_TRUE(result.IsEmpty()); + EXPECT_EQ(NS_ERROR_INVALID_ARG, storage->Put("key has\nnewline"_ns, testValue, + DataStorage_Persistent)); + result = storage->Get("keyhas\nnewline"_ns, DataStorage_Persistent); + EXPECT_TRUE(result.IsEmpty()); + // Values may not have newlines + EXPECT_EQ(NS_ERROR_INVALID_ARG, storage->Put(testKey, "value\nhas newline"_ns, + DataStorage_Persistent)); + result = storage->Get(testKey, DataStorage_Persistent); + // Values may have tabs + EXPECT_TRUE(result.IsEmpty()); + EXPECT_EQ(NS_OK, storage->Put(testKey, "val\thas tab; this is ok"_ns, + DataStorage_Persistent)); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("val\thas tab; this is ok", result.get()); + + nsCString longKey("a"); + for (int i = 0; i < 8; i++) { + longKey.Append(longKey); + } + // A key of length 256 will work + EXPECT_EQ(NS_OK, storage->Put(longKey, testValue, DataStorage_Persistent)); + result = storage->Get(longKey, DataStorage_Persistent); + EXPECT_STREQ("value", result.get()); + longKey.AppendLiteral("a"); + // A key longer than that will not work + EXPECT_EQ(NS_ERROR_INVALID_ARG, + storage->Put(longKey, testValue, DataStorage_Persistent)); + result = storage->Get(longKey, DataStorage_Persistent); + EXPECT_TRUE(result.IsEmpty()); + + nsCString longValue("a"); + for (int i = 0; i < 10; i++) { + longValue.Append(longValue); + } + // A value of length 1024 will work + EXPECT_EQ(NS_OK, storage->Put(testKey, longValue, DataStorage_Persistent)); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ(longValue.get(), result.get()); + longValue.AppendLiteral("a"); + // A value longer than that will not work + storage->Remove(testKey, DataStorage_Persistent); + EXPECT_EQ(NS_ERROR_INVALID_ARG, + storage->Put(testKey, longValue, DataStorage_Persistent)); + result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_TRUE(result.IsEmpty()); +} + +TEST_F(psm_DataStorageTest, Eviction) { + // Eviction is on a per-table basis. Tables shouldn't affect each other. + EXPECT_EQ(NS_OK, storage->Put(testKey, testValue, DataStorage_Persistent)); + for (int i = 0; i < 1025; i++) { + EXPECT_EQ(NS_OK, + storage->Put(nsPrintfCString("%d", i), nsPrintfCString("%d", i), + DataStorage_Temporary)); + nsCString result = + storage->Get(nsPrintfCString("%d", i), DataStorage_Temporary); + EXPECT_STREQ(nsPrintfCString("%d", i).get(), result.get()); + } + // We don't know which entry got evicted, but we can count them. + int entries = 0; + for (int i = 0; i < 1025; i++) { + nsCString result = + storage->Get(nsPrintfCString("%d", i), DataStorage_Temporary); + if (!result.IsEmpty()) { + entries++; + } + } + EXPECT_EQ(entries, 1024); + nsCString result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("value", result.get()); +} + +TEST_F(psm_DataStorageTest, ClearPrivateData) { + EXPECT_EQ(NS_OK, + storage->Put(testKey, privateTestValue, DataStorage_Private)); + nsCString result = storage->Get(testKey, DataStorage_Private); + EXPECT_STREQ("private", result.get()); + storage->Observe(nullptr, "last-pb-context-exited", nullptr); + result = storage->Get(testKey, DataStorage_Private); + EXPECT_TRUE(result.IsEmpty()); +} + +TEST_F(psm_DataStorageTest, Shutdown) { + EXPECT_EQ(NS_OK, storage->Put(testKey, testValue, DataStorage_Persistent)); + nsCString result = storage->Get(testKey, DataStorage_Persistent); + EXPECT_STREQ("value", result.get()); + // Get "now" (in days) close to when the data was last touched, so we won't + // get intermittent failures with the day not matching. + int64_t microsecondsPerDay = 24 * 60 * 60 * int64_t(PR_USEC_PER_SEC); + int32_t nowInDays = int32_t(PR_Now() / microsecondsPerDay); + // Simulate shutdown. + storage->Observe(nullptr, "profile-before-change", nullptr); + nsCOMPtr backingFile; + EXPECT_EQ(NS_OK, NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, + getter_AddRefs(backingFile))); + const ::testing::TestInfo* const testInfo = + ::testing::UnitTest::GetInstance()->current_test_info(); + NS_ConvertUTF8toUTF16 testName(testInfo->name()); + EXPECT_EQ(NS_OK, backingFile->Append(testName)); + nsCOMPtr fileInputStream; + EXPECT_EQ(NS_OK, NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), + backingFile)); + nsCString data; + EXPECT_EQ(NS_OK, NS_ConsumeStream(fileInputStream, UINT32_MAX, data)); + // The data will be of the form 'test\t0\t\tvalue' + EXPECT_STREQ(nsPrintfCString("test\t0\t%d\tvalue\n", nowInDays).get(), + data.get()); +} diff --git a/security/manager/ssl/tests/gtest/DeserializeCertTest.cpp b/security/manager/ssl/tests/gtest/DeserializeCertTest.cpp new file mode 100644 index 0000000000..005dc03ea6 --- /dev/null +++ b/security/manager/ssl/tests/gtest/DeserializeCertTest.cpp @@ -0,0 +1,247 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "gtest/gtest.h" +#include "nsCOMPtr.h" +#include "nsISimpleEnumerator.h" +#include "nsITransportSecurityInfo.h" +#include "nsIX509Cert.h" +#include "nsSerializationHelper.h" +#include "nsString.h" + +// nsITransportSecurityInfo de-serializatin tests +// +// These tests verify that we can still deserialize old binary strings +// generated for security info. This is necessary because service workers +// stores these strings on disk. +// +// If you make a change and start breaking these tests, you will need to +// add a compat fix for loading the old versions. For things that affect +// the UUID, but do not break the rest of the format you can simply add +// another hack condition in nsBinaryInputStream::ReadObject(). If you +// change the overall format of the serialization then we will need more +// complex handling in the security info concrete classes. +// +// We would like to move away from this binary compatibility requirement +// in service workers. See bug 1248628. +void deserializeAndVerify(const nsCString& serializedSecInfo, + bool hasFailedCertChain, + size_t failedCertChainLength = 0) { + nsCOMPtr secInfo; + nsresult rv = + NS_DeserializeObject(serializedSecInfo, getter_AddRefs(secInfo)); + ASSERT_EQ(NS_OK, rv); + ASSERT_TRUE(secInfo); + + nsCOMPtr securityInfo = do_QueryInterface(secInfo); + ASSERT_TRUE(securityInfo); + + nsCOMPtr cert; + rv = securityInfo->GetServerCert(getter_AddRefs(cert)); + ASSERT_EQ(NS_OK, rv); + ASSERT_TRUE(cert); + + nsTArray> failedCertArray; + rv = securityInfo->GetFailedCertChain(failedCertArray); + ASSERT_EQ(NS_OK, rv); + + if (hasFailedCertChain) { + ASSERT_FALSE(failedCertArray.IsEmpty()); + for (const auto& cert : failedCertArray) { + ASSERT_TRUE(cert); + } + ASSERT_EQ(failedCertChainLength, failedCertArray.Length()); + } else { + ASSERT_TRUE(failedCertArray.IsEmpty()); + } +} + +TEST(psm_DeserializeCert, gecko33) +{ + // clang-format off + // Gecko 33+ vintage Security info serialized with UUIDs: + // - nsISupports 00000000-0000-0000-c000-000000000046 + // - nsISSLStatus fa9ba95b-ca3b-498a-b889-7c79cf28fee8 + // - nsIX509Cert f8ed8364-ced9-4c6e-86ba-48af53c393e6 + nsCString base64Serialization( + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAQAAgAAAAAAAAAAAAAAAAAAAAA" + "B4vFIJp5wRkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8F+O2DZM7ZTG6GukivU8OT5gAAAAIAAAWpMII" + "FpTCCBI2gAwIBAgIQD4svsaKEC+QtqtsU2TF8ITANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUN" + "lcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFN" + "lcnZlciBDQTAeFw0xNTAyMjMwMDAwMDBaFw0xNjAzMDIxMjAwMDBaMGoxCzAJBgNVBAYTAlVTMRYwFAYDVQQHEw1TYW4gRnJhbmN" + "pc2NvMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRUwEwYDVQQKEwxGYXN0bHksIEluYy4xFzAVBgNVBAMTDnd3dy5naXRodWIuY29tMII" + "BIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+9WUCgrgUNwP/JC3cUefLAXeDpq8Ko/U8p8IRvny0Ri0I6Uq0t+RP/nF0LJ" + "Avda8QHYujdgeDTePepBX7+OiwBFhA0YO+rM3C2Z8IRaN/i9eLln+Yyc68+1z+E10s1EXdZrtDGvN6MHqygGsdfkXKfBLUJ1BZEh" + "s9sBnfcjq3kh5gZdBArdG9l5NpdmQhtceaFGsPiWuJxGxRzS4i95veUHWkhMpEYDEEBdcDGxqArvQCvzSlngdttQCfx8OUkBTb3B" + "A2okpTwwJfqPsxVetA6qR7UNc+fVb6KHwvm0bzi2rQ3xw3D/syRHwdMkpoVDQPCk43H9WufgfBKRen87dFwIDAQABo4ICPzCCAjs" + "wHwYDVR0jBBgwFoAUUWj/kK8CB3U8zNllZGKiErhZcjswHQYDVR0OBBYEFGS/RLNGCZvPWh1xSaIEcouINIQjMHsGA1UdEQR0MHK" + "CDnd3dy5naXRodWIuY29tggpnaXRodWIuY29tggwqLmdpdGh1Yi5jb22CCyouZ2l0aHViLmlvgglnaXRodWIuaW+CFyouZ2l0aHV" + "idXNlcmNvbnRlbnQuY29tghVnaXRodWJ1c2VyY29udGVudC5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwM" + "BBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzMuY3J" + "sMDSgMqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzMuY3JsMEIGA1UdIAQ7MDkwNwYJYIZIAYb" + "9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwgYMGCCsGAQUFBwEBBHcwdTAkBggrBgEFBQc" + "wAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME0GCCsGAQUFBzAChkFodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUN" + "lcnRTSEEySGlnaEFzc3VyYW5jZVNlcnZlckNBLmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAc4dbVmuKvyI7" + "KZ4Txk+ZqcAYToJGKUIVaPL94e5SZGweUisjaCbplAOihnf6Mxt8n6vnuH2IsCaz2NRHqhdcosjT3CwAiJpJNkXPKWVL/txgdSTV" + "2cqB1GG4esFOalvI52dzn+J4fTIYZvNF+AtGyHSLm2XRXYZCw455laUKf6Sk9RDShDgUvzhOKL4GXfTwKXv12MyMknJybH8UCpjC" + "HZmFBVHMcUN/87HsQo20PdOekeEvkjrrMIxW+gxw22Yb67yF/qKgwrWr+43bLN709iyw+LWiU7sQcHL2xk9SYiWQDj2tYz2soObV" + "QYTJm0VUZMEVFhtALq46cx92Zu4vFwC8AAwAAAAABAQAA"); + // clang-format on + + deserializeAndVerify(base64Serialization, false); +} + +TEST(psm_DeserializeCert, gecko46) +{ + // clang-format off + // Gecko 46+ vintage Security info serialized with UUIDs: + // - nsISupports 00000000-0000-0000-c000-000000000046 + // - nsISSLStatus fa9ba95b-ca3b-498a-b889-7c79cf28fee8 + // - nsIX509Cert bdc3979a-5422-4cd5-8589-696b6e96ea83 + nsCString base64Serialization( + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAQAAgAAAAAAAAAAAAAAAAAAAAA" + "B4vFIJp5wRkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAAIAAAWzMII" + "FrzCCBJegAwIBAgIQB3pdwzYjAfmJ/lT3+G8+ZDANBgkqhkiG9w0BAQsFADBwMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUN" + "lcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMS8wLQYDVQQDEyZEaWdpQ2VydCBTSEEyIEhpZ2ggQXNzdXJhbmNlIFN" + "lcnZlciBDQTAeFw0xNjAxMjAwMDAwMDBaFw0xNzA0MDYxMjAwMDBaMGoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybml" + "hMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRUwEwYDVQQKEwxGYXN0bHksIEluYy4xFzAVBgNVBAMTDnd3dy5naXRodWIuY29tMII" + "BIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+9WUCgrgUNwP/JC3cUefLAXeDpq8Ko/U8p8IRvny0Ri0I6Uq0t+RP/nF0LJ" + "Avda8QHYujdgeDTePepBX7+OiwBFhA0YO+rM3C2Z8IRaN/i9eLln+Yyc68+1z+E10s1EXdZrtDGvN6MHqygGsdfkXKfBLUJ1BZEh" + "s9sBnfcjq3kh5gZdBArdG9l5NpdmQhtceaFGsPiWuJxGxRzS4i95veUHWkhMpEYDEEBdcDGxqArvQCvzSlngdttQCfx8OUkBTb3B" + "A2okpTwwJfqPsxVetA6qR7UNc+fVb6KHwvm0bzi2rQ3xw3D/syRHwdMkpoVDQPCk43H9WufgfBKRen87dFwIDAQABo4ICSTCCAkU" + "wHwYDVR0jBBgwFoAUUWj/kK8CB3U8zNllZGKiErhZcjswHQYDVR0OBBYEFGS/RLNGCZvPWh1xSaIEcouINIQjMHsGA1UdEQR0MHK" + "CDnd3dy5naXRodWIuY29tggwqLmdpdGh1Yi5jb22CCmdpdGh1Yi5jb22CCyouZ2l0aHViLmlvgglnaXRodWIuaW+CFyouZ2l0aHV" + "idXNlcmNvbnRlbnQuY29tghVnaXRodWJ1c2VyY29udGVudC5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwM" + "BBggrBgEFBQcDAjB1BgNVHR8EbjBsMDSgMqAwhi5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzUuY3J" + "sMDSgMqAwhi5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1oYS1zZXJ2ZXItZzUuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb" + "9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMIGDBggrBgEFBQcBAQR3MHU" + "wJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBNBggrBgEFBQcwAoZBaHR0cDovL2NhY2VydHMuZGlnaWNlcnQ" + "uY29tL0RpZ2lDZXJ0U0hBMkhpZ2hBc3N1cmFuY2VTZXJ2ZXJDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQE" + "ATxbRdPg+o49+96/P+rbdp4ie+CGtfCgUubT/Z9C54k+BfQO0nbxVgCSM5WZQuLgo2Q+0lcxisod8zxZeU0j5wviQINwOln/iN89" + "Bx3VmDRynTe4CqhsAwOoO1ERmCAmsAJBwY/rNr4mK22p8erBrqMW0nYXYU5NFynI+pNTjojhKD4II8PNV8G2yMWwYOb/u4+WPzUA" + "HC9DpZdrWTEH/W69Cr/KxRqGsWPwpgMv2Wqav8jaT35JxqTXjOlhQqzo6fNn3eYOeCf4PkCxZKwckWjy10qDaRbjhwAMHAGj2TPr" + "idlvOj/7QyyX5m8up/1US8z1fRW4yoCSOt6V2bwuH6cAvAAMAAAAAAQEAAA=="); + // clang-format on + + deserializeAndVerify(base64Serialization, false); +} + +TEST(psm_DeserializeCert, preSSLStatusConsolidation) +{ + // clang-format off + // Generated using serialized output of test "good.include-subdomains.pinning.example.com" + // in security/manager/ssl/tests/unit/test_cert_chains.js + nsCString base64Serialization( + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAgAAgAAAAAAAAAAAAAAAAAAAAAB4vFIJp5w" + "RkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAAAAAAONMIIDiTCCAnGg" + "AwIBAgIUWbWLTwLBvfwcoiU7I8lDz9snfUgwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE2MTEyNzAw" + "MDAwMFoYDzIwMTkwMjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw" + "ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV" + "JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o" + "N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd" + "q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcowgccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0" + "gg0qLmV4YW1wbGUuY29tghUqLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs" + "ZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAB" + "hhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQBE+6IPJK5OeonoQPC4CCWMd69SjhwS7X6TNgxDJzW7" + "qpVm4SFyYZ2xqzr2zib5LsYek6/jok5LPSpJVeFuSeiesvGMxk0O4ZEihPxSM4uR4xpCnPzz7LoFIzMELJv5i+cgLw4+6cINPkLj" + "oCUdb+AXSTur7THJaO75B44I2JjJfMfzgW1FwoWgXL/PQWRw+VY6OY1glqZOXzP+vfSja1SoggpiCzdPx7h1/SEEZov7zhCZXv1C" + "enx1njlpcj9wWEJMsyZczMNtiz5GkRrLaqCz9F8ah3NvkvPAZ0oOqtxuQgMXK/c0OXJVKi0SCJsWqZDoZhCrS/dE9guxlseZqhSI" + "wC8DAwAAAAABAQAAAAAAAAZ4MjU1MTkAAAAOUlNBLVBTUy1TSEEyNTYBlZ+xZWUXSH+rm9iRO+Uxl650zaXNL0c/lvXwt//2LGgA" + "AAACZgoyJpFcT/u7IImFpjLfBb3Dl5pUIkzVhYlpa26W6oMAAAAAAAADjTCCA4kwggJxoAMCAQICFFm1i08Cwb38HKIlOyPJQ8/b" + "J31IMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNjExMjcwMDAwMDBaGA8yMDE5MDIwNTAwMDAwMFow" + "GjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2" + "ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC" + "a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk" + "zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+" + "SSP6clHEMdUDrNoYCjXtjQIDAQABo4HKMIHHMIGQBgNVHREEgYgwgYWCCWxvY2FsaG9zdIINKi5leGFtcGxlLmNvbYIVKi5waW5u" + "aW5nLmV4YW1wbGUuY29tgigqLmluY2x1ZGUtc3ViZG9tYWlucy5waW5uaW5nLmV4YW1wbGUuY29tgigqLmV4Y2x1ZGUtc3ViZG9t" + "YWlucy5waW5uaW5nLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4" + "LzANBgkqhkiG9w0BAQsFAAOCAQEARPuiDySuTnqJ6EDwuAgljHevUo4cEu1+kzYMQyc1u6qVZuEhcmGdsas69s4m+S7GHpOv46JO" + "Sz0qSVXhbknonrLxjMZNDuGRIoT8UjOLkeMaQpz88+y6BSMzBCyb+YvnIC8OPunCDT5C46AlHW/gF0k7q+0xyWju+QeOCNiYyXzH" + "84FtRcKFoFy/z0FkcPlWOjmNYJamTl8z/r30o2tUqIIKYgs3T8e4df0hBGaL+84QmV79Qnp8dZ45aXI/cFhCTLMmXMzDbYs+RpEa" + "y2qgs/RfGodzb5LzwGdKDqrcbkIDFyv3NDlyVSotEgibFqmQ6GYQq0v3RPYLsZbHmaoUiGYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM" + "1YWJaWtuluqDAAAAAAAAAtcwggLTMIIBu6ADAgECAhRdBTvvC7swO3cbVWIGn/56DrQ+cjANBgkqhkiG9w0BAQsFADASMRAwDgYD" + "VQQDDAdUZXN0IENBMCIYDzIwMTYxMTI3MDAwMDAwWhgPMjAxOTAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0G" + "CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr" + "4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk" + "fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo" + "4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQF" + "MAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCDjewR53YLc3HzZKugRDbQVxjJNILW6fSIyW9dSglYcWh6aiOK" + "9cZFVtzRWYEYkIlicAyTiPw34bXzxU1cK6sCSmBR+UTXbRPGb4OOy3MRaoF1m3jxwnPkQwxezDiqJTydCbYcBu0sKwURAZOd5QK9" + "22MsOsnrLjNlpRDmuH0VFhb5uN2I5mM3NvMnP2Or19O1Bk//iGD6AyJfiZFcii+FsDrJhbzw6lakEV7O/EnD0kk2l7I0VMtg1xZB" + "bEw7P6+V9zz5cAzaaq7EB0mCE+jJckSzSETBN+7lyVD8gwmHYxxZfPnUM/yvPbMU9L3xWD/z6HHwO6r+9m7BT+2pHjBCAAA="); + // clang-format on + + deserializeAndVerify(base64Serialization, false); +} + +TEST(psm_DeserializeCert, preSSLStatusConsolidationFailedCertChain) +{ + // clang-format off + // Generated using serialized output of test "expired.example.com" + // in security/manager/ssl/tests/unit/test_cert_chains.js + nsCString base64Serialization( + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAABAAAAAAAAAAA///gCwAAAAAB4vFIJp5w" + "RkeyPxAQ9RJGKPqbqVvKO0mKuIl8ec8o/uhmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAAAAAAMgMIIDHDCCAgSg" + "AwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAw" + "MDAwMFoYDzIwMTQwMTAxMDAwMDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvcNAQEB" + "BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6" + "pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9" + "0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK" + "lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJl" + "ZC5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcN" + "AQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzfT+ow5WVsxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7" + "IAMO1CEr5FVdCOVTma5hmu/81rkJLmZ8RQDWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3L9zJ2JqNc60+hB8l" + "297ZaSl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74VkQyNobaFzDZ+Zr3QmfbejEsY2EYnq8XuENgIO4DuYrm80/p6bMO6" + "laB0Uv5W6uXZgBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFwWwtnoK7IAAAMAAAEAAAEAAQAAAAAAAAAAAAAAAZWfsWVlF0h/q5vY" + "kTvlMZeudM2lzS9HP5b18Lf/9ixoAAAAAmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAyAwggMcMIICBKAD" + "AgECAhRj0REAgqPSOz9huEmgytwueP766jANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIwMTMwMTAxMDAw" + "MDAwWhgPMjAxNDAxMDEwMDAwMDBaMCIxIDAeBgNVBAMMF0V4cGlyZWQgVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEF" + "AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql" + "WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S" + "O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV" + "YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1YwVDAeBgNVHREEFzAVghNleHBpcmVk" + "LmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0B" + "AQsFAAOCAQEAiaIW7LbvlPpv5R3qCX8SXqqmBYdRd5iK/aynt34dXN9P6jDlZWzEj8YwqF0DjclopP2B8yxuc/WqIjbN6XdT4Xsg" + "Aw7UISvkVV0I5VOZrmGa7/zWuQkuZnxFANZY6FkrKf/toPtMfULV7vrzIK3kTYMOXyYeKX3NHwE+yhfC5Lcv3MnYmo1zrT6EHyXb" + "3tlpKXSdsp99vju6S+fmRInu0j2f99Jd2PUmu6TCNk/7vhWRDI2htoXMNn5mvdCZ9t6MSxjYRierxe4Q2Ag7gO5iubzT+npsw7qV" + "oHRS/lbq5dmAFl1FN7VYx1hYaGa+cUVCZ/6dp446XqvIXBbC2egrsmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAA" + "AAAAAtcwggLTMIIBu6ADAgECAhRdBTvvC7swO3cbVWIGn/56DrQ+cjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENB" + "MCIYDzIwMTYxMTI3MDAwMDAwWhgPMjAxOTAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUA" + "A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa" + "p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7" + "xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh" + "He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0P" + "BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCDjewR53YLc3HzZKugRDbQVxjJNILW6fSIyW9dSglYcWh6aiOK9cZFVtzRWYEYkIli" + "cAyTiPw34bXzxU1cK6sCSmBR+UTXbRPGb4OOy3MRaoF1m3jxwnPkQwxezDiqJTydCbYcBu0sKwURAZOd5QK922MsOsnrLjNlpRDm" + "uH0VFhb5uN2I5mM3NvMnP2Or19O1Bk//iGD6AyJfiZFcii+FsDrJhbzw6lakEV7O/EnD0kk2l7I0VMtg1xZBbEw7P6+V9zz5cAza" + "aq7EB0mCE+jJckSzSETBN+7lyVD8gwmHYxxZfPnUM/yvPbMU9L3xWD/z6HHwO6r+9m7BT+2pHjBCAZWfsWVlF0h/q5vYkTvlMZeu" + "dM2lzS9HP5b18Lf/9ixoAAAAAmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAyAwggMcMIICBKADAgECAhRj" + "0REAgqPSOz9huEmgytwueP766jANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIwMTMwMTAxMDAwMDAwWhgP" + "MjAxNDAxMDEwMDAwMDBaMCIxIDAeBgNVBAMMF0V4cGlyZWQgVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A" + "MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc" + "1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf" + "qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYl" + "nauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1YwVDAeBgNVHREEFzAVghNleHBpcmVkLmV4YW1w" + "bGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOC" + "AQEAiaIW7LbvlPpv5R3qCX8SXqqmBYdRd5iK/aynt34dXN9P6jDlZWzEj8YwqF0DjclopP2B8yxuc/WqIjbN6XdT4XsgAw7UISvk" + "VV0I5VOZrmGa7/zWuQkuZnxFANZY6FkrKf/toPtMfULV7vrzIK3kTYMOXyYeKX3NHwE+yhfC5Lcv3MnYmo1zrT6EHyXb3tlpKXSd" + "sp99vju6S+fmRInu0j2f99Jd2PUmu6TCNk/7vhWRDI2htoXMNn5mvdCZ9t6MSxjYRierxe4Q2Ag7gO5iubzT+npsw7qVoHRS/lbq" + "5dmAFl1FN7VYx1hYaGa+cUVCZ/6dp446XqvIXBbC2egrsmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAtcw" + "ggLTMIIBu6ADAgECAhRdBTvvC7swO3cbVWIGn/56DrQ+cjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIw" + "MTYxMTI3MDAwMDAwWhgPMjAxOTAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw" + "ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV" + "JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o" + "N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd" + "q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEG" + "MA0GCSqGSIb3DQEBCwUAA4IBAQCDjewR53YLc3HzZKugRDbQVxjJNILW6fSIyW9dSglYcWh6aiOK9cZFVtzRWYEYkIlicAyTiPw3" + "4bXzxU1cK6sCSmBR+UTXbRPGb4OOy3MRaoF1m3jxwnPkQwxezDiqJTydCbYcBu0sKwURAZOd5QK922MsOsnrLjNlpRDmuH0VFhb5" + "uN2I5mM3NvMnP2Or19O1Bk//iGD6AyJfiZFcii+FsDrJhbzw6lakEV7O/EnD0kk2l7I0VMtg1xZBbEw7P6+V9zz5cAzaaq7EB0mC" + "E+jJckSzSETBN+7lyVD8gwmHYxxZfPnUM/yvPbMU9L3xWD/z6HHwO6r+9m7BT+2pHjBC"); + // clang-format on + + deserializeAndVerify(base64Serialization, true, 2); +} diff --git a/security/manager/ssl/tests/gtest/MD4Test.cpp b/security/manager/ssl/tests/gtest/MD4Test.cpp new file mode 100644 index 0000000000..6e28e6dbc4 --- /dev/null +++ b/security/manager/ssl/tests/gtest/MD4Test.cpp @@ -0,0 +1,62 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +// This file tests the md4.c implementation. + +#include "gtest/gtest.h" +#include "md4.h" +#include "mozilla/ArrayUtils.h" +#include "mozilla/Casting.h" + +struct RFC1320TestParams { + const char* data; + const uint8_t expectedHash[16]; +}; + +static const RFC1320TestParams RFC1320_TEST_PARAMS[] = { + {"", + {0x31, 0xd6, 0xcf, 0xe0, 0xd1, 0x6a, 0xe9, 0x31, 0xb7, 0x3c, 0x59, 0xd7, + 0xe0, 0xc0, 0x89, 0xc0}}, + {"a", + {0xbd, 0xe5, 0x2c, 0xb3, 0x1d, 0xe3, 0x3e, 0x46, 0x24, 0x5e, 0x05, 0xfb, + 0xdb, 0xd6, 0xfb, 0x24}}, + {"abc", + {0xa4, 0x48, 0x01, 0x7a, 0xaf, 0x21, 0xd8, 0x52, 0x5f, 0xc1, 0x0a, 0xe8, + 0x7a, 0xa6, 0x72, 0x9d}}, + {"message digest", + {0xd9, 0x13, 0x0a, 0x81, 0x64, 0x54, 0x9f, 0xe8, 0x18, 0x87, 0x48, 0x06, + 0xe1, 0xc7, 0x01, 0x4b}}, + { + "abcdefghijklmnopqrstuvwxyz", + {0xd7, 0x9e, 0x1c, 0x30, 0x8a, 0xa5, 0xbb, 0xcd, 0xee, 0xa8, 0xed, 0x63, + 0xdf, 0x41, 0x2d, 0xa9}, + }, + { + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + {0x04, 0x3f, 0x85, 0x82, 0xf2, 0x41, 0xdb, 0x35, 0x1c, 0xe6, 0x27, 0xe1, + 0x53, 0xe7, 0xf0, 0xe4}, + }, + { + "1234567890123456789012345678901234567890123456789012345678901234567890" + "1234567890", + {0xe3, 0x3b, 0x4d, 0xdc, 0x9c, 0x38, 0xf2, 0x19, 0x9c, 0x3e, 0x7b, 0x16, + 0x4f, 0xcc, 0x05, 0x36}, + }}; + +class psm_MD4 : public ::testing::Test, + public ::testing::WithParamInterface {}; + +TEST_P(psm_MD4, RFC1320TestValues) { + const RFC1320TestParams& params(GetParam()); + uint8_t actualHash[16]; + md4sum(mozilla::BitwiseCast(params.data), + strlen(params.data), actualHash); + EXPECT_TRUE(mozilla::ArrayEqual(actualHash, params.expectedHash)) + << "MD4 hashes aren't equal for input: '" << params.data << "'"; +} + +INSTANTIATE_TEST_CASE_P(psm_MD4, psm_MD4, + testing::ValuesIn(RFC1320_TEST_PARAMS)); diff --git a/security/manager/ssl/tests/gtest/OCSPCacheTest.cpp b/security/manager/ssl/tests/gtest/OCSPCacheTest.cpp new file mode 100644 index 0000000000..77e9368ff6 --- /dev/null +++ b/security/manager/ssl/tests/gtest/OCSPCacheTest.cpp @@ -0,0 +1,321 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "CertVerifier.h" +#include "OCSPCache.h" +#include "gtest/gtest.h" +#include "mozilla/BasePrincipal.h" +#include "mozilla/Casting.h" +#include "mozilla/Sprintf.h" +#include "nss.h" +#include "mozpkix/pkixtypes.h" +#include "mozpkix/test/pkixtestutil.h" +#include "prerr.h" +#include "secerr.h" + +using namespace mozilla::pkix; +using namespace mozilla::pkix::test; + +using mozilla::OriginAttributes; + +template +inline Input LiteralInput(const char (&valueString)[N]) { + // Ideally we would use mozilla::BitwiseCast() here rather than + // reinterpret_cast for better type checking, but the |N - 1| part trips + // static asserts. + return Input(reinterpret_cast(valueString)); +} + +const int MaxCacheEntries = 1024; + +class psm_OCSPCacheTest : public ::testing::Test { + protected: + psm_OCSPCacheTest() : now(Now()) {} + + static void SetUpTestCase() { NSS_NoDB_Init(nullptr); } + + const Time now; + mozilla::psm::OCSPCache cache; +}; + +static void PutAndGet( + mozilla::psm::OCSPCache& cache, const CertID& certID, Result result, + Time time, const OriginAttributes& originAttributes = OriginAttributes()) { + // The first time is thisUpdate. The second is validUntil. + // The caller is expecting the validUntil returned with Get + // to be equal to the passed-in time. Since these values will + // be different in practice, make thisUpdate less than validUntil. + Time thisUpdate(time); + ASSERT_EQ(Success, thisUpdate.SubtractSeconds(10)); + Result rv = cache.Put(certID, originAttributes, result, thisUpdate, time); + ASSERT_TRUE(rv == Success); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_TRUE(cache.Get(certID, originAttributes, resultOut, timeOut)); + ASSERT_EQ(result, resultOut); + ASSERT_EQ(time, timeOut); +} + +Input fakeIssuer1(LiteralInput("CN=issuer1")); +Input fakeKey000(LiteralInput("key000")); +Input fakeKey001(LiteralInput("key001")); +Input fakeSerial0000(LiteralInput("0000")); + +TEST_F(psm_OCSPCacheTest, TestPutAndGet) { + Input fakeSerial000(LiteralInput("000")); + Input fakeSerial001(LiteralInput("001")); + + SCOPED_TRACE(""); + PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial001), Success, + now); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial000), + OriginAttributes(), resultOut, timeOut)); +} + +TEST_F(psm_OCSPCacheTest, TestVariousGets) { + SCOPED_TRACE(""); + for (int i = 0; i < MaxCacheEntries; i++) { + uint8_t serialBuf[8]; + snprintf(mozilla::BitwiseCast(serialBuf), + sizeof(serialBuf), "%04d", i); + Input fakeSerial; + ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4)); + Time timeIn(now); + ASSERT_EQ(Success, timeIn.AddSeconds(i)); + PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial), Success, + timeIn); + } + + Time timeIn(now); + Result resultOut; + Time timeOut(Time::uninitialized); + + // This will be at the end of the list in the cache + CertID cert0000(fakeIssuer1, fakeKey000, fakeSerial0000); + ASSERT_TRUE(cache.Get(cert0000, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(timeIn, timeOut); + // Once we access it, it goes to the front + ASSERT_TRUE(cache.Get(cert0000, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(timeIn, timeOut); + + // This will be in the middle + Time timeInPlus512(now); + ASSERT_EQ(Success, timeInPlus512.AddSeconds(512)); + + static const Input fakeSerial0512(LiteralInput("0512")); + CertID cert0512(fakeIssuer1, fakeKey000, fakeSerial0512); + ASSERT_TRUE(cache.Get(cert0512, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(timeInPlus512, timeOut); + ASSERT_TRUE(cache.Get(cert0512, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(timeInPlus512, timeOut); + + // We've never seen this certificate + static const Input fakeSerial1111(LiteralInput("1111")); + ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey000, fakeSerial1111), + OriginAttributes(), resultOut, timeOut)); +} + +TEST_F(psm_OCSPCacheTest, TestEviction) { + SCOPED_TRACE(""); + // By putting more distinct entries in the cache than it can hold, + // we cause the least recently used entry to be evicted. + for (int i = 0; i < MaxCacheEntries + 1; i++) { + uint8_t serialBuf[8]; + snprintf(mozilla::BitwiseCast(serialBuf), + sizeof(serialBuf), "%04d", i); + Input fakeSerial; + ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4)); + Time timeIn(now); + ASSERT_EQ(Success, timeIn.AddSeconds(i)); + PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial), Success, + timeIn); + } + + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial0000), + OriginAttributes(), resultOut, timeOut)); +} + +TEST_F(psm_OCSPCacheTest, TestNoEvictionForRevokedResponses) { + SCOPED_TRACE(""); + CertID notEvicted(fakeIssuer1, fakeKey000, fakeSerial0000); + Time timeIn(now); + PutAndGet(cache, notEvicted, Result::ERROR_REVOKED_CERTIFICATE, timeIn); + // By putting more distinct entries in the cache than it can hold, + // we cause the least recently used entry that isn't revoked to be evicted. + for (int i = 1; i < MaxCacheEntries + 1; i++) { + uint8_t serialBuf[8]; + snprintf(mozilla::BitwiseCast(serialBuf), + sizeof(serialBuf), "%04d", i); + Input fakeSerial; + ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4)); + Time timeIn(now); + ASSERT_EQ(Success, timeIn.AddSeconds(i)); + PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial), Success, + timeIn); + } + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_TRUE(cache.Get(notEvicted, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, resultOut); + ASSERT_EQ(timeIn, timeOut); + + Input fakeSerial0001(LiteralInput("0001")); + CertID evicted(fakeIssuer1, fakeKey000, fakeSerial0001); + ASSERT_FALSE(cache.Get(evicted, OriginAttributes(), resultOut, timeOut)); +} + +TEST_F(psm_OCSPCacheTest, TestEverythingIsRevoked) { + SCOPED_TRACE(""); + Time timeIn(now); + // Fill up the cache with revoked responses. + for (int i = 0; i < MaxCacheEntries; i++) { + uint8_t serialBuf[8]; + snprintf(mozilla::BitwiseCast(serialBuf), + sizeof(serialBuf), "%04d", i); + Input fakeSerial; + ASSERT_EQ(Success, fakeSerial.Init(serialBuf, 4)); + Time timeIn(now); + ASSERT_EQ(Success, timeIn.AddSeconds(i)); + PutAndGet(cache, CertID(fakeIssuer1, fakeKey000, fakeSerial), + Result::ERROR_REVOKED_CERTIFICATE, timeIn); + } + static const Input fakeSerial1025(LiteralInput("1025")); + CertID good(fakeIssuer1, fakeKey000, fakeSerial1025); + // This will "succeed", allowing verification to continue. However, + // nothing was actually put in the cache. + Time timeInPlus1025(timeIn); + ASSERT_EQ(Success, timeInPlus1025.AddSeconds(1025)); + Time timeInPlus1025Minus50(timeInPlus1025); + ASSERT_EQ(Success, timeInPlus1025Minus50.SubtractSeconds(50)); + Result result = cache.Put(good, OriginAttributes(), Success, + timeInPlus1025Minus50, timeInPlus1025); + ASSERT_EQ(Success, result); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_FALSE(cache.Get(good, OriginAttributes(), resultOut, timeOut)); + + static const Input fakeSerial1026(LiteralInput("1026")); + CertID revoked(fakeIssuer1, fakeKey000, fakeSerial1026); + // This will fail, causing verification to fail. + Time timeInPlus1026(timeIn); + ASSERT_EQ(Success, timeInPlus1026.AddSeconds(1026)); + Time timeInPlus1026Minus50(timeInPlus1026); + ASSERT_EQ(Success, timeInPlus1026Minus50.SubtractSeconds(50)); + result = + cache.Put(revoked, OriginAttributes(), Result::ERROR_REVOKED_CERTIFICATE, + timeInPlus1026Minus50, timeInPlus1026); + ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, result); +} + +TEST_F(psm_OCSPCacheTest, VariousIssuers) { + SCOPED_TRACE(""); + Time timeIn(now); + static const Input fakeIssuer2(LiteralInput("CN=issuer2")); + static const Input fakeSerial001(LiteralInput("001")); + CertID subject(fakeIssuer1, fakeKey000, fakeSerial001); + PutAndGet(cache, subject, Success, now); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_TRUE(cache.Get(subject, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(timeIn, timeOut); + // Test that we don't match a different issuer DN + ASSERT_FALSE(cache.Get(CertID(fakeIssuer2, fakeKey000, fakeSerial001), + OriginAttributes(), resultOut, timeOut)); + // Test that we don't match a different issuer key + ASSERT_FALSE(cache.Get(CertID(fakeIssuer1, fakeKey001, fakeSerial001), + OriginAttributes(), resultOut, timeOut)); +} + +TEST_F(psm_OCSPCacheTest, Times) { + SCOPED_TRACE(""); + CertID certID(fakeIssuer1, fakeKey000, fakeSerial0000); + PutAndGet(cache, certID, Result::ERROR_OCSP_UNKNOWN_CERT, + TimeFromElapsedSecondsAD(100)); + PutAndGet(cache, certID, Success, TimeFromElapsedSecondsAD(200)); + // This should not override the more recent entry. + ASSERT_EQ( + Success, + cache.Put(certID, OriginAttributes(), Result::ERROR_OCSP_UNKNOWN_CERT, + TimeFromElapsedSecondsAD(100), TimeFromElapsedSecondsAD(100))); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_TRUE(cache.Get(certID, OriginAttributes(), resultOut, timeOut)); + // Here we see the more recent time. + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(TimeFromElapsedSecondsAD(200), timeOut); + + // Result::ERROR_REVOKED_CERTIFICATE overrides everything + PutAndGet(cache, certID, Result::ERROR_REVOKED_CERTIFICATE, + TimeFromElapsedSecondsAD(50)); +} + +TEST_F(psm_OCSPCacheTest, NetworkFailure) { + SCOPED_TRACE(""); + CertID certID(fakeIssuer1, fakeKey000, fakeSerial0000); + PutAndGet(cache, certID, Result::ERROR_CONNECT_REFUSED, + TimeFromElapsedSecondsAD(100)); + PutAndGet(cache, certID, Success, TimeFromElapsedSecondsAD(200)); + // This should not override the already present entry. + ASSERT_EQ( + Success, + cache.Put(certID, OriginAttributes(), Result::ERROR_CONNECT_REFUSED, + TimeFromElapsedSecondsAD(300), TimeFromElapsedSecondsAD(350))); + Result resultOut; + Time timeOut(Time::uninitialized); + ASSERT_TRUE(cache.Get(certID, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Success, resultOut); + ASSERT_EQ(TimeFromElapsedSecondsAD(200), timeOut); + + PutAndGet(cache, certID, Result::ERROR_OCSP_UNKNOWN_CERT, + TimeFromElapsedSecondsAD(400)); + // This should not override the already present entry. + ASSERT_EQ( + Success, + cache.Put(certID, OriginAttributes(), Result::ERROR_CONNECT_REFUSED, + TimeFromElapsedSecondsAD(500), TimeFromElapsedSecondsAD(550))); + ASSERT_TRUE(cache.Get(certID, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Result::ERROR_OCSP_UNKNOWN_CERT, resultOut); + ASSERT_EQ(TimeFromElapsedSecondsAD(400), timeOut); + + PutAndGet(cache, certID, Result::ERROR_REVOKED_CERTIFICATE, + TimeFromElapsedSecondsAD(600)); + // This should not override the already present entry. + ASSERT_EQ( + Success, + cache.Put(certID, OriginAttributes(), Result::ERROR_CONNECT_REFUSED, + TimeFromElapsedSecondsAD(700), TimeFromElapsedSecondsAD(750))); + ASSERT_TRUE(cache.Get(certID, OriginAttributes(), resultOut, timeOut)); + ASSERT_EQ(Result::ERROR_REVOKED_CERTIFICATE, resultOut); + ASSERT_EQ(TimeFromElapsedSecondsAD(600), timeOut); +} + +TEST_F(psm_OCSPCacheTest, TestOriginAttributes) { + CertID certID(fakeIssuer1, fakeKey000, fakeSerial0000); + + SCOPED_TRACE(""); + OriginAttributes attrs; + attrs.mFirstPartyDomain.AssignLiteral("foo.com"); + PutAndGet(cache, certID, Success, now, attrs); + + Result resultOut; + Time timeOut(Time::uninitialized); + attrs.mFirstPartyDomain.AssignLiteral("bar.com"); + ASSERT_FALSE(cache.Get(certID, attrs, resultOut, timeOut)); + + // OCSP cache should not be isolated by containers. + attrs.mUserContextId = 1; + attrs.mFirstPartyDomain.AssignLiteral("foo.com"); + ASSERT_TRUE(cache.Get(certID, attrs, resultOut, timeOut)); +} diff --git a/security/manager/ssl/tests/gtest/README.txt b/security/manager/ssl/tests/gtest/README.txt new file mode 100644 index 0000000000..0e51322690 --- /dev/null +++ b/security/manager/ssl/tests/gtest/README.txt @@ -0,0 +1,2 @@ +Please name all test cases in this directory with the prefix "psm". This makes +it easier to run all PSM related GTests at once. diff --git a/security/manager/ssl/tests/gtest/TLSIntoleranceTest.cpp b/security/manager/ssl/tests/gtest/TLSIntoleranceTest.cpp new file mode 100644 index 0000000000..0c9d3ef60d --- /dev/null +++ b/security/manager/ssl/tests/gtest/TLSIntoleranceTest.cpp @@ -0,0 +1,383 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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/. */ + +#include "nsNSSIOLayer.h" +#include "sslproto.h" +#include "sslerr.h" + +#include "gtest/gtest.h" + +constexpr auto HOST = "example.org"_ns; +const int16_t PORT = 443; + +class psm_TLSIntoleranceTest : public ::testing::Test { + protected: + nsSSLIOLayerHelpers helpers; +}; + +TEST_F(psm_TLSIntoleranceTest, FullFallbackProcess) { + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, helpers.mVersionFallbackLimit); + + // No adjustment made when there is no entry for the site. + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + + ASSERT_TRUE(helpers.rememberIntolerantAtVersion(HOST, PORT, range.min, + range.max, 0)); + } + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); + + ASSERT_TRUE(helpers.rememberIntolerantAtVersion(HOST, PORT, range.min, + range.max, 0)); + } + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.max); + + ASSERT_FALSE(helpers.rememberIntolerantAtVersion(HOST, PORT, range.min, + range.max, 0)); + } + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + // When rememberIntolerantAtVersion returns false, it also resets the + // intolerance information for the server. + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } +} + +TEST_F(psm_TLSIntoleranceTest, DisableFallbackWithHighLimit) { + // this value disables version fallback entirely: with this value, all efforts + // to mark an origin as version intolerant fail + helpers.mVersionFallbackLimit = SSL_LIBRARY_VERSION_TLS_1_2; + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, 0)); + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_1, 0)); + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_0, 0)); +} + +TEST_F(psm_TLSIntoleranceTest, FallbackLimitBelowMin) { + // check that we still respect the minimum version, + // when it is higher than the fallback limit + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1, SSL_LIBRARY_VERSION_TLS_1_2, 0)); + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); + } + + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1, SSL_LIBRARY_VERSION_TLS_1_1, 0)); +} + +TEST_F(psm_TLSIntoleranceTest, TolerantOverridesIntolerant1) { + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_1, 0)); + helpers.rememberTolerantAtVersion(HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1); + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); +} + +TEST_F(psm_TLSIntoleranceTest, TolerantOverridesIntolerant2) { + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_1, 0)); + helpers.rememberTolerantAtVersion(HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_2); + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); +} + +TEST_F(psm_TLSIntoleranceTest, IntolerantDoesNotOverrideTolerant) { + // No adjustment made when there is no entry for the site. + helpers.rememberTolerantAtVersion(HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1); + // false because we reached the floor set by rememberTolerantAtVersion. + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_1, 0)); + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); +} + +TEST_F(psm_TLSIntoleranceTest, PortIsRelevant) { + helpers.rememberTolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_2); + ASSERT_FALSE(helpers.rememberIntolerantAtVersion( + HOST, 1, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, 0)); + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, 2, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, 0)); + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, 1, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } + + { + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, 2, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); + } +} + +TEST_F(psm_TLSIntoleranceTest, IntoleranceReasonInitial) { + ASSERT_EQ(0, helpers.getIntoleranceReason(HOST, 1)); + + helpers.rememberTolerantAtVersion(HOST, 2, SSL_LIBRARY_VERSION_TLS_1_2); + ASSERT_EQ(0, helpers.getIntoleranceReason(HOST, 2)); +} + +TEST_F(psm_TLSIntoleranceTest, IntoleranceReasonStored) { + helpers.rememberIntolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2, + SSL_ERROR_BAD_SERVER); + ASSERT_EQ(SSL_ERROR_BAD_SERVER, helpers.getIntoleranceReason(HOST, 1)); + + helpers.rememberIntolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_1, + SSL_ERROR_BAD_MAC_READ); + ASSERT_EQ(SSL_ERROR_BAD_MAC_READ, helpers.getIntoleranceReason(HOST, 1)); +} + +TEST_F(psm_TLSIntoleranceTest, IntoleranceReasonCleared) { + ASSERT_EQ(0, helpers.getIntoleranceReason(HOST, 1)); + + helpers.rememberIntolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2, + SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT); + ASSERT_EQ(SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT, + helpers.getIntoleranceReason(HOST, 1)); + + helpers.rememberTolerantAtVersion(HOST, 1, SSL_LIBRARY_VERSION_TLS_1_2); + ASSERT_EQ(0, helpers.getIntoleranceReason(HOST, 1)); +} + +TEST_F(psm_TLSIntoleranceTest, TLSForgetIntolerance) { + { + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, + 0)); + + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); + } + + { + helpers.forgetIntolerance(HOST, PORT); + + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } +} + +TEST_F(psm_TLSIntoleranceTest, TLSDontForgetTolerance) { + { + helpers.rememberTolerantAtVersion(HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_1); + + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } + + { + ASSERT_TRUE(helpers.rememberIntolerantAtVersion( + HOST, PORT, SSL_LIBRARY_VERSION_TLS_1_0, SSL_LIBRARY_VERSION_TLS_1_2, + 0)); + + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_1, range.max); + } + + { + helpers.forgetIntolerance(HOST, PORT); + + SSLVersionRange range = {SSL_LIBRARY_VERSION_TLS_1_0, + SSL_LIBRARY_VERSION_TLS_1_2}; + helpers.adjustForTLSIntolerance(HOST, PORT, range); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_0, range.min); + ASSERT_EQ(SSL_LIBRARY_VERSION_TLS_1_2, range.max); + } +} + +TEST_F(psm_TLSIntoleranceTest, TLSPerSiteFallbackLimit) { + constexpr auto example_com = "example.com"_ns; + constexpr auto example_net = "example.net"_ns; + constexpr auto example_org = "example.org"_ns; + + helpers.mVersionFallbackLimit = SSL_LIBRARY_VERSION_TLS_1_0; + + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); + + helpers.mVersionFallbackLimit = SSL_LIBRARY_VERSION_TLS_1_2; + + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); + + helpers.setInsecureFallbackSites(example_com); + + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); + + helpers.setInsecureFallbackSites("example.com,example.net"_ns); + + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); + + helpers.setInsecureFallbackSites(example_net); + + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_FALSE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); + + helpers.setInsecureFallbackSites(""_ns); + + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_com, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_net, SSL_LIBRARY_VERSION_TLS_1_0)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_2)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_1)); + ASSERT_TRUE( + helpers.fallbackLimitReached(example_org, SSL_LIBRARY_VERSION_TLS_1_0)); +} diff --git a/security/manager/ssl/tests/gtest/moz.build b/security/manager/ssl/tests/gtest/moz.build new file mode 100644 index 0000000000..caa4b839ab --- /dev/null +++ b/security/manager/ssl/tests/gtest/moz.build @@ -0,0 +1,29 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +SOURCES += [ + "CertDBTest.cpp", + "CertListTest.cpp", + "CoseTest.cpp", + "DataStorageTest.cpp", + "DeserializeCertTest.cpp", + "MD4Test.cpp", + "OCSPCacheTest.cpp", + "TLSIntoleranceTest.cpp", +] + +LOCAL_INCLUDES += [ + "/security/certverifier", + "/security/manager/ssl", + "/third_party/rust/cose-c/include", +] + +include("/ipc/chromium/chromium-config.mozbuild") + +FINAL_LIBRARY = "xul-gtest" + +if CONFIG["CC_TYPE"] in ("clang", "gcc"): + CXXFLAGS += ["-Wno-error=shadow"] diff --git a/security/manager/ssl/tests/mochitest/browser/browser.ini b/security/manager/ssl/tests/mochitest/browser/browser.ini new file mode 100644 index 0000000000..4a590a74e4 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser.ini @@ -0,0 +1,25 @@ +[DEFAULT] +tags = psm +support-files = + head.js + *.pem + +[browser_bug627234_perwindowpb.js] +[browser_certificateManager.js] +[browser_certViewer.js] +skip-if = verify +[browser_clientAuth_connection.js] +# Any test that has to delete certificates (e.g. as part of cleanup) is +# fundamentally incompatible with verify due to how NSS handles deleting +# certificates. +skip-if = verify +[browser_clientAuth_ui.js] +[browser_clientAuthRememberService.js] +[browser_deleteCert_ui.js] +[browser_downloadCert_ui.js] +[browser_editCACertTrust.js] +# An earlier attempt at landing this test resulted in frequent intermittent +# failures, almost entirely on Linux. See Bug 1309519. +skip-if = os == "linux" +[browser_exportP12_passwordUI.js] +[browser_loadPKCS11Module_ui.js] diff --git a/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js new file mode 100644 index 0000000000..a1be1d2a29 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_bug627234_perwindowpb.js @@ -0,0 +1,101 @@ +/* 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/. */ +"use strict"; + +function whenNewWindowLoaded(aOptions, aCallback) { + let win = OpenBrowserWindow(aOptions); + win.addEventListener( + "load", + function() { + aCallback(win); + }, + { once: true } + ); +} + +// This is a template to help porting global private browsing tests +// to per-window private browsing tests +function test() { + // initialization + waitForExplicitFinish(); + let windowsToClose = []; + let testURI = "about:blank"; + let uri; + let gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + + function privacyFlags(aIsPrivateMode) { + return aIsPrivateMode ? Ci.nsISocketProvider.NO_PERMANENT_STORAGE : 0; + } + + function doTest(aIsPrivateMode, aWindow, aCallback) { + BrowserTestUtils.browserLoaded(aWindow.gBrowser.selectedBrowser).then( + () => { + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + uri = aWindow.Services.io.newURI("https://localhost/img.png"); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000", + secInfo, + privacyFlags(aIsPrivateMode), + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + privacyFlags(aIsPrivateMode) + ), + "checking sts host" + ); + + aCallback(); + } + ); + + BrowserTestUtils.loadURI(aWindow.gBrowser.selectedBrowser, testURI); + } + + function testOnWindow(aOptions, aCallback) { + whenNewWindowLoaded(aOptions, function(aWin) { + windowsToClose.push(aWin); + // execute should only be called when need, like when you are opening + // web pages on the test. If calling executeSoon() is not necesary, then + // call whenNewWindowLoaded() instead of testOnWindow() on your test. + executeSoon(function() { + aCallback(aWin); + }); + }); + } + + // this function is called after calling finish() on the test. + registerCleanupFunction(function() { + windowsToClose.forEach(function(aWin) { + aWin.close(); + }); + uri = Services.io.newURI("http://localhost"); + gSSService.resetState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0); + }); + + // test first when on private mode + testOnWindow({ private: true }, function(aWin) { + doTest(true, aWin, function() { + // test when not on private mode + testOnWindow({}, function(aWin) { + doTest(false, aWin, function() { + // test again when on private mode + testOnWindow({ private: true }, function(aWin) { + doTest(true, aWin, function() { + finish(); + }); + }); + }); + }); + }); + }); +} diff --git a/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js b/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js new file mode 100644 index 0000000000..d686653413 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_certViewer.js @@ -0,0 +1,107 @@ +/* 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/. */ +"use strict"; + +// Repeatedly opens the certificate viewer dialog with various certificates and +// determines that the viewer correctly identifies either what usages those +// certificates are valid for or what errors prevented the certificates from +// being verified. + +var { AppConstants } = ChromeUtils.import( + "resource://gre/modules/AppConstants.jsm" +); +var { OS } = ChromeUtils.import("resource://gre/modules/osfile.jsm"); + +add_task(async function testCAandTitle() { + let cert = await readCertificate("ca.pem", "CTu,CTu,CTu"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "ca"); +}); + +add_task(async function testSSLEndEntity() { + let cert = await readCertificate("ssl-ee.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "ssl-ee"); +}); + +add_task(async function testEmailEndEntity() { + let cert = await readCertificate("email-ee.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "email-ee"); +}); + +add_task(async function testCodeSignEndEntity() { + let cert = await readCertificate("code-ee.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "code-ee"); +}); + +add_task(async function testExpired() { + let cert = await readCertificate("expired-ca.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "expired-ca"); +}); + +add_task(async function testUntrusted() { + let cert = await readCertificate("untrusted-ca.pem", "p,p,p"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "untrusted-ca"); +}); + +add_task(async function testInvalid() { + // This certificate has a keyUsage extension asserting cRLSign and + // keyCertSign, but it doesn't have a basicConstraints extension. This + // shouldn't be valid for any usage. Sadly, we give a pretty bad error + // message in this case. + let cert = await readCertificate("invalid.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "invalid"); +}); + +add_task(async function testLongOID() { + // This certificate has a certificatePolicies extension with a policy with a + // very long OID. This tests that we don't crash when looking at it. + let cert = await readCertificate("longOID.pem", ",,"); + let url = getURL(cert); + await openCertViewerAndCheckTabName(url, "Long OID"); +}); + +/** + * Given a certificate, returns its PEMs (each one of the certificate chain) string in a url. + * @param {Object} cert + * A certificate object + * @returns {String} an URL for opening the certificate viewer + */ +function getURL(cert) { + // Note that we don't get the certificate chain as in e.g browser/base/content/browser.js, + // because all the .pem files when opened with CS (https://github.com/april/certainly-something) + // shows only one certificate + let derb64 = encodeURIComponent(cert.getBase64DERString()); + return `about:certificate?cert=${derb64}`; +} + +/** + * Given an certificate URL, opens the new certificate viewer and check + * if a certain element exists, with its expected result. + * + * @param {String} url + * The URL with the certificate info + * @param {String} expectedTabName + * The expected name of the tab in the certificate viewer + */ +async function openCertViewerAndCheckTabName(url, expectedTabName) { + await BrowserTestUtils.withNewTab({ gBrowser, url }, async function(browser) { + await SpecialPowers.spawn(browser, [expectedTabName], async function( + expectedTabName + ) { + let certificateSection = await ContentTaskUtils.waitForCondition(() => { + return content.document.querySelector("certificate-section"); + }, "Certificate section found"); + let tabName = certificateSection.shadowRoot.querySelector( + ".tab[idnumber='0']" + ).textContent; + Assert.equal(tabName, expectedTabName); + }); + }); +} diff --git a/security/manager/ssl/tests/mochitest/browser/browser_certificateManager.js b/security/manager/ssl/tests/mochitest/browser/browser_certificateManager.js new file mode 100644 index 0000000000..3b6ab0d6f3 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_certificateManager.js @@ -0,0 +1,179 @@ +/* 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/. */ +"use strict"; + +const TEST_CERT_BASE64 = + "MIICrjCCAZagAwIBAgIUCR+2dzKgSt0CBU86EgRdJIa/72owDQYJKoZIhvcNAQEEBQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowETEPMA0GA1UEAwwGbWQ1LWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEBBAUAA4IBAQArfDtm5sEuzsPZps2oZhvrOYRViP0sRIAbAjuJVnAMA/7xLzI3LweXOlQJHBh3m3mrPUMAXfr4xJ5XjGySqHBUtFat9EBl/0bynd67sCMA7UOf51GC4ABOPAV0CkDj/FNqL/KSt8WB90FW+ZKnt1ojKikMIjmPjxDaaHj7KZVBQ2KtBEz1Igt5Bvbrp2AMNvjyhUCN4/z4NDPPbzkeDKYC7vmvYhN1Cs/73Jp3A0LU4z0gIyrWi6a7YEAVBzhIvJJ98U8AQQMm+iiIDGZMoAZyvEFouofF9te4xMHStUnYfa1jLY93dL1TuXrWvKB0pWg4REoQuFZUE8GS/LczW5xX"; + +async function checkServerCertificates(win, expectedValues = []) { + await TestUtils.waitForCondition(() => { + return ( + win.document.getElementById("serverList").itemChildren.length == + expectedValues.length + ); + }, `Expected to have ${expectedValues.length} but got ${win.document.getElementById("serverList").itemChildren.length}`); + + let labels = win.document + .getElementById("serverList") + .querySelectorAll("label"); + + expectedValues.forEach((item, i) => { + let hostPort = labels[i * 3].value; + let certString = labels[i * 3 + 1].value || labels[i * 3 + 1].textContent; + let isTemporaryString = + labels[i * 3 + 2].value || labels[i * 3 + 2].textContent; + + Assert.equal( + hostPort, + item.hostPort, + `Expected override to be ${item.hostPort} but got ${hostPort}` + ); + + Assert.equal( + certString, + item.certName, + `Expected override to have field ${item.certName}` + ); + + Assert.equal( + isTemporaryString, + item.isTemporary ? "Temporary" : "Permanent", + `Expected override to be ${item.isTemporary ? "Temporary" : "Permanent"}` + ); + }); +} + +async function deleteOverride(win, expectedLength) { + win.document.getElementById("serverList").selectedIndex = 0; + await TestUtils.waitForCondition(() => { + return ( + win.document.getElementById("serverList").itemChildren.length == + expectedLength + ); + }); + let newWinPromise = BrowserTestUtils.domWindowOpenedAndLoaded(); + // Since the .click() blocks we need to dispatch it to the main thread avoid that. + Services.tm.dispatchToMainThread(() => + win.document.getElementById("websites_deleteButton").click() + ); + let newWin = await newWinPromise; + newWin.document.getElementById("deleteCertificate").acceptDialog(); + Assert.equal( + win.document.getElementById("serverList").selectedIndex, + 0, + "After deletion we expect the selectedItem to be reset." + ); +} + +async function testViewButton(win) { + win.document.getElementById("serverList").selectedIndex = 1; + + Assert.ok( + win.document.getElementById("websites_viewButton").disabled, + "View button should be disabled for override without cert" + ); + + win.document.getElementById("serverList").selectedIndex = 0; + + Assert.ok( + !win.document.getElementById("websites_viewButton").disabled, + "View button should be enabled for override with cert" + ); + + let loaded = BrowserTestUtils.waitForNewTab(gBrowser, null, true); + + win.document.getElementById("websites_viewButton").click(); + + let newTab = await loaded; + let spec = newTab.linkedBrowser.documentURI.spec; + + Assert.ok( + spec.startsWith("about:certificate"), + "about:certificate should habe been opened" + ); + + let newUrl = new URL(spec); + let certEncoded = newUrl.searchParams.get("cert"); + let certDecoded = decodeURIComponent(certEncoded); + Assert.equal( + TEST_CERT_BASE64, + certDecoded, + "Loaded cert should match expected cert" + ); + + gBrowser.removeCurrentTab(); +} + +add_task(async function test_cert_manager_server_tab() { + let win = await openCertManager(); + + await checkServerCertificates(win); + + win.document.getElementById("certmanager").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + let cert = await readCertificate("md5-ee.pem", ",,"); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.rememberValidityOverride( + "example.com", + 443, + cert, + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + false + ); + + win = await openCertManager(); + + await checkServerCertificates(win, [ + { + hostPort: "example.com:443", + certName: "md5-ee", + isTemporary: false, + }, + ]); + + win.document.getElementById("certmanager").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + certOverrideService.rememberTemporaryValidityOverrideUsingFingerprint( + "example.com", + 9999, + "40:20:3E:57:FB:82:95:0D:3F:62:D7:04:39:F6:32:CC:B2:2F:70:9F:3E:66:C5:35:64:6E:49:2A:F1:02:75:9F", + Ci.nsICertOverrideService.ERROR_UNTRUSTED + ); + + win = await openCertManager(); + + await checkServerCertificates(win, [ + { + hostPort: "example.com:443", + certName: "md5-ee", + isTemporary: false, + }, + { + hostPort: "example.com:9999", + certName: "(Not Stored)", + isTemporary: true, + }, + ]); + + await testViewButton(win); + + await deleteOverride(win, 2); + + await checkServerCertificates(win, [ + { + hostPort: "example.com:9999", + certName: "(Not Stored)", + isTemporary: true, + }, + ]); + + win.document.getElementById("certmanager").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + certOverrideService.clearAllOverrides(); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_clientAuthRememberService.js b/security/manager/ssl/tests/mochitest/browser/browser_clientAuthRememberService.js new file mode 100644 index 0000000000..3ab2d9792e --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_clientAuthRememberService.js @@ -0,0 +1,257 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +/** + * Test certificate (i.e. build/pgo/certs/mochitest.client). + * @type nsIX509Cert + */ +var cert; +var cert2; +var cert3; + +var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing); +var certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +var deleted = false; + +const { MockRegistrar } = ChromeUtils.import( + "resource://testing-common/MockRegistrar.jsm" +); + +function findCertByCommonName(commonName) { + for (let cert of certDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +async function testHelper(connectURL, expectedURL) { + let win = await BrowserTestUtils.openNewBrowserWindow(); + + await SpecialPowers.pushPrefEnv({ + set: [["security.default_personal_cert", "Ask Every Time"]], + }); + + BrowserTestUtils.loadURI(win.gBrowser.selectedBrowser, connectURL); + + await BrowserTestUtils.browserLoaded( + win.gBrowser.selectedBrowser, + false, + expectedURL, + true + ); + let loadedURL = win.gBrowser.selectedBrowser.documentURI.spec; + Assert.ok( + loadedURL.startsWith(expectedURL), + `Expected and actual URLs should match (got '${loadedURL}', expected '${expectedURL}')` + ); + + await win.close(); + + // This clears the TLS session cache so we don't use a previously-established + // ticket to connect and bypass selecting a client auth certificate in + // subsequent tests. + sdr.logout(); +} + +async function openRequireClientCert() { + gClientAuthDialogs.chooseCertificateCalled = false; + await testHelper( + "https://requireclientcert.example.com:443", + "https://requireclientcert.example.com/" + ); +} + +async function openRequireClientCert2() { + gClientAuthDialogs.chooseCertificateCalled = false; + await testHelper( + "https://requireclientcert-2.example.com:443", + "https://requireclientcert-2.example.com/" + ); +} + +// Mock implementation of nsIClientAuthRememberService +const gClientAuthRememberService = { + forgetRememberedDecision(key) { + deleted = true; + Assert.equal( + key, + "exampleKey2", + "Expected to get the same key that was passed in getDecisions()" + ); + }, + + getDecisions() { + return [ + { + asciiHost: "example.com", + dbKey: cert.dbKey, + entryKey: "exampleKey1", + }, + { + asciiHost: "example.org", + dbKey: cert2.dbKey, + entryKey: "exampleKey2", + }, + { + asciiHost: "example.test", + dbKey: cert3.dbKey, + entryKey: "exampleKey3", + }, + ]; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIClientAuthRememberService"]), +}; + +const gClientAuthDialogs = { + _chooseCertificateCalled: false, + + get chooseCertificateCalled() { + return this._chooseCertificateCalled; + }, + + set chooseCertificateCalled(value) { + this._chooseCertificateCalled = value; + }, + + chooseCertificate( + hostname, + port, + organization, + issuerOrg, + certList, + selectedIndex, + rememberClientAuthCertificate + ) { + rememberClientAuthCertificate.value = true; + this.chooseCertificateCalled = true; + selectedIndex.value = 0; + return true; + }, + + QueryInterface: ChromeUtils.generateQI([Ci.nsIClientAuthDialogs]), +}; + +add_task(async function testRememberedDecisionsUI() { + cert = findCertByCommonName("Mochitest client"); + cert2 = await readCertificate("pgo-ca-all-usages.pem", ",,"); + cert3 = await readCertificate("client-cert-via-intermediate.pem", ",,"); + isnot(cert, null, "Should be able to find the test client cert"); + isnot(cert2, null, "Should be able to find pgo-ca-all-usages.pem"); + isnot(cert3, null, "Should be able to find client-cert-via-intermediate.pem"); + + let clientAuthRememberServiceCID = MockRegistrar.register( + "@mozilla.org/security/clientAuthRememberService;1", + gClientAuthRememberService + ); + + let win = await openCertManager(); + + let listItems = win.document + .getElementById("rememberedList") + .querySelectorAll("richlistitem"); + + Assert.equal( + listItems.length, + 3, + "Expected rememberedList to only have one item" + ); + + let labels = win.document + .getElementById("rememberedList") + .querySelectorAll("label"); + + Assert.equal( + labels.length, + 9, + "Expected the rememberedList to have three labels" + ); + + let expectedHosts = ["example.com", "example.org", "example.test"]; + let hosts = [labels[0].value, labels[3].value, labels[6].value]; + let expectedNames = [cert.commonName, cert2.commonName, cert3.commonName]; + let names = [labels[1].value, labels[4].value, labels[7].value]; + let expectedSerialNumbers = [ + cert.serialNumber, + cert2.serialNumber, + cert3.serialNumber, + ]; + let serialNumbers = [labels[2].value, labels[5].value, labels[8].value]; + + for (let i = 0; i < 3; i++) { + Assert.equal(hosts[i], expectedHosts[i], "Expected host to be asciiHost"); + Assert.equal( + names[i], + expectedNames[i], + "Expected name to be the commonName of the cert" + ); + Assert.equal( + serialNumbers[i], + expectedSerialNumbers[i], + "Expected serialNumber to be the serialNumber of the cert" + ); + } + + win.document.getElementById("rememberedList").selectedIndex = 1; + + win.document.getElementById("remembered_deleteButton").click(); + + Assert.ok(deleted, "Expected forgetRememberedDecision() to get called"); + + win.document.getElementById("certmanager").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + MockRegistrar.unregister(clientAuthRememberServiceCID); +}); + +add_task(async function testDeletingRememberedDecisions() { + let clientAuthDialogsCID = MockRegistrar.register( + "@mozilla.org/nsClientAuthDialogs;1", + gClientAuthDialogs + ); + let cars = Cc["@mozilla.org/security/clientAuthRememberService;1"].getService( + Ci.nsIClientAuthRememberService + ); + + await openRequireClientCert(); + Assert.ok( + gClientAuthDialogs.chooseCertificateCalled, + "chooseCertificate should have been called if visiting 'requireclientcert.example.com' for the first time" + ); + + await openRequireClientCert(); + Assert.ok( + !gClientAuthDialogs.chooseCertificateCalled, + "chooseCertificate should not have been called if visiting 'requireclientcert.example.com' for the second time" + ); + + await openRequireClientCert2(); + Assert.ok( + gClientAuthDialogs.chooseCertificateCalled, + "chooseCertificate should have been called if visiting'requireclientcert-2.example.com' for the first time" + ); + + let originAttributes = { privateBrowsingId: 0 }; + cars.deleteDecisionsByHost("requireclientcert.example.com", originAttributes); + + await openRequireClientCert(); + Assert.ok( + gClientAuthDialogs.chooseCertificateCalled, + "chooseCertificate should have been called after removing all remembered decisions for 'requireclientcert.example.com'" + ); + + await openRequireClientCert2(); + Assert.ok( + !gClientAuthDialogs.chooseCertificateCalled, + "chooseCertificate should not have been called if visiting 'requireclientcert-2.example.com' for the second time" + ); + + MockRegistrar.unregister(clientAuthDialogsCID); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js new file mode 100644 index 0000000000..a0e9723f43 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_connection.js @@ -0,0 +1,342 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests various scenarios connecting to a server that requires client cert +// authentication. Also tests that nsIClientAuthDialogs.chooseCertificate +// is called at the appropriate times and with the correct arguments. + +const { MockRegistrar } = ChromeUtils.import( + "resource://testing-common/MockRegistrar.jsm" +); + +const DialogState = { + // Assert that chooseCertificate() is never called. + ASSERT_NOT_CALLED: "ASSERT_NOT_CALLED", + // Return that the user selected the first given cert. + RETURN_CERT_SELECTED: "RETURN_CERT_SELECTED", + // Return that the user canceled. + RETURN_CERT_NOT_SELECTED: "RETURN_CERT_NOT_SELECTED", +}; + +var sdr = Cc["@mozilla.org/security/sdr;1"].getService(Ci.nsISecretDecoderRing); +let cars = Cc["@mozilla.org/security/clientAuthRememberService;1"].getService( + Ci.nsIClientAuthRememberService +); + +var gExpectedClientCertificateChoices; + +// Mock implementation of nsIClientAuthDialogs. +const gClientAuthDialogs = { + _state: DialogState.ASSERT_NOT_CALLED, + _rememberClientAuthCertificate: false, + _chooseCertificateCalled: false, + + set state(newState) { + info(`old state: ${this._state}`); + this._state = newState; + info(`new state: ${this._state}`); + }, + + get state() { + return this._state; + }, + + set rememberClientAuthCertificate(value) { + this._rememberClientAuthCertificate = value; + }, + + get rememberClientAuthCertificate() { + return this._rememberClientAuthCertificate; + }, + + get chooseCertificateCalled() { + return this._chooseCertificateCalled; + }, + + set chooseCertificateCalled(value) { + this._chooseCertificateCalled = value; + }, + + chooseCertificate( + hostname, + port, + organization, + issuerOrg, + certList, + selectedIndex, + rememberClientAuthCertificate + ) { + this.chooseCertificateCalled = true; + Assert.notEqual( + this.state, + DialogState.ASSERT_NOT_CALLED, + "chooseCertificate() should be called only when expected" + ); + + rememberClientAuthCertificate.value = this.rememberClientAuthCertificate; + + Assert.equal( + hostname, + "requireclientcert.example.com", + "Hostname should be 'requireclientcert.example.com'" + ); + Assert.equal(port, 443, "Port should be 443"); + Assert.equal( + organization, + "", + "Server cert Organization should be empty/not present" + ); + Assert.equal( + issuerOrg, + "Mozilla Testing", + "Server cert issuer Organization should be 'Mozilla Testing'" + ); + + // For mochitests, the cert at build/pgo/certs/mochitest.client should be + // selectable as well as one of the PGO certs we loaded in `setup`, so we do + // some brief checks to confirm this. + Assert.notEqual(certList, null, "Cert list should not be null"); + Assert.equal( + certList.length, + gExpectedClientCertificateChoices, + `${gExpectedClientCertificateChoices} certificates should be available` + ); + + for (let cert of certList.enumerate(Ci.nsIX509Cert)) { + Assert.notEqual(cert, null, "Cert list should contain nsIX509Certs"); + Assert.equal( + cert.issuerCommonName, + "Temporary Certificate Authority", + "cert should have expected issuer CN" + ); + } + + if (this.state == DialogState.RETURN_CERT_SELECTED) { + selectedIndex.value = 0; + return true; + } + return false; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIClientAuthDialogs"]), +}; + +add_task(async function setup() { + let clientAuthDialogsCID = MockRegistrar.register( + "@mozilla.org/nsClientAuthDialogs;1", + gClientAuthDialogs + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(clientAuthDialogsCID); + }); + + // This CA has the expected keyCertSign and cRLSign usages. It should not be + // presented for use as a client certificate. + await readCertificate("pgo-ca-regular-usages.pem", "CTu,CTu,CTu"); + // This CA has all keyUsages. For compatibility with preexisting behavior, it + // will be presented for use as a client certificate. + await readCertificate("pgo-ca-all-usages.pem", "CTu,CTu,CTu"); + // This client certificate was issued by an intermediate that was issued by + // the test CA. The server only lists the test CA's subject distinguished name + // as an acceptible issuer name for client certificates. If the implementation + // can determine that the test CA is a root CA for the client certificate and + // thus is acceptible to use, it should be included in the chooseCertificate + // callback. At the beginning of this test (speaking of this file as a whole), + // the client is not aware of the intermediate, and so it is not available in + // the callback. + await readCertificate("client-cert-via-intermediate.pem", ",,"); + // This certificate has an id-kp-OCSPSigning EKU. Client certificates + // shouldn't have this EKU, but there is at least one private PKI where they + // do. For interoperability, such certificates will be presented for use. + await readCertificate("client-cert-with-ocsp-signing.pem", ",,"); + gExpectedClientCertificateChoices = 3; +}); + +/** + * Test helper for the tests below. + * + * @param {String} prefValue + * Value to set the "security.default_personal_cert" pref to. + * @param {String} expectedURL + * If the connection is expected to load successfully, the URL that + * should load. If the connection is expected to fail and result in an + * error page, |undefined|. + * @param {Boolean} expectCallingChooseCertificate + * Determines whether we expect chooseCertificate to be called. + * @param {Object} options + * Optional options object to pass on to the window that gets opened. + */ +async function testHelper( + prefValue, + expectedURL, + expectCallingChooseCertificate, + options = undefined +) { + gClientAuthDialogs.chooseCertificateCalled = false; + await SpecialPowers.pushPrefEnv({ + set: [["security.default_personal_cert", prefValue]], + }); + + let win = await BrowserTestUtils.openNewBrowserWindow(options); + + BrowserTestUtils.loadURI( + win.gBrowser.selectedBrowser, + "https://requireclientcert.example.com:443" + ); + + await BrowserTestUtils.browserLoaded( + win.gBrowser.selectedBrowser, + false, + "https://requireclientcert.example.com/", + true + ); + let loadedURL = win.gBrowser.selectedBrowser.documentURI.spec; + Assert.ok( + loadedURL.startsWith(expectedURL), + `Expected and actual URLs should match (got '${loadedURL}', expected '${expectedURL}')` + ); + Assert.equal( + gClientAuthDialogs.chooseCertificateCalled, + expectCallingChooseCertificate, + "chooseCertificate should have been called if we were expecting it to be called" + ); + + await win.close(); + + // This clears the TLS session cache so we don't use a previously-established + // ticket to connect and bypass selecting a client auth certificate in + // subsequent tests. + sdr.logout(); +} + +// Test that if a certificate is chosen automatically the connection succeeds, +// and that nsIClientAuthDialogs.chooseCertificate() is never called. +add_task(async function testCertChosenAutomatically() { + gClientAuthDialogs.state = DialogState.ASSERT_NOT_CALLED; + await testHelper( + "Select Automatically", + "https://requireclientcert.example.com/", + false + ); + // This clears all saved client auth certificate state so we don't influence + // subsequent tests. + cars.clearRememberedDecisions(); +}); + +// Test that if the user doesn't choose a certificate, the connection fails and +// an error page is displayed. +add_task(async function testCertNotChosenByUser() { + gClientAuthDialogs.state = DialogState.RETURN_CERT_NOT_SELECTED; + await testHelper( + "Ask Every Time", + "about:neterror?e=nssFailure2&u=https%3A//requireclientcert.example.com/", + true + ); + cars.clearRememberedDecisions(); +}); + +// Test that if the user chooses a certificate the connection suceeeds. +add_task(async function testCertChosenByUser() { + gClientAuthDialogs.state = DialogState.RETURN_CERT_SELECTED; + await testHelper( + "Ask Every Time", + "https://requireclientcert.example.com/", + true + ); + cars.clearRememberedDecisions(); +}); + +// Test that the cancel decision is remembered correctly +add_task(async function testEmptyCertChosenByUser() { + gClientAuthDialogs.state = DialogState.RETURN_CERT_NOT_SELECTED; + gClientAuthDialogs.rememberClientAuthCertificate = true; + await testHelper( + "Ask Every Time", + "about:neterror?e=nssFailure2&u=https%3A//requireclientcert.example.com/", + true + ); + await testHelper( + "Ask Every Time", + "about:neterror?e=nssFailure2&u=https%3A//requireclientcert.example.com/", + false + ); + cars.clearRememberedDecisions(); +}); + +// Test that if the user chooses a certificate in a private browsing window, +// configures Firefox to remember this certificate for the duration of the +// session, closes that window (and thus all private windows), reopens a private +// window, and visits that site again, they are re-asked for a certificate (i.e. +// any state from the previous private session should be gone). Similarly, after +// closing that private window, if the user opens a non-private window, they +// again should be asked to choose a certificate (i.e. private state should not +// be remembered/used in non-private contexts). +add_task(async function testClearPrivateBrowsingState() { + gClientAuthDialogs.rememberClientAuthCertificate = true; + gClientAuthDialogs.state = DialogState.RETURN_CERT_SELECTED; + await testHelper( + "Ask Every Time", + "https://requireclientcert.example.com/", + true, + { + private: true, + } + ); + await testHelper( + "Ask Every Time", + "https://requireclientcert.example.com/", + true, + { + private: true, + } + ); + await testHelper( + "Ask Every Time", + "https://requireclientcert.example.com/", + true + ); + // NB: we don't `cars.clearRememberedDecisions()` in between the two calls to + // `testHelper` because that would clear all client auth certificate state and + // obscure what we're testing (that Firefox properly clears the relevant state + // when the last private window closes). + cars.clearRememberedDecisions(); +}); + +// Test that 3rd party certificates are taken into account when filtering client +// certificates based on the acceptible CA list sent by the server. +add_task(async function testCertFilteringWithIntermediate() { + let intermediateBytes = await OS.File.read( + getTestFilePath("intermediate.pem") + ).then( + data => { + let decoder = new TextDecoder(); + let pem = decoder.decode(data); + let base64 = pemToBase64(pem); + let bin = atob(base64); + let bytes = []; + for (let i = 0; i < bin.length; i++) { + bytes.push(bin.charCodeAt(i)); + } + return bytes; + }, + error => { + throw error; + } + ); + let nssComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsINSSComponent); + nssComponent.addEnterpriseIntermediate(intermediateBytes); + gExpectedClientCertificateChoices = 4; + gClientAuthDialogs.state = DialogState.RETURN_CERT_SELECTED; + await testHelper( + "Ask Every Time", + "https://requireclientcert.example.com/", + true + ); + cars.clearRememberedDecisions(); + // This will reset the added intermediate. + await SpecialPowers.pushPrefEnv({ + set: [["security.enterprise_roots.enabled", true]], + }); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js new file mode 100644 index 0000000000..c75cf02482 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_clientAuth_ui.js @@ -0,0 +1,199 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the client authentication certificate chooser correctly displays +// provided information and correctly returns user input. + +const TEST_HOSTNAME = "Test Hostname"; +const TEST_ORG = "Test Org"; +const TEST_ISSUER_ORG = "Test Issuer Org"; +const TEST_PORT = 123; + +var certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); +/** + * Test certificate (i.e. build/pgo/certs/mochitest.client). + * @type nsIX509Cert + */ +var cert; + +/** + * Opens the client auth cert chooser dialog. + * + * @param {nsIX509Cert} cert The cert to pass to the dialog for display. + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value nsIWritablePropertyBag2 passed to the dialog. + */ +function openClientAuthDialog(cert) { + let certList = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray); + certList.appendElement(cert); + + let returnVals = Cc["@mozilla.org/hash-property-bag;1"].createInstance( + Ci.nsIWritablePropertyBag2 + ); + let win = window.openDialog( + "chrome://pippki/content/clientauthask.xhtml", + "", + "", + TEST_HOSTNAME, + TEST_ORG, + TEST_ISSUER_ORG, + TEST_PORT, + certList, + returnVals + ); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve([win, returnVals])); + }, + { once: true } + ); + }); +} + +/** + * Checks that the contents of the given cert chooser dialog match the details + * of build/pgo/certs/mochitest.client. + * + * @param {window} win The cert chooser window. + * @param {String} notBefore + * The notBeforeLocalTime attribute of mochitest.client. + * @param {String} notAfter + * The notAfterLocalTime attribute of mochitest.client. + */ +function checkDialogContents(win, notBefore, notAfter) { + is( + win.document.getElementById("hostname").textContent, + `${TEST_HOSTNAME}:${TEST_PORT}`, + "Actual and expected hostname and port should be equal" + ); + is( + win.document.getElementById("organization").textContent, + `Organization: “${TEST_ORG}â€`, + "Actual and expected organization should be equal" + ); + is( + win.document.getElementById("issuer").textContent, + `Issued Under: “${TEST_ISSUER_ORG}â€`, + "Actual and expected issuer organization should be equal" + ); + + is( + win.document.getElementById("nicknames").label, + "Mochitest client [03]", + "Actual and expected selected cert nickname and serial should be equal" + ); + is( + win.document.getElementById("nicknames").itemCount, + 1, + "correct number of items" + ); + + let [ + subject, + serialNum, + validity, + issuer, + tokenName, + ] = win.document.getElementById("details").value.split("\n"); + is( + subject, + "Issued to: CN=Mochitest client", + "Actual and expected subject should be equal" + ); + is( + serialNum, + "Serial number: 03", + "Actual and expected serial number should be equal" + ); + is( + validity, + `Valid from ${notBefore} to ${notAfter}`, + "Actual and expected validity should be equal" + ); + is( + issuer, + "Issued by: OU=Profile Guided Optimization,O=Mozilla Testing,CN=Temporary Certificate Authority", + "Actual and expected issuer should be equal" + ); + is( + tokenName, + "Stored on: Software Security Device", + "Actual and expected token name should be equal" + ); +} + +function findCertByCommonName(commonName) { + for (let cert of certDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +add_task(async function setup() { + cert = findCertByCommonName("Mochitest client"); + isnot(cert, null, "Should be able to find the test client cert"); +}); + +// Test that the contents of the dialog correspond to the details of the +// provided cert. +add_task(async function testContents() { + let [win] = await openClientAuthDialog(cert); + checkDialogContents( + win, + cert.validity.notBeforeLocalTime, + cert.validity.notAfterLocalTime + ); + await BrowserTestUtils.closeWindow(win); +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(async function testAcceptDialogReturnValues() { + let [win, retVals] = await openClientAuthDialog(cert); + win.document.getElementById("rememberBox").checked = true; + info("Accepting dialog"); + win.document.getElementById("certAuthAsk").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + ok( + retVals.get("certChosen"), + "Return value should signal user chose a certificate" + ); + is( + retVals.get("selectedIndex"), + 0, + "0 should be returned as the selected index" + ); + ok( + retVals.get("rememberSelection"), + "Return value should signal 'Remember this decision' checkbox was checked" + ); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(async function testCancelDialogReturnValues() { + let [win, retVals] = await openClientAuthDialog(cert); + win.document.getElementById("rememberBox").checked = false; + info("Canceling dialog"); + win.document.getElementById("certAuthAsk").cancelDialog(); + await BrowserTestUtils.windowClosed(win); + + ok( + !retVals.get("certChosen"), + "Return value should signal user did not choose a certificate" + ); + ok( + !retVals.get("rememberSelection"), + "Return value should signal 'Remember this decision' checkbox was unchecked" + ); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js new file mode 100644 index 0000000000..0d06c553a2 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_deleteCert_ui.js @@ -0,0 +1,257 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests various aspects of the cert delete confirmation dialog. +// Among other things, tests that for each type of cert that can be deleted: +// 1. The various lines of explanation text are correctly set. +// 2. The implementation correctly falls back through multiple cert attributes +// to determine what to display to represent a cert. + +/** + * An array of tree items corresponding to TEST_CASES. + * @type nsICertTreeItem[] + */ +var gCertArray = []; + +const FAKE_HOST_PORT = "Fake host and port"; + +/** + * @typedef {TestCase} + * @type Object + * @property {String} certFilename + * Filename of the cert, or null if we don't want to import a cert for + * this test case (i.e. we expect the hostPort attribute of + * nsICertTreeItem to be used). + * @property {String} expectedDisplayString + * The string we expect the UI to display to represent the given cert. + * @property {String} expectedSerialNumber + * The serial number we expect the UI to display if it exists. + */ + +/** + * A list of test cases representing certs that get "deleted". + * @type TestCase[] + */ +const TEST_CASES = [ + { + certFilename: null, + expectedDisplayString: FAKE_HOST_PORT, + expectedSerialNumber: null, + }, + { + certFilename: "has-cn.pem", + expectedDisplayString: "Foo", + expectedSerialNumber: null, + }, + { + certFilename: "has-ou.pem", + expectedDisplayString: "Bar", + expectedSerialNumber: null, + }, + { + certFilename: "has-o.pem", + expectedDisplayString: "Baz", + expectedSerialNumber: null, + }, + { + certFilename: "has-non-empty-subject.pem", + expectedDisplayString: "C=US", + expectedSerialNumber: null, + }, + { + certFilename: "has-empty-subject.pem", + expectedDisplayString: "Certificate with serial number: 0A", + expectedSerialNumber: "0A", + }, +]; + +/** + * Opens the cert delete confirmation dialog. + * + * @param {String} tabID + * The ID of the cert category tab the certs to delete belong to. + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value object passed to the dialog. + */ +function openDeleteCertConfirmDialog(tabID) { + let retVals = { + deleteConfirmed: false, + }; + let win = window.openDialog( + "chrome://pippki/content/deletecert.xhtml", + "", + "", + tabID, + gCertArray, + retVals + ); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve([win, retVals])); + }, + { once: true } + ); + }); +} + +add_task(async function setup() { + for (let testCase of TEST_CASES) { + let cert = null; + if (testCase.certFilename) { + cert = await readCertificate(testCase.certFilename, ",,"); + } + let certTreeItem = { + hostPort: FAKE_HOST_PORT, + cert, + QueryInterface: ChromeUtils.generateQI(["nsICertTreeItem"]), + }; + gCertArray.push(certTreeItem); + } +}); + +/** + * Test helper for the below test cases. + * + * @param {String} tabID + * ID of the cert category tab the certs to delete belong to. + * @param {String} expectedTitleL10nId + * The L10nId of title the dialog is expected to have. + * @param {String} expectedConfirmL10nId + * The l10n id of confirmation message the dialog expected to show. + * @param {String} expectedImpactL10nId + * The l10n id of impact the dialog expected to show. + */ +async function testHelper( + tabID, + expectedTitleL10nId, + expectedConfirmL10nId, + expectedImpactL10nId +) { + let [win] = await openDeleteCertConfirmDialog(tabID); + let certList = win.document.getElementById("certlist"); + + Assert.deepEqual( + win.document.l10n.getAttributes(win.document.documentElement), + expectedTitleL10nId, + `Actual and expected titles should match for ${tabID}` + ); + let confirm = win.document.getElementById("confirm"); + Assert.deepEqual( + win.document.l10n.getAttributes(confirm), + expectedConfirmL10nId, + `Actual and expected confirm message should match for ${tabID}` + ); + let impact = win.document.getElementById("impact"); + Assert.deepEqual( + win.document.l10n.getAttributes(impact), + expectedImpactL10nId, + `Actual and expected impact should match for ${tabID}` + ); + + Assert.equal( + certList.itemCount, + TEST_CASES.length, + `No. of certs displayed should match for ${tabID}` + ); + for (let i = 0; i < certList.itemCount; i++) { + let item = certList.getItemAtIndex(i); + if (TEST_CASES[i].expectedSerialNumber == null) { + Assert.equal( + item.label, + TEST_CASES[i].expectedDisplayString, + "Actual and expected display string should match for " + + `index ${i} for ${tabID}` + ); + } else { + Assert.deepEqual( + win.document.l10n.getAttributes(item.children[0]), + { + id: "cert-with-serial", + args: { serialNumber: TEST_CASES[i].expectedSerialNumber }, + }, + "Actual and expected display string should match for " + + `index ${i} for ${tabID}` + ); + } + } + + await BrowserTestUtils.closeWindow(win); +} + +// Test deleting certs from the "Your Certificates" tab. +add_task(async function testDeletePersonalCerts() { + const expectedTitleL10nId = { id: "delete-user-cert-title", args: null }; + const expectedConfirmL10nId = { id: "delete-user-cert-confirm", args: null }; + const expectedImpactL10nId = { id: "delete-user-cert-impact", args: null }; + await testHelper( + "mine_tab", + expectedTitleL10nId, + expectedConfirmL10nId, + expectedImpactL10nId + ); +}); + +// Test deleting certs from the "People" tab. +add_task(async function testDeleteOtherPeopleCerts() { + const expectedTitleL10nId = { id: "delete-email-cert-title", args: null }; + // ’ doesn't seem to work when embedded in the following literals, which is + // why escape codes are used instead. + const expectedConfirmL10nId = { id: "delete-email-cert-confirm", args: null }; + const expectedImpactL10nId = { id: "delete-email-cert-impact", args: null }; + await testHelper( + "others_tab", + expectedTitleL10nId, + expectedConfirmL10nId, + expectedImpactL10nId + ); +}); + +// Test deleting certs from the "Authorities" tab. +add_task(async function testDeleteCACerts() { + const expectedTitleL10nId = { id: "delete-ca-cert-title", args: null }; + const expectedConfirmL10nId = { id: "delete-ca-cert-confirm", args: null }; + const expectedImpactL10nId = { id: "delete-ca-cert-impact", args: null }; + await testHelper( + "ca_tab", + expectedTitleL10nId, + expectedConfirmL10nId, + expectedImpactL10nId + ); +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(async function testAcceptDialogReturnValues() { + let [win, retVals] = await openDeleteCertConfirmDialog( + "ca_tab" /* arbitrary */ + ); + info("Accepting dialog"); + win.document.getElementById("deleteCertificate").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + retVals.deleteConfirmed, + "Return value should signal user accepted" + ); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(async function testCancelDialogReturnValues() { + let [win, retVals] = await openDeleteCertConfirmDialog( + "ca_tab" /* arbitrary */ + ); + info("Canceling dialog"); + win.document.getElementById("deleteCertificate").cancelDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + !retVals.deleteConfirmed, + "Return value should signal user did not accept" + ); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js new file mode 100644 index 0000000000..876124d5c2 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_downloadCert_ui.js @@ -0,0 +1,133 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the cert download/import UI correctly identifies the cert being +// downloaded, and allows the trust of the cert to be specified. + +const { MockRegistrar } = ChromeUtils.import( + "resource://testing-common/MockRegistrar.jsm" +); + +/** + * @typedef {TestCase} + * @type Object + * @property {String} certFilename + * Filename of the cert for this test case. + * @property {String} expectedDisplayString + * The string we expect the UI to display to represent the given cert. + * @property {nsIX509Cert} cert + * Handle to the cert once read in setup(). + */ + +/** + * A list of test cases representing certs that get "downloaded". + * @type TestCase[] + */ +const TEST_CASES = [ + { certFilename: "has-cn.pem", expectedDisplayString: "Foo", cert: null }, + { + certFilename: "has-empty-subject.pem", + expectedDisplayString: "Certificate Authority (unnamed)", + cert: null, + }, +]; + +/** + * Opens the cert download dialog. + * + * @param {nsIX509Cert} cert + * The cert to pass to the dialog for display. + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value nsIWritablePropertyBag2 passed to the dialog. + */ +function openCertDownloadDialog(cert) { + let returnVals = Cc["@mozilla.org/hash-property-bag;1"].createInstance( + Ci.nsIWritablePropertyBag2 + ); + let win = window.openDialog( + "chrome://pippki/content/downloadcert.xhtml", + "", + "", + cert, + returnVals + ); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve([win, returnVals])); + }, + { once: true } + ); + }); +} + +add_task(async function setup() { + for (let testCase of TEST_CASES) { + testCase.cert = await readCertificate(testCase.certFilename, ",,"); + Assert.notEqual( + testCase.cert, + null, + `'${testCase.certFilename}' should have been read` + ); + } +}); + +// Test that the trust header message corresponds to the provided cert, and that +// the View Cert button launches the cert viewer for the provided cert. +add_task(async function testTrustHeaderAndViewCertButton() { + for (let testCase of TEST_CASES) { + let [win] = await openCertDownloadDialog(testCase.cert); + let expectedTrustHeaderString = + `Do you want to trust \u201C${testCase.expectedDisplayString}\u201D ` + + "for the following purposes?"; + Assert.equal( + win.document.getElementById("trustHeader").textContent, + expectedTrustHeaderString, + "Actual and expected trust header text should match for " + + `${testCase.certFilename}` + ); + + await BrowserTestUtils.closeWindow(win); + } +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(async function testAcceptDialogReturnValues() { + let [win, retVals] = await openCertDownloadDialog(TEST_CASES[0].cert); + win.document.getElementById("trustSSL").checked = true; + win.document.getElementById("trustEmail").checked = false; + info("Accepting dialog"); + win.document.getElementById("download_cert").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + retVals.get("importConfirmed"), + "Return value should signal user chose to import the cert" + ); + Assert.ok( + retVals.get("trustForSSL"), + "Return value should signal SSL trust checkbox was checked" + ); + Assert.ok( + !retVals.get("trustForEmail"), + "Return value should signal E-mail trust checkbox was unchecked" + ); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(async function testCancelDialogReturnValues() { + let [win, retVals] = await openCertDownloadDialog(TEST_CASES[0].cert); + info("Canceling dialog"); + win.document.getElementById("download_cert").cancelDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + !retVals.get("importConfirmed"), + "Return value should signal user chose not to import the cert" + ); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js b/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js new file mode 100644 index 0000000000..f4592ea9dc --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_editCACertTrust.js @@ -0,0 +1,140 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the UI for editing the trust of a CA certificate correctly +// reflects trust in the cert DB, and correctly updates trust in the cert DB +// when requested. + +var gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +/** + * The cert we're editing the trust of. + * @type nsIX509Cert + */ +var gCert; + +/** + * Opens the cert trust editing dialog. + * + * @returns {Promise} + * A promise that resolves when the dialog has finished loading with + * the window of the opened dialog. + */ +function openEditCertTrustDialog() { + let win = window.openDialog( + "chrome://pippki/content/editcacert.xhtml", + "", + "", + gCert + ); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve(win)); + }, + { once: true } + ); + }); +} + +add_task(async function setup() { + // Initially trust ca.pem for SSL but not e-mail. + gCert = await readCertificate("ca.pem", "CT,,"); + Assert.ok( + gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL + ), + "Sanity check: ca.pem should be trusted for SSL" + ); + Assert.ok( + !gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL + ), + "Sanity check: ca.pem should not be trusted for e-mail" + ); +}); + +// Tests the following: +// 1. The checkboxes correctly reflect the trust set in setup(). +// 2. Accepting the dialog after flipping some of the checkboxes results in the +// correct trust being set in the cert DB. +add_task(async function testAcceptDialog() { + let win = await openEditCertTrustDialog(); + + let sslCheckbox = win.document.getElementById("trustSSL"); + let emailCheckbox = win.document.getElementById("trustEmail"); + Assert.ok(sslCheckbox.checked, "Cert should be trusted for SSL in UI"); + Assert.ok( + !emailCheckbox.checked, + "Cert should not be trusted for e-mail in UI" + ); + + sslCheckbox.checked = false; + emailCheckbox.checked = true; + + info("Accepting dialog"); + win.document.getElementById("editCaCert").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + !gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL + ), + "Cert should no longer be trusted for SSL" + ); + Assert.ok( + gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL + ), + "Cert should now be trusted for e-mail" + ); +}); + +// Tests the following: +// 1. The checkboxes correctly reflect the trust set in testAcceptDialog(). +// 2. Canceling the dialog even after flipping the checkboxes doesn't result in +// a change of trust in the cert DB. +add_task(async function testCancelDialog() { + let win = await openEditCertTrustDialog(); + + let sslCheckbox = win.document.getElementById("trustSSL"); + let emailCheckbox = win.document.getElementById("trustEmail"); + Assert.ok(!sslCheckbox.checked, "Cert should not be trusted for SSL in UI"); + Assert.ok(emailCheckbox.checked, "Cert should be trusted for e-mail in UI"); + + sslCheckbox.checked = true; + emailCheckbox.checked = false; + + info("Canceling dialog"); + win.document.getElementById("editCaCert").cancelDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + !gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL + ), + "Cert should still not be trusted for SSL" + ); + Assert.ok( + gCertDB.isCertTrusted( + gCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL + ), + "Cert should still be trusted for e-mail" + ); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js b/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js new file mode 100644 index 0000000000..b36690be06 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_exportP12_passwordUI.js @@ -0,0 +1,163 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the UI for setting the password on a to be exported PKCS #12 file: +// 1. Correctly requires the password to be typed in twice as confirmation. +// 2. Calculates and displays the strength of said password. + +/** + * @typedef {TestCase} + * @type Object + * @property {String} name + * The name of the test case for display purposes. + * @property {String} password1 + * The password to enter into the first password textbox. + * @property {String} password2 + * The password to enter into the second password textbox. + * @property {String} strength + * The expected strength of the password in the range [0, 100]. + */ + +/** + * A list of test cases representing various inputs to the password textboxes. + * @type TestCase[] + */ +const TEST_CASES = [ + { name: "empty", password1: "", password2: "", strength: "0" }, + { name: "match-weak", password1: "foo", password2: "foo", strength: "10" }, + { + name: "match-medium", + password1: "foo123", + password2: "foo123", + strength: "60", + }, + { + name: "match-strong", + password1: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三", + password2: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三", + strength: "100", + }, + { name: "mismatch-weak", password1: "foo", password2: "bar", strength: "10" }, + { + name: "mismatch-medium", + password1: "foo123", + password2: "bar", + strength: "60", + }, + { + name: "mismatch-strong", + password1: "fooBARBAZ 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三", + password2: "bar", + strength: "100", + }, +]; + +/** + * Opens the dialog shown to set the password on a PKCS #12 file being exported. + * + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * an array consisting of: + * 1. The window of the opened dialog. + * 2. The return value nsIWritablePropertyBag2 passed to the dialog. + */ +function openSetP12PasswordDialog() { + let returnVals = Cc["@mozilla.org/hash-property-bag;1"].createInstance( + Ci.nsIWritablePropertyBag2 + ); + let win = window.openDialog( + "chrome://pippki/content/setp12password.xhtml", + "", + "", + returnVals + ); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve([win, returnVals])); + }, + { once: true } + ); + }); +} + +// Tests that the first password textbox is the element that is initially +// focused. +add_task(async function testFocus() { + let [win] = await openSetP12PasswordDialog(); + Assert.equal( + win.document.activeElement, + win.document.getElementById("pw1"), + "First password textbox should have focus" + ); + await BrowserTestUtils.closeWindow(win); +}); + +// Tests that the password strength algorithm used is reasonable, and that the +// Accept button is only enabled if the two passwords match. +add_task(async function testPasswordStrengthAndEquality() { + let [win] = await openSetP12PasswordDialog(); + let password1Textbox = win.document.getElementById("pw1"); + let password2Textbox = win.document.getElementById("pw2"); + let strengthProgressBar = win.document.getElementById("pwmeter"); + + for (let testCase of TEST_CASES) { + password1Textbox.value = testCase.password1; + password2Textbox.value = testCase.password2; + // Setting the value of the password textboxes via |.value| apparently + // doesn't cause the oninput handlers to be called, so we do it here. + password1Textbox.oninput(); + password2Textbox.oninput(); + + Assert.equal( + win.document.getElementById("setp12password").getButton("accept") + .disabled, + password1Textbox.value != password2Textbox.value, + "Actual and expected accept button disable state should " + + `match for ${testCase.name}` + ); + Assert.equal( + strengthProgressBar.value, + testCase.strength, + `Actual and expected strength value should match for ${testCase.name}` + ); + } + + await BrowserTestUtils.closeWindow(win); +}); + +// Test that the right values are returned when the dialog is accepted. +add_task(async function testAcceptDialogReturnValues() { + let [win, retVals] = await openSetP12PasswordDialog(); + const password = "fooBAR 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?一二三"; + win.document.getElementById("pw1").value = password; + win.document.getElementById("pw2").value = password; + info("Accepting dialog"); + win.document.getElementById("setp12password").acceptDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + retVals.get("confirmedPassword"), + "Return value should signal user confirmed a password" + ); + Assert.equal( + retVals.get("password"), + password, + "Actual and expected password should match" + ); +}); + +// Test that the right values are returned when the dialog is canceled. +add_task(async function testCancelDialogReturnValues() { + let [win, retVals] = await openSetP12PasswordDialog(); + info("Canceling dialog"); + win.document.getElementById("setp12password").cancelDialog(); + await BrowserTestUtils.windowClosed(win); + + Assert.ok( + !retVals.get("confirmedPassword"), + "Return value should signal user didn't confirm a password" + ); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js b/security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js new file mode 100644 index 0000000000..4c278d6c1b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/browser_loadPKCS11Module_ui.js @@ -0,0 +1,312 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the dialog used for loading PKCS #11 modules. + +const { MockRegistrar } = ChromeUtils.import( + "resource://testing-common/MockRegistrar.jsm" +); + +const gMockPKCS11ModuleDB = { + addModuleCallCount: 0, + expectedLibPath: "", + expectedModuleName: "", + throwOnAddModule: false, + + addModule(moduleName, libraryFullPath, cryptoMechanismFlags, cipherFlags) { + this.addModuleCallCount++; + Assert.equal( + moduleName, + this.expectedModuleName, + "addModule: Name given should be what's in the name textbox" + ); + Assert.equal( + libraryFullPath, + this.expectedLibPath, + "addModule: Path given should be what's in the path textbox" + ); + Assert.equal( + cryptoMechanismFlags, + 0, + "addModule: No crypto mechanism flags should be passed" + ); + Assert.equal(cipherFlags, 0, "addModule: No cipher flags should be passed"); + + if (this.throwOnAddModule) { + throw new Error(`addModule: Throwing exception`); + } + }, + + deleteModule(moduleName) { + Assert.ok(false, `deleteModule: should not be called`); + }, + + getInternal() { + throw new Error("not expecting getInternal() to be called"); + }, + + getInternalFIPS() { + throw new Error("not expecting getInternalFIPS() to be called"); + }, + + listModules() { + throw new Error("not expecting listModules() to be called"); + }, + + get canToggleFIPS() { + throw new Error("not expecting get canToggleFIPS() to be called"); + }, + + toggleFIPSMode() { + throw new Error("not expecting toggleFIPSMode() to be called"); + }, + + get isFIPSEnabled() { + throw new Error("not expecting get isFIPSEnabled() to be called"); + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPKCS11ModuleDB"]), +}; + +const gMockPromptService = { + alertCallCount: 0, + expectedText: "", + expectedWindow: null, + + alert(parent, dialogTitle, text) { + this.alertCallCount++; + Assert.equal( + parent, + this.expectedWindow, + "alert: Parent should be expected window" + ); + Assert.equal(dialogTitle, null, "alert: Title should be null"); + Assert.equal( + text, + this.expectedText, + "alert: Actual and expected text should match" + ); + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPromptService"]), +}; + +var gMockPKCS11CID = MockRegistrar.register( + "@mozilla.org/security/pkcs11moduledb;1", + gMockPKCS11ModuleDB +); +var gMockPromptServiceCID = MockRegistrar.register( + "@mozilla.org/embedcomp/prompt-service;1", + gMockPromptService +); + +var gMockFilePicker = SpecialPowers.MockFilePicker; +gMockFilePicker.init(window); + +var gTempFile = Services.dirsvc.get("TmpD", Ci.nsIFile); +gTempFile.append("browser_loadPKCS11Module_ui-fakeModule"); + +registerCleanupFunction(() => { + gMockFilePicker.cleanup(); + MockRegistrar.unregister(gMockPKCS11CID); + MockRegistrar.unregister(gMockPromptServiceCID); +}); + +function resetCallCounts() { + gMockPKCS11ModuleDB.addModuleCallCount = 0; + gMockPromptService.alertCallCount = 0; +} + +/** + * Opens the dialog shown to load a PKCS #11 module. + * + * @returns {Promise} + * A promise that resolves when the dialog has finished loading, with + * the window of the opened dialog. + */ +function openLoadModuleDialog() { + let win = window.openDialog( + "chrome://pippki/content/load_device.xhtml", + "", + "" + ); + return new Promise(resolve => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve(win)); + }, + { once: true } + ); + }); +} + +/** + * Presses the browse button and simulates interacting with the file picker that + * should be triggered. + * + * @param {window} win + * The dialog window. + * @param {Boolean} cancel + * If true, the file picker is canceled. If false, gTempFile is chosen in + * the file picker and the file picker is accepted. + */ +async function browseToTempFile(win, cancel) { + gMockFilePicker.showCallback = () => { + gMockFilePicker.setFiles([gTempFile]); + + if (cancel) { + info("MockFilePicker returning cancel"); + return Ci.nsIFilePicker.returnCancel; + } + + info("MockFilePicker returning OK"); + return Ci.nsIFilePicker.returnOK; + }; + + info("Pressing browse button"); + win.document.getElementById("browse").doCommand(); + await TestUtils.topicObserved("LoadPKCS11Module:FilePickHandled"); +} + +add_task(async function testBrowseButton() { + let win = await openLoadModuleDialog(); + let pathBox = win.document.getElementById("device_path"); + let originalPathBoxValue = "expected path if picker is canceled"; + pathBox.value = originalPathBoxValue; + + // Test what happens if the file picker is canceled. + await browseToTempFile(win, true); + Assert.equal( + pathBox.value, + originalPathBoxValue, + "Path shown should be unchanged due to canceled picker" + ); + + // Test what happens if the file picker is not canceled. + await browseToTempFile(win, false); + Assert.equal( + pathBox.value, + gTempFile.path, + "Path shown should be same as the one chosen in the file picker" + ); + + await BrowserTestUtils.closeWindow(win); +}); + +function testAddModuleHelper(win, throwOnAddModule) { + resetCallCounts(); + gMockPKCS11ModuleDB.expectedLibPath = gTempFile.path; + gMockPKCS11ModuleDB.expectedModuleName = "test module"; + gMockPKCS11ModuleDB.throwOnAddModule = throwOnAddModule; + + win.document.getElementById("device_name").value = + gMockPKCS11ModuleDB.expectedModuleName; + win.document.getElementById("device_path").value = + gMockPKCS11ModuleDB.expectedLibPath; + + info("Accepting dialog"); + win.document.getElementById("loaddevice").acceptDialog(); +} + +add_task(async function testAddModuleSuccess() { + let win = await openLoadModuleDialog(); + + testAddModuleHelper(win, false); + await BrowserTestUtils.windowClosed(win); + + Assert.equal( + gMockPKCS11ModuleDB.addModuleCallCount, + 1, + "addModule() should have been called once" + ); + Assert.equal( + gMockPromptService.alertCallCount, + 0, + "alert() should never have been called" + ); +}); + +add_task(async function testAddModuleFailure() { + let win = await openLoadModuleDialog(); + gMockPromptService.expectedText = "Unable to add module"; + gMockPromptService.expectedWindow = win; + + // The exception we throw in addModule is first reported as an uncaught + // exception by XPConnect before an exception is propagated to the actual + // caller. + expectUncaughtException(true); + + testAddModuleHelper(win, true); + expectUncaughtException(false); + // If adding a module fails, the dialog will not close. As such, we have to + // close the window ourselves. + await BrowserTestUtils.closeWindow(win); + + Assert.equal( + gMockPKCS11ModuleDB.addModuleCallCount, + 1, + "addModule() should have been called once" + ); + Assert.equal( + gMockPromptService.alertCallCount, + 1, + "alert() should have been called once" + ); +}); + +add_task(async function testCancel() { + let win = await openLoadModuleDialog(); + resetCallCounts(); + + info("Canceling dialog"); + win.document.getElementById("loaddevice").cancelDialog(); + + Assert.equal( + gMockPKCS11ModuleDB.addModuleCallCount, + 0, + "addModule() should never have been called" + ); + Assert.equal( + gMockPromptService.alertCallCount, + 0, + "alert() should never have been called" + ); + + await BrowserTestUtils.windowClosed(win); +}); + +async function testModuleNameHelper(moduleName, acceptButtonShouldBeDisabled) { + let win = await openLoadModuleDialog(); + resetCallCounts(); + + info(`Setting Module Name to '${moduleName}'`); + let moduleNameBox = win.document.getElementById("device_name"); + moduleNameBox.value = moduleName; + // this makes this not a great test, but it's the easiest way to simulate this + moduleNameBox.onchange(); + + let dialogNode = win.document.querySelector("dialog"); + Assert.equal( + dialogNode.getAttribute("buttondisabledaccept"), + acceptButtonShouldBeDisabled ? "true" : "", // it's a string + `dialog accept button should ${ + acceptButtonShouldBeDisabled ? "" : "not " + }be disabled` + ); + + return BrowserTestUtils.closeWindow(win); +} + +add_task(async function testEmptyModuleName() { + await testModuleNameHelper("", true); +}); + +add_task(async function testReservedModuleName() { + await testModuleNameHelper("Root Certs", true); +}); + +add_task(async function testAcceptableModuleName() { + await testModuleNameHelper("Some Module Name", false); +}); diff --git a/security/manager/ssl/tests/mochitest/browser/ca.pem b/security/manager/ssl/tests/mochitest/browser/ca.pem new file mode 100644 index 0000000000..48031d478c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUb2Np/S2xMtQR+BvitAuzKtjWxMswDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBPEDwwrdd6h+SHkc0J+p4Ik/yc +aoLWNdGsVD4hJYa0IOgNh6Z/GyhTXM9hr/q0f7fewjfNhXi/nrXNcW5w4FJERhHp +HvZO6Z08i8CrVYSiijFcLf6ClK4e163j0LXUutBWY2PCf4TDS+fnF9PJmle0kPLU +IxqptfSSoCjLuWyYyRmjZIdNCtrNCU9g85SDaUO6l79vBm0TYOLhOiPBN0F7DWXo +JlOZKWEco6qqS22yIM1r/5KNc5ekPTD+UJFh7qprAq0riEfR38DYJmUq3w07q5Tb +HQdG8JHEtemi7dHr/WoJY18MLZaF7BSLAwBWmBWzx8Lj2V+/4TP4NtRWkL7y +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ca.pem.certspec new file mode 100644 index 0000000000..6660f5d478 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem b/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem new file mode 100644 index 0000000000..698b70da88 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAfmgAwIBAgIUcepT9pQ4IQkGYiLxzM+rfwju1TYwDQYJKoZIhvcNAQEL +BQAwQTEoMCYGA1UEAwwfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEV +MBMGA1UECwwMSW50ZXJtZWRpYXRlMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCcxJTAjBgNVBAMMHGNsaWVudCBjZXJ0IHZpYSBpbnRlcm1lZGlh +dGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUA +A4IBAQAcVbcUEeT+hYt/z82f9Ut81G6QKtq5lr/1ifSkLqV6t7P5chDt7bpujsFw +ZI4jxHLZLL3M1znCSMBNseNRGWLW8cGlapOsO2KDNQdXbHcNJpLxETiWMRp/62Ii +jW2/rdp4wYekjp/lYy6qQDj85N2Zc+zimqz1ELIPHQyxGQUy5uQ78+sE/eLIR8A4 +XvYwyd1pIatfYHkc2pb8LeZAAtSQ9lFQ2sJiBMac2n68wAOj1Dq3AG9MdcBuGMsh +TiA7k4mdBiQywg8QG4GmXoP1j6QDJG0o5/8hIpbo95cmZ81Jye3TsZ8Sbmz3LR1J +6lOk2w1lAfxwCim2cMMZ44StOBsq +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem.certspec b/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem.certspec new file mode 100644 index 0000000000..cab2448889 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/client-cert-via-intermediate.pem.certspec @@ -0,0 +1,3 @@ +issuer:/CN=Temporary Certificate Authority/OU=Intermediate +subject:client cert via intermediate +extension:extKeyUsage:clientAuth diff --git a/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem b/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem new file mode 100644 index 0000000000..a9052d4611 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSDCCAjCgAwIBAgIUUZw/zP5GmSytJJWBwEzzqZzjcTYwDQYJKoZIhvcNAQEL +BQAwajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAw +MFowKzEpMCcGA1UEAwwgY2xpZW50IGNlcnQgd2l0aCBPQ1NQU2lnbmluZyBla3Uw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ +PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH +9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw +4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86 +exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0 +ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N +AgMBAAGjITAfMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDCTANBgkqhkiG +9w0BAQsFAAOCAQEAFuiPgjMg34f/TNocFSU4Qc3hPod0s0W7oH53wp8I3kJXsPGs +/P16w6YJ5dd5R9JZh6xBq63OnhFjS+j1Z6+NXalZrgSD2Q8FVNFS1z3P7bR+GSQ+ +r8ltlqkNV+Wu+Hk6TvfkrZhDX3VQ1IXtXXDQ0SuWLvczrPK3h+GCBE/LG1KybyBw +aHHl8aqXSd7eXcwJF5/hLQlaGZlHHxVh451WHrE1i8/kX+9GdyNwlAXMP9JySqei +YRwQPMa7MPDM5qkmFhlDh4+LWj8ugssv6n+6L5gFRNm6Db52aeNR17H2vezI7OUO +5u0gDZ8IG4XwS1u1IRPxNtK5ZT8uV+BqhOPmhg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem.certspec b/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem.certspec new file mode 100644 index 0000000000..5cbd5af8f0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/client-cert-with-ocsp-signing.pem.certspec @@ -0,0 +1,3 @@ +issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +subject:client cert with OCSPSigning eku +extension:extKeyUsage:clientAuth,OCSPSigning diff --git a/security/manager/ssl/tests/mochitest/browser/code-ee.pem b/security/manager/ssl/tests/mochitest/browser/code-ee.pem new file mode 100644 index 0000000000..2e5941318a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/code-ee.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyDCCAbCgAwIBAgIUUaEQHoacA0ankeJpt9iGsfyV7rYwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEjEQMA4GA1UEAwwHY29kZS1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMXMBUwEwYDVR0lBAwwCgYI +KwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAADhEW+xHUzkTkX1/RW4aODeW+NM +aSI20y3CtLtF2BDcl08YoCCnPVdbBG/DSbKb+eZecgvKWgHGOPKFRWA4YXm8TXXW +naVEWTDbbspVKjC6GzViuy2CsnNS5Bb5mhnGiMTI/zFvnfE+OwnfPFL+FAsLIaOm +OhyWU6/pwWN3hQytWHK6+QI22A58nVc/vLiyLMfWnn/8Akkolob3gFj0hOZaXYbn +mSSvBmWVTjq/7PfZLb/SD0VfGhbZMx7BebJGkUaikICS1w5F3bnM9ToRzkshhsBw +9nI7Kq8kff8PHBSaVWR36Ygix157D7bMiGuZ5ZLpXAayYcXhGQhhIZs2+lE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/code-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/code-ee.pem.certspec new file mode 100644 index 0000000000..93f9a84265 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/code-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:code-ee +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem new file mode 100644 index 0000000000..f4ff304c1c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwjCCAaqgAwIBAgIUa3NpO02kyKRl+mnC7LrTUIC0W8EwDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKZXhwaXJlZC1jYTAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAdMRswGQYDVQQDDBJlZS1mcm9tLWV4cGlyZWQtY2EwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT +2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV +JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8N +jf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCA +BiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh +He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMB +AAEwDQYJKoZIhvcNAQELBQADggEBAB7gNu/A0HmfIZQmKxaZno6txhlnzqU3jtCy +TwmiYWpqCJgjNHdKKaPDNTILaDtcPtdG55JqbIxbv3mpHfbiwy9XLSYT56V3/XJy +buMpUpXYTpsm+bXfU6aqsndiGwwuSSSrKP0MHi3R9hz/A+3hOqldu+a0d6zs4ByK +YSjAvQwORGgLf0cLRY0CIroiMttCC2x1whvwVl4jWsa3p0wciRstsIwHUxbhcGJC +R8bKFvK0VbNxcvyU3zwWwFnN+3ACBJT8ucI+MStFtR4oCILvvo0kL1O9C+tpWhEA +9b7J+h9WJVroYvfDIjvuYrdkeBhaQaSk0b1WvO+0ZGKGstLFC/c= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem.certspec new file mode 100644 index 0000000000..3e280fc4fc --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-expired-ca.pem.certspec @@ -0,0 +1,2 @@ +issuer:expired-ca +subject:ee-from-expired-ca diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem new file mode 100644 index 0000000000..890292763c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUd3uwPuHZt768G7dbGuv/MlnjS4YwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMdW50cnVzdGVkLWNhMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMB8xHTAbBgNVBAMMFGVlLWZyb20tdW50cnVzdGVkLWNh +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCE43NUMM7jR2Xic3/8RdN8axQxqqnA +YlRedr8BaEVDdiwneEG17EEGil1NU/a2DyBn6OC0I9Xx7NaB4ukYcJqheaczMHkG +1SvpddaNmjteAtdfc+vQ2ktvwvVAi+wQDtV23Bz5kgYvONRHhk2NgTb/HPrAyG3x +jg40Gi6wePb2vrzXQUxat88AEqh7BjCkeyJSXu/o56Pxo+TxHMX8QlZhaFT22Kj+ +J5u+WXEYygNdeTwDfIsyh0a6R/Eko+onzcT4JkNdFwI5u5bmoDQn1SjW1MBCmhJy +Css4M/wP5BY4RzgbKA2uDdVQ2M2xPg2IeGi3bS4qwlUNNPm1iOx8WlZK +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem.certspec new file mode 100644 index 0000000000..833e1a23a6 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ee-from-untrusted-ca.pem.certspec @@ -0,0 +1,2 @@ +issuer:untrusted-ca +subject:ee-from-untrusted-ca diff --git a/security/manager/ssl/tests/mochitest/browser/email-ee.pem b/security/manager/ssl/tests/mochitest/browser/email-ee.pem new file mode 100644 index 0000000000..eb51c01b1b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/email-ee.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUZcgkXcHN7EQAuaIttjnYPdQFvOIwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEzERMA8GA1UEAwwIZW1haWwtZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoG +CCsGAQUFBwMEMA0GCSqGSIb3DQEBCwUAA4IBAQBSMjBmd3FC9Q/AOByGmK8GhlFk +XhlBYmeVmxDJVDN0Z3OIcZUK1DWUl9M7hLJAUMbanng0jF98npAO1exDYx5ECyhV +SEe+KjfsQuPj7AS0zb60Uf/4w7b5dFW3y1pKo2ruEoPWvjLzR4IYfkc5p+utc1VT +0m568rEnF8dDGF19/FpsVjnzfwa8vmafXyXrogocOjk3qxRpx2wUqotbDwz6qDA1 +N/+LeE5+WHEgVDPF22BBECf/iPi1mUQQLURoUbQ499ELSZIRfIzI/MQUHBrF4Cx1 +TRnTDRhtzWvrcSaDBplLZzxTTWNhExwQUlg2rdFAPd9rdLuraimsLcly8xUC +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/email-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/email-ee.pem.certspec new file mode 100644 index 0000000000..82e3296706 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/email-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:email-ee +extension:extKeyUsage:emailProtection diff --git a/security/manager/ssl/tests/mochitest/browser/expired-ca.pem b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem new file mode 100644 index 0000000000..e019b37127 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUS6xUkMzG2REizII2g+VecO/KqX8wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDExMDEwMTAw +MDAwMFowFTETMBEGA1UEAwwKZXhwaXJlZC1jYTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABJdjrt25wocw4aP +eR1kZuu3WS0bKfuvhQQPFkAG+HYSC5eu0OriQCRlxn+qHY7du9dePcD6DTMDIVDW +r+oBJ9BwCEREyTcV8AEaHdcTAakXOMhq6OOltl6HUu3lSlqRslzAhtl1chM0P8m1 +Aj+ceOkCFHvnsDd+zcSP75u8zzJKypSWQwAg/i5S0BNLOWYarPiczuYi4HAOpwtX +QqlmDNMYySqPFfH72BuQdCLuviBXmMP8/kOouBNP4ti06RR88XgqfoL/jV4gkIM7 +92hXt0WpS/QffjWzLaej39YhW4pMZ+hF4bk9nUCtN/MHtg8WDj1CgfSJZegrl28W +3riMotA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/expired-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem.certspec new file mode 100644 index 0000000000..15bdcd7d73 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/expired-ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:expired-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +validity:20100101-20110101 diff --git a/security/manager/ssl/tests/mochitest/browser/has-cn.pem b/security/manager/ssl/tests/mochitest/browser/has-cn.pem new file mode 100644 index 0000000000..f334d5a887 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-cn.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAgIUXfOLVuh26E15Y2GJNpqg+kEUVBEwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowNzEMMAoGA1UEAwwDRm9vMQwwCgYDVQQLDANCYXIxDDAKBgNVBAoMA0Jh +ejELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAI8sysFQZh4G +EZKpcpOiGC0KLdbzkYAoALxjgvI+WPgOQBQBHSLGGTeIAe677xToSO6E/n9xocMh +62YRiZc5PGpUb+T7hinZ1pq+10SXN5ERZKJiKbDfp4iUStySiRs3OL0tNpnjtcVv +gIMZRcGr50vWBebe8fCRa/TFA3TilspiTjmRZCS6dUO7YHW8aMPWfG4gaSBF8E+6 +JCoK7YL1R/JxP4y7uAoU5+xfDBmC/vOUekUYZOH8w4Vs7dijC+weUU4zhe2L+QMb +OC1SyG1/MZ9Orzetz3tYGZ0shZTONn/wjAnzRrUGRUmAl+LVlW+Wxs1YL3TjKqTr +0QZaPOUVoms= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/has-cn.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-cn.pem.certspec new file mode 100644 index 0000000000..a4a0fcb5fa --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-cn.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/CN=Foo/OU=Bar/O=Baz/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem new file mode 100644 index 0000000000..e4cf5a14fd --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICijCCAXKgAwIBAgIBCjANBgkqhkiG9w0BAQsFADANMQswCQYDVQQDDAJjYTAi +GA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAAMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQAMkmx5NF2dju8/ckdgRK2M3fvoyEmBAYLOjWNh5ZfBX7VL +vL6bjzwcwza41feaDwgZbIWzzqKwVJhkOb9ULFMFlkEO0k2WhvTpEc/ELJnE1uCr +qKokl0b5BdllNGQQ9tSzhAwWumjfkhmVRZXziawWIiquA2UzowsdQX7Qf675Ae1e +B9WJvTxfxfSscON3xKAThOcMbjs5G9SaIp+C43qRJMn2KBsbu0qmWuMXG7Iy7Dbd +ak9CD2QG9tKDYOgjcvZRxdyErfjfIRoz3/4fiac7Ca6ooSc+TCF7va1yHNqhaYcH +VNTl7xyArMu5uPXtcLwEBudlJgPNuLy5A3HgChh4 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem.certspec new file mode 100644 index 0000000000..6346f7b83a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-empty-subject.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject: +serialNumber:10 diff --git a/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem new file mode 100644 index 0000000000..85bd93c62a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICqjCCAZKgAwIBAgIUQ1K/9yfCiqPsZYUo+7EBrddrWTowDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEBhMCVVMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAJXk +OiIktljwCkbDVVSyHlMX/kXOlzt4sVjWfL/YyFIaNVuiUpOYfEXlYFUc7nX8PXsL +a4RvATrJ90fUcGxHqWdqJr19zrWW5co+vjDNFMTFFltootym0fQocq55JvVUK9ml +BmZ+B60I82gI7L/M1NCPkylNvrG/UdD034pqY4ppgu6z/9lH6P6EpXZPseo6Ofx8 +tpSeTfYdtebvBbAkWmel56jzyN6C40ddIIjVHYKfLFgFsuavVhbwMm0AB1dFCnGQ +06x1QGsAthQ7C7q7mYtoe+TZ6sHahUofE4gNJyQprIyBn/Itae/H6qO6qBewoYWX +cBATil0Vqe2ZQ7FS5nk= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem.certspec new file mode 100644 index 0000000000..cc1b668a63 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-non-empty-subject.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/has-o.pem b/security/manager/ssl/tests/mochitest/browser/has-o.pem new file mode 100644 index 0000000000..9e4d7e3a28 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-o.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuDCCAaCgAwIBAgIUL+2cA4H9fH3BS4yDvSfNqAx+SDkwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGzEMMAoGA1UECgwDQmF6MQswCQYDVQQGEwJVUzCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEABlpU9dWi5TSGL0CISRugnOlpBATWlZbB2UYqN4H8n0R9mA28 +ss8F7+dzWq9yldVP5shpCqoHYbKgvcKwM7ki7l3QjaKvk4jqkxkp+0qw7LlNreFB +9xH86vn0zcu/9PUYVjAAS2B5pObLhf0RpdS9km026WpL11o298hbuR8sOeADAPwh +yqxrZz8i+ZCzBzwgNGGIwcgfpIRSQD+4rbpN5h2r3HmZupRuChA5rGR/z3xywD4J +/81ELM7raPXtq15RoUUc/dR4rIqgDwI8zOL4zndw5Eiuxmw79BnsW7ziXSgZw2rJ +vpxukd+42dBTnPEPHlFVZlnjn4zd97YwnuKXgw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/has-o.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-o.pem.certspec new file mode 100644 index 0000000000..f7cc3ffc73 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-o.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/O=Baz/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/has-ou.pem b/security/manager/ssl/tests/mochitest/browser/has-ou.pem new file mode 100644 index 0000000000..dfb8b2266b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-ou.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUB17J0zfbRaw+XdVWt9xzDjrY3o0wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowKTEMMAoGA1UECwwDQmFyMQwwCgYDVQQKDANCYXoxCzAJBgNVBAYTAlVT +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQB83qFAuJObc3l0cOKL6NW2krNxkt/X +ynRDZV1oVJ8Bw5vKb4PX8owP/answOwYsBK+Sy0g2+Y/JvhaI+PD/i/2MjwdP8qu +vRXKGbbtfgKqfBonwZl1/6BNNS65Mb0Z1VLdE1Ah79afpHamppD07O7cqA+Hw2qj +9mnoDoAiCBKDdKHDp+wLs7mUh8JSIOb0ZWkCqtED5l81KUB4T0bOI0HCuS15Zu+E +wWCGw0w3Un0W0l6sUVIE23J1exo6qJKk9gFWl3mOOZLOCT4Rgpvwyx13PpzU4JqS +vrxcuwwPKtEo7+smxl3DSpU/Vq0cuYbc2aS1xlCU2Vpl1VBNmao5KKAo +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/has-ou.pem.certspec b/security/manager/ssl/tests/mochitest/browser/has-ou.pem.certspec new file mode 100644 index 0000000000..8879dabf51 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/has-ou.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:/OU=Bar/O=Baz/C=US diff --git a/security/manager/ssl/tests/mochitest/browser/head.js b/security/manager/ssl/tests/mochitest/browser/head.js new file mode 100644 index 0000000000..af3c62ca43 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/head.js @@ -0,0 +1,83 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +var gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +/** + * List of certs imported via readCertificate(). Certs in this list are + * automatically deleted from the cert DB when a test including this head file + * finishes. + * @type nsIX509Cert[] + */ +var gImportedCerts = []; + +registerCleanupFunction(() => { + for (let cert of gImportedCerts) { + gCertDB.deleteCertificate(cert); + } +}); + +// This function serves the same purpose as the one defined in head_psm.js. +function pemToBase64(pem) { + return pem + .replace(/-----BEGIN CERTIFICATE-----/, "") + .replace(/-----END CERTIFICATE-----/, "") + .replace(/[\r\n]/g, ""); +} + +/** + * Given the filename of a certificate, returns a promise that will resolve with + * a handle to the certificate when that certificate has been read and imported + * with the given trust settings. + * + * Certs imported via this function will automatically be deleted from the cert + * DB once the calling test finishes. + * + * @param {String} filename + * The filename of the certificate (assumed to be in the same directory). + * @param {String} trustString + * A string describing how the certificate should be trusted (see + * `certutil -A --help`). + * @return {Promise} + * A promise that will resolve with a handle to the certificate. + */ +function readCertificate(filename, trustString) { + return OS.File.read(getTestFilePath(filename)).then( + data => { + let decoder = new TextDecoder(); + let pem = decoder.decode(data); + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let base64 = pemToBase64(pem); + certdb.addCertFromBase64(base64, trustString); + let cert = certdb.constructX509FromBase64(base64); + gImportedCerts.push(cert); + return cert; + }, + error => { + throw error; + } + ); +} + +/** + * Asynchronously opens the certificate manager. + * + * @return {Window} a handle on the opened certificate manager window + */ +async function openCertManager() { + let win = window.openDialog("chrome://pippki/content/certManager.xhtml"); + return new Promise((resolve, reject) => { + win.addEventListener( + "load", + function() { + executeSoon(() => resolve(win)); + }, + { once: true } + ); + }); +} diff --git a/security/manager/ssl/tests/mochitest/browser/intermediate.pem b/security/manager/ssl/tests/mochitest/browser/intermediate.pem new file mode 100644 index 0000000000..dd9c5ec6c5 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/intermediate.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIUf/ZI9pFYXbeWG/5AXJ9EJIgxBtcwDQYJKoZIhvcNAQEL +BQAwajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAw +MFowQTEoMCYGA1UEAwwfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEV +MBMGA1UECwwMSW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsG +A1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKO/vWs1AonZSTOAG+k2uA+HF +m6clrXdQxq3cbXG/bHT1c1lMNLu8p3HYojZq4S6394iNDFBKR/EV0RIdYRVW8NOJ +zfEFK4HIh6ReH5JBNbNqGGBbxBu1OR4UGXiTiKJh8VAPcuKhb01lAlkmmLWwE0em +rX3YaC7syGCQX/7Il3W8Kt4xvPjTkx8UX6+SiIezaw9thUAFvynaYK+1uw3/3W31 +ObPIQke9dKhth/3+87zrmiZI95CdCpWXzsL48OJseU53HpEnA3Du0CHQYLWrAS+T +fQIyV1qGMIXYRP0QW4eBVfVlKfACYZqRMOozR5AXIBp3ns5t3MXlyWS/0uAfJA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/intermediate.pem.certspec b/security/manager/ssl/tests/mochitest/browser/intermediate.pem.certspec new file mode 100644 index 0000000000..a562814041 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/intermediate.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +subject:/CN=Temporary Certificate Authority/OU=Intermediate +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/mochitest/browser/invalid.pem b/security/manager/ssl/tests/mochitest/browser/invalid.pem new file mode 100644 index 0000000000..dc8c0730fc --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/invalid.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwDCCAaigAwIBAgIUaXqQ23/rq8JrbOwIIDACtHsydH0wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEjEQMA4GA1UEAwwHaW52YWxpZDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMPMA0wCwYDVR0PBAQDAgEG +MA0GCSqGSIb3DQEBCwUAA4IBAQAUtQnvaYAoyfHVMIPYiEctg/dBhiqjp1ZYUbQO +nIuHETKtzTLUGJOSNFBIAaDcGHvJH7K4Ldp74+73EwDpGlK/wOQ4Of57pfNlYuCe +PQ9CGRKsEGSPsE6w9EstcbnEvqZJmKFY+YEJU936KqJOA052EMBnW3dy2sXwqyX5 +zzNKSC5+3gLGn2rk0Xa1CIyZpNSGLP5Q801iO7bXXkKG5rOV0FTfR1mu39vnu/RI +vO7BdLSbGPfdAv0io6aFLYw3kP5vSLFzUAoYHxrPokIoEM7pZtlSfECAXengcfis +L5WYqNQ3Y+XXf02VaRhEGnyL1MMmPGVpvBwWAJnR97YSfylx +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/invalid.pem.certspec b/security/manager/ssl/tests/mochitest/browser/invalid.pem.certspec new file mode 100644 index 0000000000..71a1707c35 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/invalid.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:invalid +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/mochitest/browser/longOID.pem b/security/manager/ssl/tests/mochitest/browser/longOID.pem new file mode 100644 index 0000000000..a966355b2d --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/longOID.pem @@ -0,0 +1,25 @@ +-----BEGIN CERTIFICATE----- +MIIESjCCAzKgAwIBAgIUUUlZgo9gztazitkyNqsantBeQO4wDQYJKoZIhvcNAQEL +BQAwEzERMA8GA1UEAwwITG9uZyBPSUQwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIy +MDIwNTAwMDAwMFowEzERMA8GA1UEAwwITG9uZyBPSUQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjggGQMIIBjDAM +BgNVHRMEBTADAQH/MIIBegYDVR0gBIIBcTCCAW0wggFpBoIBZSqD3OuTf4Pc65N/ +g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zr +k3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D +3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuT +f4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc +65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/ +g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zr +k3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D3OuTf4Pc65N/g9zrk3+D +3OuTf4Pc65N/ATANBgkqhkiG9w0BAQsFAAOCAQEAcsD8I4kt/jjepOgtZMI38IB5 +wRhrnfvGvPE7/1mWkQyz2tRRdbMOrhLrWzMHjZwQtwWmEeQczPVeXHEyt9Sz+v0/ +rghH+32VAPI6fDYzj9KNBn60sNiLCBlOucegpW/Dechcf25O/xhF6G9ljU2RIbpj +BAwTGd9gIYOpuAYGprht9d9smznPkO5qBpU7GV1SOzzhAldFYOMuYvjpgvtL7UXJ +2FhaWxyC11Sw1aUdm8V93Mf4rs8RzizjY/4pKyl6yRarNXx7lP6qf95fWi0A3LYT +3giV0e6NKrWjGLl1vnj8919wTzsh3OsVaAKDQNMz3I9/ENdDHMFl0WpAWjfQpg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/longOID.pem.certspec b/security/manager/ssl/tests/mochitest/browser/longOID.pem.certspec new file mode 100644 index 0000000000..c3c08ac84b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/longOID.pem.certspec @@ -0,0 +1,4 @@ +issuer:Long OID +subject:Long OID +extension:basicConstraints:cA, +extension:certificatePolicies:1.2.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.999999999.1 diff --git a/security/manager/ssl/tests/mochitest/browser/md5-ee.pem b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem new file mode 100644 index 0000000000..39fab2dbea --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrjCCAZagAwIBAgIUCR+2dzKgSt0CBU86EgRdJIa/72owDQYJKoZIhvcNAQEE +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowETEPMA0GA1UEAwwGbWQ1LWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEBBAUAA4IB +AQArfDtm5sEuzsPZps2oZhvrOYRViP0sRIAbAjuJVnAMA/7xLzI3LweXOlQJHBh3 +m3mrPUMAXfr4xJ5XjGySqHBUtFat9EBl/0bynd67sCMA7UOf51GC4ABOPAV0CkDj +/FNqL/KSt8WB90FW+ZKnt1ojKikMIjmPjxDaaHj7KZVBQ2KtBEz1Igt5Bvbrp2AM +NvjyhUCN4/z4NDPPbzkeDKYC7vmvYhN1Cs/73Jp3A0LU4z0gIyrWi6a7YEAVBzhI +vJJ98U8AQQMm+iiIDGZMoAZyvEFouofF9te4xMHStUnYfa1jLY93dL1TuXrWvKB0 +pWg4REoQuFZUE8GS/LczW5xX +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/md5-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem.certspec new file mode 100644 index 0000000000..279c158026 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/md5-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:md5-ee +signature:md5WithRSAEncryption diff --git a/security/manager/ssl/tests/mochitest/browser/moz.build b/security/manager/ssl/tests/mochitest/browser/moz.build new file mode 100644 index 0000000000..51ea96f9e2 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/moz.build @@ -0,0 +1,41 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +BROWSER_CHROME_MANIFESTS += ["browser.ini"] + +# Temporarily disabled. See bug 1256495. +# (Note that when this gets enabled, some extra work will have to happen so +# that the mochitest harness knows where to get the generated certificates - +# right now it assumes they're in the source directory, which isn't the case +# when they're automatically generated.) +# test_certificates = ( +# 'ca.pem', +# 'client-cert-via-intermediate.pem', +# 'client-cert-with-ocsp-signing.pem', +# 'code-ee.pem', +# 'ee-from-expired-ca.pem', +# 'ee-from-untrusted-ca.pem', +# 'email-ee.pem', +# 'expired-ca.pem', +# 'has-cn.pem', +# 'has-empty-subject.pem', +# 'has-non-empty-subject.pem', +# 'has-o.pem', +# 'has-ou.pem', +# 'intermediate.pem', +# 'invalid.pem', +# 'longOID.pem', +# 'md5-ee.pem', +# 'pgo-ca-all-usages.pem', +# 'pgo-ca-regular-usages.pem', +# 'revoked.pem', +# 'ssl-ee.pem', +# 'unknown-issuer.pem', +# 'untrusted-ca.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem b/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem new file mode 100644 index 0000000000..b67283580b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgzCCAmugAwIBAgIUCYMVPDJVUSkrLVxErDqoXsUuy2AwDQYJKoZIhvcNAQEL +BQAwajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAw +MFowajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQD +AgH+MA0GCSqGSIb3DQEBCwUAA4IBAQBXqqT2fBXtmQaPHr86unEVaXirLmnc9qR2 +yMhrBSbZP1w6MWQDD/TWXjnjqeADqXZy1feI/yBBQDnkJa1x4IVz5oujQDuf/chQ +vAemh7t7DhyfIZ+OQCMadSIOva06PhQuiwYXqM3Pg5MyBNp8NKP9fwSri39if4ru +4VgSudV5yo2Z/pduJMl2zFGsu+ZbYco0AKqN4RX7Rwkp7Uf7uiizgAPVEpCrm+Ja +EJUitKh1ejVH3SakdUfQEboQYsZl9c2S5/oKUlON4weoYctvc0zQkscRnqyuBkBJ +RB/YMKaHcphMRfmJFbwA5Vs0AOJ5E9u/hhvhcdBL6ZTUi3uEermS +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem.certspec b/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem.certspec new file mode 100644 index 0000000000..4def496f67 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/pgo-ca-all-usages.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +subject:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +extension:basicConstraints:cA, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem b/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem new file mode 100644 index 0000000000..c52d36d1bc --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgzCCAmugAwIBAgIUF5e1WSjUvqgAuz9/WyPcq+OgkOAwDQYJKoZIhvcNAQEL +BQAwajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAw +MFowajEoMCYGA1UEAxMfVGVtcG9yYXJ5IENlcnRpZmljYXRlIEF1dGhvcml0eTEY +MBYGA1UEChMPTW96aWxsYSBUZXN0aW5nMSQwIgYDVQQLExtQcm9maWxlIEd1aWRl +ZCBPcHRpbWl6YXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQD +AgEGMA0GCSqGSIb3DQEBCwUAA4IBAQA2+3qj2Bme+jVFlNva/gyvL0QOg8lgDc++ +pWTDd+NMpeqwarX6z4+wjzXh9ZPKk29alBWpnhVVvD4WAOa1TSLbevTlV+viGloP +uvZwoxn6naumwv992hJS8TJda8ZgKB5N5REdsDoD1hWeLevjWACMToSaXN+Bx8jF +GFoh1ifj1SD4DN51sc4KkKscjcSbBwyWJUCJGsDw7H5FtSSNEfGnctdsoLCWS84z +Jw/WUs/3hOB+MRsdqPBISlLrd5fnmL6RL7ZkDqad1Fi69GZQBDZUBmTxXhNl4VHK +RkQZCVLg9YWDzaKDj1Q326+sSur3PvQGJBplMEOWIOz/MVs2skeT +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem.certspec b/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem.certspec new file mode 100644 index 0000000000..448e167bd0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/pgo-ca-regular-usages.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +subject:printableString/CN=Temporary Certificate Authority/O=Mozilla Testing/OU=Profile Guided Optimization +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/mochitest/browser/revoked.pem b/security/manager/ssl/tests/mochitest/browser/revoked.pem new file mode 100644 index 0000000000..02c06872e1 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/revoked.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrzCCAZegAwIBAgIUJf4afZUeBhMdHovc6HjvffKmXJYwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEjEQMA4GA1UEAwwHcmV2b2tlZDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsFAAOC +AQEAKYqs7wd9/1ufx9s+YsRsd/MBRE/figWWVI+Gha3qLnx2NI7389n9qY8ES0az +bqNV71w8qYcn8tzlLCTLrgkhnt/rkMwXorvI+vfF+7fQeFlqFgXw46WxM4NtzLTz +0Hdt3+QULysZdG/my/HB1mcBWPRSrSZer7s1oKRcsoNgbSvmuyIWrrUVmn/tiaKy +kC5oOADLIoSHeGh4SvyUnP1oF3Aq5vxsykd66q/bP4MrmZinlJYNq/ybeEvrTEuA +XrBkRkslcVE6+VS/1ieT/5aa4IUyQ7DYy8i+IyspkD0xJ6cklSNodMl55odQK67Y +iC/MEn7uG9DJmwEH0ZN6Qxc3LA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/revoked.pem.certspec b/security/manager/ssl/tests/mochitest/browser/revoked.pem.certspec new file mode 100644 index 0000000000..daf75c670f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/revoked.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:revoked diff --git a/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem new file mode 100644 index 0000000000..aff528d39b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUU9i1j3V1LGw7IBlKgfVezTka1I0wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowETEPMA0GA1UEAwwGc3NsLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyEwHzAdBgNVHSUEFjAUBggr +BgEFBQcDAQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBACoLO/x/rat1m2td +0FMcOoXAJiTmHIIg22yC7RgFZxkSxnp8Wr2cevTUkBhwsITD6I7T6UTkqwnaXFBt +eeTxYuGoYx7VdefLNvAIdBKWZgtMvBr9+KHrhoFXOxL/+7oBFjFH0EP7B53aflJc +/rVf0CUb4iwS3ebjk5wOLZhB+sk3PfuzsdSOPjpUQZSmni/hI1d+Am1Kn0Qs0COI +0SPezVt7U5Gr0Ewc3eP2fI1I7YJbWKP/s5bd0C/aWW+tLBWxolYT3X4+S/7Bg52N +bCxwkd5GHJZkpA/M2++kiDQVfedMsN2E7IlsXILxckQsGlODJgrSbQb9vIYP1hGm +ryWS8kc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem.certspec b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem.certspec new file mode 100644 index 0000000000..c4037675f1 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/ssl-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ssl-ee +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem new file mode 100644 index 0000000000..ef4515983d --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuzCCAaOgAwIBAgIUI0xny6j77OiAn+msMVdsgBLMj/swDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHdW5rbm93bjAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAZMRcwFQYDVQQDDA51bmtub3duLWlzc3VlcjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs +9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8 +HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7Ak +kqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJet +lmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2r +kQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkq +hkiG9w0BAQsFAAOCAQEAP/jp5cJkeSP5DmAgvymt6zviEHmm24nHgHuLDwTPf446 +pCl4YGFSwzV44d6503AyFNOUbTg+l+2lOpG3CU3mDi+agcG+r4QEG3a01Mh9uWfB +I60VBHfQwq4yoA7gwnhUyf5dEOgwJkerc8uZMaoVv0OlRjp89ycqkmBjHpzRUR9A +6WzIKzA69foFI5b2UVMtUuXAZPyzPep2D35XNc1iSA4OsA5IhLJD7n7caQKoEiYv +i6A0Ze4ZgOHU/w7Aj+DUjq8JK85cdpUksCxAnPGannRhpK90/uc+d6IyovxjCdo1 +YQCfU6R3RXWPQmhHRxrQX6LMde5sxUADtW/GDutaAQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem.certspec b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem.certspec new file mode 100644 index 0000000000..c76a4e2c7b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/unknown-issuer.pem.certspec @@ -0,0 +1,2 @@ +issuer:unknown +subject:unknown-issuer diff --git a/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem new file mode 100644 index 0000000000..0be7744cc8 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUA0ih/Zea7LtjFynUOzwIwcOQCjkwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMdW50cnVzdGVkLWNhMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAb7HneKXYzHjB +ehF6bTye2hTACi84WqaW9c2K7KrqBa+zqR+/aF5pjRdlYoSOOiAKIWzHdJZYY0sh +fgoDFCCYuPg6Bim4AVthRxMDn07TDAkSxAV+M1P3bJLEeWx3/muTL0t98P/JXTS3 +GfmXjcWJ1E1bCMSrUclSk9Y6AKhyIOeapB0YovhvP8fWLso9RT7mv7W/xGmWohhP +bdjjislgWouFtOWBrata/u4ifS3hsBpYESXL9D2EzdoDtgzRG0yetCLmxTogfDqm +MeW75eQqQYiqU+VfnbvI46AvI9ihfXXzEfqVSzKkLwuYKiPa42QtU/sLNTbZeSqB +bR9mMRqyKQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem.certspec b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem.certspec new file mode 100644 index 0000000000..04f4430574 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/browser/untrusted-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:untrusted-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs new file mode 100644 index 0000000000..8e9afb098c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/alloworigin.sjs @@ -0,0 +1,6 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Access-Control-Allow-Origin", "*"); + response.write("hello!"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/backward.html b/security/manager/ssl/tests/mochitest/mixedcontent/backward.html new file mode 100644 index 0000000000..8699a07dda --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/backward.html @@ -0,0 +1,18 @@ + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/bug329869.js b/security/manager/ssl/tests/mochitest/mixedcontent/bug329869.js new file mode 100644 index 0000000000..9d67ba1f92 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/bug329869.js @@ -0,0 +1,11 @@ +/* import-globals-from mixedContentTest.js */ +"use strict"; + +document.open(); +// eslint-disable-next-line no-unsanitized/method +document.write("This is insecure XSS script " + document.cookie); +isSecurityState( + "broken", + "security broken after document write from unsecure script" +); +finish(); diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step2.html b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step2.html new file mode 100644 index 0000000000..4bbf9bfe8c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step2.html @@ -0,0 +1,28 @@ + + + + Bug 383369 test, step 2 + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html new file mode 100644 index 0000000000..276c2343fd --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/bug383369step3.html @@ -0,0 +1,29 @@ + + + + Bug 383369 test, final step + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/download.auto b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto new file mode 100644 index 0000000000..4d2fb7d5ae --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto @@ -0,0 +1 @@ +Temporary file for security/mixedconent tests \ No newline at end of file diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/download.auto^headers^ b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto^headers^ new file mode 100644 index 0000000000..9c3159e153 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/download.auto^headers^ @@ -0,0 +1,2 @@ +Content-disposition: "attachment" +Content-type: application/x-auto-download diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs new file mode 100644 index 0000000000..5cce2826f8 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 200, "OK"); + //response.setHeader("Content-type", "image/gif"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs new file mode 100644 index 0000000000..20d9dea829 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/hugebmp.sjs @@ -0,0 +1,13 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-type", "image/bitmap"); + + let bmpheader = "\x42\x4D\x36\x10\x0E\x00\x00\x00\x00\x00\x36\x00\x00\x00\x28\x00\x00\x00\x80\x02\x00\x00\xE0\x01\x00\x00\x01\x00\x18\x00\x00\x00\x00\x00\x00\x10\x0E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"; + let bmpdatapiece = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + + response.bodyOutputStream.write(bmpheader, 54); + // Fill 640*480*3 nulls + for (let i = 0; i < (640 * 480 * 3) / 64; ++i) + response.bodyOutputStream.write(bmpdatapiece, 64); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html new file mode 100644 index 0000000000..064783e0cb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html @@ -0,0 +1,14 @@ + + + + + + + This is frame 1: + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html b/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html new file mode 100644 index 0000000000..37fc604ea6 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframe2.html @@ -0,0 +1,15 @@ + + + + + + + This is frame 2: + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html new file mode 100644 index 0000000000..6c7a5473cb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframeMetaRedirect.html @@ -0,0 +1,8 @@ + + + + + Redirecting by meta tag... + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs new file mode 100644 index 0000000000..ea93b80b7d --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframesecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs new file mode 100644 index 0000000000..937e29954f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/iframeunsecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/iframe.html"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs new file mode 100644 index 0000000000..7af6116e10 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/imgsecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs new file mode 100644 index 0000000000..a8eb26642a --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/imgunsecredirect.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js new file mode 100644 index 0000000000..6c300b7fc3 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/mixedContentTest.js @@ -0,0 +1,211 @@ +"use strict"; + +/** + * Helper script for mixed content testing. It opens a new top-level window + * from a secure origin and '?runtest' query. That tells us to run the test + * body, function runTest(). Then we wait for call of finish(). On its first + * call it loads helper page 'backward.html' that immediately navigates + * back to the test secure test. This checks the bfcache. We got second call + * to onload and this time we call afterNavigationTest() function to let the + * test check security state after re-navigation back. Then we again wait for + * finish() call, that this time finishes completelly the test. + */ + +// Tells the framework if to load the test in an insecure page (http://) +var loadAsInsecure = false; +// Set true to bypass the navigation forward/back test +var bypassNavigationTest = false; +// Set true to do forward/back navigation over an http:// page, test state leaks +var navigateToInsecure = false; +// Open the test in two separate windows, test requests sharing among windows +var openTwoWindows = false; +// Override the name of the test page to load, useful e.g. to prevent load +// of images or other content before the test starts; this is actually +// a 'redirect' to a different test page. +var testPage = ""; +// Assign a function to this variable to have a clean up at the end +var testCleanUp = null; +// Contains mixed active content that needs to load to run the test +var hasMixedActiveContent = false; + +// Internal variables +var _windowCount = 0; + +window.onload = async function onLoad() { + if (location.search == "?runtest") { + try { + if (history.length == 1) { + // Each test that includes this helper file is supposed to define + // runTest(). See the top level comment. + await runTest(); // eslint-disable-line no-undef + } else { + // Each test that includes this helper file is supposed to define + // afterNavigationTest(). See the top level comment. + await afterNavigationTest(); // eslint-disable-line no-undef + } + } catch (ex) { + ok(false, "Exception thrown during test: " + ex); + finish(); + } + } else { + window.addEventListener("message", onMessageReceived); + + let secureTestLocation = loadAsInsecure + ? "http://example.com" + : "https://example.com"; + secureTestLocation += location.pathname; + if (testPage != "") { + let array = secureTestLocation.split("/"); + array.pop(); + array.push(testPage); + secureTestLocation = array.join("/"); + } + secureTestLocation += "?runtest"; + + if (hasMixedActiveContent) { + SpecialPowers.pushPrefEnv( + { set: [["security.mixed_content.block_active_content", false]] }, + null + ); + } + if (openTwoWindows) { + _windowCount = 2; + window.open(secureTestLocation, "_new1", ""); + window.open(secureTestLocation, "_new2", ""); + } else { + _windowCount = 1; + window.open(secureTestLocation); + } + } +}; + +function onMessageReceived(event) { + switch (event.data) { + // Indication of all test parts finish (from any of the frames) + case "done": + if (--_windowCount == 0) { + if (testCleanUp) { + testCleanUp(); + } + if (hasMixedActiveContent) { + SpecialPowers.popPrefEnv(null); + } + + SimpleTest.finish(); + } + break; + + // Any other message is an error or success message of a test. + default: + SimpleTest.ok(!event.data.match(/^FAILURE/), event.data); + break; + } +} + +function postMsg(message) { + opener.postMessage(message, "http://mochi.test:8888"); +} + +function finish() { + if (history.length == 1 && !bypassNavigationTest) { + window.setTimeout(() => { + window.location.assign( + navigateToInsecure + ? "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/backward.html" + : "https://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/backward.html" + ); + }, 0); + } else { + postMsg("done"); + window.close(); + } +} + +function ok(a, message) { + if (!a) { + postMsg("FAILURE: " + message); + } else { + postMsg(message); + } +} + +function is(a, b, message) { + if (a != b) { + postMsg(`FAILURE: ${message}, expected ${b} got ${a}`); + } else { + postMsg(`${message}, expected ${b} got ${a}`); + } +} + +async function isSecurityState(expectedState, message, test) { + if (!test) { + test = ok; + } + + let state = await SpecialPowers.getSecurityState(window); + + let isInsecure = + state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IS_INSECURE; + let isBroken = + state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IS_BROKEN; + let isEV = + state & SpecialPowers.Ci.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL; + + let gotState = "secure"; + if (isInsecure) { + gotState = "insecure"; + } else if (isBroken) { + gotState = "broken"; + } else if (isEV) { + gotState = "EV"; + } + + test( + gotState == expectedState, + (message || "") + ", expected " + expectedState + " got " + gotState + ); + + switch (expectedState) { + case "insecure": + test( + isInsecure && !isBroken && !isEV, + "for 'insecure' excpected flags [1,0,0], " + (message || "") + ); + break; + case "broken": + test( + !isInsecure && isBroken && !isEV, + "for 'broken' expected flags [0,1,0], " + (message || "") + ); + break; + case "secure": + test( + !isInsecure && !isBroken && !isEV, + "for 'secure' expected flags [0,0,0], " + (message || "") + ); + break; + case "EV": + test( + !isInsecure && !isBroken && isEV, + "for 'EV' expected flags [0,0,1], " + (message || "") + ); + break; + default: + throw new Error("Invalid isSecurityState state"); + } +} + +function waitForSecurityState(expectedState, callback) { + let roundsLeft = 200; // Wait for 20 seconds (=200*100ms) + let interval = window.setInterval(async () => { + await isSecurityState(expectedState, "", isok => { + if (isok) { + roundsLeft = 0; + } + }); + if (!roundsLeft--) { + window.clearInterval(interval); + callback(); + } + }, 100); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/mochitest.ini b/security/manager/ssl/tests/mochitest/mixedcontent/mochitest.ini new file mode 100644 index 0000000000..b63031004f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/mochitest.ini @@ -0,0 +1,65 @@ +[DEFAULT] +prefs = + security.mixed_content.upgrade_display_content=false +support-files = + alloworigin.sjs + backward.html + bug329869.js + bug383369step2.html + bug383369step3.html + download.auto + download.auto^headers^ + emptyimage.sjs + hugebmp.sjs + iframe.html + iframe2.html + iframeMetaRedirect.html + iframesecredirect.sjs + iframeunsecredirect.sjs + imgsecredirect.sjs + imgunsecredirect.sjs + mixedContentTest.js + moonsurface.jpg + nocontent.sjs + redirecttoemptyimage.sjs + somestyle.css + unsecureIframe.html + unsecurePictureDup.html + +[test_bug329869.html] +[test_bug383369.html] +skip-if = toolkit == 'android' +[test_bug455367.html] +[test_bug472986.html] +[test_bug477118.html] +[test_bug521461.html] +[test_cssBefore1.html] +[test_cssContent1.html] +[test_cssContent2.html] +[test_documentWrite1.html] +[test_documentWrite2.html] +[test_dynDelayedUnsecurePicture.html] +[test_dynDelayedUnsecureXHR.html] +[test_dynUnsecureBackground.html] +[test_dynUnsecureIframeRedirect.html] +[test_dynUnsecurePicture.html] +[test_dynUnsecurePicturePreload.html] +[test_dynUnsecureRedirect.html] +disabled=intermitently fails, quite often, bug 487402 +[test_innerHtmlDelayedUnsecurePicture.html] +[test_innerHtmlUnsecurePicture.html] +[test_javascriptPicture.html] +[test_secureAll.html] +[test_securePicture.html] +[test_unsecureBackground.html] +[test_unsecureCSS.html] +[test_unsecureIframe.html] +[test_unsecureIframe2.html] +[test_unsecureIframeMetaRedirect.html] +disabled=intermittently fails, less often, bug 487632 +[test_unsecureIframeRedirect.html] +[test_unsecurePicture.html] +[test_unsecurePictureDup.html] +[test_unsecurePictureInIframe.html] +[test_unsecureRedirect.html] +skip-if = verify && debug && (os == 'linux' || os == 'mac') diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg b/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg new file mode 100644 index 0000000000..c0ffca256a Binary files /dev/null and b/security/manager/ssl/tests/mochitest/mixedcontent/moonsurface.jpg differ diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/moz.build b/security/manager/ssl/tests/mochitest/mixedcontent/moz.build new file mode 100644 index 0000000000..7c990fbc62 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/moz.build @@ -0,0 +1,7 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +MOCHITEST_MANIFESTS += ["mochitest.ini"] diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs new file mode 100644 index 0000000000..53fa4bc0c2 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/nocontent.sjs @@ -0,0 +1,4 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 204, "No Content"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs b/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs new file mode 100644 index 0000000000..4d85e16581 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/redirecttoemptyimage.sjs @@ -0,0 +1,5 @@ +function handleRequest(request, response) +{ + response.setStatusLine(request.httpVersion, 307, "Moved temporarly"); + response.setHeader("Location", "http://example.com/tests/security/manager/ssl/tests/mochitest/mixedcontent/emptyimage.sjs"); +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css b/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css new file mode 100644 index 0000000000..9867e3c41e --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/somestyle.css @@ -0,0 +1,4 @@ +body +{ + background-color: lightBlue; +} diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html new file mode 100644 index 0000000000..ccb9a8d9cf --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug329869.html @@ -0,0 +1,36 @@ + + + + dymanic script load + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html new file mode 100644 index 0000000000..d45d5eb761 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug383369.html @@ -0,0 +1,92 @@ + + + + Bug 383369 test + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug455367.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug455367.html new file mode 100644 index 0000000000..d2ad64c454 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug455367.html @@ -0,0 +1,37 @@ + + + + No content image doesn't break security + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug472986.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug472986.html new file mode 100644 index 0000000000..bd55a600ca --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug472986.html @@ -0,0 +1,46 @@ + + + + img.src replace + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug477118.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug477118.html new file mode 100644 index 0000000000..90932790f0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug477118.html @@ -0,0 +1,34 @@ + + + + Bug 477118 + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_bug521461.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug521461.html new file mode 100644 index 0000000000..59085a5ec4 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_bug521461.html @@ -0,0 +1,39 @@ + + + + Bug 521461 + + + + + + + + + + + +This is an unsecure page! diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_cssBefore1.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssBefore1.html new file mode 100644 index 0000000000..98cee1bb53 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssBefore1.html @@ -0,0 +1,42 @@ + + + + CSS :before styling 1 + + + + + + + + + + + + + +

+ There is a moon surface left to this text +

+ + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent1.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent1.html new file mode 100644 index 0000000000..5c5019ca78 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent1.html @@ -0,0 +1,41 @@ + + + + CSS conent styling 1 + + + + + + + + + + + + + + +

+ + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent2.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent2.html new file mode 100644 index 0000000000..19e5784334 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_cssContent2.html @@ -0,0 +1,46 @@ + + + + CSS conent styling 2 + + + + + + + + + + + + +

+ + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite1.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite1.html new file mode 100644 index 0000000000..90eca5bcdb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite1.html @@ -0,0 +1,38 @@ + + + + document.write('<img src="http://">') + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite2.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite2.html new file mode 100644 index 0000000000..e009fd4f54 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_documentWrite2.html @@ -0,0 +1,40 @@ + + + + document.write('<iframe src="http://">') + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecurePicture.html new file mode 100644 index 0000000000..514902d047 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecurePicture.html @@ -0,0 +1,47 @@ + + + + img.src changes to unsecure test + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecureXHR.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecureXHR.html new file mode 100644 index 0000000000..d9a8cc8af7 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynDelayedUnsecureXHR.html @@ -0,0 +1,48 @@ + + + + unsecure XHR test + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureBackground.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureBackground.html new file mode 100644 index 0000000000..fd66b21a64 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureBackground.html @@ -0,0 +1,44 @@ + + + + body.background changes to unsecure test + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureIframeRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureIframeRedirect.html new file mode 100644 index 0000000000..8934de4b79 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureIframeRedirect.html @@ -0,0 +1,44 @@ + + + + iframe.src changes to unsecure redirect test + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicture.html new file mode 100644 index 0000000000..5ef5a28b2c --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicture.html @@ -0,0 +1,46 @@ + + + + img.src changes to unsecure test + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicturePreload.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicturePreload.html new file mode 100644 index 0000000000..d8506e8cc5 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecurePicturePreload.html @@ -0,0 +1,36 @@ + + + + img.src changes to unsecure test + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureRedirect.html new file mode 100644 index 0000000000..a73c7f8619 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_dynUnsecureRedirect.html @@ -0,0 +1,39 @@ + + + + img.src changes to unsecure redirect test + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlDelayedUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlDelayedUnsecurePicture.html new file mode 100644 index 0000000000..45bf140384 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlDelayedUnsecurePicture.html @@ -0,0 +1,42 @@ + + + + innerHTML changes to unsecure test + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlUnsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlUnsecurePicture.html new file mode 100644 index 0000000000..d8b3e5f6e0 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_innerHtmlUnsecurePicture.html @@ -0,0 +1,40 @@ + + + + innerHTML changes to unsecure test + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_javascriptPicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_javascriptPicture.html new file mode 100644 index 0000000000..66a28ce74e --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_javascriptPicture.html @@ -0,0 +1,34 @@ + + + + Secure img load + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_secureAll.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_secureAll.html new file mode 100644 index 0000000000..efd754dd58 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_secureAll.html @@ -0,0 +1,42 @@ + + + + All secure anti-regression check + + + + + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe2.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe2.html new file mode 100644 index 0000000000..8f49ecda51 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframe2.html @@ -0,0 +1,36 @@ + + + + Unsecure iframe load + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeMetaRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeMetaRedirect.html new file mode 100644 index 0000000000..4eebbf5b22 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeMetaRedirect.html @@ -0,0 +1,36 @@ + + + + Unsecure redirect iframe load + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeRedirect.html new file mode 100644 index 0000000000..12a4233494 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureIframeRedirect.html @@ -0,0 +1,36 @@ + + + + Unsecure redirect iframe load + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePicture.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePicture.html new file mode 100644 index 0000000000..3c19811db9 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePicture.html @@ -0,0 +1,34 @@ + + + + Unsecure img load + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureDup.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureDup.html new file mode 100644 index 0000000000..81ed58ffde --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureDup.html @@ -0,0 +1,20 @@ + + + + Unsecure img load in two windows + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureInIframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureInIframe.html new file mode 100644 index 0000000000..21bcf5f810 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecurePictureInIframe.html @@ -0,0 +1,36 @@ + + + + Unsecure img in iframe load + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureRedirect.html b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureRedirect.html new file mode 100644 index 0000000000..82611ff3fe --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/test_unsecureRedirect.html @@ -0,0 +1,36 @@ + + + + Redirect from secure to unsecure img + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html b/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html new file mode 100644 index 0000000000..2282677418 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/unsecureIframe.html @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/mixedcontent/unsecurePictureDup.html b/security/manager/ssl/tests/mochitest/mixedcontent/unsecurePictureDup.html new file mode 100644 index 0000000000..7ce3701620 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/mixedcontent/unsecurePictureDup.html @@ -0,0 +1,34 @@ + + + + Unsecure img load in two windows + + + + + + + + + + + + + + + diff --git a/security/manager/ssl/tests/mochitest/moz.build b/security/manager/ssl/tests/mochitest/moz.build new file mode 100644 index 0000000000..3b7f2ba585 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/moz.build @@ -0,0 +1,11 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +TEST_DIRS += [ + "browser", + "mixedcontent", + "stricttransportsecurity", +] diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini b/security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini new file mode 100644 index 0000000000..b2ce8fef00 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/chrome.ini @@ -0,0 +1,6 @@ +[DEFAULT] +tags = psm +skip-if = os == 'android' +support-files = page_blank.html + +[test_sts_privatebrowsing_perwindowpb.html] diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/mochitest.ini b/security/manager/ssl/tests/mochitest/stricttransportsecurity/mochitest.ini new file mode 100644 index 0000000000..7970639053 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/mochitest.ini @@ -0,0 +1,12 @@ +[DEFAULT] +tags = psm +support-files = + nosts_bootstrap.html + nosts_bootstrap.html^headers^ + plain_bootstrap.html + plain_bootstrap.html^headers^ + subdom_bootstrap.html + subdom_bootstrap.html^headers^ + verify.sjs + +[test_stricttransportsecurity.html] diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/moz.build b/security/manager/ssl/tests/mochitest/stricttransportsecurity/moz.build new file mode 100644 index 0000000000..28769dedc1 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/moz.build @@ -0,0 +1,9 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +MOCHITEST_MANIFESTS += ["mochitest.ini"] + +MOCHITEST_CHROME_MANIFESTS += ["chrome.ini"] diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html new file mode 100644 index 0000000000..e528a40abb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html @@ -0,0 +1,28 @@ + + + + + + STS test iframe + + + + + This frame was loaded using + + and set the STS header to force this site and allow subdomain upgrading. + + diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html^headers^ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html^headers^ new file mode 100644 index 0000000000..9e23c73b7f --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/nosts_bootstrap.html^headers^ @@ -0,0 +1 @@ +Cache-Control: no-cache diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html new file mode 100644 index 0000000000..db5d31a96b --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/page_blank.html @@ -0,0 +1,5 @@ + + + PAGE BLANK + + diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html new file mode 100644 index 0000000000..e528a40abb --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html @@ -0,0 +1,28 @@ + + + + + + STS test iframe + + + + + This frame was loaded using + + and set the STS header to force this site and allow subdomain upgrading. + + diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html^headers^ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html^headers^ new file mode 100644 index 0000000000..a46bf65bd9 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/plain_bootstrap.html^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-cache +Strict-Transport-Security: max-age=60 diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html new file mode 100644 index 0000000000..9fca3457e4 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html @@ -0,0 +1,28 @@ + + + + + + STS test iframe + + + + + This frame was loaded using + + and set the STS header to force this site and allow subdomain upgrading. + + diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html^headers^ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html^headers^ new file mode 100644 index 0000000000..e54fc6a1d5 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/subdom_bootstrap.html^headers^ @@ -0,0 +1,2 @@ +Cache-Control: no-cache +Strict-Transport-Security: max-age=60; includeSubDomains diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_stricttransportsecurity.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_stricttransportsecurity.html new file mode 100644 index 0000000000..040357d8b8 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_stricttransportsecurity.html @@ -0,0 +1,126 @@ + + + + + + opens additional content that should be converted to https + + + + + + + + This test will load some iframes and do some tests. + + + diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html new file mode 100644 index 0000000000..510b6f7435 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/test_sts_privatebrowsing_perwindowpb.html @@ -0,0 +1,268 @@ + + + + + + opens additional content that should be converted to https + + + + + + + + This test will load some iframes and do some tests. + + diff --git a/security/manager/ssl/tests/mochitest/stricttransportsecurity/verify.sjs b/security/manager/ssl/tests/mochitest/stricttransportsecurity/verify.sjs new file mode 100644 index 0000000000..e5e4eb5f67 --- /dev/null +++ b/security/manager/ssl/tests/mochitest/stricttransportsecurity/verify.sjs @@ -0,0 +1,47 @@ +/* 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/. */ + +// SJS file that serves un-cacheable responses for STS tests that postMessage +// to the parent saying whether or not they were loaded securely. + +function handleRequest(request, response) +{ + var query = {}; + request.queryString.split('&').forEach(function (val) { + var [name, value] = val.split('='); + query[name] = unescape(value); + }); + + response.setHeader("Cache-Control", "no-cache", false); + response.setHeader("Content-Type", "text/html", false); + + if ('id' in query) { + var outstr = [ + " ", + " subframe for STS", + " ", + " ", + " ", + " STS state verification frame loaded via", + " ", + " ", + " "].join("\n"); + response.write(outstr); + } else { + response.write("ERROR: no id provided"); + } +} diff --git a/security/manager/ssl/tests/moz.build b/security/manager/ssl/tests/moz.build new file mode 100644 index 0000000000..d39ca0ff17 --- /dev/null +++ b/security/manager/ssl/tests/moz.build @@ -0,0 +1,17 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +DIRS += ["unit"] + +TEST_DIRS += [ + "gtest", + "mochitest", +] + +XPCSHELL_TESTS_MANIFESTS += ["unit/xpcshell.ini"] + +if not CONFIG["MOZ_NO_SMART_CARDS"]: + XPCSHELL_TESTS_MANIFESTS += ["unit/xpcshell-smartcards.ini"] diff --git a/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem b/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem new file mode 100644 index 0000000000..9d8aae350d --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6DCCAdCgAwIBAgIUL/mOXLOH4zs7sAoXCffwl7mbFPMwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAmMSQwIgYDVQQDDBtFRSB3aXRoIGJhZCBzdWJqZWN0QWx0TmFt +ZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAGjHjAcMBoGA1UdEQQTMBGCDyouKi5leGFtcGxlLmNvbTANBgkqhkiG +9w0BAQsFAAOCAQEAnyhjk+PoHjlqMAOhxlX6+Xn7x5HXzVRmOYPSHlrKtaSDF2/y +Io1L/Ji7aMJ932MhaUNc83sFfHqGHLTHGhAe3icjuv745WdGsXzykAI+y4Z1gAH+ ++0yzUJsYlNmYgn+8kaYTTI9P+HIRoqYPZ2YqshwNNSxdXnSs1jDYCg3yDsKX6DO6 +5vTET9ef5Ea6ePYZiGbwyvYA6lGz1JorrnZPD8uiQnx8CSa20YywYeZH0UGc8Jd+ +G/xRGd+T0eRMy4Xsvv4kZyiAQFPVRsYCDhrgpkeiYsWwlrgZ/LTZN7muBwsPPyy3 +fM2Y6VfVJhEjyv/nv8C44PnKaYYSK7ZWU+dpkw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem.certspec new file mode 100644 index 0000000000..1b368c26f1 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/badSubjectAltNames.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:EE with bad subjectAltNames +extension:subjectAlternativeName:*.*.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem b/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem new file mode 100644 index 0000000000..9faffde6d6 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDKzCCAhOgAwIBAgIUPU/rVUoMybyCeEAWx++fMAuZ6k0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8xOTQ2MDIxNDAwMDAwMFoYDzIwMzEw +MTAxMDAwMDAwWjAsMSowKAYDVQQDDCFCZWZvcmUgVU5JWCBFcG9jaCBUZXN0IEVu +ZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W +1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtq +ZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx +0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthV +t2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo +4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx +1QOs2hgKNe2NAgMBAAGjWzBZMCMGA1UdEQQcMBqCGGJlZm9yZS1lcG9jaC5leGFt +cGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2Nh +bGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQADggEBALocgfctX/9NDtkQ7zAkGl14 +UXkXBCq7vn5fKss2bCG7D6M/+Q4ZJ64/QXGK96tKqdJctiyIN3KArnk4/pWfYCQG +DgIHXFAgbKUQU0uiGmPwbPQnYq8la6VEarMrzWnGhqVPG1wsqiO1cnecycvm2W7W +9n7qvw3s2Gf0WZIQKqpNmuhouboeiK1xFxryLWiNaG087WPHb71e1C+1enVb/hJN +E1KD7dBtBh0sOC6bOFdc4BzhDHnDzPSznSqouotHf5U8YniKoPcDCml544msKwP8 +LCj3tG1VdMxL+p83ETDHG6GLUY20R0E6WJJfvfZ3hdxRUKgaAs+diT3xYXXYqTA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem.certspec new file mode 100644 index 0000000000..ac97b2231a --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpoch.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Before UNIX Epoch Test End-entity +validity:19460214-20310101 +extension:subjectAlternativeName:before-epoch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem b/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem new file mode 100644 index 0000000000..6cdfa86a25 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7zCCAdegAwIBAgIUL5tQyA2FR4V3eMcfGyWTxS4vmp0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8xOTQ2MDIxNDAwMDAwMFoYDzIwMzEw +MTAxMDAwMDAwWjAuMSwwKgYDVQQDDCNCZWZvcmUgVU5JWCBFcG9jaCBUZXN0IElu +dGVybWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahE +jhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1 +a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1p +GrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW +2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcO +p2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJR +xDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYw +DQYJKoZIhvcNAQELBQADggEBAGDlMbdxc1BHrn6l1svyskkHx68lSeTGVucIpClu +mJIT3rsTR5swYuyvrWe/gqkVqGRv2gIpMUYAJoHWjF4fRyWkIjJz5JnSP5qxFKKk +NFrjXFpGSqxJGtuMUNNGk7P30RLje5aE00bqrZHokfrokzChC3G3QJPOwvJtP1Gk +wldQ8AeoHu/u3oEB3caoC1QpFfgF5kunNETSIxX5bTmsjTSSJnJjnf46FQdbOWUh +P5Qkr6ZNK4ZAOIm+PRRyJ44JiHab+up/cEs17/T5dNcnHCy4TYXquNKwOe35qakm +iexwhKycaAEM0TcTI1OA5K4tCwFvaiOr4eTzxN28Cemd89E= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem.certspec new file mode 100644 index 0000000000..835e63f2b6 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpochINT.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Before UNIX Epoch Test Intermediate +validity:19460214-20310101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem b/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem new file mode 100644 index 0000000000..070de1796b --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWjCCAkKgAwIBAgIUVV34jakVUF6D+5QkiXJ1kemF5q0wDQYJKoZIhvcNAQEL +BQAwLjEsMCoGA1UEAwwjQmVmb3JlIFVOSVggRXBvY2ggVGVzdCBJbnRlcm1lZGlh +dGUwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowODE2MDQGA1UE +AwwtVGVzdCBFbmQtZW50aXR5IHdpdGggQmVmb3JlIFVOSVggRXBvY2ggaXNzdWVy +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABo2IwYDAqBgNVHREEIzAhgh9iZWZvcmUtZXBvY2gtaXNzdWVyLmV4YW1w +bGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2Fs +aG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAhJFzxTYfWOkyMlXOowz7kFnK +ChekuiwNJB3r0ZGwExAXmrdPKCfBz+OKsPM+3i+bNzIlJNrI2ZhKzylsAJ1mIeRF +vvpviu5NeZ0TgT7Man5n7WSBylFgSiKymk6V529k0ZrCvVxU1BZK0kXbqYZmGVDt +TOtkHEKP1YkNnjOs7pYZ7bslkH94oWbT2Cd+W3362o/ko6CCmkhaj2WAqSRyVEUy ++qdQndSpyvp85tRFZLb8bQkCqTtOVCLQfLHYWXRQ4qZQWy8kFPA7OpCMdXlR6Bwu +vyYi9dw5cRXwAdbLzMpVouPBBXLbTT2b+R+vW5L/LoNGTgrnL+K8WshCSYZ+YQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem.certspec new file mode 100644 index 0000000000..9aabe21628 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/beforeEpochIssuer.pem.certspec @@ -0,0 +1,4 @@ +issuer:Before UNIX Epoch Test Intermediate +subject:Test End-entity with Before UNIX Epoch issuer +extension:subjectAlternativeName:before-epoch-issuer.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem b/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem new file mode 100644 index 0000000000..3fffeaf56f --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRTCCAi2gAwIBAgIUF4tSVpnzLjrUBoa9WMfShlqrEjwwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAvMS0wKwYDVQQDDCRUZXN0IEludGVybWVkaWF0ZSB1c2VkIGFz +IEVuZC1FbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjcjBwMAwGA1UdEwQFMAMBAf8wMgYIKwYBBQUHAQEE +JjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMCwGA1UdEQQl +MCOCIWNhLXVzZWQtYXMtZW5kLWVudGl0eS5leGFtcGxlLmNvbTANBgkqhkiG9w0B +AQsFAAOCAQEAllsGy7B4yROdLH5rmLV6Q6AxUMKk/ixwfCnkt3ibKGtoypvAG6wn +vevqezN7BUeqIZd0QeoZBEtKwxv87oCiVDgSPXhkGqxryN9i8Zii07Sa27rCVZHd +F/AJv7qSgl2mYPYAAcyDX5F5ecbc3i9tc96mYSUJawhgPCwNB6PGB+HUr5fSskzx +j7Rg+0k9TEpk5bcTlsqH2hFvM9ZycEFC0/9trBVvnvh51WTHX/AzZDaaHPyOd2jD +RxqCMwde0EfpNQmpz39WnRJqs7bf2Cdc080m/apFL9yjZOuCfNaWdezfNjWoBKNC +S5tpZOoqNYzdV/8VAy74Nv+cXGNX4Ct7RA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem.certspec new file mode 100644 index 0000000000..8e16705b50 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ca-used-as-end-entity.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate used as End-Entity +extension:basicConstraints:cA, +extension:authorityInformationAccess:http://localhost:8888/ +extension:subjectAlternativeName:ca-used-as-end-entity.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/default-ee.key b/security/manager/ssl/tests/unit/bad_certs/default-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/bad_certs/default-ee.key.keyspec b/security/manager/ssl/tests/unit/bad_certs/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/bad_certs/default-ee.pem b/security/manager/ssl/tests/unit/bad_certs/default-ee.pem new file mode 100644 index 0000000000..c85c051004 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/default-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUUwG2e1zCLPYPQc2aSZ4UsI/GiK0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcow +gccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tghUqLnBp +bm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu +ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCbcbjTQmzRu++LJ/R1KjA99THZ +aRGG7u0knPs40bz+rIOAR7SllYTvZ1g5HanNG3GZ5+DExVmVtixcrqJFTV0BJsi0 +rv8XR4F3Cdict+rJ+hCSBqu6BGNWdptsaSPiSm+eL//tgjGY1zm9ln1B/OvTYA/n +f+OV07v44pwRBUe8C9Awb2J3KMHATPciKTk0Pwmh0jXi4FN9ehG1rXZMY2daHoKq +hzbBc8EaGzPPAyFumHd6wNqWX+/chEtT00SlcJw/lbQZnK8XvUSOhRuUeRdCM5wX +3w+Gy4P/FrI5tePoR9606GR6plC8QZxT3+Z6lTyCHz3I05+PNXwfmZH3ABSg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/default-ee.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/default-ee.pem.certspec new file mode 100644 index 0000000000..554339ff52 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/default-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test End-entity +extension:subjectAlternativeName:localhost,*.example.com,*.pinning.example.com,*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem b/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem new file mode 100644 index 0000000000..3ea3efa405 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIUN/wGbPUAtIu5Cd7Ojx955mKb5Y0wDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUTWlzc2luZyBJbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgw +MDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowJzElMCMGA1UEAwwcZWUtZnJvbS1taXNz +aW5nLWludGVybWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG +8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V +gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3 +04hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l +0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz +/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMnMCUwIwYDVR0RBBwwGoIJbG9jYWxob3N0 +gg0qLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAmRFIXGwnArqj8ekdT +bg+l3r5pkovY9UJpm5hdAvgKuTuFE3fvrfNt+TaftS90i/OlF9LcyIMzWehiJa3O +axNeKptICjkcX6U6hF+4qvBxCpw3pD+SAsRgWugNzdFdytUxjX5cEnWMFq2MXSNc +FRpzVJvspN/NdfoF8HYvnYszH4ReKaKF7uZKUVhu0MZ1+zSZBU9ajOyZ+Zo+AIdL +Hhq3XsTxGcKwjEQZGaRoyKQe6bBxfejISetjsSsW+ZpFQsA1S+oUaIhHR1FzIMiG +qyEhll/97Ub1PU3u/XNVBUcNETdHO+HERPpHkQPS8pNdZSzPR9aLY/te7iEv634D +L4J2 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem.certspec new file mode 100644 index 0000000000..48bb1c6e4a --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ee-from-missing-intermediate.pem.certspec @@ -0,0 +1,3 @@ +issuer:Missing Intermediate +subject:ee-from-missing-intermediate +extension:subjectAlternativeName:localhost,*.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem b/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem new file mode 100644 index 0000000000..e47d2c7c6f --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIUIeBfVf/r/GMhsN7xxnsSiVo7hQswDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjArMSkwJwYDVQQDEyBJbW1pbmVudGx5IERpc3RydXN0ZWQgRW5k +IEVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaNvMG0wNwYDVR0RBDAwLoIJbG9jYWxob3N0giFpbW1pbmVu +dGx5LWRpc3RydXN0ZWQuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsG +AQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IB +AQCmalWWhf0TDhN3e7UAbXC4mrg766FnGqrGsmbL2wm0q4IuzF9Xc4x26Y2mFaWg +tkyv0W5YCpSwwbCI2wL6h2iWBZgz55APndydlwCDO5zrDWMx0tlaVSG6ZJiafQFk +G3Mjky9dzmBMgAsS1L4y+rpP0Wla6WYxjtXmMOMEfLuOOhEK/8CjYru4bWSLKHxL +baBhvXM3bMbFl/G3c6AAcLMwi+jau3NCZEXORFAoeoxskAIlyfRaqGatXcO19AZp +5zURdW4WYMVM1DwuUTdKLR/I17xYuTnXdO9qOW6jUssGrspEpg+5Ruec0Q6kJsx3 +ZSJwMRGt69Y0hEGHDzjE3uwZ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem.certspec new file mode 100644 index 0000000000..dd8c6707ce --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ee-imminently-distrusted.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:printableString/CN=Imminently Distrusted End Entity +extension:subjectAlternativeName:localhost,imminently-distrusted.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem new file mode 100644 index 0000000000..d11edd2ca8 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJTCCAg2gAwIBAgIUY5v46X4dh8IilHQNDrSwO5u+Og4wDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMB4xHDAaBgNVBAMME0VFIElzc3VlZCBieSBub24t +Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAGjWzBZMCMGA1UdEQQcMBqCCWxvY2FsaG9zdIINKi5leGFtcGxlLmNv +bTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6 +ODg4OC8wDQYJKoZIhvcNAQELBQADggEBACbMjO/TTypmr3K1qgJHG4YVBzfXrj/u +eARxTnPhbHivqP/e1wgVyHHhp/5QMBooXN9sykYwA22ZyzXRGYIXpsvfW/gx6fBT +VVPNF5F6vt+FVtJEUZ4x101cArcWsizao5dRua1t3mE8tGiju+FIDZksF0m/UAQu +JoNexlBnG2ooLZ8j+vwzLuo74K/VzVDktNPcNRnaF0TAaS078OYgmZfKHvkF/13z +lyW5vCzqZLDMNnoszP95n4X9EjI+xo4kp+WfRz6c/bq6bQZdtRZAUo4vZSwxYnDm ++tH+r13KhZGekLczAgxK510RJrykZY+XrpZSBpGesSPzlwe8Ne+nkfI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem.certspec new file mode 100644 index 0000000000..63c36d34b3 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByNonCA.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test End-entity +subject:EE Issued by non-CA +extension:subjectAlternativeName:localhost,*.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem new file mode 100644 index 0000000000..0045add98f --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6jCCAdKgAwIBAgIUf83/oBwb560grMAqpqiLeF/len4wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVjEgQ2VydDAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAfMR0wGwYDVQQDDBRFRSBJc3N1ZWQgYnkgVjEgQ2VydDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaMnMCUwIwYDVR0RBBwwGoIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tMA0GCSqG +SIb3DQEBCwUAA4IBAQCzt3ZusWZ/JxpErDDTk0/Y3DHseHv+7h4UY/wkMyGycn26 +qEDxDcAR2Xkj5b72DXt/et94b+BT0zd1lq8FFfjL29tSIdSsu+7fwO+lN8JMqGjT +6F4u2BTjgvpAgoO7Zg9fqblE+r0YNOxlXL0EqDzsFFrz/u6PgsBWdKgEY6nWVFzg +Pay4REzvXrJMIs0UA8mGgN6Bd9kYA7wGatLU7sa0AWtYppaTk1E+e7F2R4K26JEk +Zo1BXuSITiYB8GKYyQU9q6HyVm38hq1TCzd8lewuLeLuTh69u7vvnMvIjeN+bjSz +ExfzO3SZQeTHibGLf7oH2e72Fi+MN1OyTu0C6b2F +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem.certspec new file mode 100644 index 0000000000..9ed9b33db7 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/eeIssuedByV1Cert.pem.certspec @@ -0,0 +1,3 @@ +issuer:V1 Cert +subject:EE Issued by V1 Cert +extension:subjectAlternativeName:localhost,*.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem b/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem new file mode 100644 index 0000000000..b42f270d1b --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6TCCAdGgAwIBAgIUVQ7hP4Gor8gwKkSGLxvowMGx/BswDQYJKoZIhvcNAQEL +BQAwADAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAtMSswKQYD +VQQDDCJFbmQgZW50aXR5IHNpZ25lZCBieSBlbXB0eSBuYW1lIENBMIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVK +tOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7N +Q/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39Zgsr +sCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxs +l62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYl +nauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyow +KDAmBgNVHREEHzAdghtlbXB0eWlzc3Vlcm5hbWUuZXhhbXBsZS5jb20wDQYJKoZI +hvcNAQELBQADggEBAC8PShkXwq0NGcZQ5nsyWwQDW0mRVL8lOyTU8O9GhHNSlwzs +zhh1QgRmksWIXuxctIODYUlxLnQSCkUVMJjUNpXkZcnmxcgrazC+dfx9B49TQm8a +9bvjlmZwWGtXi4fuI+mn0447GSOOBTjo5d7rHuwMZM+tZRNifXdBxFi6458xmFbP +73+IxRc3Yl5jcCmlN+yb5D1elR9oeH2Sn6MrmNr9OEEWumTXb5Wqzb5D1gxNMV/Y +V0h+u8QLgG3w1KJGL6u/Ahr2KnkfMMq2VuTvJ5wtjSMnA/9UJH1icJ+Ij9grvuZn +4LbHY07qNnSr50j0Lki4rM/vrI23/T56QKwYndM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem.certspec new file mode 100644 index 0000000000..a99d84b79e --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/emptyIssuerName.pem.certspec @@ -0,0 +1,3 @@ +issuer: +subject:End entity signed by empty name CA +extension:subjectAlternativeName:emptyissuername.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem b/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem new file mode 100644 index 0000000000..848e776155 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwTCCAamgAwIBAgIUVYzw/kKPlc6jC3ssIBL3rywd/VQwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR +qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv +WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+ +rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv +JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5 +Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6 +clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB +BjANBgkqhkiG9w0BAQsFAAOCAQEAl6tTwSFSaEMVA8N+h/pQuCF+yG7XKBJKgETn +y5fYobUbYrT5IOhxLotk/DmXTrNRwY7dycRz+zcbWCLypfpKK45XDHe9OXlMa5SE +RoR++XrS6Q3xSK/Sg1LFZPcc5crNwKGWYTg+1ec4pwN71fKxi0Dk+y2UiJ6MMc1m +z8o46kqOVQj1Ct4PiHsHQffKKAFPFnU4S49mOK8oEpn42YPMylfDd+xaSS5NEw1R +SwUceewlaEOzfO1V6RK1EGNtfLqS4A2PHIDOtTvD6E8EMi1MLIvnXEIpduOuk0zQ +zmC/1+oG/sadO27BdGLFkCLBQu+TYQ+j4B1n53lEV00vJ599xw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem.certspec new file mode 100644 index 0000000000..0a7cfdfd84 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/emptyNameCA.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject: +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem b/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem new file mode 100644 index 0000000000..2c2e5da70c --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDOzCCAiOgAwIBAgIUL6Ownjd7KeqXI1vuKoBnuMLqzpswDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMB8xHTAbBgNVBAMMFGV2LXRlc3QtaW50ZXJtZWRpYXRlMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +o3kwdzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBHBggrBgEFBQcBAQQ7MDkw +NwYIKwYBBQUHMAGGK2h0dHA6Ly9sb2NhbGhvc3Q6ODg4OC9ldi10ZXN0LWludGVy +bWVkaWF0ZS8wEQYDVR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEBCwUAA4IBAQAJ +gL0sq/Ak2xI3iYXPHg9ECQVPlnKRM09u7Ykj2ehg6INT9vf4XJ9Dyj8BWt0B3qtY +y29bUl7SREVCuMgNWRu6OiflmVuwccJkNm7fYRrq9dto3sYTU1VPANq7jJ7J6S9X +7kizD5UgV664WfA61uSfXdTb1z8NKCbQv3bO4v4mXeAPe1i2GTHN0fk1wpex1ETp +XqaIgVULkgdl8wIPXXhbGXugogc1uXytcVPxLAqfH329qPQnSW3S71jMqGE2HxzL +5oIbWqHJJba8YkDjk8/KC9cyk08bA5OXJ4IPxxRJfQ4+q4EPjXpKKhXdfMjsgryX +wMwN88kEWkSl+VVy4uWk +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem.certspec new file mode 100644 index 0000000000..d5b5859672 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ev-test-intermediate.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:ev-test-intermediate +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://localhost:8888/ev-test-intermediate/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/bad_certs/ev-test.pem b/security/manager/ssl/tests/unit/bad_certs/ev-test.pem new file mode 100644 index 0000000000..36a96ce2ba --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ev-test.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQjCCAiqgAwIBAgIUQyrN+2RfvyLlvHscTU0HNQdN9O0wDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUZXYtdGVzdC1pbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgw +MDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowEjEQMA4GA1UEAwwHZXYtdGVzdDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaN/MH0wOgYIKwYBBQUHAQEELjAsMCoGCCsGAQUFBzABhh5odHRwOi8vbG9jYWxo +b3N0Ojg4ODgvZXYtdGVzdC8wHwYDVR0gBBgwFjAUBhIrBgEEAetJhRqFGoUaAYN0 +CQEwHgYDVR0RBBcwFYITZXYtdGVzdC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsF +AAOCAQEAcpJJ7FQJ8rtBQBitqPDdYgLYIuPq7kCNTwT2B2m60a8nIzc/wGtAePrN +80x/VbLXeXOW+Pl6tzPWvja17SMzeEsakXkVZnE0qnQyfxxY69T7tKUsbGCUIIug +Iwqdz11q2MbiWdOlZDh4o8G/dPM6FVLpKzfC6OmeUrLLmYE0Tme0+ejlZ0kVe4GZ +CYrvCmXpIjXaF84mAWhd9LdJ42iVGusVbdTGN7xh8FACVZS80h4BKQXyYUzrPFpW +boKOjshNrzvoTi7ihg46HMHNSAE7zdBrAieQpIZvRqCJbqk8hRvdCk6s1vj2w5hc +NTE6HialIan5T7+ok0K5ok+ILT4Etg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ev-test.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ev-test.pem.certspec new file mode 100644 index 0000000000..10f8022585 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ev-test.pem.certspec @@ -0,0 +1,5 @@ +issuer:ev-test-intermediate +subject:ev-test +extension:authorityInformationAccess:http://localhost:8888/ev-test/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/evroot.key b/security/manager/ssl/tests/unit/bad_certs/evroot.key new file mode 100644 index 0000000000..1d88a930d5 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/evroot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC1SYlcnQAQjRGh ++Z+HqePRpdtd+uzxiNpXv2QTaI8s5HIs/xCQOMF0Ask6Kkc9vShq7T/c02PPWikU +dwG92BjXYVv5NWvV08gzaqqMCXE2igbDzURhuT5RQk4XRLsuqtRqqzjOGWghlh+H +cUoWY2k/CXYc301roSXqzse+Jw04j3ifbN94rjFE7SjEXnkpOGOnoipImAo2pA5y +1XnJuSXf+MeTNi/9aJenwXVMXpfJZ8Pq3RquiqLMzjSKAWm4Diii1wwalgxvM18t +oJubZD9av7pJ6Kqpgelg4n2HSAvdVd2UF/oYUJ+7VUzPgaQ5fouoEoo0vfJ4ZcGJ +5XNPsikFAgMBAAECggEBAJg9VPlNb0x26yPW+T14UjUwz3Ow0WJUxueBdo1F9VaB +0dAvsr0qrGq8HDiYYJNcUqDY9BSCAQOUd4MUHYZL/zCANjilwBUlcK6dGPPYyhY+ ++0dbDd3zLn4W7HVl5rteAlxBxcZuV6A87eVUIh+DBFNHosTEUcPc5Ha3h84MBXJE +vp4E7xMRjbuz1eCmzIcCnq/Upp7ZsUdZsV452KmITlb1TS+asBPw0V8xipq2svc9 +HsPJ/idK6JQxoQZAvniZsAEcXlCToYNHCGid4QBjTaveYPvWqu+joz3zSh829gwE +MDa3SNHJ7pjEAxoK/sYO/aCpkL5ST1YU6sT9s0pS+VECgYEA6twssz5f8co3a72V +vWoXd9LPT6xHVF6S0RpiCbnV5N7UeDRYHBabPIhHQqCeoYdQXBylVBTY0ltJdjLV +7CqqBSM0MPrUmJJ3en1o4Dj1YaO4lp5gsKJj3vv9pIqbD/OdlbyIsVJnyK3pe1EH +lI5B5DMknYf32xCdXXRYTYa8wdcCgYEAxZrldqIWRwJI2USlW56b+TKZ2jQexW5V +jrqCGrzhv1e3nPQR0pBMd0+duh8VGF9gewV0oIIF1uwotmo21jQjLqry/qN1Yauv +nWRLaNs4yZZMuMluwKxh66ZNBbRGVC9COXb1rN5OzJVTbS31eJVPk/DP2cWPt4ui +p23VrChNyIMCgYEAwdLvOQYzHFKspkgR+f5CW+somDIvs9tRAyzo1+n8MiQL6SAZ +zySA/NXjKYNxJxGLKlmhv+BsiD46REfz8DHNmuvQuNNo/Hl0DSzOjq2zJN9/CR6v +4VZDYdVJILAbBHEjDl5H2T+O0zljxRe8T8ePbYsfnrqFvM7bcDMCZQjbYoUCgYEA +hSG421aU376ASjFfnvybZSdcVJCs8qNFbWXm5hC/n2R/xnUB1PV3LyMqxwzN75/C +pt+kFcfEG2r8evnQfDygP37ZPAnwuZ8sMEQ0Mi8QcXCbvBuqTJFXX6apWeB9SZaV +bZXiK1eTi25HyNUf/t/Jv4iM4NGj5CtlqJvtS5HT5fUCgYEA3El7BrkgyL4LAHe3 +mOl37vdEqQ7Cxdfmy7IkSPrHLagaMxgODYoC6DFGDH/H/TphL3uZMLYbeZ+OkI5j +LpugQJtqpwsDo7p4dCYmO1vVhD34R27bXRT2qGE+uvW5zVykL1+9KALgjk5J5XCf +UVFRDKpassHG6z7+kpXRbowlyRY= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/bad_certs/evroot.key.keyspec b/security/manager/ssl/tests/unit/bad_certs/evroot.key.keyspec new file mode 100644 index 0000000000..1a3d76a550 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/evroot.key.keyspec @@ -0,0 +1 @@ +ev diff --git a/security/manager/ssl/tests/unit/bad_certs/evroot.pem b/security/manager/ssl/tests/unit/bad_certs/evroot.pem new file mode 100644 index 0000000000..13c3031905 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/evroot.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUIZSHsVgzcvhPgdfrgdMGlpSfMegwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTUwMTAxMDAwMDAwWhgPMjAzNTAx +MDEwMDAwMDBaMBExDzANBgNVBAMMBmV2cm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALVJiVydABCNEaH5n4ep49Gl21367PGI2le/ZBNojyzkciz/ +EJA4wXQCyToqRz29KGrtP9zTY89aKRR3Ab3YGNdhW/k1a9XTyDNqqowJcTaKBsPN +RGG5PlFCThdEuy6q1GqrOM4ZaCGWH4dxShZjaT8JdhzfTWuhJerOx74nDTiPeJ9s +33iuMUTtKMReeSk4Y6eiKkiYCjakDnLVecm5Jd/4x5M2L/1ol6fBdUxel8lnw+rd +Gq6KoszONIoBabgOKKLXDBqWDG8zXy2gm5tkP1q/uknoqqmB6WDifYdIC91V3ZQX ++hhQn7tVTM+BpDl+i6gSijS98nhlwYnlc0+yKQUCAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABTOHA9XbfLv/C7+ +5KycYXToOIBRSjQ0j2nsiqFda4Jx+aKsvdpdrrbLHvhrpfsA3ZgB2+eKHunVc4fo +UHNqZllAs2nx+AEinq4GX8iya5BpiyTIxXWu8v06siGgz1GxlJw1cJ/ZnFEQ9IBf +cCAr5fCoZ4RC+2OVhiSTnYPCKM+zCyw3YpISjNOg1VVkp46Htp+831Eh12YfwvdY +Fgh1fc5ohYC5GCLRuXKc9PGTsr3gp7Y0liYbK7v0RBjd+GivNQ3dS3W+lB3Ow0LH +z/fc3qvrhsd58jHpb1QZQzd9bQjuIIM6Gij7TNdNNarEVZfSJjPYLfXosNdYh5fH +HmbOwao= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/evroot.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/evroot.pem.certspec new file mode 100644 index 0000000000..3121f3486e --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/evroot.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:evroot +subjectKey:ev +issuerKey:ev +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem b/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem new file mode 100644 index 0000000000..a7d657a970 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHDCCAgSgAwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAwMDAwMFoYDzIwMTQw +MTAxMDAwMDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJlZC5leGFtcGxlLmNvbTAyBggrBgEF +BQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJ +KoZIhvcNAQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzf +T+ow5WVsxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7IAMO1CEr5FVdCOVTma5h +mu/81rkJLmZ8RQDWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3 +L9zJ2JqNc60+hB8l297ZaSl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74V +kQyNobaFzDZ+Zr3QmfbejEsY2EYnq8XuENgIO4DuYrm80/p6bMO6laB0Uv5W6uXZ +gBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFwWwtnoK7I= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem.certspec new file mode 100644 index 0000000000..0a03bc36f4 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expired-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Expired Test End-entity +validity:20130101-20140101 +extension:subjectAlternativeName:expired.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem b/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem new file mode 100644 index 0000000000..e03d862761 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIUY9VlD+O8GH3DRfxtYTip4pS6eBYwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDExMDEwMTAwMDAwMFoYDzIwMTMw +MTAxMDAwMDAwWjAkMSIwIAYDVQQDDBlFeHBpcmVkIFRlc3QgSW50ZXJtZWRpYXRl +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0B +AQsFAAOCAQEANf+C+WsnAgYfISDS37prll2DOGYWKajcVZNzkScDzNGkK2s0c/td +Mb+HXehqvYz20hT4wEwQZnPt9qMWH7bBEWiJfw85OINbKmG/i0gjZZDgbFMMdHvc +j6BXJoxL0gAy8fOQyTDuMNX0NBJzSmWhzBsL99BHAWdG6XXQTzSyumiekc8ip4GG +EhJvArbZwgIBigzdpbc/lQI0dR2qER0BUXamWU8fi2RuvQqtEi2ANjJHrWOillXU +PR3j0F2LyvoiYlhiNhE1g3JH4VYZ+3eboRCrjel4J3rZHksN17r6+Fla1/YZdz2l +nAGA5McLBKXYBVcARV4adXlBe1z79TiDeQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem.certspec new file mode 100644 index 0000000000..38a0abd8a4 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expiredINT.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Expired Test Intermediate +validity:20110101-20130101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem b/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem new file mode 100644 index 0000000000..2d00c1ca6c --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQDCCAiigAwIBAgIUfTvvLki+Legnl10m+fcP7kxDp1YwDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZRXhwaXJlZCBUZXN0IEludGVybWVkaWF0ZTAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAuMSwwKgYDVQQDDCNUZXN0IEVu +ZC1lbnRpdHkgd2l0aCBleHBpcmVkIGlzc3VlcjCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNcMFowJAYDVR0RBB0w +G4IZZXhwaXJlZGlzc3Vlci5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYI +KwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQAD +ggEBAF4T4Ye5qxMLGz/5dOgRxn/LXh717T2FKxXcWM50cShOGBU5NOjIVB5fkRS7 +uJsfgvHrT05123/ttDzVZefz2N1ZvXSxuzzJoA0DFhX/XSr4VXgLPEYHO0usDwxE +HJq8ZmtgM4Xw39QlFU4Sw8ZA5tjOfFjdKv5Ow1ulbVVGZyk/9FsmcsSYZuPXFIvH +DZyxrz8wFJOyrB/6Q/fOcTHeeh7bcC8YSAVtQvCFYOoKK1dJHwttpIa4/mdfsjpl +aP+ixciWjoKNmiPTqTZy8BdDSlh+pRFJppGfNfkub55T4+5XegcQPUWkJA1w6woM +hNZU708Mvf7u8j3XJuWlxNI8rHI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem.certspec new file mode 100644 index 0000000000..855f454221 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/expiredissuer.pem.certspec @@ -0,0 +1,4 @@ +issuer:Expired Test Intermediate +subject:Test End-entity with expired issuer +extension:subjectAlternativeName:expiredissuer.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem b/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem new file mode 100644 index 0000000000..9f306fcb94 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgIUBT+m5UYwTuABfetlYca4GEtsukAwDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOVW5rbm93biBJc3N1ZXIwIhgPMjAxOTExMjgwMDAwMDBa +GA8yMDIyMDIwNTAwMDAwMFowGjEYMBYGA1UEAwwPSUROIENlcnRpZmljYXRlMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08 +E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc +1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP +DY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQ +gAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV +YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID +AQABozgwNjA0BgNVHREELTArgilidWc0MTM5MDkueG4tLWh4YWpiaGVnMmF6M2Fs +LnhuLS1qeGFscGRscDANBgkqhkiG9w0BAQsFAAOCAQEABk5q77He1tAU87VBBq2R +E/lyg2rTNFU6oOgGUY9sWbz+RbTSxk8xjg89d6BhW8K9KFEzkTdS74sjxTKc9pMB +jXDpKL5LzhPtBBRndtzsAaaKMfnR0r7EkxihAP7TNTkLgYBQzIyOXIAZvyDr+fnG +J3om1g4pkt1rVFc4CtrTqSzr4Bdm7vwYWIU5ogwsF9Gpg7shShacbJam4pA6VzHE +fl1v1bAmpCyfGiYFbDTSLLFMYiZvf03sy8MrCCxPftGqr9n6trkQfN+hzbImGJFw +hkSt9hniJmVVglf0UVBmJTJ1Ud8rl9aoeOr9Ic2QvQ6HTvq5xzu8NECInNkzDENt +Kw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem.certspec new file mode 100644 index 0000000000..b3d840fbd3 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/idn-certificate.pem.certspec @@ -0,0 +1,3 @@ +issuer:Unknown Issuer +subject:IDN Certificate +extension:subjectAlternativeName:bug413909.xn--hxajbheg2az3al.xn--jxalpdlp diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key new file mode 100644 index 0000000000..d43495f851 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICcAIBADANBgkqhkiG9w0BAQEFAASCAlowggJWAgEAAoGAANKbsS+4T93NKbOl +GctmxDuNj4vlRbp5OEzmY+0D33WZFgDrkgeQ0lMM7OVE25mnHwWJaj7SBxZVNKqZ +BX5HxH47yBrab6HhLjcmi1BGpVJo+drXzLSF2BouGdUNTwtoVKyvbXvmnZoIMTbh +WvqPU8HIyE/GB3J53Q5V1zaaW90CAwEAAQJ/PEllBwvzkMJR1aLFJ3xbX9C97oXK +1/4rJ5grsoURSlBwBANq4c+K5Usl5Ns5IVq9fpA/YYwtiy8IzGzRLbzNciBeSUW2 +s984nl5D3goUi7LITiQx/b5ZILBEuycvRez/ByG337YDl/xhOp6jXCIwBTDK6PkV +nFNN878JEJUZAQJAD58XWXyFuAUbnGmvtV71dsmW29CQR9DM3ludYOpcZ/5PrGe+ +gD9LasWj8FD3a5ZvsU9c8QV2HlrebdlgsYO6VQJADXtjcRLOYaVRaMD5yThvsnmr +QMug1Ukza7plJ3JjqseCYRosgdm2Nc94xAAYhZ4BjF6QBtEuPS7m80bnn6QzaQJA +Cf1smj6m6RrjIHD5/BwhD/k1L5e+XR7rlRuzloHp3FtnKlMiIbPYkAyanZm50KTh +AtxFDKG4ewsTid5lFsCuDQJAAUG4MkkbfdSoMwiSACTHnK5kvUR9+IO7TFZyqWur +SLcSOzTyYyRFLNzrF/IeVw40fL4v1MLY+ZEOrCy22JW4yQJABFjdau4YyIsvm4Hx +vDB1riDcH5lz0gck8gsGBD1hR8h4nUoHroi8gshDjIk+AXsTlH9i4LGJWKMetmSx +nmTT4A== +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key.keyspec b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key.keyspec new file mode 100644 index 0000000000..21ed73d60b --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.key.keyspec @@ -0,0 +1 @@ +rsa1016 diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem new file mode 100644 index 0000000000..de4b933cf1 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtzCCAZ+gAwIBAgIUUTSENycPfy4QVpNTpBCq/pVp3nowDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowKTEnMCUGA1UEAwweSW5hZGVxdWF0ZSBLZXkg +U2l6ZSBFbmQtRW50aXR5MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgADSm7Ev +uE/dzSmzpRnLZsQ7jY+L5UW6eThM5mPtA991mRYA65IHkNJTDOzlRNuZpx8FiWo+ +0gcWVTSqmQV+R8R+O8ga2m+h4S43JotQRqVSaPna18y0hdgaLhnVDU8LaFSsr217 +5p2aCDE24Vr6j1PByMhPxgdyed0OVdc2mlvdAgMBAAGjZTBjMC0GA1UdEQQmMCSC +ImluYWRlcXVhdGUta2V5LXNpemUtZWUuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEE +JjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3 +DQEBCwUAA4IBAQCf8g6xupfTgr6N78Zru3/XdJ9zzf8gNLNDEzncs8YipkkPEkUY +F2yGf0bNOwqZnHMTo0D4lwaNTFFv1obY7kZd5auFt9WqI1GUWdPM7FaQS4a1oAqU +6gWCz+tIbTJXVDrAJ+yYXntV030Qqr7i0DFvwJz5fPFk6V1192Xa2aLUDoenxv5d +eiczsYvJMgBD6zkXSef+rSf24FgS23km6DHja89recbZ/fz09HJ5q9NDQ/EMilHf +EJMP1Ny/73Ht6V+Q9RJdtA5PXDyOgc7WHjFY+Z2LZH51VDg1XJ49W4ClYqxB1Yg4 +4qhh6OwIoFEipevWJ2uGNwJfD9KV4jiDwUAB +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem.certspec new file mode 100644 index 0000000000..02b595dc9a --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequateKeySizeEE.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test Intermediate +subject:Inadequate Key Size End-Entity +subjectKey:rsa1016 +extension:subjectAlternativeName:inadequate-key-size-ee.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem b/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem new file mode 100644 index 0000000000..0899f9d613 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQTCCAimgAwIBAgIUJ8CbecVvBfSdpQSAm71sCRjoCTUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAvMS0wKwYDVQQDDCRJbmFkZXF1YXRlIEtleSBVc2FnZSBUZXN0 +IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjbjBsMAsGA1UdDwQEAwIBAjApBgNVHREEIjAggh5p +bmFkZXF1YXRla2V5dXNhZ2UuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIG +CCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUA +A4IBAQCog4fCed4qaa2aLX7kx1l+03kSlDg9ZmnyIDR2kBsFZePto9TM6488Gaem +m3GEHT6d/RQK1g7zG40lmYDAg33PShzxZqgCmyxzpSfc1HbFfh9w4m47JANY7Q7E +NWDg42P64v/+Vdvxoprn594XklxYc8ci+y0NL9c79BWVEBlpyXaRwCJiKwfkcr6o +1X/07hkbKCPi9uBR6GFPtQSJmnFRKGT4ePdRHAccqn6CExIhamCK0I/y+lsr8Atg +ZtSrWLnXbqwYvdDyofhMWttDXPXCiWEdUq031KpQ/ENXxHi2cs7eEAtjjSZNefBv +vX+wC4ZNznyAb8tR5Zvx3sDoasRT +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem.certspec new file mode 100644 index 0000000000..4d553890b9 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/inadequatekeyusage-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Inadequate Key Usage Test End-entity +extension:keyUsage:cRLSign +extension:subjectAlternativeName:inadequatekeyusage.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem b/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem new file mode 100644 index 0000000000..676c46dfd0 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0DCCAbigAwIBAgIUTfYfuzoa/9f2RQTT/c6KssuRWkkwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAUMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjGDAWMBQGA1Ud +EQQNMAuCCTEyNy4wLjAuMTANBgkqhkiG9w0BAQsFAAOCAQEAYeN7Q1I0ihJhj2GG +o/0XZM/WuxPJ0JaJzEWMvf4ZGYeSaxp86tyMFNUOhGaDCvHCu9ZiruHUEC1J5Z7h +z4kSwG2h95SKLsOr5d3NDN3bGJJtzPARz8xeynFHI2f1AAiGM+ai714jNUgtVoXx +a1U5J+Ls+xbIzNiRPRzze8shnHrqTXmHL+R4G3F9MRsLUPQs4tVubi2J8+lVRrsK +QAFfnQp3VVGoWfDAj5OFDC9kCf6fVz9sVjTjHD2LuFCKvagOIxG62Y1qVhd5CLyJ +HUAzeorgZuUl7QXN2RT2w5itIcpzGRbNmd5CoN7Tbm7TyuS6BIBWyjjxlWM5Ue/j +ae8XOw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem.certspec new file mode 100644 index 0000000000..7662338470 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/ipAddressAsDNSNameInSAN.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:127.0.0.1 +extension:subjectAlternativeName:127.0.0.1 diff --git a/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem b/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem new file mode 100644 index 0000000000..3f373d09f7 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIUGUp8qIucVUZ0D+cPoEILDVfteu8wDQYJKoZIhvcNAQEE +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDExMDEwMTAwMDAwMFoYDzIwMTMw +MTAxMDAwMDAwWjAvMS0wKwYDVQQDDCRUZXN0IE1ENVNpZ25hdHVyZS1FeHBpcmVk +IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjYzBhMCsGA1UdEQQkMCKCIG1kNXNpZ25hdHVyZS1l +eHBpcmVkLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW +aHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQQFAAOCAQEAYMtZZk0A +c3xvnK0PSwNxsWidAdOEY5uOKJTPT1LZFUQsNHw/2f7csfDneTeLNoCNKH7LPF3t +J+zwUMzq1Ut0vIRSs5r84P7LK7KaBRrSwWPSnTP90X4VX3IVIQ7dbwTkrlUaRzfs +B4Pqa/p2GVuvrLmbtmd2SDw+52GubJYVOF6u2s4KKgUGhHWtegzQOsVKTFEOoqBr +X3yDEJhK7M82NMiGtq3Fr5F0sLD6DuGL0Mm7ei9junSLS4sH0M+Hac2BVmXwYNTS +ekKzyjmZ1TYRlo2sCgYyYfCLcTOswG7uVHLU+ie0+Dbaik2NcolUgFNnC7Uk3E+t +DhSRNeOtKglSxw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem.certspec new file mode 100644 index 0000000000..e4c2b7008d --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/md5signature-expired.pem.certspec @@ -0,0 +1,6 @@ +issuer:Test CA +subject:Test MD5Signature-Expired End-entity +validity:20110101-20130101 +signature:md5WithRSAEncryption +extension:subjectAlternativeName:md5signature-expired.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/md5signature.pem b/security/manager/ssl/tests/unit/bad_certs/md5signature.pem new file mode 100644 index 0000000000..a2d46f868d --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/md5signature.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDLDCCAhSgAwIBAgIUPbgiSgWOnRxOdlLj8dU/qbEhukQwDQYJKoZIhvcNAQEE +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAtMSswKQYDVQQDDCJUZXN0IEVuZC1lbnRpdHkgd2l0aCBNRDUg +c2lnbmF0dXJlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABo1swWTAjBgNVHREEHDAaghhtZDVzaWduYXR1cmUuZXhh +bXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9j +YWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBBAUAA4IBAQCFfTcMksF9oZhEnsAmGhLx +u7LvPXarRynLOia8+un6Lx33ZtvItBpLHtbbPkPvlsiv7oyKspzNbk5IpKdYEQbd +dYx6diFkEP8/xAnX8o1Jng1rbynLmVhnabRSnJfTOihGFlusN3UAVrmSZyZVAdEl +knnKqDL+U+CSVMdEeaqBECNQOFIUL7F+uutt6jfKNuN/fpDHEz9vCfUGiuZVC7Kd +2fVCwhDDOC7bN6rvQP3e+06uLoXGGleOM1aZjhNNdiYHvqq8veYiGLZckmkcF1a8 +XqCDuLoQDs0dVvsj4pNEyciXuk5wCuV6bgw4s4unPFMP9EBmgWQGFaW+iePqT6uS +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/md5signature.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/md5signature.pem.certspec new file mode 100644 index 0000000000..02742d910e --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/md5signature.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test End-entity with MD5 signature +signature:md5WithRSAEncryption +extension:subjectAlternativeName:md5signature.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem b/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem new file mode 100644 index 0000000000..d5782da2cd --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDKTCCAhGgAwIBAgIUXWNmi3NOMsq8iBKvohtG0kX2YFIwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAwMDAwMFoYDzIwMTQw +MTAxMDAwMDAwWjArMSkwJwYDVQQDDCBNaXNtYXRjaC1FeHBpcmVkIFRlc3QgRW5k +LWVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaNaMFgwIgYDVR0RBBswGYIXZG9lc250bWF0Y2guZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCt7JzZlMgD/ZHZobiGxcfE/EPQ +/V405Xu7DGdTJh5cTiFF1h3sQl06BfrCEAo0yhOrpPyMtmhTI+rMyF7PvFWZMQ89 +bk9y4cZ7jG1NEd6B+jlYfD4mFbLR3AbMEbf6QVjYDK29+XnjnhvczT5NPPl8g7rF +6y1FhFcFMTGiGZCOyhCz0nXbG/LpP/alH+WucXRdpMLUQbEXEDzWOq5WJ1ZPS556 +2Ouurfr1mkydAlXCGc5RYPVLRY48CwX2z+kfHRnF4TCb3ck5oOlqabP+bc+HD7EE +UgEEdnE6zpUs1D7s8C8Mp89LUcXx+s51/ZUQvGE4btBMML0lNImwwbqxbv02 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem.certspec new file mode 100644 index 0000000000..262f08d6be --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-expired.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Mismatch-Expired Test End-entity +validity:20130101-20140101 +extension:subjectAlternativeName:doesntmatch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem b/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem new file mode 100644 index 0000000000..b70a632693 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDLzCCAhegAwIBAgIUcYUtGOYg2nrx/OAYr+cxTZVbv34wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDMzMDEwMTAwMDAwMFoYDzIwMzQw +MTAxMDAwMDAwWjAxMS8wLQYDVQQDDCZNaXNtYXRjaC1Ob3QgWWV0IFZhbGlkIFRl +c3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaNaMFgwIgYDVR0RBBswGYIXZG9lc250bWF0Y2gu +ZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8v +bG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCu5v5Saw0htF59xmKf +CQJ7YI4M/TvuNJjhVdwq5phvEw3k+qweEdpLHERGu4nrzyDTMKqN8kXO6tXUspnh +LpXCvmaDLNxx/UyYofWslqYqFwM4vQ4l5QEUriR1ndMN256ELRSx2cEpWCi9xHMb +1cqB12ulLMCpitmK+NXpflViZy7HliTQOCdwhLPDNWRKsRF85EHOuFzcx4uqfWdw +5zwA0zVOYG21fyY51bhy4oy7HjTWUOrGi/klwzz2TEDTUX6nRHYagrFxO7C1GMlg +pe32InUfLU0rR8G9lP/tSug8HawSH/TCE+63jo2BGWaIYGSd+k11QzU+CsT15+A2 +tbAC +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem.certspec new file mode 100644 index 0000000000..947eb7d678 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-notYetValid.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Mismatch-Not Yet Valid Test End-entity +validity:20330101-20340101 +extension:subjectAlternativeName:doesntmatch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem new file mode 100644 index 0000000000..4902855da5 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDOTCCAiGgAwIBAgIUO1bWrdrsbGfiDSe6i14vOA3vWsIwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDExMDEwMTAwMDAwMFoY +DzIwMTMwMTAxMDAwMDAwWjA1MTMwMQYDVQQDDCpNaXNtYXRjaC1VbnRydXN0ZWQt +RXhwaXJlZCBUZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjWjBYMCIGA1UdEQQbMBmCF2Rv +ZXNudG1hdGNoLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcw +AYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAlTFY +rHGARngEHz3XEngdY1E3hf2GdITTHssgVRvpW3IvNmUJDhk3zVqvjb2hIVDmxFRv +ad7yCKK7FQum2A1MKZh/Pl7ylWv6vkdtB8HSg9F5qYifyUD/XEjYp3uSrfAXW7Pp +XHZHgBR6nlOB1EpAqrLtpEjxMX6F0fcXClOlWf0UsPLv1M6JvPNns/4tbHBnrhfm +e0DqBMfZIJV7x633eZhpLQmOIA27rZtpElWZsA6Gtenl3szr8mpOgy3hxuEs9oFn +cigHg2ECzaOKM5ayTP0dc2OVbVgUX/2doF8pGHiIKdsThYNLNEOioBZjJhQlreZE +K67bzkMDhLQmMBUMtw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem.certspec new file mode 100644 index 0000000000..adc8ebaf8b --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted-expired.pem.certspec @@ -0,0 +1,5 @@ +issuer:Other test CA +subject:Mismatch-Untrusted-Expired Test End-entity +validity:20110101-20130101 +extension:subjectAlternativeName:doesntmatch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem new file mode 100644 index 0000000000..708fdbe324 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMTCCAhmgAwIBAgIUIeL7ME9jR6UnL5tbkKtCbMzAstAwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAtMSswKQYDVQQDDCJNaXNtYXRjaC1VbnRydXN0ZWQg +VGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +uohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGoby +a+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWC +D/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfT +iEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXT +Ce+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+ +SSP6clHEMdUDrNoYCjXtjQIDAQABo1owWDAiBgNVHREEGzAZghdkb2VzbnRtYXRj +aC5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6 +Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQADggEBABPy72/P12xlsoLz +nImXr6gkVB84x2t32n9berLA5BuvB7XW3V5AnHM4cvEPw/SkWgkjb/CgKy/jE5mo +ExTyrtneG3PcX5KgIJedKgKYPjyji01SnsT4jlWlzRND2ISC5sv/0xQovrEsgkAP +pOLodr5WfjZhE0E0gA3TNwFW+/xDZeMwYeVuv1XwPtmto/r026VYhlQfhi7cZ0Rf +6/sW7zBKDhAgg2Puk32w8J7eP+KxkIbAPdfeLrWU4hl4U5Srnt7tFaTaIng5YAGC +6U3M8fEETS0YIgl1wRU77ywkIeSGX4jcRF3l5zwoexiDbSjSuJ/4lg6YItfW/Rd6 +xbzRon0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem.certspec new file mode 100644 index 0000000000..91c5f548b6 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch-untrusted.pem.certspec @@ -0,0 +1,4 @@ +issuer:Other test CA +subject:Mismatch-Untrusted Test End-entity +extension:subjectAlternativeName:doesntmatch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch.pem b/security/manager/ssl/tests/unit/bad_certs/mismatch.pem new file mode 100644 index 0000000000..2699b8196c --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQDCCAiigAwIBAgIUU/pv4TGBlwPGJxIpKC/9rJ31RaUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAjMSEwHwYDVQQDDBhNaXNtYXRjaCBUZXN0IEVuZC1lbnRpdHkw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ +PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH +9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw +4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86 +exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0 +ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N +AgMBAAGjeTB3MEEGA1UdEQQ6MDiCF2RvZXNudG1hdGNoLmV4YW1wbGUuY29tgh0q +LmFsc29kb2VzbnRtYXRjaC5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYI +KwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQAD +ggEBAIQ9iWQWypTHSxt73EdcGiorVJTczAisC4ar683CcwwcbonkG8c6Ca8OZZFz +QWYZYwKO6xouFMpKYoby933dKiEwQrtyckaBKHsGlgOQWKzY4BiaCULeYg24d6S0 +rWzKOAwZgmA5eaAqHxmoIz2qefNLOED1sYFzg85jeT6vL+SeEuHFh8GOGct2RHEA +I+EcdKgYT6/kFrHtxEkCu0QULVVk0g9PDlVeZZ8eOOMBYi1bsQq03QjKFTzUaQY2 +18iwDvWbIgh21MwTYGMDhCvEfXYXWKe+AqiMHNYDyfk2lmgxOHB48J7Akow4MiBX +zGuf1lvgdACSETNaPq5TXniBnMI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatch.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatch.pem.certspec new file mode 100644 index 0000000000..b93599fc88 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatch.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Mismatch Test End-entity +extension:subjectAlternativeName:doesntmatch.example.com,*.alsodoesntmatch.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem b/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem new file mode 100644 index 0000000000..4c1e16b065 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxDCCAaygAwIBAgIURUZJw9lGOsp7dEOmmehwl1FeaBwwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAiMSAwHgYDVQQDDBdkb2VzbnRtYXRjaC5leGFtcGxlLmNvbTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAATANBgkqhkiG9w0BAQsFAAOCAQEABN5ha7Gn+zVm7AdnMKIIuDt5C5X3CfF7 +YKRgqPby5clFJybaYHz9msYoxgSFAyoA+nuD1KCCSbQA77rMFKVJ2mDQJh7a1tEI +RdSDZMhgKbuA8qG3knr0Q6eBjfwDI4Gx8SIxU9BdJ3NhY9a31TQfzuhKeV+hN8FR +9GGOO1121x29U4jih4vtt35blMZu4VLrvMAR+aapyBOTK2UzZeqYb8JTyWQrkdBT +03nvtThsVl1SMZuyKDwCBAbenDqCknuZ/1FED7njbl9VuoEz8ApMopn0XnliM4RU +AuyvWWF9oBY6+xLIZsDfK+shmlaH5hRUMQC25NVwOpE/VfIxdJPp6w== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem.certspec new file mode 100644 index 0000000000..86ef45b7ce --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mismatchCN.pem.certspec @@ -0,0 +1,2 @@ +issuer:Test CA +subject:doesntmatch.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/mitm.pem b/security/manager/ssl/tests/unit/bad_certs/mitm.pem new file mode 100644 index 0000000000..37567fe10c --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mitm.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+jCCAeKgAwIBAgIUS4dnYahNJmxk0T1Z0H+W8A+5tcgwDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOVGVzdCBNSVRNIFJvb3QwIhgPMjAxOTExMjgwMDAwMDBa +GA8yMDIyMDIwNTAwMDAwMFowMDEuMCwGA1UEAwwlVGVzdCBlbmQtZW50aXR5IGlz +c3VlZCBmcm9tIE1JVE0gUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab +bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts +Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI +H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8 +rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX +Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMfMB0wGwYDVR0RBBQwEoIQbWl0bS5l +eGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAKNQhLbnyWK6cd8qvK8ZD/8cY +Je/PuuCew7E76VtbQFX3/d5foJJE2sKY/SHtfvFocAQbLp68/Pydfs2CmrvFlyFa +3rSUMJBSoFDOJ4az1Ht5iF374fnFCx61CXpxYl6b7SguWgZRd5qrstsTMw3cL+Er +/8f88N+aOX8P92eU20S4ZyCq0aO1yOBoOpmidPGqtNTuCQa32kyi96mCDGoBrWii +k9OQb8nrr/sORVGSIK377+/PdXyjPCPvDwYhhVEyIomYQrXXWrL6TTy5I5e1kpIs +9zi7T7XnQbcRaHSWOwYkRGAkuKlXbq7eS3LF+PSHSzcBr5r9vYCXBZMmtBToMg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/mitm.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/mitm.pem.certspec new file mode 100644 index 0000000000..1439391f1b --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/mitm.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test MITM Root +subject:Test end-entity issued from MITM Root +extension:subjectAlternativeName:mitm.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/moz.build b/security/manager/ssl/tests/unit/bad_certs/moz.build new file mode 100644 index 0000000000..9390fd9c87 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/moz.build @@ -0,0 +1,71 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'badSubjectAltNames.pem', +# 'beforeEpoch.pem', +# 'beforeEpochINT.pem', +# 'beforeEpochIssuer.pem', +# 'ca-used-as-end-entity.pem', +# 'default-ee.pem', +# 'ee-from-missing-intermediate.pem', +# 'ee-imminently-distrusted.pem', +# 'eeIssuedByNonCA.pem', +# 'eeIssuedByV1Cert.pem', +# 'emptyIssuerName.pem', +# 'emptyNameCA.pem', +# 'ev-test-intermediate.pem', +# 'ev-test.pem', +# 'evroot.pem', +# 'expired-ee.pem', +# 'expiredINT.pem', +# 'expiredissuer.pem', +# 'idn-certificate.pem', +# 'inadequateKeySizeEE.pem', +# 'inadequatekeyusage-ee.pem', +# 'ipAddressAsDNSNameInSAN.pem', +# 'md5signature-expired.pem', +# 'md5signature.pem', +# 'mismatch-expired.pem', +# 'mismatch-notYetValid.pem', +# 'mismatch-untrusted-expired.pem', +# 'mismatch-untrusted.pem', +# 'mismatch.pem', +# 'mismatchCN.pem', +# 'mitm.pem', +# 'noValidNames.pem', +# 'notYetValid.pem', +# 'notYetValidINT.pem', +# 'notYetValidIssuer.pem', +# 'nsCertTypeCritical.pem', +# 'nsCertTypeCriticalWithExtKeyUsage.pem', +# 'nsCertTypeNotCritical.pem', +# 'other-issuer-ee.pem', +# 'other-test-ca.pem', +# 'self-signed-EE-with-cA-true.pem', +# 'selfsigned-inadequateEKU.pem', +# 'selfsigned.pem', +# 'test-ca.pem', +# 'test-int.pem', +# 'unknownissuer.pem', +# 'untrusted-expired.pem', +# 'untrustedissuer.pem', +# 'v1Cert.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'default-ee.key', +# 'evroot.key', +# 'inadequateKeySizeEE.key', +# 'other-test-ca.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem b/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem new file mode 100644 index 0000000000..0086ff5310 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDAzCCAeugAwIBAgIUc9BglcR5VS6X67v9lA6Nojd9gPUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjApMScwJQYDVQQDDB5FbmQtZW50aXR5IHdpdGggbm8gdmFsaWQg +bmFtZXMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAGjNjA0MDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0 +cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAbE3XcdHBwtBh +Kqy2B6BDvVnYn06/rx0T+6HrWPkn5BRWwhQW3K6OBf/Mfm+F9QI73YGWSalVZPs/ +pIpfM2qvjXztkEJ0ZfZTEjo6b0Jd5gJ72XFYC0CZbRS8C81ck4f4hjegT+Fbyp3f +hzNWHbdfo6yRIVtv3aGcfzn1K8RWy33620t+mNroaSNQoVVuO+TVGHWEp5g4vn8A +GxUc0gx0ePNtENLpEC071aPBO4OEU/SiT1bVCp9XNCP6GSyVAl1b/VguBWn+G9pD +m6kn0PjaNxLH9JQESIKrgHyj1s0vBizLdb4Yx+hmQVdHUESt99cmlkeJi6fBHwUU +ekQ1Wipf1Q== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem.certspec new file mode 100644 index 0000000000..87088e87e5 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/noValidNames.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:End-entity with no valid names +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem b/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem new file mode 100644 index 0000000000..79cc10aa68 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJjCCAg6gAwIBAgIUH+AmYB0Pf6g+gBjtVqu94DStb3UwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDMxMDEwMTAwMDAwMFoYDzIwMzIw +MTAxMDAwMDAwWjAoMSYwJAYDVQQDDB1Ob3QgWWV0IFZhbGlkIFRlc3QgRW5kLWVu +dGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1u +togGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6 +pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqL +KkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3Zlqq +fgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3sv +Im9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6za +GAo17Y0CAwEAAaNaMFgwIgYDVR0RBBswGYIXbm90eWV0dmFsaWQuZXhhbXBsZS5j +b20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0 +Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQB1xgChilLhS38NJG3FU3vyD8LN3uGV +wgzFB33egzO4s4GkPK5zjGpkyQG0ofYFmlbP8NpVrjKykbhbgusdvsZOknuPBBAJ +jgHDrt5fdT4ah7xlRr+o4KC8RpYOZ8pGy6eoheCZZdNvhV3cDVxYWrkFZbdbtvw9 +YqqgpgiFx/j85ZqFudq/ApdMwcueZWPjmc47Y2fsTtrqO7rVVtX9FrG4O3BWcrVH +5RJpwN5mBsC//zNhhuvaGNWZB3XGNH0wgxEweI+cpfufWHnshJFKoEESJBrdHywz ++kuH3ha9W3JwyorON9M7uduDBdUBsjwjwLpYLd+Saie6X+XjROrGYe8f +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem.certspec new file mode 100644 index 0000000000..5b60c29ebe --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValid.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Not Yet Valid Test End-entity +validity:20310101-20320101 +extension:subjectAlternativeName:notyetvalid.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem b/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem new file mode 100644 index 0000000000..0a111582bf --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6zCCAdOgAwIBAgIUW7kXNYkW5OLObAOtdMQ9uL8FHUkwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDMxMDEwMTAwMDAwMFoYDzIwMzMw +MTAxMDAwMDAwWjAqMSgwJgYDVQQDDB9Ob3QgWWV0IFZhbGlkIFRlc3QgSW50ZXJt +ZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB +/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRx +CHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMC +OosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdm +Wqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGz +ey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUD +rNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq +hkiG9w0BAQsFAAOCAQEAJgm8BvVnIEy9uGjgTxLcNnIoOZeLgQ9CPrNir6RHzGIK +1hIHcNCDdC2mDc9DvyQ8MQPzJvAiMAOvo1v8yHDijC/mmYi6hTGuC6hDxF2YHKXu +8VZZOSMdaE9pkKUQ8sckzKMS+Oxw8EJOV7VeW/WZsSLKSpba0qAioae7wEBMg0QS +0Mp72+l4nMMUG5T/gzea6gy/nGTb0ghV97K1r5jekFNuy1pZZbKun9lLd9KJNmEs +XiJCn2M7Ce3nEhJfaJcDmz9sde4HOlJ/BVLV9ljkOL2cQ3TxdEkLT9/Unp9dmcLo +1sdvWkwimWiKT3XAs6Df64uM4GYl3PqPH5tQmUyPFg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem.certspec new file mode 100644 index 0000000000..8a00f2ee23 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValidINT.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Not Yet Valid Test Intermediate +validity:20310101-20330101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem b/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem new file mode 100644 index 0000000000..07e38c01fd --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDUDCCAjigAwIBAgIUWzSKPj2hWVPCNbbwxWOZDW3/ESwwDQYJKoZIhvcNAQEL +BQAwKjEoMCYGA1UEAwwfTm90IFlldCBWYWxpZCBUZXN0IEludGVybWVkaWF0ZTAi +GA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjA0MTIwMAYDVQQDDClU +ZXN0IEVuZC1lbnRpdHkgd2l0aCBub3QgeWV0IHZhbGlkIGlzc3VlcjCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1 +SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+ +zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYL +K7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwc +bJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibW +JZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNg +MF4wKAYDVR0RBCEwH4Idbm90eWV0dmFsaWRpc3N1ZXIuZXhhbXBsZS5jb20wMgYI +KwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgv +MA0GCSqGSIb3DQEBCwUAA4IBAQA6+mauWSqBTyI7KT2VVkNlmB0d0AZRnel1MMp8 +XkwBajtIMfwFiuQ5TZhIKbqPgV2tpUex4Uv5EPre2runpGWCBJNcWdQiTPPewHfK +vWwVvSEOcsNIzo5jaJLM14JDQUgTlqjVjiIxbIAdouck6is4oFCBLbpkE3pUQCC9 +l6dzuDwmMRNEp0HEv/lDl5slubTOVrRN1G5CLEGRI9BdWk4IsJiNcvSJeVF1PhlV +oE2/gcEcJo8gGzxwP07v6RAEf5quUCFDWbZwO9wba8vq1zVItMPHcxnM9n5vDzDa +lognzXkxApHHzP0TJMi6PV5899iJgk+4tOJq+VrW7aIY9piS +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem.certspec new file mode 100644 index 0000000000..d8420898e7 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/notYetValidIssuer.pem.certspec @@ -0,0 +1,4 @@ +issuer:Not Yet Valid Test Intermediate +subject:Test End-entity with not yet valid issuer +extension:subjectAlternativeName:notyetvalidissuer.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem new file mode 100644 index 0000000000..af14e9b6a1 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/zCCAeegAwIBAgIUO53hCvwCYNgrXfxkrdB945nRkCcwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAeMRwwGgYDVQQDDBNuc0NlcnRUeXBlIENyaXRpY2FsMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +oz0wOzAjBgNVHREEHDAagglsb2NhbGhvc3SCDSouZXhhbXBsZS5jb20wFAYJYIZI +AYb4QgEBAQH/BAQDAgZAMA0GCSqGSIb3DQEBCwUAA4IBAQAk0AOu1pTYiYQ4ojdG +1foeVBLBzCaC7jOK8FW/Ow04r5mli8saKVzC5YsPBRZreJp6nVnlBnjtmgHB4PW9 +XJcHzd46uzD7h/w8kFDpLsEgM3tTZ5oezNz82EFp9aoUvTXDrdMxBnC0S/lB2fek +9B5XTmmooU+DPYhTYYOVXXpjPCsRlKsAncu+vTGmagHGHCsRmrv6HkbSfLUEkdCl +dmyC9L9Fsr79RjtqPNQoLmc3zD78iH6fW2oSJnhYLGJrAJDIHuSLvVZ42puKxzMV +ZV01nNh3vXkxCFlNoQxlz8YTHr7dSku6+DGs9yMldhCgR+c3lrvhZk6d6tcM83iA +mqr3 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem.certspec new file mode 100644 index 0000000000..b236bdea47 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCritical.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:nsCertType Critical +extension:subjectAlternativeName:localhost,*.example.com +extension:nsCertType[critical]:sslServer diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem new file mode 100644 index 0000000000..60664c7c8c --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDMDCCAhigAwIBAgIUO8zMxMDLlO213zx4ekxrMaUbPiowDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAvMS0wKwYDVQQDDCRuc0NlcnRUeXBlIENyaXRpY2FsIFdpdGgg +ZXh0S2V5VXNhZ2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjXTBbMCMGA1UdEQQcMBqCCWxvY2FsaG9zdIINKi5l +eGFtcGxlLmNvbTAUBglghkgBhvhCAQEBAf8EBAMCBkAwCQYDVR0TBAIwADATBgNV +HSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAQEAJFaCPufuePUQLh1a +TzJHqLoTZrAg+9L/NpGnFLpsyENIQOHiKf53KQ53oFT0lv7+g+s9qU/KKf7xu2IF +egggCwb5VD4KeU72EgmNwDT3i7oYuyU8nq+wo9XegChNdhMz3luyoVtwAp9I2oe9 +yOb/9JOWOH0+qzIExpqCOx0GSNHVk6H9QQKIDwfPiaqmUXQA/HruHeoLI6LSI6WF +CYyLzxoE8QKttN+1kL7e6GEWqvOExf1ZWRtvnPpt1qf5httvNq7aDZ0PID4hP4kP +SHlJu7PmrQe9AHJULTTSCJGTEwi/ll5HInMOFltxYNfDZ+H+cTnZb5ej+xwHLfdf +4uU4pQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem.certspec new file mode 100644 index 0000000000..0ae63e20f2 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeCriticalWithExtKeyUsage.pem.certspec @@ -0,0 +1,6 @@ +issuer:Test CA +subject:nsCertType Critical With extKeyUsage +extension:subjectAlternativeName:localhost,*.example.com +extension:nsCertType[critical]:sslServer +extension:basicConstraints:, +extension:extKeyUsage:serverAuth diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem new file mode 100644 index 0000000000..5a715769ad --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDADCCAeigAwIBAgIUZ/ocY0tl1j/n07vD7m9BRpTDAUUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAiMSAwHgYDVQQDDBduc0NlcnRUeXBlIE5vdCBDcml0aWNhbDCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaM6MDgwIwYDVR0RBBwwGoIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tMBEG +CWCGSAGG+EIBAQQEAwIGQDANBgkqhkiG9w0BAQsFAAOCAQEACDqdp7f3wMnxSwIE +GSzvCwSBjMkV1ELElEiSYuhXzh1jQ+ke+xLmLkjYJi3E8BmTmJ3g+9jUlMFL6n1y +b4OOdRXM3JJyCnv2EBURvonfk1hIzWqK6Fuiwfzs5YdRLeHPrUMw1trGvovQqZfY +9qCnkgmeJL8OO9AeicCDYRhl/KMid+rHNJePhfkURKs0ww9AzrBFepAorZ5UOmDe +8UfP4dJarEledosnoIZ6GSEwpLoQQ9ChzsdpaIAhKLIPz52l7Na/N/qUXKw2CMQv +RnifJXwS2/DhaEjGsXGHq7rmC2tGaVJci+zamUhJdyb5iJlbsAqXQ6Ufq9jhNUoB +4nnKNw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem.certspec new file mode 100644 index 0000000000..a44a1feeef --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/nsCertTypeNotCritical.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:nsCertType Not Critical +extension:subjectAlternativeName:localhost,*.example.com +extension:nsCertType:sslServer diff --git a/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem b/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem new file mode 100644 index 0000000000..580b682319 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDfzCCAmegAwIBAgIUbYx/Zvi5+U/zqP9O3mq26pzGgIAwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAnMSUwIwYDVQQDDBxXcm9uZyBDQSBQaW4gVGVzdCBF +bmQtRW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXXGUmYJ +n3cIKmeR8bh2w39c5TiwbErNIrHL1G+mWtoq3UHIwkmKxKOzwfYUh/QbaYlBvYCl +HDwSAkTFhKTESDMF5ROMAQbPCL6ahidguuai6PNvI8XZgxO53683g0XazlHU1tzS +pss8xwbrzTBw7JjM5AqlkdcpWn9xxb5maR0rLf7ISURZC8Wj6kn9k7HXU0BfF3N2 +mZWGZiVHl+1CaQiICBFCIGmYikP+5Izmh4HdIramnNKDdRMfkysSjOKG+n0lHAYq +0n7wFvGHzdVOgys1uJMPdLqQqovHYWckKrH9bWIUDRjEwLjGj8N0hFcyStfehuZV +Lx0eGR1xIWjTuwIDAQABo4GtMIGqMHQGA1UdEQRtMGuCKCouaW5jbHVkZS1zdWJk +b21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5z +LnBpbm5pbmcuZXhhbXBsZS5jb22CFSoucGlubmluZy5leGFtcGxlLmNvbTAyBggr +BgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8w +DQYJKoZIhvcNAQELBQADggEBAF95ssZxomk3Jj886Bqm8kDAHWR/njF15jNyLnVQ +JOTQcbOItFbgftUOuY4aN3MQ2q+LzuDwsalcsm7vvmOXf/tp4LWjGKrFOdIkO0XG +/yUZy5xBJgSnIKuDUtES3hrl2X6LllZBhLiKBiKuFqudYo8LG1JeyLdxDpCKoDZh +dyDK3XQ42oqJz9GOXBIZiwl4x8AmaLSE3o+CRYwNxwNOpdqRWeSwlETC46LEdtSo +0StD9MEu+onWbizWCsCB8p6ILvvPr1JJGI6GcR1sPtr2qTkT5veXWXBTZYuqW2Cl +gs288iz7Kbbq1ABu9ZCQ6SzpyA+LAIadtkHeDc4p87KcjQc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem.certspec new file mode 100644 index 0000000000..a905a66ac2 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-issuer-ee.pem.certspec @@ -0,0 +1,6 @@ +issuer:Other test CA +subject:Wrong CA Pin Test End-Entity +issuerKey:alternate +subjectKey:alternate +extension:subjectAlternativeName:*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com,*.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key new file mode 100644 index 0000000000..abde350c28 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBdcZSZgmfdwgq +Z5HxuHbDf1zlOLBsSs0iscvUb6Za2irdQcjCSYrEo7PB9hSH9BtpiUG9gKUcPBIC +RMWEpMRIMwXlE4wBBs8IvpqGJ2C65qLo828jxdmDE7nfrzeDRdrOUdTW3NKmyzzH +BuvNMHDsmMzkCqWR1ylaf3HFvmZpHSst/shJRFkLxaPqSf2TsddTQF8Xc3aZlYZm +JUeX7UJpCIgIEUIgaZiKQ/7kjOaHgd0itqac0oN1Ex+TKxKM4ob6fSUcBirSfvAW +8YfN1U6DKzW4kw90upCqi8dhZyQqsf1tYhQNGMTAuMaPw3SEVzJK196G5lUvHR4Z +HXEhaNO7AgMBAAECggEAfj9tfLg572auXX3ZL/VBC7NB3BRyjTkDRXDho3B5DzDw +aBNV//QeKtTpqdn86/vRJ736uMAK/7Hzzqcyfq1HqhYh8qwe4UygLwSzsnhgF5gL +GBpEnQOwPmnRErg1ceVUNPASBWV10oMu1nMdznmeN8g/bVHFWrcetYAVrwXhrxXH +R2A+9/J9A6b/BJ2Wu/hUweTlDvWwWND7CBgOCsf3vo8v8Wc9l/yeVduoOAd7v4p8 +/ylihXeFJpzZ1brStXRp5K/NM8TKLS9pnxHnyPvc1ITwjY77ijy4qXLrJL7Zcu+q +5LtxIJPkj+lKRutimodQeMQCGposk8mnA5Dp0KVEAQKBgQDmP8clprp2klp/+MtZ +xPVt1+yD/oW/H1PhHKyagSWLz8CugZB3sPLRR3qvho3mqOy+r3uyKxlvKprYLTKG +8NDMKd5xnl8r6OUJtyhNWWPt02L5J4h6TEqJeZ00DVGzAax2AasnF5Ak/KrdOL9l +Iq9j6xZGHsAqfyewb+Cd3afAoQKBgQDXGLH+n4+Z8A6DKuH73G/iqyfzTgScSYAQ ++g63CEhSGCNGCDtclsPu5VksAUpBDGuTCxZcE7XCaqMurG58klqFUcJRNPL0pyxk +IfGacxSKDt+rpdOmiIs1y6GMAP047lqvC1RXMdcgdhu8ze50SlLKQV6Y5N4Bzf52 +TBlns+jK2wKBgAHlrKJmyUqI0i4TwrkuokcRbGV6B2gXvf0w20s6nTCVuaS2dJZH +4vhOenhPx4OLCMhZcc96A2+jDjuRw8TQ3yePgMG26FnYRWrbE33vqp8fCsW6yakY +T9TqJ51yLqYm8WDXiq17yDhFzLKd8RXIP2G3YiuZvUOcYJtXkKY8WVGBAoGBAIDM +RdENJITuDRKX/Ae/gLO+/0Yeon4fOPNxeJw69mtKDt0hksIneR208cd64ka/NC8x +hWsPVlgbWKlbETHAxTltsqjDxvOeouM2vCBa5qKgs2hp/KmMu6czzwExmm+bsmt8 +oj0wF/xVHNjaiv3Rf2+i4w00hoeYHNYjTVcekLffAoGAb3fAwfKuesFpVhzKSZxS +vfvgTN3M29wSrsWoVpHoWUt+4pkI8w57lqpiVLgO1K7sm5k3gr38ebadjVjGiHD6 +S+G8DDUnKIxcgrtK668V7f8RBAP8eOas5qgoJ79C8M+nUeUHZRxWONuTk90j3R9r +KVFR3kS3f+Vaew3yceGaZcA= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key.keyspec b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key.keyspec new file mode 100644 index 0000000000..cbd5f309c0 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.key.keyspec @@ -0,0 +1 @@ +alternate diff --git a/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem new file mode 100644 index 0000000000..a2e264030a --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIURym6o+VN9xgZXT/QLrvN/nv1ZN4wDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDE1MDEwMTAwMDAwMFoY +DzIwMjUwMTAxMDAwMDAwWjAYMRYwFAYDVQQDDA1PdGhlciB0ZXN0IENBMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXXGUmYJn3cIKmeR8bh2w39c5Tiw +bErNIrHL1G+mWtoq3UHIwkmKxKOzwfYUh/QbaYlBvYClHDwSAkTFhKTESDMF5ROM +AQbPCL6ahidguuai6PNvI8XZgxO53683g0XazlHU1tzSpss8xwbrzTBw7JjM5Aql +kdcpWn9xxb5maR0rLf7ISURZC8Wj6kn9k7HXU0BfF3N2mZWGZiVHl+1CaQiICBFC +IGmYikP+5Izmh4HdIramnNKDdRMfkysSjOKG+n0lHAYq0n7wFvGHzdVOgys1uJMP +dLqQqovHYWckKrH9bWIUDRjEwLjGj8N0hFcyStfehuZVLx0eGR1xIWjTuwIDAQAB +ox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AQEAtXplrvls6HSbbibpzfGxOPmSuh2TH05bE4vQk+d7Kz6EOAFvgTiZbLwTxbrQ +gfrM05t+67C2nAeiwAtW34nUnu6S8MYA6mJjURWICbl7cAvCHuNjg1atVr6f1Y+9 +VFFG6aUibw3bzKneREmDEVcxlEWUaMvv/JjfyMA5veSyX6iTJYkIBrEiVV5Alzg5 +yVHBi6+tpuJDO/YLlG8kmfzkYeJkTyAGx1EJ2yQHim7R232638yb0KrhS4zKsfFU +egHhM4c+MpiCLc9q2EgblbYGx5GM+2leuzXunj1KPClHFrnmkRRm3rcESG2pK9RN +/48Nd38VNofRojEbzDSCdOFmow== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem.certspec new file mode 100644 index 0000000000..3bc975aa22 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/other-test-ca.pem.certspec @@ -0,0 +1,7 @@ +issuer:Other test CA +subject:Other test CA +issuerKey:alternate +subjectKey:alternate +validity:20150101-20250101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem b/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem new file mode 100644 index 0000000000..fdbb9a06db --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDeTCCAmGgAwIBAgIUXSAD8MMxkJHsAS4PFETbUKRZyQ0wDQYJKoZIhvcNAQEL +BQAwMzExMC8GA1UEAwwoVGVzdCBTZWxmLXNpZ25lZCBFbmQtZW50aXR5IHdpdGgg +Q0EgdHJ1ZTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAzMTEw +LwYDVQQDDChUZXN0IFNlbGYtc2lnbmVkIEVuZC1lbnRpdHkgd2l0aCBDQSB0cnVl +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABo4GAMH4wDAYDVR0TBAUwAwEB/zAyBggrBgEFBQcBAQQmMCQwIgYIKwYB +BQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wOgYDVR0RBDMwMYIvc2VsZi1z +aWduZWQtZW5kLWVudGl0eS13aXRoLWNBLXRydWUuZXhhbXBsZS5jb20wDQYJKoZI +hvcNAQELBQADggEBAGSgc1erifMbfX4bRpm4+jylXmCnAnBbdxrQKtSDpMMGZV// +a66yGUEHRQ0SGNWo042NlLvQ52Z5OlS2eocrlny+eKCi7n4mVCjwKKRjZ9zfQU9r +wbKozCA75PTkdYI1GforX4dkWhCCIMRKPDQv/zoI9bikJuMd+fadAjbLUeEiwkOM +xmmDJ5wikGlj0U56+mu+8FN2A9NDDJHRAJd9YoD68cSb/IZSoOUVVsVGokLextDo +/IxkvhignOEko5NWQOu2m6TbiqWzMlvwZZ1FcshgGuilrHpXPPmsbpILtzx3pG8Y +E/PNSVRHKre5sPAEGPkt5q6l9WWUjgmXYnclKuY= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem.certspec new file mode 100644 index 0000000000..0ca92d7fd1 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/self-signed-EE-with-cA-true.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test Self-signed End-entity with CA true +subject:Test Self-signed End-entity with CA true +extension:basicConstraints:cA, +extension:authorityInformationAccess:http://localhost:8888/ +extension:subjectAlternativeName:self-signed-end-entity-with-cA-true.example.com diff --git a/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem b/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem new file mode 100644 index 0000000000..06924b41e9 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhzCCAm+gAwIBAgIUf+URCTKBiuOZl+FIY/BdYQHsrx8wDQYJKoZIhvcNAQEL +BQAwNTEzMDEGA1UEAwwqU2VsZi1zaWduZWQgSW5hZGVxdWF0ZSBFS1UgVGVzdCBF +bmQtZW50aXR5MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMDUx +MzAxBgNVBAMMKlNlbGYtc2lnbmVkIEluYWRlcXVhdGUgRUtVIFRlc3QgRW5kLWVu +dGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1u +togGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6 +pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqL +KkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3Zlqq +fgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3sv +Im9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6za +GAo17Y0CAwEAAaOBijCBhzALBgNVHQ8EBAMCBDAwEwYDVR0lBAwwCgYIKwYBBQUH +AwEwLwYDVR0RBCgwJoIkc2VsZnNpZ25lZC1pbmFkZXF1YXRlRUtVLmV4YW1wbGUu +Y29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9z +dDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAeotRluVjBUDHNaKs8g5VCS5keHXt +nZMRxjAY0P6IqKdlfx3MUR8MbGHpHK1/f+3nzkKUTwemJXpUmsuPTTxOQwN5maSd +0ekOG/Ycdpy3QF6vT0SFlv3AZDmYIAo13qt3mmpFYkaeMbBqXURZzBsdxzNF5IJ9 +bN9BlQzGj7VKd7bAWXAo8HMeR83OzwANONXoMSolT6JN5NX/JRd79Iyl7Vc3WBRy +XDRlr74y5/YvETbQjDBOqi5+vWdceHmX3GekexXqtfnO/oX1hhupnMC+Mzjr3Awi +euQP2QHwdxy0TQg5h8elCLOcYkpAF1IASZ6VFqWpSa/Sobu9hc5laau5TA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem.certspec new file mode 100644 index 0000000000..477b90ce14 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/selfsigned-inadequateEKU.pem.certspec @@ -0,0 +1,6 @@ +issuer:Self-signed Inadequate EKU Test End-entity +subject:Self-signed Inadequate EKU Test End-entity +extension:keyUsage:keyEncipherment,dataEncipherment +extension:extKeyUsage:serverAuth +extension:subjectAlternativeName:selfsigned-inadequateEKU.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem b/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem new file mode 100644 index 0000000000..2743bd61a3 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNzCCAh+gAwIBAgIUR1TNNr+Uv6ZR4ml0F8x6mwwA/lEwDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbU2VsZi1zaWduZWQgVGVzdCBFbmQtZW50aXR5MCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCYxJDAiBgNVBAMMG1NlbGYt +c2lnbmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNZMFcwIQYDVR0RBBowGIIWc2Vs +ZnNpZ25lZC5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGG +Fmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQADggEBADbaX7tZ +XI5N3VzxZ3TUQ07croUVJj7DcduwDS1m2fc2w+Lub1odVm38RQGxvIROyfNdQA2q +Djb5QyKYTnQgfFNR+rOFdDT22pRWzHQ/jqtNUzaxwrO4vGKTlISRrZBRkxde6c8m +7Z5MDu6MyDkfJyFcm5oZX4L84wDTeALRAizR2c6dHT3CxVSqoCVK1hBLe7H5gy7R +nwL6OSFy0FCnibqJwoeSFQbbga9nYsmIm165+r/4qQRrdhrRVZXtZmMmrauua86r +nRqr5ZZWGV3kM3M5mlLiH7UYgYuC2i4XwxGoxuOX7ekX6ro3/grctareAzgsNWzv +8skVQ1O9v6l22b0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem.certspec new file mode 100644 index 0000000000..99a814be17 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/selfsigned.pem.certspec @@ -0,0 +1,4 @@ +issuer:Self-signed Test End-entity +subject:Self-signed Test End-entity +extension:subjectAlternativeName:selfsigned.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/test-ca.pem b/security/manager/ssl/tests/unit/bad_certs/test-ca.pem new file mode 100644 index 0000000000..40515addbd --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUZekW+kmMLmUyacMUQAExM6vEFpswDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjASMRAwDgYDVQQDDAdUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAoabyPFisrr0c +kmPrDCY8pyDZ6ScxE/ziG+5RG4yJzW0QLrnt6rusMdKuxwaLiTISsNI14vh9QQyG +XQsVeiGNGIwyJ9k2ZbLvw6pjdUeaswkthSqUDYwYgCljBwViuFkK4SAwya0Vb0p8 +pErDX8pzSF78inMB/7f0+DPdEQgtAGPYfB0gMRWOliyJSVoJXTgJ2B6PTMMvIcIO +OXcqjDvVYY4o9+YtsDfmzGOSa/YmbM4hO6lv/cO3zv3aT+szyQK8X44koSkvct2P +QL4cY3/incY0l0I12PaScOJDuvITiRNca7gxbUiT2jz1eqzGPIyVS6ku2cO0v9tP +TIiD5XDdFg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/test-ca.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/test-ca.pem.certspec new file mode 100644 index 0000000000..5d2435d7bb --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/test-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test CA +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/test-int.pem b/security/manager/ssl/tests/unit/bad_certs/test-int.pem new file mode 100644 index 0000000000..08249b863e --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/test-int.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIUa0X7/7DlTaedpgrIJg25iBPOkIMwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE1MDEwMTAwMDAwMFoYDzIwMjUw +MTAxMDAwMDAwWjAcMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1 +SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+ +zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYL +K7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwc +bJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibW +JZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMd +MBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEB +AILNZM9yT9ylMpjyi0tXaDORzpHiJ8vEoVKk98bC2BQF0kMEEB547p+Ms8zdJY00 +Bxe9qigT8rQwKprXq5RvgIZ32QLn/yMPiCp/e6zBdsx77TkfmnSnxvPi+0nlA+eM +8JYN0UST4vWD4vPPX9GgZDVoGQTiF3hUivJ5R8sHb/ozcSukMKQQ22+AIU7w6wyA +IbCAG7Pab4k2XFAeEnUZsl9fCym5jsPN9Pnv9rlBi6h8shHw1R2ROXjgxubjiMr3 +B456vFTJImLJjyA1iTSlr/+VXGUYg6Z0/HYnsO00+8xUKM71dPxGAfIFNaSscpyk +rGFLvocT/kym6r8galxCJUo= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/test-int.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/test-int.pem.certspec new file mode 100644 index 0000000000..33b42c2f41 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/test-int.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate +validity:20150101-20250101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem b/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem new file mode 100644 index 0000000000..b2c5370f76 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqTCCApGgAwIBAgIUexjAmwfKg8l4RNHPND1Dh+75sXEwDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbVGVzdCBJbnRlcm1lZGlhdGUgdG8gZGVsZXRlMCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMC4xLDAqBgNVBAMMI1Rlc3Qg +RW5kLWVudGl0eSBmcm9tIHVua25vd24gaXNzdWVyMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4HCMIG/MIGIBgNV +HREEgYAwfoIZdW5rbm93bmlzc3Vlci5leGFtcGxlLmNvbYI0dW5rbm93bmlzc3Vl +ci5pbmNsdWRlLXN1YmRvbWFpbnMucGlubmluZy5leGFtcGxlLmNvbYIrdW5rbm93 +bmlzc3Vlci50ZXN0LW1vZGUucGlubmluZy5leGFtcGxlLmNvbTAyBggrBgEFBQcB +AQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZI +hvcNAQELBQADggEBABITeIp7PtTCDIpSYqXqkf8cibmOkSHPDxBmHxR463rGXNiD +ZGT3ATksVoKh/HugKxb8FC6e2oEszN3bVARypjkMFEmqD2LkC5SIU5KmvU0+E4Eq +cjlvh7rDf0KED3aYXro3QUbmUKg12owyn0xzMqdwlvD6cWT2R6bBC0g6LN11BiLq +/BSMGU+p62LEjhqZjxzBNflGnj5lY9BCIelZ9rhO5WhIFURqZANXKw+MKAwTREl3 +AD1TmJztLABQukbGnYYplmn/COnzPDo//3mTCtYZlg158srgsDMNINfEvPcA2ZsS +Yg/nywbaXMCMyNiSUJJWf8Z/gDX8sfDbD7k/ets= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem.certspec new file mode 100644 index 0000000000..a735c730ca --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/unknownissuer.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate to delete +subject:Test End-entity from unknown issuer +extension:subjectAlternativeName:unknownissuer.example.com,unknownissuer.include-subdomains.pinning.example.com,unknownissuer.test-mode.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem b/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem new file mode 100644 index 0000000000..921d14583f --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIUGTh5myT/JfbNsso9a1ZhGr8B11gwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDExMDEwMTAwMDAwMFoY +DzIwMTMwMTAxMDAwMDAwWjAsMSowKAYDVQQDDCFVbnRydXN0ZWQtRXhwaXJlZCBU +ZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjYDBeMCgGA1UdEQQhMB+CHXVudHJ1c3RlZC1l +eHBpcmVkLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYW +aHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAMktkDNyd +MHFk4K4dcOfi0McOkxvdZW6/Nqts51scx8A3q8sT5pdW3ftBjvN7O+3c1cNGoThG +9SA6uLDV2NT2EQp65yxMZe8j1OHX3qybqZ/RVY5r7VHF4JDsPHHXsgew5+CRGraj +MTIFUqmgAYLMcv74vB0OLIt3JL4XnHVP7atULMLJrOP8QUmkUhZ49MDqyslN0i6w +X7KwhdM00+JKadqUFqOAfhacMHsH5ErsQ3LXrQRMJiFoaVbElMy9e/jJmY7rg4pw +0EMnkt+Vj650FkWsCnLndBia+6z+81L4EZ7uwBeeks2fYhXt85qqkuzmZq2T2diu +ArcEblKIbUYlVg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem.certspec new file mode 100644 index 0000000000..3efd1ce677 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/untrusted-expired.pem.certspec @@ -0,0 +1,5 @@ +issuer:Other test CA +subject:Untrusted-Expired Test End-entity +validity:20110101-20130101 +extension:subjectAlternativeName:untrusted-expired.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem b/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem new file mode 100644 index 0000000000..61cabc2522 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDODCCAiCgAwIBAgIUM0gXawDCbh+O00f2TLkI3uS0aRswDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAwMS4wLAYDVQQDDCVUZXN0IEVuZC1lbnRpdHkgd2l0 +aCB1bnRydXN0ZWQgaXNzdWVyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo14wXDAmBgNVHREEHzAdght1bnRydXN0 +ZWRpc3N1ZXIuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzAB +hhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCoqxjz +UdEXTpLlinCBiDl0BM5qRYcWRM7YKaUAVfX0Wn7Csuk67PQS0armkRUQYJqY8Q1a +/ChTD44Y9dtoe50gIIlWhXfOrVEWQHu36NQZx4uosrFXHmL96EmH4tznvWVydzh8 +4z7NQQ2rg9buiyY5zEyne2S2xDADvnYk/uszUv4AQ2+zQA2oARH3S9OO9VtFy1ZF +wfkt12IGRnv7kptP6YdAbZqCHfXWVc2Dg8lS0OwGxtpRU9bYJZt7ojlIOmUSJjQs +6iXqCUvax1KAWGNosVUlOgU0lEpyG94NkChiwgRgTpUEdnabnme0DYuhhm/suQEZ +/1Tb6W2ER3oiR1I+ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem.certspec new file mode 100644 index 0000000000..5ba0bc2535 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/untrustedissuer.pem.certspec @@ -0,0 +1,4 @@ +issuer:Other test CA +subject:Test End-entity with untrusted issuer +extension:subjectAlternativeName:untrustedissuer.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem b/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem new file mode 100644 index 0000000000..ae4712fe05 --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrzCCAZcCFAOC1GLXYEEbe03otHMT9P0Sz1UpMA0GCSqGSIb3DQEBCwUAMBIx +EDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEjEQMA4GA1UEAwwHVjEgQ2VydDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsFAAOC +AQEAPfp2lSeHPS2M1Snc9ZMJ39bNbpLT3dJpbUFZ8lz3eh3NZEhDNig1ZgINC0Z4 +pwzAmt5Jurq6cHjr4akF+7I3LMmG6mdVrmcQY88ArkfC/PhYvh9eswhzq7C1y7nX +KLFP30U5h9R8Y4+6XEyz+yB9z3Yyf8Pq7a9qWDdPNE9faHU628h74FFu0y+EvSD+ +4CU0Zte8w2+OBracUPne52Gi196rcO0Ic+H0d0PCSgC+KqkTbQjynqpgkGif3W54 +yXflu6sBODd6Xil7qjlw9Bky5VNyLDuKOH+nz+15U3gMfPHm+mJjWXhBjqSyD743 +72mMwbtT7ze7kCeAER4p/a2JZg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem.certspec b/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem.certspec new file mode 100644 index 0000000000..7824630bbc --- /dev/null +++ b/security/manager/ssl/tests/unit/bad_certs/v1Cert.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:V1 Cert +version:1 diff --git a/security/manager/ssl/tests/unit/head_psm.js b/security/manager/ssl/tests/unit/head_psm.js new file mode 100644 index 0000000000..cfec935e86 --- /dev/null +++ b/security/manager/ssl/tests/unit/head_psm.js @@ -0,0 +1,1231 @@ +/* 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/. + */ +"use strict"; + +const { AppConstants } = ChromeUtils.import( + "resource://gre/modules/AppConstants.jsm" +); +const { ctypes } = ChromeUtils.import("resource://gre/modules/ctypes.jsm"); +const { FileUtils } = ChromeUtils.import( + "resource://gre/modules/FileUtils.jsm" +); +const { HttpServer } = ChromeUtils.import("resource://testing-common/httpd.js"); +const { MockRegistrar } = ChromeUtils.import( + "resource://testing-common/MockRegistrar.jsm" +); +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { Promise } = ChromeUtils.import("resource://gre/modules/Promise.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +const { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); + +const { X509 } = ChromeUtils.import("resource://gre/modules/psm/X509.jsm"); + +const isDebugBuild = Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2) + .isDebugBuild; + +// The test EV roots are only enabled in debug builds as a security measure. +const gEVExpected = isDebugBuild; + +const CLIENT_AUTH_FILE_NAME = "ClientAuthRememberList.txt"; +const SSS_STATE_FILE_NAME = "SiteSecurityServiceState.txt"; +const PRELOAD_STATE_FILE_NAME = "SecurityPreloadState.txt"; + +const SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE; +const SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE; +const MOZILLA_PKIX_ERROR_BASE = Ci.nsINSSErrorsService.MOZILLA_PKIX_ERROR_BASE; + +// This isn't really a valid PRErrorCode, but is useful for signalling that +// a test is expected to succeed. +const PRErrorCodeSuccess = 0; + +// Sort in numerical order +const SEC_ERROR_INVALID_TIME = SEC_ERROR_BASE + 8; +const SEC_ERROR_BAD_DER = SEC_ERROR_BASE + 9; +const SEC_ERROR_BAD_SIGNATURE = SEC_ERROR_BASE + 10; +const SEC_ERROR_EXPIRED_CERTIFICATE = SEC_ERROR_BASE + 11; +const SEC_ERROR_REVOKED_CERTIFICATE = SEC_ERROR_BASE + 12; +const SEC_ERROR_UNKNOWN_ISSUER = SEC_ERROR_BASE + 13; +const SEC_ERROR_UNTRUSTED_ISSUER = SEC_ERROR_BASE + 20; +const SEC_ERROR_UNTRUSTED_CERT = SEC_ERROR_BASE + 21; +const SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = SEC_ERROR_BASE + 30; +const SEC_ERROR_CA_CERT_INVALID = SEC_ERROR_BASE + 36; +const SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION = SEC_ERROR_BASE + 41; +const SEC_ERROR_PKCS7_BAD_SIGNATURE = SEC_ERROR_BASE + 47; +const SEC_ERROR_INADEQUATE_KEY_USAGE = SEC_ERROR_BASE + 90; +const SEC_ERROR_INADEQUATE_CERT_TYPE = SEC_ERROR_BASE + 91; +const SEC_ERROR_CERT_NOT_IN_NAME_SPACE = SEC_ERROR_BASE + 112; +const SEC_ERROR_CERT_BAD_ACCESS_LOCATION = SEC_ERROR_BASE + 117; +const SEC_ERROR_OCSP_MALFORMED_REQUEST = SEC_ERROR_BASE + 120; +const SEC_ERROR_OCSP_SERVER_ERROR = SEC_ERROR_BASE + 121; +const SEC_ERROR_OCSP_TRY_SERVER_LATER = SEC_ERROR_BASE + 122; +const SEC_ERROR_OCSP_REQUEST_NEEDS_SIG = SEC_ERROR_BASE + 123; +const SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST = SEC_ERROR_BASE + 124; +const SEC_ERROR_OCSP_UNKNOWN_CERT = SEC_ERROR_BASE + 126; +const SEC_ERROR_OCSP_MALFORMED_RESPONSE = SEC_ERROR_BASE + 129; +const SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE = SEC_ERROR_BASE + 130; +const SEC_ERROR_OCSP_OLD_RESPONSE = SEC_ERROR_BASE + 132; +const SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE = SEC_ERROR_BASE + 141; +const SEC_ERROR_OCSP_INVALID_SIGNING_CERT = SEC_ERROR_BASE + 144; +const SEC_ERROR_POLICY_VALIDATION_FAILED = SEC_ERROR_BASE + 160; +const SEC_ERROR_OCSP_BAD_SIGNATURE = SEC_ERROR_BASE + 157; +const SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED = SEC_ERROR_BASE + 176; + +const SSL_ERROR_NO_CYPHER_OVERLAP = SSL_ERROR_BASE + 2; +const SSL_ERROR_BAD_CERT_DOMAIN = SSL_ERROR_BASE + 12; +const SSL_ERROR_BAD_CERT_ALERT = SSL_ERROR_BASE + 17; +const SSL_ERROR_WEAK_SERVER_CERT_KEY = SSL_ERROR_BASE + 132; +const SSL_ERROR_DC_INVALID_KEY_USAGE = SSL_ERROR_BASE + 184; + +const SSL_ERROR_ECH_RETRY_WITH_ECH = SSL_ERROR_BASE + 188; +const SSL_ERROR_ECH_RETRY_WITHOUT_ECH = SSL_ERROR_BASE + 189; +const SSL_ERROR_ECH_FAILED = SSL_ERROR_BASE + 190; +const SSL_ERROR_ECH_REQUIRED_ALERT = SSL_ERROR_BASE + 191; + +const MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE = MOZILLA_PKIX_ERROR_BASE + 0; +const MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY = + MOZILLA_PKIX_ERROR_BASE + 1; +const MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE = MOZILLA_PKIX_ERROR_BASE + 2; +const MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA = MOZILLA_PKIX_ERROR_BASE + 3; +const MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE = + MOZILLA_PKIX_ERROR_BASE + 5; +const MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE = + MOZILLA_PKIX_ERROR_BASE + 6; +const MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING = + MOZILLA_PKIX_ERROR_BASE + 8; +const MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING = + MOZILLA_PKIX_ERROR_BASE + 10; +const MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME = MOZILLA_PKIX_ERROR_BASE + 12; +const MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED = + MOZILLA_PKIX_ERROR_BASE + 13; +const MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT = MOZILLA_PKIX_ERROR_BASE + 14; +const MOZILLA_PKIX_ERROR_MITM_DETECTED = MOZILLA_PKIX_ERROR_BASE + 15; + +// Supported Certificate Usages +const certificateUsageSSLClient = 0x0001; +const certificateUsageSSLServer = 0x0002; +const certificateUsageSSLCA = 0x0008; +const certificateUsageEmailSigner = 0x0010; +const certificateUsageEmailRecipient = 0x0020; + +// A map from the name of a certificate usage to the value of the usage. +// Useful for printing debugging information and for enumerating all supported +// usages. +const allCertificateUsages = { + certificateUsageSSLClient, + certificateUsageSSLServer, + certificateUsageSSLCA, + certificateUsageEmailSigner, + certificateUsageEmailRecipient, +}; + +const NO_FLAGS = 0; + +const CRLiteModeDisabledPrefValue = 0; +const CRLiteModeTelemetryOnlyPrefValue = 1; +const CRLiteModeEnforcePrefValue = 2; + +// Convert a string to an array of bytes consisting of the char code at each +// index. +function stringToArray(s) { + let a = []; + for (let i = 0; i < s.length; i++) { + a.push(s.charCodeAt(i)); + } + return a; +} + +// Converts an array of bytes to a JS string using fromCharCode on each byte. +function arrayToString(a) { + let s = ""; + for (let b of a) { + s += String.fromCharCode(b); + } + return s; +} + +// Commonly certificates are represented as PEM. The format is roughly as +// follows: +// +// -----BEGIN CERTIFICATE----- +// [some lines of base64, each typically 64 characters long] +// -----END CERTIFICATE----- +// +// However, nsIX509CertDB.constructX509FromBase64 and related functions do not +// handle input of this form. Instead, they require a single string of base64 +// with no newlines or BEGIN/END headers. This is a helper function to convert +// PEM to the format that nsIX509CertDB requires. +function pemToBase64(pem) { + return pem + .replace(/-----BEGIN CERTIFICATE-----/, "") + .replace(/-----END CERTIFICATE-----/, "") + .replace(/[\r\n]/g, ""); +} + +function build_cert_chain(certNames, testDirectory = "bad_certs") { + let certList = []; + certNames.forEach(function(certName) { + let cert = constructCertFromFile(`${testDirectory}/${certName}.pem`); + certList.push(cert); + }); + return certList; +} + +function areCertArraysEqual(certArrayA, certArrayB) { + if (certArrayA.length != certArrayB.length) { + return false; + } + + for (let i = 0; i < certArrayA.length; i++) { + const certA = certArrayA[i]; + const certB = certArrayB[i]; + if (!certA.equals(certB)) { + return false; + } + } + return true; +} + +function readFile(file) { + let fstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance( + Ci.nsIFileInputStream + ); + fstream.init(file, -1, 0, 0); + let available = fstream.available(); + let data = + available > 0 ? NetUtil.readInputStreamToString(fstream, available) : ""; + fstream.close(); + return data; +} + +function addCertFromFile(certdb, filename, trustString) { + let certFile = do_get_file(filename, false); + let certBytes = readFile(certFile); + try { + return certdb.addCert(certBytes, trustString); + } catch (e) {} + // It might be PEM instead of DER. + return certdb.addCertFromBase64(pemToBase64(certBytes), trustString); +} + +function constructCertFromFile(filename) { + let certFile = do_get_file(filename, false); + let certBytes = readFile(certFile); + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + try { + return certdb.constructX509(stringToArray(certBytes)); + } catch (e) {} + // It might be PEM instead of DER. + return certdb.constructX509FromBase64(pemToBase64(certBytes)); +} + +function setCertTrust(cert, trustString) { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + certdb.setCertTrustFromString(cert, trustString); +} + +function getXPCOMStatusFromNSS(statusNSS) { + let nssErrorsService = Cc["@mozilla.org/nss_errors_service;1"].getService( + Ci.nsINSSErrorsService + ); + return nssErrorsService.getXPCOMFromNSSError(statusNSS); +} + +// Helper for checkCertErrorGenericAtTime +class CertVerificationExpectedErrorResult { + constructor(certName, expectedError, expectedEVStatus, resolve) { + this.certName = certName; + this.expectedError = expectedError; + this.expectedEVStatus = expectedEVStatus; + this.resolve = resolve; + } + + verifyCertFinished(aPRErrorCode, aVerifiedChain, aHasEVPolicy) { + equal( + aPRErrorCode, + this.expectedError, + `verifying ${this.certName}: should get error ${this.expectedError}` + ); + if (this.expectedEVStatus != undefined) { + equal( + aHasEVPolicy, + this.expectedEVStatus, + `verifying ${this.certName}: ` + + `should ${this.expectedEVStatus ? "be" : "not be"} EV` + ); + } + this.resolve(); + } +} + +// certdb implements nsIX509CertDB. See nsIX509CertDB.idl for documentation. +// In particular, hostname is optional. +function checkCertErrorGenericAtTime( + certdb, + cert, + expectedError, + usage, + time, + /* optional */ isEVExpected, + /* optional */ hostname, + /* optional */ flags = NO_FLAGS +) { + return new Promise((resolve, reject) => { + let result = new CertVerificationExpectedErrorResult( + cert.commonName, + expectedError, + isEVExpected, + resolve + ); + certdb.asyncVerifyCertAtTime(cert, usage, flags, hostname, time, result); + }); +} + +// certdb implements nsIX509CertDB. See nsIX509CertDB.idl for documentation. +// In particular, hostname is optional. +function checkCertErrorGeneric( + certdb, + cert, + expectedError, + usage, + /* optional */ isEVExpected, + /* optional */ hostname +) { + let now = new Date().getTime() / 1000; + return checkCertErrorGenericAtTime( + certdb, + cert, + expectedError, + usage, + now, + isEVExpected, + hostname + ); +} + +function checkEVStatus(certDB, cert, usage, isEVExpected) { + return checkCertErrorGeneric( + certDB, + cert, + PRErrorCodeSuccess, + usage, + isEVExpected + ); +} + +function _getLibraryFunctionWithNoArguments( + functionName, + libraryName, + returnType +) { + // Open the NSS library. copied from services/crypto/modules/WeaveCrypto.js + let path = ctypes.libraryName(libraryName); + + // XXX really want to be able to pass specific dlopen flags here. + let nsslib; + try { + nsslib = ctypes.open(path); + } catch (e) { + // In case opening the library without a full path fails, + // try again with a full path. + let file = Services.dirsvc.get("GreBinD", Ci.nsIFile); + file.append(path); + nsslib = ctypes.open(file.path); + } + + let SECStatus = ctypes.int; + let func = nsslib.declare( + functionName, + ctypes.default_abi, + returnType || SECStatus + ); + return func; +} + +function clearOCSPCache() { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + certdb.clearOCSPCache(); +} + +function clearSessionCache() { + let nssComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsINSSComponent); + nssComponent.clearSSLExternalAndInternalSessionCache(); +} + +function getSSLStatistics() { + let SSL3Statistics = new ctypes.StructType("SSL3Statistics", [ + { sch_sid_cache_hits: ctypes.long }, + { sch_sid_cache_misses: ctypes.long }, + { sch_sid_cache_not_ok: ctypes.long }, + { hsh_sid_cache_hits: ctypes.long }, + { hsh_sid_cache_misses: ctypes.long }, + { hsh_sid_cache_not_ok: ctypes.long }, + { hch_sid_cache_hits: ctypes.long }, + { hch_sid_cache_misses: ctypes.long }, + { hch_sid_cache_not_ok: ctypes.long }, + { sch_sid_stateless_resumes: ctypes.long }, + { hsh_sid_stateless_resumes: ctypes.long }, + { hch_sid_stateless_resumes: ctypes.long }, + { hch_sid_ticket_parse_failures: ctypes.long }, + ]); + let SSL3StatisticsPtr = new ctypes.PointerType(SSL3Statistics); + let SSL_GetStatistics = null; + try { + SSL_GetStatistics = _getLibraryFunctionWithNoArguments( + "SSL_GetStatistics", + "ssl3", + SSL3StatisticsPtr + ); + } catch (e) { + // On Windows, this is actually in the nss3 library. + SSL_GetStatistics = _getLibraryFunctionWithNoArguments( + "SSL_GetStatistics", + "nss3", + SSL3StatisticsPtr + ); + } + if (!SSL_GetStatistics) { + throw new Error("Failed to get SSL statistics"); + } + return SSL_GetStatistics(); +} + +// Set up a TLS testing environment that has a TLS server running and +// ready to accept connections. This async function starts the server and +// waits for the server to indicate that it is ready. +// +// Each test should have its own subdomain of example.com, for example +// my-first-connection-test.example.com. The server can use the server +// name (passed through the SNI TLS extension) to determine what behavior +// the server side of the text should exhibit. See TLSServer.h for more +// information on how to write the server side of tests. +// +// Create a new source file for your new server executable in +// security/manager/ssl/tests/unit/tlsserver/cmd similar to the other ones in +// that directory, and add a reference to it to the sources variable in that +// directory's moz.build. +// +// Modify TEST_HARNESS_BINS in +// testing/mochitest/Makefile.in and NO_PKG_FILES in +// toolkit/mozapps/installer/packager.mk to make sure the new executable +// gets included in the packages used for shipping the tests to the test +// runners in our build/test farm. (Things will work fine locally without +// these changes but will break on TBPL.) +// +// Your test script should look something like this: +/* + +// -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// 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/. +"use strict"; + +// + +function run_test() { + do_get_profile(); + add_tls_server_setup("", ""); + + add_connection_test(".example.com", + SEC_ERROR_xxx, + function() { ... }, + function(aTransportSecurityInfo) { ... }, + function(aTransport) { ... }); + [...] + add_connection_test(".example.com", PRErrorCodeSuccess); + + run_next_test(); +} +*/ + +function add_tls_server_setup(serverBinName, certsPath, addDefaultRoot = true) { + add_test(function() { + _setupTLSServerTest(serverBinName, certsPath, addDefaultRoot); + }); +} + +/** + * Add a TLS connection test case. + * + * @param {String} aHost + * The hostname to pass in the SNI TLS extension; this should unambiguously + * identify which test is being run. + * @param {PRErrorCode} aExpectedResult + * The expected result of the connection. If an error is not expected, pass + * in PRErrorCodeSuccess. + * @param {Function} aBeforeConnect + * A callback function that takes no arguments that will be called before the + * connection is attempted. + * @param {Function} aWithSecurityInfo + * A callback function that takes an nsITransportSecurityInfo, which is called + * after the TLS handshake succeeds. + * @param {Function} aAfterStreamOpen + * A callback function that is called with the nsISocketTransport once the + * output stream is ready. + * @param {OriginAttributes} aOriginAttributes (optional) + * The origin attributes that the socket transport will have. This parameter + * affects OCSP because OCSP cache is double-keyed by origin attributes' first + * party domain. + * + * @param {OriginAttributes} aEchConfig (optional) + * A Base64-encoded ECHConfig. If non-empty, it will be configured to the client + * socket resulting in an Encrypted Client Hello extension being sent. The client + * keypair is ephermeral and generated within NSS. + */ +function add_connection_test( + aHost, + aExpectedResult, + aBeforeConnect, + aWithSecurityInfo, + aAfterStreamOpen, + /* optional */ aOriginAttributes, + /* optional */ aEchConfig +) { + add_test(function() { + if (aBeforeConnect) { + aBeforeConnect(); + } + asyncConnectTo( + aHost, + aExpectedResult, + aWithSecurityInfo, + aAfterStreamOpen, + aOriginAttributes, + aEchConfig + ).then(run_next_test); + }); +} + +async function asyncConnectTo( + aHost, + aExpectedResult, + /* optional */ aWithSecurityInfo = undefined, + /* optional */ aAfterStreamOpen = undefined, + /* optional */ aOriginAttributes = undefined, + /* optional */ aEchConfig = undefined +) { + const REMOTE_PORT = 8443; + + function Connection(host) { + this.host = host; + this.thread = Services.tm.currentThread; + this.defer = Promise.defer(); + let sts = Cc["@mozilla.org/network/socket-transport-service;1"].getService( + Ci.nsISocketTransportService + ); + this.transport = sts.createTransport(["ssl"], host, REMOTE_PORT, null); + if (aEchConfig) { + this.transport.setEchConfig(atob(aEchConfig)); + } + // See bug 1129771 - attempting to connect to [::1] when the server is + // listening on 127.0.0.1 causes frequent failures on OS X 10.10. + this.transport.connectionFlags |= Ci.nsISocketTransport.DISABLE_IPV6; + this.transport.setEventSink(this, this.thread); + if (aOriginAttributes) { + this.transport.originAttributes = aOriginAttributes; + } + this.inputStream = null; + this.outputStream = null; + this.connected = false; + } + + Connection.prototype = { + // nsITransportEventSink + onTransportStatus(aTransport, aStatus, aProgress, aProgressMax) { + if ( + !this.connected && + aStatus == Ci.nsISocketTransport.STATUS_CONNECTED_TO + ) { + this.connected = true; + this.outputStream.asyncWait(this, 0, 0, this.thread); + } + }, + + // nsIInputStreamCallback + onInputStreamReady(aStream) { + try { + // this will throw if the stream has been closed by an error + let str = NetUtil.readInputStreamToString(aStream, aStream.available()); + Assert.equal(str, "0", "Should have received ASCII '0' from server"); + this.inputStream.close(); + this.outputStream.close(); + this.result = Cr.NS_OK; + } catch (e) { + this.result = e.result; + } + this.defer.resolve(this); + }, + + // nsIOutputStreamCallback + onOutputStreamReady(aStream) { + if (aAfterStreamOpen) { + aAfterStreamOpen(this.transport); + } + this.outputStream.write("0", 1); + let inStream = this.transport + .openInputStream(0, 0, 0) + .QueryInterface(Ci.nsIAsyncInputStream); + this.inputStream = inStream; + this.inputStream.asyncWait(this, 0, 0, this.thread); + }, + + go() { + this.outputStream = this.transport + .openOutputStream(0, 0, 0) + .QueryInterface(Ci.nsIAsyncOutputStream); + return this.defer.promise; + }, + }; + + /* Returns a promise to connect to host that resolves to the result of that + * connection */ + function connectTo(host) { + Services.prefs.setCharPref("network.dns.localDomains", host); + let connection = new Connection(host); + return connection.go(); + } + + return connectTo(aHost).then(function(conn) { + info("handling " + aHost); + let expectedNSResult = + aExpectedResult == PRErrorCodeSuccess + ? Cr.NS_OK + : getXPCOMStatusFromNSS(aExpectedResult); + Assert.equal( + conn.result, + expectedNSResult, + "Actual and expected connection result should match" + ); + if (aWithSecurityInfo) { + aWithSecurityInfo( + conn.transport.securityInfo.QueryInterface(Ci.nsITransportSecurityInfo) + ); + } + }); +} + +function _getBinaryUtil(binaryUtilName) { + let utilBin = Services.dirsvc.get("GreD", Ci.nsIFile); + // On macOS, GreD is .../Contents/Resources, and most binary utilities + // are located there, but certutil is in GreBinD (or .../Contents/MacOS), + // so we have to change the path accordingly. + if (binaryUtilName === "certutil") { + utilBin = Services.dirsvc.get("GreBinD", Ci.nsIFile); + } + utilBin.append(binaryUtilName + mozinfo.bin_suffix); + // If we're testing locally, the above works. If not, the server executable + // is in another location. + if (!utilBin.exists()) { + utilBin = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + while (utilBin.path.includes("xpcshell")) { + utilBin = utilBin.parent; + } + utilBin.append("bin"); + utilBin.append(binaryUtilName + mozinfo.bin_suffix); + } + // But maybe we're on Android, where binaries are in /data/local/xpcb. + if (!utilBin.exists()) { + utilBin.initWithPath("/data/local/xpcb/"); + utilBin.append(binaryUtilName); + } + Assert.ok(utilBin.exists(), `Binary util ${binaryUtilName} should exist`); + return utilBin; +} + +// Do not call this directly; use add_tls_server_setup +function _setupTLSServerTest(serverBinName, certsPath, addDefaultRoot) { + asyncStartTLSTestServer(serverBinName, certsPath, addDefaultRoot).then( + run_next_test + ); +} + +async function asyncStartTLSTestServer( + serverBinName, + certsPath, + addDefaultRoot +) { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + // The trusted CA that is typically used for "good" certificates. + if (addDefaultRoot) { + addCertFromFile(certdb, `${certsPath}/test-ca.pem`, "CTu,u,u"); + } + + const CALLBACK_PORT = 8444; + + let envSvc = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment + ); + let greBinDir = Services.dirsvc.get("GreBinD", Ci.nsIFile); + envSvc.set("DYLD_LIBRARY_PATH", greBinDir.path); + // TODO(bug 1107794): Android libraries are in /data/local/xpcb, but "GreBinD" + // does not return this path on Android, so hard code it here. + envSvc.set("LD_LIBRARY_PATH", greBinDir.path + ":/data/local/xpcb"); + envSvc.set("MOZ_TLS_SERVER_DEBUG_LEVEL", "3"); + envSvc.set("MOZ_TLS_SERVER_CALLBACK_PORT", CALLBACK_PORT); + + let httpServer = new HttpServer(); + let serverReady = new Promise(resolve => { + httpServer.registerPathHandler("/", function handleServerCallback( + aRequest, + aResponse + ) { + aResponse.setStatusLine(aRequest.httpVersion, 200, "OK"); + aResponse.setHeader("Content-Type", "text/plain"); + let responseBody = "OK!"; + aResponse.bodyOutputStream.write(responseBody, responseBody.length); + executeSoon(function() { + httpServer.stop(resolve); + }); + }); + httpServer.start(CALLBACK_PORT); + }); + + let serverBin = _getBinaryUtil(serverBinName); + let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); + process.init(serverBin); + let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + certDir.append(`${certsPath}`); + Assert.ok(certDir.exists(), `certificate folder (${certsPath}) should exist`); + // Using "sql:" causes the SQL DB to be used so we can run tests on Android. + process.run(false, ["sql:" + certDir.path, Services.appinfo.processID], 2); + + registerCleanupFunction(function() { + process.kill(); + }); + + await serverReady; +} + +// Returns an Array of OCSP responses for a given ocspRespArray and a location +// for a nssDB where the certs and public keys are prepopulated. +// ocspRespArray is an array of arrays like: +// [ [typeOfResponse, certnick, extracertnick, thisUpdateSkew]...] +function generateOCSPResponses(ocspRespArray, nssDBlocation) { + let utilBinName = "GenerateOCSPResponse"; + let ocspGenBin = _getBinaryUtil(utilBinName); + let retArray = []; + + for (let i = 0; i < ocspRespArray.length; i++) { + let argArray = []; + let ocspFilepre = do_get_file(i.toString() + ".ocsp", true); + let filename = ocspFilepre.path; + // Using "sql:" causes the SQL DB to be used so we can run tests on Android. + argArray.push("sql:" + nssDBlocation); + argArray.push(ocspRespArray[i][0]); // ocsRespType; + argArray.push(ocspRespArray[i][1]); // nick; + argArray.push(ocspRespArray[i][2]); // extranickname + argArray.push(ocspRespArray[i][3]); // thisUpdate skew + argArray.push(filename); + info("argArray = " + argArray); + + let process = Cc["@mozilla.org/process/util;1"].createInstance( + Ci.nsIProcess + ); + process.init(ocspGenBin); + process.run(true, argArray, argArray.length); + Assert.equal(0, process.exitValue, "Process exit value should be 0"); + let ocspFile = do_get_file(i.toString() + ".ocsp", false); + retArray.push(readFile(ocspFile)); + ocspFile.remove(false); + } + return retArray; +} + +// Starts and returns an http responder that will cause a test failure if it is +// queried. The server identities are given by a non-empty array +// serverIdentities. +function getFailingHttpServer(serverPort, serverIdentities) { + let httpServer = new HttpServer(); + httpServer.registerPrefixHandler("/", function(request, response) { + Assert.ok(false, "HTTP responder should not have been queried"); + }); + httpServer.identity.setPrimary("http", serverIdentities.shift(), serverPort); + serverIdentities.forEach(function(identity) { + httpServer.identity.add("http", identity, serverPort); + }); + httpServer.start(serverPort); + return httpServer; +} + +// Starts an http OCSP responder that serves good OCSP responses and +// returns an object with a method stop that should be called to stop +// the http server. +// NB: Because generating OCSP responses inside the HTTP request +// handler can cause timeouts, the expected responses are pre-generated +// all at once before starting the server. This means that their producedAt +// times will all be the same. If a test depends on this not being the case, +// perhaps calling startOCSPResponder twice (at different times) will be +// necessary. +// +// serverPort is the port of the http OCSP responder +// identity is the http hostname that will answer the OCSP requests +// nssDBLocation is the location of the NSS database from where the OCSP +// responses will be generated (assumes appropiate keys are present) +// expectedCertNames is an array of nicks of the certs to be responsed +// expectedBasePaths is an optional array that is used to indicate +// what is the expected base path of the OCSP request. +// expectedMethods is an optional array of methods ("GET" or "POST") indicating +// by which HTTP method the server is expected to be queried. +// expectedResponseTypes is an optional array of OCSP response types to use (see +// GenerateOCSPResponse.cpp). +// responseHeaderPairs is an optional array of HTTP header (name, value) pairs +// to set in each response. +function startOCSPResponder( + serverPort, + identity, + nssDBLocation, + expectedCertNames, + expectedBasePaths, + expectedMethods, + expectedResponseTypes, + responseHeaderPairs = [] +) { + let ocspResponseGenerationArgs = expectedCertNames.map(function( + expectedNick + ) { + let responseType = "good"; + if (expectedResponseTypes && expectedResponseTypes.length >= 1) { + responseType = expectedResponseTypes.shift(); + } + return [responseType, expectedNick, "unused", 0]; + }); + let ocspResponses = generateOCSPResponses( + ocspResponseGenerationArgs, + nssDBLocation + ); + let httpServer = new HttpServer(); + httpServer.registerPrefixHandler("/", function handleServerCallback( + aRequest, + aResponse + ) { + info("got request for: " + aRequest.path); + let basePath = aRequest.path.slice(1).split("/")[0]; + if (expectedBasePaths.length >= 1) { + Assert.equal( + basePath, + expectedBasePaths.shift(), + "Actual and expected base path should match" + ); + } + Assert.ok( + expectedCertNames.length >= 1, + "expectedCertNames should contain >= 1 entries" + ); + if (expectedMethods && expectedMethods.length >= 1) { + Assert.equal( + aRequest.method, + expectedMethods.shift(), + "Actual and expected fetch method should match" + ); + } + aResponse.setStatusLine(aRequest.httpVersion, 200, "OK"); + aResponse.setHeader("Content-Type", "application/ocsp-response"); + for (let headerPair of responseHeaderPairs) { + aResponse.setHeader(headerPair[0], headerPair[1]); + } + aResponse.write(ocspResponses.shift()); + }); + httpServer.identity.setPrimary("http", identity, serverPort); + httpServer.start(serverPort); + return { + stop(callback) { + // make sure we consumed each expected response + Assert.equal( + ocspResponses.length, + 0, + "Should have 0 remaining expected OCSP responses" + ); + if (expectedMethods) { + Assert.equal( + expectedMethods.length, + 0, + "Should have 0 remaining expected fetch methods" + ); + } + if (expectedBasePaths) { + Assert.equal( + expectedBasePaths.length, + 0, + "Should have 0 remaining expected base paths" + ); + } + if (expectedResponseTypes) { + Assert.equal( + expectedResponseTypes.length, + 0, + "Should have 0 remaining expected response types" + ); + } + httpServer.stop(callback); + }, + }; +} + +// Given an OCSP responder (see startOCSPResponder), returns a promise that +// resolves when the responder has successfully stopped. +function stopOCSPResponder(responder) { + return new Promise((resolve, reject) => { + responder.stop(resolve); + }); +} + +// Utility functions for adding tests relating to certificate error overrides + +// Helper function for add_cert_override_test. Probably doesn't need to be +// called directly. +function add_cert_override(aHost, aExpectedBits, aSecurityInfo) { + let bits = + (aSecurityInfo.isUntrusted + ? Ci.nsICertOverrideService.ERROR_UNTRUSTED + : 0) | + (aSecurityInfo.isDomainMismatch + ? Ci.nsICertOverrideService.ERROR_MISMATCH + : 0) | + (aSecurityInfo.isNotValidAtThisTime + ? Ci.nsICertOverrideService.ERROR_TIME + : 0); + + Assert.equal( + bits, + aExpectedBits, + "Actual and expected override bits should match" + ); + let cert = aSecurityInfo.serverCert; + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.rememberValidityOverride( + aHost, + 8443, + cert, + aExpectedBits, + true + ); +} + +// Given a host, expected error bits (see nsICertOverrideService.idl), and an +// expected error code, tests that an initial connection to the host fails +// with the expected errors and that adding an override results in a subsequent +// connection succeeding. +function add_cert_override_test( + aHost, + aExpectedBits, + aExpectedError, + aExpectedSecInfo = undefined +) { + add_connection_test( + aHost, + aExpectedError, + null, + add_cert_override.bind(this, aHost, aExpectedBits) + ); + add_connection_test(aHost, PRErrorCodeSuccess, null, aSecurityInfo => { + Assert.ok( + aSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN, + "Cert override flag should be set on the security state" + ); + if (aExpectedSecInfo) { + if (aExpectedSecInfo.failedCertChain) { + ok( + aExpectedSecInfo.failedCertChain.equals(aSecurityInfo.failedCertChain) + ); + } + } + }); +} + +// Helper function for add_prevented_cert_override_test. This is much like +// add_cert_override except it may not be the case that the connection has an +// SecInfo set on it. In this case, the error was not overridable anyway, so +// we consider it a success. +function attempt_adding_cert_override(aHost, aExpectedBits, aSecurityInfo) { + if (aSecurityInfo.serverCert) { + let bits = + (aSecurityInfo.isUntrusted + ? Ci.nsICertOverrideService.ERROR_UNTRUSTED + : 0) | + (aSecurityInfo.isDomainMismatch + ? Ci.nsICertOverrideService.ERROR_MISMATCH + : 0) | + (aSecurityInfo.isNotValidAtThisTime + ? Ci.nsICertOverrideService.ERROR_TIME + : 0); + Assert.equal( + bits, + aExpectedBits, + "Actual and expected override bits should match" + ); + let cert = aSecurityInfo.serverCert; + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.rememberValidityOverride( + aHost, + 8443, + cert, + aExpectedBits, + true + ); + } +} + +// Given a host, expected error bits (see nsICertOverrideService.idl), and +// an expected error code, tests that an initial connection to the host fails +// with the expected errors and that adding an override does not result in a +// subsequent connection succeeding (i.e. the same error code is encountered). +// The idea here is that for HSTS hosts or hosts with key pins, no error is +// overridable, even if an entry is added to the override service. +function add_prevented_cert_override_test( + aHost, + aExpectedBits, + aExpectedError +) { + add_connection_test( + aHost, + aExpectedError, + null, + attempt_adding_cert_override.bind(this, aHost, aExpectedBits) + ); + add_connection_test(aHost, aExpectedError); +} + +// Helper for asyncTestCertificateUsages. +class CertVerificationResult { + constructor(certName, usageString, successExpected, resolve) { + this.certName = certName; + this.usageString = usageString; + this.successExpected = successExpected; + this.resolve = resolve; + } + + verifyCertFinished(aPRErrorCode, aVerifiedChain, aHasEVPolicy) { + if (this.successExpected) { + equal( + aPRErrorCode, + PRErrorCodeSuccess, + `verifying ${this.certName} for ${this.usageString} should succeed` + ); + } else { + notEqual( + aPRErrorCode, + PRErrorCodeSuccess, + `verifying ${this.certName} for ${this.usageString} should fail` + ); + } + this.resolve(); + } +} + +/** + * Asynchronously attempts to verify the given certificate for all supported + * usages (see allCertificateUsages). Verifies that the results match the + * expected successful usages. Returns a promise that will resolve when all + * verifications have been performed. + * Verification happens "now" with no specified flags or hostname. + * + * @param {nsIX509CertDB} certdb + * The certificate database to use to verify the certificate. + * @param {nsIX509Cert} cert + * The certificate to be verified. + * @param {Number[]} expectedUsages + * A list of usages (as their integer values) that are expected to verify + * successfully. + * @return {Promise} + * A promise that will resolve with no value when all asynchronous operations + * have completed. + */ +function asyncTestCertificateUsages(certdb, cert, expectedUsages) { + let now = new Date().getTime() / 1000; + let promises = []; + Object.keys(allCertificateUsages).forEach(usageString => { + let promise = new Promise((resolve, reject) => { + let usage = allCertificateUsages[usageString]; + let successExpected = expectedUsages.includes(usage); + let result = new CertVerificationResult( + cert.commonName, + usageString, + successExpected, + resolve + ); + let flags = Ci.nsIX509CertDB.FLAG_LOCAL_ONLY; + certdb.asyncVerifyCertAtTime(cert, usage, flags, null, now, result); + }); + promises.push(promise); + }); + return Promise.all(promises); +} + +/** + * Loads the pkcs11testmodule.cpp test PKCS #11 module, and registers a cleanup + * function that unloads it once the calling test completes. + * + * @param {nsIFile} libraryFile + * The dynamic library file that implements the module to + * load. + * @param {String} moduleName + * What to call the module. + * @param {Boolean} expectModuleUnloadToFail + * Should be set to true for tests that manually unload the + * test module, so the attempt to auto unload the test module + * doesn't cause a test failure. Should be set to false + * otherwise, so failure to automatically unload the test + * module gets reported. + */ +function loadPKCS11Module(libraryFile, moduleName, expectModuleUnloadToFail) { + ok(libraryFile.exists(), "The PKCS11 module file should exist"); + + let pkcs11ModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + registerCleanupFunction(() => { + try { + pkcs11ModuleDB.deleteModule(moduleName); + } catch (e) { + Assert.ok( + expectModuleUnloadToFail, + `Module unload should suceed only when expected: ${e}` + ); + } + }); + pkcs11ModuleDB.addModule(moduleName, libraryFile.path, 0, 0); +} + +/** + * @param {String} data + * @returns {String} + */ +function hexify(data) { + // |slice(-2)| chomps off the last two characters of a string. + // Therefore, if the Unicode value is < 0x10, we have a single-character hex + // string when we want one that's two characters, and unconditionally + // prepending a "0" solves the problem. + return Array.from(data, (c, i) => + ("0" + data.charCodeAt(i).toString(16)).slice(-2) + ).join(""); +} + +/** + * @param {String[]} lines + * Lines to write. Each line automatically has "\n" appended to it when + * being written. + * @param {nsIFileOutputStream} outputStream + */ +function writeLinesAndClose(lines, outputStream) { + for (let line of lines) { + line += "\n"; + outputStream.write(line, line.length); + } + outputStream.close(); +} + +/** + * @param {String} moduleName + * The name of the module that should not be loaded. + * @param {String} libraryName + * A unique substring of name of the dynamic library file of the module + * that should not be loaded. + */ +function checkPKCS11ModuleNotPresent(moduleName, libraryName) { + let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + let modules = moduleDB.listModules(); + ok( + modules.hasMoreElements(), + "One or more modules should be present with test module not present" + ); + for (let module of modules) { + notEqual( + module.name, + moduleName, + `Non-test module name shouldn't equal '${moduleName}'` + ); + ok( + !(module.libName && module.libName.includes(libraryName)), + `Non-test module lib name should not include '${libraryName}'` + ); + } +} + +/** + * Checks that the test module exists in the module list. + * Also checks various attributes of the test module for correctness. + * + * @param {String} moduleName + * The name of the module that should be present. + * @param {String} libraryName + * A unique substring of the name of the dynamic library file + * of the module that should be loaded. + * @returns {nsIPKCS11Module} + * The test module. + */ +function checkPKCS11ModuleExists(moduleName, libraryName) { + let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + let modules = moduleDB.listModules(); + ok( + modules.hasMoreElements(), + "One or more modules should be present with test module present" + ); + let testModule = null; + for (let module of modules) { + if (module.name == moduleName) { + testModule = module; + break; + } + } + notEqual(testModule, null, "Test module should have been found"); + notEqual(testModule.libName, null, "Test module lib name should not be null"); + ok( + testModule.libName.includes(ctypes.libraryName(libraryName)), + `Test module lib name should include lib name of '${libraryName}'` + ); + + return testModule; +} + +// Given an nsIX509Cert, return the bytes of its subject DN (as a JS string) and +// the sha-256 hash of its subject public key info, base64-encoded. +function getSubjectAndSPKIHash(nsCert) { + let certBytes = nsCert.getRawDER(); + let cert = new X509.Certificate(); + cert.parse(certBytes); + let subject = cert.tbsCertificate.subject._der._bytes; + let subjectString = arrayToString(subject); + let spkiHashString = nsCert.sha256SubjectPublicKeyInfoDigest; + return { subjectString, spkiHashString }; +} + +function run_certutil_on_directory(directory, args, expectSuccess = true) { + let envSvc = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment + ); + let greBinDir = Services.dirsvc.get("GreBinD", Ci.nsIFile); + envSvc.set("DYLD_LIBRARY_PATH", greBinDir.path); + // TODO(bug 1107794): Android libraries are in /data/local/xpcb, but "GreBinD" + // does not return this path on Android, so hard code it here. + envSvc.set("LD_LIBRARY_PATH", greBinDir.path + ":/data/local/xpcb"); + let certutilBin = _getBinaryUtil("certutil"); + let process = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess); + process.init(certutilBin); + args.push("-d"); + args.push(`sql:${directory}`); + process.run(true, args, args.length); + if (expectSuccess) { + Assert.equal(process.exitValue, 0, "certutil should succeed"); + } +} diff --git a/security/manager/ssl/tests/unit/moz.build b/security/manager/ssl/tests/unit/moz.build new file mode 100644 index 0000000000..212f14a22f --- /dev/null +++ b/security/manager/ssl/tests/unit/moz.build @@ -0,0 +1,42 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +DIRS += ["tlsserver"] + +if not CONFIG["MOZ_NO_SMART_CARDS"]: + DIRS += ["pkcs11testmodule"] + +TEST_DIRS += [ + "bad_certs", + "ocsp_certs", + "test_baseline_requirements", + "test_cert_eku", + "test_cert_embedded_null", + "test_cert_keyUsage", + "test_cert_sha1", + "test_cert_signatures", + "test_cert_trust", + "test_cert_utf8", + "test_cert_version", + "test_certDB_import", + "test_content_signing", + "test_ct", + "test_delegated_credentials", + "test_encrypted_client_hello", + "test_ev_certs", + "test_intermediate_basic_usage_constraints", + "test_intermediate_preloads", + "test_keysize", + "test_keysize_ev", + "test_missing_intermediate", + "test_name_constraints", + "test_ocsp_url", + "test_onecrl", + "test_sanctions", + "test_signed_apps", + "test_startcom_wosign", + "test_validity", +] diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem b/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem new file mode 100644 index 0000000000..3fffeaf56f --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRTCCAi2gAwIBAgIUF4tSVpnzLjrUBoa9WMfShlqrEjwwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAvMS0wKwYDVQQDDCRUZXN0IEludGVybWVkaWF0ZSB1c2VkIGFz +IEVuZC1FbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjcjBwMAwGA1UdEwQFMAMBAf8wMgYIKwYBBQUHAQEE +JjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMCwGA1UdEQQl +MCOCIWNhLXVzZWQtYXMtZW5kLWVudGl0eS5leGFtcGxlLmNvbTANBgkqhkiG9w0B +AQsFAAOCAQEAllsGy7B4yROdLH5rmLV6Q6AxUMKk/ixwfCnkt3ibKGtoypvAG6wn +vevqezN7BUeqIZd0QeoZBEtKwxv87oCiVDgSPXhkGqxryN9i8Zii07Sa27rCVZHd +F/AJv7qSgl2mYPYAAcyDX5F5ecbc3i9tc96mYSUJawhgPCwNB6PGB+HUr5fSskzx +j7Rg+0k9TEpk5bcTlsqH2hFvM9ZycEFC0/9trBVvnvh51WTHX/AzZDaaHPyOd2jD +RxqCMwde0EfpNQmpz39WnRJqs7bf2Cdc080m/apFL9yjZOuCfNaWdezfNjWoBKNC +S5tpZOoqNYzdV/8VAy74Nv+cXGNX4Ct7RA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem.certspec new file mode 100644 index 0000000000..8e16705b50 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ca-used-as-end-entity.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate used as End-Entity +extension:basicConstraints:cA, +extension:authorityInformationAccess:http://localhost:8888/ +extension:subjectAlternativeName:ca-used-as-end-entity.example.com diff --git a/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key.keyspec b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem new file mode 100644 index 0000000000..c85c051004 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUUwG2e1zCLPYPQc2aSZ4UsI/GiK0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcow +gccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tghUqLnBp +bm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu +ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCbcbjTQmzRu++LJ/R1KjA99THZ +aRGG7u0knPs40bz+rIOAR7SllYTvZ1g5HanNG3GZ5+DExVmVtixcrqJFTV0BJsi0 +rv8XR4F3Cdict+rJ+hCSBqu6BGNWdptsaSPiSm+eL//tgjGY1zm9ln1B/OvTYA/n +f+OV07v44pwRBUe8C9Awb2J3KMHATPciKTk0Pwmh0jXi4FN9ehG1rXZMY2daHoKq +hzbBc8EaGzPPAyFumHd6wNqWX+/chEtT00SlcJw/lbQZnK8XvUSOhRuUeRdCM5wX +3w+Gy4P/FrI5tePoR9606GR6plC8QZxT3+Z6lTyCHz3I05+PNXwfmZH3ABSg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem.certspec new file mode 100644 index 0000000000..554339ff52 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/default-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test End-entity +extension:subjectAlternativeName:localhost,*.example.com,*.pinning.example.com,*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem new file mode 100644 index 0000000000..8e6085c3e1 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4zCCAcugAwIBAgIUE031neMThT1B9azoKkIDscqx+88wDQYJKoZIhvcNAQEF +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAoMSYwJAYDVQQDDB1UZXN0IFNIQTEgRGVsZWdhdGVkIFJlc3Bv +bmRlcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMF1xlJmCZ93CCpn +kfG4dsN/XOU4sGxKzSKxy9RvplraKt1ByMJJisSjs8H2FIf0G2mJQb2ApRw8EgJE +xYSkxEgzBeUTjAEGzwi+moYnYLrmoujzbyPF2YMTud+vN4NF2s5R1Nbc0qbLPMcG +680wcOyYzOQKpZHXKVp/ccW+ZmkdKy3+yElEWQvFo+pJ/ZOx11NAXxdzdpmVhmYl +R5ftQmkIiAgRQiBpmIpD/uSM5oeB3SK2ppzSg3UTH5MrEozihvp9JRwGKtJ+8Bbx +h83VToMrNbiTD3S6kKqLx2FnJCqx/W1iFA0YxMC4xo/DdIRXMkrX3obmVS8dHhkd +cSFo07sCAwEAAaMXMBUwEwYDVR0lBAwwCgYIKwYBBQUHAwkwDQYJKoZIhvcNAQEF +BQADggEBAI2xNUwZgoTpe439ouS6dI/8JRgWKTq9pzZdW5v7a0Tlwx7KUmoZ6mlZ +xgvCVlk/6zIXT+eN0l79YDzWGzqjLpsFPuxPuczb1KraEFBteHwm/lrUpij2cnYD +yOUNgCpIpUfR0UO5AOzAs1yHeMb/5YkfFl+4xU6rY6QL0RaI5n9rFbaPbXE0cNGg +ORxg8K6/JwlwsfXg0pT/5KtcWEvdo2YVU5X26UROFBbwtWmcp6xpqnYVJY69mXGN +utLR039Nv6IO5F6m0looSt0p3SSCNgqyls3GY6c8xXqS0YOR04IvGDHqWg2QKPtQ +T1HiTliyNYNFzr2e84eTeqQm8aTUMYs= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem.certspec new file mode 100644 index 0000000000..bdf3e2ee4d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSHA1Signer.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test SHA1 Delegated Responder +subjectKey:alternate +signature:sha1WithRSAEncryption +extension:extKeyUsage:OCSPSigning diff --git a/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem new file mode 100644 index 0000000000..9c5ceb2af7 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3jCCAcagAwIBAgIUM8qmS5w0gb5569IOxnYzJV4lfV4wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAjMSEwHwYDVQQDDBhUZXN0IERlbGVnYXRlZCBSZXNwb25kZXIw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDBdcZSZgmfdwgqZ5HxuHbD +f1zlOLBsSs0iscvUb6Za2irdQcjCSYrEo7PB9hSH9BtpiUG9gKUcPBICRMWEpMRI +MwXlE4wBBs8IvpqGJ2C65qLo828jxdmDE7nfrzeDRdrOUdTW3NKmyzzHBuvNMHDs +mMzkCqWR1ylaf3HFvmZpHSst/shJRFkLxaPqSf2TsddTQF8Xc3aZlYZmJUeX7UJp +CIgIEUIgaZiKQ/7kjOaHgd0itqac0oN1Ex+TKxKM4ob6fSUcBirSfvAW8YfN1U6D +KzW4kw90upCqi8dhZyQqsf1tYhQNGMTAuMaPw3SEVzJK196G5lUvHR4ZHXEhaNO7 +AgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsGAQUFBwMJMA0GCSqGSIb3DQEBCwUAA4IB +AQCeOJWvm8T7quyhSh8Yyu6/h7Yzi6h7YcVaK0azDuvWpWvJALZcYnKir6qOFbbD +x9pVEZ1r5DmwuC0UqBKo3KC8sDykT4fkjxKzW1OfOI0Iy6i76LHDGN7Ohg/U8I6x +V3rdTyVkNxFDKo4nK5WHNkMR5CBY7LcysV5sDFI79O3eM62UVSgP7+RaOV0cul0x +S8a1uad+azyE7EIM9qVkaO9456Z8ZT9P04fX5LRjrY/RVKXAUmpWGFmGes+matjw +2StNMW9jmbxc+eFoMUqUD9R4iJdElGj8ut4JbRvAHmtPv/Bj64WwIvsdvLRkCN06 +7vmqrN3x/8Bjga6uDx+zMHkr +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem.certspec new file mode 100644 index 0000000000..19971eeb4d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/delegatedSigner.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test Delegated Responder +subjectKey:alternate +extension:extKeyUsage:OCSPSigning diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem new file mode 100644 index 0000000000..7d22b7e3d1 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDAjCCAeqgAwIBAgIUEePkwqVPaz9IVH+MGS7msFHPqyowDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowPTE7MDkGA1UEAwwyVGVzdCBJbnZhbGlkIERl +bGVnYXRlZCBSZXNwb25kZXIgRnJvbSBJbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQDBdcZSZgmfdwgqZ5HxuHbDf1zlOLBsSs0iscvU +b6Za2irdQcjCSYrEo7PB9hSH9BtpiUG9gKUcPBICRMWEpMRIMwXlE4wBBs8IvpqG +J2C65qLo828jxdmDE7nfrzeDRdrOUdTW3NKmyzzHBuvNMHDsmMzkCqWR1ylaf3HF +vmZpHSst/shJRFkLxaPqSf2TsddTQF8Xc3aZlYZmJUeX7UJpCIgIEUIgaZiKQ/7k +jOaHgd0itqac0oN1Ex+TKxKM4ob6fSUcBirSfvAW8YfN1U6DKzW4kw90upCqi8dh +ZyQqsf1tYhQNGMTAuMaPw3SEVzJK196G5lUvHR4ZHXEhaNO7AgMBAAGjFzAVMBMG +A1UdJQQMMAoGCCsGAQUFBwMJMA0GCSqGSIb3DQEBCwUAA4IBAQBFmLHca/8lrjch +HtvuzERgSHeF8gsOjCKbkKmIJqAX7oAl+xoGV7sRzbk9Jcsl1be+xoffBCfuBPXI +a1Mr08nB7HV5h1fKu1Bt68i1rpKp0cDawfJeccovZQCbEpmwJ+sF5SCdA628KxoX +JclPsYODRqt6JSTb7WTRD7tIDO+CO9Q9Z2fis3zj6ZEN+mgnqj/SRFjkHnGKaRLN +1Aaj5Lbr6B1HZN5UbhAKySqkDAm/iWg8pFm6syJ3qMfjf65jecvbP6T0gXDueYG/ +qAcnddtqGmQQvU1WbmbtC4Vxg71yw62OhRtfUd5gVpRaVWE9Rcv09JHsu5Nox14p +sTEjoV/Q +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem.certspec new file mode 100644 index 0000000000..be0d3e9e5f --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerFromIntermediate.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate +subject:Test Invalid Delegated Responder From Intermediate +subjectKey:alternate +extension:extKeyUsage:OCSPSigning diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem new file mode 100644 index 0000000000..f44489f591 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8jCCAdqgAwIBAgIUbf11GwRR/gsZC/ZdyZ4rphMYM9AwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjA/MT0wOwYDVQQDDDRUZXN0IEludmFsaWQgRGVsZWdhdGVkIFJl +c3BvbmRlciBrZXlVc2FnZSBjcmxTaWduaW5nMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAwXXGUmYJn3cIKmeR8bh2w39c5TiwbErNIrHL1G+mWtoq3UHI +wkmKxKOzwfYUh/QbaYlBvYClHDwSAkTFhKTESDMF5ROMAQbPCL6ahidguuai6PNv +I8XZgxO53683g0XazlHU1tzSpss8xwbrzTBw7JjM5AqlkdcpWn9xxb5maR0rLf7I +SURZC8Wj6kn9k7HXU0BfF3N2mZWGZiVHl+1CaQiICBFCIGmYikP+5Izmh4HdIram +nNKDdRMfkysSjOKG+n0lHAYq0n7wFvGHzdVOgys1uJMPdLqQqovHYWckKrH9bWIU +DRjEwLjGj8N0hFcyStfehuZVLx0eGR1xIWjTuwIDAQABow8wDTALBgNVHQ8EBAMC +AQIwDQYJKoZIhvcNAQELBQADggEBADLwe7YTejSPwSk2T+oDdGunG96A7fTOadGo +/ygjd90S4ockZ+Bi/WgpEf/nPAhArYjKOdL0ND1lm2Zv5f5Ge/XrqX2rL4s7Owfq +sOounyEP2RMwX58I1bkrCsx7kKGDOIRXyhukaCdiircMiu/GT8tiBmxCJ5NfTsEi +k0R3+RaFQ0uhuryJWJ0IzjwPx7MaekSJuZ3rwSkm41zgCLU6cU9PkBW3jGW+M4Dg +cTvUzqryhFfdctaESk5OUT2XW7f4s1QlcbjyK5XDD97vC7zey/C8K+2xizaLDBVZ +iWdoE3WDmOHcYlLFeVg2l2sVAO1slQItVuQ1myy3VZo1r+SXEgs= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem.certspec new file mode 100644 index 0000000000..2833ed9b52 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerKeyUsageCrlSigning.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test Invalid Delegated Responder keyUsage crlSigning +subjectKey:alternate +extension:keyUsage:cRLSign diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem new file mode 100644 index 0000000000..4d8de4e52d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3DCCAcSgAwIBAgIULfke5oAO5ZbtLXezjOOcrqEQIHwwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjA6MTgwNgYDVQQDDC9UZXN0IEludmFsaWQgRGVsZWdhdGVkIFJl +c3BvbmRlciBObyBleHRLZXlVc2FnZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAMF1xlJmCZ93CCpnkfG4dsN/XOU4sGxKzSKxy9RvplraKt1ByMJJisSj +s8H2FIf0G2mJQb2ApRw8EgJExYSkxEgzBeUTjAEGzwi+moYnYLrmoujzbyPF2YMT +ud+vN4NF2s5R1Nbc0qbLPMcG680wcOyYzOQKpZHXKVp/ccW+ZmkdKy3+yElEWQvF +o+pJ/ZOx11NAXxdzdpmVhmYlR5ftQmkIiAgRQiBpmIpD/uSM5oeB3SK2ppzSg3UT +H5MrEozihvp9JRwGKtJ+8Bbxh83VToMrNbiTD3S6kKqLx2FnJCqx/W1iFA0YxMC4 +xo/DdIRXMkrX3obmVS8dHhkdcSFo07sCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA +Yco2Ah5HxHlmkSm1YhZ6AyuGv/FyXmMkJ+7Jr7NCXy/MuQAGj1QtKbhFCtt2iotU +D8V+sNPgUbtimTkstt3cdUsQhT61l+S9ZN1Be8Vza0S6RBA48RbkyDCx69DfjOWa +yJF0WB0eg5H2GMq2+i2LNU1qgFhld62miB1g7We80GYX/+bBEfTvjuojaeSWijN2 +6txGUC1udv4o2ELsuvma0nymBr3et9xVwuFfWoLbQAeyRHCScdSku0vB/kDQb6Pt +uCasUnBGiMPpf4w5DDNetLFh9FITYLCb4xWoPsj+6DSizVmD2/rOXhaNSwyHdWn9 +v2FW/J0cNFFuZLTSBA3z4w== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem.certspec new file mode 100644 index 0000000000..92444c94ad --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerNoExtKeyUsage.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:Test Invalid Delegated Responder No extKeyUsage +subjectKey:alternate diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem new file mode 100644 index 0000000000..ddc5ca01b8 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+DCCAeCgAwIBAgIUdw7kK4XEwM9Ipz41NlM1pF9VSEkwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjA9MTswOQYDVQQDDDJUZXN0IEludmFsaWQgRGVsZWdhdGVkIFJl +c3BvbmRlciBXcm9uZyBleHRLZXlVc2FnZTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMF1xlJmCZ93CCpnkfG4dsN/XOU4sGxKzSKxy9RvplraKt1ByMJJ +isSjs8H2FIf0G2mJQb2ApRw8EgJExYSkxEgzBeUTjAEGzwi+moYnYLrmoujzbyPF +2YMTud+vN4NF2s5R1Nbc0qbLPMcG680wcOyYzOQKpZHXKVp/ccW+ZmkdKy3+yElE +WQvFo+pJ/ZOx11NAXxdzdpmVhmYlR5ftQmkIiAgRQiBpmIpD/uSM5oeB3SK2ppzS +g3UTH5MrEozihvp9JRwGKtJ+8Bbxh83VToMrNbiTD3S6kKqLx2FnJCqx/W1iFA0Y +xMC4xo/DdIRXMkrX3obmVS8dHhkdcSFo07sCAwEAAaMXMBUwEwYDVR0lBAwwCgYI +KwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBABdCK3EKY/6lwuCehtiHVJ6XcFBO +rTUmmRxkrRfXzn47Llofu/QC9OISWhfV/JefrNh44mYkkscsWV76eHsEqOp2F3Gz +Kv0bhlFt2ihCh1dzgz6tGWT5fwidow3nBSdssMZGqHD51kZXXGgB0xWopKDhnXgS +hUforJ1X4anMZzDgV52DSGB+dTo0atgq6ke2m+nOsW8CErYVGHs2ey4lugNPo+AO +XYaZqTclKGtrPjXt0P0E8ZaUs+Vxzx8jh0S096FDSPWMLdrfIETRB90legO8M2Qo +woGV4FsA48aPqqy6LPEke0NltJ/AlBwS5wz54TwWkhjjBV/dmBrFV2bFQzU= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem.certspec new file mode 100644 index 0000000000..bc704fbd41 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/invalidDelegatedSignerWrongExtKeyUsage.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test Invalid Delegated Responder Wrong extKeyUsage +subjectKey:alternate +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/unit/ocsp_certs/moz.build b/security/manager/ssl/tests/unit/ocsp_certs/moz.build new file mode 100644 index 0000000000..212b3cad1d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/moz.build @@ -0,0 +1,42 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca-used-as-end-entity.pem', +# 'default-ee.pem', +# 'delegatedSHA1Signer.pem', +# 'delegatedSigner.pem', +# 'invalidDelegatedSignerFromIntermediate.pem', +# 'invalidDelegatedSignerKeyUsageCrlSigning.pem', +# 'invalidDelegatedSignerNoExtKeyUsage.pem', +# 'invalidDelegatedSignerWrongExtKeyUsage.pem', +# 'multi-tls-feature-bad-ee.pem', +# 'multi-tls-feature-good-ee.pem', +# 'must-staple-ee.pem', +# 'must-staple-ee-with-must-staple-int.pem', +# 'must-staple-missing-ee.pem', +# 'ocspEEWithIntermediate.pem', +# 'ocspOtherEndEntity.pem', +# 'other-test-ca.pem', +# 'rsa-1016-keysizeDelegatedSigner.pem', +# 'test-ca.pem', +# 'test-int.pem', +# 'test-multi-tls-feature-int.pem', +# 'test-must-staple-int.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'default-ee.key', +# 'other-test-ca.key', +# 'rsa-1016-keysizeDelegatedSigner.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem new file mode 100644 index 0000000000..be14c630f8 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJDCCAgygAwIBAgIUX5dBLWiffAZEKD2dHegBV9jFkhMwDQYJKoZIhvcNAQEL +BQAwNzE1MDMGA1UEAwwsVGVzdCBJbnRlcm1lZGlhdGUgV2l0aCBNdWx0aXBsZSBU +TFMgRmVhdHVyZXMwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFow +LDEqMCgGA1UEAwwhTXVsdGkgVExTIEZlYXR1cmUgVGVzdCBFbmQtRW50aXR5MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08 +E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc +1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP +DY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQ +gAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV +YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID +AQABoy8wLTAYBgNVHREEETAPgg0qLmV4YW1wbGUuY29tMBEGCCsGAQUFBwEYBAUw +AwIBBTANBgkqhkiG9w0BAQsFAAOCAQEAoxlWVngbuVoxZdE2qM6gPpMbCR0vW99b +XWki1fUm9RwQ0XhobwDXJvpopSguoZ5gNsXoGHpLUTsQNVgdcNz9YJkjU05JhQQF +KRAufrkry4TLe+PmGmLCWkMJh2hemv8Ih5TUs2GPS4QsbAXKa3me6T3J4q4KBlH/ +RNN0cozoIbGdUmCmSFKgxnMuUN5E5/RpN06lgZIthtjcCvgbWHrOTPDJOs50KZSr +l4+fHiHxBoRvW0MJ3S/oixA6SQWrO86kv0iahn0kZA5cnqhrC8qI9HUnFT31k7AZ +XS4+EolIyjDrlse8fnehhW00dXjzH+zgvUNJFyafB3AYtJTco0gVqQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem.certspec new file mode 100644 index 0000000000..3fa2793b30 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-bad-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate With Multiple TLS Features +subject:Multi TLS Feature Test End-Entity +extension:subjectAlternativeName:*.example.com +extension:TLSFeature:OCSPMustStaple diff --git a/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem new file mode 100644 index 0000000000..60a6c8b511 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDJzCCAg+gAwIBAgIUNbatscZX2IBW2HGooNJW4304zyEwDQYJKoZIhvcNAQEL +BQAwNzE1MDMGA1UEAwwsVGVzdCBJbnRlcm1lZGlhdGUgV2l0aCBNdWx0aXBsZSBU +TFMgRmVhdHVyZXMwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFow +LDEqMCgGA1UEAwwhTXVsdGkgVExTIEZlYXR1cmUgVGVzdCBFbmQtRW50aXR5MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08 +E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc +1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP +DY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQ +gAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV +YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID +AQABozIwMDAYBgNVHREEETAPgg0qLmV4YW1wbGUuY29tMBQGCCsGAQUFBwEYBAgw +BgIBBQIBBjANBgkqhkiG9w0BAQsFAAOCAQEAKvmpaXwjW7///EBD0Qt6u4eYWxOf +kItU9yAiOjoKpSl803Jskqpt1WAYeOWv0+vjlFlkSR+Wb4bUiWFUG0ETXQPnpndy +zc0smDI+2ILQSRAUqF6UYvMqqkMQfTEfZN3CTSH48BdBw2G1brWnPBl/2qRZTFRy +/mdOZqJmE4UZhkf8ihtyQstqlVNqNAW6luS8u3tm5Uwk/ZVsH80yphF0OPQAFMGV +GxYbNYpmaUcJ4xGH1bwvxpUc7eVvu18GpZpl74VYThaizvXWTlIQGMxQU0OgBSAx +1uNpLNMo2eoGXPt7sC9v9fMq/KFN/VfCULlIwrALDfQdhJ4ctTQbHNCZtQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem.certspec new file mode 100644 index 0000000000..7a8dd223d0 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/multi-tls-feature-good-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate With Multiple TLS Features +subject:Multi TLS Feature Test End-Entity +extension:subjectAlternativeName:*.example.com +extension:TLSFeature:OCSPMustStaple,6 diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem new file mode 100644 index 0000000000..f82cc96a06 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDCDCCAfCgAwIBAgIUcXF8++LMW19oSQg8vdU5I0GGZWkwDQYJKoZIhvcNAQEL +BQAwLTErMCkGA1UEAwwiVGVzdCBJbnRlcm1lZGlhdGUgV2l0aCBNdXN0LVN0YXBs +ZTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAaMRgwFgYDVQQD +DA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24a +hvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7t +FYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o +N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0d +JdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4 +s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjLzAtMBgGA1UdEQQRMA+CDSouZXhhbXBs +ZS5jb20wEQYIKwYBBQUHARgEBTADAgEFMA0GCSqGSIb3DQEBCwUAA4IBAQArhytK +0cN71epgzB/5M26RujocEL8Puk5O04x1uEbU7j3y+mNTO7bLB5z76ZKEzU98blLq +V6Ds7PvmBHW/41KP8e7MwkOGprvUllfI8zmTvxXDV2iHGtmOvvEbfOf/QZS0e4Dj +eZCcew9p4/+Efe5lcto6QazTfFSJLxjkpKHU6S0ZgAu5mEZl5UW7VdR5LHzHp17t +dT4EWMt41CPoGxeJWYL5pOK14sD5GmUQ9OADzPBiN1M2v/9JY9IOWRabP1VafTYK +95PHA21eXqmA6SjCugaCMXW99pdStcBSCvQEAWfHBWloyALzG5Mh7H14tuM41ldF +abWEJfmtmGP2F2ru +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem.certspec new file mode 100644 index 0000000000..352a60675d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee-with-must-staple-int.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate With Must-Staple +subject:Test End-entity +extension:subjectAlternativeName:*.example.com +extension:TLSFeature:OCSPMustStaple diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem new file mode 100644 index 0000000000..9453f79225 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDITCCAgmgAwIBAgIUFdjcRo9oZDqo1b9UOWgfewuqbdwwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjYzBh +MBgGA1UdEQQRMA+CDSouZXhhbXBsZS5jb20wEQYIKwYBBQUHARgEBTADAgEFMDIG +CCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4 +LzANBgkqhkiG9w0BAQsFAAOCAQEAMkt3s3WLtDF364ZlSZ+WSei6kpk8XNmQ8PlM +SswAApahPrWlYlZ/V7Y18MHLHF26Rmoh2NdUczmLcOvvwRxq9/ekooDP4HkB7WFz +YnfDo5lWhqRUyTVmSVUS2SS7mmvt1fPbZrB8kjATqhvAmOu23XmxZzJu3ylGfBn2 +MJhLxt3VhOymRkiX3sPFboxCsipj5zD3jeqGbwJCnlr3kwqvTayUEke35mvkwCew +3L7akzbjXdJ8sFeLw/ZNpPbslRkVmV3lCv1Kl08U0POM6tKoow4sw4P0iVXGQqRT +H/4Stc8jzHop21H5chKAfMVQqIM3u05o022+rzrCQomyoVCLaA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem.certspec new file mode 100644 index 0000000000..43edfff0d9 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test End-entity +extension:subjectAlternativeName:*.example.com +extension:TLSFeature:OCSPMustStaple +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem new file mode 100644 index 0000000000..a436415f30 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9TCCAd2gAwIBAgIUL+F6WGk9sZuSuDMbhvPWt8PKv3owDQYJKoZIhvcNAQEL +BQAwLTErMCkGA1UEAwwiVGVzdCBJbnRlcm1lZGlhdGUgV2l0aCBNdXN0LVN0YXBs +ZTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAaMRgwFgYDVQQD +DA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24a +hvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7t +FYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o +N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0d +JdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4 +s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHDAaMBgGA1UdEQQRMA+CDSouZXhhbXBs +ZS5jb20wDQYJKoZIhvcNAQELBQADggEBALem6GEzJyvZWTVaYg54X2qWTnFfHVyu +4F/UbGX54D+8hl/zumovWsAtPPfcls94uAMeVvAoRTBP8dUcubilzMwMig7QUPUs +2YeqeQZ+2+NFHwmMG9SnkSU+CK8lnD4JJClLUuS2rYh5q+tp7c+U7+jFuktqIAQg +PJijEhiFq0wlqjXg2ytvbdurEm/LAz+wu8sEJtWsWLCZt8QiQfYhX/epFRreO8tB +Ulu/FCh/1kWx7JAIudigMSQqsg2R7ohgHyOV5Bm9ad2OyTuBjQ8xGFba3Y4jtPvy +w6mpRAeFEJB7FVTdDQFAyEryoSuOE8MAve2Ld/+9YDddom4S5+ocXo8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem.certspec new file mode 100644 index 0000000000..8e4a6ac0c5 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/must-staple-missing-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test Intermediate With Must-Staple +subject:Test End-entity +extension:subjectAlternativeName:*.example.com diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem b/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem new file mode 100644 index 0000000000..71459bdd6d --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUc2xqnbHi4aDQ1Rj+6hXoSA+ut+8wDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowLDEqMCgGA1UEAwwhVGVzdCBFbmQtZW50aXR5 +IHdpdGggSW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1swWTAjBgNVHREEHDAagglsb2NhbGhv +c3SCDSouZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZo +dHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCig/et41o2 +7hC3LJBIt5yh/eOgjZEUiuJlLAtrMssa5VjdxMDRyqBgn7FUMZMVnIpqRe9V0/a5 +E+yMZp+PvMWxexPlue7SOe7VYaDGvStdJ4ecsEqZzw151k6EuvyT2NJZPj92Mx+0 +gAAo2GysadZEn4E1juLZDCk+fTU1sq8Fek3XocrB/5on3UotDtglBIKW+O8N/vVh +0Fymnt8owdmt9anGJW9GSLf11b2qZ9XS+5Wlyn3ujDDaeL6+d70mKWo1AuxA7IQx +ODcsUb6lCGtyyJCLul6oW1ABJNGh1QGAPc3XSeONc2/w7UZcc5IzpmD46V1soJXl +yLUPGwF1W//L +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem.certspec new file mode 100644 index 0000000000..ae3a51565a --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ocspEEWithIntermediate.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test Intermediate +subject:Test End-entity with Intermediate +extension:subjectAlternativeName:localhost,*.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem b/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem new file mode 100644 index 0000000000..25036c7c21 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFDCCAfygAwIBAgIUX1EMg6wBeHSbS/NgLV/M/PaxdWswDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAVMRMwEQYDVQQDDApPdGhlciBDZXJ0MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1swWTAjBgNV +HREEHDAagglsb2NhbGhvc3SCDSouZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAk +MCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEB +CwUAA4IBAQCvTyo5F7zhOPBd0LZJpC0ZQAktZtct7z9j0E+iUbo6tohRsvRMmbDs +lO/cwks/I2sNa3fzHEzE+oC/0kiCS9JUiHUSUrHQrPOraP1urmRdhzECbyFVQsdw +E9YEtfZemxBQd/pHj7VnYlZ9xNimGZ7rcSi0vif3QbB3BlJiFfAe+IrJ1tkfYOGY +3xwoCCWOIGj0xl79MXzlG6iI9678y0vUu45tM1JbnauekEjF65CqME035e3eFq/t +oqghb07JW7JSGmIz0JE+0qli2iT2QIML77Wk0OTE9niDPAbORFPRbNytycNQ8yHk +xDvo21FgYZFATLiYf4oUADqp23sTIhac +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem.certspec new file mode 100644 index 0000000000..5756f6ab5f --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/ocspOtherEndEntity.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Other Cert +extension:subjectAlternativeName:localhost,*.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key new file mode 100644 index 0000000000..abde350c28 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBdcZSZgmfdwgq +Z5HxuHbDf1zlOLBsSs0iscvUb6Za2irdQcjCSYrEo7PB9hSH9BtpiUG9gKUcPBIC +RMWEpMRIMwXlE4wBBs8IvpqGJ2C65qLo828jxdmDE7nfrzeDRdrOUdTW3NKmyzzH +BuvNMHDsmMzkCqWR1ylaf3HFvmZpHSst/shJRFkLxaPqSf2TsddTQF8Xc3aZlYZm +JUeX7UJpCIgIEUIgaZiKQ/7kjOaHgd0itqac0oN1Ex+TKxKM4ob6fSUcBirSfvAW +8YfN1U6DKzW4kw90upCqi8dhZyQqsf1tYhQNGMTAuMaPw3SEVzJK196G5lUvHR4Z +HXEhaNO7AgMBAAECggEAfj9tfLg572auXX3ZL/VBC7NB3BRyjTkDRXDho3B5DzDw +aBNV//QeKtTpqdn86/vRJ736uMAK/7Hzzqcyfq1HqhYh8qwe4UygLwSzsnhgF5gL +GBpEnQOwPmnRErg1ceVUNPASBWV10oMu1nMdznmeN8g/bVHFWrcetYAVrwXhrxXH +R2A+9/J9A6b/BJ2Wu/hUweTlDvWwWND7CBgOCsf3vo8v8Wc9l/yeVduoOAd7v4p8 +/ylihXeFJpzZ1brStXRp5K/NM8TKLS9pnxHnyPvc1ITwjY77ijy4qXLrJL7Zcu+q +5LtxIJPkj+lKRutimodQeMQCGposk8mnA5Dp0KVEAQKBgQDmP8clprp2klp/+MtZ +xPVt1+yD/oW/H1PhHKyagSWLz8CugZB3sPLRR3qvho3mqOy+r3uyKxlvKprYLTKG +8NDMKd5xnl8r6OUJtyhNWWPt02L5J4h6TEqJeZ00DVGzAax2AasnF5Ak/KrdOL9l +Iq9j6xZGHsAqfyewb+Cd3afAoQKBgQDXGLH+n4+Z8A6DKuH73G/iqyfzTgScSYAQ ++g63CEhSGCNGCDtclsPu5VksAUpBDGuTCxZcE7XCaqMurG58klqFUcJRNPL0pyxk +IfGacxSKDt+rpdOmiIs1y6GMAP047lqvC1RXMdcgdhu8ze50SlLKQV6Y5N4Bzf52 +TBlns+jK2wKBgAHlrKJmyUqI0i4TwrkuokcRbGV6B2gXvf0w20s6nTCVuaS2dJZH +4vhOenhPx4OLCMhZcc96A2+jDjuRw8TQ3yePgMG26FnYRWrbE33vqp8fCsW6yakY +T9TqJ51yLqYm8WDXiq17yDhFzLKd8RXIP2G3YiuZvUOcYJtXkKY8WVGBAoGBAIDM +RdENJITuDRKX/Ae/gLO+/0Yeon4fOPNxeJw69mtKDt0hksIneR208cd64ka/NC8x +hWsPVlgbWKlbETHAxTltsqjDxvOeouM2vCBa5qKgs2hp/KmMu6czzwExmm+bsmt8 +oj0wF/xVHNjaiv3Rf2+i4w00hoeYHNYjTVcekLffAoGAb3fAwfKuesFpVhzKSZxS +vfvgTN3M29wSrsWoVpHoWUt+4pkI8w57lqpiVLgO1K7sm5k3gr38ebadjVjGiHD6 +S+G8DDUnKIxcgrtK668V7f8RBAP8eOas5qgoJ79C8M+nUeUHZRxWONuTk90j3R9r +KVFR3kS3f+Vaew3yceGaZcA= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key.keyspec b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key.keyspec new file mode 100644 index 0000000000..cbd5f309c0 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.key.keyspec @@ -0,0 +1 @@ +alternate diff --git a/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem new file mode 100644 index 0000000000..a2e264030a --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIURym6o+VN9xgZXT/QLrvN/nv1ZN4wDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNT3RoZXIgdGVzdCBDQTAiGA8yMDE1MDEwMTAwMDAwMFoY +DzIwMjUwMTAxMDAwMDAwWjAYMRYwFAYDVQQDDA1PdGhlciB0ZXN0IENBMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwXXGUmYJn3cIKmeR8bh2w39c5Tiw +bErNIrHL1G+mWtoq3UHIwkmKxKOzwfYUh/QbaYlBvYClHDwSAkTFhKTESDMF5ROM +AQbPCL6ahidguuai6PNvI8XZgxO53683g0XazlHU1tzSpss8xwbrzTBw7JjM5Aql +kdcpWn9xxb5maR0rLf7ISURZC8Wj6kn9k7HXU0BfF3N2mZWGZiVHl+1CaQiICBFC +IGmYikP+5Izmh4HdIramnNKDdRMfkysSjOKG+n0lHAYq0n7wFvGHzdVOgys1uJMP +dLqQqovHYWckKrH9bWIUDRjEwLjGj8N0hFcyStfehuZVLx0eGR1xIWjTuwIDAQAB +ox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AQEAtXplrvls6HSbbibpzfGxOPmSuh2TH05bE4vQk+d7Kz6EOAFvgTiZbLwTxbrQ +gfrM05t+67C2nAeiwAtW34nUnu6S8MYA6mJjURWICbl7cAvCHuNjg1atVr6f1Y+9 +VFFG6aUibw3bzKneREmDEVcxlEWUaMvv/JjfyMA5veSyX6iTJYkIBrEiVV5Alzg5 +yVHBi6+tpuJDO/YLlG8kmfzkYeJkTyAGx1EJ2yQHim7R232638yb0KrhS4zKsfFU +egHhM4c+MpiCLc9q2EgblbYGx5GM+2leuzXunj1KPClHFrnmkRRm3rcESG2pK9RN +/48Nd38VNofRojEbzDSCdOFmow== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem.certspec new file mode 100644 index 0000000000..3bc975aa22 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/other-test-ca.pem.certspec @@ -0,0 +1,7 @@ +issuer:Other test CA +subject:Other test CA +issuerKey:alternate +subjectKey:alternate +validity:20150101-20250101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key new file mode 100644 index 0000000000..d43495f851 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key @@ -0,0 +1,16 @@ +-----BEGIN PRIVATE KEY----- +MIICcAIBADANBgkqhkiG9w0BAQEFAASCAlowggJWAgEAAoGAANKbsS+4T93NKbOl +GctmxDuNj4vlRbp5OEzmY+0D33WZFgDrkgeQ0lMM7OVE25mnHwWJaj7SBxZVNKqZ +BX5HxH47yBrab6HhLjcmi1BGpVJo+drXzLSF2BouGdUNTwtoVKyvbXvmnZoIMTbh +WvqPU8HIyE/GB3J53Q5V1zaaW90CAwEAAQJ/PEllBwvzkMJR1aLFJ3xbX9C97oXK +1/4rJ5grsoURSlBwBANq4c+K5Usl5Ns5IVq9fpA/YYwtiy8IzGzRLbzNciBeSUW2 +s984nl5D3goUi7LITiQx/b5ZILBEuycvRez/ByG337YDl/xhOp6jXCIwBTDK6PkV +nFNN878JEJUZAQJAD58XWXyFuAUbnGmvtV71dsmW29CQR9DM3ludYOpcZ/5PrGe+ +gD9LasWj8FD3a5ZvsU9c8QV2HlrebdlgsYO6VQJADXtjcRLOYaVRaMD5yThvsnmr +QMug1Ukza7plJ3JjqseCYRosgdm2Nc94xAAYhZ4BjF6QBtEuPS7m80bnn6QzaQJA +Cf1smj6m6RrjIHD5/BwhD/k1L5e+XR7rlRuzloHp3FtnKlMiIbPYkAyanZm50KTh +AtxFDKG4ewsTid5lFsCuDQJAAUG4MkkbfdSoMwiSACTHnK5kvUR9+IO7TFZyqWur +SLcSOzTyYyRFLNzrF/IeVw40fL4v1MLY+ZEOrCy22JW4yQJABFjdau4YyIsvm4Hx +vDB1riDcH5lz0gck8gsGBD1hR8h4nUoHroi8gshDjIk+AXsTlH9i4LGJWKMetmSx +nmTT4A== +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key.keyspec b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key.keyspec new file mode 100644 index 0000000000..21ed73d60b --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.key.keyspec @@ -0,0 +1 @@ +rsa1016 diff --git a/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem new file mode 100644 index 0000000000..f16060beee --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICazCCAVOgAwIBAgIUYU3JfdG046x00L5zAkjGn4xjoZUwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjA1MTMwMQYDVQQDDCpSU0EgMTAxNiBLZXkgU2l6ZSBUZXN0IERl +bGVnYXRlZCBSZXNwb25kZXIwgZ4wDQYJKoZIhvcNAQEBBQADgYwAMIGIAoGAANKb +sS+4T93NKbOlGctmxDuNj4vlRbp5OEzmY+0D33WZFgDrkgeQ0lMM7OVE25mnHwWJ +aj7SBxZVNKqZBX5HxH47yBrab6HhLjcmi1BGpVJo+drXzLSF2BouGdUNTwtoVKyv +bXvmnZoIMTbhWvqPU8HIyE/GB3J53Q5V1zaaW90CAwEAAaMXMBUwEwYDVR0lBAww +CgYIKwYBBQUHAwkwDQYJKoZIhvcNAQELBQADggEBAHkGbdeUVBJCqfgXfmU4Acl1 +ZNunakiEmkZA2oOKvvksDaDg3rKbfZU6WwXhploKPtoWbCIyEkP3BTRJ6SqxNdq0 +S9yE3jR4CmfRy6+4f+cUIexihlI8l8PYC6ccXcZ5gvawCuMZ1YcVlq3LZS1WuNbV +qBhLURgwzXjpKMIzmsz0e6zIHNBskGX/vXLJjjUJSwnxxdTuCOZ0BUNpz26jMfdl +fEfYkPIEW0jvGSmg52NM6Uu20JUGM13lxp7WSrBPNqDnnV0Ivpvyiy1O7eOYBDRL +9LpnghoviPlE04OgvWtiEETNYkDxs606xOGd3eb/1HYLEdJtWdR7F2/KweJBqe8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem.certspec new file mode 100644 index 0000000000..05f73368a8 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/rsa-1016-keysizeDelegatedSigner.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:RSA 1016 Key Size Test Delegated Responder +subjectKey:rsa1016 +extension:extKeyUsage:OCSPSigning diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem b/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem new file mode 100644 index 0000000000..40515addbd --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUZekW+kmMLmUyacMUQAExM6vEFpswDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjASMRAwDgYDVQQDDAdUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAoabyPFisrr0c +kmPrDCY8pyDZ6ScxE/ziG+5RG4yJzW0QLrnt6rusMdKuxwaLiTISsNI14vh9QQyG +XQsVeiGNGIwyJ9k2ZbLvw6pjdUeaswkthSqUDYwYgCljBwViuFkK4SAwya0Vb0p8 +pErDX8pzSF78inMB/7f0+DPdEQgtAGPYfB0gMRWOliyJSVoJXTgJ2B6PTMMvIcIO +OXcqjDvVYY4o9+YtsDfmzGOSa/YmbM4hO6lv/cO3zv3aT+szyQK8X44koSkvct2P +QL4cY3/incY0l0I12PaScOJDuvITiRNca7gxbUiT2jz1eqzGPIyVS6ku2cO0v9tP +TIiD5XDdFg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem.certspec new file mode 100644 index 0000000000..5d2435d7bb --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test CA +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem b/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem new file mode 100644 index 0000000000..08249b863e --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIUa0X7/7DlTaedpgrIJg25iBPOkIMwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE1MDEwMTAwMDAwMFoYDzIwMjUw +MTAxMDAwMDAwWjAcMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1 +SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+ +zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYL +K7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwc +bJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibW +JZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMd +MBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEB +AILNZM9yT9ylMpjyi0tXaDORzpHiJ8vEoVKk98bC2BQF0kMEEB547p+Ms8zdJY00 +Bxe9qigT8rQwKprXq5RvgIZ32QLn/yMPiCp/e6zBdsx77TkfmnSnxvPi+0nlA+eM +8JYN0UST4vWD4vPPX9GgZDVoGQTiF3hUivJ5R8sHb/ozcSukMKQQ22+AIU7w6wyA +IbCAG7Pab4k2XFAeEnUZsl9fCym5jsPN9Pnv9rlBi6h8shHw1R2ROXjgxubjiMr3 +B456vFTJImLJjyA1iTSlr/+VXGUYg6Z0/HYnsO00+8xUKM71dPxGAfIFNaSscpyk +rGFLvocT/kym6r8galxCJUo= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem.certspec new file mode 100644 index 0000000000..33b42c2f41 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-int.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate +validity:20150101-20250101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem b/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem new file mode 100644 index 0000000000..63e94388af --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDjCCAfagAwIBAgIUZVYCAllpNYOv9692qhipPYQMx/4wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjA3MTUwMwYDVQQDDCxUZXN0IEludGVybWVkaWF0ZSBXaXRoIE11 +bHRpcGxlIFRMUyBGZWF0dXJlczCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab +bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts +Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI +H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8 +rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX +Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMzMDEwDAYDVR0TBAUwAwEB/zALBgNV +HQ8EBAMCAQYwFAYIKwYBBQUHARgECDAGAgEFAgEGMA0GCSqGSIb3DQEBCwUAA4IB +AQAdkLVuX3A0Q9pzWuUV0XADf/nao4Wo5tlpQgsPFNmtrZSeeMJhue7JczJpeuKj +0b176lb9VSKh8gdU7r1yvEYadl146UZnUvjbKGKQUlU9TLZBdgLnLIs845zRT8+T +6fQcWzapnhXVt7YSaNCri/iWXyWbOU/PdYjTZejU0lcCEml+t3J7KaKmrZqWZQT/ +CJa7hphC6qEmgE4zoWdmur3nhRFq7JkPGl1JeVEK4M4coec7gTqM/Z1gCkKLmBW9 +fHsYVtf+viYfL6I6xxQtTa7WdgGFKKJyJJ70A6om6TFiD5RHZDZ90wuwtjg1y25x +4rfoP1xZ9+2So4/8fNiX6PuD +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem.certspec new file mode 100644 index 0000000000..3f0e925aae --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-multi-tls-feature-int.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate With Multiple TLS Features +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:TLSFeature:OCSPMustStaple,6 diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem b/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem new file mode 100644 index 0000000000..ecdd4a9261 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDATCCAemgAwIBAgIUV+gXM8WzfHTQR4sK51eSBZrYF9IwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAtMSswKQYDVQQDDCJUZXN0IEludGVybWVkaWF0ZSBXaXRoIE11 +c3QtU3RhcGxlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABozAwLjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAR +BggrBgEFBQcBGAQFMAMCAQUwDQYJKoZIhvcNAQELBQADggEBAJ3n7RFMk6L0VPZi +1inbBkR3qLljszxJIkBQiYEV+leqxMXzn3S1CyTD1Pgnc59TCcf2W6upn58duyFN +NQWj9o5BDGNoq4vs8LZAxs7KivhtDsrGAsr049nVG9VbbpxvCjsEA+oygqquPbhF +N+775DpAYL/ZDdl/M3/R3XjLgK4FwIu9MDCc45HuYCPTIAp9ASNH65fBfV0be3FM +2k1/luQygte7VkXKRLxA0/+q498Q3awyWdkFin1/0sTIcMpr2MAuFUMO9j1/BdD+ +2xRUpuHc5sEMHdCNEDZylCLrEMa6tqz9FzUclxAVL7y1irrlGxOfjm4tYzO3P2rr +bT6iDxk= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem.certspec b/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem.certspec new file mode 100644 index 0000000000..7c29aa0ad1 --- /dev/null +++ b/security/manager/ssl/tests/unit/ocsp_certs/test-must-staple-int.pem.certspec @@ -0,0 +1,5 @@ +issuer:Test CA +subject:Test Intermediate With Must-Staple +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:TLSFeature:OCSPMustStaple diff --git a/security/manager/ssl/tests/unit/pkcs11testmodule/moz.build b/security/manager/ssl/tests/unit/pkcs11testmodule/moz.build new file mode 100644 index 0000000000..0eef91b076 --- /dev/null +++ b/security/manager/ssl/tests/unit/pkcs11testmodule/moz.build @@ -0,0 +1,20 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +FINAL_TARGET = "_tests/xpcshell/security/manager/ssl/tests/unit/pkcs11testmodule" + +UNIFIED_SOURCES += [ + "pkcs11testmodule.cpp", +] + +SharedLibrary("pkcs11testmodule") + +# C_GetFunctionList needs to be exported. As it turns out, it's much easier to +# just export all the symbols. +NoVisibilityFlags() +SYMBOLS_FILE = "pkcs11testmodule.symbols" + +NO_PGO = True diff --git a/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.cpp b/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.cpp new file mode 100644 index 0000000000..fcc332bc40 --- /dev/null +++ b/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.cpp @@ -0,0 +1,577 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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/. */ + +// This is a testing PKCS #11 module that simulates a token being inserted and +// removed from a slot every 50ms. This is achieved mainly in +// Test_C_WaitForSlotEvent. If the application that loaded this module calls +// C_WaitForSlotEvent, this module waits for 50ms and returns, having changed +// its internal state to report that the token has either been inserted or +// removed, as appropriate. +// This module also provides an alternate token that is always present for tests +// that don't want the cyclic behavior described above. + +#include +#include + +#if defined(WIN32) +# include // for Sleep +#else +# include // for usleep +#endif + +#include "pkcs11.h" + +CK_RV Test_C_Initialize(CK_VOID_PTR) { return CKR_OK; } + +CK_RV Test_C_Finalize(CK_VOID_PTR) { return CKR_OK; } + +static const CK_VERSION CryptokiVersion = {2, 2}; +static const CK_VERSION TestLibraryVersion = {0, 0}; +static const char TestLibraryDescription[] = "Test PKCS11 Library"; +static const char TestManufacturerID[] = "Test PKCS11 Manufacturer ID"; + +/* The dest buffer is one in the CK_INFO or CK_TOKEN_INFO structs. + * Those buffers are padded with spaces. DestSize corresponds to the declared + * size for those buffers (e.g. 32 for `char foo[32]`). + * The src buffer is a string literal. SrcSize includes the string + * termination character (e.g. 4 for `const char foo[] = "foo"` */ +template +void CopyString(unsigned char (&dest)[DestSize], const char (&src)[SrcSize]) { + static_assert(DestSize >= SrcSize - 1, "DestSize >= SrcSize - 1"); + memcpy(dest, src, SrcSize - 1); + memset(dest + SrcSize - 1, ' ', DestSize - SrcSize + 1); +} + +CK_RV Test_C_GetInfo(CK_INFO_PTR pInfo) { + if (!pInfo) { + return CKR_ARGUMENTS_BAD; + } + + pInfo->cryptokiVersion = CryptokiVersion; + CopyString(pInfo->manufacturerID, TestManufacturerID); + pInfo->flags = 0; // must be 0 + CopyString(pInfo->libraryDescription, TestLibraryDescription); + pInfo->libraryVersion = TestLibraryVersion; + return CKR_OK; +} + +CK_RV Test_C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR) { return CKR_OK; } + +static int tokenPresent = 0; + +CK_RV Test_C_GetSlotList(CK_BBOOL limitToTokensPresent, + CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) { + if (!pulCount) { + return CKR_ARGUMENTS_BAD; + } + + // We always return slot 2 + CK_ULONG slotCount = 1; + if (!limitToTokensPresent) { + // If we want empty slots, we also return slots 1 and 3 + slotCount += 2; + } else if (tokenPresent) { + // If we don't want empty slots, but token 1 is present, return that (but + // not slot 3) + slotCount++; + } + + if (pSlotList) { + if (*pulCount < slotCount) { + return CKR_BUFFER_TOO_SMALL; + } + // apparently CK_SLOT_IDs are integers [1,N] because + // who likes counting from 0 all the time? + switch (slotCount) { + case 1: + pSlotList[0] = 2; + break; + case 2: + if (tokenPresent) { + pSlotList[0] = 1; + pSlotList[1] = 2; + } else { + pSlotList[0] = 2; + pSlotList[1] = 3; + } + break; + case 3: + pSlotList[0] = 1; + pSlotList[1] = 2; + pSlotList[2] = 3; + break; + default: + assert("Unexpected slot count in Test_C_GetSlotList" == NULL); + return CKR_GENERAL_ERROR; + } + } + + *pulCount = slotCount; + return CKR_OK; +} + +static const char TestSlotDescription[] = "Test PKCS11 Slot"; +static const char TestSlot2Description[] = "Test PKCS11 Slot 二"; +static const char TestSlot3Description[] = "Empty PKCS11 Slot"; + +CK_RV Test_C_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) { + if (!pInfo) { + return CKR_ARGUMENTS_BAD; + } + + switch (slotID) { + case 1: + CopyString(pInfo->slotDescription, TestSlotDescription); + pInfo->flags = + (tokenPresent ? CKF_TOKEN_PRESENT : 0) | CKF_REMOVABLE_DEVICE; + break; + case 2: + CopyString(pInfo->slotDescription, TestSlot2Description); + pInfo->flags = CKF_TOKEN_PRESENT | CKF_REMOVABLE_DEVICE; + break; + case 3: + CopyString(pInfo->slotDescription, TestSlot3Description); + pInfo->flags = CKF_REMOVABLE_DEVICE; + break; + default: + return CKR_ARGUMENTS_BAD; + } + + CopyString(pInfo->manufacturerID, TestManufacturerID); + pInfo->hardwareVersion = TestLibraryVersion; + pInfo->firmwareVersion = TestLibraryVersion; + return CKR_OK; +} + +// Deliberately include énye to ensure we're handling encoding correctly. +// The PKCS #11 base specification v2.20 specifies that strings be encoded +// as UTF-8. +static const char TestTokenLabel[] = "Test PKCS11 Tokeñ Label"; +static const char TestToken2Label[] = "Test PKCS11 Tokeñ 2 Label"; +static const char TestTokenModel[] = "Test Model"; + +CK_RV Test_C_GetTokenInfo(CK_SLOT_ID slotID, CK_TOKEN_INFO_PTR pInfo) { + if (!pInfo) { + return CKR_ARGUMENTS_BAD; + } + + switch (slotID) { + case 1: + CopyString(pInfo->label, TestTokenLabel); + break; + case 2: + CopyString(pInfo->label, TestToken2Label); + break; + default: + return CKR_ARGUMENTS_BAD; + } + + CopyString(pInfo->manufacturerID, TestManufacturerID); + CopyString(pInfo->model, TestTokenModel); + memset(pInfo->serialNumber, 0, sizeof(pInfo->serialNumber)); + pInfo->flags = CKF_TOKEN_INITIALIZED; + pInfo->ulMaxSessionCount = 1; + pInfo->ulSessionCount = 0; + pInfo->ulMaxRwSessionCount = 1; + pInfo->ulRwSessionCount = 0; + pInfo->ulMaxPinLen = 4; + pInfo->ulMinPinLen = 4; + pInfo->ulTotalPublicMemory = 1024; + pInfo->ulFreePublicMemory = 1024; + pInfo->ulTotalPrivateMemory = 1024; + pInfo->ulFreePrivateMemory = 1024; + pInfo->hardwareVersion = TestLibraryVersion; + pInfo->firmwareVersion = TestLibraryVersion; + memset(pInfo->utcTime, 0, sizeof(pInfo->utcTime)); + return CKR_OK; +} + +CK_RV Test_C_GetMechanismList(CK_SLOT_ID, CK_MECHANISM_TYPE_PTR, + CK_ULONG_PTR pulCount) { + if (!pulCount) { + return CKR_ARGUMENTS_BAD; + } + + *pulCount = 0; + return CKR_OK; +} + +CK_RV Test_C_GetMechanismInfo(CK_SLOT_ID, CK_MECHANISM_TYPE, + CK_MECHANISM_INFO_PTR) { + return CKR_OK; +} + +CK_RV Test_C_InitToken(CK_SLOT_ID, CK_UTF8CHAR_PTR, CK_ULONG, CK_UTF8CHAR_PTR) { + return CKR_OK; +} + +CK_RV Test_C_InitPIN(CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SetPIN(CK_SESSION_HANDLE, CK_UTF8CHAR_PTR, CK_ULONG, + CK_UTF8CHAR_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_OpenSession(CK_SLOT_ID slotID, CK_FLAGS, CK_VOID_PTR, CK_NOTIFY, + CK_SESSION_HANDLE_PTR phSession) { + switch (slotID) { + case 1: + *phSession = 1; + break; + case 2: + *phSession = 2; + break; + default: + return CKR_ARGUMENTS_BAD; + } + + return CKR_OK; +} + +CK_RV Test_C_CloseSession(CK_SESSION_HANDLE) { return CKR_OK; } + +CK_RV Test_C_CloseAllSessions(CK_SLOT_ID) { return CKR_OK; } + +CK_RV Test_C_GetSessionInfo(CK_SESSION_HANDLE hSession, + CK_SESSION_INFO_PTR pInfo) { + if (!pInfo) { + return CKR_ARGUMENTS_BAD; + } + + switch (hSession) { + case 1: + pInfo->slotID = 1; + break; + case 2: + pInfo->slotID = 2; + break; + default: + return CKR_ARGUMENTS_BAD; + } + + pInfo->state = CKS_RO_PUBLIC_SESSION; + pInfo->flags = CKF_SERIAL_SESSION; + return CKR_OK; +} + +CK_RV Test_C_GetOperationState(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SetOperationState(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_OBJECT_HANDLE, CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Login(CK_SESSION_HANDLE, CK_USER_TYPE, CK_UTF8CHAR_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Logout(CK_SESSION_HANDLE) { return CKR_FUNCTION_NOT_SUPPORTED; } + +CK_RV Test_C_CreateObject(CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG, + CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_CopyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ATTRIBUTE_PTR, + CK_ULONG, CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DestroyObject(CK_SESSION_HANDLE, CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GetObjectSize(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SetAttributeValue(CK_SESSION_HANDLE, CK_OBJECT_HANDLE, + CK_ATTRIBUTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_FindObjectsInit(CK_SESSION_HANDLE, CK_ATTRIBUTE_PTR, CK_ULONG) { + return CKR_OK; +} + +CK_RV Test_C_FindObjects(CK_SESSION_HANDLE, CK_OBJECT_HANDLE_PTR, CK_ULONG, + CK_ULONG_PTR pulObjectCount) { + *pulObjectCount = 0; + return CKR_OK; +} + +CK_RV Test_C_FindObjectsFinal(CK_SESSION_HANDLE) { return CKR_OK; } + +CK_RV Test_C_EncryptInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, + CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Encrypt(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_EncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_EncryptFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DecryptInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, + CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Decrypt(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DecryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DecryptFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DigestInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Digest(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DigestUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DigestKey(CK_SESSION_HANDLE, CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DigestFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Sign(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, + CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignRecover(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_VerifyInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_Verify(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, CK_BYTE_PTR, + CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_VerifyUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_VerifyFinal(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_VerifyRecoverInit(CK_SESSION_HANDLE, CK_MECHANISM_PTR, + CK_OBJECT_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_VerifyRecover(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DigestEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DecryptDigestUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SignEncryptUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DecryptVerifyUpdate(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG, + CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GenerateKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_ATTRIBUTE_PTR, + CK_ULONG, CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GenerateKeyPair(CK_SESSION_HANDLE, CK_MECHANISM_PTR, + CK_ATTRIBUTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, + CK_ULONG, CK_OBJECT_HANDLE_PTR, + CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_WrapKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, + CK_OBJECT_HANDLE, CK_BYTE_PTR, CK_ULONG_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_UnwrapKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, + CK_BYTE_PTR, CK_ULONG, CK_ATTRIBUTE_PTR, CK_ULONG, + CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_DeriveKey(CK_SESSION_HANDLE, CK_MECHANISM_PTR, CK_OBJECT_HANDLE, + CK_ATTRIBUTE_PTR, CK_ULONG, CK_OBJECT_HANDLE_PTR) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_SeedRandom(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GenerateRandom(CK_SESSION_HANDLE, CK_BYTE_PTR, CK_ULONG) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_GetFunctionStatus(CK_SESSION_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_CancelFunction(CK_SESSION_HANDLE) { + return CKR_FUNCTION_NOT_SUPPORTED; +} + +CK_RV Test_C_WaitForSlotEvent(CK_FLAGS, CK_SLOT_ID_PTR pSlot, CK_VOID_PTR) { +#ifdef WIN32 + Sleep(50); // Sleep takes the duration argument as milliseconds +#else + usleep(50000); // usleep takes the duration argument as microseconds +#endif + *pSlot = 1; + tokenPresent = !tokenPresent; + return CKR_OK; +} + +static CK_FUNCTION_LIST FunctionList = {{2, 2}, + Test_C_Initialize, + Test_C_Finalize, + Test_C_GetInfo, + Test_C_GetFunctionList, + Test_C_GetSlotList, + Test_C_GetSlotInfo, + Test_C_GetTokenInfo, + Test_C_GetMechanismList, + Test_C_GetMechanismInfo, + Test_C_InitToken, + Test_C_InitPIN, + Test_C_SetPIN, + Test_C_OpenSession, + Test_C_CloseSession, + Test_C_CloseAllSessions, + Test_C_GetSessionInfo, + Test_C_GetOperationState, + Test_C_SetOperationState, + Test_C_Login, + Test_C_Logout, + Test_C_CreateObject, + Test_C_CopyObject, + Test_C_DestroyObject, + Test_C_GetObjectSize, + Test_C_GetAttributeValue, + Test_C_SetAttributeValue, + Test_C_FindObjectsInit, + Test_C_FindObjects, + Test_C_FindObjectsFinal, + Test_C_EncryptInit, + Test_C_Encrypt, + Test_C_EncryptUpdate, + Test_C_EncryptFinal, + Test_C_DecryptInit, + Test_C_Decrypt, + Test_C_DecryptUpdate, + Test_C_DecryptFinal, + Test_C_DigestInit, + Test_C_Digest, + Test_C_DigestUpdate, + Test_C_DigestKey, + Test_C_DigestFinal, + Test_C_SignInit, + Test_C_Sign, + Test_C_SignUpdate, + Test_C_SignFinal, + Test_C_SignRecoverInit, + Test_C_SignRecover, + Test_C_VerifyInit, + Test_C_Verify, + Test_C_VerifyUpdate, + Test_C_VerifyFinal, + Test_C_VerifyRecoverInit, + Test_C_VerifyRecover, + Test_C_DigestEncryptUpdate, + Test_C_DecryptDigestUpdate, + Test_C_SignEncryptUpdate, + Test_C_DecryptVerifyUpdate, + Test_C_GenerateKey, + Test_C_GenerateKeyPair, + Test_C_WrapKey, + Test_C_UnwrapKey, + Test_C_DeriveKey, + Test_C_SeedRandom, + Test_C_GenerateRandom, + Test_C_GetFunctionStatus, + Test_C_CancelFunction, + Test_C_WaitForSlotEvent}; + +CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList) { + *ppFunctionList = &FunctionList; + return CKR_OK; +} diff --git a/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.symbols b/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.symbols new file mode 100644 index 0000000000..562ecea21d --- /dev/null +++ b/security/manager/ssl/tests/unit/pkcs11testmodule/pkcs11testmodule.symbols @@ -0,0 +1 @@ +C_GetFunctionList diff --git a/security/manager/ssl/tests/unit/pycert.py b/security/manager/ssl/tests/unit/pycert.py new file mode 100755 index 0000000000..627f7b6ad1 --- /dev/null +++ b/security/manager/ssl/tests/unit/pycert.py @@ -0,0 +1,815 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Reads a certificate specification from stdin or a file and outputs a +signed x509 certificate with the desired properties. + +The input format is as follows: + +issuer: +subject: +[version:{1,2,3,4}] +[validity:] +[issuerKey:] +[subjectKey:] +[signature:{sha256WithRSAEncryption,sha1WithRSAEncryption, + md5WithRSAEncryption,ecdsaWithSHA256,ecdsaWithSHA384, + ecdsaWithSHA512}] +[serialNumber:] +[extension:>] +[...] + +Known extensions are: +basicConstraints:[cA],[pathLenConstraint] +keyUsage:[digitalSignature,nonRepudiation,keyEncipherment, + dataEncipherment,keyAgreement,keyCertSign,cRLSign] +extKeyUsage:[serverAuth,clientAuth,codeSigning,emailProtection + nsSGC, # Netscape Server Gated Crypto + OCSPSigning,timeStamping] +subjectAlternativeName:[,...] +authorityInformationAccess: +certificatePolicies:[,...] +nameConstraints:{permitted,excluded}:[,...] +nsCertType:sslServer +TLSFeature:[,...] +embeddedSCTList:[:,...] +delegationUsage: + +Where: + [] indicates an optional field or component of a field + <> indicates a required component of a field + {} indicates a choice of exactly one value among a set of values + [a,b,c] indicates a list of potential values, of which zero or more + may be used + +For instance, the version field is optional. However, if it is +specified, it must have exactly one value from the set {1,2,3,4}. + +Most fields have reasonable default values. By default one shared RSA +key is used for all signatures and subject public key information +fields. Using "issuerKey:" or +"subjectKey:" causes a different key be used for +signing or as the subject public key information field, respectively. +See pykey.py for the list of available specifications. +The signature algorithm is sha256WithRSAEncryption by default. + +The validity period may be specified as either concrete notBefore and +notAfter values or as a validity period centered around 'now'. For the +latter, this will result in a notBefore of 'now' - duration/2 and a +notAfter of 'now' + duration/2. + +Issuer and subject distinguished name specifications are of the form +'[stringEncoding]/C=XX/O=Example/CN=example.com'. C (country name), ST +(state or province name), L (locality name), O (organization name), OU +(organizational unit name), CN (common name) and emailAddress (email +address) are currently supported. The optional stringEncoding field may +be 'utf8String' or 'printableString'. If the given string does not +contain a '/', it is assumed to represent a common name. If an empty +string is provided, then an empty distinguished name is returned. +DirectoryNames also use this format. When specifying a directoryName in +a nameConstraints extension, the implicit form may not be used. + +If an extension name has '[critical]' after it, it will be marked as +critical. Otherwise (by default), it will not be marked as critical. + +TLSFeature values can either consist of a named value (currently only +'OCSPMustStaple' which corresponds to status_request) or a numeric TLS +feature value (see rfc7633 for more information). + +If a serial number is not explicitly specified, it is automatically +generated based on the contents of the certificate. +""" + +from pyasn1.codec.der import decoder +from pyasn1.codec.der import encoder +from pyasn1.type import constraint, tag, univ, useful +from pyasn1_modules import rfc2459 +from struct import pack +import base64 +import datetime +import hashlib +import re +import socket +import six +import sys + +import pyct +import pykey + + +class Error(Exception): + """Base class for exceptions in this module.""" + + pass + + +class UnknownBaseError(Error): + """Base class for handling unexpected input in this module.""" + + def __init__(self, value): + super(UnknownBaseError, self).__init__() + self.value = value + self.category = "input" + + def __str__(self): + return 'Unknown %s type "%s"' % (self.category, repr(self.value)) + + +class UnknownAlgorithmTypeError(UnknownBaseError): + """Helper exception type to handle unknown algorithm types.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "algorithm" + + +class UnknownParameterTypeError(UnknownBaseError): + """Helper exception type to handle unknown input parameters.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "parameter" + + +class UnknownExtensionTypeError(UnknownBaseError): + """Helper exception type to handle unknown input extensions.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "extension" + + +class UnknownKeyPurposeTypeError(UnknownBaseError): + """Helper exception type to handle unknown key purposes.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "keyPurpose" + + +class UnknownKeyTargetError(UnknownBaseError): + """Helper exception type to handle unknown key targets.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "key target" + + +class UnknownVersionError(UnknownBaseError): + """Helper exception type to handle unknown specified versions.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "version" + + +class UnknownNameConstraintsSpecificationError(UnknownBaseError): + """Helper exception type to handle unknown specified + nameConstraints.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "nameConstraints specification" + + +class UnknownDNTypeError(UnknownBaseError): + """Helper exception type to handle unknown DN types.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "DN" + + +class UnknownNSCertTypeError(UnknownBaseError): + """Helper exception type to handle unknown nsCertType types.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "nsCertType" + + +class UnknownTLSFeature(UnknownBaseError): + """Helper exception type to handle unknown TLS Features.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "TLSFeature" + + +class UnknownDelegatedCredentialError(UnknownBaseError): + """Helper exception type to handle unknown Delegated Credential args.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "delegatedCredential" + + +class InvalidSCTSpecification(Error): + """Helper exception type to handle invalid SCT specifications.""" + + def __init__(self, value): + super(InvalidSCTSpecification, self).__init__() + self.value = value + + def __str__(self): + return repr('invalid SCT specification "{}"' % self.value) + + +class InvalidSerialNumber(Error): + """Exception type to handle invalid serial numbers.""" + + def __init__(self, value): + super(InvalidSerialNumber, self).__init__() + self.value = value + + def __str__(self): + return repr(self.value) + + +def getASN1Tag(asn1Type): + """Helper function for returning the base tag value of a given + type from the pyasn1 package""" + return asn1Type.tagSet.baseTag.tagId + + +def stringToAccessDescription(string): + """Helper function that takes a string representing a URI + presumably identifying an OCSP authority information access + location. Returns an AccessDescription usable by pyasn1.""" + accessMethod = rfc2459.id_ad_ocsp + accessLocation = rfc2459.GeneralName() + accessLocation["uniformResourceIdentifier"] = string + sequence = univ.Sequence() + sequence.setComponentByPosition(0, accessMethod) + sequence.setComponentByPosition(1, accessLocation) + return sequence + + +def stringToDN(string, tag=None): + """Takes a string representing a distinguished name or directory + name and returns a Name for use by pyasn1. See the documentation + for the issuer and subject fields for more details. Takes an + optional implicit tag in cases where the Name needs to be tagged + differently.""" + if string and "/" not in string: + string = "/CN=%s" % string + rdns = rfc2459.RDNSequence() + pattern = "/(C|ST|L|O|OU|CN|emailAddress)=" + split = re.split(pattern, string) + # split should now be [[encoding], , , , , ...] + if split[0]: + encoding = split[0] + else: + encoding = "utf8String" + for pos, (nameType, value) in enumerate(zip(split[1::2], split[2::2])): + ava = rfc2459.AttributeTypeAndValue() + if nameType == "C": + ava["type"] = rfc2459.id_at_countryName + nameComponent = rfc2459.X520countryName(value) + elif nameType == "ST": + ava["type"] = rfc2459.id_at_stateOrProvinceName + nameComponent = rfc2459.X520StateOrProvinceName() + elif nameType == "L": + ava["type"] = rfc2459.id_at_localityName + nameComponent = rfc2459.X520LocalityName() + elif nameType == "O": + ava["type"] = rfc2459.id_at_organizationName + nameComponent = rfc2459.X520OrganizationName() + elif nameType == "OU": + ava["type"] = rfc2459.id_at_organizationalUnitName + nameComponent = rfc2459.X520OrganizationalUnitName() + elif nameType == "CN": + ava["type"] = rfc2459.id_at_commonName + nameComponent = rfc2459.X520CommonName() + elif nameType == "emailAddress": + ava["type"] = rfc2459.emailAddress + nameComponent = rfc2459.Pkcs9email(value) + else: + raise UnknownDNTypeError(nameType) + if not nameType == "C" and not nameType == "emailAddress": + # The value may have things like '\0' (i.e. a slash followed by + # the number zero) that have to be decoded into the resulting + # '\x00' (i.e. a byte with value zero). + nameComponent[encoding] = six.ensure_binary(value).decode( + encoding="unicode_escape" + ) + ava["value"] = nameComponent + rdn = rfc2459.RelativeDistinguishedName() + rdn.setComponentByPosition(0, ava) + rdns.setComponentByPosition(pos, rdn) + if tag: + name = rfc2459.Name().subtype(implicitTag=tag) + else: + name = rfc2459.Name() + name.setComponentByPosition(0, rdns) + return name + + +def stringToAlgorithmIdentifiers(string): + """Helper function that converts a description of an algorithm + to a representation usable by the pyasn1 package and a hash + algorithm constant for use by pykey.""" + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmType = None + algorithm = None + # We add Null parameters for RSA only + addParameters = False + if string == "sha1WithRSAEncryption": + algorithmType = pykey.HASH_SHA1 + algorithm = rfc2459.sha1WithRSAEncryption + addParameters = True + elif string == "sha256WithRSAEncryption": + algorithmType = pykey.HASH_SHA256 + algorithm = univ.ObjectIdentifier("1.2.840.113549.1.1.11") + addParameters = True + elif string == "md5WithRSAEncryption": + algorithmType = pykey.HASH_MD5 + algorithm = rfc2459.md5WithRSAEncryption + addParameters = True + elif string == "ecdsaWithSHA256": + algorithmType = pykey.HASH_SHA256 + algorithm = univ.ObjectIdentifier("1.2.840.10045.4.3.2") + elif string == "ecdsaWithSHA384": + algorithmType = pykey.HASH_SHA384 + algorithm = univ.ObjectIdentifier("1.2.840.10045.4.3.3") + elif string == "ecdsaWithSHA512": + algorithmType = pykey.HASH_SHA512 + algorithm = univ.ObjectIdentifier("1.2.840.10045.4.3.4") + else: + raise UnknownAlgorithmTypeError(string) + algorithmIdentifier["algorithm"] = algorithm + if addParameters: + # Directly setting parameters to univ.Null doesn't currently work. + nullEncapsulated = encoder.encode(univ.Null()) + algorithmIdentifier["parameters"] = univ.Any(nullEncapsulated) + return (algorithmIdentifier, algorithmType) + + +def datetimeToTime(dt): + """Takes a datetime object and returns an rfc2459.Time object with + that time as its value as a GeneralizedTime""" + time = rfc2459.Time() + time["generalTime"] = useful.GeneralizedTime(dt.strftime("%Y%m%d%H%M%SZ")) + return time + + +def serialBytesToString(serialBytes): + """Takes a list of integers in the interval [0, 255] and returns + the corresponding serial number string.""" + serialBytesLen = len(serialBytes) + if serialBytesLen > 127: + raise InvalidSerialNumber("{} bytes is too long".format(serialBytesLen)) + # Prepend the ASN.1 INTEGER tag and length bytes. + stringBytes = [getASN1Tag(univ.Integer), serialBytesLen] + serialBytes + return bytes(stringBytes) + + +class Certificate(object): + """Utility class for reading a certificate specification and + generating a signed x509 certificate""" + + def __init__(self, paramStream): + self.versionValue = 2 # a value of 2 is X509v3 + self.signature = "sha256WithRSAEncryption" + self.issuer = "Default Issuer" + actualNow = datetime.datetime.utcnow() + self.now = datetime.datetime.strptime(str(actualNow.year), "%Y") + aYearAndAWhile = datetime.timedelta(days=400) + self.notBefore = self.now - aYearAndAWhile + self.notAfter = self.now + aYearAndAWhile + self.subject = "Default Subject" + self.extensions = None + # The serial number can be automatically generated from the + # certificate specification. We need this value to depend in + # part of what extensions are present. self.extensions are + # pyasn1 objects. Depending on the string representation of + # these objects can cause the resulting serial number to change + # unexpectedly, so instead we depend on the original string + # representation of the extensions as specified. + self.extensionLines = None + self.savedEmbeddedSCTListData = None + self.subjectKey = pykey.keyFromSpecification("default") + self.issuerKey = pykey.keyFromSpecification("default") + self.serialNumber = None + self.decodeParams(paramStream) + # If a serial number wasn't specified, generate one based on + # the certificate contents. + if not self.serialNumber: + self.serialNumber = self.generateSerialNumber() + # This has to be last because the SCT signature depends on the + # contents of the certificate. + if self.savedEmbeddedSCTListData: + self.addEmbeddedSCTListData() + + def generateSerialNumber(self): + """Generates a serial number for this certificate based on its + contents. Intended to be reproducible for compatibility with + the build system on OS X (see the comment above main, later in + this file).""" + hasher = hashlib.sha256() + hasher.update(six.ensure_binary(str(self.versionValue))) + hasher.update(six.ensure_binary(self.signature)) + hasher.update(six.ensure_binary(self.issuer)) + hasher.update(six.ensure_binary(str(self.notBefore))) + hasher.update(six.ensure_binary(str(self.notAfter))) + hasher.update(six.ensure_binary(self.subject)) + if self.extensionLines: + for extensionLine in self.extensionLines: + hasher.update(six.ensure_binary(extensionLine)) + if self.savedEmbeddedSCTListData: + # savedEmbeddedSCTListData is + # (embeddedSCTListSpecification, critical), where |critical| + # may be None + hasher.update(six.ensure_binary(self.savedEmbeddedSCTListData[0])) + if self.savedEmbeddedSCTListData[1]: + hasher.update(six.ensure_binary(self.savedEmbeddedSCTListData[1])) + serialBytes = [c for c in hasher.digest()[:20]] + # Ensure that the most significant bit isn't set (which would + # indicate a negative number, which isn't valid for serial + # numbers). + serialBytes[0] &= 0x7F + # Also ensure that the least significant bit on the most + # significant byte is set (to prevent a leading zero byte, + # which also wouldn't be valid). + serialBytes[0] |= 0x01 + return serialBytesToString(serialBytes) + + def decodeParams(self, paramStream): + for line in paramStream.readlines(): + self.decodeParam(line.strip()) + + def decodeParam(self, line): + param = line.split(":")[0] + value = ":".join(line.split(":")[1:]) + if param == "version": + self.setVersion(value) + elif param == "subject": + self.subject = value + elif param == "issuer": + self.issuer = value + elif param == "validity": + self.decodeValidity(value) + elif param == "extension": + self.decodeExtension(value) + elif param == "issuerKey": + self.setupKey("issuer", value) + elif param == "subjectKey": + self.setupKey("subject", value) + elif param == "signature": + self.signature = value + elif param == "serialNumber": + serialNumber = int(value) + # Ensure only serial numbers that conform to the rules listed in + # generateSerialNumber() are permitted. + if serialNumber < 1 or serialNumber > 127: + raise InvalidSerialNumber(value) + self.serialNumber = serialBytesToString([serialNumber]) + else: + raise UnknownParameterTypeError(param) + + def setVersion(self, version): + intVersion = int(version) + if intVersion >= 1 and intVersion <= 4: + self.versionValue = intVersion - 1 + else: + raise UnknownVersionError(version) + + def decodeValidity(self, duration): + match = re.search("([0-9]{8})-([0-9]{8})", duration) + if match: + self.notBefore = datetime.datetime.strptime(match.group(1), "%Y%m%d") + self.notAfter = datetime.datetime.strptime(match.group(2), "%Y%m%d") + else: + delta = datetime.timedelta(days=(int(duration) / 2)) + self.notBefore = self.now - delta + self.notAfter = self.now + delta + + def decodeExtension(self, extension): + match = re.search(r"([a-zA-Z]+)(\[critical\])?:(.*)", extension) + if not match: + raise UnknownExtensionTypeError(extension) + extensionType = match.group(1) + critical = match.group(2) + value = match.group(3) + if extensionType == "basicConstraints": + self.addBasicConstraints(value, critical) + elif extensionType == "keyUsage": + self.addKeyUsage(value, critical) + elif extensionType == "extKeyUsage": + self.addExtKeyUsage(value, critical) + elif extensionType == "subjectAlternativeName": + self.addSubjectAlternativeName(value, critical) + elif extensionType == "authorityInformationAccess": + self.addAuthorityInformationAccess(value, critical) + elif extensionType == "certificatePolicies": + self.addCertificatePolicies(value, critical) + elif extensionType == "nameConstraints": + self.addNameConstraints(value, critical) + elif extensionType == "nsCertType": + self.addNSCertType(value, critical) + elif extensionType == "TLSFeature": + self.addTLSFeature(value, critical) + elif extensionType == "embeddedSCTList": + self.savedEmbeddedSCTListData = (value, critical) + elif extensionType == "delegationUsage": + self.addDelegationUsage(critical) + else: + raise UnknownExtensionTypeError(extensionType) + + if extensionType != "embeddedSCTList": + if not self.extensionLines: + self.extensionLines = [] + self.extensionLines.append(extension) + + def setupKey(self, subjectOrIssuer, value): + if subjectOrIssuer == "subject": + self.subjectKey = pykey.keyFromSpecification(value) + elif subjectOrIssuer == "issuer": + self.issuerKey = pykey.keyFromSpecification(value) + else: + raise UnknownKeyTargetError(subjectOrIssuer) + + def addExtension(self, extensionType, extensionValue, critical): + if not self.extensions: + self.extensions = [] + encapsulated = univ.OctetString(encoder.encode(extensionValue)) + extension = rfc2459.Extension() + extension["extnID"] = extensionType + # critical is either the string '[critical]' or None. + # We only care whether or not it is truthy. + if critical: + extension["critical"] = True + extension["extnValue"] = encapsulated + self.extensions.append(extension) + + def addBasicConstraints(self, basicConstraints, critical): + cA = basicConstraints.split(",")[0] + pathLenConstraint = basicConstraints.split(",")[1] + basicConstraintsExtension = rfc2459.BasicConstraints() + basicConstraintsExtension["cA"] = cA == "cA" + if pathLenConstraint: + pathLenConstraintValue = univ.Integer(int(pathLenConstraint)).subtype( + subtypeSpec=constraint.ValueRangeConstraint(0, float("inf")) + ) + basicConstraintsExtension["pathLenConstraint"] = pathLenConstraintValue + self.addExtension( + rfc2459.id_ce_basicConstraints, basicConstraintsExtension, critical + ) + + def addKeyUsage(self, keyUsage, critical): + keyUsageExtension = rfc2459.KeyUsage(keyUsage) + self.addExtension(rfc2459.id_ce_keyUsage, keyUsageExtension, critical) + + def keyPurposeToOID(self, keyPurpose): + if keyPurpose == "serverAuth": + return rfc2459.id_kp_serverAuth + if keyPurpose == "clientAuth": + return rfc2459.id_kp_clientAuth + if keyPurpose == "codeSigning": + return rfc2459.id_kp_codeSigning + if keyPurpose == "emailProtection": + return rfc2459.id_kp_emailProtection + if keyPurpose == "nsSGC": + return univ.ObjectIdentifier("2.16.840.1.113730.4.1") + if keyPurpose == "OCSPSigning": + return univ.ObjectIdentifier("1.3.6.1.5.5.7.3.9") + if keyPurpose == "timeStamping": + return rfc2459.id_kp_timeStamping + raise UnknownKeyPurposeTypeError(keyPurpose) + + def addExtKeyUsage(self, extKeyUsage, critical): + extKeyUsageExtension = rfc2459.ExtKeyUsageSyntax() + for count, keyPurpose in enumerate(extKeyUsage.split(",")): + extKeyUsageExtension.setComponentByPosition( + count, self.keyPurposeToOID(keyPurpose) + ) + self.addExtension(rfc2459.id_ce_extKeyUsage, extKeyUsageExtension, critical) + + def addSubjectAlternativeName(self, names, critical): + IPV4_PREFIX = "ip4:" + + subjectAlternativeName = rfc2459.SubjectAltName() + for count, name in enumerate(names.split(",")): + generalName = rfc2459.GeneralName() + if "/" in name: + directoryName = stringToDN( + name, tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4) + ) + generalName["directoryName"] = directoryName + elif "@" in name: + generalName["rfc822Name"] = name + elif name.startswith(IPV4_PREFIX): + generalName["iPAddress"] = socket.inet_pton( + socket.AF_INET, name[len(IPV4_PREFIX) :] + ) + else: + # The string may have things like '\0' (i.e. a slash + # followed by the number zero) that have to be decoded into + # the resulting '\x00' (i.e. a byte with value zero). + generalName["dNSName"] = six.ensure_binary(name).decode( + "unicode_escape" + ) + subjectAlternativeName.setComponentByPosition(count, generalName) + self.addExtension( + rfc2459.id_ce_subjectAltName, subjectAlternativeName, critical + ) + + def addAuthorityInformationAccess(self, ocspURI, critical): + sequence = univ.Sequence() + accessDescription = stringToAccessDescription(ocspURI) + sequence.setComponentByPosition(0, accessDescription) + self.addExtension(rfc2459.id_pe_authorityInfoAccess, sequence, critical) + + def addCertificatePolicies(self, policyOIDs, critical): + policies = rfc2459.CertificatePolicies() + for pos, policyOID in enumerate(policyOIDs.split(",")): + if policyOID == "any": + policyOID = "2.5.29.32.0" + policy = rfc2459.PolicyInformation() + policyIdentifier = rfc2459.CertPolicyId(policyOID) + policy["policyIdentifier"] = policyIdentifier + policies.setComponentByPosition(pos, policy) + self.addExtension(rfc2459.id_ce_certificatePolicies, policies, critical) + + def addNameConstraints(self, constraints, critical): + nameConstraints = rfc2459.NameConstraints() + if constraints.startswith("permitted:"): + (subtreesType, subtreesTag) = ("permittedSubtrees", 0) + elif constraints.startswith("excluded:"): + (subtreesType, subtreesTag) = ("excludedSubtrees", 1) + else: + raise UnknownNameConstraintsSpecificationError(constraints) + generalSubtrees = rfc2459.GeneralSubtrees().subtype( + implicitTag=tag.Tag( + tag.tagClassContext, tag.tagFormatConstructed, subtreesTag + ) + ) + subtrees = constraints[(constraints.find(":") + 1) :] + for pos, name in enumerate(subtrees.split(",")): + generalName = rfc2459.GeneralName() + if "/" in name: + directoryName = stringToDN( + name, tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4) + ) + generalName["directoryName"] = directoryName + else: + generalName["dNSName"] = name + generalSubtree = rfc2459.GeneralSubtree() + generalSubtree["base"] = generalName + generalSubtrees.setComponentByPosition(pos, generalSubtree) + nameConstraints[subtreesType] = generalSubtrees + self.addExtension(rfc2459.id_ce_nameConstraints, nameConstraints, critical) + + def addNSCertType(self, certType, critical): + if certType != "sslServer": + raise UnknownNSCertTypeError(certType) + self.addExtension( + univ.ObjectIdentifier("2.16.840.1.113730.1.1"), + univ.BitString("'01'B"), + critical, + ) + + def addDelegationUsage(self, critical): + if critical: + raise UnknownDelegatedCredentialError(critical) + self.addExtension( + univ.ObjectIdentifier("1.3.6.1.4.1.44363.44"), univ.Null(), critical + ) + + def addTLSFeature(self, features, critical): + namedFeatures = {"OCSPMustStaple": 5} + featureList = [f.strip() for f in features.split(",")] + sequence = univ.Sequence() + for pos, feature in enumerate(featureList): + featureValue = 0 + try: + featureValue = int(feature) + except ValueError: + try: + featureValue = namedFeatures[feature] + except Exception: + raise UnknownTLSFeature(feature) + sequence.setComponentByPosition(pos, univ.Integer(featureValue)) + self.addExtension( + univ.ObjectIdentifier("1.3.6.1.5.5.7.1.24"), sequence, critical + ) + + def addEmbeddedSCTListData(self): + (scts, critical) = self.savedEmbeddedSCTListData + encodedSCTs = [] + for sctSpec in scts.split(","): + match = re.search("(\w+):(\d{8})", sctSpec) + if not match: + raise InvalidSCTSpecification(sctSpec) + keySpec = match.group(1) + key = pykey.keyFromSpecification(keySpec) + time = datetime.datetime.strptime(match.group(2), "%Y%m%d") + tbsCertificate = self.getTBSCertificate() + tbsDER = encoder.encode(tbsCertificate) + sct = pyct.SCT(key, time, tbsDER, self.issuerKey) + signed = sct.signAndEncode() + lengthPrefix = pack("!H", len(signed)) + encodedSCTs.append(lengthPrefix + signed) + encodedSCTBytes = b"".join(encodedSCTs) + lengthPrefix = pack("!H", len(encodedSCTBytes)) + extensionBytes = lengthPrefix + encodedSCTBytes + self.addExtension( + univ.ObjectIdentifier("1.3.6.1.4.1.11129.2.4.2"), + univ.OctetString(extensionBytes), + critical, + ) + + def getVersion(self): + return rfc2459.Version(self.versionValue).subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0) + ) + + def getSerialNumber(self): + return decoder.decode(self.serialNumber)[0] + + def getIssuer(self): + return stringToDN(self.issuer) + + def getValidity(self): + validity = rfc2459.Validity() + validity["notBefore"] = self.getNotBefore() + validity["notAfter"] = self.getNotAfter() + return validity + + def getNotBefore(self): + return datetimeToTime(self.notBefore) + + def getNotAfter(self): + return datetimeToTime(self.notAfter) + + def getSubject(self): + return stringToDN(self.subject) + + def getTBSCertificate(self): + (signatureOID, _) = stringToAlgorithmIdentifiers(self.signature) + tbsCertificate = rfc2459.TBSCertificate() + tbsCertificate["version"] = self.getVersion() + tbsCertificate["serialNumber"] = self.getSerialNumber() + tbsCertificate["signature"] = signatureOID + tbsCertificate["issuer"] = self.getIssuer() + tbsCertificate["validity"] = self.getValidity() + tbsCertificate["subject"] = self.getSubject() + tbsCertificate[ + "subjectPublicKeyInfo" + ] = self.subjectKey.asSubjectPublicKeyInfo() + if self.extensions: + extensions = rfc2459.Extensions().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3) + ) + for count, extension in enumerate(self.extensions): + extensions.setComponentByPosition(count, extension) + tbsCertificate["extensions"] = extensions + return tbsCertificate + + def toDER(self): + (signatureOID, hashAlgorithm) = stringToAlgorithmIdentifiers(self.signature) + certificate = rfc2459.Certificate() + tbsCertificate = self.getTBSCertificate() + certificate["tbsCertificate"] = tbsCertificate + certificate["signatureAlgorithm"] = signatureOID + tbsDER = encoder.encode(tbsCertificate) + certificate["signatureValue"] = self.issuerKey.sign(tbsDER, hashAlgorithm) + return encoder.encode(certificate) + + def toPEM(self): + output = "-----BEGIN CERTIFICATE-----" + der = self.toDER() + b64 = six.ensure_text(base64.b64encode(der)) + while b64: + output += "\n" + b64[:64] + b64 = b64[64:] + output += "\n-----END CERTIFICATE-----" + return output + + +# The build harness will call this function with an output +# file-like object and a path to a file containing a +# specification. This will read the specification and output +# the certificate as PEM. +# This utility tries as hard as possible to ensure that two +# runs with the same input will have the same output. This is +# particularly important when building on OS X, where we +# generate everything twice for unified builds. During the +# unification step, if any pair of input files differ, the build +# system throws an error. +# The one concrete failure mode is if one run happens before +# midnight on New Year's Eve and the next run happens after +# midnight. +def main(output, inputPath): + with open(inputPath) as configStream: + output.write(Certificate(configStream).toPEM() + "\n") + + +# When run as a standalone program, this will read a specification from +# stdin and output the certificate as PEM to stdout. +if __name__ == "__main__": + print(Certificate(sys.stdin).toPEM()) diff --git a/security/manager/ssl/tests/unit/pycms.py b/security/manager/ssl/tests/unit/pycms.py new file mode 100755 index 0000000000..befe68e346 --- /dev/null +++ b/security/manager/ssl/tests/unit/pycms.py @@ -0,0 +1,219 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Reads a specification from stdin and outputs a PKCS7 (CMS) message with +the desired properties. + +The specification format is as follows: + +sha1: +sha256: +signer: + + +Eith or both of sha1 and sha256 may be specified. The value of +each hash directive is what will be put in the messageDigest +attribute of the SignerInfo that corresponds to the signature +algorithm defined by the hash algorithm and key type of the +default key. Together, these comprise the signerInfos field of +the SignedData. If neither hash is specified, the signerInfos +will be an empty SET (i.e. there will be no actual signature +information). +The certificate specification must come last. +""" + +from pyasn1.codec.der import decoder +from pyasn1.codec.der import encoder +from pyasn1.type import tag, univ +from pyasn1_modules import rfc2315, rfc2459 +import base64 +from io import StringIO +import pycert +import pykey +import sys + + +class Error(Exception): + """Base class for exceptions in this module.""" + + pass + + +class UnknownDirectiveError(Error): + """Helper exception type to handle unknown specification + directives.""" + + def __init__(self, directive): + super(UnknownDirectiveError, self).__init__() + self.directive = directive + + def __str__(self): + return "Unknown directive %s" % repr(self.directive) + + +class CMS(object): + """Utility class for reading a CMS specification and + generating a CMS message""" + + def __init__(self, paramStream): + self.sha1 = "" + self.sha256 = "" + signerSpecification = StringIO() + readingSignerSpecification = False + for line in paramStream.readlines(): + if readingSignerSpecification: + print(line.strip(), file=signerSpecification) + elif line.strip() == "signer:": + readingSignerSpecification = True + elif line.startswith("sha1:"): + self.sha1 = line.strip()[len("sha1:") :] + elif line.startswith("sha256:"): + self.sha256 = line.strip()[len("sha256:") :] + else: + raise UnknownDirectiveError(line.strip()) + signerSpecification.seek(0) + self.signer = pycert.Certificate(signerSpecification) + self.signingKey = pykey.keyFromSpecification("default") + + def buildAuthenticatedAttributes(self, value, implicitTag=None): + """Utility function to build a pyasn1 AuthenticatedAttributes + object. Useful because when building a SignerInfo, the + authenticatedAttributes needs to be tagged implicitly, but when + signing an AuthenticatedAttributes, it needs the explicit SET + tag.""" + if implicitTag: + authenticatedAttributes = rfc2315.Attributes().subtype( + implicitTag=implicitTag + ) + else: + authenticatedAttributes = rfc2315.Attributes() + contentTypeAttribute = rfc2315.Attribute() + # PKCS#9 contentType + contentTypeAttribute["type"] = univ.ObjectIdentifier("1.2.840.113549.1.9.3") + contentTypeAttribute["values"] = univ.SetOf(rfc2459.AttributeValue()) + # PKCS#7 data + contentTypeAttribute["values"][0] = univ.ObjectIdentifier( + "1.2.840.113549.1.7.1" + ) + authenticatedAttributes[0] = contentTypeAttribute + hashAttribute = rfc2315.Attribute() + # PKCS#9 messageDigest + hashAttribute["type"] = univ.ObjectIdentifier("1.2.840.113549.1.9.4") + hashAttribute["values"] = univ.SetOf(rfc2459.AttributeValue()) + hashAttribute["values"][0] = univ.OctetString(hexValue=value) + authenticatedAttributes[1] = hashAttribute + return authenticatedAttributes + + def pykeyHashToDigestAlgorithm(self, pykeyHash): + """Given a pykey hash algorithm identifier, builds an + AlgorithmIdentifier for use with pyasn1.""" + if pykeyHash == pykey.HASH_SHA1: + oidString = "1.3.14.3.2.26" + elif pykeyHash == pykey.HASH_SHA256: + oidString = "2.16.840.1.101.3.4.2.1" + else: + raise pykey.UnknownHashAlgorithmError(pykeyHash) + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier["algorithm"] = univ.ObjectIdentifier(oidString) + # Directly setting parameters to univ.Null doesn't currently work. + nullEncapsulated = encoder.encode(univ.Null()) + algorithmIdentifier["parameters"] = univ.Any(nullEncapsulated) + return algorithmIdentifier + + def buildSignerInfo(self, certificate, pykeyHash, digestValue): + """Given a pyasn1 certificate, a pykey hash identifier + and a hash value, creates a SignerInfo with the + appropriate values.""" + signerInfo = rfc2315.SignerInfo() + signerInfo["version"] = 1 + issuerAndSerialNumber = rfc2315.IssuerAndSerialNumber() + issuerAndSerialNumber["issuer"] = self.signer.getIssuer() + issuerAndSerialNumber["serialNumber"] = certificate["tbsCertificate"][ + "serialNumber" + ] + signerInfo["issuerAndSerialNumber"] = issuerAndSerialNumber + signerInfo["digestAlgorithm"] = self.pykeyHashToDigestAlgorithm(pykeyHash) + rsa = rfc2459.AlgorithmIdentifier() + rsa["algorithm"] = rfc2459.rsaEncryption + rsa["parameters"] = univ.Null() + authenticatedAttributes = self.buildAuthenticatedAttributes( + digestValue, + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0), + ) + authenticatedAttributesTBS = self.buildAuthenticatedAttributes(digestValue) + signerInfo["authenticatedAttributes"] = authenticatedAttributes + signerInfo["digestEncryptionAlgorithm"] = rsa + authenticatedAttributesEncoded = encoder.encode(authenticatedAttributesTBS) + signature = self.signingKey.sign(authenticatedAttributesEncoded, pykeyHash) + # signature will be a hexified bit string of the form + # "''H". For some reason that's what BitString wants, + # but since this is an OCTET STRING, we have to strip off the + # quotation marks and trailing "H". + signerInfo["encryptedDigest"] = univ.OctetString(hexValue=signature[1:-2]) + return signerInfo + + def toDER(self): + contentInfo = rfc2315.ContentInfo() + contentInfo["contentType"] = rfc2315.signedData + + signedData = rfc2315.SignedData() + signedData["version"] = rfc2315.Version(1) + + digestAlgorithms = rfc2315.DigestAlgorithmIdentifiers() + digestAlgorithms[0] = self.pykeyHashToDigestAlgorithm(pykey.HASH_SHA1) + signedData["digestAlgorithms"] = digestAlgorithms + + dataContentInfo = rfc2315.ContentInfo() + dataContentInfo["contentType"] = rfc2315.data + signedData["contentInfo"] = dataContentInfo + + certificates = rfc2315.ExtendedCertificatesAndCertificates().subtype( + implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0) + ) + extendedCertificateOrCertificate = rfc2315.ExtendedCertificateOrCertificate() + certificate = decoder.decode( + self.signer.toDER(), asn1Spec=rfc2459.Certificate() + )[0] + extendedCertificateOrCertificate["certificate"] = certificate + certificates[0] = extendedCertificateOrCertificate + signedData["certificates"] = certificates + + signerInfos = rfc2315.SignerInfos() + + if len(self.sha1) > 0: + signerInfos[len(signerInfos)] = self.buildSignerInfo( + certificate, pykey.HASH_SHA1, self.sha1 + ) + if len(self.sha256) > 0: + signerInfos[len(signerInfos)] = self.buildSignerInfo( + certificate, pykey.HASH_SHA256, self.sha256 + ) + signedData["signerInfos"] = signerInfos + + encoded = encoder.encode(signedData) + anyTag = univ.Any(encoded).subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0) + ) + + contentInfo["content"] = anyTag + return encoder.encode(contentInfo) + + def toPEM(self): + output = "-----BEGIN PKCS7-----" + der = self.toDER() + b64 = base64.b64encode(der) + while b64: + output += "\n" + b64[:64] + b64 = b64[64:] + output += "\n-----END PKCS7-----\n" + return output + + +# When run as a standalone program, this will read a specification from +# stdin and output the certificate as PEM to stdout. +if __name__ == "__main__": + print(CMS(sys.stdin).toPEM()) diff --git a/security/manager/ssl/tests/unit/pyct.py b/security/manager/ssl/tests/unit/pyct.py new file mode 100644 index 0000000000..125b626fc2 --- /dev/null +++ b/security/manager/ssl/tests/unit/pyct.py @@ -0,0 +1,103 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Helper library for creating a Signed Certificate Timestamp given the +details of a signing key, when to sign, and the certificate data to +sign. Currently only supports precert_entry types. See RFC 6962. +""" + +from pyasn1.codec.der import encoder +from struct import pack +import binascii +import calendar +import hashlib + +import pykey + + +class InvalidKeyError(Exception): + """Helper exception to handle unknown key types.""" + + def __init__(self, key): + self.key = key + + def __str__(self): + return 'Invalid key: "%s"' % str(self.key) + + +class SCT(object): + """SCT represents a Signed Certificate Timestamp.""" + + def __init__(self, key, date, tbsCertificate, issuerKey): + self.key = key + self.timestamp = calendar.timegm(date.timetuple()) * 1000 + self.tbsCertificate = tbsCertificate + self.issuerKey = issuerKey + + def signAndEncode(self): + """Returns a signed and encoded representation of the SCT as a + string.""" + # The signature is over the following data: + # sct_version (one 0 byte) + # signature_type (one 0 byte) + # timestamp (8 bytes, milliseconds since the epoch) + # entry_type (two bytes [0, 1] - currently only precert_entry is + # supported) + # signed_entry (bytes of PreCert) + # extensions (2-byte-length-prefixed, currently empty (so two 0 + # bytes)) + # A PreCert is: + # issuer_key_hash (32 bytes of SHA-256 hash of the issuing + # public key, as DER-encoded SPKI) + # tbs_certificate (3-byte-length-prefixed data) + timestamp = pack("!Q", self.timestamp) + hasher = hashlib.sha256() + hasher.update(encoder.encode(self.issuerKey.asSubjectPublicKeyInfo())) + issuer_key_hash = hasher.digest() + len_prefix = pack("!L", len(self.tbsCertificate))[1:] + data = ( + b"\0\0" + + timestamp + + b"\0\1" + + issuer_key_hash + + len_prefix + + self.tbsCertificate + + b"\0\0" + ) + if isinstance(self.key, pykey.ECCKey): + signatureByte = b"\3" + elif isinstance(self.key, pykey.RSAKey): + signatureByte = b"\1" + else: + raise InvalidKeyError(self.key) + # sign returns a hex string like "''H", but we want + # bytes here + hexSignature = self.key.sign(data, pykey.HASH_SHA256) + signature = binascii.unhexlify(hexSignature[1:-2]) + # The actual data returned is the following: + # sct_version (one 0 byte) + # id (32 bytes of SHA-256 hash of the signing key, as + # DER-encoded SPKI) + # timestamp (8 bytes, milliseconds since the epoch) + # extensions (2-byte-length-prefixed data, currently + # empty) + # hash (one 4 byte representing sha256) + # signature (one byte - 1 for RSA and 3 for ECDSA) + # signature (2-byte-length-prefixed data) + hasher = hashlib.sha256() + hasher.update(encoder.encode(self.key.asSubjectPublicKeyInfo())) + key_id = hasher.digest() + signature_len_prefix = pack("!H", len(signature)) + return ( + b"\0" + + key_id + + timestamp + + b"\0\0\4" + + signatureByte + + signature_len_prefix + + signature + ) diff --git a/security/manager/ssl/tests/unit/pykey.py b/security/manager/ssl/tests/unit/pykey.py new file mode 100755 index 0000000000..05163adc36 --- /dev/null +++ b/security/manager/ssl/tests/unit/pykey.py @@ -0,0 +1,958 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Reads a key specification from stdin or a file and outputs a +PKCS #8 file representing the (private) key. Also provides +methods for signing data and representing the key as a subject +public key info for use with pyasn1. + +The key specification format is as follows: + +default: a 2048-bit RSA key +alternate: a different 2048-bit RSA key +ev: a 2048-bit RSA key that, when combined with the right pycert + specification, results in a certificate that is enabled for + extended validation in debug Firefox (see ExtendedValidation.cpp). +evRSA2040: a 2040-bit RSA key that, when combined with the right pycert + specification, results in a certificate that is enabled for + extended validation in debug Firefox. +rsa2040: a 2040-bit RSA key +rsa1024: a 1024-bit RSA key +rsa1016: a 1016-bit RSA key +secp256k1: an ECC key on the curve secp256k1 +secp244r1: an ECC key on the curve secp244r1 +secp256r1: an ECC key on the curve secp256r1 +secp384r1: an ECC key on the curve secp384r1 +secp521r1: an ECC key on the curve secp521r1 +""" + +from pyasn1.codec.der import encoder +from pyasn1.type import univ, namedtype, tag +from pyasn1_modules import rfc2459 +import base64 +import binascii +import ecdsa +import hashlib +import math +import rsa +import six +import sys + +# "constants" to make it easier for consumers to specify hash algorithms +HASH_MD5 = "hash:md5" +HASH_SHA1 = "hash:sha1" +HASH_SHA256 = "hash:sha256" +HASH_SHA384 = "hash:sha384" +HASH_SHA512 = "hash:sha512" + + +# NOTE: With bug 1621441 we migrated from one library for ecdsa to another. +# These libraries differ somewhat in terms of functionality and interface. In +# order to ensure there are no diffs and that the generated signatures are +# exactly the same between the two libraries, we need to patch some stuff in. + + +def _gen_k(curve): + # This calculation is arbitrary, but it matches what we were doing pre- + # bug 1621441 (see the above NOTE). Crucially, this generation of k is + # non-random; the ecdsa library exposes an option to deterministically + # generate a value of k for us, but it doesn't match up to what we were + # doing before so we have to inject a custom value. + num_bytes = int(math.log(curve.order - 1, 2) + 1) // 8 + 8 + entropy = int.from_bytes(b"\04" * num_bytes, byteorder="big") + p = curve.curve.p() + return (entropy % (p - 1)) + 1 + + +# As above, the library has built-in logic for truncating digests that are too +# large, but they use a slightly different technique than our previous library. +# Re-implement that logic here. +def _truncate_digest(digest, curve): + i = int.from_bytes(digest, byteorder="big") + p = curve.curve.p() + while i > p: + i >>= 1 + return i.to_bytes(math.ceil(i.bit_length() / 8), byteorder="big") + + +def byteStringToHexifiedBitString(string): + """Takes a string of bytes and returns a hex string representing + those bytes for use with pyasn1.type.univ.BitString. It must be of + the form "''H", where the trailing 'H' indicates to + pyasn1 that the input is a hex string.""" + return "'%s'H" % six.ensure_binary(string).hex() + + +class UnknownBaseError(Exception): + """Base class for handling unexpected input in this module.""" + + def __init__(self, value): + super(UnknownBaseError, self).__init__() + self.value = value + self.category = "input" + + def __str__(self): + return 'Unknown %s type "%s"' % (self.category, repr(self.value)) + + +class UnknownKeySpecificationError(UnknownBaseError): + """Helper exception type to handle unknown key specifications.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "key specification" + + +class UnknownHashAlgorithmError(UnknownBaseError): + """Helper exception type to handle unknown key specifications.""" + + def __init__(self, value): + UnknownBaseError.__init__(self, value) + self.category = "hash algorithm" + + +class UnsupportedHashAlgorithmError(Exception): + """Helper exception type for unsupported hash algorithms.""" + + def __init__(self, value): + super(UnsupportedHashAlgorithmError, self).__init__() + self.value = value + + def __str__(self): + return 'Unsupported hash algorithm "%s"' % repr(self.value) + + +class RSAPublicKey(univ.Sequence): + """Helper type for encoding an RSA public key""" + + componentType = namedtype.NamedTypes( + namedtype.NamedType("N", univ.Integer()), + namedtype.NamedType("E", univ.Integer()), + ) + + +class RSAPrivateKey(univ.Sequence): + """Helper type for encoding an RSA private key""" + + componentType = namedtype.NamedTypes( + namedtype.NamedType("version", univ.Integer()), + namedtype.NamedType("modulus", univ.Integer()), + namedtype.NamedType("publicExponent", univ.Integer()), + namedtype.NamedType("privateExponent", univ.Integer()), + namedtype.NamedType("prime1", univ.Integer()), + namedtype.NamedType("prime2", univ.Integer()), + namedtype.NamedType("exponent1", univ.Integer()), + namedtype.NamedType("exponent2", univ.Integer()), + namedtype.NamedType("coefficient", univ.Integer()), + ) + + +class ECPrivateKey(univ.Sequence): + """Helper type for encoding an EC private key + ECPrivateKey ::= SEQUENCE { + version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), + privateKey OCTET STRING, + parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, + (NOTE: parameters field is not supported) + publicKey [1] BIT STRING OPTIONAL + }""" + + componentType = namedtype.NamedTypes( + namedtype.NamedType("version", univ.Integer()), + namedtype.NamedType("privateKey", univ.OctetString()), + namedtype.OptionalNamedType( + "publicKey", + univ.BitString().subtype( + explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1) + ), + ), + ) + + +class ECPoint(univ.Sequence): + """Helper type for encoding a EC point""" + + componentType = namedtype.NamedTypes( + namedtype.NamedType("x", univ.Integer()), + namedtype.NamedType("y", univ.Integer()), + ) + + +class PrivateKeyInfo(univ.Sequence): + """Helper type for encoding a PKCS #8 private key info""" + + componentType = namedtype.NamedTypes( + namedtype.NamedType("version", univ.Integer()), + namedtype.NamedType("privateKeyAlgorithm", rfc2459.AlgorithmIdentifier()), + namedtype.NamedType("privateKey", univ.OctetString()), + ) + + +class RSAKey(object): + # For reference, when encoded as a subject public key info, the + # base64-encoded sha-256 hash of this key is + # VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8= + sharedRSA_N = int( + "00ba8851a8448e16d641fd6eb6880636103d3c13d9eae4354ab4ecf56857" + "6c247bc1c725a8e0d81fbdb19c069b6e1a86f26be2af5a756b6a6471087a" + "a55aa74587f71cd5249c027ecd43fc1e69d038202993ab20c349e4dbb94c" + "c26b6c0eed15820ff17ead691ab1d3023a8b2a41eea770e00f0d8dfd660b" + "2bb02492a47db988617990b157903dd23bc5e0b8481fa837d38843ef2716" + "d855b7665aaa7e02902f3a7b10800624cc1c6c97ad96615bb7e29612c075" + "31a30c91ddb4caf7fcad1d25d309efb9170ea768e1b37b2f226f69e3b48a" + "95611dee26d6259dab91084e36cb1c24042cbf168b2fe5f18f991731b8b3" + "fe4923fa7251c431d503acda180a35ed8d", + 16, + ) + sharedRSA_E = 65537 + sharedRSA_D = int( + "009ecbce3861a454ecb1e0fe8f85dd43c92f5825ce2e997884d0e1a949da" + "a2c5ac559b240450e5ac9fe0c3e31c0eefa6525a65f0c22194004ee1ab46" + "3dde9ee82287cc93e746a91929c5e6ac3d88753f6c25ba5979e73e5d8fb2" + "39111a3cdab8a4b0cdf5f9cab05f1233a38335c64b5560525e7e3b92ad7c" + "7504cf1dc7cb005788afcbe1e8f95df7402a151530d5808346864eb370aa" + "79956a587862cb533791307f70d91c96d22d001a69009b923c683388c9f3" + "6cb9b5ebe64302041c78d908206b87009cb8cabacad3dbdb2792fb911b2c" + "f4db6603585be9ae0ca3b8e6417aa04b06e470ea1a3b581ca03a6781c931" + "5b62b30e6011f224725946eec57c6d9441", + 16, + ) + sharedRSA_P = int( + "00dd6e1d4fffebf68d889c4d114cdaaa9caa63a59374286c8a5c29a717bb" + "a60375644d5caa674c4b8bc7326358646220e4550d7608ac27d55b6db74f" + "8d8127ef8fa09098b69147de065573447e183d22fe7d885aceb513d9581d" + "d5e07c1a90f5ce0879de131371ecefc9ce72e9c43dc127d238190de81177" + "3ca5d19301f48c742b", + 16, + ) + sharedRSA_Q = int( + "00d7a773d9ebc380a767d2fec0934ad4e8b5667240771acdebb5ad796f47" + "8fec4d45985efbc9532968289c8d89102fadf21f34e2dd4940eba8c09d6d" + "1f16dcc29729774c43275e9251ddbe4909e1fd3bf1e4bedf46a39b8b3833" + "28ef4ae3b95b92f2070af26c9e7c5c9b587fedde05e8e7d86ca57886fb16" + "5810a77b9845bc3127", + 16, + ) + sharedRSA_exp1 = int( + "0096472b41a610c0ade1af2266c1600e3671355ba42d4b5a0eb4e9d7eb35" + "81400ba5dd132cdb1a5e9328c7bbc0bbb0155ea192972edf97d12751d8fc" + "f6ae572a30b1ea309a8712dd4e33241db1ee455fc093f5bc9b592d756e66" + "21474f32c07af22fb275d340792b32ba2590bbb261aefb95a258eea53765" + "5315be9c24d191992d", + 16, + ) + sharedRSA_exp2 = int( + "28b450a7a75a856413b2bda6f7a63e3d964fb9ecf50e3823ef6cc8e8fa26" + "ee413f8b9d1205540f12bbe7a0c76828b7ba65ad83cca4d0fe2a220114e1" + "b35d03d5a85bfe2706bd50fce6cfcdd571b46ca621b8ed47d605bbe765b0" + "aa4a0665ac25364da20154032e1204b8559d3e34fb5b177c9a56ff93510a" + "5a4a6287c151de2d", + 16, + ) + sharedRSA_coef = int( + "28067b9355801d2ef52dfa96d8adb589673cf8ee8a9c6ff72aeeabe9ef6b" + "e58a4f4abf05f788947dc851fdaa34542147a71a246bfb054ee76aa346ab" + "cd2692cfc9e44c51e6f069c735e073ba019f6a7214961c91b26871caeabf" + "8f064418a02690e39a8d5ff3067b7cdb7f50b1f53418a703966c4fc774bf" + "7402af6c43247f43", + 16, + ) + + # For reference, when encoded as a subject public key info, the + # base64-encoded sha-256 hash of this key is + # MQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJI= + alternateRSA_N = int( + "00c175c65266099f77082a6791f1b876c37f5ce538b06c4acd22b1cbd46f" + "a65ada2add41c8c2498ac4a3b3c1f61487f41b698941bd80a51c3c120244" + "c584a4c4483305e5138c0106cf08be9a862760bae6a2e8f36f23c5d98313" + "b9dfaf378345dace51d4d6dcd2a6cb3cc706ebcd3070ec98cce40aa591d7" + "295a7f71c5be66691d2b2dfec84944590bc5a3ea49fd93b1d753405f1773" + "7699958666254797ed426908880811422069988a43fee48ce68781dd22b6" + "a69cd28375131f932b128ce286fa7d251c062ad27ef016f187cdd54e832b" + "35b8930f74ba90aa8bc76167242ab1fd6d62140d18c4c0b8c68fc3748457" + "324ad7de86e6552f1d1e191d712168d3bb", + 16, + ) + alternateRSA_E = 65537 + alternateRSA_D = int( + "7e3f6d7cb839ef66ae5d7dd92ff5410bb341dc14728d39034570e1a37079" + "0f30f0681355fff41e2ad4e9a9d9fcebfbd127bdfab8c00affb1f3cea732" + "7ead47aa1621f2ac1ee14ca02f04b3b2786017980b181a449d03b03e69d1" + "12b83571e55434f012056575d2832ed6731dce799e37c83f6d51c55ab71e" + "b58015af05e1af15c747603ef7f27d03a6ff049d96bbf854c1e4e50ef5b0" + "58d0fb08180e0ac7f7be8f2ff1673d97fc9e55dba838077bbf8a7cff2962" + "857785269cd9d5bad2b57469e4afcd33c4ca2d2f699f11e7c8fbdcd484f0" + "8d8efb8a3cb8a972eb24bed972efaae4bb712093e48fe94a46eb629a8750" + "78c4021a9a2c93c9a70390e9d0a54401", + 16, + ) + alternateRSA_P = int( + "00e63fc725a6ba76925a7ff8cb59c4f56dd7ec83fe85bf1f53e11cac9a81" + "258bcfc0ae819077b0f2d1477aaf868de6a8ecbeaf7bb22b196f2a9ad82d" + "3286f0d0cc29de719e5f2be8e509b7284d5963edd362f927887a4c4a8979" + "9d340d51b301ac7601ab27179024fcaadd38bf6522af63eb16461ec02a7f" + "27b06fe09ddda7c0a1", + 16, + ) + alternateRSA_Q = int( + "00d718b1fe9f8f99f00e832ae1fbdc6fe2ab27f34e049c498010fa0eb708" + "4852182346083b5c96c3eee5592c014a410c6b930b165c13b5c26aa32eac" + "6e7c925a8551c25134f2f4a72c6421f19a73148a0edfaba5d3a6888b35cb" + "a18c00fd38ee5aaf0b545731d720761bbccdee744a52ca415e98e4de01cd" + "fe764c1967b3e8cadb", + 16, + ) + alternateRSA_exp1 = int( + "01e5aca266c94a88d22e13c2b92ea247116c657a076817bdfd30db4b3a9d" + "3095b9a4b6749647e2f84e7a784fc7838b08c85971cf7a036fa30e3b91c3" + "c4d0df278f80c1b6e859d8456adb137defaa9f1f0ac5bac9a9184fd4ea27" + "9d722ea626f160d78aad7bc83845ccb29df115c83f61b7622b99bd439c60" + "9b5790a63c595181", + 16, + ) + alternateRSA_exp2 = int( + "0080cc45d10d2484ee0d1297fc07bf80b3beff461ea27e1f38f371789c3a" + "f66b4a0edd2192c227791db4f1c77ae246bf342f31856b0f56581b58a95b" + "1131c0c5396db2a8c3c6f39ea2e336bc205ae6a2a0b36869fca98cbba733" + "cf01319a6f9bb26b7ca23d3017fc551cd8da8afdd17f6fa2e30d34868798" + "1cd6234d571e90b7df", + 16, + ) + alternateRSA_coef = int( + "6f77c0c1f2ae7ac169561cca499c52bdfbe04cddccdbdc12aec5a85691e8" + "594b7ee29908f30e7b96aa6254b80ed4aeec9b993782bdfc79b69d8d58c6" + "8870fa4be1bc0c3527288c5c82bb4aebaf15edff110403fc78e6ace6a828" + "27bf42f0cfa751e507651c5638db9393dd23dd1f6b295151de44b77fe55a" + "7b0df271e19a65c0", + 16, + ) + + evRSA_N = int( + "00b549895c9d00108d11a1f99f87a9e3d1a5db5dfaecf188da57bf641368" + "8f2ce4722cff109038c17402c93a2a473dbd286aed3fdcd363cf5a291477" + "01bdd818d7615bf9356bd5d3c8336aaa8c0971368a06c3cd4461b93e5142" + "4e1744bb2eaad46aab38ce196821961f87714a1663693f09761cdf4d6ba1" + "25eacec7be270d388f789f6cdf78ae3144ed28c45e79293863a7a22a4898" + "0a36a40e72d579c9b925dff8c793362ffd6897a7c1754c5e97c967c3eadd" + "1aae8aa2ccce348a0169b80e28a2d70c1a960c6f335f2da09b9b643f5abf" + "ba49e8aaa981e960e27d87480bdd55dd9417fa18509fbb554ccf81a4397e" + "8ba8128a34bdf27865c189e5734fb22905", + 16, + ) + evRSA_E = 65537 + evRSA_D = int( + "00983d54f94d6f4c76eb23d6f93d78523530cf73b0d16254c6e781768d45" + "f55681d1d02fb2bd2aac6abc1c389860935c52a0d8f41482010394778314" + "1d864bff30803638a5c0152570ae9d18f3d8ca163efb475b0dddf32e7e16" + "ec7565e6bb5e025c41c5c66e57a03cede554221f83045347a2c4c451c3dc" + "e476b787ce0c057244be9e04ef13118dbbb3d5e0a6cc87029eafd4a69ed9" + "b14759b15e39d8a9884e56f54d2f9ab013f0d15f318a9ab6b2f73d1ec3c9" + "fe274ae89431a10640be7899b0011c5e5093a1834708689de100634dabde" + "60fbd6aaefa3a33df34a1f36f60c043036b748d1c9ee98c4031a0afec60e" + "fda0a990be524f5614eac4fdb34a52f951", + 16, + ) + evRSA_P = int( + "00eadc2cb33e5ff1ca376bbd95bd6a1777d2cf4fac47545e92d11a6209b9" + "d5e4ded47834581c169b3c884742a09ea187505c1ca55414d8d25b497632" + "d5ec2aaa05233430fad49892777a7d68e038f561a3b8969e60b0a263defb" + "fda48a9b0ff39d95bc88b15267c8ade97b5107948e41e433249d87f7db10" + "9d5d74584d86bcc1d7", + 16, + ) + evRSA_Q = int( + "00c59ae576a216470248d944a55b9e9bf93299da341ec56e558eba821abc" + "e1bf57b79cf411d2904c774f9dba1f15185f607b0574a08205d6ec28b66a" + "36d634232eaaf2fea37561abaf9d644b68db38c9964cb8c96ec0ac61eba6" + "4d05b446542f423976f5acde4ecc95536d2df578954f93f0cfd9c58fb78b" + "a2a76dd5ac284dc883", + 16, + ) + evRSA_exp1 = int( + "00c1d2ef3906331c52aca64811f9fe425beb2898322fb3db51032ce8d7e9" + "fc32240be92019cf2480fcd5e329837127118b2a59a1bfe06c883e3a4447" + "f3f031cd9aebd0b8d368fc79740d2cce8eadb324df7f091eafe1564361d5" + "4920b01b0471230e5e47d93f8ed33963c517bc4fc78f6d8b1f9eba85bcce" + "db7033026508db6285", + 16, + ) + evRSA_exp2 = int( + "008521b8db5694dfbe804a315f9efc9b65275c5490acf2a3456d65e6e610" + "bf9f647fc67501d4f5772f232ac70ccdef9fc2a6dfa415c7c41b6afc7af9" + "d07c3ca03f7ed93c09f0b99f2c304434322f1071709bbc1baa4c91575fa6" + "a959e07d4996956d95e22b57938b6e47c8d51ffedfc9bf888ce0d1a3e42b" + "65a89bed4b91d3e5f5", + 16, + ) + evRSA_coef = int( + "00dc497b06b920c8be0b0077b798e977eef744a90ec2c5d7e6cbb22448fa" + "c72da81a33180e0d8a02e831460c7fc7fd3a612f7b9930b61b799f8e908e" + "632e9ba0409b6aa70b03a3ba787426263b5bd5843df8476edb5d14f6a861" + "3ebaf5b9cd5ca42f5fbd2802e08e4e49e5709f5151510caa5ab2c1c6eb3e" + "fe9295d16e8c25c916", + 16, + ) + + evRSA2040_N = int( + "00ca7020dc215f57914d343fae4a015111697af997a5ece91866499fc23f" + "1b88a118cbd30b10d91c7b9a0d4ee8972fcae56caf57f25fc1275a2a4dbc" + "b982428c32ef587bf2387410330a0ffb16b8029bd783969ef675f6de38c1" + "8f67193cb6c072f8b23d0b3374112627a57b90055771d9e62603f53788d7" + "f63afa724f5d108096df31f89f26b1eb5f7c4357980e008fcd55d827dd26" + "2395ca2f526a07897cc40c593b38716ebc0caa596719c6f29ac9b73a7a94" + "4748a3aa3e09e9eb4d461ea0027e540926614728b9d243975cf9a0541bef" + "d25e76b51f951110b0e7644fc7e38441791b6d2227384cb8004e23342372" + "b1cf5cc3e73e31b7bbefa160e6862ebb", + 16, + ) + evRSA2040_E = 65537 + evRSA2040_D = int( + "00b2db74bce92362abf72955a638ae8720ba3033bb7f971caf39188d7542" + "eaa1c1abb5d205b1e2111f4791c08911a2e141e8cfd7054702d23100b564" + "2c06e1a31b118afd1f9a2f396cced425c501d91435ca8656766ced2b93bb" + "b8669fce9bacd727d1dacb3dafabc3293e35389eef8ea0b58e1aeb1a20e6" + "a61f9fcd453f7567fe31d123b616a26fef4df1d6c9f7490111d028eefd1d" + "972045b1a242273dd7a67ebf111db2741a5a93c7b2289cc4a236f5a99a6e" + "c7a8206fdae1c1d04bdbb1980d4a298c5a17dae4186474a5f7835d882bce" + "f24aef4ed6f149f94d96c9f7d78e647fc778a9017ff208d3b4a1768b1821" + "62102cdab032fabbab38d5200a324649", + 16, + ) + evRSA2040_P = int( + "0f3844d0d4d4d6a21acd76a6fc370b8550e1d7ec5a6234172e790f0029ae" + "651f6d5c59330ab19802b9d7a207de7a1fb778e3774fdbdc411750633d8d" + "1b3fe075006ffcfd1d10e763c7a9227d2d5f0c2dade1c9e659c350a159d3" + "6bb986f12636d4f9942b288bc0fe21da8799477173144249ca2e389e6c5c" + "25aa78c8cad7d4df", + 16, + ) + evRSA2040_Q = int( + "0d4d0bedd1962f07a1ead6b23a4ed67aeaf1270f052a6d29ba074945c636" + "1a5c4f8f07bf859e067aed3f4e6e323ef2aa8a6acd340b0bdc7cfe4fd329" + "e3c97f870c7f7735792c6aa9d0f7e7542a28ed6f01b0e55a2b8d9c24a65c" + "6da314c95484f5c7c3954a81bb016b07ed17ee9b06039695bca059a79f8d" + "c2423d328d5265a5", + 16, + ) + evRSA2040_exp1 = int( + "09f29a2ff05be8a96d614ba31b08935420a86c6bc42b99a6692ea0da5763" + "f01e596959b7ddce73ef9c2e4f6e5b40710887500d44ba0c3cd3132cba27" + "475f39c2df7552e2d123a2497a4f97064028769a48a3624657f72bf539f3" + "d0de234feccd3be8a0aa90c6bf6e9b0bed43070a24d061ff3ed1751a3ef2" + "ff7f6b90b9dbd5fb", + 16, + ) + evRSA2040_exp2 = int( + "01a659e170cac120a03be1cf8f9df1caa353b03593bd7476e5853bd874c2" + "87388601c6c341ce9d1d284a5eef1a3a669d32b816a5eaecd8b7844fe070" + "64b9bca0c2b318d540277b3f7f1510d386bb36e03b04771e5d229e88893e" + "13b753bfb94518bb638e2404bd6e6a993c1668d93fc0b82ff08aaf34347d" + "3fe8397108c87ca5", + 16, + ) + evRSA2040_coef = int( + "040257c0d4a21c0b9843297c65652db66304fb263773d728b6abfa06d37a" + "c0ca62c628023e09e37dc0a901e4ce1224180e2582a3aa4b6a1a7b98e2bd" + "70077aec14ac8ab66a755c71e0fc102471f9bbc1b46a95aa0b645f2c38e7" + "6450289619ea3f5e8ae61037bffcf8249f22aa4e76e2a01909f3feb290ce" + "93edf57b10ebe796", + 16, + ) + + rsa2040_N = int( + "00bac0652fdfbc0055882ffbaeaceec88fa2d083c297dd5d40664dd3d90f" + "52f9aa02bd8a50fba16e0fd991878ef475f9b350d9f8e3eb2abd717ce327" + "b09788531f13df8e3e4e3b9d616bb8a41e5306eed2472163161051180127" + "6a4eb66f07331b5cbc8bcae7016a8f9b3d4f2ac4553c624cf5263bcb348e" + "8840de6612870960a792191b138fb217f765cec7bff8e94f16b39419bf75" + "04c59a7e4f79bd6d173e9c7bf3d9d2a4e73cc180b0590a73d584fb7fc9b5" + "4fa544607e53fc685c7a55fd44a81d4142b6af51ea6fa6cea52965a2e8c5" + "d84f3ca024d6fbb9b005b9651ce5d9f2ecf40ed404981a9ffc02636e311b" + "095c6332a0c87dc39271b5551481774b", + 16, + ) + rsa2040_E = 65537 + rsa2040_D = int( + "603db267df97555cbed86b8df355034af28f1eb7f3e7829d239bcc273a7c" + "7a69a10be8f21f1b6c4b02c6bae3731c3158b5bbff4605f57ab7b7b2a0cb" + "a2ec005a2db5b1ea6e0aceea5bc745dcd2d0e9d6b80d7eb0ea2bc08127bc" + "e35fa50c42cc411871ba591e23ba6a38484a33eff1347f907ee9a5a92a23" + "11bb0b435510020f78e3bb00099db4d1182928096505fcba84f3ca1238fd" + "1eba5eea1f391bbbcc5424b168063fc17e1ca6e1912ccba44f9d0292308a" + "1fedb80612529b39f59d0a3f8180b5ba201132197f93a5815ded938df8e7" + "d93c9b15766588f339bb59100afda494a7e452d7dd4c9a19ce2ec3a33a18" + "b20f0b4dade172bee19f26f0dcbe41", + 16, + ) + rsa2040_P = int( + "0ec3869cb92d406caddf7a319ab29448bc505a05913707873361fc5b986a" + "499fb65eeb815a7e37687d19f128087289d9bb8818e7bcca502c4900ad9a" + "ece1179be12ff3e467d606fc820ea8f07ac9ebffe2236e38168412028822" + "3e42dbe68dfd972a85a6447e51695f234da7911c67c9ab9531f33df3b994" + "32d4ee88c9a4efbb", + 16, + ) + rsa2040_Q = int( + "0ca63934549e85feac8e0f5604303fd1849fe88af4b7f7e1213283bbc7a2" + "c2a509f9273c428c68de3db93e6145f1b400bd6d4a262614e9043ad362d4" + "eba4a6b995399c8934a399912199e841d8e8dbff0489f69e663796730b29" + "80530b31cb70695a21625ea2adccc09d930516fa872211a91e22dd89fd9e" + "b7da8574b72235b1", + 16, + ) + rsa2040_exp1 = int( + "0d7d3a75e17f65f8a658a485c4095c10a4f66979e2b73bca9cf8ef21253e" + "1facac6d4791f58392ce8656f88f1240cc90c29653e3100c6d7a38ed44b1" + "63b339e5f3b6e38912126c69b3ceff2e5192426d9649b6ffca1abb75d2ba" + "2ed6d9a26aa383c5973d56216ff2edb90ccf887742a0f183ac92c94cf187" + "657645c7772d9ad7", + 16, + ) + rsa2040_exp2 = int( + "03f550194c117f24bea285b209058032f42985ff55acebe88b16df9a3752" + "7b4e61dc91a68dbc9a645134528ce5f248bda2893c96cb7be79ee73996c7" + "c22577f6c2f790406f3472adb3b211b7e94494f32c5c6fcc0978839fe472" + "4c31b06318a2489567b4fca0337acb1b841227aaa5f6c74800a2306929f0" + "2ce038bad943df41", + 16, + ) + rsa2040_coef = int( + "080a7dbfa8c2584814c71664c56eb62ce4caf16afe88d4499159d674774a" + "3a3ecddf1256c02fc91525c527692422d0aba94e5c41ee12dc71bb66f867" + "9fa17e096f28080851ba046eb31885c1414e8985ade599d907af17453d1c" + "caea2c0d06443f8367a6be154b125e390ee0d90f746f08801dd3f5367f59" + "fba2e5a67c05f375", + 16, + ) + + rsa1024_N = int( + "00d3a97440101eba8c5df9503e6f935eb52ffeb3ebe9d0dc5cace26f973c" + "a94cbc0d9c31d66c0c013bce9c82d0d480328df05fb6bcd7990a5312ddae" + "6152ad6ee61c8c1bdd8663c68bd36224a9882ae78e89f556dfdbe6f51da6" + "112cbfc27c8a49336b41afdb75321b52b24a7344d1348e646351a551c757" + "1ccda0b8fe35f61a75", + 16, + ) + rsa1024_E = 65537 + rsa1024_D = int( + "5b6708e185548fc07ff062dba3792363e106ff9177d60ee3227162391024" + "1813f958a318f26db8b6a801646863ebbc69190d6c2f5e7723433e99666d" + "76b3987892cd568f1f18451e8dc05477c0607ee348380ebb7f4c98d0c036" + "a0260bc67b2dab46cbaa4ce87636d839d8fddcbae2da3e02e8009a21225d" + "d7e47aff2f82699d", + 16, + ) + rsa1024_P = int( + "00fcdee570323e8fc399dbfc63d8c1569546fb3cd6886c628668ab1e1d0f" + "ca71058febdf76d702970ad6579d80ac2f9521075e40ef8f3f39983bd819" + "07e898bad3", + 16, + ) + rsa1024_Q = int( + "00d64801c955b4eb75fbae230faa8b28c9cc5e258be63747ff5ac8d2af25" + "3e9f6d6ce03ea2eb13ae0eb32572feb848c32ca00743635374338fedacd8" + "c5885f7897", + 16, + ) + rsa1024_exp1 = int( + "76c0526d5b1b28368a75d5d42a01b9a086e20b9310241e2cd2d0b166a278" + "c694ff1e9d25d9193d47789b52bb0fa194de1af0b77c09007f12afdfeef9" + "58d108c3", + 16, + ) + rsa1024_exp2 = int( + "008a41898d8b14217c4d782cbd15ef95d0a660f45ed09a4884f4e170367b" + "946d2f20398b907896890e88fe17b54bd7febe133ebc7720c86fe0649cca" + "7ca121e05f", + 16, + ) + rsa1024_coef = int( + "22db133445f7442ea2a0f582031ee214ff5f661972986f172651d8d6b4ec" + "3163e99bff1c82fe58ec3d075c6d8f26f277020edb77c3ba821b9ba3ae18" + "ff8cb2cb", + 16, + ) + + rsa1016_N = int( + "00d29bb12fb84fddcd29b3a519cb66c43b8d8f8be545ba79384ce663ed03" + "df75991600eb920790d2530cece544db99a71f05896a3ed207165534aa99" + "057e47c47e3bc81ada6fa1e12e37268b5046a55268f9dad7ccb485d81a2e" + "19d50d4f0b6854acaf6d7be69d9a083136e15afa8f53c1c8c84fc6077279" + "dd0e55d7369a5bdd", + 16, + ) + rsa1016_E = 65537 + rsa1016_D = int( + "3c4965070bf390c251d5a2c5277c5b5fd0bdee85cad7fe2b27982bb28511" + "4a507004036ae1cf8ae54b25e4db39215abd7e903f618c2d8b2f08cc6cd1" + "2dbccd72205e4945b6b3df389e5e43de0a148bb2c84e2431fdbe5920b044" + "bb272f45ecff0721b7dfb60397fc613a9ea35c22300530cae8f9159c534d" + "f3bf0910951901", + 16, + ) + rsa1016_P = int( + "0f9f17597c85b8051b9c69afb55ef576c996dbd09047d0ccde5b9d60ea5c" + "67fe4fac67be803f4b6ac5a3f050f76b966fb14f5cf105761e5ade6dd960" + "b183ba55", + 16, + ) + rsa1016_Q = int( + "0d7b637112ce61a55168c0f9c9386fb279ab40cba0d549336bba65277263" + "aac782611a2c81d9b635cf78c40018859e018c5e9006d12e3d2ee6f346e7" + "9fa43369", + 16, + ) + rsa1016_exp1 = int( + "09fd6c9a3ea6e91ae32070f9fc1c210ff9352f97be5d1eeb951bb39681e9" + "dc5b672a532221b3d8900c9a9d99b9d0a4e102dc450ca1b87b0b1389de65" + "16c0ae0d", + 16, + ) + rsa1016_exp2 = int( + "0141b832491b7dd4a83308920024c79cae64bd447df883bb4c5672a96bab" + "48b7123b34f26324452cdceb17f21e570e347cbe2fd4c2d8f9910eac2cb6" + "d895b8c9", + 16, + ) + rsa1016_coef = int( + "0458dd6aee18c88b2f9b81f1bc3075ae20dc1f9973d20724f20b06043d61" + "47c8789d4a07ae88bc82c8438c893e017b13947f62e0b18958a31eb664b1" + "9e64d3e0", + 16, + ) + + def __init__(self, specification): + if specification == "default": + self.RSA_N = self.sharedRSA_N + self.RSA_E = self.sharedRSA_E + self.RSA_D = self.sharedRSA_D + self.RSA_P = self.sharedRSA_P + self.RSA_Q = self.sharedRSA_Q + self.RSA_exp1 = self.sharedRSA_exp1 + self.RSA_exp2 = self.sharedRSA_exp2 + self.RSA_coef = self.sharedRSA_coef + elif specification == "alternate": + self.RSA_N = self.alternateRSA_N + self.RSA_E = self.alternateRSA_E + self.RSA_D = self.alternateRSA_D + self.RSA_P = self.alternateRSA_P + self.RSA_Q = self.alternateRSA_Q + self.RSA_exp1 = self.alternateRSA_exp1 + self.RSA_exp2 = self.alternateRSA_exp2 + self.RSA_coef = self.alternateRSA_coef + elif specification == "ev": + self.RSA_N = self.evRSA_N + self.RSA_E = self.evRSA_E + self.RSA_D = self.evRSA_D + self.RSA_P = self.evRSA_P + self.RSA_Q = self.evRSA_Q + self.RSA_exp1 = self.evRSA_exp1 + self.RSA_exp2 = self.evRSA_exp2 + self.RSA_coef = self.evRSA_coef + elif specification == "evRSA2040": + self.RSA_N = self.evRSA2040_N + self.RSA_E = self.evRSA2040_E + self.RSA_D = self.evRSA2040_D + self.RSA_P = self.evRSA2040_P + self.RSA_Q = self.evRSA2040_Q + self.RSA_exp1 = self.evRSA2040_exp1 + self.RSA_exp2 = self.evRSA2040_exp2 + self.RSA_coef = self.evRSA2040_coef + elif specification == "rsa2040": + self.RSA_N = self.rsa2040_N + self.RSA_E = self.rsa2040_E + self.RSA_D = self.rsa2040_D + self.RSA_P = self.rsa2040_P + self.RSA_Q = self.rsa2040_Q + self.RSA_exp1 = self.rsa2040_exp1 + self.RSA_exp2 = self.rsa2040_exp2 + self.RSA_coef = self.rsa2040_coef + elif specification == "rsa1024": + self.RSA_N = self.rsa1024_N + self.RSA_E = self.rsa1024_E + self.RSA_D = self.rsa1024_D + self.RSA_P = self.rsa1024_P + self.RSA_Q = self.rsa1024_Q + self.RSA_exp1 = self.rsa1024_exp1 + self.RSA_exp2 = self.rsa1024_exp2 + self.RSA_coef = self.rsa1024_coef + elif specification == "rsa1016": + self.RSA_N = self.rsa1016_N + self.RSA_E = self.rsa1016_E + self.RSA_D = self.rsa1016_D + self.RSA_P = self.rsa1016_P + self.RSA_Q = self.rsa1016_Q + self.RSA_exp1 = self.rsa1016_exp1 + self.RSA_exp2 = self.rsa1016_exp2 + self.RSA_coef = self.rsa1016_coef + else: + raise UnknownKeySpecificationError(specification) + + def toDER(self): + privateKeyInfo = PrivateKeyInfo() + privateKeyInfo["version"] = 0 + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier["algorithm"] = rfc2459.rsaEncryption + # Directly setting parameters to univ.Null doesn't currently work. + nullEncapsulated = encoder.encode(univ.Null()) + algorithmIdentifier["parameters"] = univ.Any(nullEncapsulated) + privateKeyInfo["privateKeyAlgorithm"] = algorithmIdentifier + rsaPrivateKey = RSAPrivateKey() + rsaPrivateKey["version"] = 0 + rsaPrivateKey["modulus"] = self.RSA_N + rsaPrivateKey["publicExponent"] = self.RSA_E + rsaPrivateKey["privateExponent"] = self.RSA_D + rsaPrivateKey["prime1"] = self.RSA_P + rsaPrivateKey["prime2"] = self.RSA_Q + rsaPrivateKey["exponent1"] = self.RSA_exp1 + rsaPrivateKey["exponent2"] = self.RSA_exp2 + rsaPrivateKey["coefficient"] = self.RSA_coef + rsaPrivateKeyEncoded = encoder.encode(rsaPrivateKey) + privateKeyInfo["privateKey"] = univ.OctetString(rsaPrivateKeyEncoded) + return encoder.encode(privateKeyInfo) + + def toPEM(self): + output = "-----BEGIN PRIVATE KEY-----" + der = self.toDER() + b64 = six.ensure_text(base64.b64encode(der)) + while b64: + output += "\n" + b64[:64] + b64 = b64[64:] + output += "\n-----END PRIVATE KEY-----" + return output + + def asSubjectPublicKeyInfo(self): + """Returns a subject public key info representing + this key for use by pyasn1.""" + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier["algorithm"] = rfc2459.rsaEncryption + # Directly setting parameters to univ.Null doesn't currently work. + nullEncapsulated = encoder.encode(univ.Null()) + algorithmIdentifier["parameters"] = univ.Any(nullEncapsulated) + spki = rfc2459.SubjectPublicKeyInfo() + spki["algorithm"] = algorithmIdentifier + rsaKey = RSAPublicKey() + rsaKey["N"] = univ.Integer(self.RSA_N) + rsaKey["E"] = univ.Integer(self.RSA_E) + subjectPublicKey = univ.BitString( + byteStringToHexifiedBitString(encoder.encode(rsaKey)) + ) + spki["subjectPublicKey"] = subjectPublicKey + return spki + + def sign(self, data, hashAlgorithm): + """Returns a hexified bit string representing a + signature by this key over the specified data. + Intended for use with pyasn1.type.univ.BitString""" + hashAlgorithmName = None + if hashAlgorithm == HASH_MD5: + hashAlgorithmName = "MD5" + elif hashAlgorithm == HASH_SHA1: + hashAlgorithmName = "SHA-1" + elif hashAlgorithm == HASH_SHA256: + hashAlgorithmName = "SHA-256" + elif hashAlgorithm == HASH_SHA384: + hashAlgorithmName = "SHA-384" + elif hashAlgorithm == HASH_SHA512: + hashAlgorithmName = "SHA-512" + else: + raise UnknownHashAlgorithmError(hashAlgorithm) + rsaPrivateKey = rsa.PrivateKey( + self.RSA_N, self.RSA_E, self.RSA_D, self.RSA_P, self.RSA_Q + ) + signature = rsa.sign(data, rsaPrivateKey, hashAlgorithmName) + return byteStringToHexifiedBitString(signature) + + +ecPublicKey = univ.ObjectIdentifier("1.2.840.10045.2.1") +secp256k1 = univ.ObjectIdentifier("1.3.132.0.10") +secp224r1 = univ.ObjectIdentifier("1.3.132.0.33") +secp256r1 = univ.ObjectIdentifier("1.2.840.10045.3.1.7") +secp384r1 = univ.ObjectIdentifier("1.3.132.0.34") +secp521r1 = univ.ObjectIdentifier("1.3.132.0.35") + + +def longToEvenLengthHexString(val): + h = format(val, "x") + if not len(h) % 2 == 0: + h = "0" + h + return h + + +class ECCKey(object): + secp256k1KeyPair = ( + "35ee7c7289d8fef7a86afe5da66d8bc2ebb6a8543fd2fead089f45ce7acd0fa6" + + "4382a9500c41dad770ffd4b511bf4b492eb1238800c32c4f76c73a3f3294e7c5", + "67cebc208a5fa3df16ec2bb34acc59a42ab4abb0538575ca99b92b6a2149a04f", + ) + + secp224r1KeyPair = ( + "668d72cca6fd6a1b3557b5366104d84408ecb637f08e8c86bbff82cc" + + "00e88f0066d7af63c3298ba377348a1202b03b37fd6b1ff415aa311e", + "04389459926c3296c242b83e10a6cd2011c8fe2dae1b772ea5b21067", + ) + + secp256r1KeyPair = ( + "4fbfbbbb61e0f8f9b1a60a59ac8704e2ec050b423e3cf72e923f2c4f794b455c" + + "2a69d233456c36c4119d0706e00eedc8d19390d7991b7b2d07a304eaa04aa6c0", + "2191403d5710bf15a265818cd42ed6fedf09add92d78b18e7a1e9feb95524702", + ) + + secp384r1KeyPair = ( + "a1687243362b5c7b1889f379154615a1c73fb48dee863e022915db608e252de4b71" + + "32da8ce98e831534e6a9c0c0b09c8d639ade83206e5ba813473a11fa330e05da8c9" + + "6e4383fe27873da97103be2888cff002f05af71a1fddcc8374aa6ea9ce", + "035c7a1b10d9fafe837b64ad92f22f5ced0789186538669b5c6d872cec3d926122b" + + "393772b57602ff31365efe1393246", + ) + + secp521r1KeyPair = ( + "014cdc9cacc47941096bc9cc66752ec27f597734fa66c62b792f88c519d6d37f0d1" + + "6ea1c483a1827a010b9128e3a08070ca33ef5f57835b7c1ba251f6cc3521dc42b01" + + "0653451981b445d343eed3782a35d6cff0ff484f5a883d209f1b9042b726703568b" + + "2f326e18b833bdd8aa0734392bcd19501e10d698a79f53e11e0a22bdd2aad90", + "014f3284fa698dd9fe1118dd331851cdfaac5a3829278eb8994839de9471c940b85" + + "8c69d2d05e8c01788a7d0b6e235aa5e783fc1bee807dcc3865f920e12cf8f2d29", + ) + + def __init__(self, specification): + if specification == "secp256k1": + key_pair = self.secp256k1KeyPair + self.keyOID = secp256k1 + self.curve = ecdsa.SECP256k1 + elif specification == "secp224r1": + key_pair = self.secp224r1KeyPair + self.keyOID = secp224r1 + self.curve = ecdsa.NIST224p + elif specification == "secp256r1": + key_pair = self.secp256r1KeyPair + self.keyOID = secp256r1 + self.curve = ecdsa.NIST256p + elif specification == "secp384r1": + key_pair = self.secp384r1KeyPair + self.keyOID = secp384r1 + self.curve = ecdsa.NIST384p + elif specification == "secp521r1": + key_pair = self.secp521r1KeyPair + self.keyOID = secp521r1 + self.curve = ecdsa.NIST521p + else: + raise UnknownKeySpecificationError(specification) + + self.public_key, self.private_key = ( + binascii.unhexlify(key_pair[0]), + binascii.unhexlify(key_pair[1]), + ) + self.key = ecdsa.SigningKey.from_string(self.private_key, curve=self.curve) + + def getPublicKeyHexifiedString(self): + """Returns the EC public key as a hex string using the uncompressed + point representation. This is intended to be used in the encoder + functions, as it surrounds the value with ''H to indicate its type.""" + p1, p2 = ( + self.public_key[: len(self.public_key) // 2], + self.public_key[len(self.public_key) // 2 :], + ) + # We don't want leading zeroes. + p1, p2 = (p1.lstrip(b"\0"), p2.lstrip(b"\0")) + # '04' indicates that the points are in uncompressed form. + return byteStringToHexifiedBitString(b"\04" + p1 + p2) + + def toPEM(self): + """Return the EC private key in PEM-encoded form.""" + output = "-----BEGIN EC PRIVATE KEY-----" + der = self.toDER() + b64 = six.ensure_text(base64.b64encode(der)) + while b64: + output += "\n" + b64[:64] + b64 = b64[64:] + output += "\n-----END EC PRIVATE KEY-----" + return output + + def toDER(self): + """Return the EC private key in DER-encoded form, encoded per SEC 1 + section C.4 format.""" + privateKeyInfo = PrivateKeyInfo() + privateKeyInfo["version"] = 0 + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier["algorithm"] = ecPublicKey + algorithmIdentifier["parameters"] = self.keyOID + privateKeyInfo["privateKeyAlgorithm"] = algorithmIdentifier + ecPrivateKey = ECPrivateKey() + ecPrivateKey["version"] = 1 + ecPrivateKey["privateKey"] = self.private_key + ecPrivateKey["publicKey"] = univ.BitString( + self.getPublicKeyHexifiedString() + ).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)) + ecPrivateKeyEncoded = encoder.encode(ecPrivateKey) + privateKeyInfo["privateKey"] = univ.OctetString(ecPrivateKeyEncoded) + return encoder.encode(privateKeyInfo) + + def asSubjectPublicKeyInfo(self): + """Returns a subject public key info representing + this key for use by pyasn1.""" + algorithmIdentifier = rfc2459.AlgorithmIdentifier() + algorithmIdentifier["algorithm"] = ecPublicKey + algorithmIdentifier["parameters"] = self.keyOID + spki = rfc2459.SubjectPublicKeyInfo() + spki["algorithm"] = algorithmIdentifier + spki["subjectPublicKey"] = univ.BitString(self.getPublicKeyHexifiedString()) + return spki + + def signRaw(self, data, hashAlgorithm): + """Performs the ECDSA signature algorithm over the given data. + The returned value is a string representing the bytes of the + resulting point when encoded by left-padding each of (r, s) to + the key size and concatenating them. + """ + assert hashAlgorithm.startswith("hash:") + hashAlgorithm = hashAlgorithm[len("hash:") :] + k = _gen_k(self.curve) + digest = hashlib.new(hashAlgorithm, six.ensure_binary(data)).digest() + digest = _truncate_digest(digest, self.curve) + # NOTE: Under normal circumstances it's advisable to use + # sign_digest_deterministic. In this case we don't want the library's + # default generation of k, so we call the normal "sign" method and + # inject it here. + return self.key.sign_digest(digest, sigencode=ecdsa.util.sigencode_string, k=k) + + def sign(self, data, hashAlgorithm): + """Returns a hexified bit string representing a + signature by this key over the specified data. + Intended for use with pyasn1.type.univ.BitString""" + # signRaw returns an encoded point, which is useful in some situations. + # However, for signatures on X509 certificates, we need to decode it so + # we can encode it as a BITSTRING consisting of a SEQUENCE of two + # INTEGERs. + raw = self.signRaw(data, hashAlgorithm) + point = ECPoint() + point["x"] = int.from_bytes(raw[: len(raw) // 2], byteorder="big") + point["y"] = int.from_bytes(raw[len(raw) // 2 :], byteorder="big") + return byteStringToHexifiedBitString(encoder.encode(point)) + + +def keyFromSpecification(specification): + """Pass in a specification, get the appropriate key back.""" + if specification.startswith("secp"): + return ECCKey(specification) + return RSAKey(specification) + + +# The build harness will call this function with an output file-like +# object and a path to a file containing a specification. This will +# read the specification and output the key as ASCII-encoded PKCS #8. + + +def main(output, inputPath): + with open(inputPath) as configStream: + output.write(keyFromSpecification(configStream.read().strip()).toPEM() + "\n") + + +# When run as a standalone program, this will read a specification from +# stdin and output the certificate as PEM to stdout. +if __name__ == "__main__": + print(keyFromSpecification(sys.stdin.read().strip()).toPEM()) diff --git a/security/manager/ssl/tests/unit/requirements.txt b/security/manager/ssl/tests/unit/requirements.txt new file mode 100644 index 0000000000..095fcb04fc --- /dev/null +++ b/security/manager/ssl/tests/unit/requirements.txt @@ -0,0 +1,6 @@ +lxml +pyasn1 == 0.3.7 +pyasn1_modules == 0.1.5 +ecc +mock +rsa diff --git a/security/manager/ssl/tests/unit/sign_app.py b/security/manager/ssl/tests/unit/sign_app.py new file mode 100755 index 0000000000..8c90376581 --- /dev/null +++ b/security/manager/ssl/tests/unit/sign_app.py @@ -0,0 +1,399 @@ +#!/usr/bin/env python3 +# +# 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/. + +""" +Given a directory of files, packages them up and signs the +resulting zip file. Mainly for creating test inputs to the +nsIX509CertDB.openSignedAppFileAsync API. +""" +from base64 import b64encode +from cbor2 import dumps +from cbor2.types import CBORTag +from hashlib import sha1, sha256 +import argparse +from io import StringIO +import os +import pycert +import pycms +import pykey +import re +import six +import zipfile + + +ES256 = -7 +ES384 = -35 +ES512 = -36 +KID = 4 +ALG = 1 +COSE_Sign = 98 + + +def coseAlgorithmToPykeyHash(algorithm): + """Helper function that takes one of (ES256, ES384, ES512) + and returns the corresponding pykey.HASH_* identifier.""" + if algorithm == ES256: + return pykey.HASH_SHA256 + if algorithm == ES384: + return pykey.HASH_SHA384 + if algorithm == ES512: + return pykey.HASH_SHA512 + raise UnknownCOSEAlgorithmError(algorithm) + + +# COSE_Signature = [ +# protected : serialized_map, +# unprotected : {}, +# signature : bstr +# ] + + +def coseSignature(payload, algorithm, signingKey, signingCertificate, bodyProtected): + """Returns a COSE_Signature structure. + payload is a string representing the data to be signed + algorithm is one of (ES256, ES384, ES512) + signingKey is a pykey.ECKey to sign the data with + signingCertificate is a byte string + bodyProtected is the serialized byte string of the protected body header + """ + protected = {ALG: algorithm, KID: signingCertificate} + protectedEncoded = dumps(protected) + # Sig_structure = [ + # context : "Signature" + # body_protected : bodyProtected + # sign_protected : protectedEncoded + # external_aad : nil + # payload : bstr + # ] + sigStructure = [u"Signature", bodyProtected, protectedEncoded, None, payload] + sigStructureEncoded = dumps(sigStructure) + pykeyHash = coseAlgorithmToPykeyHash(algorithm) + signature = signingKey.signRaw(sigStructureEncoded, pykeyHash) + return [protectedEncoded, {}, signature] + + +# COSE_Sign = [ +# protected : serialized_map, +# unprotected : {}, +# payload : nil, +# signatures : [+ COSE_Signature] +# ] + + +def coseSig(payload, intermediates, signatures): + """Returns the entire (tagged) COSE_Sign structure. + payload is a string representing the data to be signed + intermediates is an array of byte strings + signatures is an array of (algorithm, signingKey, + signingCertificate) triplets to be passed to + coseSignature + """ + protected = {KID: intermediates} + protectedEncoded = dumps(protected) + coseSignatures = [] + for (algorithm, signingKey, signingCertificate) in signatures: + coseSignatures.append( + coseSignature( + payload, algorithm, signingKey, signingCertificate, protectedEncoded + ) + ) + tagged = CBORTag(COSE_Sign, [protectedEncoded, {}, None, coseSignatures]) + return dumps(tagged) + + +def walkDirectory(directory): + """Given a relative path to a directory, enumerates the + files in the tree rooted at that location. Returns a list + of pairs of paths to those files. The first in each pair + is the full path to the file. The second in each pair is + the path to the file relative to the directory itself.""" + paths = [] + for path, _dirs, files in os.walk(directory): + for f in files: + fullPath = os.path.join(path, f) + internalPath = re.sub(r"^/", "", fullPath.replace(directory, "")) + paths.append((fullPath, internalPath)) + return paths + + +def addManifestEntry(filename, hashes, contents, entries): + """Helper function to fill out a manifest entry. + Takes the filename, a list of (hash function, hash function name) + pairs to use, the contents of the file, and the current list + of manifest entries.""" + entry = "Name: %s\n" % filename + for (hashFunc, name) in hashes: + base64hash = b64encode(hashFunc(contents).digest()).decode("ascii") + entry += "%s-Digest: %s\n" % (name, base64hash) + entries.append(entry) + + +def getCert(subject, keyName, issuerName, ee, issuerKey=""): + """Helper function to create an X509 cert from a specification. + Takes the subject, the subject key name to use, the issuer name, + a bool whether this is an EE cert or not, and optionally an issuer key + name.""" + certSpecification = ( + "issuer:%s\n" % issuerName + + "subject:" + + subject + + "\n" + + "subjectKey:%s\n" % keyName + ) + if ee: + certSpecification += "extension:keyUsage:digitalSignature" + else: + certSpecification += ( + "extension:basicConstraints:cA,\n" + + "extension:keyUsage:cRLSign,keyCertSign" + ) + if issuerKey: + certSpecification += "\nissuerKey:%s" % issuerKey + certSpecificationStream = StringIO() + print(certSpecification, file=certSpecificationStream) + certSpecificationStream.seek(0) + return pycert.Certificate(certSpecificationStream) + + +def coseAlgorithmToSignatureParams(coseAlgorithm, issuerName): + """Given a COSE algorithm ('ES256', 'ES384', 'ES512') and an issuer + name, returns a (algorithm id, pykey.ECCKey, encoded certificate) + triplet for use with coseSig. + """ + if coseAlgorithm == "ES256": + keyName = "secp256r1" + algId = ES256 + elif coseAlgorithm == "ES384": + keyName = "secp384r1" + algId = ES384 + elif coseAlgorithm == "ES512": + keyName = "secp521r1" # COSE uses the hash algorithm; this is the curve + algId = ES512 + else: + raise UnknownCOSEAlgorithmError(coseAlgorithm) + key = pykey.ECCKey(keyName) + # The subject must differ to avoid errors when importing into NSS later. + ee = getCert( + "xpcshell signed app test signer " + keyName, + keyName, + issuerName, + True, + "default", + ) + return (algId, key, ee.toDER()) + + +def signZip( + appDirectory, + outputFile, + issuerName, + rootName, + manifestHashes, + signatureHashes, + pkcs7Hashes, + coseAlgorithms, + emptySignerInfos, + headerPaddingFactor, +): + """Given a directory containing the files to package up, + an output filename to write to, the name of the issuer of + the signing certificate, the name of trust anchor, a list of hash algorithms + to use in the manifest file, a similar list for the signature file, + a similar list for the pkcs#7 signature, a list of COSE signature algorithms + to include, whether the pkcs#7 signer info should be kept empty, and how + many MB to pad the manifests by (to test handling large manifest files), + packages up the files in the directory and creates the output as + appropriate.""" + # The header of each manifest starts with the magic string + # 'Manifest-Version: 1.0' and ends with a blank line. There can be + # essentially anything after the first line before the blank line. + mfEntries = ["Manifest-Version: 1.0"] + if headerPaddingFactor > 0: + # In this format, each line can only be 72 bytes long. We make + # our padding 50 bytes per line (49 of content and one newline) + # so the math is easy. + singleLinePadding = "a" * 49 + # 1000000 / 50 = 20000 + allPadding = [singleLinePadding] * (headerPaddingFactor * 20000) + mfEntries.extend(allPadding) + # Append the blank line. + mfEntries.append("") + + with zipfile.ZipFile(outputFile, "w", zipfile.ZIP_DEFLATED) as outZip: + for (fullPath, internalPath) in walkDirectory(appDirectory): + with open(fullPath, "rb") as inputFile: + contents = inputFile.read() + outZip.writestr(internalPath, contents) + + # Add the entry to the manifest we're building + addManifestEntry(internalPath, manifestHashes, contents, mfEntries) + + if len(coseAlgorithms) > 0: + coseManifest = "\n".join(mfEntries) + outZip.writestr("META-INF/cose.manifest", coseManifest) + coseManifest = six.ensure_binary(coseManifest) + addManifestEntry( + "META-INF/cose.manifest", manifestHashes, coseManifest, mfEntries + ) + intermediates = [] + coseIssuerName = issuerName + if rootName: + coseIssuerName = "xpcshell signed app test issuer" + intermediate = getCert(coseIssuerName, "default", rootName, False) + intermediate = intermediate.toDER() + intermediates.append(intermediate) + signatures = [ + coseAlgorithmToSignatureParams(coseAlgorithm, coseIssuerName) + for coseAlgorithm in coseAlgorithms + ] + coseSignatureBytes = coseSig(coseManifest, intermediates, signatures) + outZip.writestr("META-INF/cose.sig", coseSignatureBytes) + addManifestEntry( + "META-INF/cose.sig", manifestHashes, coseSignatureBytes, mfEntries + ) + + if len(pkcs7Hashes) != 0 or emptySignerInfos: + mfContents = "\n".join(mfEntries) + sfContents = "Signature-Version: 1.0\n" + for (hashFunc, name) in signatureHashes: + hashed = hashFunc(six.ensure_binary(mfContents)).digest() + base64hash = b64encode(hashed).decode("ascii") + sfContents += "%s-Digest-Manifest: %s\n" % (name, base64hash) + + cmsSpecification = "" + for name in pkcs7Hashes: + hashFunc, _ = hashNameToFunctionAndIdentifier(name) + cmsSpecification += "%s:%s\n" % ( + name, + hashFunc(six.ensure_binary(sfContents)).hexdigest(), + ) + cmsSpecification += ( + "signer:\n" + + "issuer:%s\n" % issuerName + + "subject:xpcshell signed app test signer\n" + + "extension:keyUsage:digitalSignature" + ) + cmsSpecificationStream = StringIO() + print(cmsSpecification, file=cmsSpecificationStream) + cmsSpecificationStream.seek(0) + cms = pycms.CMS(cmsSpecificationStream) + p7 = cms.toDER() + outZip.writestr("META-INF/A.RSA", p7) + outZip.writestr("META-INF/A.SF", sfContents) + outZip.writestr("META-INF/MANIFEST.MF", mfContents) + + +class Error(Exception): + """Base class for exceptions in this module.""" + + pass + + +class UnknownHashAlgorithmError(Error): + """Helper exception type to handle unknown hash algorithms.""" + + def __init__(self, name): + super(UnknownHashAlgorithmError, self).__init__() + self.name = name + + def __str__(self): + return "Unknown hash algorithm %s" % repr(self.name) + + +class UnknownCOSEAlgorithmError(Error): + """Helper exception type to handle unknown COSE algorithms.""" + + def __init__(self, name): + super(UnknownCOSEAlgorithmError, self).__init__() + self.name = name + + def __str__(self): + return "Unknown COSE algorithm %s" % repr(self.name) + + +def hashNameToFunctionAndIdentifier(name): + if name == "sha1": + return (sha1, "SHA1") + if name == "sha256": + return (sha256, "SHA256") + raise UnknownHashAlgorithmError(name) + + +def main(outputFile, appPath, *args): + """Main entrypoint. Given an already-opened file-like + object, a path to the app directory to sign, and some + optional arguments, signs the contents of the directory and + writes the resulting package to the 'file'.""" + parser = argparse.ArgumentParser(description="Sign an app.") + parser.add_argument( + "-i", + "--issuer", + action="store", + help="Issuer name", + default="xpcshell signed apps test root", + ) + parser.add_argument("-r", "--root", action="store", help="Root name", default="") + parser.add_argument( + "-m", + "--manifest-hash", + action="append", + help="Hash algorithms to use in manifest", + default=[], + ) + parser.add_argument( + "-s", + "--signature-hash", + action="append", + help="Hash algorithms to use in signature file", + default=[], + ) + parser.add_argument( + "-c", + "--cose-sign", + action="append", + help="Append a COSE signature with the given " + + "algorithms (out of ES256, ES384, and ES512)", + default=[], + ) + parser.add_argument( + "-z", + "--pad-headers", + action="store", + default=0, + help="Pad the header sections of the manifests " + + "with X MB of repetitive data", + ) + group = parser.add_mutually_exclusive_group() + group.add_argument( + "-p", + "--pkcs7-hash", + action="append", + help="Hash algorithms to use in PKCS#7 signature", + default=[], + ) + group.add_argument( + "-e", + "--empty-signerInfos", + action="store_true", + help="Emit pkcs#7 SignedData with empty signerInfos", + ) + parsed = parser.parse_args(args) + if len(parsed.manifest_hash) == 0: + parsed.manifest_hash.append("sha256") + if len(parsed.signature_hash) == 0: + parsed.signature_hash.append("sha256") + signZip( + appPath, + outputFile, + parsed.issuer, + parsed.root, + [hashNameToFunctionAndIdentifier(h) for h in parsed.manifest_hash], + [hashNameToFunctionAndIdentifier(h) for h in parsed.signature_hash], + parsed.pkcs7_hash, + parsed.cose_sign, + parsed.empty_signerInfos, + int(parsed.pad_headers), + ) diff --git a/security/manager/ssl/tests/unit/sss_readstate_child_worker.js b/security/manager/ssl/tests/unit/sss_readstate_child_worker.js new file mode 100644 index 0000000000..851a4e26ce --- /dev/null +++ b/security/manager/ssl/tests/unit/sss_readstate_child_worker.js @@ -0,0 +1,66 @@ +/* import-globals-from head_psm.js */ +"use strict"; + +function run_test() { + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + + ok( + !SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://expired.example.com"), + 0 + ) + ); + ok( + SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://notexpired.example.com"), + 0 + ) + ); + ok( + SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + !SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://incsubdomain.example.com"), + 0 + ) + ); + ok( + SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.incsubdomain.example.com"), + 0 + ) + ); + ok( + !SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains2.preloaded.test"), + 0 + ) + ); + ok( + !SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains2.preloaded.test"), + 0 + ) + ); + do_test_finished(); +} diff --git a/security/manager/ssl/tests/unit/test_add_preexisting_cert.js b/security/manager/ssl/tests/unit/test_add_preexisting_cert.js new file mode 100644 index 0000000000..1f1a7825f2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_add_preexisting_cert.js @@ -0,0 +1,46 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +"use strict"; + +// Tests that adding a certificate already present in the certificate database +// with different trust bits than those stored in the database does not result +// in the new trust bits being ignored. + +do_get_profile(); +var certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function load_cert(cert, trust) { + let file = "test_intermediate_basic_usage_constraints/" + cert + ".pem"; + return addCertFromFile(certDB, file, trust); +} + +add_task(async function() { + load_cert("ca", "CTu,CTu,CTu"); + let int_cert = load_cert("int-limited-depth", "CTu,CTu,CTu"); + let file = + "test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem"; + let cert_pem = readFile(do_get_file(file)); + let ee = certDB.constructX509FromBase64(pemToBase64(cert_pem)); + await checkCertErrorGeneric( + certDB, + ee, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + // Change the already existing intermediate certificate's trust using + // addCertFromBase64(). + notEqual(int_cert, null, "Intermediate cert should be in the cert DB"); + let base64_cert = int_cert.getBase64DERString(); + let returnedEE = certDB.addCertFromBase64(base64_cert, "p,p,p"); + notEqual(returnedEE, null, "addCertFromBase64 should return a certificate"); + await checkCertErrorGeneric( + certDB, + ee, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageSSLServer + ); +}); diff --git a/security/manager/ssl/tests/unit/test_allow_all_cert_errors.js b/security/manager/ssl/tests/unit/test_allow_all_cert_errors.js new file mode 100644 index 0000000000..e9f1b6c9db --- /dev/null +++ b/security/manager/ssl/tests/unit/test_allow_all_cert_errors.js @@ -0,0 +1,25 @@ +/* -*- tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ +"use strict"; + +function run_test() { + do_get_profile(); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData( + true + ); + + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + add_connection_test("expired.example.com", PRErrorCodeSuccess); + add_test(function() { + certOverrideService.setDisableAllSecurityChecksAndLetAttackersInterceptMyData( + false + ); + run_next_test(); + }); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem new file mode 100644 index 0000000000..161ce88377 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUXwklABFZn09Yj1azSdQ4kpuizxYwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCdpP06UqpAnAAak/i4+LShrIG/ +DdjHLQ8qLChBdPkT6Gxx1XVoNfG3GJsIGCoOf6isORMfBlBXiR5kmLFTE3kJhA/I +pDxDGYDqt9DNb0fxeMpOJxwQ+mBMZIKLPu+nk4jTqUrOX8bLwDMiXTbFeY91SUr8 +4b43YzXVorVQSlYOfcsmrnEfmfJNauHBrzak5BQhsEXHqAI7qV9TCQA1+cGwH8jb +Aw2SyVu1usAyHkM2wCisHXeidf3qR6PxmfLMAgHKXBLz3DsXY30xDI4jJS9MySu9 +lhrs1IJf5PdJk5z5viYqZQemuv0R+R7ItbpCHpreUXh2GutiAY4Xsgrhfcer +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem.certspec new file mode 100644 index 0000000000..9c21e7adcf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:ca +validity:20100101-20500101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/moz.build b/security/manager/ssl/tests/unit/test_baseline_requirements/moz.build new file mode 100644 index 0000000000..df0cef67d6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/moz.build @@ -0,0 +1,19 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'no-san-old.pem', +# 'no-san-older.pem', +# 'no-san-recent.pem', +# 'san-contains-no-hostnames-old.pem', +# 'san-contains-no-hostnames-older.pem', +# 'san-contains-no-hostnames-recent.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem new file mode 100644 index 0000000000..a13b0cbcd1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUS00fexo4Y4FagP1oiKQiGCJKd/swDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAGjMx1NAs2guKp3wRRAWdiAw9NCeX+qCsxxkr4jUdgQ14wZwU2fZ/2rK +7Z/StpwlWN+G4dWwCRCjibKvjauQs+XLT9wMO3U/1VBcQda36duX70ss2SAF9crs +dmZdISevFItTn+W6JNyr1Wt2sSiD4buXpW1UzNwuxnWGpo/a++bMEYaM8KDdz73t +KA9VShYNbcrUZgf70bvCbc8BR3vYUwyIp3fP7TngD/dRLYJyv5ayo9VXVJxOzYU7 +/aRrBvAdAL2w8eQzzYm6uyHlOE+imWYix2QOGNFJIiRXFRTii9Rr0o4geW7x2wZJ ++TzO4XPVlax1h6KDPRLsmwhbJDAMuUU= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem.certspec new file mode 100644 index 0000000000..7a34d0758f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-old.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:example.com +validity:20160724-20160924 diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem new file mode 100644 index 0000000000..f2bb8c97d9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUZ3gdKZRvWFYArMRStT2zAGE6JDQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNTA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBABERZmWOEZAI2dQHbpXo7BJFw8eigDs8xWGtnu5UbNFs7zGnXzta0L8T +RBoaWeEbsaVpuGQ648eorgQRGwNdL3JkJb0qHtaSl5/raAOvv+YqmGzZhFWcj3ib +WUOWODdFlY3oUzpPjA+IeRzULya6//s8DhEKfVi2mJXc/sS6fE9J234IhKBysyr1 +cRIApw6OCr0V78TbHzEPh1z0QuMKY8hH0lz3JvQqGD59oTEdSJ5VVbmDLxqqmVtA +/i4j2lYkDos2HvHGP7a/LC20FI0lOcSqazSeKc+y2Mand9tDXCU/dEEYMj1IW5rM +z2+96XzCbJBesYFEEfWXG6XysP3UtE0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem.certspec new file mode 100644 index 0000000000..aa682a7afd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-older.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:example.com +validity:20150724-20160924 diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem new file mode 100644 index 0000000000..7ac56a0689 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUWxGwhSb8roUQoLNpJajl0X8jk10wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA4MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAKxEoWUrHht8zENUlC/3tj/KbDSeaIy5nVE49aJRqHwuSczG5PTDn7sD +rjl6Qq2rx3Z3ftZxJNIdpS3BUeUJ+FsQ2fK3ckDyeWkzxADlWp2l2bgKDtnW5Xjw +lfzFt1Z/4PUmz0JyNGqijvpT/YYM9uM5OOKmKvy6C/6HiIMI2f5pVHM2bFWLuHLI +p9yqp056EKPWCEQbkqseXLS0O8ZyxAyW4kHezUQzn1KFq9IGZu5sBZ8Imop0xnal +2wXCuEisuAIOQNb1l9t+hf/P53+oRLjPbJzuzLZGSNA5PzoTbmZOqOdJS+kCNGCX +IahLlU3dPILDlvl8DLFhk+lz9mA8x90= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem.certspec new file mode 100644 index 0000000000..e38478165c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/no-san-recent.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:example.com +validity:20160824-20160924 diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem new file mode 100644 index 0000000000..ba11dcc152 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIUOWkKeR6blD0zzhElEnCm4eSqLTAwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjMDAuMCwGA1UdEQQl +MCOkITAfMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjANBgkqhkiG9w0B +AQsFAAOCAQEACPZ4Ed3iONrIIKtg3865taT5TUj4Ts3tnYn4riFqojr6h/CHEDPR +LStAJ4yYGQoTTzQzaxYjEZXHIEI/bCZ1VpGNpZt8DXWsJWwJgt8QUNeYT0eFFE2M +CjrLJC1OIQRvlR89WEbk/q45KBQC0faeizqkAn+YUSG8mjHHbmSO8PWbh4z0YYlg +BjwhTRFWUmWfQKC+mHyWblbYyFKlsFWf6cGOd4qE8N/hIz7oPzI4IPN1EQ/IfaQy +WOOyxPZeu+J5VPlPE10nV5afoRcPLh/6vTwH85tPGzxWU4Jo4NDtFOtZAZR/S7sO +OB/ST8Dbvs7qQFfRtgCtpEMicG7kxO1F+Q== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem.certspec new file mode 100644 index 0000000000..41817bde75 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-old.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:example.com +validity:20160724-20160924 +extension:subjectAlternativeName:/O=Example Organization diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem new file mode 100644 index 0000000000..6882ba0554 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIUG1q3+RCKIizPHadkamCYLL7cp2swDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNTA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjMDAuMCwGA1UdEQQl +MCOkITAfMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjANBgkqhkiG9w0B +AQsFAAOCAQEAqa/ayP8zXODUJJmuZLTJsdT2VaqbOh2WWk2bC2A82feGvCevLuL0 +0gPk+001Zx49Y1erMmt2M1cKtf2Lob8SGLNGUlJf2K7SNJTk7nyog+4UIlK4Hsxo +CQ9sqKGJjkwHTDK1rB9gSW4e27Taj6tudnsUfgKWVzERxipebtLsCvz8Jfa0YLRI +bGr6L4LoWiN2RNiK7/IOycfJ8VLDlBRouHD2Xfu0pFcvymMvfOC7GG4oBAacCKGn +muUfoODgKw2yCIOSe7jsJOQ9yOp03sRipISfO0TALFzJX0V5+7CYDLZYR8vs/F/4 +0cIqkhwyCfUWYsGI4gPPR/nVxNvTRZhiFw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem.certspec new file mode 100644 index 0000000000..65acf0b024 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-older.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:example.com +validity:20150724-20160924 +extension:subjectAlternativeName:/O=Example Organization diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem new file mode 100644 index 0000000000..cd87acfe48 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIUD1kNqQ0aKQ2TJjGUYztUh8I7j4AwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA4MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowFjEUMBIGA1UEAwwLZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjMDAuMCwGA1UdEQQl +MCOkITAfMR0wGwYDVQQKDBRFeGFtcGxlIE9yZ2FuaXphdGlvbjANBgkqhkiG9w0B +AQsFAAOCAQEAU9n5I/Hdfod2fPBYWHZA/5/SabHkOBUHfrg6UUQYeHagVbqmoTQD +M5F/DcDna+w6nHagIC/GRHBHkgY3Syh8QK5LnL3zi5tC0u4dzysDUjWtEAEgIcWA +/pYtp6qZwJzxvn68PTnYnFDL61+LDLxlUBa2iRieRkCUOokCLL4ce3jsSTuJ+mGk +XoaRrRREgtG5loYK8hFXM1RDkzyCa82DF/qD+iYgUJS9LMXrsksIRHP7Lqzhnwba +Q4N8rgsBDFkNTEAmGcnTLMTlfO+SyKdHZI4n9VHdUQ1n38qFn70jj1YjcqEOFKXb +wldSrYMedEOFVWyXaVWmxMwMTiDIKWMoxg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem.certspec b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem.certspec new file mode 100644 index 0000000000..140c201434 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements/san-contains-no-hostnames-recent.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:example.com +validity:20160824-20160924 +extension:subjectAlternativeName:/O=Example Organization diff --git a/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js b/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js new file mode 100644 index 0000000000..56de79ae7c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_baseline_requirements_subject_common_name.js @@ -0,0 +1,295 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +// The preference security.pki.name_matching_mode controls whether or not +// mozilla::pkix will fall back to using a certificate's subject common name +// during name matching. If the Baseline Requirements are followed, fallback +// should not be necessary (because any name information in the subject common +// name should be present in the subject alternative name extension). Due to +// compatibility concerns, the platform can be configured to fall back for +// certificates that are valid before 23 August 2016. Note that for certificates +// issued by an imported root, the platform will fall back if necessary, +// regardless of the value of the preference. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function certFromFile(certName) { + return constructCertFromFile(`test_baseline_requirements/${certName}.pem`); +} + +function loadCertWithTrust(certName, trustString) { + addCertFromFile( + gCertDB, + `test_baseline_requirements/${certName}.pem`, + trustString + ); +} + +function checkCertOn25August2016(cert, expectedResult) { + // (new Date("2016-08-25T00:00:00Z")).getTime() / 1000 + const VALIDATION_TIME = 1472083200; + return checkCertErrorGenericAtTime( + gCertDB, + cert, + expectedResult, + certificateUsageSSLServer, + VALIDATION_TIME, + false, + "example.com" + ); +} + +add_task(async function() { + registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.pki.name_matching_mode"); + Services.prefs.clearUserPref("security.test.built_in_root_hash"); + Services.prefs.clearUserPref("privacy.reduceTimerPrecision"); + }); + + Services.prefs.setBoolPref("privacy.reduceTimerPrecision", false); + + loadCertWithTrust("ca", "CTu,,"); + + // When verifying a certificate, if the trust anchor is not a built-in root, + // name matching will fall back to using the subject common name if necessary + // (i.e. if there is no subject alternative name extension or it does not + // contain any dNSName or iPAddress entries). Thus, since imported roots are + // not in general treated as built-ins, these should all successfully verify + // regardless of the value of the pref. + Services.prefs.setIntPref("security.pki.name_matching_mode", 0); + info("current mode: always fall back, root not built-in"); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + Services.prefs.setIntPref("security.pki.name_matching_mode", 1); + info( + "current mode: fall back for notBefore < August 23, 2016, root " + + "not built-in" + ); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + Services.prefs.setIntPref("security.pki.name_matching_mode", 2); + info( + "current mode: fall back for notBefore < August 23, 2015, root " + + "not built-in" + ); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + Services.prefs.setIntPref("security.pki.name_matching_mode", 3); + info("current mode: never fall back, root not built-in"); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016(certFromFile("no-san-old"), PRErrorCodeSuccess); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + // In debug builds, we can treat an imported root as a built-in, and thus we + // can actually test the different values of the pref. + if (isDebugBuild) { + let root = certFromFile("ca"); + Services.prefs.setCharPref( + "security.test.built_in_root_hash", + root.sha256Fingerprint + ); + + // Always fall back if necessary. + Services.prefs.setIntPref("security.pki.name_matching_mode", 0); + info("current mode: always fall back, root built-in"); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("no-san-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + // Only fall back if notBefore < 23 August 2016 + Services.prefs.setIntPref("security.pki.name_matching_mode", 1); + info( + "current mode: fall back for notBefore < August 23, 2016, root " + + "built-in" + ); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + // Only fall back if notBefore < 23 August 2015 + Services.prefs.setIntPref("security.pki.name_matching_mode", 2); + info( + "current mode: fall back for notBefore < August 23, 2015, root " + + "built-in" + ); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-old"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-older"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + PRErrorCodeSuccess + ); + + // Never fall back. + Services.prefs.setIntPref("security.pki.name_matching_mode", 3); + info("current mode: never fall back, root built-in"); + await checkCertOn25August2016( + certFromFile("no-san-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-old"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("no-san-older"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-recent"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-old"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + await checkCertOn25August2016( + certFromFile("san-contains-no-hostnames-older"), + SSL_ERROR_BAD_CERT_DOMAIN + ); + } +}); diff --git a/security/manager/ssl/tests/unit/test_blocklist_onecrl.js b/security/manager/ssl/tests/unit/test_blocklist_onecrl.js new file mode 100644 index 0000000000..388816417a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_blocklist_onecrl.js @@ -0,0 +1,75 @@ +"use strict"; + +do_get_profile(); + +const { Utils } = ChromeUtils.import("resource://services-settings/Utils.jsm"); +const { RemoteSettings } = ChromeUtils.import( + "resource://services-settings/remote-settings.js" +); +const { RemoteSecuritySettings } = ChromeUtils.import( + "resource://gre/modules/psm/RemoteSecuritySettings.jsm" +); +const { OneCRLBlocklistClient } = RemoteSecuritySettings.init(); + +const global = this; + +add_task(async function test_uses_a_custom_signer() { + Assert.notEqual( + OneCRLBlocklistClient.signerName, + RemoteSettings("not-specified").signerName + ); +}); + +add_task(async function test_has_initial_dump() { + Assert.ok( + await Utils.hasLocalDump( + OneCRLBlocklistClient.bucketName, + OneCRLBlocklistClient.collectionName + ) + ); +}); + +add_task(async function test_default_jexl_filter_is_used() { + Assert.deepEqual( + OneCRLBlocklistClient.filterFunc, + RemoteSettings("not-specified").filterFunc + ); +}); + +add_task( + async function test_revocations_are_updated_on_sync_with_cert_storage() { + const certList = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + const has_revocations = () => + new Promise(resolve => { + certList.hasPriorData( + Ci.nsICertStorage.DATA_TYPE_REVOCATION, + (rv, hasPriorData) => { + if (rv == Cr.NS_OK) { + return resolve(hasPriorData); + } + return resolve(false); + } + ); + }); + + Assert.ok(!(await has_revocations())); + + await OneCRLBlocklistClient.emit("sync", { + data: { + current: [], + created: [ + { + issuerName: "MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=", + serialNumber: "a0X7/7DlTaedpgrIJg25iBPOkIM=", + }, + ], + updated: [], + deleted: [], + }, + }); + + Assert.ok(await has_revocations()); + } +); diff --git a/security/manager/ssl/tests/unit/test_blocklist_pinning.js b/security/manager/ssl/tests/unit/test_blocklist_pinning.js new file mode 100644 index 0000000000..87fd836f45 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_blocklist_pinning.js @@ -0,0 +1,127 @@ +"use strict"; + +const { Utils } = ChromeUtils.import("resource://services-settings/Utils.jsm"); +const { RemoteSettings } = ChromeUtils.import( + "resource://services-settings/remote-settings.js" +); +const { RemoteSecuritySettings } = ChromeUtils.import( + "resource://gre/modules/psm/RemoteSecuritySettings.jsm" +); + +const sss = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService +); + +const { PinningBlocklistClient } = RemoteSecuritySettings.init(); + +add_task(async function test_uses_a_custom_signer() { + Assert.notEqual( + PinningBlocklistClient.signerName, + RemoteSettings("not-specified").signerName + ); +}); + +add_task(async function test_pinning_has_initial_dump() { + if (AppConstants.platform == "android") { + // Skip test: we don't ship pinning dumps on Android (see package-manifest). + return; + } + Assert.ok( + await Utils.hasLocalDump( + PinningBlocklistClient.bucketName, + PinningBlocklistClient.collectionName + ) + ); +}); + +add_task(async function test_default_jexl_filter_is_used() { + Assert.deepEqual( + PinningBlocklistClient.filterFunc, + RemoteSettings("not-specified").filterFunc + ); +}); + +add_task(async function test_no_pins_by_default() { + // ensure our pins are all missing before we start + ok( + !sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://four.example.com"), + 0 + ) + ); + ok( + !sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://five.example.com"), + 0 + ) + ); +}); + +add_task(async function test_multiple_entries() { + const current = [ + { + pinType: "STSPin", + hostName: "five.example.com", + includeSubdomains: false, + expires: new Date().getTime() + 1000000, + versions: [Services.appinfo.version, "some version that won't match"], + }, + ]; + await PinningBlocklistClient.emit("sync", { data: { current } }); + + // Check that the HSTS preload added to the collection works... + ok( + sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://five.example.com"), + 0 + ) + ); + // // ...and that includeSubdomains is honored + ok( + !sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://subdomain.five.example.com"), + 0 + ) + ); + + // Overwrite existing entries. + current[current.length - 1].includeSubdomains = true; + await PinningBlocklistClient.emit("sync", { data: { current } }); + // The STS entry for five.example.com now has includeSubdomains set; + // ensure that the new includeSubdomains value is honored. + ok( + sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://subdomain.five.example.com"), + 0 + ) + ); +}); + +add_task(async function test_bad_entries() { + const current = [ + { + pinType: "STSPin", + hostName: "five.example.com", + includeSubdomains: true, + expires: new Date().getTime() + 1000000, + }, // missing versions. + ]; + // The event listener will catch any error, and won't throw. + // See https://bugzilla.mozilla.org/show_bug.cgi?id=1554939 + await PinningBlocklistClient.emit("sync", { data: { current } }); + + // Check that the HSTS preload overwrites existing entries... + // Version field is missing. + ok( + !sss.isSecureURI( + sss.HEADER_HSTS, + Services.io.newURI("https://five.example.com"), + 0 + ) + ); +}); diff --git a/security/manager/ssl/tests/unit/test_broken_fips.js b/security/manager/ssl/tests/unit/test_broken_fips.js new file mode 100644 index 0000000000..964092e2db --- /dev/null +++ b/security/manager/ssl/tests/unit/test_broken_fips.js @@ -0,0 +1,64 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// Tests that if Firefox attempts and fails to load a PKCS#11 module DB that was +// in FIPS mode, Firefox can still make use of keys in the key database. +// secomd.db can be created via `certutil -N -d `. Putting it in FIPS mode +// involves running `modutil -fips true -dbdir `. key4.db is from +// test_sdr_preexisting/key4.db. + +function run_test() { + // Append a single quote and non-ASCII characters to the profile path. + let env = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment + ); + let profd = env.get("XPCSHELL_TEST_PROFILE_DIR"); + let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); + file.initWithPath(profd); + file.append("'÷1"); + env.set("XPCSHELL_TEST_PROFILE_DIR", file.path); + + let profile = do_get_profile(); // must be called before getting nsIX509CertDB + Assert.ok( + /[^\x20-\x7f]/.test(profile.path), + "the profile path should contain a non-ASCII character" + ); + + let keyDBName = "key4.db"; + let keyDBFile = do_get_file(`test_broken_fips/${keyDBName}`); + keyDBFile.copyTo(profile, keyDBName); + + let pkcs11modDBName = "pkcs11.txt"; + let pkcs11modDBFile = do_get_file(`test_broken_fips/${pkcs11modDBName}`); + pkcs11modDBFile.copyTo(profile, pkcs11modDBName); + + let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + ok(!moduleDB.isFIPSEnabled, "FIPS should not be enabled"); + + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + const encrypted = + "MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECGeDHwVfyFqzBBAYvqMq/kDMsrARVNdC1C8d"; + const expectedResult = "password"; + let decrypted = sdr.decryptString(encrypted); + equal( + decrypted, + expectedResult, + "decrypted ciphertext should match expected plaintext" + ); + + let pkcs11modDBFileFIPS = do_get_profile(); + pkcs11modDBFileFIPS.append(`${pkcs11modDBName}.fips`); + ok( + pkcs11modDBFileFIPS.exists(), + "backed-up PKCS#11 module db should now exist" + ); +} diff --git a/security/manager/ssl/tests/unit/test_broken_fips/key4.db b/security/manager/ssl/tests/unit/test_broken_fips/key4.db new file mode 100644 index 0000000000..8f320dfdbd Binary files /dev/null and b/security/manager/ssl/tests/unit/test_broken_fips/key4.db differ diff --git a/security/manager/ssl/tests/unit/test_broken_fips/pkcs11.txt b/security/manager/ssl/tests/unit/test_broken_fips/pkcs11.txt new file mode 100644 index 0000000000..78a11f5fa7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_broken_fips/pkcs11.txt @@ -0,0 +1,5 @@ +library= +name=NSS Internal FIPS PKCS #11 Module +parameters=configdir='.' certPrefix='' keyPrefix='' secmod='' flags= updatedir='' updateCertPrefix='' updateKeyPrefix='' updateid='' updateTokenDescription='' +NSS=slotParams={0x00000003=[slotFlags=RSA,RC4,RC2,DES,DH,SHA1,MD5,MD2,SSL,TLS,AES,SHA256,SHA512,Camellia,SEED,RANDOM ] } Flags=internal,FIPS,critical + diff --git a/security/manager/ssl/tests/unit/test_certDB_export_pkcs12.js b/security/manager/ssl/tests/unit/test_certDB_export_pkcs12.js new file mode 100644 index 0000000000..3bcbc52f2b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_export_pkcs12.js @@ -0,0 +1,57 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests exporting a certificate and key as a PKCS#12 blob and importing it +// again with a new password set. + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const PKCS12_FILE = "test_certDB_import/cert_from_windows.pfx"; +const CERT_COMMON_NAME = "test_cert_from_windows"; +const TEST_CERT_PASSWORD = "é»’ã„"; +const TEST_OUTPUT_PASSWORD = "other password"; + +function findCertByCommonName(commonName) { + for (let cert of gCertDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +function run_test() { + // Import the certificate and key so we have something to export. + let cert = findCertByCommonName(CERT_COMMON_NAME); + equal(cert, null, "cert should not be found before import"); + let certFile = do_get_file(PKCS12_FILE); + ok(certFile, `${PKCS12_FILE} should exist`); + let errorCode = gCertDB.importPKCS12File(certFile, TEST_CERT_PASSWORD); + equal(errorCode, Ci.nsIX509CertDB.Success, "cert should be imported"); + cert = findCertByCommonName(CERT_COMMON_NAME); + notEqual(cert, null, "cert should be found now"); + + // Export the certificate and key. + let output = do_get_tempdir(); + output.append("output.p12"); + ok(!output.exists(), "output shouldn't exist before exporting PKCS12 file"); + errorCode = gCertDB.exportPKCS12File(output, [cert], TEST_CERT_PASSWORD); + equal(errorCode, Ci.nsIX509CertDB.Success, "cert should be exported"); + ok(output.exists(), "output should exist after exporting PKCS12 file"); + + // We should be able to import the exported blob again using the new password. + errorCode = gCertDB.importPKCS12File(output, TEST_CERT_PASSWORD); + equal(errorCode, Ci.nsIX509CertDB.Success, "cert should be imported"); + output.remove(false /* not a directory; recursive doesn't apply */); + + // Ideally there would be some way to confirm that this actually did anything. + // Unfortunately, since deleting a certificate currently doesn't actually do + // anything until the platform is restarted, we can't confirm that we + // successfully re-imported the certificate. +} diff --git a/security/manager/ssl/tests/unit/test_certDB_export_pkcs12_with_master_password.js b/security/manager/ssl/tests/unit/test_certDB_export_pkcs12_with_master_password.js new file mode 100644 index 0000000000..598d159c95 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_export_pkcs12_with_master_password.js @@ -0,0 +1,117 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests exporting a certificate and key as a PKCS#12 blob if the user has a +// master password set. + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const PKCS12_FILE = "test_certDB_import/cert_from_windows.pfx"; +const CERT_COMMON_NAME = "test_cert_from_windows"; +const TEST_CERT_PASSWORD = "é»’ã„"; + +var gPrompt = { + password: "password", + clickOk: true, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), + + // This intentionally does not use arrow function syntax to avoid an issue + // where in the context of the arrow function, |this != gPrompt| due to + // how objects get wrapped when going across xpcom boundaries. + alert(title, text) { + info(`alert('${text}')`); + ok(false, "not expecting alert() to be called"); + }, + + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + equal( + text, + "Please enter your Primary Password.", + "password prompt text should be as expected" + ); + equal(checkMsg, null, "checkMsg should be null"); + password.value = this.password; + return this.clickOk; + }, +}; + +const gPromptFactory = { + QueryInterface: ChromeUtils.generateQI(["nsIPromptFactory"]), + getPrompt: (aWindow, aIID) => gPrompt, +}; + +function findCertByCommonName(commonName) { + for (let cert of gCertDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +function run_test() { + let promptFactoryCID = MockRegistrar.register( + "@mozilla.org/prompter;1", + gPromptFactory + ); + + registerCleanupFunction(() => { + MockRegistrar.unregister(promptFactoryCID); + }); + + // Set a master password. + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + let token = tokenDB.getInternalKeyToken(); + token.initPassword("password"); + token.logoutSimple(); + + // Import the certificate and key so we have something to export. + let cert = findCertByCommonName(CERT_COMMON_NAME); + equal(cert, null, "cert should not be found before import"); + let certFile = do_get_file(PKCS12_FILE); + ok(certFile, `${PKCS12_FILE} should exist`); + let errorCode = gCertDB.importPKCS12File(certFile, TEST_CERT_PASSWORD); + equal(errorCode, Ci.nsIX509CertDB.Success, "cert should import"); + cert = findCertByCommonName(CERT_COMMON_NAME); + notEqual(cert, null, "cert should be found now"); + + // Log out so we're prompted for the password. + token.logoutSimple(); + + // Export the certificate and key (and don't cancel the password request + // dialog). + let output = do_get_tempdir(); + output.append("output.p12"); + ok(!output.exists(), "output shouldn't exist before exporting PKCS12 file"); + errorCode = gCertDB.exportPKCS12File(output, [cert], TEST_CERT_PASSWORD); + equal(errorCode, Ci.nsIX509CertDB.Success, "cert should export"); + ok(output.exists(), "output should exist after exporting PKCS12 file"); + output.remove(false /* not a directory; recursive doesn't apply */); + + // Log out again so we're prompted for the password. + token.logoutSimple(); + + // Attempt to export the certificate and key, but this time cancel the + // password request dialog. The export operation should also be canceled. + gPrompt.clickOk = false; + let output2 = do_get_tempdir(); + output2.append("output2.p12"); + ok(!output2.exists(), "output2 shouldn't exist before exporting PKCS12 file"); + errorCode = gCertDB.exportPKCS12File(output, [cert], TEST_CERT_PASSWORD); + equal( + errorCode, + Ci.nsIX509CertDB.ERROR_PKCS12_BACKUP_FAILED, + "cert should not export" + ); + + ok(!output2.exists(), "output2 shouldn't exist after failing to export"); +} diff --git a/security/manager/ssl/tests/unit/test_certDB_import.js b/security/manager/ssl/tests/unit/test_certDB_import.js new file mode 100644 index 0000000000..76bf968970 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import.js @@ -0,0 +1,217 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the various nsIX509CertDB import methods. + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const CA_CERT_COMMON_NAME = "importedCA"; +const TEST_EMAIL_ADDRESS = "test@example.com"; + +let gCACertImportDialogCount = 0; + +// Mock implementation of nsICertificateDialogs. +const gCertificateDialogs = { + confirmDownloadCACert: (ctx, cert, trust) => { + gCACertImportDialogCount++; + equal( + cert.commonName, + CA_CERT_COMMON_NAME, + "CA cert to import should have the correct CN" + ); + trust.value = Ci.nsIX509CertDB.TRUSTED_EMAIL; + return true; + }, + setPKCS12FilePassword: (ctx, password) => { + // This is only relevant to exporting. + ok(false, "setPKCS12FilePassword() should not have been called"); + }, + getPKCS12FilePassword: (ctx, password) => { + // We don't test anything that calls this method yet. + ok(false, "getPKCS12FilePassword() should not have been called"); + }, + + QueryInterface: ChromeUtils.generateQI(["nsICertificateDialogs"]), +}; + +// Implements nsIInterfaceRequestor. Mostly serves to mock nsIPrompt. +const gInterfaceRequestor = { + alert: (title, text) => { + // We don't test anything that calls this method yet. + ok(false, `alert() should not have been called: ${text}`); + }, + + getInterface: iid => { + if (iid.equals(Ci.nsIPrompt)) { + return this; + } + + throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE); + }, +}; + +function getCertAsByteArray(certPath) { + let certFile = do_get_file(certPath, false); + let certBytes = readFile(certFile); + + let byteArray = []; + for (let i = 0; i < certBytes.length; i++) { + byteArray.push(certBytes.charCodeAt(i)); + } + + return byteArray; +} + +function commonFindCertBy(propertyName, value) { + for (let cert of gCertDB.getCerts()) { + if (cert[propertyName] == value) { + return cert; + } + } + return null; +} + +function findCertByCommonName(commonName) { + return commonFindCertBy("commonName", commonName); +} + +function findCertByEmailAddress(emailAddress) { + return commonFindCertBy("emailAddress", emailAddress); +} + +function testImportCACert() { + // Sanity check the CA cert is missing. + equal( + findCertByCommonName(CA_CERT_COMMON_NAME), + null, + "CA cert should not be in the database before import" + ); + + // Import and check for success. + let caArray = getCertAsByteArray("test_certDB_import/importedCA.pem"); + gCertDB.importCertificates( + caArray, + caArray.length, + Ci.nsIX509Cert.CA_CERT, + gInterfaceRequestor + ); + equal( + gCACertImportDialogCount, + 1, + "Confirmation dialog for the CA cert should only be shown once" + ); + + let caCert = findCertByCommonName(CA_CERT_COMMON_NAME); + notEqual(caCert, null, "CA cert should now be found in the database"); + ok( + gCertDB.isCertTrusted( + caCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL + ), + "CA cert should be trusted for e-mail" + ); +} + +function testImportEmptyCertPackage() { + // Because this is an empty cert package, nothing will be imported. We know it succeeded if no errors are thrown. + let byteArray = [ + 0x30, + 0x0f, + 0x06, + 0x09, + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x02, + 0x05, + 0xa0, + 0x02, + 0x30, + 0x00, + ]; + gCertDB.importCertificates( + byteArray, + byteArray.length, + Ci.nsIX509Cert.CA_CERT, + gInterfaceRequestor + ); +} + +function testImportEmptyUserCert() { + // Because this is an empty cert package, nothing will be imported. We know it succeeded if no errors are thrown. + let byteArray = [ + 0x30, + 0x0f, + 0x06, + 0x09, + 0x60, + 0x86, + 0x48, + 0x01, + 0x86, + 0xf8, + 0x42, + 0x02, + 0x05, + 0xa0, + 0x02, + 0x30, + 0x00, + ]; + gCertDB.importUserCertificate( + byteArray, + byteArray.length, + gInterfaceRequestor + ); +} + +function run_test() { + let certificateDialogsCID = MockRegistrar.register( + "@mozilla.org/nsCertificateDialogs;1", + gCertificateDialogs + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(certificateDialogsCID); + }); + + // Sanity check the e-mail cert is missing. + equal( + findCertByEmailAddress(TEST_EMAIL_ADDRESS), + null, + "E-mail cert should not be in the database before import" + ); + + // Import the CA cert so that the e-mail import succeeds. + testImportCACert(); + testImportEmptyCertPackage(); + testImportEmptyUserCert(); + + // Import the e-mail cert and check for success. + let emailArray = getCertAsByteArray("test_certDB_import/emailEE.pem"); + gCertDB.importEmailCertificate( + emailArray, + emailArray.length, + gInterfaceRequestor + ); + let emailCert = findCertByEmailAddress(TEST_EMAIL_ADDRESS); + notEqual(emailCert, null, "E-mail cert should now be found in the database"); + let bundle = Services.strings.createBundle( + "chrome://pipnss/locale/pipnss.properties" + ); + equal( + emailCert.tokenName, + bundle.GetStringFromName("PrivateTokenDescription"), + "cert's tokenName should be the expected localized value" + ); +} diff --git a/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows.pfx b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows.pfx new file mode 100644 index 0000000000..e969d672d7 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows.pfx differ diff --git a/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_emptypass.pfx b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_emptypass.pfx new file mode 100644 index 0000000000..879d424b85 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_emptypass.pfx differ diff --git a/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_nopass.pfx b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_nopass.pfx new file mode 100644 index 0000000000..7dcd668121 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_certDB_import/cert_from_windows_nopass.pfx differ diff --git a/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem b/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem new file mode 100644 index 0000000000..136356c362 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUZ0427vGPMGf5dB3ZIhW8mkoNr04wDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKaW1wb3J0ZWRDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAhMR8wHQYJKoZIhvcNAQkBFhB0ZXN0QGV4YW1wbGUuY29t +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQBi4qlU7QLKNNAFYso7DWFZzptHNiR5 +5oOGSbUPu8pvi8YoJbyzefH7A9kiIyvdZNkBKPUZTwwFWKM+QwmZVrH8e7G3zI/G +447HiUQ4VNeeAYkT3K126nxEhVsk/gWPfv7qv3jUQcii/3PlUhHNqVRZNcEe/u4D +zwWp/j56ydzmQoWwBN/pal//uQOjum9PPpk+V1RYCDtekOHwOHQsuhKXTscMcamy +SJmG06/O3JF8yhjq03X1cHtj3YF2PH0fTCcgZMv/3GY34kZ61A4VJWUWRZFoCujy +Fx8jMEoMvJt/oIBggNJsDCBP9ksesfA5ImOqI5hziqo52oHG0Z9+0f1D +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem.certspec b/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem.certspec new file mode 100644 index 0000000000..0528bc624a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/emailEE.pem.certspec @@ -0,0 +1,2 @@ +issuer:importedCA +subject:/emailAddress=test@example.com diff --git a/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem b/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem new file mode 100644 index 0000000000..6c8ab901ae --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICzDCCAbSgAwIBAgIUUQGnWi0czVZBST5XDA1wp0G74kowDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKaW1wb3J0ZWRDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAVMRMwEQYDVQQDDAppbXBvcnRlZENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxAwDjAM +BgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCkMue2IDPldrL6f/ox5CoU +RPLnEPQyUDYIz4eFdAS/PX2A1/KEvYthVuVNbGZ1r5/3htt4cOKJCUYI/LWKc4eB +6gC9uhcC6JBqRfsQB4zK9RZu860shuNPGuEWA1KYgy1bzi8iJ2kTaHO0y3yXL+ow +guKrFJTK5NWPnxWQsdLE5lA9p67bNHjWxDzRHkDqeyIPiG/zmrudprxWXHk+EQgx +1hKN0rTaSAZnCyeik11i7MCyAnvrAk0mr9j8jX1+yf5mbFeKk0XcjSRmzoAQZBSA +9br5LUP1CvN2DbphDK1jkgP2Dx0dBuQH4HZBbY6lcKGfi4mdiJUkwiwqp346q7vo +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem.certspec b/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem.certspec new file mode 100644 index 0000000000..b168253544 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/importedCA.pem.certspec @@ -0,0 +1,3 @@ +issuer:importedCA +subject:importedCA +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_certDB_import/moz.build b/security/manager/ssl/tests/unit/test_certDB_import/moz.build new file mode 100644 index 0000000000..dfc75de914 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import/moz.build @@ -0,0 +1,14 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See Bug 1256495. +# test_certificates = ( +# 'emailEE.pem', +# 'importedCA.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_certDB_import_pkcs12.js b/security/manager/ssl/tests/unit/test_certDB_import_pkcs12.js new file mode 100644 index 0000000000..a295d424ff --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import_pkcs12.js @@ -0,0 +1,117 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests import PKCS12 file by nsIX509CertDB. + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const PKCS12_FILE = "test_certDB_import/cert_from_windows.pfx"; +const PKCS12_FILE_EMPTY_PASS = + "test_certDB_import/cert_from_windows_emptypass.pfx"; +const PKCS12_FILE_NO_PASS = "test_certDB_import/cert_from_windows_nopass.pfx"; +const CERT_COMMON_NAME = "test_cert_from_windows"; +const TEST_CERT_PASSWORD = "é»’ã„"; + +// Has getPKCS12FilePassword been called since we last reset this? +let gGetPKCS12FilePasswordCalled = false; +let gCurrentTestcase = null; + +let gTestcases = [ + // Test that importing a PKCS12 file with the wrong password fails. + { + name: "import using incorrect password", + filename: PKCS12_FILE, + passwordToUse: "this is the wrong password", + successExpected: false, + errorCode: Ci.nsIX509CertDB.ERROR_BAD_PASSWORD, + checkCertExist: true, + }, + // Test that importing something that isn't a PKCS12 file fails. + { + name: "import non-PKCS12 file", + filename: "test_certDB_import_pkcs12.js", + passwordToUse: TEST_CERT_PASSWORD, + successExpected: false, + errorCode: Ci.nsIX509CertDB.ERROR_DECODE_ERROR, + checkCertExist: true, + }, + // Test that importing a PKCS12 file with the correct password succeeds. + // This needs to be last because currently there isn't a way to delete the + // imported certificate (and thus reset the test state) that doesn't depend on + // the garbage collector running. + { + name: "import PKCS12 file", + filename: PKCS12_FILE, + passwordToUse: TEST_CERT_PASSWORD, + successExpected: true, + errorCode: Ci.nsIX509CertDB.Success, + checkCertExist: true, + }, + // Same cert file protected with empty string password + { + name: "import PKCS12 file empty password", + filename: PKCS12_FILE_EMPTY_PASS, + passwordToUse: "", + successExpected: true, + errorCode: Ci.nsIX509CertDB.Success, + checkCertExist: false, + }, + // Same cert file protected with no password + { + name: "import PKCS12 file no password", + filename: PKCS12_FILE_NO_PASS, + passwordToUse: null, + successExpected: true, + errorCode: Ci.nsIX509CertDB.Success, + checkCertExist: false, + }, +]; + +function doesCertExist(commonName) { + let allCerts = gCertDB.getCerts(); + for (let cert of allCerts) { + if (cert.isBuiltInRoot) { + continue; + } + if (cert.commonName == commonName) { + return true; + } + } + + return false; +} + +function runOneTestcase(testcase) { + info(`running ${testcase.name}`); + if (testcase.checkCertExist) { + ok( + !doesCertExist(CERT_COMMON_NAME), + "cert should not be in the database before import" + ); + } + + // Import and check for failure. + let certFile = do_get_file(testcase.filename); + ok(certFile, `${testcase.filename} should exist`); + gGetPKCS12FilePasswordCalled = false; + gCurrentTestcase = testcase; + let errorCode = gCertDB.importPKCS12File(certFile, testcase.passwordToUse); + equal(errorCode, testcase.errorCode, `verifying error code`); + equal( + doesCertExist(CERT_COMMON_NAME), + testcase.successExpected, + `cert should${testcase.successExpected ? "" : " not"} be found now` + ); +} + +function run_test() { + for (let testcase of gTestcases) { + runOneTestcase(testcase); + } +} diff --git a/security/manager/ssl/tests/unit/test_certDB_import_with_master_password.js b/security/manager/ssl/tests/unit/test_certDB_import_with_master_password.js new file mode 100644 index 0000000000..e31dc605b8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_certDB_import_with_master_password.js @@ -0,0 +1,148 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that a CA certificate can still be imported if the user has a master +// password set. + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const CA_CERT_COMMON_NAME = "importedCA"; + +let gCACertImportDialogCount = 0; + +// Mock implementation of nsICertificateDialogs. +const gCertificateDialogs = { + confirmDownloadCACert: (ctx, cert, trust) => { + gCACertImportDialogCount++; + equal( + cert.commonName, + CA_CERT_COMMON_NAME, + "CA cert to import should have the correct CN" + ); + trust.value = Ci.nsIX509CertDB.TRUSTED_EMAIL; + return true; + }, + setPKCS12FilePassword: (ctx, password) => { + // This is only relevant to exporting. + ok(false, "setPKCS12FilePassword() should not have been called"); + }, + getPKCS12FilePassword: (ctx, password) => { + // We don't test anything that calls this method yet. + ok(false, "getPKCS12FilePassword() should not have been called"); + }, + + QueryInterface: ChromeUtils.generateQI(["nsICertificateDialogs"]), +}; + +var gMockPrompter = { + passwordToTry: "password", + numPrompts: 0, + + // This intentionally does not use arrow function syntax to avoid an issue + // where in the context of the arrow function, |this != gMockPrompter| due to + // how objects get wrapped when going across xpcom boundaries. + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + this.numPrompts++; + if (this.numPrompts > 1) { + // don't keep retrying a bad password + return false; + } + equal( + text, + "Please enter your Primary Password.", + "password prompt text should be as expected" + ); + equal(checkMsg, null, "checkMsg should be null"); + ok(this.passwordToTry, "passwordToTry should be non-null"); + password.value = this.passwordToTry; + return true; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), + + // Again with the arrow function issue. + getInterface(iid) { + if (iid.equals(Ci.nsIPrompt)) { + return this; + } + + throw Components.Exception("", Cr.NS_ERROR_NO_INTERFACE); + }, +}; + +function getCertAsByteArray(certPath) { + let certFile = do_get_file(certPath, false); + let certBytes = readFile(certFile); + + let byteArray = []; + for (let i = 0; i < certBytes.length; i++) { + byteArray.push(certBytes.charCodeAt(i)); + } + + return byteArray; +} + +function findCertByCommonName(commonName) { + for (let cert of gCertDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +function run_test() { + let certificateDialogsCID = MockRegistrar.register( + "@mozilla.org/nsCertificateDialogs;1", + gCertificateDialogs + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(certificateDialogsCID); + }); + + // Set a master password. + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + let token = tokenDB.getInternalKeyToken(); + token.initPassword("password"); + token.logoutSimple(); + + // Sanity check the CA cert is missing. + equal( + findCertByCommonName(CA_CERT_COMMON_NAME), + null, + "CA cert should not be in the database before import" + ); + + // Import and check for success. + let caArray = getCertAsByteArray("test_certDB_import/importedCA.pem"); + gCertDB.importCertificates( + caArray, + caArray.length, + Ci.nsIX509Cert.CA_CERT, + gMockPrompter + ); + equal( + gCACertImportDialogCount, + 1, + "Confirmation dialog for the CA cert should only be shown once" + ); + + let caCert = findCertByCommonName(CA_CERT_COMMON_NAME); + notEqual(caCert, null, "CA cert should now be found in the database"); + ok( + gCertDB.isCertTrusted( + caCert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_EMAIL + ), + "CA cert should be trusted for e-mail" + ); +} diff --git a/security/manager/ssl/tests/unit/test_cert_chains.js b/security/manager/ssl/tests/unit/test_cert_chains.js new file mode 100644 index 0000000000..56c68a049a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_chains.js @@ -0,0 +1,814 @@ +// -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// 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/. + +"use strict"; + +function test_cert_equals() { + let certA = constructCertFromFile("bad_certs/default-ee.pem"); + let certB = constructCertFromFile("bad_certs/default-ee.pem"); + let certC = constructCertFromFile("bad_certs/expired-ee.pem"); + + ok( + certA != certB, + "Cert objects constructed from the same file should not be equal" + + " according to the equality operators" + ); + ok( + certA.equals(certB), + "equals() on cert objects constructed from the same cert file should" + + " return true" + ); + ok( + !certA.equals(certC), + "equals() on cert objects constructed from files for different certs" + + " should return false" + ); +} + +// We hard-code the following certificates for the pkcs7 export tests so that we +// don't have to change the test data when the certificates change each year. +// Luckily these tests don't depend on the certificates being valid, so it's ok +// to let them expire. +const gDefaultEEPEM = `-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUDUo/9G0rz7fJiWTw0hY6TIyPRSIwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAwMDAwMFoYDzIwMjAw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcow +gccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tghUqLnBp +bm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu +ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCkguNhMyVCYhyYXfE22wNvlaob +K2YRb4OGMxySIKuQ80N0XlO+xpLJTs9YzFVY1+JTHNez1QfwP9KJeZznTzVzLh4s +v0swx/+oUxCfLb0VIl/kdUqLkbGYrAmtjeOKZLaqVtRH0BnmbPowLak1pi6nQYOU ++aL9QOuvT/j3rXoimcdo6X3TK1SN2/64fGMyG/pwas+JXehbReUf4n1ewk84ADtb ++ew8tRAKf/uxzKUj5t/UgqDsnTWq5wUc5IJKwoHT41sQnNqPg12x4+WGWiAsWCpR +/hKYHFGr7rb4JTGEPAJpWcv9WtZYAvwT78a2xpHp5XNglj16IjWEukvJuU1W +-----END CERTIFICATE-----`; + +const gExpiredEEPEM = `-----BEGIN CERTIFICATE----- +MIIDHDCCAgSgAwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAwMDAwMFoYDzIwMTQw +MTAxMDAwMDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJlZC5leGFtcGxlLmNvbTAyBggrBgEF +BQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJ +KoZIhvcNAQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzf +T+ow5WVsxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7IAMO1CEr5FVdCOVTma5h +mu/81rkJLmZ8RQDWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3 +L9zJ2JqNc60+hB8l297ZaSl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74V +kQyNobaFzDZ+Zr3QmfbejEsY2EYnq8XuENgIO4DuYrm80/p6bMO6laB0Uv5W6uXZ +gBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFwWwtnoK7I= +-----END CERTIFICATE-----`; + +const gTestCAPEM = `-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUKaFwIwCwHXUgKRuOhAX4pjYsmbgwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAwMDAwMFoYDzIwMjAw +MjA1MDAwMDAwWjASMRAwDgYDVQQDDAdUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAIMgnywHFbPzJ +BEcbpx/aWQOI2tUFlo7MUoPSoACHzoI/HOUTx25eKHlpNK2jSljLufhUd//eCCXg ++OQt4f2N/tRw8gumbs3YDF7+t3ZNGt+iQxZTwN7MKsGIZy+6R523XHw8lpzFX5iz +XgIS+0APlX+XyZk7MRCcBWh6PSaSqEOOvUXVp6Omh3it034kBWnm809TEWmwiVw3 +ssPDmpUCArdDNMMdvQehzaH96cdjcSsguqpX9NcMDUmmiG7HLQ2iy+WSzek9S46S +bKKDLw8Ebevfkl6PEpg+GDulq+EPXayN3AsFXkF8MaFLgfeprkENjN1g4jM+WSyN +6DC7vCkj7A== +-----END CERTIFICATE-----`; + +const gUnknownIssuerPEM = ` +-----BEGIN CERTIFICATE----- +MIIDqTCCApGgAwIBAgIUMRiJ9TrwqTOoVFU+j5FDWDWS1X8wDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbVGVzdCBJbnRlcm1lZGlhdGUgdG8gZGVsZXRlMCIYDzIw +MTcxMTI3MDAwMDAwWhgPMjAyMDAyMDUwMDAwMDBaMC4xLDAqBgNVBAMMI1Rlc3Qg +RW5kLWVudGl0eSBmcm9tIHVua25vd24gaXNzdWVyMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4HCMIG/MIGIBgNV +HREEgYAwfoIZdW5rbm93bmlzc3Vlci5leGFtcGxlLmNvbYI0dW5rbm93bmlzc3Vl +ci5pbmNsdWRlLXN1YmRvbWFpbnMucGlubmluZy5leGFtcGxlLmNvbYIrdW5rbm93 +bmlzc3Vlci50ZXN0LW1vZGUucGlubmluZy5leGFtcGxlLmNvbTAyBggrBgEFBQcB +AQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZI +hvcNAQELBQADggEBALAnJjBJ+MOc7kMRzmESYZRSxKak7A1K67xBXWzWmK3t3WXv +e/RLjV/RhbyTN20h2ZjSVcuDzgNYC/RJ/z3Xd5Q9QEGoi1ly84HeaeHw/3kUSHxv +J3JnbPu2lk96U5y7tXEVfbEVZYpx4Us72fuURPWriVldILH2lgrEg+iKZWbY/wcT +vfu1j/flMkGEOpc1HytlmR9fkCDnqzFfcmv7Eh3X1BiSBOIemGnUHxONwlthSE68 +IItE5l3c82G8oQGmve6r0N9h7t6opIjH1koFWMck/pzDA01FmWey4ASdlmjE8NSJ +Al1zsF8EiLOZeI1rvurcXwVOd0Olk9/QT5hwTkk= +-----END CERTIFICATE-----`; + +const gOCSPEEWithIntermediatePEM = ` +-----BEGIN CERTIFICATE----- +MIIDNTCCAh2gAwIBAgIUZ67hS7lHVnCQtXx7oXFlzihqh0cwDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxNzExMjcwMDAw +MDBaGA8yMDIwMDIwNTAwMDAwMFowLDEqMCgGA1UEAwwhVGVzdCBFbmQtZW50aXR5 +IHdpdGggSW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo1swWTAjBgNVHREEHDAagglsb2NhbGhv +c3SCDSouZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZo +dHRwOi8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQAo043hM4Gi +UtoXKOQB2v0C8nF4Yyzpf+i0LlxQCFZkiLYu9pIuQu16I3TbLQRBwhCC0ml7TqJB +AbryzILTorCQP8A1WQa1kt6cb30jCyXLcWnDA/ULPexn9cYm6I0YyLFlnkcVzMGL +Fc+LyWTAPEW5rMauu5iOOp/6L5rBF0M9bg5yXSGNDv8gk3Jc+opJbBDTrAuKDNLp +JSEp4rqovNFnirzlJWDS+ScAsWHtoLcrH6gnQRPsEV1WFQnYr3HkAakYQok9xs5A +ikBS6mgz4/cFBts8bSGSuXxctkN2Ss7Y5l3YmTYKCxPz6retVfrhi/islH4W3z9H +pu3ZqyACO6Lb +-----END CERTIFICATE-----`; + +const gTestIntPEM = ` +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIUa0X7/7DlTaedpgrIJg25iBPOkIMwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE1MDEwMTAwMDAwMFoYDzIwMjUw +MTAxMDAwMDAwWjAcMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTCCASIwDQYJ +KoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1 +SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+ +zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYL +K7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwc +bJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibW +JZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMd +MBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEB +AILNZM9yT9ylMpjyi0tXaDORzpHiJ8vEoVKk98bC2BQF0kMEEB547p+Ms8zdJY00 +Bxe9qigT8rQwKprXq5RvgIZ32QLn/yMPiCp/e6zBdsx77TkfmnSnxvPi+0nlA+eM +8JYN0UST4vWD4vPPX9GgZDVoGQTiF3hUivJ5R8sHb/ozcSukMKQQ22+AIU7w6wyA +IbCAG7Pab4k2XFAeEnUZsl9fCym5jsPN9Pnv9rlBi6h8shHw1R2ROXjgxubjiMr3 +B456vFTJImLJjyA1iTSlr/+VXGUYg6Z0/HYnsO00+8xUKM71dPxGAfIFNaSscpyk +rGFLvocT/kym6r8galxCJUo= +-----END CERTIFICATE-----`; + +function build_cert_list_from_pem_list(pemList) { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let certList = []; + for (let pem of pemList) { + let cert = certdb.constructX509FromBase64(pemToBase64(pem)); + certList.push(cert); + } + return certList; +} + +function test_cert_pkcs7_export() { + // This was generated by running BadCertAndPinningServer locally on the bad_certs + // directory and visiting: + // https://good.include-subdomains.pinning.example.com:8443/ + // and then viewing the certificate chain presented (in the page info dialog) + // and exporting it. + // (NB: test-ca must be imported and trusted for the connection to succeed) + const expectedPKCS7ForDefaultEE = + "MIAGCSqGSIb3DQEHAqCAMIACAQExADCABgkqhkiG9w0BBwEAAKCCBmQwggLTMIIBu6ADAgE" + + "CAhQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZX" + + "N0IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB" + + "1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI" + + "BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xz" + + "VJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCy" + + "uwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW" + + "7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE" + + "LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8" + + "wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAgyCfLAcVs/MkERxunH9pZA4ja1Q" + + "WWjsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR3/94IJeD45C3h/Y3+1HDyC6ZuzdgMX" + + "v63dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmLNeAhL7QA+Vf5fJmTsxEJwFaHo9JpKo" + + "Q469RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8OalQICt0M0wx29B6HNof3px2NxKyC6qlf" + + "01wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+SXo8SmD4YO6Wr4Q9drI3cCwVeQXwxoU" + + "uB96muQQ2M3WDiMz5ZLI3oMLu8KSPsMIIDiTCCAnGgAwIBAgIUDUo/9G0rz7fJiWTw0hY6T" + + "IyPRSIwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAw" + + "MDAwMFoYDzIwMjAwMjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggE" + + "iMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNU" + + "q07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0" + + "DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ" + + "sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJH" + + "dtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFz" + + "G4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcowgccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob" + + "3N0gg0qLmV4YW1wbGUuY29tghUqLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1z" + + "dWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnB" + + "pbm5pbmcuZXhhbXBsZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi" + + "8vbG9jYWxob3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCkguNhMyVCYhyYXfE22wNvl" + + "aobK2YRb4OGMxySIKuQ80N0XlO+xpLJTs9YzFVY1+JTHNez1QfwP9KJeZznTzVzLh4sv0sw" + + "x/+oUxCfLb0VIl/kdUqLkbGYrAmtjeOKZLaqVtRH0BnmbPowLak1pi6nQYOU+aL9QOuvT/j" + + "3rXoimcdo6X3TK1SN2/64fGMyG/pwas+JXehbReUf4n1ewk84ADtb+ew8tRAKf/uxzKUj5t" + + "/UgqDsnTWq5wUc5IJKwoHT41sQnNqPg12x4+WGWiAsWCpR/hKYHFGr7rb4JTGEPAJpWcv9W" + + "tZYAvwT78a2xpHp5XNglj16IjWEukvJuU1WMQAAAAAAAAA="; + let certListDefaultEE = build_cert_list_from_pem_list([ + gDefaultEEPEM, + gTestCAPEM, + ]); + + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let pkcs7DefaultEE = certdb.asPKCS7Blob(certListDefaultEE); + + equal( + btoa(pkcs7DefaultEE), + expectedPKCS7ForDefaultEE, + "PKCS7 export should work as expected for default-ee chain" + ); + + // This was generated by running BadCertAndPinningServer locally on the bad_certs + // directory and visiting: + // https://unknownissuer.example.com:8443/ + // and then viewing the certificate presented (in the add certificate + // exception dialog) and exporting it. + const expectedPKCS7ForUnknownIssuer = + "MIAGCSqGSIb3DQEHAqCAMIACAQExADCABgkqhkiG9w0BBwEAAKCCA60wggOpMIICkaADAgE" + + "CAhQxGIn1OvCpM6hUVT6PkUNYNZLVfzANBgkqhkiG9w0BAQsFADAmMSQwIgYDVQQDDBtUZX" + + "N0IEludGVybWVkaWF0ZSB0byBkZWxldGUwIhgPMjAxNzExMjcwMDAwMDBaGA8yMDIwMDIwN" + + "TAwMDAwMFowLjEsMCoGA1UEAwwjVGVzdCBFbmQtZW50aXR5IGZyb20gdW5rbm93biBpc3N1" + + "ZXIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTw" + + "T2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs" + + "1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkf" + + "bmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA" + + "dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/" + + "l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcIwgb8wgYgGA1UdEQSBgDB+ghl1bm" + + "tub3duaXNzdWVyLmV4YW1wbGUuY29tgjR1bmtub3duaXNzdWVyLmluY2x1ZGUtc3ViZG9tY" + + "Wlucy5waW5uaW5nLmV4YW1wbGUuY29tgit1bmtub3duaXNzdWVyLnRlc3QtbW9kZS5waW5u" + + "aW5nLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2x" + + "vY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAsCcmMEn4w5zuQxHOYRJhlFLEpq" + + "TsDUrrvEFdbNaYre3dZe979EuNX9GFvJM3bSHZmNJVy4POA1gL9En/Pdd3lD1AQaiLWXLzg" + + "d5p4fD/eRRIfG8ncmds+7aWT3pTnLu1cRV9sRVlinHhSzvZ+5RE9auJWV0gsfaWCsSD6Ipl" + + "Ztj/BxO9+7WP9+UyQYQ6lzUfK2WZH1+QIOerMV9ya/sSHdfUGJIE4h6YadQfE43CW2FITrw" + + "gi0TmXdzzYbyhAaa97qvQ32Hu3qikiMfWSgVYxyT+nMMDTUWZZ7LgBJ2WaMTw1IkCXXOwXw" + + "SIs5l4jWu+6txfBU53Q6WT39BPmHBOSTEAAAAAAAAA"; + let certListUnknownIssuer = build_cert_list_from_pem_list([ + gUnknownIssuerPEM, + ]); + let pkcs7UnknownIssuer = certdb.asPKCS7Blob(certListUnknownIssuer); + equal( + btoa(pkcs7UnknownIssuer), + expectedPKCS7ForUnknownIssuer, + "PKCS7 export should work as expected for unknown issuer" + ); + + // This was generated by running OCSPStaplingServer locally on the ocsp_certs + // directory and visiting: + // https://ocsp-stapling-with-intermediate.example.com:8443/ + // and then viewing the certificate chain presented (in the page info dialog) + // and exporting it. + // (NB: test-ca must be imported and trusted for the connection to succeed) + const expectedPKCS7WithIntermediate = + "MIAGCSqGSIb3DQEHAqCAMIACAQExADCABgkqhkiG9w0BBwEAAKCCCPEwggLTMIIBu6ADAgE" + + "CAhQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZX" + + "N0IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB" + + "1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI" + + "BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xz" + + "VJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCy" + + "uwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW" + + "7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE" + + "LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8" + + "wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAgyCfLAcVs/MkERxunH9pZA4ja1Q" + + "WWjsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR3/94IJeD45C3h/Y3+1HDyC6ZuzdgMX" + + "v63dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmLNeAhL7QA+Vf5fJmTsxEJwFaHo9JpKo" + + "Q469RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8OalQICt0M0wx29B6HNof3px2NxKyC6qlf" + + "01wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+SXo8SmD4YO6Wr4Q9drI3cCwVeQXwxoU" + + "uB96muQQ2M3WDiMz5ZLI3oMLu8KSPsMIIC3TCCAcWgAwIBAgIUa0X7/7DlTaedpgrIJg25i" + + "BPOkIMwDQYJKoZIhvcNAQELBQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE1MDEwMTAw" + + "MDAwMFoYDzIwMjUwMTAxMDAwMDAwWjAcMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTC" + + "CASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6u" + + "Q1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8H" + + "mnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh" + + "eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaM" + + "Mkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5" + + "kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EB" + + "AMCAQYwDQYJKoZIhvcNAQELBQADggEBAILNZM9yT9ylMpjyi0tXaDORzpHiJ8vEoVKk98bC" + + "2BQF0kMEEB547p+Ms8zdJY00Bxe9qigT8rQwKprXq5RvgIZ32QLn/yMPiCp/e6zBdsx77Tk" + + "fmnSnxvPi+0nlA+eM8JYN0UST4vWD4vPPX9GgZDVoGQTiF3hUivJ5R8sHb/ozcSukMKQQ22" + + "+AIU7w6wyAIbCAG7Pab4k2XFAeEnUZsl9fCym5jsPN9Pnv9rlBi6h8shHw1R2ROXjgxubji" + + "Mr3B456vFTJImLJjyA1iTSlr/+VXGUYg6Z0/HYnsO00+8xUKM71dPxGAfIFNaSscpykrGFL" + + "vocT/kym6r8galxCJUowggM1MIICHaADAgECAhRnruFLuUdWcJC1fHuhcWXOKGqHRzANBgk" + + "qhkiG9w0BAQsFADAcMRowGAYDVQQDDBFUZXN0IEludGVybWVkaWF0ZTAiGA8yMDE3MTEyNz" + + "AwMDAwMFoYDzIwMjAwMjA1MDAwMDAwWjAsMSowKAYDVQQDDCFUZXN0IEVuZC1lbnRpdHkgd" + + "2l0aCBJbnRlcm1lZGlhdGUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo" + + "RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHE" + + "IeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7q" + + "dw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCAB" + + "iTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd" + + "q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjWzBZMCMGA1U" + + "dEQQcMBqCCWxvY2FsaG9zdIINKi5leGFtcGxlLmNvbTAyBggrBgEFBQcBAQQmMCQwIgYIKw" + + "YBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJKoZIhvcNAQELBQADggEBACjTj" + + "eEzgaJS2hco5AHa/QLycXhjLOl/6LQuXFAIVmSIti72ki5C7XojdNstBEHCEILSaXtOokEB" + + "uvLMgtOisJA/wDVZBrWS3pxvfSMLJctxacMD9Qs97Gf1xibojRjIsWWeRxXMwYsVz4vJZMA" + + "8Rbmsxq67mI46n/ovmsEXQz1uDnJdIY0O/yCTclz6iklsENOsC4oM0uklISniuqi80WeKvO" + + "UlYNL5JwCxYe2gtysfqCdBE+wRXVYVCdivceQBqRhCiT3GzkCKQFLqaDPj9wUG2zxtIZK5f" + + "Fy2Q3ZKztjmXdiZNgoLE/Pqt61V+uGL+KyUfhbfP0em7dmrIAI7otsxAAAAAAAAAA=="; + let certListWithIntermediate = build_cert_list_from_pem_list([ + gOCSPEEWithIntermediatePEM, + gTestIntPEM, + gTestCAPEM, + ]); + let pkcs7WithIntermediate = certdb.asPKCS7Blob(certListWithIntermediate); + equal( + btoa(pkcs7WithIntermediate), + expectedPKCS7WithIntermediate, + "PKCS7 export should work as expected for chain with intermediate" + ); +} + +function test_cert_pkcs7_empty_array() { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + throws( + () => certdb.asPKCS7Blob([]), + /NS_ERROR_ILLEGAL_VALUE/, + "trying to convert an empty array to pkcs7 should throw" + ); +} + +function test_security_info_serialization(securityInfo, expectedErrorCode) { + // Serialize the securityInfo to a string + let serHelper = Cc["@mozilla.org/network/serialization-helper;1"].getService( + Ci.nsISerializationHelper + ); + let serialized = serHelper.serializeToString(securityInfo); + + // Deserialize from the string and compare to the original object + let deserialized = serHelper.deserializeObject(serialized); + deserialized.QueryInterface(Ci.nsITransportSecurityInfo); + equal( + securityInfo.securityState, + deserialized.securityState, + "Original and deserialized security state should match" + ); + equal( + securityInfo.errorMessage, + deserialized.errorMessage, + "Original and deserialized error message should match" + ); + equal( + securityInfo.errorCode, + expectedErrorCode, + "Original and expected error code should match" + ); + equal( + deserialized.errorCode, + expectedErrorCode, + "Deserialized and expected error code should match" + ); +} + +// In Bug 1580315, nsNSSCertList/nsIX509CertList was replaced by +// Array, so the serialization of the certList changed. This +// test is used to make sure we can still deserialize the transportSecurityInfo +// binary string which has the old certList binary. +function test_old_succeeded_certlist_deseralization_v1() { + // This was the serialized output of test "good.include-subdomains.pinning.example.com" + // in security/manager/ssl/tests/unit/test_cert_chains.js + // The serialized output was generated before we replace nsIX509CertList with + // Array, so it had the old version of transportSecurityInfo. + const serialized = + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAAAgA" + + "AAAAAAAAAAAAAAAAAAAEAMQFmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAA" + + "AAAAONMIIDiTCCAnGgAwIBAgIUDUo/9G0rz7fJiWTw0hY6TIyPRSIwDQYJKoZIhvcNAQELB" + + "QAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAwMDAwMFoYDzIwMjAwMjA1MDAw" + + "MDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4I" + + "BDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZ" + + "wGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tF" + + "YIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n" + + "FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN" + + "7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe" + + "2NAgMBAAGjgcowgccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tg" + + "hUqLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu" + + "ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb20" + + "wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA" + + "0GCSqGSIb3DQEBCwUAA4IBAQCkguNhMyVCYhyYXfE22wNvlaobK2YRb4OGMxySIKuQ80N0X" + + "lO+xpLJTs9YzFVY1+JTHNez1QfwP9KJeZznTzVzLh4sv0swx/+oUxCfLb0VIl/kdUqLkbGY" + + "rAmtjeOKZLaqVtRH0BnmbPowLak1pi6nQYOU+aL9QOuvT/j3rXoimcdo6X3TK1SN2/64fGM" + + "yG/pwas+JXehbReUf4n1ewk84ADtb+ew8tRAKf/uxzKUj5t/UgqDsnTWq5wUc5IJKwoHT41" + + "sQnNqPg12x4+WGWiAsWCpR/hKYHFGr7rb4JTGEPAJpWcv9WtZYAvwT78a2xpHp5XNglj16I" + + "jWEukvJuU1WwC8AAwAAAAABAQAAAAAAAAZ4MjU1MTkAAAAOUlNBLVBTUy1TSEEyNTYBlZ+x" + + "ZWUXSH+rm9iRO+Uxl650zaXNL0c/lvXwt//2LGgAAAACZgoyJpFcT/u7IImFpjLfBb3Dl5p" + + "UIkzVhYlpa26W6oMAAAAAAAADjTCCA4kwggJxoAMCAQICFA1KP/RtK8+3yYlk8NIWOkyMj0" + + "UiMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNzExMjcwMDAwM" + + "DBaGA8yMDIwMDIwNTAwMDAwMFowGjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MIIBIjAN" + + "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz" + + "1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4IC" + + "mTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXk" + + "D3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK" + + "9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP" + + "+SSP6clHEMdUDrNoYCjXtjQIDAQABo4HKMIHHMIGQBgNVHREEgYgwgYWCCWxvY2FsaG9zdI" + + "INKi5leGFtcGxlLmNvbYIVKi5waW5uaW5nLmV4YW1wbGUuY29tgigqLmluY2x1ZGUtc3ViZ" + + "G9tYWlucy5waW5uaW5nLmV4YW1wbGUuY29tgigqLmV4Y2x1ZGUtc3ViZG9tYWlucy5waW5u" + + "aW5nLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2x" + + "vY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEApILjYTMlQmIcmF3xNtsDb5WqGy" + + "tmEW+DhjMckiCrkPNDdF5TvsaSyU7PWMxVWNfiUxzXs9UH8D/SiXmc5081cy4eLL9LMMf/q" + + "FMQny29FSJf5HVKi5GxmKwJrY3jimS2qlbUR9AZ5mz6MC2pNaYup0GDlPmi/UDrr0/49616" + + "IpnHaOl90ytUjdv+uHxjMhv6cGrPiV3oW0XlH+J9XsJPOAA7W/nsPLUQCn/7scylI+bf1IK" + + "g7J01qucFHOSCSsKB0+NbEJzaj4NdsePlhlogLFgqUf4SmBxRq+62+CUxhDwCaVnL/VrWWA" + + "L8E+/GtsaR6eVzYJY9eiI1hLpLyblNVmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtul" + + "uqDAAAAAAAAAtcwggLTMIIBu6ADAgECAhQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG" + + "9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDA" + + "yMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDw" + + "AwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm" + + "24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP" + + "8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFth" + + "Vt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7Ly" + + "JvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NA" + + "gMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IB" + + "AQAgyCfLAcVs/MkERxunH9pZA4ja1QWWjsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR" + + "3/94IJeD45C3h/Y3+1HDyC6ZuzdgMXv63dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmL" + + "NeAhL7QA+Vf5fJmTsxEJwFaHo9JpKoQ469RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8Oal" + + "QICt0M0wx29B6HNof3px2NxKyC6qlf01wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+S" + + "Xo8SmD4YO6Wr4Q9drI3cCwVeQXwxoUuB96muQQ2M3WDiMz5ZLI3oMLu8KSPsAA=="; + + let serHelper = Cc["@mozilla.org/network/serialization-helper;1"].getService( + Ci.nsISerializationHelper + ); + // deserialize from the string and compare to the original object + let deserialized = serHelper.deserializeObject(serialized); + deserialized.QueryInterface(Ci.nsITransportSecurityInfo); + + equal( + deserialized.failedCertChain.length, + 0, + "failedCertChain for a successful connection should be empty" + ); + let certChain = build_cert_list_from_pem_list([gDefaultEEPEM, gTestCAPEM]); + ok( + areCertArraysEqual(certChain, deserialized.succeededCertChain), + "succeededCertChain should be deserialized correctly" + ); +} + +// Same as the above test, however, this is the v2 version of the +// serialization. +function test_old_succeeded_certlist_deseralization_v2() { + const serialized = + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAAAgA" + + "AAAAAAAAAAAAAAAAAAAEAMgFmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAA" + + "AAAAONMIIDiTCCAnGgAwIBAgIUDUo/9G0rz7fJiWTw0hY6TIyPRSIwDQYJKoZIhvcNAQELB" + + "QAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE3MTEyNzAwMDAwMFoYDzIwMjAwMjA1MDAw" + + "MDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4I" + + "BDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZ" + + "wGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tF" + + "YIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n" + + "FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN" + + "7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe" + + "2NAgMBAAGjgcowgccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tg" + + "hUqLnBpbm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu" + + "ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBsZS5jb20" + + "wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxob3N0Ojg4ODgvMA" + + "0GCSqGSIb3DQEBCwUAA4IBAQCkguNhMyVCYhyYXfE22wNvlaobK2YRb4OGMxySIKuQ80N0X" + + "lO+xpLJTs9YzFVY1+JTHNez1QfwP9KJeZznTzVzLh4sv0swx/+oUxCfLb0VIl/kdUqLkbGY" + + "rAmtjeOKZLaqVtRH0BnmbPowLak1pi6nQYOU+aL9QOuvT/j3rXoimcdo6X3TK1SN2/64fGM" + + "yG/pwas+JXehbReUf4n1ewk84ADtb+ew8tRAKf/uxzKUj5t/UgqDsnTWq5wUc5IJKwoHT41" + + "sQnNqPg12x4+WGWiAsWCpR/hKYHFGr7rb4JTGEPAJpWcv9WtZYAvwT78a2xpHp5XNglj16I" + + "jWEukvJuU1WEwEABAAAAAABAQAAAAAAAAZ4MjU1MTkAAAAOUlNBLVBTUy1TSEEyNTYBlZ+x" + + "ZWUXSH+rm9iRO+Uxl650zaXNL0c/lvXwt//2LGgAAAACZgoyJpFcT/u7IImFpjLfBb3Dl5p" + + "UIkzVhYlpa26W6oMAAAAAAAADjTCCA4kwggJxoAMCAQICFA1KP/RtK8+3yYlk8NIWOkyMj0" + + "UiMA0GCSqGSIb3DQEBCwUAMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwIhgPMjAxNzExMjcwMDAwM" + + "DBaGA8yMDIwMDIwNTAwMDAwMFowGjEYMBYGA1UEAwwPVGVzdCBFbmQtZW50aXR5MIIBIjAN" + + "BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz" + + "1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4IC" + + "mTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXk" + + "D3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK" + + "9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP" + + "+SSP6clHEMdUDrNoYCjXtjQIDAQABo4HKMIHHMIGQBgNVHREEgYgwgYWCCWxvY2FsaG9zdI" + + "INKi5leGFtcGxlLmNvbYIVKi5waW5uaW5nLmV4YW1wbGUuY29tgigqLmluY2x1ZGUtc3ViZ" + + "G9tYWlucy5waW5uaW5nLmV4YW1wbGUuY29tgigqLmV4Y2x1ZGUtc3ViZG9tYWlucy5waW5u" + + "aW5nLmV4YW1wbGUuY29tMDIGCCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2x" + + "vY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEApILjYTMlQmIcmF3xNtsDb5WqGy" + + "tmEW+DhjMckiCrkPNDdF5TvsaSyU7PWMxVWNfiUxzXs9UH8D/SiXmc5081cy4eLL9LMMf/q" + + "FMQny29FSJf5HVKi5GxmKwJrY3jimS2qlbUR9AZ5mz6MC2pNaYup0GDlPmi/UDrr0/49616" + + "IpnHaOl90ytUjdv+uHxjMhv6cGrPiV3oW0XlH+J9XsJPOAA7W/nsPLUQCn/7scylI+bf1IK" + + "g7J01qucFHOSCSsKB0+NbEJzaj4NdsePlhlogLFgqUf4SmBxRq+62+CUxhDwCaVnL/VrWWA" + + "L8E+/GtsaR6eVzYJY9eiI1hLpLyblNVmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtul" + + "uqDAAAAAAAAAtcwggLTMIIBu6ADAgECAhQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG" + + "9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDA" + + "yMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1Rlc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDw" + + "AwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm" + + "24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP" + + "8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFth" + + "Vt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7Ly" + + "JvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NA" + + "gMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IB" + + "AQAgyCfLAcVs/MkERxunH9pZA4ja1QWWjsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR" + + "3/94IJeD45C3h/Y3+1HDyC6ZuzdgMXv63dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmL" + + "NeAhL7QA+Vf5fJmTsxEJwFaHo9JpKoQ469RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8Oal" + + "QICt0M0wx29B6HNof3px2NxKyC6qlf01wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+S" + + "Xo8SmD4YO6Wr4Q9drI3cCwVeQXwxoUuB96muQQ2M3WDiMz5ZLI3oMLu8KSPsAAA="; + + let serHelper = Cc["@mozilla.org/network/serialization-helper;1"].getService( + Ci.nsISerializationHelper + ); + // deserialize from the string and compare to the original object + let deserialized = serHelper.deserializeObject(serialized); + deserialized.QueryInterface(Ci.nsITransportSecurityInfo); + + equal( + deserialized.failedCertChain.length, + [], + "failedCertChain for a successful connection should be empty" + ); + let certChain = build_cert_list_from_pem_list([gDefaultEEPEM, gTestCAPEM]); + ok( + areCertArraysEqual(certChain, deserialized.succeededCertChain), + "succeededCertChain should be deserialized correctly" + ); +} + +// In Bug 1580315, nsNSSCertList/nsIX509CertList was replaced by +// Array, so the serialization of the certList changed. This +// test is used to make sure we can still deserialize the TransportSecurityInfo +// binary string which has the old certList binary. +function test_old_failed_certlist_deseralization_v1() { + // This was the serialized output of test "expired.example.com" + // in security/manager/ssl/tests/unit/test_cert_chains.js + // The serialized output was generated before we replace nsIX509CertList with + // Array, so it had the old version of transportSecurityInfo. + const serialized = + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAABAA" + + "AAAAAAAAA///gCwAAAAEAMQFmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAA" + + "AAAAMgMIIDHDCCAgSgAwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQELB" + + "QAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAwMDAwMFoYDzIwMTQwMTAxMDAw" + + "MDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvc" + + "NAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wc" + + "clqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk2" + + "7lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI" + + "H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wn" + + "vuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxD" + + "HVA6zaGAo17Y0CAwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJlZC5leGFtcGxlLmNvbTAyB" + + "ggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJ" + + "KoZIhvcNAQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzfT+ow5WV" + + "sxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7IAMO1CEr5FVdCOVTma5hmu/81rkJLmZ8RQ" + + "DWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3L9zJ2JqNc60+hB8l297Za" + + "Sl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74VkQyNobaFzDZ+Zr3QmfbejEsY2EYn" + + "q8XuENgIO4DuYrm80/p6bMO6laB0Uv5W6uXZgBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFw" + + "WwtnoK7IAAAAAAAEAAAEAAQAAAAAAAAAAAAAAAZWfsWVlF0h/q5vYkTvlMZeudM2lzS9HP5" + + "b18Lf/9ixoAAAAAmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAyAwg" + + "gMcMIICBKADAgECAhRj0REAgqPSOz9huEmgytwueP766jANBgkqhkiG9w0BAQsFADASMRAw" + + "DgYDVQQDDAdUZXN0IENBMCIYDzIwMTMwMTAxMDAwMDAwWhgPMjAxNDAxMDEwMDAwMDBaMCI" + + "xIDAeBgNVBAMMF0V4cGlyZWQgVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAA" + + "OCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngfv" + + "bGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO" + + "7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEP" + + "vJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naO" + + "Gzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYC" + + "jXtjQIDAQABo1YwVDAeBgNVHREEFzAVghNleHBpcmVkLmV4YW1wbGUuY29tMDIGCCsGAQUF" + + "BwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0" + + "BAQsFAAOCAQEAiaIW7LbvlPpv5R3qCX8SXqqmBYdRd5iK/aynt34dXN9P6jDlZWzEj8YwqF" + + "0DjclopP2B8yxuc/WqIjbN6XdT4XsgAw7UISvkVV0I5VOZrmGa7/zWuQkuZnxFANZY6FkrK" + + "f/toPtMfULV7vrzIK3kTYMOXyYeKX3NHwE+yhfC5Lcv3MnYmo1zrT6EHyXb3tlpKXSdsp99" + + "vju6S+fmRInu0j2f99Jd2PUmu6TCNk/7vhWRDI2htoXMNn5mvdCZ9t6MSxjYRierxe4Q2Ag" + + "7gO5iubzT+npsw7qVoHRS/lbq5dmAFl1FN7VYx1hYaGa+cUVCZ/6dp446XqvIXBbC2egrsm" + + "YKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAtcwggLTMIIBu6ADAgECA" + + "hQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0" + + "IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1R" + + "lc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBj" + + "YQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJ" + + "JwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw" + + "JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7f" + + "ilhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL" + + "8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wC" + + "wYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAgyCfLAcVs/MkERxunH9pZA4ja1QWW" + + "jsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR3/94IJeD45C3h/Y3+1HDyC6ZuzdgMXv6" + + "3dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmLNeAhL7QA+Vf5fJmTsxEJwFaHo9JpKoQ4" + + "69RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8OalQICt0M0wx29B6HNof3px2NxKyC6qlf01" + + "wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+SXo8SmD4YO6Wr4Q9drI3cCwVeQXwxoUuB" + + "96muQQ2M3WDiMz5ZLI3oMLu8KSPs"; + + let serHelper = Cc["@mozilla.org/network/serialization-helper;1"].getService( + Ci.nsISerializationHelper + ); + // Deserialize from the string and compare to the original object + let deserialized = serHelper.deserializeObject(serialized); + deserialized.QueryInterface(Ci.nsITransportSecurityInfo); + + equal( + deserialized.succeededCertChain.length, + 0, + "succeededCertChain should be empty" + ); + let certChain = build_cert_list_from_pem_list([gExpiredEEPEM, gTestCAPEM]); + ok( + areCertArraysEqual(certChain, deserialized.failedCertChain), + "failedCertChain should be deserialized correctly" + ); +} + +// Same as the above test, however, this is the v2 version of the +// serialization. +function test_old_failed_certlist_deseralization_v2() { + const serialized = + "FnhllAKWRHGAlo+ESXykKAAAAAAAAAAAwAAAAAAAAEaphjojH6pBabDSgSnsfLHeAAAABAA" + + "AAAAAAAAA///gCwAAAAEAMgFmCjImkVxP+7sgiYWmMt8FvcOXmlQiTNWFiWlrbpbqgwAAAA" + + "AAAAMgMIIDHDCCAgSgAwIBAgIUY9ERAIKj0js/YbhJoMrcLnj++uowDQYJKoZIhvcNAQELB" + + "QAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDEzMDEwMTAwMDAwMFoYDzIwMTQwMTAxMDAw" + + "MDAwWjAiMSAwHgYDVQQDDBdFeHBpcmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvc" + + "NAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wc" + + "clqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk2" + + "7lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI" + + "H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wn" + + "vuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxD" + + "HVA6zaGAo17Y0CAwEAAaNWMFQwHgYDVR0RBBcwFYITZXhwaXJlZC5leGFtcGxlLmNvbTAyB" + + "ggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9sb2NhbGhvc3Q6ODg4OC8wDQYJ" + + "KoZIhvcNAQELBQADggEBAImiFuy275T6b+Ud6gl/El6qpgWHUXeYiv2sp7d+HVzfT+ow5WV" + + "sxI/GMKhdA43JaKT9gfMsbnP1qiI2zel3U+F7IAMO1CEr5FVdCOVTma5hmu/81rkJLmZ8RQ" + + "DWWOhZKyn/7aD7TH1C1e768yCt5E2DDl8mHil9zR8BPsoXwuS3L9zJ2JqNc60+hB8l297Za" + + "Sl0nbKffb47ukvn5kSJ7tI9n/fSXdj1JrukwjZP+74VkQyNobaFzDZ+Zr3QmfbejEsY2EYn" + + "q8XuENgIO4DuYrm80/p6bMO6laB0Uv5W6uXZgBZdRTe1WMdYWGhmvnFFQmf+naeOOl6ryFw" + + "WwtnoK7IAAAAAAAEAAAEAAQAAAAAAAAAAAAAAAZWfsWVlF0h/q5vYkTvlMZeudM2lzS9HP5" + + "b18Lf/9ixoAAAAAmYKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAyAwg" + + "gMcMIICBKADAgECAhRj0REAgqPSOz9huEmgytwueP766jANBgkqhkiG9w0BAQsFADASMRAw" + + "DgYDVQQDDAdUZXN0IENBMCIYDzIwMTMwMTAxMDAwMDAwWhgPMjAxNDAxMDEwMDAwMDBaMCI" + + "xIDAeBgNVBAMMF0V4cGlyZWQgVGVzdCBFbmQtZW50aXR5MIIBIjANBgkqhkiG9w0BAQEFAA" + + "OCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngfv" + + "bGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO" + + "7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEP" + + "vJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naO" + + "Gzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYC" + + "jXtjQIDAQABo1YwVDAeBgNVHREEFzAVghNleHBpcmVkLmV4YW1wbGUuY29tMDIGCCsGAQUF" + + "BwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4LzANBgkqhkiG9w0" + + "BAQsFAAOCAQEAiaIW7LbvlPpv5R3qCX8SXqqmBYdRd5iK/aynt34dXN9P6jDlZWzEj8YwqF" + + "0DjclopP2B8yxuc/WqIjbN6XdT4XsgAw7UISvkVV0I5VOZrmGa7/zWuQkuZnxFANZY6FkrK" + + "f/toPtMfULV7vrzIK3kTYMOXyYeKX3NHwE+yhfC5Lcv3MnYmo1zrT6EHyXb3tlpKXSdsp99" + + "vju6S+fmRInu0j2f99Jd2PUmu6TCNk/7vhWRDI2htoXMNn5mvdCZ9t6MSxjYRierxe4Q2Ag" + + "7gO5iubzT+npsw7qVoHRS/lbq5dmAFl1FN7VYx1hYaGa+cUVCZ/6dp446XqvIXBbC2egrsm" + + "YKMiaRXE/7uyCJhaYy3wW9w5eaVCJM1YWJaWtuluqDAAAAAAAAAtcwggLTMIIBu6ADAgECA" + + "hQpoXAjALAddSApG46EBfimNiyZuDANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0" + + "IENBMCIYDzIwMTcxMTI3MDAwMDAwWhgPMjAyMDAyMDUwMDAwMDBaMBIxEDAOBgNVBAMMB1R" + + "lc3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBj" + + "YQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJ" + + "JwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw" + + "JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7f" + + "ilhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL" + + "8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wC" + + "wYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAgyCfLAcVs/MkERxunH9pZA4ja1QWW" + + "jsxSg9KgAIfOgj8c5RPHbl4oeWk0raNKWMu5+FR3/94IJeD45C3h/Y3+1HDyC6ZuzdgMXv6" + + "3dk0a36JDFlPA3swqwYhnL7pHnbdcfDyWnMVfmLNeAhL7QA+Vf5fJmTsxEJwFaHo9JpKoQ4" + + "69RdWno6aHeK3TfiQFaebzT1MRabCJXDeyw8OalQICt0M0wx29B6HNof3px2NxKyC6qlf01" + + "wwNSaaIbsctDaLL5ZLN6T1LjpJsooMvDwRt69+SXo8SmD4YO6Wr4Q9drI3cCwVeQXwxoUuB" + + "96muQQ2M3WDiMz5ZLI3oMLu8KSPsAA=="; + + let serHelper = Cc["@mozilla.org/network/serialization-helper;1"].getService( + Ci.nsISerializationHelper + ); + // Deserialize from the string and compare to the original object + let deserialized = serHelper.deserializeObject(serialized); + deserialized.QueryInterface(Ci.nsITransportSecurityInfo); + + let certChain = build_cert_list_from_pem_list([gExpiredEEPEM, gTestCAPEM]); + ok( + areCertArraysEqual(certChain, deserialized.failedCertChain), + "failedCertChain should be deserialized correctly" + ); +} +function run_test() { + do_get_profile(); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + // Test nsIX509Cert.equals + add_test(function() { + test_cert_equals(); + run_next_test(); + }); + + add_test(function() { + test_cert_pkcs7_export(); + run_next_test(); + }); + + add_test(function() { + test_cert_pkcs7_empty_array(); + run_next_test(); + }); + + add_test(function() { + test_old_succeeded_certlist_deseralization_v2(); + run_next_test(); + }); + + add_test(function() { + test_old_failed_certlist_deseralization_v2(); + run_next_test(); + }); + + add_test(function() { + test_old_succeeded_certlist_deseralization_v1(); + run_next_test(); + }); + + add_test(function() { + test_old_failed_certlist_deseralization_v1(); + run_next_test(); + }); + + // Test successful connection (failedCertChain should be null) + add_connection_test( + // re-use pinning certs (keeler) + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess, + null, + function withSecurityInfo(aTransportSecurityInfo) { + aTransportSecurityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + test_security_info_serialization(aTransportSecurityInfo, 0); + equal( + aTransportSecurityInfo.failedCertChain.length, + 0, + "failedCertChain for a successful connection should be null" + ); + } + ); + + // Test overrideable connection failure (failedCertChain should be non-null) + add_connection_test( + "expired.example.com", + SEC_ERROR_EXPIRED_CERTIFICATE, + null, + function withSecurityInfo(securityInfo) { + securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + test_security_info_serialization( + securityInfo, + SEC_ERROR_EXPIRED_CERTIFICATE + ); + notEqual( + securityInfo.failedCertChain, + null, + "failedCertChain should not be null for an overrideable" + + " connection failure" + ); + let originalCertChain = build_cert_chain(["expired-ee", "test-ca"]); + ok( + areCertArraysEqual(originalCertChain, securityInfo.failedCertChain), + "failedCertChain should equal the original cert chain for an" + + " overrideable connection failure" + ); + } + ); + + // Test overrideable connection failure (failedCertChain should be non-null) + add_connection_test( + "unknownissuer.example.com", + SEC_ERROR_UNKNOWN_ISSUER, + null, + function withSecurityInfo(securityInfo) { + securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + test_security_info_serialization(securityInfo, SEC_ERROR_UNKNOWN_ISSUER); + notEqual( + securityInfo.failedCertChain, + null, + "failedCertChain should not be null for an overrideable" + + " connection failure" + ); + let originalCertChain = build_cert_chain(["unknownissuer"]); + ok( + areCertArraysEqual(originalCertChain, securityInfo.failedCertChain), + "failedCertChain should equal the original cert chain for an" + + " overrideable connection failure" + ); + } + ); + + // Test non-overrideable error (failedCertChain should be non-null) + add_connection_test( + "inadequatekeyusage.example.com", + SEC_ERROR_INADEQUATE_KEY_USAGE, + null, + function withSecurityInfo(securityInfo) { + securityInfo.QueryInterface(Ci.nsITransportSecurityInfo); + test_security_info_serialization( + securityInfo, + SEC_ERROR_INADEQUATE_KEY_USAGE + ); + notEqual( + securityInfo.failedCertChain, + null, + "failedCertChain should not be null for a non-overrideable" + + " connection failure" + ); + let originalCertChain = build_cert_chain([ + "inadequatekeyusage-ee", + "test-ca", + ]); + ok( + areCertArraysEqual(originalCertChain, securityInfo.failedCertChain), + "failedCertChain should equal the original cert chain for a" + + " non-overrideable connection failure" + ); + } + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_cert_dbKey.js b/security/manager/ssl/tests/unit/test_cert_dbKey.js new file mode 100644 index 0000000000..a45b638b8f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_dbKey.js @@ -0,0 +1,263 @@ +// -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// 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/. + +"use strict"; + +// This test tests that the nsIX509Cert.dbKey and nsIX509CertDB.findCertByDBKey +// APIs work as expected. That is, getting a certificate's dbKey and using it +// in findCertByDBKey should return the same certificate. Also, for backwards +// compatibility, findCertByDBKey should ignore any whitespace in its input +// (even though now nsIX509Cert.dbKey will never have whitespace in it). + +function hexStringToBytes(hex) { + let bytes = []; + for (let hexByteStr of hex.split(":")) { + bytes.push(parseInt(hexByteStr, 16)); + } + return bytes; +} + +function encodeCommonNameAsBytes(commonName) { + // The encoding will look something like this (in hex): + // 30 (SEQUENCE) + // 31 (SET) + // 30 (SEQUENCE) + // 06 (OID) 03 (length) + // 55 04 03 (id-at-commonName) + // 0C (UTF8String) + // + // To make things simple, it would be nice to have the length of each + // component be less than 128 bytes (so we can have single-byte lengths). + // For this to hold, the maximum length of the contents of the outermost + // SEQUENCE must be 127. Everything not in the contents of the common name + // will take up 11 bytes, so the value of the common name itself can be at + // most 116 bytes. + ok( + commonName.length <= 116, + "test assumption: common name can't be longer than 116 bytes (makes " + + "DER encoding easier)" + ); + let commonNameOIDBytes = [0x06, 0x03, 0x55, 0x04, 0x03]; + let commonNameBytes = [0x0c, commonName.length]; + for (let i = 0; i < commonName.length; i++) { + commonNameBytes.push(commonName.charCodeAt(i)); + } + let bytes = commonNameOIDBytes.concat(commonNameBytes); + bytes.unshift(bytes.length); + bytes.unshift(0x30); // SEQUENCE + bytes.unshift(bytes.length); + bytes.unshift(0x31); // SET + bytes.unshift(bytes.length); + bytes.unshift(0x30); // SEQUENCE + return bytes; +} + +function testInvalidDBKey(certDB, dbKey) { + throws( + () => certDB.findCertByDBKey(dbKey), + /NS_ERROR_ILLEGAL_INPUT/, + `findCertByDBKey(${dbKey}) should raise NS_ERROR_ILLEGAL_INPUT` + ); +} + +function testDBKeyForNonexistentCert(certDB, dbKey) { + let cert = certDB.findCertByDBKey(dbKey); + ok(!cert, "shouldn't find cert for given dbKey"); +} + +function byteArrayToByteString(bytes) { + let byteString = ""; + for (let b of bytes) { + byteString += String.fromCharCode(b); + } + return byteString; +} + +function run_test() { + do_get_profile(); + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let cert = constructCertFromFile("bad_certs/test-ca.pem"); + equal( + cert.issuerName, + "CN=" + cert.issuerCommonName, + "test assumption: this certificate's issuer distinguished name " + + "consists only of a common name" + ); + let issuerBytes = encodeCommonNameAsBytes(cert.issuerCommonName); + ok( + issuerBytes.length < 256, + "test assumption: length of encoded issuer is less than 256 bytes" + ); + let serialNumberBytes = hexStringToBytes(cert.serialNumber); + ok( + serialNumberBytes.length < 256, + "test assumption: length of encoded serial number is less than 256 bytes" + ); + let dbKeyHeader = [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + serialNumberBytes.length, + 0, + 0, + 0, + issuerBytes.length, + ]; + let expectedDbKeyBytes = dbKeyHeader.concat(serialNumberBytes, issuerBytes); + let expectedDbKey = btoa(byteArrayToByteString(expectedDbKeyBytes)); + equal( + cert.dbKey, + expectedDbKey, + "actual and expected dbKey values should match" + ); + + let certFromDbKey = certDB.findCertByDBKey(expectedDbKey); + ok( + certFromDbKey.equals(cert), + "nsIX509CertDB.findCertByDBKey should find the right certificate" + ); + + ok( + expectedDbKey.length > 64, + "test assumption: dbKey should be longer than 64 characters" + ); + let expectedDbKeyWithCRLF = expectedDbKey.replace(/(.{64})/, "$1\r\n"); + ok( + expectedDbKeyWithCRLF.indexOf("\r\n") == 64, + "test self-check: adding CRLF to dbKey should succeed" + ); + certFromDbKey = certDB.findCertByDBKey(expectedDbKeyWithCRLF); + ok( + certFromDbKey.equals(cert), + "nsIX509CertDB.findCertByDBKey should work with dbKey with CRLF" + ); + + let expectedDbKeyWithSpaces = expectedDbKey.replace(/(.{64})/, "$1 "); + ok( + expectedDbKeyWithSpaces.indexOf(" ") == 64, + "test self-check: adding spaces to dbKey should succeed" + ); + certFromDbKey = certDB.findCertByDBKey(expectedDbKeyWithSpaces); + ok( + certFromDbKey.equals(cert), + "nsIX509CertDB.findCertByDBKey should work with dbKey with spaces" + ); + + // Test some invalid dbKey values. + testInvalidDBKey(certDB, "AAAA"); // Not long enough. + // No header. + testInvalidDBKey( + certDB, + btoa( + byteArrayToByteString( + [0, 0, 0, serialNumberBytes.length, 0, 0, 0, issuerBytes.length].concat( + serialNumberBytes, + issuerBytes + ) + ) + ) + ); + testInvalidDBKey( + certDB, + btoa( + byteArrayToByteString([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 255, + 255, + 255, + 255, // serial number length is way too long + 255, + 255, + 255, + 255, // issuer length is way too long + 0, + 0, + 0, + 0, + ]) + ) + ); + // Truncated issuer. + testInvalidDBKey( + certDB, + btoa( + byteArrayToByteString([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 10, + 1, + 1, + 2, + 3, + ]) + ) + ); + // Issuer doesn't decode to valid common name. + testDBKeyForNonexistentCert( + certDB, + btoa( + byteArrayToByteString([ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 3, + 1, + 1, + 2, + 3, + ]) + ) + ); + + // zero-length serial number and issuer -> no such certificate + testDBKeyForNonexistentCert( + certDB, + btoa( + byteArrayToByteString([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + ) + ); +} diff --git a/security/manager/ssl/tests/unit/test_cert_eku.js b/security/manager/ssl/tests/unit/test_cert_eku.js new file mode 100644 index 0000000000..d185407243 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku.js @@ -0,0 +1,189 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +// Tests that the extended key usage extension is properly processed by the +// platform when verifying certificates. There are already comprehensive tests +// in mozilla::pkix itself, but these tests serve as integration tests to ensure +// that the cases we're particularly concerned about are correctly handled. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function certFromFile(certName) { + return constructCertFromFile(`test_cert_eku/${certName}.pem`); +} + +function loadCertWithTrust(certName, trustString) { + addCertFromFile(certdb, `test_cert_eku/${certName}.pem`, trustString); +} + +function checkEndEntity(cert, expectedResult) { + return checkCertErrorGeneric( + certdb, + cert, + expectedResult, + certificateUsageSSLServer + ); +} + +function checkCertOn25August2016(cert, expectedResult) { + // (new Date("2016-08-25T00:00:00Z")).getTime() / 1000 + const VALIDATION_TIME = 1472083200; + return checkCertErrorGenericAtTime( + certdb, + cert, + expectedResult, + certificateUsageSSLServer, + VALIDATION_TIME + ); +} + +add_task(async function() { + registerCleanupFunction(() => { + Services.prefs.clearUserPref("privacy.reduceTimerPrecision"); + }); + Services.prefs.setBoolPref("privacy.reduceTimerPrecision", false); + + loadCertWithTrust("ca", "CTu,,"); + // end-entity has id-kp-serverAuth => success + await checkEndEntity(certFromFile("ee-SA"), PRErrorCodeSuccess); + // end-entity has id-kp-serverAuth => success + await checkEndEntity(certFromFile("ee-SA-CA"), PRErrorCodeSuccess); + // end-entity has extended key usage, but id-kp-serverAuth is not present => + // failure + await checkEndEntity(certFromFile("ee-CA"), SEC_ERROR_INADEQUATE_CERT_TYPE); + // end-entity has id-kp-serverAuth => success + await checkEndEntity(certFromFile("ee-SA-nsSGC"), PRErrorCodeSuccess); + + // end-entity has extended key usage, but id-kp-serverAuth is not present => + // failure (in particular, Netscape Server Gated Crypto (also known as + // Netscape Step Up) is not an acceptable substitute for end-entity + // certificates). + // Verify this for all Netscape Step Up policy configurations. + // 0 = "always accept nsSGC in place of serverAuth for CA certificates" + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 0); + await checkEndEntity( + certFromFile("ee-nsSGC"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + // 1 = "accept nsSGC before 23 August 2016" + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 1); + await checkEndEntity( + certFromFile("ee-nsSGC"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + // 2 = "accept nsSGC before 23 August 2015" + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 2); + await checkEndEntity( + certFromFile("ee-nsSGC"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + // 3 = "never accept nsSGC" + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 3); + await checkEndEntity( + certFromFile("ee-nsSGC"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + + // end-entity has id-kp-OCSPSigning, which is not acceptable for end-entity + // certificates being verified as TLS server certificates => failure + await checkEndEntity( + certFromFile("ee-SA-OCSP"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + + // intermediate has id-kp-serverAuth => success + loadCertWithTrust("int-SA", ",,"); + await checkEndEntity(certFromFile("ee-int-SA"), PRErrorCodeSuccess); + // intermediate has id-kp-serverAuth => success + loadCertWithTrust("int-SA-CA", ",,"); + await checkEndEntity(certFromFile("ee-int-SA-CA"), PRErrorCodeSuccess); + // intermediate has extended key usage, but id-kp-serverAuth is not present + // => failure + loadCertWithTrust("int-CA", ",,"); + await checkEndEntity( + certFromFile("ee-int-CA"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + // intermediate has id-kp-serverAuth => success + loadCertWithTrust("int-SA-nsSGC", ",,"); + await checkEndEntity(certFromFile("ee-int-SA-nsSGC"), PRErrorCodeSuccess); + + // Intermediate has Netscape Server Gated Crypto. Success will depend on the + // Netscape Step Up policy configuration and the notBefore property of the + // intermediate. + loadCertWithTrust("int-nsSGC-recent", ",,"); + loadCertWithTrust("int-nsSGC-old", ",,"); + loadCertWithTrust("int-nsSGC-older", ",,"); + // 0 = "always accept nsSGC in place of serverAuth for CA certificates" + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 0); + info("Netscape Step Up policy: always accept"); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-recent"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-older"), + PRErrorCodeSuccess + ); + // 1 = "accept nsSGC before 23 August 2016" + info("Netscape Step Up policy: accept before 23 August 2016"); + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 1); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-recent"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-old"), + PRErrorCodeSuccess + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-older"), + PRErrorCodeSuccess + ); + // 2 = "accept nsSGC before 23 August 2015" + info("Netscape Step Up policy: accept before 23 August 2015"); + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 2); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-recent"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-old"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-older"), + PRErrorCodeSuccess + ); + // 3 = "never accept nsSGC" + info("Netscape Step Up policy: never accept"); + Services.prefs.setIntPref("security.pki.netscape_step_up_policy", 3); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-recent"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-old"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + await checkCertOn25August2016( + certFromFile("ee-int-nsSGC-older"), + SEC_ERROR_INADEQUATE_CERT_TYPE + ); + + // intermediate has id-kp-OCSPSigning, which is acceptable for CA + // certificates => success + loadCertWithTrust("int-SA-OCSP", ",,"); + await checkEndEntity(certFromFile("ee-int-SA-OCSP"), PRErrorCodeSuccess); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ca.pem b/security/manager/ssl/tests/unit/test_cert_eku/ca.pem new file mode 100644 index 0000000000..790e942fbd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvDCCAaSgAwIBAgIUbYeck7JVOWdVm1AGwsw/DzdRnaYwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNTAxMDEwMDAwMDBaGA8yMDM1MDEwMTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggEBAI0AO+ZBY1oImSrpifcmQZTE/C4xIu7Uu5GX/A7ApQU7 +8UAXivMgRDbtrjOie1HNH9DIxHBCFY/Y7f0VRXxWmPEmT+5LpHrLoi+YF0h2wh/1 +RuiJV1AfaEdVJyNCVDSQrS8BQG5O3LebBq00gjSJSQ4+DHu7YHWkyMIZk+lbBiO1 +GsD0FWBDlOtiMpL/CQWjyiskiqQjrDCs5m0NayqgzYAMtdlEd+pAKEMNO8Fr8xSI +tAlcG4frvH0kLJ2scX9ayvKTZrAiAxJz9CjmmnXOyL78yyr/hkJbzYTvk0+1cClg +J2aGnsFIHgUxEx7sApOqlmG8g1lqL7UPqpi8ItVNl48= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ca.pem.certspec new file mode 100644 index 0000000000..c6e443f5d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +validity:20150101-20350101 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem new file mode 100644 index 0000000000..b947abe69f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUC5X2jRE2ClirTUZa/5o/butQdrgwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEDEOMAwGA1UEAwwFZWUtQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsG +AQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQCaHEnFif4rqZGKOtXrnXTCvFvkxr7i +hBU/zInfRn+9Q1+k4/yyjdThNNLCuTVu3sMlWjIbZGvF/iudIN/m2ZkT4qOmi+LX +fy7a+QEEFLPZy+CCAQ3KHX2p+LEf9rnuUVOiqub9/lxD/KJOBV6SOwVGU+D7bxq4 +/+Y1mVFpxlGqQgHgSroZCPDAquRVYJC43x+lrlPNnX5fOetd3ipbZDcEdLf6Vy1A +RsWVyFgJhVR8Uw267iI9/j9rIbChLY4aQNxTmH6/Knz+KYussltkcotgEu5YAQSs +y7VL3y2JzlLQaq/0WorvkjHjZ8F4eILSS1fGAHrK6HT1eJsDxJzYVayO +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem.certspec new file mode 100644 index 0000000000..d49cabaa2f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-CA.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-CA +extension:extKeyUsage:clientAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem new file mode 100644 index 0000000000..a9fc97c5b0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUFZM7fDUSi2PQ/ZLQ1JsWSrDyX7kwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEzERMA8GA1UEAwwIZWUtU0EtQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjITAfMB0GA1UdJQQWMBQG +CCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAd6LFItpHZW0s +kKR7utmFTcQmuSXg6OJF7DSbF0bJkVfE9L0ZrYc4ATp3M9zTxlZAVKJIFX8RPMp4 +tNPQrfsa3jQGWzRdIv6dtsHau3EUVrNQwdsErtko3LUr/W6anHy9VTOJuXWQ//qf +eBiZHOfxf2WAZCjDcOP8k6/rttbrpka0Y1VjPzNNXJR83lLk0ADxt2R9R6/PYsq1 +uxuYbBbkmB3vlLrfpYw3yCEXkaAByTCvCALaEXzC9vS1gDxhPvucS122A9GdCe8j +8wkHMNFpfeCafqTypD6KDS/6yl+GEiB1ErHM2pkwn9oromh9R9M1ILkBtICy+w/W +4FqGVfffaQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem.certspec new file mode 100644 index 0000000000..5250cc4a84 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-CA.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-SA-CA +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem new file mode 100644 index 0000000000..de6b780718 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1TCCAb2gAwIBAgIUO/5lR94sxaHEzsErl8RFZ8quniAwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFTETMBEGA1UEAwwKZWUtU0EtT0NTUDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMhMB8wHQYDVR0lBBYw +FAYIKwYBBQUHAwEGCCsGAQUFBwMJMA0GCSqGSIb3DQEBCwUAA4IBAQB+jNOQ3Nti +BB0Vi9y2+E/TMcrR+A0YNJpGQfxbH2bPs1RONwq+b8/RXzTb5OXkh02gb94inOn6 +E8uvxwZeFNp6hRdJWrUMP/Fw0H5zn7F/X7h9yRGDV3aICULFK9G/c26jgiQY4+P8 +j61EnAaEI68KDXZ/QFSrH/nxlb+xOl+MZQfnD4jEbyGWknL6RX2uhOuc3c6mzaEI +FkKRXtLuAnGaaBwnjPenNKO7wPKaaF5wo1JcO5uZqaEI/hkw3WXUF25HBhq8ntx4 +VYKQaKQwzwLvptLDxUsf4nhbyQYNSxUJq/L2hnZDuiLFQzWiK4cFnOiBeojZDoq4 +gVp7BdWxFL7A +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem.certspec new file mode 100644 index 0000000000..3b3eff9ae4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-OCSP.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-SA-OCSP +extension:extKeyUsage:serverAuth,OCSPSigning diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem new file mode 100644 index 0000000000..70f5bd54b4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1zCCAb+gAwIBAgIUD6t9UhitEOD4JaK87FphFLXfkgowDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLZWUtU0EtbnNTR0MwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjIjAgMB4GA1UdJQQX +MBUGCCsGAQUFBwMBBglghkgBhvhCBAEwDQYJKoZIhvcNAQELBQADggEBAIveO3ip +QuHtl08d57tWw4yCLEvkm00QHiW45hvkB7sAc/yc5oQ6Ctas8kFeiQlFov0oc855 +H/m1/+q69AhjloTCRP56ETxQD8XOYpJ65Z+h7xLJ0ePb16KzFdP4D/RrrP88Q+IW +P8y80sk79ZYFpXw/pQVWmeYlZ/2B+0lRG2Qr14Y87oJq58e2v3D8JVTYIaqvcUUV +KL+vvz2VD2oIRVcHkPKRDziC71au/uGZNpaRFiJLrqMXp5tbSTnTfvEU8UQNvWsD +up7hx5Sjnm1hih9NxNNYC0JqjqAe09fPLuKEpmhkMs+cQBhQkgGum82WOu/BVgTA +bOzdhBReGuu6di4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem.certspec new file mode 100644 index 0000000000..4c51425ce7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA-nsSGC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-SA-nsSGC +extension:extKeyUsage:serverAuth,nsSGC diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem new file mode 100644 index 0000000000..72fdae0143 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUO1FsmRgdyx0D0iMZXEesXr+RpxswDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEDEOMAwGA1UEAwwFZWUtU0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsG +AQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQBHY3Yp7JCSy1kJOdflxPplNuPlU5i/ +WTQbM3LKjibHKefWe22GAKIArymZWtE5/1OLUOyicB2bd4AdLA2dflTN2kZ0isVd +K4Gk5z7o+i3rSULI5DeAhlAHPDMP9+NV1os+j/c5eK+CKAaWEJtcH+khDeb6kH83 +1IQDAgvYOpXrZTnoC+dKc/9esdmAzEWeP05F5PgfFCTAjKX2voMmnJOjGtSoV/UM +76RHmB3Z4tLeJ85eXU2k6E+RwMrb6JLZe+xfeInN3EE/g4dfnh+/KAHhgLl7MTyn +GRIlTXisaOYe27wGK4/O9vuvoaQu4A5QrZcUp9lFv7cD1Fz1E8zBC8oY +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem.certspec new file mode 100644 index 0000000000..690f579afa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-SA.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-SA +extension:extKeyUsage:serverAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem new file mode 100644 index 0000000000..cc1e10404d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAZ2gAwIBAgIUZaXG7JEsTaOaPw87/nUy+/eUmqYwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBQxEjAQBgNVBAMMCWVlLWludC1DQTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7 +wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp +k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh +eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW +EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc +JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAigF8fmjv72/13vJXo6IeNjrY7B7Vo4ojlCP+3MjGBCgCXy1Bm34p +X8t4DcJMZ9e4QPkGpA30jl/TymxaFUA/Hr2zezdJ+uU66qPWzzsiQCYZVXpkHgDL +yd2MpiQZeIoX7t71BdxZbikajedXutn36U/ZIehZcSeNeaz/Fd8MqABVcvvjuTsn +0Lbt8eubJml/x6WtQbDjPspI25oQwbQz3stXOGv4uBfuALKzO9AtlAXWpS/JFhhs +4rqa8VEqHKGtP8fSieSsqhy4R98gR/PfYS/XvnRo71U+/m2iGxMizz7/FIuO13X+ +Xq1+S2fKey7Z3ZbA8+zdfHwlZpBydKAkMA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem.certspec new file mode 100644 index 0000000000..670973930d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-CA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-CA +subject:ee-int-CA diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem new file mode 100644 index 0000000000..759812ff9f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuzCCAaOgAwIBAgIUY8AAXoT/5+XKoZB/qHd8n2QKXn0wDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJaW50LVNBLUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAy +MjAyMDUwMDAwMDBaMBcxFTATBgNVBAMMDGVlLWludC1TQS1DQTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs +9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8 +HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7Ak +kqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJet +lmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2r +kQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkq +hkiG9w0BAQsFAAOCAQEAongard/cqAypTPlDgt8nFQQxFkNgZ0L0izzNhbZ2VuYM +8+gxKgT76VhixF5fM4aojpTKpvfBjMMVfBeYc9zLjad4jIvroYEzRTuOVeHhsVyf +sre2adRS1Z1rj45x5G4N6KriZimKJGgaZeBeTNA4rVO6Tf9mUzllaHG9e3VhPXCR +Pzqhb29lpdIkqn3TZR+RU/gRHLgk5uAL5d3izvI2xmH16zWdtEULjPA6fATiLPDi +36dmkUFNBQBQ74xZBBmj98R0FpVGCEPj3yX8/hjYT4R2ixhLLZXrybLwSbVD7MVq +GOnF+ezXULHmbUkNUO1expuWLFnrOTqsNMFOse453A== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem.certspec new file mode 100644 index 0000000000..bd012ab712 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-CA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-SA-CA +subject:ee-int-SA-CA diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem new file mode 100644 index 0000000000..0b442fb3ce --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvzCCAaegAwIBAgIUG6TTZ+C/RpJ/4TcDy/SngGYRzAkwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLaW50LVNBLU9DU1AwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowGTEXMBUGA1UEAwwOZWUtaW50LVNBLU9DU1AwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk +NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC +fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m +CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM +HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m +1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEw +DQYJKoZIhvcNAQELBQADggEBAFPckRG2h/ZdBJmtCRQ0sLB76hwRRHxm6WMyCzUM +V5kOmpgcIRIlbSJmYCVBzgcmVgT0q/6eK6qg+vCnrhBthv+lx+ZI42x0QEatyL0X +FTqwEe5x0nnw6wqhDuFBQ5KGOyGfb5fRk3cT7m6Fya00X/87uPs/HuoYBJsnschJ +2zCyP3yGQRiiQ8moBvQZvJBJ1wwlNPduMLF9WhQRxW6ijxZGiNctHmZU452ol+3/ +jOK2N7FvkK19f+fzMa0y1bWE8M68fIIIylWEpiYSrzCO04nf6TD6HK2Ss25qCoKS +dzowS1bL9TdUmwbCXnL/CyXSDWHMaAhNWD/DEwL6t3altBc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem.certspec new file mode 100644 index 0000000000..2374d248f6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-OCSP.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-SA-OCSP +subject:ee-int-SA-OCSP diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem new file mode 100644 index 0000000000..ed4d21e745 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwTCCAamgAwIBAgIUQ+NMzLj5C9j8fDWZOGMQ0w7huRcwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LVNBLW5zU0dDMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD2VlLWludC1TQS1uc1NHQzCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +ATANBgkqhkiG9w0BAQsFAAOCAQEAMQ6PCkVUC9IQH/ZQippzUv5UWQo+YagnX13p +10m5+Qt4OT/qxaj1hKbSnZrgZfphDoQ/8DKmHKFuRH8sCNXloc1XNrgXDb959BH8 +1R/BreULnXn7avmSycVTW06XuctRfozB15YjG9V6EUQgPOyzWeK7qmtJWJSxlsMw +JxRtbD8M+UOXHO8mmneRjz0N7kzEEOhr97sr/XCbcRuc81PU9n8X3gqITEyvBRld +MqXNuVF/cvN8DJG9A7gKQ6NWlpks2k2U2k93je5lsofLmdQFQjc8AQ63aW8i9Fa8 +kBOWlHNVMK838BSR8DPT05Pc6f6kAT9biLMx8Z7z3/5AmbJXlQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem.certspec new file mode 100644 index 0000000000..6c3cb64730 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA-nsSGC.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-SA-nsSGC +subject:ee-int-SA-nsSGC diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem new file mode 100644 index 0000000000..31833bde84 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAZ2gAwIBAgIUWSf0ySmH86e0yX7mdf5oq7s682cwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LVNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBQxEjAQBgNVBAMMCWVlLWludC1TQTCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7 +wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp +k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh +eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW +EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc +JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAfaFAdO8ATfh6LHVfh/R9TVdi+khwSItsGLXJO3XEJd5luGSb2bkH +HM+9TWZmBC/LHhtnm5RDcQ9qSPSDoj7KRHPXccN0mLjTwr/nMnZaqG8P/khxsb1V +8vQvHVz3XrNXbothv8TCidYPSain7Zr3j8iB8bArzwOL5gf0z7xyDtpnsRMkTd48 +/cOhY+YA5vx+mNE7NUVUSMk1jtfg7Q8FVSGVOzZlRFoZ7IxlDN7nt2fTepPjuYDM +NTiJ1qLwkve2mig0ZPzov4eTH+i/gkFC08Kqc9IKI14VmFT72Lxu6pDTAeO4bEQm +Jm5i9Z4ffgJmbL8nUC4IDTOau4eGoTjhig== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem.certspec new file mode 100644 index 0000000000..72ddb78dfd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-SA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-SA +subject:ee-int-SA diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem new file mode 100644 index 0000000000..8e8d4c2c04 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwzCCAaugAwIBAgIUB/nCi+kTmIkobMVqQFtJnevhGwEwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNaW50LW5zU0dDLW9sZDAiGA8yMDE2MDcyNDAwMDAwMFoY +DzIwMTYwOTI0MDAwMDAwWjAbMRkwFwYDVQQDDBBlZS1pbnQtbnNTR0Mtb2xkMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08 +E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc +1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP +DY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQ +gAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV +YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID +AQABMA0GCSqGSIb3DQEBCwUAA4IBAQBcxzg5hx9tQ57Jv3wibAhPktjmqapB2suH +eGE253Xn5haGq+0E3Qkmn7oF1ou6QyLvP+qbElhkx7+eEvhMhzRZFU8XmxzHRqbb +dZ0/MQw+aLEOc4Utl+1n3pDbVhBjoG3yVxyErndHfyXg+hNPMBEPvtfMYnSkKHX1 +3w3pJSs8HtUNMG3jecwXOJic0kUu6V5npNC0KTeZq4OOzp48WCpEfsQ6W5MzR4PN +mrCVU2t1GzCKRNA8E8a9unOcxnukz8FaY9RCkeW3cTwRNt0VaFprX32d1C4mz5rV +vNz/TGA0jy2b4Mg/dpGXrxqyRy1mG3zfs7sDhEoCxLsd/7ytu/bs +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem.certspec new file mode 100644 index 0000000000..a21b49b783 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-old.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-nsSGC-old +subject:ee-int-nsSGC-old +validity:20160724-20160924 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem new file mode 100644 index 0000000000..4acdf7b59d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxzCCAa+gAwIBAgIUYfx/2lyIWKMRlK/zS6/kmkp+t/MwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPaW50LW5zU0dDLW9sZGVyMCIYDzIwMTUwNzI0MDAwMDAw +WhgPMjAxNjA5MjQwMDAwMDBaMB0xGzAZBgNVBAMMEmVlLWludC1uc1NHQy1vbGRl +cjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAbCqK5OcHMj28V1PKiL4CHeN2oTCj +pObUJrAUqsHJbqS2Q+huzzoSsL+yT4uKeiuDMZnKOm8OIZMtM7M4zQb6b5H1Wqm+ +fM5384kUubmSG+CzUd4adK8NjSwgYhgdvAecbzhPS1GUlai9qDJU+elQVIrNZCL4 +6B634koCQkarYybibdXgoum9zzcla0TRXe9rHjb8VYe+BH7tLAnWGpUqw4x36Buz +gv605ApVb+QDAB9NH4/EZ1TXuKby6I9I19EkfADHL5XUKHGFH2EE+6Fsqihgu3QG +NRYMU2GL79bZcwOm2t2v+ZB2fp+UlEs8nykWY7PgwbJ+ObgSauNHhKi5DA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem.certspec new file mode 100644 index 0000000000..93e1831a32 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-older.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-nsSGC-older +subject:ee-int-nsSGC-older +validity:20150724-20160924 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem new file mode 100644 index 0000000000..557c8276e8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUE/PT07mikR8SeEYcqdLT8IL5vMIwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LW5zU0dDLXJlY2VudDAiGA8yMDE2MDgyNDAwMDAw +MFoYDzIwMTcwODI0MDAwMDAwWjAeMRwwGgYDVQQDDBNlZS1pbnQtbnNTR0MtcmVj +ZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62 +iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql +WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosq +Qe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ +ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8i +b2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoY +CjXtjQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAKnYtenyuUSykB8EP4IkEeeVPo +PeZpLKEHHr9CnjIC8b0lHhTsFQhIiNsCWt8xh+JS273QJi/A2rdo1M4KiMZyURne +RZvTBpFu5F8E+VixDP9xmpAffrgqPqgNRyN+co7tUQZgsJHhb8LSKKMHQTMTBOgW +nrVlMR+MwXBBQx7Yc7KkVob8DMWmIAAXlv0JY6ID2lRb4haBVS1gsPIj24mVF8XG +dRJIgtVUvey49/PvErG6FNA32QPDCyv9UOkX9mtpnu9dT+v6mAkbRcSDYAsTTWh2 +seog8fOBA8WoqO+EtTIY2VLiO2G8pTp8MftYVc1Mhd5Kh/ZT+PtdngloPnDM +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem.certspec new file mode 100644 index 0000000000..4a3ad8ec05 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-int-nsSGC-recent.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-nsSGC-recent +subject:ee-int-nsSGC-recent +validity:20160824-20170824 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem b/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem new file mode 100644 index 0000000000..46f729df5c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyjCCAbKgAwIBAgIUOcdHr2fMC/woQI+w/G6U646FIE0wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowEzERMA8GA1UEAwwIZWUtbnNTR0MwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjGDAWMBQGA1UdJQQNMAsG +CWCGSAGG+EIEATANBgkqhkiG9w0BAQsFAAOCAQEATjPFb+Y7HWDeWq02niJ4Puxu +T68/Q/P1M9BCeLMCaZAybxCJ1FDR/aOGfZMF8TQlx77wYz63j5s4BVjM1gLwl59w +EQK1xaav37Jt5IxfTFVBkJovOnDZFkDa3s+ebZfFpXl5pUFCZc8XOzkV/dy5mbE+ +baYZUikhVIDrvRmWcbXwzhEJhl5qfzgFkiWP9vA0vkVt3NAMuPclh/6L9844d4TN +uVo0C6X6I9jK3X7x2skLk00RT1MeigOE9o6Xuu0SYujDOXBAeOcjCE3mFJZQUr71 +FkD3Exrxo/UjbgIpLdBNLp2TEDR5bbwUIkk6bZy37vDa2xYCxe+Ret3ykpxshw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem.certspec new file mode 100644 index 0000000000..43d58ab6d4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/ee-nsSGC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-nsSGC +extension:extKeyUsage:nsSGC diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem new file mode 100644 index 0000000000..ec83db25ec --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1TCCAb2gAwIBAgIULaosvYiVvbvMj07BsP9K65Ea2yMwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowETEPMA0GA1UEAwwGaW50LUNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyUwIzAMBgNVHRMEBTADAQH/ +MBMGA1UdJQQMMAoGCCsGAQUFBwMCMA0GCSqGSIb3DQEBCwUAA4IBAQBRB7aEaMyA +kIN82mO+ZICrTUqFqe/0LHF4N3c5hR/JqjHGnrYcyNnewYccQXMQhZhZu1aRfZ8o +bs5Hz52teZsxjL8udA0c75bF48Dd2BHT++lHV4AHO8EZsW6SwF5NDGGJH6B8bRq9 +5FoiuOtWHan8MFTqC5FxHeaXsDiqS8MlEojSTvkh5Huq9HQAEAziJFfUyRZ1W8qw +m0GNX+/iXvqj0g0vrIBkVnPnUgHuglQITcH8luYhBJlv7I9YE55wNMCIf/xcHJro +htKzXzaJvdXeZrNlOLTzhEt8scv0sOF/tgiqVYpIHB7ku5x0Qnw7NRf6j9zDdzqm +SlKm9uRBg4LX +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem.certspec new file mode 100644 index 0000000000..e5bc18198c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-CA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-CA +extension:basicConstraints:cA, +extension:extKeyUsage:clientAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem new file mode 100644 index 0000000000..9ebd34f0df --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4jCCAcqgAwIBAgIUU53rn1mYUmAkdWEYl4H8CjVjAqUwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFDESMBAGA1UEAwwJaW50LVNBLUNBMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo +4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD +SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX +kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx +owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/ +Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoy8wLTAMBgNVHRMEBTAD +AQH/MB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsF +AAOCAQEANp5URW6l61bXiiNt7GQU/Q5bXrlHO31ipGzyo1t936xejdsnEZuRqc7i +QCKsCDynX7z6+hqyjFiOx7hTxh3tek/LICciZfigatB0mGqK0SsqaDMPbPvJgPCT +PDJUskEI92R4Qzelvol46F/4mZUQTOvoCASZRcr4RefqF/ClcE167XqZDn2DYxn/ +jpNY+Bs+VINWEgaqPbznEh3sQHksmweUWW49deIidAZGCwIHJFfFOegT0xBSRRdp +BN2WV78zIr4LFsrpwSKD82LJ2jdeq86hrc9UXJ55+JffNXtsWxXr/vXxiNEW+qJ0 +g4OGIAY9XAF/sJ2iPJd5ynaCmpEqVw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem.certspec new file mode 100644 index 0000000000..94e9a42d48 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-CA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-SA-CA +extension:basicConstraints:cA, +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem new file mode 100644 index 0000000000..e37d294074 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5DCCAcygAwIBAgIULf8za+LuAorq+vV7GCo4dV9SG8MwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLaW50LVNBLU9DU1AwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjLzAtMAwGA1UdEwQF +MAMBAf8wHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMJMA0GCSqGSIb3DQEB +CwUAA4IBAQBuugyWnIWv5eql67JO/rdh5JswvOfsmDql24twefbVILsHDMKHNMm7 +Xzq7N2lQ0Ye5hy1G0Tmpgd6GV8Yyi1lWwRmI0zZCsRWDYeodbXgDYbDoBBdzNUeH +KpPqV7PCkdMgoJp8AAlYOJnNKw9ARAQBe6ut5mq1fNgpzRGEeHpl0WVFKF0c1pSd +snNLv8LgtCOXdbpc+gHEZ4CLHffVic1cVWg2M+EivuZsFZRPUMFlfevlC5Uh9ea9 +UWvp3Ta3ipZX+XuCTkmzDMLRNm6pM/Je6yKo8zywxLgGt+kpK6itSLEMmQFql49A +NWS74xUiOXJWsE0+YeZ0aaNSPe0tFyLX +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem.certspec new file mode 100644 index 0000000000..c38a640b9b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-OCSP.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-SA-OCSP +extension:basicConstraints:cA, +extension:extKeyUsage:serverAuth,OCSPSigning diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem new file mode 100644 index 0000000000..c149580a8f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc6gAwIBAgIUVWq3GjxxzfgGFcE6ypKcX3YnKZEwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMaW50LVNBLW5zU0dDMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozAwLjAMBgNVHRME +BTADAQH/MB4GA1UdJQQXMBUGCCsGAQUFBwMBBglghkgBhvhCBAEwDQYJKoZIhvcN +AQELBQADggEBAFUF48SjYDpRRNNlGynD/g4jHOW5TTdUueiEWNCYEayldMMe6Rhq +kkEhY+3yC5Ys94YZFoiWaPmlR9FGFNdvjYV+abyElqYoSWO99qOJUldvm4xFwGQr +TwalO2jqwy4qtos/qbw6M/dflrRQzEZ5Cf5yYLwm9E18ALbuiU+B2Jp3n5LQ6T1Q +dDt+FkP3LlCWde+Y3aFOY+aLCkXgLwCOVCluwet8/IsKTGD6qzJhd3R2f1fnX8EU +EBfhaw850FpB8Xn4OvDYd+rEHSURNsNGxLzMVxhoBZKTzbwim5Cwem/5n8epRheW +L3eKTia8yBvTtvxDE3+iKkR+Oz9ozOGp6Ys= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem.certspec new file mode 100644 index 0000000000..c84201d874 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA-nsSGC.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-SA-nsSGC +extension:basicConstraints:cA, +extension:extKeyUsage:serverAuth,nsSGC diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem new file mode 100644 index 0000000000..5dac5b5c24 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1TCCAb2gAwIBAgIUV3pjDiG/4yqDPtPjv5HyVpDHrncwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowETEPMA0GA1UEAwwGaW50LVNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyUwIzAMBgNVHRMEBTADAQH/ +MBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3DQEBCwUAA4IBAQABgZe7+5NE +2Ui9SdwymCBbH8KrZcPKWRCBb/iCxVMbt39k+MQPaQQgxEKqGiYYCE79yJo0HznF ++gN/Jc62tuY+oBUc+E3MvULqR6AMB1qjSs48uq57aunoE5gDgwoGU/gMA1Mfd22s +X08jcbpWfsyDVglzeK9J/Ihc7QPnBk3iMnv10TuFq+8/C6E+2ZQmTYd9CjVAPyS0 +C1DVIBoPsRrcWlh5cKVXQIVBECGLNAIIXbPGcO6tirxOtNG6ehnROfQn6hBqZQrs +LIrrRHHGuF+eT9PV3Eld4puoHQ2FYPo8lK41xqqbZJYW7a9kP0EEJVQYLrwcM/0i +haT6qq3JwqKA +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem.certspec new file mode 100644 index 0000000000..74bec2b21c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-SA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-SA +extension:basicConstraints:cA, +extension:extKeyUsage:serverAuth diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem new file mode 100644 index 0000000000..e0deef7c3f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIUbXK8dZ2kTHVUtKZ1Uamdr5h27tQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowGDEWMBQGA1UEAwwNaW50LW5zU0dDLW9sZDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7 +wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp +k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh +eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW +EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc +JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMmMCQwDAYDVR0T +BAUwAwEB/zAUBgNVHSUEDTALBglghkgBhvhCBAEwDQYJKoZIhvcNAQELBQADggEB +AK/99QYaWy5/SG7iKiGwSgJ49hobsVUf4DTN9+4FIesvXNUtXc+vmPVNwgy8S4Kn +23zOUmp2LaRBQ3VxaiQ0o/RN3ZjULhPhGi3cHsjDTKXH3U0snAloUYONx1JCFOif +RWwLeiyps1oW9ARfUQrbQRtw87ospU5aJ7JSPoVgbCMXubmEpRSeTMv0SHdOs6g7 +ahSaoT7BBRuHDnCb8+ZR509H9Dc4M2Dv4lQ9vlWGZjXnfM1ImIeUBTWQ0fngyoZW +neTStGeL5MmCjjMMupJYbjNsenQXd9doD08+voOfmKgaMQDH0fgEACJHjmmt+eQ4 +j8WZP3lRZHZm/s23xNl+6S4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem.certspec new file mode 100644 index 0000000000..35f61671ed --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-old.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-nsSGC-old +extension:basicConstraints:cA, +extension:extKeyUsage:nsSGC +validity:20160724-20160924 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem new file mode 100644 index 0000000000..dd709c343d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIUITNR+z5zrXNAq+3y9u3et1fNp6YwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNTA3MjQwMDAwMDBaGA8yMDE2MDkyNDAw +MDAwMFowGjEYMBYGA1UEAwwPaW50LW5zU0dDLW9sZGVyMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyYwJDAMBgNV +HRMEBTADAQH/MBQGA1UdJQQNMAsGCWCGSAGG+EIEATANBgkqhkiG9w0BAQsFAAOC +AQEAtkFQHiG8UeleNMgvJVneYQzIQt8wiZwudAH2FdiyeCtYUp95z19IzPlZeYq0 +FXlMJJ+SOn2wSZ9jHshV5VF8S4Rb3ou0EVJcu+X7cs3jOuLtV/KwFDKXrncWpF7L +sH1yGVkAUNMQlE52MgPxg7P6yd+lbU9MlqD5rpifsAecrXzctzi8l3qb2UJvkHku +BLE+ViTnn9RFDQFQ/1AAF9cbSJaUF0rwWznXpB0PAu+v9lBpn9a83/GXZc1SO2mE +MIdgRpuB1Lr+wZq5ulXHAeBJ+kH8lrG2CIXSQPFQjPfiS2D5hM1cdd7GSEh4BoZv +AbTKG12NXN9AG7RpG7upSBG4mQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem.certspec new file mode 100644 index 0000000000..f7a870c0f1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-older.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-nsSGC-older +extension:basicConstraints:cA, +extension:extKeyUsage:nsSGC +validity:20150724-20160924 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem new file mode 100644 index 0000000000..c5c8e724c2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4DCCAcigAwIBAgIUec5AldPAXDY+y1Q7RfO4SfvteiEwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjA4MjQwMDAwMDBaGA8yMDE3MDgyNDAw +MDAwMFowGzEZMBcGA1UEAwwQaW50LW5zU0dDLXJlY2VudDCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMmMCQwDAYD +VR0TBAUwAwEB/zAUBgNVHSUEDTALBglghkgBhvhCBAEwDQYJKoZIhvcNAQELBQAD +ggEBAJO1C5eYEk2/+xvgWsCsUZi7PMoZLhb5Jb2V61JMWREfCozmYepqlamR6IZV +fn5Q9OClLtAzSybeia40nsW/xb/o+5zJn0rPzk6JIsMToJk07fqp+uG9LbAM82IV +RnHzmCS4/3n4fl1k1GGL0A/NYBUsilY9oKhVl1zukB/z3ALp9LyProNLsEZmWkl7 +F07+lR9PPMOqA1SuDJmZMyZ4cKDyYYF7NYKGi57xpgpUXGq8IPOKKGq4XlYqQhOQ +sVSuc+16A+NlPwMogczcgTgy7QD6DF4WNOCDGwuF0YB7uROEbYvh4lkKJfhnAtb7 +1/xnmTVssnCTsbppIiXtKs8zzu0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem.certspec b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem.certspec new file mode 100644 index 0000000000..f421ddc1a8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/int-nsSGC-recent.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-nsSGC-recent +extension:basicConstraints:cA, +extension:extKeyUsage:nsSGC +validity:20160824-20170824 diff --git a/security/manager/ssl/tests/unit/test_cert_eku/moz.build b/security/manager/ssl/tests/unit/test_cert_eku/moz.build new file mode 100644 index 0000000000..ede7f4b548 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_eku/moz.build @@ -0,0 +1,35 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'ee-CA.pem', +# 'ee-SA-CA.pem', +# 'ee-SA-OCSP.pem', +# 'ee-SA-nsSGC.pem', +# 'ee-SA.pem', +# 'ee-int-CA.pem', +# 'ee-int-SA-CA.pem', +# 'ee-int-SA-OCSP.pem', +# 'ee-int-SA-nsSGC.pem', +# 'ee-int-SA.pem', +# 'ee-int-nsSGC-old.pem', +# 'ee-int-nsSGC-older.pem', +# 'ee-int-nsSGC-recent.pem', +# 'ee-nsSGC.pem', +# 'int-CA.pem', +# 'int-SA-CA.pem', +# 'int-SA-OCSP.pem', +# 'int-SA-nsSGC.pem', +# 'int-SA.pem', +# 'int-nsSGC-old.pem', +# 'int-nsSGC-older.pem', +# 'int-nsSGC-recent.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null.js b/security/manager/ssl/tests/unit/test_cert_embedded_null.js new file mode 100644 index 0000000000..c1b20c1664 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null.js @@ -0,0 +1,54 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +// Tests that a certificate with a clever subject common name like +// 'www.bank1.com[NUL]www.bad-guy.com' (where [NUL] is a single byte with +// value 0) will not be treated as valid for www.bank1.com. +// Includes a similar test case but for the subject alternative name extension. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +async function do_testcase(certname, checkCommonName) { + let cert = constructCertFromFile(`test_cert_embedded_null/${certname}.pem`); + // Where applicable, check that the testcase is meaningful (i.e. that the + // certificate's subject common name has an embedded NUL in it). + if (checkCommonName) { + equal( + cert.commonName, + "www.bank1.com\\00www.bad-guy.com", + "certificate subject common name should have an embedded NUL byte" + ); + } + await checkCertErrorGeneric( + certdb, + cert, + SSL_ERROR_BAD_CERT_DOMAIN, + certificateUsageSSLServer, + undefined, + "www.bank1.com" + ); + await checkCertErrorGeneric( + certdb, + cert, + SSL_ERROR_BAD_CERT_DOMAIN, + certificateUsageSSLServer, + undefined, + "www.bad-guy.com" + ); +} + +add_task(async function() { + addCertFromFile(certdb, "test_cert_embedded_null/ca.pem", "CTu,,"); + + await do_testcase("embeddedNull", true); + await do_testcase("embeddedNullSAN", false); + await do_testcase("embeddedNullCNAndSAN", true); + await do_testcase("embeddedNullSAN2", false); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem b/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem new file mode 100644 index 0000000000..48031d478c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUb2Np/S2xMtQR+BvitAuzKtjWxMswDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBPEDwwrdd6h+SHkc0J+p4Ik/yc +aoLWNdGsVD4hJYa0IOgNh6Z/GyhTXM9hr/q0f7fewjfNhXi/nrXNcW5w4FJERhHp +HvZO6Z08i8CrVYSiijFcLf6ClK4e163j0LXUutBWY2PCf4TDS+fnF9PJmle0kPLU +IxqptfSSoCjLuWyYyRmjZIdNCtrNCU9g85SDaUO6l79vBm0TYOLhOiPBN0F7DWXo +JlOZKWEco6qqS22yIM1r/5KNc5ekPTD+UJFh7qprAq0riEfR38DYJmUq3w07q5Tb +HQdG8JHEtemi7dHr/WoJY18MLZaF7BSLAwBWmBWzx8Lj2V+/4TP4NtRWkL7y +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem.certspec new file mode 100644 index 0000000000..6660f5d478 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem new file mode 100644 index 0000000000..3ec195d7ad --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxTCCAa2gAwIBAgIUN3cis45zT7JXRJUjglyGLKsRNY4wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowKDEmMCQGA1UEAwwdd3d3LmJhbmsxLmNvbQB3d3cuYmFkLWd1eS5jb20w +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ +PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH +9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw +4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86 +exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0 +ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N +AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAEH79W5n+TiJob4LWvypQNMj4Fi44pwh +L/Pcpe+vXd19sN/UyY4WAH4S6U+Fu+wNlItMWWFQnlkibutTQQLpJhXTSR2q/ttU +CWo9MdCJ8JGFwTReHDoajxdD2NJ/C8vK/dJeFNtCUXLAnwR2bk+F+StDQt6I6iS4 +EXL/A+y1L3jw9j/qVO8ewNp8QJvA8jOe3AQyI3q8fHENExUk0opo1Nvorrlj4xWg +MP+NTIHZeJMGUfBw9vRwIZvfsx5BVQ5aqWpzVR9wxv7UCbO5NKeva57P6s+UeqX5 +rNxjzk0t7MV/3TZSTkMSVCUDc//sGUHMGk0F5fFsZ4/7SM+dO9+PaFM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem.certspec b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem.certspec new file mode 100644 index 0000000000..d1a32349a2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNull.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:www.bank1.com\0www.bad-guy.com diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem new file mode 100644 index 0000000000..6a1dd23bbf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8zCCAdugAwIBAgIUP8GnOjltE+C0ll5IYA6asvsZ+/MwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowKDEmMCQGA1UEAwwdd3d3LmJhbmsxLmNvbQB3d3cuYmFkLWd1eS5jb20w +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ +PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH +9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw +4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86 +exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0 +ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N +AgMBAAGjLDAqMCgGA1UdEQQhMB+CHXd3dy5iYW5rMS5jb20Ad3d3LmJhZC1ndXku +Y29tMA0GCSqGSIb3DQEBCwUAA4IBAQAF6YEQrh2rMu+HEcySofn4x3MStqoXrqwc +mn4r4cm4Qvrlubg+vewRan9b8pMryixRG8obsiEp+KGEB74XoSJmwumv8Ov3WL8V +njKT2vAfVLgyZp4p+ZD3firGJMdzZcRDAU8Sg+yM0Vru3fx40piusBqeMbc7lOga +AF+JCMtHPEJc32C4Y+itY0bedXUcBALljTHkam5nQ6+ShPk8X7wazKs8gn3wIBSB +XmLZtmqEjzeI1UuUoyP3/AymCgo90Xi27aA8GGsxsmaUk5Am07Sw9WobLpeRoNgp +c4dV4+2tcDqVM7nK2V4LKNlH9/2oRXoWnQNoDBzRZis9C6SeNV29 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem.certspec b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem.certspec new file mode 100644 index 0000000000..1029d6cdd0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullCNAndSAN.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:www.bank1.com\0www.bad-guy.com +extension:subjectAlternativeName:www.bank1.com\0www.bad-guy.com diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem new file mode 100644 index 0000000000..7a9140f31b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6TCCAdGgAwIBAgIUAy5rhhLOHnC6Vr7TTF+tKn9VA+UwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHjEcMBoGA1UEAwwTZW1iZWRkZWQgTlVMIGluIFNBTjCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs +9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8 +HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7Ak +kqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJet +lmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2r +kQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMsMCow +KAYDVR0RBCEwH4Idd3d3LmJhbmsxLmNvbQB3d3cuYmFkLWd1eS5jb20wDQYJKoZI +hvcNAQELBQADggEBAEmpR9Bldw/m1N5yODTW8J5E1vIy8UbxtcNJnGZaQNCeCbXO +r5d1EwqhGIsrVrYk4kjPD3gLPJuwAGh4yRVTiHWM+dCGf0EyzY5Ytlw42J0ny0PW +15dRoEf07hKxnloqwXy3pAQqtoRyKgIY38xrSYcIAaGlt/wbuO469nzyD7QoamxR +VcSosi0YxSlD8yye+E8fiZyBzB+fiD9W+JHX6mhYEznvtdW3J6zTG7aCOBEswh9C +kVBpMu7gAvGrIviIrtw7EFYxqwmNQg8/KMfeitOoBH7aznq0qsVajkXLo2QrX4CE +VzOabf4X7rLlcdqGN3fl4aDcZNuGR8goj4dgRkY= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem.certspec b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem.certspec new file mode 100644 index 0000000000..f224888eee --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:embedded NUL in SAN +extension:subjectAlternativeName:www.bank1.com\0www.bad-guy.com diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem new file mode 100644 index 0000000000..e08110f6bc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7jCCAdagAwIBAgIUQx7QA9Wf1gacnL1geoQjuSqMSx4wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLYmFkLWd1eS5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjOTA3MDUGA1UdEQQu +MCyCC2JhZC1ndXkuY29tgh13d3cuYmFuazEuY29tAHd3dy5iYWQtZ3V5LmNvbTAN +BgkqhkiG9w0BAQsFAAOCAQEAWyk3hxMIPXpSeKlePbth7wYv0kUF0RmT6eERgDtz +h/0GIVYx7kaCNQLuBAaRCP/50Tj17R/gYWiPN7YXa1kGfgUYy25mOsrccMR1wvYy +KDzCv4Fip0dDkYAVFRmpTHzy1JQ64dnVlgOkCWuhSb93XOcOJ651BAgPjRwzjDZ4 +vHYidUF61uOU3i/UsLrJJXHdojIgYsyfHv2B7aCkuO4ea1WcmwrS2YYW7DoDBft1 +/X4vRkWhJRKBrertLXCzpC/0ERO0pvGAQp1CJJIddIoO+XwCKnvvgsQI0ao34pJp +Bsk3ZkIyNeYL5o9MAEAr8R4KkpZqACFWoyGqlwP9GPkqOw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem.certspec b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem.certspec new file mode 100644 index 0000000000..d352d034b6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/embeddedNullSAN2.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:bad-guy.com +extension:subjectAlternativeName:bad-guy.com,www.bank1.com\0www.bad-guy.com diff --git a/security/manager/ssl/tests/unit/test_cert_embedded_null/moz.build b/security/manager/ssl/tests/unit/test_cert_embedded_null/moz.build new file mode 100644 index 0000000000..57c9013ddc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_embedded_null/moz.build @@ -0,0 +1,17 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'embeddedNull.pem', +# 'embeddedNullCNAndSAN.pem', +# 'embeddedNullSAN.pem', +# 'embeddedNullSAN2.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_expiration_canary.js b/security/manager/ssl/tests/unit/test_cert_expiration_canary.js new file mode 100644 index 0000000000..4519dd3935 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_expiration_canary.js @@ -0,0 +1,40 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Attempts to verify a certificate for a time a few weeks into the future in +// the hopes of avoiding mass test failures when the certificates all expire. +// If this test fails, the certificates probably need to be regenerated. +// See bug 1525191. + +// If this test and only this test fails, do the following: +// 1. Create a bug for the issue in "Core :: Security: PSM". +// 2. Write a patch to temporarily disable the test. +// 3. Land the patch. +// 4. Write a patch to reenable the test but don't land it. +// 5. Needinfo the triage owner of Bugzilla's "Core :: Security: PSM" component +// in the bug. +// 6. Patches to update certificates get created. +// 7. Test the patches with a Try push. +// 8. Land the patches on all trees whose code will still be used when the +// certificates expire in 3 weeks. +add_task(async function() { + do_get_profile(); + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + addCertFromFile(certDB, "bad_certs/test-ca.pem", "CTu,,"); + let threeWeeksFromNowInSeconds = Date.now() / 1000 + 3 * 7 * 24 * 60 * 60; + let ee = constructCertFromFile("bad_certs/default-ee.pem"); + await checkCertErrorGenericAtTime( + certDB, + ee, + PRErrorCodeSuccess, + certificateUsageSSLServer, + threeWeeksFromNowInSeconds, + false, + "test.example.com" + ); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot.js b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot.js new file mode 100644 index 0000000000..d69ea5105c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot.js @@ -0,0 +1,73 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +// Tests that nsIX509Cert.isBuiltInRoot works as expected. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +// This is a certificate that (currently) ships with the platform. +// It should be considered a built-in root. +const sGeoTrustBase64 = + "" + + "MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL" + + "MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj" + + "KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2" + + "MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0" + + "eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV" + + "BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw" + + "NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV" + + "BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH" + + "MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL" + + "So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal" + + "tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO" + + "BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG" + + "CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT" + + "qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz" + + "rD6ogRLQy7rQkgu2npaqBA+K"; + +// This is a certificate that does not ship with the platform. +// It should not be considered a built-in root. +const sLetsEncryptBase64 = + "" + + "MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw" + + "PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD" + + "Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa" + + "MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD" + + "ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD" + + "ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB" + + "BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg" + + "PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG" + + "dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1" + + "gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4" + + "4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud" + + "EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy" + + "BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j" + + "b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv" + + "ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ" + + "MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH" + + "AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw" + + "MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM" + + "LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3" + + "pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd" + + "v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd" + + "ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW" + + "ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk" + + "6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj" + + "f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk="; + +function run_test() { + let builtInCert = certdb.constructX509FromBase64(sGeoTrustBase64); + ok(builtInCert, "should be able to decode base-64 of built-in cert"); + ok(builtInCert.isBuiltInRoot, "cert should be considered built-in"); + + let notBuiltInCert = certdb.constructX509FromBase64(sLetsEncryptBase64); + ok(notBuiltInCert, "should be able to decode base-64 of built-in cert"); + ok(!notBuiltInCert.isBuiltInRoot, "cert should not be considered built-in"); +} diff --git a/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload.js b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload.js new file mode 100644 index 0000000000..a8c6d09f2b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload.js @@ -0,0 +1,124 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +// Tests that nsIX509Cert.isBuiltInRoot works as expected. Differs from +// test_cert_isBuiltInRoot.js in that this test uses a preexisting NSS +// certificate DB that already contains some of the certificates in question. +// +// To create the necessary preexisting files, obtain the "GeoTrust Primary +// Certification Authority - G2" certificate and the "Let's Encrypt Authority +// X1" certificate (copied below for reference) and perform the following steps: +// +// `certutil -d . -N` (use an empty password) +// `certutil -d . -A -n "GeoTrust Primary Certification Authority - G2" -t ,, \ +// -a -i GeoTrust.pem` +// `certutil -d . -A -n "Let's Encrypt Authority X1" -t ,, -a \ +// -i LetsEncrypt.pem` +// +// This should create the cert9.db and key4.db files. +// +// (The crucial property of the first certificate is that it is a built-in trust +// anchor, so any replacement must also have this property. The second +// certificate is not a built-in trust anchor, so any replacement must not be a +// built-in trust anchor.) +// +// GeoTrust Primary Certification Authority - G2: +// -----BEGIN CERTIFICATE----- +// MIICrjCCAjWgAwIBAgIQPLL0SAoA4v7rJDteYD7DazAKBggqhkjOPQQDAzCBmDEL +// MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +// KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +// MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +// eSAtIEcyMB4XDTA3MTEwNTAwMDAwMFoXDTM4MDExODIzNTk1OVowgZgxCzAJBgNV +// BAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYDVQQLEzAoYykgMjAw +// NyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxNjA0BgNV +// BAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgLSBH +// MjB2MBAGByqGSM49AgEGBSuBBAAiA2IABBWx6P0DFUPlrOuHNxFi79KDNlJ9RVcL +// So17VDs6bl8VAsBQps8lL33KSLjHUGMcKiEIfJo22Av+0SbFWDEwKCXzXV2juLal +// tJLtbCyf691DiaI8S0iRHVDsJt/WYC69IaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAO +// BgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFBVfNVdRVfslsq0DafwBo/q+EVXVMAoG +// CCqGSM49BAMDA2cAMGQCMGSWWaboCd6LuvpaiIjwH5HTRqjySkwCY/tsXzjbLkGT +// qQ7mndwxHLKgpxgceeHHNgIwOlavmnRs9vuD4DPTCF+hnMJbn0bWtsuRBmOiBucz +// rD6ogRLQy7rQkgu2npaqBA+K +// -----END CERTIFICATE----- +// +// Let's Encrypt Authority X1: +// -----BEGIN CERTIFICATE----- +// MIIEqDCCA5CgAwIBAgIRAJgT9HUT5XULQ+dDHpceRL0wDQYJKoZIhvcNAQELBQAw +// PzEkMCIGA1UEChMbRGlnaXRhbCBTaWduYXR1cmUgVHJ1c3QgQ28uMRcwFQYDVQQD +// Ew5EU1QgUm9vdCBDQSBYMzAeFw0xNTEwMTkyMjMzMzZaFw0yMDEwMTkyMjMzMzZa +// MEoxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MSMwIQYDVQQD +// ExpMZXQncyBFbmNyeXB0IEF1dGhvcml0eSBYMTCCASIwDQYJKoZIhvcNAQEBBQAD +// ggEPADCCAQoCggEBAJzTDPBa5S5Ht3JdN4OzaGMw6tc1Jhkl4b2+NfFwki+3uEtB +// BaupnjUIWOyxKsRohwuj43Xk5vOnYnG6eYFgH9eRmp/z0HhncchpDpWRz/7mmelg +// PEjMfspNdxIknUcbWuu57B43ABycrHunBerOSuu9QeU2mLnL/W08lmjfIypCkAyG +// dGfIf6WauFJhFBM/ZemCh8vb+g5W9oaJ84U/l4avsNwa72sNlRZ9xCugZbKZBDZ1 +// gGusSvMbkEl4L6KWTyogJSkExnTA0DHNjzE4lRa6qDO4Q/GxH8Mwf6J5MRM9LTb4 +// 4/zyM2q5OTHFr8SNDR1kFjOq+oQpttQLwNh9w5MCAwEAAaOCAZIwggGOMBIGA1Ud +// EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMH8GCCsGAQUFBwEBBHMwcTAy +// BggrBgEFBQcwAYYmaHR0cDovL2lzcmcudHJ1c3RpZC5vY3NwLmlkZW50cnVzdC5j +// b20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9hcHBzLmlkZW50cnVzdC5jb20vcm9vdHMv +// ZHN0cm9vdGNheDMucDdjMB8GA1UdIwQYMBaAFMSnsaR7LHH62+FLkHX/xBVghYkQ +// MFQGA1UdIARNMEswCAYGZ4EMAQIBMD8GCysGAQQBgt8TAQEBMDAwLgYIKwYBBQUH +// AgEWImh0dHA6Ly9jcHMucm9vdC14MS5sZXRzZW5jcnlwdC5vcmcwPAYDVR0fBDUw +// MzAxoC+gLYYraHR0cDovL2NybC5pZGVudHJ1c3QuY29tL0RTVFJPT1RDQVgzQ1JM +// LmNybDATBgNVHR4EDDAKoQgwBoIELm1pbDAdBgNVHQ4EFgQUqEpqYwR93brm0Tm3 +// pkVl7/Oo7KEwDQYJKoZIhvcNAQELBQADggEBANHIIkus7+MJiZZQsY14cCoBG1hd +// v0J20/FyWo5ppnfjL78S2k4s2GLRJ7iD9ZDKErndvbNFGcsW+9kKK/TnY21hp4Dd +// ITv8S9ZYQ7oaoqs7HwhEMY9sibED4aXw09xrJZTC9zK1uIfW6t5dHQjuOWv+HHoW +// ZnupyxpsEUlEaFb+/SCI4KCSBdAsYxAcsHYI5xxEI4LutHp6s3OT2FuO90WfdsIk +// 6q78OMSdn875bNjdBYAqxUp2/LEIHfDBkLoQz0hFJmwAbYahqKaLn73PAAm1X2kj +// f1w8DdnkabOLGeOVcj9LQ+s67vBykx4anTjURkbqZslUEUsn2k5xeua2zUk= +// -----END CERTIFICATE----- + +"use strict"; + +function run_test() { + const certDBName = "cert9.db"; + const keyDBName = "key4.db"; + let profile = do_get_profile(); + let certDBFile = do_get_file(`test_cert_isBuiltInRoot_reload/${certDBName}`); + certDBFile.copyTo(profile, certDBName); + let keyDBFile = do_get_file(`test_cert_isBuiltInRoot_reload/${keyDBName}`); + keyDBFile.copyTo(profile, keyDBName); + + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + // This is a built-in root, but not one that was added to the preexisting + // certificate DB. + // Verisign Class 1 Public Primary Certification Authority - G3 + // Certificate fingerprint (SHA1): 204285DCF7EB764195578E136BD4B7D1E98E46A5 + // https://crt.sh/?id=8984570 + const veriSignCertDBKey = `AAAAAAAAAAAAAAARAAAAzQCLW3VWhFSFCwDPrzhI + zrGkMIHKMQswCQYDVQQGEwJVUzEXMBUGA1UEChMOVmVyaVNpZ24sIEluYy4xHzAdB + gNVBAsTFlZlcmlTaWduIFRydXN0IE5ldHdvcmsxOjA4BgNVBAsTMShjKSAxOTk5IF + ZlcmlTaWduLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxRTBDBgNVBAM + TPFZlcmlTaWduIENsYXNzIDEgUHVibGljIFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB + dXRob3JpdHkgLSBHMw==`; + let veriSignCert = certdb.findCertByDBKey(veriSignCertDBKey); + ok(veriSignCert, "Should be able to find VeriSign root"); + ok(veriSignCert.isBuiltInRoot, "VeriSign root is a built-in"); + + // This is a built-in root. It was added to the preexisting certificate DB. It + // should still be considered a built-in. + const geoTrustCertDBKey = `AAAAAAAAAAAAAAAQAAAAmzyy9EgK + AOL+6yQ7XmA+w2swgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJ + bmMuMTkwNwYDVQQLEzAoYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhv + cml6ZWQgdXNlIG9ubHkxNjA0BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlm + aWNhdGlvbiBBdXRob3JpdHkgLSBHMg==`; + let geoTrustCert = certdb.findCertByDBKey(geoTrustCertDBKey); + ok(geoTrustCert, "Should be able to find GeoTrust root"); + ok(geoTrustCert.isBuiltInRoot, "GeoTrust root is a built-in"); + + // This is not a built-in root. It was added to the preexisting certificate + // DB. It should not be considered a built-in root. + const letsEncryptCertDBKey = `AAAAAAAAAAAAAAARAAAAQQCYE + /R1E+V1C0PnQx6XHkS9MD8xJDAiBgNVBAoTG0RpZ2l0YWwgU2lnbmF0dXJlIFRyd + XN0IENvLjEXMBUGA1UEAxMORFNUIFJvb3QgQ0EgWDM=`; + let letsEncryptCert = certdb.findCertByDBKey(letsEncryptCertDBKey); + ok(letsEncryptCert, "Should be able to find LetsEncrypt root"); + ok(!letsEncryptCert.isBuiltInRoot, "LetsEncrypt root is not a built-in"); +} diff --git a/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/cert9.db b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/cert9.db new file mode 100644 index 0000000000..b4567566d4 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/cert9.db differ diff --git a/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/key4.db b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/key4.db new file mode 100644 index 0000000000..ed8747112d Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_isBuiltInRoot_reload/key4.db differ diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage.js b/security/manager/ssl/tests/unit/test_cert_keyUsage.js new file mode 100644 index 0000000000..a32be6152d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage.js @@ -0,0 +1,76 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +var certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const caList = [ + "ca-no-keyUsage-extension", + "ca-missing-keyCertSign", + "ca-all-usages", +]; +const eeList = [ + "ee-no-keyUsage-extension", + "ee-keyCertSign-only", + "ee-keyEncipherment-only", + "ee-keyCertSign-and-keyEncipherment", +]; + +const caUsage = [certificateUsageSSLCA]; +const allEEUsages = [ + certificateUsageSSLClient, + certificateUsageSSLServer, + certificateUsageEmailSigner, + certificateUsageEmailRecipient, +]; +const serverEEUsages = [ + certificateUsageSSLServer, + certificateUsageEmailRecipient, +]; + +const expectedUsagesMap = { + "ca-no-keyUsage-extension": caUsage, + "ca-missing-keyCertSign": [], + "ca-all-usages": caUsage, + + "ee-no-keyUsage-extension-ca-no-keyUsage-extension": allEEUsages, + "ee-no-keyUsage-extension-ca-missing-keyCertSign": [], + "ee-no-keyUsage-extension-ca-all-usages": allEEUsages, + + "ee-keyCertSign-only-ca-no-keyUsage-extension": [], + "ee-keyCertSign-only-ca-missing-keyCertSign": [], + "ee-keyCertSign-only-ca-all-usages": [], + + "ee-keyEncipherment-only-ca-no-keyUsage-extension": serverEEUsages, + "ee-keyEncipherment-only-ca-missing-keyCertSign": [], + "ee-keyEncipherment-only-ca-all-usages": serverEEUsages, + + "ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension": serverEEUsages, + "ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign": [], + "ee-keyCertSign-and-keyEncipherment-ca-all-usages": serverEEUsages, +}; + +add_task(async function() { + for (let ca of caList) { + addCertFromFile(certdb, "test_cert_keyUsage/" + ca + ".pem", "CTu,CTu,CTu"); + let caCert = constructCertFromFile("test_cert_keyUsage/" + ca + ".pem"); + await asyncTestCertificateUsages(certdb, caCert, expectedUsagesMap[ca]); + for (let ee of eeList) { + let eeFullName = ee + "-" + ca; + let eeCert = constructCertFromFile( + "test_cert_keyUsage/" + eeFullName + ".pem" + ); + await asyncTestCertificateUsages( + certdb, + eeCert, + expectedUsagesMap[eeFullName] + ); + } + } +}); diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem new file mode 100644 index 0000000000..f59173e4d4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIUJUeujAg8AwYGhKxQTX/25wMUlcUwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNY2EtYWxsLXVzYWdlczAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAYMRYwFAYDVQQDDA1jYS1hbGwtdXNhZ2VzMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +ox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB/jANBgkqhkiG9w0BAQsFAAOC +AQEAG8zr2oIAMopI4FXUoIcqnnqRafTg/URYGcBcuqpXQiCFufslaqIY2c1iQExS +S6TcNM2BD2+XjudfRO4R3qSNWNHcq7MFGaiZEOIzIF4bSozXg4HWLkhhZFxPO6Sp +zWd1wr3sHs+LpympZAB4Hs3BCkrYBPACKwTXSP8iqmZ5gN/vRMhyyZMNPSBE9YYO +H7hl+eDeShTQZ8wrhMj2C1QRP8bLtANMpR1yzHNYBVaGFEGJi3ojgSlkZjt1OBu+ +AXOkTU72YycuV0Pin+5RPWGTpbQCBKKkDT4dWEKe9Ur04JdrVuFPHY1AA422Bg1k +WpRsoqRh9fqXtwntrf3gRm/jIw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem.certspec new file mode 100644 index 0000000000..2ca523c74e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-all-usages.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca-all-usages +subject:ca-all-usages +extension:basicConstraints:cA, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem new file mode 100644 index 0000000000..49b7d2b962 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8TCCAdmgAwIBAgIUb5GhjzP0jcrSceWaX1M31KkwYIgwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWY2EtbWlzc2luZy1rZXlDZXJ0U2lnbjAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAhMR8wHQYDVQQDDBZjYS1taXNzaW5n +LWtleUNlcnRTaWduMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR +qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv +WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+ +rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv +JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5 +Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6 +clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB ++jANBgkqhkiG9w0BAQsFAAOCAQEAGWOD5t5lqzj8nk4TXD4wNPTlZYYpGqRNkQJ4 +LAgt8LhtH656c1OPKCxwJDQXF9XapnkqnPzpT4M3wiRfVBVZgEoO0TN0Fh4CWNJM +Dkq+kNC+rCvb9bddoF9Kzw1MoGa8A5y/JLqAQHi7TL+GwkksdgMvjBkmbEUqc0bc +JdZ5USOBJPEWcsyfxNleyLHtcvI0JcngAeHfb6mK+Tr3wHUeRq1o6llfHOz1nzwE +Lf1rhl6+hY458nxJjIv4p7YzON6dmzkkbKn4Rq4PPppMy44w2jxNqqtbev2TGJBh +lnEibCTgzwFs0xJaQpKqKpHy4lBgjAMwjTzS76UsI30sYV9QjQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem.certspec new file mode 100644 index 0000000000..26e0158ebe --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-missing-keyCertSign.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca-missing-keyCertSign +subject:ca-missing-keyCertSign +extension:basicConstraints:cA, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,cRLSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem new file mode 100644 index 0000000000..e79801f9dc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6DCCAdCgAwIBAgIUd46cj+Dhtp73GVJRwiYAMXpO09EwDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2Etbm8ta2V5VXNhZ2UtZXh0ZW5zaW9uMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCMxITAfBgNVBAMMGGNhLW5vLWtl +eVVzYWdlLWV4dGVuc2lvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG +8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V +gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3 +04hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l +0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz +/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG +9w0BAQsFAAOCAQEAfo7G469It6DM1PTLY0lfxGdV+4uCJPAWNKKjDk4swLsNy1yz +4zxv5HUwQPnZZqm5dZT22EPUHmycWzt/N/cnjfn10pxDvB41h+XmWgmLPltVXD6E +66N+9sNHb+XIwZdFdGa+oHJI0MLLH+/Uym4t46HuSsjAjvSth40yf7D76WXRmPUn +2bTuxqK+T2Ioq3z8DXx47fNPSqmFiFsj7wUdfQfxugjTbwDNlZ9quxEicYChnl4O +mScxJ/cDoBgB2ZV3FdcSeIc+0aVd7Nxx5sNOifS12/O8m0pflK5dVUtoNXLFoa78 +udnWXJ0J9224khw25u5vabj/gWJGe8TaI61tNw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem.certspec new file mode 100644 index 0000000000..d32e6a6496 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ca-no-keyUsage-extension.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-no-keyUsage-extension +subject:ca-no-keyUsage-extension +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem new file mode 100644 index 0000000000..0b391b9b35 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc6gAwIBAgIUIQJpgukzHUBKie2RdSdPXFoY4LwwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNY2EtYWxsLXVzYWdlczAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAtMSswKQYDVQQDDCJlZS1rZXlDZXJ0U2lnbi1hbmQt +a2V5RW5jaXBoZXJtZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +uohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGoby +a+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWC +D/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfT +iEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXT +Ce+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+ +SSP6clHEMdUDrNoYCjXtjQIDAQABow8wDTALBgNVHQ8EBAMCAiQwDQYJKoZIhvcN +AQELBQADggEBAA69Kh2Wk+QjEnMqyClxxpodQa37MQqGkXAVgSKgWHYQSagQ0EEJ +SD8oDeNdgeh2mb7lvBysQCw29jgoRj8f/9Pi1+8xkCGBocitM2Um8nYWJ70nHMgt +YOY1io2vQnQmI/dTIrSn330Gf5aCByqIEczEB7Erv/wuZY4l3RPG/HI6e94DXLOt +rSBW/bFM61PU8C/q31VLZ8IHebdaaRO3OL7T0BM4bzQafc3lPfMbqiVy9GzBfQ/a +nRrJirwqNGrKRyAWQ3gfvC60eNTjryH+NSA2N7gPawr2HxMkBqbUXhQwRMRatNKx +JwmoBQTlPI3GVL42qeWGO/ozgwQoRqwHqBs= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem.certspec new file mode 100644 index 0000000000..0bb2721a31 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-all-usages +subject:ee-keyCertSign-and-keyEncipherment +extension:keyUsage:keyEncipherment,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem new file mode 100644 index 0000000000..45427ccd17 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7zCCAdegAwIBAgIUG6KKRn9QfADWZAOAYBt7T0HRwxUwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWY2EtbWlzc2luZy1rZXlDZXJ0U2lnbjAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAtMSswKQYDVQQDDCJlZS1rZXlDZXJ0 +U2lnbi1hbmQta2V5RW5jaXBoZXJtZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow8wDTALBgNVHQ8EBAMCAiQw +DQYJKoZIhvcNAQELBQADggEBAA3HxmNPBMOe9i3095PKNQU3OPoJ+iRM6cQLM6KQ +PnfTAXPJFK4gdiY/xH3A69fq8h44F7VoHmxBf2VNurgI8GYiG2U6rLtTshPvDyHe +4KKTIz7rqiCAjdU5jslTS56HYvf0NguwdnFumXybWMAq0ThKCbQMXK16umegtoVE +RgtupUHDwdx8FA+GdcEYYqe7n+yO5ZuzoMlOdAaCl4sO/2XjpTcTNOauUVfrgJ9k +WlKTF6kzL7jhQVYosbGNpE/NblUjRt2/gDbz9tbi/OOcRqq0bQ3l7g6k+lpX7yYf +TKBnXzLhUoP+TNRF/MnO/Hj+HefiGXDtugH2e1CoXJOXluM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem.certspec new file mode 100644 index 0000000000..567ab0ce2d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-missing-keyCertSign +subject:ee-keyCertSign-and-keyEncipherment +extension:keyUsage:keyEncipherment,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem new file mode 100644 index 0000000000..54b5156753 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8TCCAdmgAwIBAgIUKX6X2shljk68mAen0V5Rvu+OMJgwDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2Etbm8ta2V5VXNhZ2UtZXh0ZW5zaW9uMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMC0xKzApBgNVBAMMImVlLWtleUNl +cnRTaWduLWFuZC1rZXlFbmNpcGhlcm1lbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQEAwIC +JDANBgkqhkiG9w0BAQsFAAOCAQEAW4N1dHXHynllzRvDdokzMD8vKAFcXyOSXP5N +lFqigC5B7Gmt19WFwui/y+qGws1H1PeJPdt73ht/R0tRFMfptuswGlyPufT7t+yP +bVH3JEPuBYBBNragxVsXtqkYIxJGNH96xGBhAbovL7Ie4iIhY+6tsn0j/DATn301 +9Sv+Q3aUTjmpAYo+X7G/TkxOM37vtJbCvZhEYy3NnFQliIdyneJoXRX7V7Yxu+Yv +vAnoDbiuiaT4N/XnP2OTdiwi/Obm7ITujbhwf2QOJvB8gGBIcGQ864opOmqIOn6i +gx6ZpIB0bXeRun3j7qQdm/NeunBBG/EGlK1bcobxYB0lEthxUg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem.certspec new file mode 100644 index 0000000000..c48ef66126 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-no-keyUsage-extension +subject:ee-keyCertSign-and-keyEncipherment +extension:keyUsage:keyEncipherment,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem new file mode 100644 index 0000000000..649c6b2744 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1zCCAb+gAwIBAgIUS7/18rlCU549DxhuSleCZnLydSUwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNY2EtYWxsLXVzYWdlczAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAeMRwwGgYDVQQDDBNlZS1rZXlDZXJ0U2lnbi1vbmx5 +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2 +ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdF +h/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6n +cOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAv +OnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2nj +tIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXt +jQIDAQABow8wDTALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQELBQADggEBAHGZLv0V +Jx+wMdx0BJkZWUpJq2rKTepW7b9zsGKO1OFo3Y9S+jCHobanWqmz2bwiEThQ4Ebx +wy6eXK9/ex46HNMU/R2OmqjNRJ+fn8NIbSLRK1UTGBnUNFMJgwFqoDGKCHmSGIA/ +DPR0dCFn9VFSVet7vSLSLbUurvTgfSR9GlyXw3abJ1BWsxP+3iCXr5NBNRVepZte +NGIajiG8gnm+JVhAAG1XSnd+/Q99IcLwkJK6QQ8rYQgsg86yF7f1PF/+1jMWo/3E +irkb0oBiyx3aitcPcci3yHcBAHqB/BIooJiQmt9EhvnVOKxFycw1yh3bpbzp0sIr +MBu/rdb+5QSUqCc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem.certspec new file mode 100644 index 0000000000..c495ca6d0e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-all-usages.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-all-usages +subject:ee-keyCertSign-only +extension:keyUsage:keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem new file mode 100644 index 0000000000..a818a38d1a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4DCCAcigAwIBAgIUW6rkcglhshQOePFgTRd3FZiywHgwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWY2EtbWlzc2luZy1rZXlDZXJ0U2lnbjAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAeMRwwGgYDVQQDDBNlZS1rZXlDZXJ0 +U2lnbi1vbmx5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABow8wDTALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQELBQAD +ggEBAAkfffPLkCJ7QwlVv19U2I69EEG7R8dfPcckXdxRQvRBSrnvFpq4xP+mS+b/ +cPzkCF7XK2JbKILWdpLl1Gl0fqIMdqAo3CUgAh2EgFXb+dDaTNF50vIKhIEnnVBt +xWVQDOxNtFRrwtoUleeV7gOdY8oII+ehCIAqWSSN0tIHdYaoD84ngoIOYD7qGytK +KN7AIIsZ9Ka+2WVGaWloE81ubJK68VThgrjW4eOHGjiHt38cEqge5zco2xj1rSE5 +G7Szdi+gcIOMoqJon3mXq/bkqaUZyTJs7BSm/tic/qID9cIeX2ZpuKCu1HWJqhSF +Jdx3G8WPh5xnKwwKtDmdZoS5NgE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem.certspec new file mode 100644 index 0000000000..23ddd0eb8a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-missing-keyCertSign.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-missing-keyCertSign +subject:ee-keyCertSign-only +extension:keyUsage:keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem new file mode 100644 index 0000000000..f95886bfb5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4jCCAcqgAwIBAgIUHwJqP3oKeHdRO4h+n18uLiTGuvswDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2Etbm8ta2V5VXNhZ2UtZXh0ZW5zaW9uMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMB4xHDAaBgNVBAMME2VlLWtleUNl +cnRTaWduLW9ubHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQEAwICBDANBgkqhkiG9w0BAQsF +AAOCAQEAGT9yKiHNhaNqa+QCuBKgMYN6cthRl7cXmB6rbgSl6x4+LGLFC/mpVx2n +2ON9I9weQOcdqdA/s6LaT4sdk3V+BR7NDUBN0mHehxxYvMdOKWirMBGQsU/yspEh +asD9RVHBBiX4AaCBfz+k+a0xGg1WNX+XQr7OGARPBclvN4gK/C3EnqWvcInd6dKh +L11X5V8+O76coeii1pRTuEJTgJhttlFurr10YQM59xcJCvbNnDF4NP0ithumm3TX +iH6h29vnr9Xuyhz6yBo8Izvw2mSKtn619U4nxqD0kT11ovfOLbBfS+0D67i7uGUe +9xnFnXmaC7x/UPZ40Ba2bpm5KIo22w== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem.certspec new file mode 100644 index 0000000000..a5a2d62a7d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyCertSign-only-ca-no-keyUsage-extension.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-no-keyUsage-extension +subject:ee-keyCertSign-only +extension:keyUsage:keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem new file mode 100644 index 0000000000..94d5b8376d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC2zCCAcOgAwIBAgIUD4en2K6uMB5YpGMfwGgTtM+cZMMwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNY2EtYWxsLXVzYWdlczAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAiMSAwHgYDVQQDDBdlZS1rZXlFbmNpcGhlcm1lbnQt +b25seTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1u +togGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6 +pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqL +KkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3Zlqq +fgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3sv +Im9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6za +GAo17Y0CAwEAAaMPMA0wCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEBCwUAA4IBAQCD +FhkKA16rSKyeeyWbKV0GLm0leHDTHD1lLq9OMFJTnM8oIV4wTxkNlM8GBvmXrbJ9 +bR2XBZADefQ2/hYBWCQJHBONOss+G3OF4xYYYQT0gDnhZuABWpT97FLMOsajPaAJ +GcCy4CXFiWmBR3Z70duV7B7AbYM18SOstghaOHCT6dLzA00C/MkeuSwwmylJ0jjX +VE5kmrh8RMy4o9BT2RGLNCAyJehCik0DqHyQjq61Q2pE/eVwSaDIFH29Q57ianyB +fsVGxWjebixLkFm+GWqTbTsGyACwL2tDgE9zA7FcuQ+bUsmNt14+9Sf9j+DGcMXn +wroXpu9cJ2hUBGH/1kya +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem.certspec new file mode 100644 index 0000000000..08154a53ee --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-all-usages.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-all-usages +subject:ee-keyEncipherment-only +extension:keyUsage:keyEncipherment diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem new file mode 100644 index 0000000000..413eec8073 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5DCCAcygAwIBAgIUR9LRIE9OxiebeLBW62zXCGMQD/4wDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWY2EtbWlzc2luZy1rZXlDZXJ0U2lnbjAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAiMSAwHgYDVQQDDBdlZS1rZXlFbmNp +cGhlcm1lbnQtb25seTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaMPMA0wCwYDVR0PBAQDAgUgMA0GCSqGSIb3DQEB +CwUAA4IBAQAgn7t4QKh0bvoLuwFaZMhTEG1aeC/UH8CAi9InsjNFFKsrqKNMFXIB +BHMwsNX0pd92UVQmcxOelJGKh4Ssebqwi3CegvUxjkoc0XJmJIsmGnta7aliFgYq +8yS9CzxQAsQBS8L/NgJx+kYL5OyyYcOdKkDH2MnHvMl66JwSKoerp0xxK+senJmM +UjvR5bZgR+4L/IZ9G1J70u5EIKOKusrHHnD95y9OtwJSXriErMDaeTMK7C+HSqdK +6+d7OSj/l7sBWgvvIRBAOqIOe3WBnNw5HVAfEf+RkzL9ry0llF93z429BxnV17r0 +DecPXRH8iTA11aPezhblHImD9I+LnEnx +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem.certspec new file mode 100644 index 0000000000..9bdcf4b7b8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-missing-keyCertSign.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-missing-keyCertSign +subject:ee-keyEncipherment-only +extension:keyUsage:keyEncipherment diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem new file mode 100644 index 0000000000..42d173b89a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc6gAwIBAgIUUb8T3+6DgXwOgUnl93BH2znvH7swDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2Etbm8ta2V5VXNhZ2UtZXh0ZW5zaW9uMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCIxIDAeBgNVBAMMF2VlLWtleUVu +Y2lwaGVybWVudC1vbmx5MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +uohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGoby +a+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWC +D/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfT +iEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXT +Ce+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+ +SSP6clHEMdUDrNoYCjXtjQIDAQABow8wDTALBgNVHQ8EBAMCBSAwDQYJKoZIhvcN +AQELBQADggEBADPdx2NPP/lnfhFONgim1PT1z9715fnVBUOovdbOFrX4o5bAW9A4 +5EL+4jWXFEgSDCWbaVZIunaExT0clbrdP+96KSu0eCmO8UtWuEmLvWBpwnLNSJmV +V07kpv4cF3ju7m6FMVn2yAWC3MwUVwtG3rc1cTEaQb8mRSP168L+c4bgbDfjT3SH +cjc0Xku8+0qEF8mvDkEjEQ6DXciMQMEA+mdnhjLY7pCxEeMeYn3wbc02j0sDg9mc +P5r7KFALon3lvNNvfgX8ksqs/FxvtkMJuJfxuqqw0JKbTUnCSWDUQLLpH5vTSNwS +J6HaMBk4cBmm7RiMSNHb4q4DD2KPQaR3ia0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem.certspec new file mode 100644 index 0000000000..a2383ecfdd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-keyEncipherment-only-ca-no-keyUsage-extension.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca-no-keyUsage-extension +subject:ee-keyEncipherment-only +extension:keyUsage:keyEncipherment diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem new file mode 100644 index 0000000000..f9c0e98abf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyzCCAbOgAwIBAgIUdb+6dAvNPrDSi4t1Mh0VWTH9+PwwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNY2EtYWxsLXVzYWdlczAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAjMSEwHwYDVQQDDBhlZS1uby1rZXlVc2FnZS1leHRl +bnNpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAAOmZY9qkWrF1fxh37r8uzeI +DIliysuC/r8Zv2PH1uXNQ/Xc2/YRevoLlXYFjPSv+dDLBTLU8gaKoc4A8VbScMXj +RD/4Dgg5P8zp8tYhC6IC6lJU+BsYdE4bVEfxYIuFsj9t3IWaV6dfBGV6tZr5+hma +fd132i0EB6j9tHdWxyjRjbLlpS+Ebws1YxpxhFthtDXia8g4jowh1SRYpK3a+Feh +f/uZAVVDUia9iLK17JwQCWSvIAoMz5A1GyYzfjL6CnhIpXO77G1crCGoUeWbJ94j +5IX1zQfT0YQhdiIQEoD11478aok3BhIIE1KO6iCSXj4o+OVAlFWZexPcutqnTFA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem.certspec new file mode 100644 index 0000000000..6d2e672961 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-all-usages.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca-all-usages +subject:ee-no-keyUsage-extension diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem new file mode 100644 index 0000000000..4fd1085a57 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAgIUQSQmSr1VH8nomKY2NVNJ+HN8y+0wDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWY2EtbWlzc2luZy1rZXlDZXJ0U2lnbjAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAjMSEwHwYDVQQDDBhlZS1uby1rZXlV +c2FnZS1leHRlbnNpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAA36Vps+r3Ao +jobxXMLVlFswo/qOC6/G1BtF8l0UPuOuSf7xpKDWVsorWY/FmsHAdcauHm0m5MUP +nCVhPfH8xYP6TBQw2wWrGk/RBnWDNLewrdEIlWSTFUALY6SKcvRO1adWGJ/uJZr3 +O6KCvrg22O4ZlOFLpb5B8XhUVcCPiH30vdo2MeiaA/IOs0dqMZAfzH5s25WRjwnJ +byYST/yVutDdexECWVibIFwi1N+APduacEyDXvao5y3VXz96kblSLtZaSX/2mHDc +fhKTLWw4ykHqBIWmDYs2RJrSqFM45bNShLYGCqTPmYFmCU5SY9e+elcfReLcbJzv +FNK2ofnYhm4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem.certspec new file mode 100644 index 0000000000..3cba2f0d81 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-missing-keyCertSign.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca-missing-keyCertSign +subject:ee-no-keyUsage-extension diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem new file mode 100644 index 0000000000..4bf7250fee --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1jCCAb6gAwIBAgIUOXIHlX23XCDj+TpQN+GOUIa0wl0wDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2Etbm8ta2V5VXNhZ2UtZXh0ZW5zaW9uMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCMxITAfBgNVBAMMGGVlLW5vLWtl +eVVzYWdlLWV4dGVuc2lvbjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG +8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V +gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3 +04hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l +0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz +/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAkKUtc+iJ +0yBV2Y3xKmTIDe3he3Cy3VSembzQTpc+FBfQ4n9gXZSw5O8PllaWD4pjz7ovDYNp +rl422x6vkfmm7ebZb1PqVXZDkONXYn22a/76j7EFl+LlG6EMUw8OJ+iMTiCrDS2j +MbTpyRKLbgPMcT7GxZZDmqRJKva/VFVJ92XuIndZrltQ/RAr5QAg1+ijo2VpowWn +etUhR/GZ6WbDS85KQLEOFeWHS9ez02asCjQcanWgMYPqZXG1wQQbEAgfJLT1Bqar +k+TRt7NRlJPbxI8R5UfXJfCdXYrT17jhO52b7UZcCmCe/kyQPwtir5axOupFy17i +NHOBFw1PVX4KfQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem.certspec b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem.certspec new file mode 100644 index 0000000000..c850725a63 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca-no-keyUsage-extension +subject:ee-no-keyUsage-extension diff --git a/security/manager/ssl/tests/unit/test_cert_keyUsage/moz.build b/security/manager/ssl/tests/unit/test_cert_keyUsage/moz.build new file mode 100644 index 0000000000..a16fff4b94 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_keyUsage/moz.build @@ -0,0 +1,27 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca-all-usages.pem', +# 'ca-missing-keyCertSign.pem', +# 'ca-no-keyUsage-extension.pem', +# 'ee-keyCertSign-and-keyEncipherment-ca-all-usages.pem', +# 'ee-keyCertSign-and-keyEncipherment-ca-missing-keyCertSign.pem', +# 'ee-keyCertSign-and-keyEncipherment-ca-no-keyUsage-extension.pem', +# 'ee-keyCertSign-only-ca-all-usages.pem', +# 'ee-keyCertSign-only-ca-missing-keyCertSign.pem', +# 'ee-keyCertSign-only-ca-no-keyUsage-extension.pem', +# 'ee-keyEncipherment-only-ca-all-usages.pem', +# 'ee-keyEncipherment-only-ca-missing-keyCertSign.pem', +# 'ee-keyEncipherment-only-ca-no-keyUsage-extension.pem', +# 'ee-no-keyUsage-extension-ca-all-usages.pem', +# 'ee-no-keyUsage-extension-ca-missing-keyCertSign.pem', +# 'ee-no-keyUsage-extension-ca-no-keyUsage-extension.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_override_bits_mismatches.js b/security/manager/ssl/tests/unit/test_cert_override_bits_mismatches.js new file mode 100644 index 0000000000..4ac8820515 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_override_bits_mismatches.js @@ -0,0 +1,116 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Test that when an override exists for a (host, certificate) pair, +// connections will succeed only if the set of error bits in the override +// contains each bit in the set of encountered error bits. +// Strangely, it is possible to store an override with an empty set of error +// bits, so this tests that too. + +do_get_profile(); + +function add_override_bits_mismatch_test( + host, + certPath, + expectedBits, + expectedError +) { + const MAX_BITS = + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_TIME; + let cert = constructCertFromFile(certPath); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + for (let overrideBits = 0; overrideBits <= MAX_BITS; overrideBits++) { + add_test(function() { + certOverrideService.clearValidityOverride(host, 8443); + certOverrideService.rememberValidityOverride( + host, + 8443, + cert, + overrideBits, + true + ); + run_next_test(); + }); + // The override will succeed only if the set of error bits in the override + // contains each bit in the set of expected error bits. + let successExpected = (overrideBits | expectedBits) == overrideBits; + add_connection_test( + host, + successExpected ? PRErrorCodeSuccess : expectedError + ); + } +} + +function run_test() { + Services.prefs.setIntPref("security.OCSP.enabled", 1); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + }); + fakeOCSPResponder.start(8888); + + add_override_bits_mismatch_test( + "unknownissuer.example.com", + "bad_certs/unknownissuer.pem", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_override_bits_mismatch_test( + "mismatch.example.com", + "bad_certs/mismatch.pem", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_override_bits_mismatch_test( + "expired.example.com", + "bad_certs/expired-ee.pem", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_EXPIRED_CERTIFICATE + ); + + add_override_bits_mismatch_test( + "mismatch-untrusted.example.com", + "bad_certs/mismatch-untrusted.pem", + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_MISMATCH, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_override_bits_mismatch_test( + "untrusted-expired.example.com", + "bad_certs/untrusted-expired.pem", + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_override_bits_mismatch_test( + "mismatch-expired.example.com", + "bad_certs/mismatch-expired.pem", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_TIME, + SSL_ERROR_BAD_CERT_DOMAIN + ); + + add_override_bits_mismatch_test( + "mismatch-untrusted-expired.example.com", + "bad_certs/mismatch-untrusted-expired.pem", + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_UNKNOWN_ISSUER + ); + + add_test(function() { + fakeOCSPResponder.stop(run_next_test); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_cert_overrides.js b/security/manager/ssl/tests/unit/test_cert_overrides.js new file mode 100644 index 0000000000..f160f00562 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_overrides.js @@ -0,0 +1,718 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Tests the certificate overrides we allow. +// add_cert_override_test will queue a test that does the following: +// 1. Attempt to connect to the given host. This should fail with the +// given error and override bits. +// 2. Add an override for that host/port/certificate/override bits. +// 3. Connect again. This should succeed. + +do_get_profile(); + +function check_telemetry() { + let histogram = Services.telemetry + .getHistogramById("SSL_CERT_ERROR_OVERRIDES") + .snapshot(); + equal(histogram.values[0], 0, "Should have 0 unclassified values"); + equal( + histogram.values[2], + 9, + "Actual and expected SEC_ERROR_UNKNOWN_ISSUER values should match" + ); + equal( + histogram.values[3], + 1, + "Actual and expected SEC_ERROR_CA_CERT_INVALID values should match" + ); + equal( + histogram.values[4] || 0, + 0, + "Actual and expected SEC_ERROR_UNTRUSTED_ISSUER values should match" + ); + equal( + histogram.values[5], + 1, + "Actual and expected SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE values should match" + ); + equal( + histogram.values[6] || 0, + 0, + "Actual and expected SEC_ERROR_UNTRUSTED_CERT values should match" + ); + equal( + histogram.values[7] || 0, + 0, + "Actual and expected SEC_ERROR_INADEQUATE_KEY_USAGE values should match" + ); + equal( + histogram.values[8], + 2, + "Actual and expected SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED values should match" + ); + equal( + histogram.values[9], + 13, + "Actual and expected SSL_ERROR_BAD_CERT_DOMAIN values should match" + ); + equal( + histogram.values[10], + 5, + "Actual and expected SEC_ERROR_EXPIRED_CERTIFICATE values should match" + ); + equal( + histogram.values[11], + 2, + "Actual and expected MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY values should match" + ); + equal( + histogram.values[12], + 1, + "Actual and expected MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA values should match" + ); + equal( + histogram.values[13], + 1, + "Actual and expected MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE values should match" + ); + equal( + histogram.values[14], + 2, + "Actual and expected MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE values should match" + ); + equal( + histogram.values[15], + 1, + "Actual and expected MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE values should match" + ); + equal( + histogram.values[16], + 2, + "Actual and expected SEC_ERROR_INVALID_TIME values should match" + ); + equal( + histogram.values[17], + 1, + "Actual and expected MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME values should match" + ); + equal( + histogram.values[19], + 3, + "Actual and expected MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT values should match" + ); + equal( + histogram.values[20], + 1, + "Actual and expected MOZILLA_PKIX_ERROR_MITM_DETECTED values should match" + ); + + let keySizeHistogram = Services.telemetry + .getHistogramById("CERT_CHAIN_KEY_SIZE_STATUS") + .snapshot(); + equal( + keySizeHistogram.values[0], + 0, + "Actual and expected unchecked key size values should match" + ); + equal( + keySizeHistogram.values[1], + 16, + "Actual and expected successful verifications of 2048-bit keys should match" + ); + equal( + keySizeHistogram.values[2] || 0, + 0, + "Actual and expected successful verifications of 1024-bit keys should match" + ); + equal( + keySizeHistogram.values[3], + 68, + "Actual and expected verification failures unrelated to key size should match" + ); + + run_next_test(); +} + +// Internally, specifying "port" -1 is the same as port 443. This tests that. +function run_port_equivalency_test(inPort, outPort) { + Assert.ok( + (inPort == 443 && outPort == -1) || (inPort == -1 && outPort == 443), + "The two specified ports must be -1 and 443 (in any order)" + ); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + let cert = constructCertFromFile("bad_certs/default-ee.pem"); + let expectedBits = Ci.nsICertOverrideService.ERROR_UNTRUSTED; + let expectedTemporary = true; + certOverrideService.rememberValidityOverride( + "example.com", + inPort, + cert, + expectedBits, + expectedTemporary + ); + let actualBits = {}; + let actualTemporary = {}; + Assert.ok( + certOverrideService.hasMatchingOverride( + "example.com", + outPort, + cert, + actualBits, + actualTemporary + ), + `override set on port ${inPort} should match port ${outPort}` + ); + equal( + actualBits.value, + expectedBits, + "input override bits should match output bits" + ); + equal( + actualTemporary.value, + expectedTemporary, + "input override temporary value should match output temporary value" + ); + Assert.ok( + !certOverrideService.hasMatchingOverride("example.com", 563, cert, {}, {}), + `override set on port ${inPort} should not match port 563` + ); + certOverrideService.clearValidityOverride("example.com", inPort); + Assert.ok( + !certOverrideService.hasMatchingOverride( + "example.com", + outPort, + cert, + actualBits, + {} + ), + `override cleared on port ${inPort} should match port ${outPort}` + ); + equal(actualBits.value, 0, "should have no bits set if there is no override"); +} + +function run_test() { + run_port_equivalency_test(-1, 443); + run_port_equivalency_test(443, -1); + + Services.prefs.setIntPref("security.OCSP.enabled", 1); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + }); + fakeOCSPResponder.start(8888); + + add_simple_tests(); + add_localhost_tests(); + add_combo_tests(); + add_distrust_tests(); + + add_test(function() { + fakeOCSPResponder.stop(check_telemetry); + }); + + run_next_test(); +} + +function add_simple_tests() { + add_cert_override_test( + "expired.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_EXPIRED_CERTIFICATE + ); + add_cert_override_test( + "notyetvalid.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + MOZILLA_PKIX_ERROR_NOT_YET_VALID_CERTIFICATE + ); + add_cert_override_test( + "before-epoch.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_INVALID_TIME + ); + add_cert_override_test( + "selfsigned.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT + ); + add_cert_override_test( + "unknownissuer.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_cert_override_test( + "expiredissuer.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE + ); + add_cert_override_test( + "notyetvalidissuer.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_NOT_YET_VALID_ISSUER_CERTIFICATE + ); + add_cert_override_test( + "before-epoch-issuer.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_INVALID_TIME + ); + add_cert_override_test( + "md5signature.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + add_cert_override_test( + "emptyissuername.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_EMPTY_ISSUER_NAME + ); + // This has name information in the subject alternative names extension, + // but not the subject common name. + add_cert_override_test( + "mismatch.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + // This has name information in the subject common name but not the subject + // alternative names extension. + add_cert_override_test( + "mismatch-CN.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + + // A Microsoft IIS utility generates self-signed certificates with + // properties similar to the one this "host" will present. + add_cert_override_test( + "selfsigned-inadequateEKU.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT + ); + + add_prevented_cert_override_test( + "inadequatekeyusage.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_INADEQUATE_KEY_USAGE + ); + + // Test triggering the MitM detection. We don't set-up a proxy here. Just + // set the pref. Without the pref set we expect an unkown issuer error. + add_cert_override_test( + "mitm.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_test(function() { + Services.prefs.setStringPref( + "security.pki.mitm_canary_issuer", + "CN=Test MITM Root" + ); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride("mitm.example.com", 8443); + run_next_test(); + }); + add_cert_override_test( + "mitm.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_MITM_DETECTED + ); + add_test(function() { + Services.prefs.setStringPref( + "security.pki.mitm_canary_issuer", + "CN=Other MITM Root" + ); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride("mitm.example.com", 8443); + run_next_test(); + }); + // If the canary issuer doesn't match the one we see, we exepct and unknown + // issuer error. + add_cert_override_test( + "mitm.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + // If security.pki.mitm_canary_issuer.enabled is false, there should always + // be an unknown issuer error. + add_test(function() { + Services.prefs.setBoolPref( + "security.pki.mitm_canary_issuer.enabled", + false + ); + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride("mitm.example.com", 8443); + run_next_test(); + }); + add_cert_override_test( + "mitm.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_test(function() { + Services.prefs.clearUserPref("security.pki.mitm_canary_issuer"); + run_next_test(); + }); + + // This is intended to test the case where a verification has failed for one + // overridable reason (e.g. unknown issuer) but then, in the process of + // reporting that error, a non-overridable error is encountered. The + // non-overridable error should be prioritized. + add_test(function() { + let rootCert = constructCertFromFile("bad_certs/test-ca.pem"); + setCertTrust(rootCert, ",,"); + run_next_test(); + }); + add_prevented_cert_override_test( + "nsCertTypeCritical.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION + ); + add_test(function() { + let rootCert = constructCertFromFile("bad_certs/test-ca.pem"); + setCertTrust(rootCert, "CTu,,"); + run_next_test(); + }); + + // Bug 990603: Apache documentation has recommended generating a self-signed + // test certificate with basic constraints: CA:true. For compatibility, this + // is a scenario in which an override is allowed. + add_cert_override_test( + "self-signed-end-entity-with-cA-true.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT + ); + + add_cert_override_test( + "ca-used-as-end-entity.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); + + // If an X.509 version 1 certificate is not a trust anchor, we will + // encounter an overridable error. + add_cert_override_test( + "end-entity-issued-by-v1-cert.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA + ); + // If we make that certificate a trust anchor, the connection will succeed. + add_test(function() { + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride( + "end-entity-issued-by-v1-cert.example.com", + 8443 + ); + let v1Cert = constructCertFromFile("bad_certs/v1Cert.pem"); + setCertTrust(v1Cert, "CTu,,"); + clearSessionCache(); + run_next_test(); + }); + add_connection_test( + "end-entity-issued-by-v1-cert.example.com", + PRErrorCodeSuccess + ); + // Reset the trust for that certificate. + add_test(function() { + let v1Cert = constructCertFromFile("bad_certs/v1Cert.pem"); + setCertTrust(v1Cert, ",,"); + clearSessionCache(); + run_next_test(); + }); + + // Due to compatibility issues, we allow overrides for certificates issued by + // certificates that are not valid CAs. + add_cert_override_test( + "end-entity-issued-by-non-CA.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_CA_CERT_INVALID + ); + + // This host presents a 1016-bit RSA key. + add_cert_override_test( + "inadequate-key-size-ee.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE + ); + + add_cert_override_test( + "ipAddressAsDNSNameInSAN.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_cert_override_test( + "noValidNames.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_cert_override_test( + "badSubjectAltNames.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + + add_cert_override_test( + "bug413909.xn--hxajbheg2az3al.xn--jxalpdlp", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_test(function() { + // At this point, the override for bug413909.xn--hxajbheg2az3al.xn--jxalpdlp + // is still valid. Do some additional tests relating to IDN handling. + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + let uri = Services.io.newURI( + "https://bug413909.xn--hxajbheg2az3al.xn--jxalpdlp" + ); + let cert = constructCertFromFile("bad_certs/idn-certificate.pem"); + Assert.ok( + certOverrideService.hasMatchingOverride( + uri.asciiHost, + 8443, + cert, + {}, + {} + ), + "IDN certificate should have matching override using ascii host" + ); + Assert.throws( + () => + !certOverrideService.hasMatchingOverride( + uri.displayHost, + 8443, + cert, + {}, + {} + ), + /NS_ERROR_ILLEGAL_VALUE/, + "IDN certificate should not have matching override using (non-ascii) host" + ); + let invalidHost = uri.asciiHost.replace(/./g, c => + String.fromCharCode(c.charCodeAt(0) | 0x100) + ); + Assert.throws( + () => + !certOverrideService.hasMatchingOverride( + invalidHost, + 8443, + cert, + {}, + {} + ), + /NS_ERROR_ILLEGAL_VALUE/, + "hasMatchingOverride should not truncate high-bytes" + ); + run_next_test(); + }); + + add_test(function() { + // Add a bunch of overrides... + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + let cert = constructCertFromFile("bad_certs/default-ee.pem"); + let expectedBits = Ci.nsICertOverrideService.ERROR_UNTRUSTED; + certOverrideService.rememberValidityOverride( + "example.com", + 443, + cert, + expectedBits, + false + ); + Assert.ok( + certOverrideService.hasMatchingOverride("example.com", 443, cert, {}, {}), + "Should have added override for example.com:443" + ); + certOverrideService.rememberValidityOverride( + "example.com", + 80, + cert, + expectedBits, + false + ); + Assert.ok( + certOverrideService.hasMatchingOverride("example.com", 80, cert, {}, {}), + "Should have added override for example.com:80" + ); + certOverrideService.rememberValidityOverride( + "example.org", + 443, + cert, + expectedBits, + false + ); + Assert.ok( + certOverrideService.hasMatchingOverride("example.org", 443, cert, {}, {}), + "Should have added override for example.org:443" + ); + certOverrideService.rememberValidityOverride( + "example.org", + 80, + cert, + expectedBits, + true + ); + Assert.ok( + certOverrideService.hasMatchingOverride("example.org", 80, cert, {}, {}), + "Should have added override for example.org:80" + ); + + // Clear them all... + certOverrideService.clearAllOverrides(); + + // And ensure they're all gone. + Assert.ok( + !certOverrideService.hasMatchingOverride( + "example.com", + 443, + cert, + {}, + {} + ), + "Should have removed override for example.com:443" + ); + Assert.ok( + !certOverrideService.hasMatchingOverride("example.com", 80, cert, {}, {}), + "Should have removed override for example.com:80" + ); + Assert.ok( + !certOverrideService.hasMatchingOverride( + "example.org", + 443, + cert, + {}, + {} + ), + "Should have removed override for example.org:443" + ); + Assert.ok( + !certOverrideService.hasMatchingOverride("example.org", 80, cert, {}, {}), + "Should have removed override for example.org:80" + ); + + run_next_test(); + }); +} + +function add_localhost_tests() { + add_cert_override_test( + "localhost", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_cert_override_test( + "127.0.0.1", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_cert_override_test( + "::1", + Ci.nsICertOverrideService.ERROR_MISMATCH, + SSL_ERROR_BAD_CERT_DOMAIN + ); +} + +function add_combo_tests() { + add_cert_override_test( + "mismatch-expired.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_TIME, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_cert_override_test( + "mismatch-notYetValid.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_TIME, + SSL_ERROR_BAD_CERT_DOMAIN + ); + add_cert_override_test( + "mismatch-untrusted.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_cert_override_test( + "untrusted-expired.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_cert_override_test( + "mismatch-untrusted-expired.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_UNKNOWN_ISSUER + ); + + add_cert_override_test( + "md5signature-expired.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + + add_cert_override_test( + "ca-used-as-end-entity-name-mismatch.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); +} + +function add_distrust_tests() { + // Before we specifically distrust this certificate, it should be trusted. + add_connection_test("untrusted.example.com", PRErrorCodeSuccess); + + add_distrust_test( + "bad_certs/default-ee.pem", + "untrusted.example.com", + SEC_ERROR_UNTRUSTED_CERT + ); + + add_distrust_test( + "bad_certs/other-test-ca.pem", + "untrustedissuer.example.com", + SEC_ERROR_UNTRUSTED_ISSUER + ); + + add_distrust_test( + "bad_certs/test-ca.pem", + "ca-used-as-end-entity.example.com", + SEC_ERROR_UNTRUSTED_ISSUER + ); +} + +function add_distrust_test(certFileName, hostName, expectedResult) { + let certToDistrust = constructCertFromFile(certFileName); + + add_test(function() { + // Add an entry to the NSS certDB that says to distrust the cert + setCertTrust(certToDistrust, "pu,,"); + clearSessionCache(); + run_next_test(); + }); + add_prevented_cert_override_test( + hostName, + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + expectedResult + ); + add_test(function() { + setCertTrust(certToDistrust, "u,,"); + run_next_test(); + }); +} diff --git a/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js b/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js new file mode 100644 index 0000000000..bf7104eaaa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_overrides_read_only.js @@ -0,0 +1,126 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Tests that permanent certificate error overrides can be added even if the +// certificate/key databases are in read-only mode. + +// Helper function for add_read_only_cert_override_test. Probably doesn't need +// to be called directly. +function add_read_only_cert_override(aHost, aExpectedBits, aSecurityInfo) { + let bits = + (aSecurityInfo.isUntrusted + ? Ci.nsICertOverrideService.ERROR_UNTRUSTED + : 0) | + (aSecurityInfo.isDomainMismatch + ? Ci.nsICertOverrideService.ERROR_MISMATCH + : 0) | + (aSecurityInfo.isNotValidAtThisTime + ? Ci.nsICertOverrideService.ERROR_TIME + : 0); + + Assert.equal( + bits, + aExpectedBits, + "Actual and expected override bits should match" + ); + let cert = aSecurityInfo.serverCert; + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + // Setting the last argument to false here ensures that we attempt to store a + // permanent override (which is what was failing in bug 1427273). + certOverrideService.rememberValidityOverride( + aHost, + 8443, + cert, + aExpectedBits, + false + ); +} + +// Given a host, expected error bits (see nsICertOverrideService.idl), and an +// expected error code, tests that an initial connection to the host fails with +// the expected errors and that adding an override results in a subsequent +// connection succeeding. +function add_read_only_cert_override_test( + aHost, + aExpectedBits, + aExpectedError +) { + add_connection_test( + aHost, + aExpectedError, + null, + add_read_only_cert_override.bind(this, aHost, aExpectedBits) + ); + add_connection_test(aHost, PRErrorCodeSuccess, null, aSecurityInfo => { + Assert.ok( + aSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN, + "Cert override flag should be set on the security state" + ); + }); +} + +function run_test() { + let profile = do_get_profile(); + const KEY_DB_NAME = "key4.db"; + const CERT_DB_NAME = "cert9.db"; + let srcKeyDBFile = do_get_file( + `test_cert_overrides_read_only/${KEY_DB_NAME}` + ); + srcKeyDBFile.copyTo(profile, KEY_DB_NAME); + let srcCertDBFile = do_get_file( + `test_cert_overrides_read_only/${CERT_DB_NAME}` + ); + srcCertDBFile.copyTo(profile, CERT_DB_NAME); + + // set the databases to read-only + let keyDBFile = do_get_profile(); + keyDBFile.append(KEY_DB_NAME); + keyDBFile.permissions = 0o400; + let certDBFile = do_get_profile(); + certDBFile.append(CERT_DB_NAME); + certDBFile.permissions = 0o400; + + Services.prefs.setIntPref("security.OCSP.enabled", 1); + // Specifying false as the last argument means we don't try to add the default + // test root CA (which would fail). + add_tls_server_setup("BadCertAndPinningServer", "bad_certs", false); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + }); + fakeOCSPResponder.start(8888); + + // Since we can't add the root CA to the (read-only) trust db, all of these + // will result in an "unknown issuer error" and need the "untrusted" error bit + // set in addition to whatever other specific error bits are necessary. + add_read_only_cert_override_test( + "expired.example.com", + Ci.nsICertOverrideService.ERROR_TIME | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_read_only_cert_override_test( + "selfsigned.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT + ); + add_read_only_cert_override_test( + "mismatch.example.com", + Ci.nsICertOverrideService.ERROR_MISMATCH | + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + + add_test(function() { + fakeOCSPResponder.stop(run_next_test); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db b/security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db new file mode 100644 index 0000000000..3d452f335c Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_overrides_read_only/cert9.db differ diff --git a/security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db b/security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db new file mode 100644 index 0000000000..44d0cb1728 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_overrides_read_only/key4.db differ diff --git a/security/manager/ssl/tests/unit/test_cert_sha1.js b/security/manager/ssl/tests/unit/test_cert_sha1.js new file mode 100644 index 0000000000..371945bf85 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1.js @@ -0,0 +1,187 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +// Tests the rejection of SHA-1 certificates based on the preference +// security.pki.sha1_enforcement_level. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +// We need to test as if we are at a fixed time, so that we are testing the +// 2016 checks on SHA-1, not the notBefore checks. +// +// (new Date("2016-03-01")).getTime() / 1000 +const VALIDATION_TIME = 1456790400; + +function certFromFile(certName) { + return constructCertFromFile("test_cert_sha1/" + certName + ".pem"); +} + +function loadCertWithTrust(certName, trustString) { + addCertFromFile(certdb, "test_cert_sha1/" + certName + ".pem", trustString); +} + +function checkEndEntity(cert, expectedResult) { + return checkCertErrorGenericAtTime( + certdb, + cert, + expectedResult, + certificateUsageSSLServer, + VALIDATION_TIME + ); +} + +add_task(async function() { + loadCertWithTrust("ca", "CTu,,"); + loadCertWithTrust("int-pre", ",,"); + loadCertWithTrust("int-post", ",,"); + + // Test cases per pref setting + // + // root intermed. end entity + // =========================== + // root + // | + // +--- pre-2016 + // | | + // | +----- pre-2016 <--- (a) + // | +----- post-2016 <--- (b) + // | + // +--- post-2016 + // | + // +----- post-2016 <--- (c) + // + // Expected outcomes (accept / reject): + // + // a b c + // Allowed (0) Accept Accept Accept + // Forbidden (1) Reject Reject Reject + // (2) is no longer available and is treated as Forbidden (1) internally. + // ImportedRoot (3) Reject Reject Reject (for built-in roots) + // ImportedRoot Accept Accept Accept (for non-built-in roots) + // ImportedRootOrBefore2016 (4) Accept Reject Reject (for built-in roots) + // ImportedRootOrBefore2016 Accept Accept Accept (for non-built-in roots) + // + // The pref setting of ImportedRoot accepts usage of SHA-1 only for + // certificates issued by non-built-in roots. By default, the testing + // certificates are all considered issued by a non-built-in root. However, we + // have the ability to treat a given non-built-in root as built-in. We test + // both of these situations below. + // + // As a historical note, a policy option (Before2016) was previously available + // that only allowed SHA-1 for certificates with a notBefore before 2016. + // However, to enable the policy of only allowing SHA-1 from non-built-in + // roots in the most straightforward way (while still having a time-based + // policy that users could enable if this new policy were problematic), + // Before2016 was shifted to also allow SHA-1 from non-built-in roots, hence + // ImportedRootOrBefore2016. + // + // A note about intermediate certificates: the certificate verifier has the + // ability to directly verify a given certificate for the purpose of issuing + // TLS web server certificates. However, when asked to do so, the certificate + // verifier does not take into account the currently configured SHA-1 policy. + // This is in part due to implementation complexity and because this isn't + // actually how TLS web server certificates are verified in the TLS handshake + // (which makes a full implementation that supports heeding the SHA-1 policy + // unnecessary). + + // SHA-1 allowed + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 0); + await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess); + + // SHA-1 forbidden + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 1); + await checkEndEntity( + certFromFile("ee-pre_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-post"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + + // SHA-1 forbidden (test the case where the pref has been set to 2) + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 2); + await checkEndEntity( + certFromFile("ee-pre_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-post"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + + // SHA-1 allowed only when issued by an imported root. First test with the + // test root considered a built-in (on debug only - this functionality is + // disabled on non-debug builds). + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 3); + if (isDebugBuild) { + let root = certFromFile("ca"); + Services.prefs.setCharPref( + "security.test.built_in_root_hash", + root.sha256Fingerprint + ); + await checkEndEntity( + certFromFile("ee-pre_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-post"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + Services.prefs.clearUserPref("security.test.built_in_root_hash"); + } + + // SHA-1 still allowed only when issued by an imported root. + // Now test with the test root considered a non-built-in. + await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess); + + // SHA-1 allowed before 2016 or when issued by an imported root. First test + // with the test root considered a built-in. + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 4); + if (isDebugBuild) { + let root = certFromFile("ca"); + Services.prefs.setCharPref( + "security.test.built_in_root_hash", + root.sha256Fingerprint + ); + await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + await checkEndEntity( + certFromFile("ee-post_int-pre"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + await checkEndEntity( + certFromFile("ee-post_int-post"), + SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED + ); + Services.prefs.clearUserPref("security.test.built_in_root_hash"); + } + + // SHA-1 still only allowed before 2016 or when issued by an imported root. + // Now test with the test root considered a non-built-in. + await checkEndEntity(certFromFile("ee-pre_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-pre"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-post_int-post"), PRErrorCodeSuccess); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem b/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem new file mode 100644 index 0000000000..60140056de --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUUbC4F7yPobFDd+B73iWKejQ3THkwDQYJKoZIhvcNAQEF +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAsGA1UdDwQEAwIBBjAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCU+Y0AeMXFIfX4/L2aX37uSR70 +pGpPrh0FPOwBO2ETUc4j7Whol9wOSPnUwuPIpiDhar5qRuhY6aCPGTIJbRZrVeXv +T5uFQXq+3CQdIyI55AkFDh9tO7wX7p3pRgzma47mBxIH082Uwy7+eEeQfhuJ5cU4 +e/zyHf6FEdkSrDjgwDip+dn8Q7tnjdaN3WYQjOFRXkHyYCIFkORDPTbYSYZ6DAqq +Q/loKTdrcbyeEwFVBZxQu4Nb6mjhkfk8U+8TIGMCTQXhoQhgMWMeMo2E0kWvYbjc +YDiRzmnsdvPu2LKnTvH28M9ODi3ZzcOuLs6jAKAiXISq0CbmwaddV/oAMoF2 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem.certspec new file mode 100644 index 0000000000..7e65e9ee30 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ca.pem.certspec @@ -0,0 +1,6 @@ +issuer:ca +subject:ca +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem new file mode 100644 index 0000000000..8fb93e69e3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAZ2gAwIBAgIUJWQl8gkrLL7gPn47YYMdN7qBP5wwDQYJKoZIhvcNAQEF +BQAwEzERMA8GA1UEAwwIaW50LXBvc3QwIhgPMjAxNjAxMDIwMDAwMDBaGA8yMDE3 +MDIwMTAwMDAwMFowEjEQMA4GA1UEAwwHZWUtcG9zdDCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7 +wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp +k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh +eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW +EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc +JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0B +AQUFAAOCAQEAVOPvLS8zwos/RdClnabdxMh5g1WN5T1BsIMExE6oU6sJ7n4HyIXt +RnFTFe0t2CdXBCQPK6qG8ymeLQFNKykYlQxVZb8m5YgUK3k4IeMS/EoX4g7taREI +IwK9/n7+oKZYlz2Q/ro/R2HFmLXsCIUrsxV3vAWQCm8rSeCKzEVNlDaQ5FEMVAM7 +VlNhNNKtUnXkzZ3SRj6O4eOq3G4azr5DNo5kAQPaIbAI3k/3AHyPqIjHcoSiG1Ug +aqzIK6fNNCIAxIKAY2ERJfxA4fPlBZXono2sCOgCdFfF7QAo+o9SO8v3B+djuHgb +flbfdyEnN+y32UpYe3qV8LnFmRqGAe/vbQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem.certspec new file mode 100644 index 0000000000..76834f8447 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-post.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-post +subject:ee-post +validity:20160102-20170201 +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem new file mode 100644 index 0000000000..2385322a64 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIUIVsTCuql4BDO2r4O5zePBEoHg3QwDQYJKoZIhvcNAQEF +BQAwEjEQMA4GA1UEAwwHaW50LXByZTAiGA8yMDE2MDEwMTAwMDAwMFoYDzIwMTcw +MjAxMDAwMDAwWjASMRAwDgYDVQQDDAdlZS1wb3N0MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEB +BQUAA4IBAQCW5zeJg+LzGn07GtdBprRLarL7aLNFSr+s+3yzphq9kN43prElX6eD +gdggPWicZozTm3IFLfJfsuhiodBZjWmkF/dsvvT3W77AcKzNWjShCnnA/Vf5IF6k +U01ROfjmgcX0mMuhVUB7b9Fl6G5DFxJgny2jYehZcJIzWUBLiwu41TIxj5Cv5F9p ++XIHEyygqm8rYzbW8F49FRbsDD9nvhmdVqXsoTaKxY8bsKKu1EpBSBXozRbLKcAn +/zrLy0HHS4qfXTHm0UKt+RCYVylL5I5YGR6rapXHChkBTBHFXdkPVsW5uHKBdBqY +98zoAAMWRvJ3xOuqAbtKG6DKadiOpz6l +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem.certspec new file mode 100644 index 0000000000..1e8bb35b34 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-post_int-pre.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-pre +subject:ee-post +validity:20160101-20170201 +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem b/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem new file mode 100644 index 0000000000..11a5e41e99 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUOU+CyYnf3GRRgGHvbeJB8HTUvJ4wDQYJKoZIhvcNAQEF +BQAwEjEQMA4GA1UEAwwHaW50LXByZTAiGA8yMDE1MDEwMTAwMDAwMFoYDzIwMTcw +MjAxMDAwMDAwWjARMQ8wDQYDVQQDDAZlZS1wcmUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEF +BQADggEBACWLcVnT0nNyU/qFZNDZPGDFPuZCXuodBf3sgz1XDmcp5wlH+IjW3J8H +3HH6ZwIUpTtppqVxuvo2y9GP+GNyeXhxmokHTVdKDj8HqYl5lV+reO1UmzEH0AU8 +x3hd2Fkzv/h3N3EPVETWuPiFSB0oAN/xwsXC/7Yi4AY0s/I/4q/vkS76Oa2RyL3f +gbaa80+nR73BX+0wRqyg+Sgo2hOzjkCQchtZPUFYsRLhsHHBnokD8GJlT7NBKSN1 +TFt6uXpfEmqDICoyZoAw6rtnFfdEsZNo+PU6NDN3T0fkolBQPvuzfqcqAl85dpJK +ow8mFKkb2t6qQH98yabi/172l03/P34= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem.certspec new file mode 100644 index 0000000000..0f4a6ec257 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/ee-pre_int-pre.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-pre +subject:ee-pre +validity:20150101-20170201 +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem b/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem new file mode 100644 index 0000000000..94ab4f5b15 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzzCCAbegAwIBAgIUYQ6xulHM0FrQ0sKMdbPI2ecC3PcwDQYJKoZIhvcNAQEF +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxNjAxMDEwMDAwMDBaGA8yMDI2MDEwMTAw +MDAwMFowEzERMA8GA1UEAwwIaW50LXBvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAsGA1UdDwQEAwIB +BjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4IBAQCJN8/XexXMusXYbhVW +uYA1YpaSTrz96CXlckIuABnzCrGD5iHkfFoB0LPKd+EZ80fdHIvS1zQTYohy6O95 +JageOaTY9HsOEqsgr1BA9VKZW4QlGp7csQzNMa52WRetimv6XY/lrfPf4qAhomWG +/ImmLJpGTVPhEdz6Pl4Kvmf9zNf/BcXtBTWLSGWUC5UItC58WTopqcr5kLg3DmXB +Qr7DjqA7DT92N6qefFkTYspDZJzv0nL9OfqkdCj/s6bm3iisTQq3aek6IP6OEkXF +4TWUF3RDBsyRpG8jt/XsOsrwJDOGZGFPmMTz2uZPsZkeZhU+sfFDWL7wojl7kHV1 +c7f5 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem.certspec new file mode 100644 index 0000000000..50156c9f6e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/int-post.pem.certspec @@ -0,0 +1,6 @@ +issuer:ca +subject:int-post +validity:20160101-20260101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem b/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem new file mode 100644 index 0000000000..0b916d5755 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbagAwIBAgIUYW27TGzVOIbjpG1ADx7m7mZnrNQwDQYJKoZIhvcNAQEF +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDIwMDEwMTAw +MDAwMFowEjEQMA4GA1UEAwwHaW50LXByZTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswCwYDVR0PBAQDAgEG +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAESNgcKkxBwkaBykKo2Q +GzgimnI3eNw8O8GrhefL+r3Ek/CH4/oBHGvfvrz6D19uemdOyHxo5QNW2iWEq0No +pE6Hhm504P1fdkfQvjqjIhu/h3y5QjO3zdMGeVE/39TWAGrGsNFKE+jSxm8IbycF +Ue6165agasf+PhQdorjFca48iLcowKYs5Df0SAhY7zbw1fM1HTr1YGAXc1K9aCA5 +fTmu8Nd0fNKc1NcbNDpdCG2YEj1nox1iMN5A4nY1ve88zJsnlpfsoJkHJqo2Cy+M +mpQSnkTlf3Gfpl8NO3UW9FTcnK8L4Ix2DSNBDe8Yg2YL5w/VIxecFwlmwV0wWdg6 +vl0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem.certspec b/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem.certspec new file mode 100644 index 0000000000..9f0a59ee99 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/int-pre.pem.certspec @@ -0,0 +1,6 @@ +issuer:ca +subject:int-pre +validity:20100101-20200101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, +signature:sha1WithRSAEncryption diff --git a/security/manager/ssl/tests/unit/test_cert_sha1/moz.build b/security/manager/ssl/tests/unit/test_cert_sha1/moz.build new file mode 100644 index 0000000000..93cba24554 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_sha1/moz.build @@ -0,0 +1,18 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'int-pre.pem', +# 'ee-pre_int-pre.pem', +# 'ee-post_int-pre.pem', +# 'int-post.pem', +# 'ee-post_int-post.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_signatures.js b/security/manager/ssl/tests/unit/test_cert_signatures.js new file mode 100644 index 0000000000..e92b5a4ab8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures.js @@ -0,0 +1,140 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// Tests that certificates cannot be tampered with without being detected. +// Tests a combination of cases: RSA signatures, ECDSA signatures, certificate +// chains where the intermediate has been tampered with, chains where the +// end-entity has been tampered, tampering of the signature, and tampering in +// the rest of the certificate. + +do_get_profile(); // must be called before getting nsIX509CertDB +var certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +// Reads a PEM-encoded certificate, modifies the nth byte (0-indexed), and +// returns the base64-encoded bytes of the certificate. Negative indices may be +// specified to modify a byte from the end of the certificate. +function readAndTamperWithNthByte(certificatePath, n) { + let pem = readFile(do_get_file(certificatePath, false)); + let der = atob(pemToBase64(pem)); + if (n < 0) { + // remember, n is negative at this point + n = der.length + n; + } + let replacement = "\x22"; + if (der.charCodeAt(n) == replacement) { + replacement = "\x23"; + } + der = der.substring(0, n) + replacement + der.substring(n + 1); + return btoa(der); +} + +// The signature on certificates appears last. This should modify the contents +// of the signature such that it no longer validates correctly while still +// resulting in a structurally valid certificate. +const BYTE_IN_SIGNATURE = -8; +function addSignatureTamperedCertificate(certificatePath) { + let base64 = readAndTamperWithNthByte(certificatePath, BYTE_IN_SIGNATURE); + certdb.addCertFromBase64(base64, ",,"); +} + +function ensureSignatureVerificationFailure(certificatePath) { + let cert = constructCertFromFile(certificatePath); + return checkCertErrorGeneric( + certdb, + cert, + SEC_ERROR_BAD_SIGNATURE, + certificateUsageSSLServer + ); +} + +function tamperWithSignatureAndEnsureVerificationFailure(certificatePath) { + let base64 = readAndTamperWithNthByte(certificatePath, BYTE_IN_SIGNATURE); + let cert = certdb.constructX509FromBase64(base64); + return checkCertErrorGeneric( + certdb, + cert, + SEC_ERROR_BAD_SIGNATURE, + certificateUsageSSLServer + ); +} + +// The beginning of a certificate looks like this (in hex, using DER): +// 30 XX XX XX [the XX encode length - there are probably 3 bytes here] +// 30 XX XX XX [length again] +// A0 03 +// 02 01 +// 02 +// 02 XX [length again - 1 byte as long as we're using pycert] +// XX XX ... [serial number - 20 bytes as long as we're using pycert] +// Since we want to modify the serial number, we need to change something from +// byte 15 to byte 34 (0-indexed). If it turns out that the two length sections +// we assumed were 3 bytes are shorter (they can't be longer), modifying +// something from byte 15 to byte 30 will still get us what we want. Since the +// serial number is a DER INTEGER and because it must be positive, it's best to +// skip the first two bytes of the serial number so as to not run into any +// issues there. Thus byte 17 is a good byte to modify. +const BYTE_IN_SERIAL_NUMBER = 17; +function addSerialNumberTamperedCertificate(certificatePath) { + let base64 = readAndTamperWithNthByte(certificatePath, BYTE_IN_SERIAL_NUMBER); + certdb.addCertFromBase64(base64, ",,"); +} + +function tamperWithSerialNumberAndEnsureVerificationFailure(certificatePath) { + let base64 = readAndTamperWithNthByte(certificatePath, BYTE_IN_SERIAL_NUMBER); + let cert = certdb.constructX509FromBase64(base64); + return checkCertErrorGeneric( + certdb, + cert, + SEC_ERROR_BAD_SIGNATURE, + certificateUsageSSLServer + ); +} + +add_task(async function() { + addCertFromFile(certdb, "test_cert_signatures/ca-rsa.pem", "CTu,,"); + addCertFromFile(certdb, "test_cert_signatures/ca-secp384r1.pem", "CTu,,"); + + // Tamper with the signatures on intermediate certificates and ensure that + // end-entity certificates issued by those intermediates do not validate + // successfully. + addSignatureTamperedCertificate("test_cert_signatures/int-rsa.pem"); + addSignatureTamperedCertificate("test_cert_signatures/int-secp384r1.pem"); + await ensureSignatureVerificationFailure("test_cert_signatures/ee-rsa.pem"); + await ensureSignatureVerificationFailure( + "test_cert_signatures/ee-secp384r1.pem" + ); + + // Tamper with the signatures on end-entity certificates and ensure that they + // do not validate successfully. + await tamperWithSignatureAndEnsureVerificationFailure( + "test_cert_signatures/ee-rsa-direct.pem" + ); + await tamperWithSignatureAndEnsureVerificationFailure( + "test_cert_signatures/ee-secp384r1-direct.pem" + ); + + // Tamper with the serial numbers of intermediate certificates and ensure + // that end-entity certificates issued by those intermediates do not validate + // successfully. + addSerialNumberTamperedCertificate("test_cert_signatures/int-rsa.pem"); + addSerialNumberTamperedCertificate("test_cert_signatures/int-secp384r1.pem"); + await ensureSignatureVerificationFailure("test_cert_signatures/ee-rsa.pem"); + await ensureSignatureVerificationFailure( + "test_cert_signatures/ee-secp384r1.pem" + ); + + // Tamper with the serial numbers of end-entity certificates and ensure that + // they do not validate successfully. + await tamperWithSerialNumberAndEnsureVerificationFailure( + "test_cert_signatures/ee-rsa-direct.pem" + ); + await tamperWithSerialNumberAndEnsureVerificationFailure( + "test_cert_signatures/ee-secp384r1-direct.pem" + ); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem new file mode 100644 index 0000000000..290b01e0b2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUJaZFyIe9qjfQ+Uofk9CZqYEHlTgwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGY2EtcnNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBExDzANBgNVBAMMBmNhLXJzYTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBALa6fRuvA3KLtAMN +jeo0kNekw4UJ4eZK2m1XPHOEbrPXIZ9tTRAPPioOuNCLHYsj0038iu2tjpHmorgs +sCYSjvVxVxu9jWu2Ka99X/o8j1bH137Rrr9JpD1/Ur5/TvqjS4YmL+vhmogb9fr6 +1Duw6H9/L0E+KROhAQcxjAxe3kGHhBeIMLPFo4jtpTQo5rFUA2N1z9BHd7J3/zAv +T72inci5G739Uo2l2EeAWB3VtqrMCZeSLw4WbBJiRS9sO7Q3weIRH+k5qqBlKcB9 +hQnP+MXADWkphfe5AucI8aKY5fK5vCn2SlWQ+/6J3rnPkNUYVHkjKTnqkPBeoCeq +S3FICGE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem.certspec new file mode 100644 index 0000000000..5890d2db60 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ca-rsa.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca-rsa +subject:ca-rsa +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem new file mode 100644 index 0000000000..fd92a46fef --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBjjCCARSgAwIBAgIUOyTEDH+eecqyzh2AucmMGj9fTLAwCgYIKoZIzj0EAwIw +FzEVMBMGA1UEAwwMY2Etc2VjcDM4NHIxMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAy +MjAyMDUwMDAwMDBaMBcxFTATBgNVBAMMDGNhLXNlY3AzODRyMTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKFockM2K1x7GInzeRVGFaHHP7SN7oY+AikV22COJS3ktxMt +qM6Y6DFTTmqcDAsJyNY5regyBuW6gTRzoR+jMOBdqMluQ4P+J4c9qXEDviiIz/AC +8Fr3Gh/dzIN0qm6pzqMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwCgYI +KoZIzj0EAwIDaAAwZQIxAO0GJz6haDpUtNgaQ3SESJY85j6+gRcD7Nc9cvCiVAZZ +1OxFRuhW515lVbeTqfcA8wIwEy0o836FaKqjhXZB1FUAVV+3Qr3iStR9Be83+S6N +9SZg7pExVwePnv4bYkrcja5s +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem.certspec new file mode 100644 index 0000000000..0701c23c1e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ca-secp384r1.pem.certspec @@ -0,0 +1,7 @@ +issuer:ca-secp384r1 +subject:ca-secp384r1 +issuerKey:secp384r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem new file mode 100644 index 0000000000..3e1eef7d68 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuTCCAaGgAwIBAgIUfab+E3B6QwSzRFe7us5sNYBJa10wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGY2EtcnNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBgxFjAUBgNVBAMMDWVlLXJzYS1kaXJlY3QwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZI +hvcNAQELBQADggEBAJMWIw3o4w2U4Nvw2R0QZ41JZDGMSRSj88Jc3rqU9R0RrmuJ +xWj1/PidCJGo0ZhKsBxgleezXqyxPrnm/2nIK6GValEbHQh5lybnGugnu8sjjHv0 +XRifYbr+Hw1IIs6ZCZbqt6X4BsbinS8Kj/SArptw45dnXYO+xQVkcZVXRj8tRuWo +9H3uWpnspur3Jod2fhhyEWTYYHiH/B7XtD81slgWrNwPFvsdDiiLqBgsZ7O/vDAO +zE7VowW8qcs7R3sNOZrPx5bW+uAp2LSpZVToLdInMzLuLA9DdUqppyE5uBQ+MgEy +s052+WQ549Z8LN0l8iLYs9Ir9p437jNw9sty12k= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem.certspec new file mode 100644 index 0000000000..4e25ddcf94 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa-direct.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca-rsa +subject:ee-rsa-direct diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem new file mode 100644 index 0000000000..7b368c2554 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUG5+/xrLNQFse7iMoGWpBJsrHx84wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHaW50LXJzYTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjARMQ8wDQYDVQQDDAZlZS1yc2EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAFuOB6tFv6DrMoDrZcBwqptvrUE152IoCVT7M+p3VPIgTA4jyAm3tgog +ID3CZJmoYJrd+7HNDhFsjudGOF21k8z8snqSCCYBDETlLz5EKq5XmVGLw+hdKyZB +MtCmXXDr4qBFupN4D7x/1boqiB7L/AvDPOTk3H+UOF4xPLRFFSCZda0pAcbuPkAn +M07E1P9/qN6qBNp0/AT8tOHvcw5L2oSnfSJyYDCB+fStuh3MGj8crwq5sOprEWXp +5xxFiGM+0RyVTj6CqkJxb7UuY1g+rqKHxQo0CauF3g6pWFYz68NfHdOxiq17T5Ze +cc/o2Bl0HfldhPykzcdafPe4sEF0gxQ= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem.certspec new file mode 100644 index 0000000000..b974a0a0a8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-rsa.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-rsa +subject:ee-rsa diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem new file mode 100644 index 0000000000..9a09340159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBdTCB/KADAgECAhRfE+Et8NOs0+Akxjdd6jKTDpPw6jAKBggqhkjOPQQDAjAX +MRUwEwYDVQQDDAxjYS1zZWNwMzg0cjEwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIy +MDIwNTAwMDAwMFowHjEcMBoGA1UEAwwTZWUtc2VjcDM4NHIxLWRpcmVjdDB2MBAG +ByqGSM49AgEGBSuBBAAiA2IABKFockM2K1x7GInzeRVGFaHHP7SN7oY+AikV22CO +JS3ktxMtqM6Y6DFTTmqcDAsJyNY5regyBuW6gTRzoR+jMOBdqMluQ4P+J4c9qXED +viiIz/AC8Fr3Gh/dzIN0qm6pzjAKBggqhkjOPQQDAgNoADBlAjEA7QYnPqFoOlS0 +2BpDdIRIljzmPr6BFwPs1z1y8KJUBlnU7EVG6FbnXmVVt5Op9wDzAjAYYo+yN543 +lFkKtNGxnw22Jtgv0oA8co0+1n9dOxz8zTR0msc+9jzshYa7VZQ0hNA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem.certspec new file mode 100644 index 0000000000..386ab95f78 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1-direct.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca-secp384r1 +subject:ee-secp384r1-direct +issuerKey:secp384r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem new file mode 100644 index 0000000000..1baaad5156 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBcDCB9qADAgECAhRPYP/LpKATb8Eee6XdLyXiGnwgJzAKBggqhkjOPQQDAjAY +MRYwFAYDVQQDDA1pbnQtc2VjcDM4NHIxMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAy +MjAyMDUwMDAwMDBaMBcxFTATBgNVBAMMDGVlLXNlY3AzODRyMTB2MBAGByqGSM49 +AgEGBSuBBAAiA2IABKFockM2K1x7GInzeRVGFaHHP7SN7oY+AikV22COJS3ktxMt +qM6Y6DFTTmqcDAsJyNY5regyBuW6gTRzoR+jMOBdqMluQ4P+J4c9qXEDviiIz/AC +8Fr3Gh/dzIN0qm6pzjAKBggqhkjOPQQDAgNpADBmAjEA7QYnPqFoOlS02BpDdIRI +ljzmPr6BFwPs1z1y8KJUBlnU7EVG6FbnXmVVt5Op9wDzAjEAx9LL4IWV8HF8MrGQ +ZdFqG+sVSQ3QCUcEsVjGG/gZ6RcMlEnjW21iGqxnIZpKtiTN +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem.certspec new file mode 100644 index 0000000000..b8f7993be8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/ee-secp384r1.pem.certspec @@ -0,0 +1,5 @@ +issuer:int-secp384r1 +subject:ee-secp384r1 +issuerKey:secp384r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem b/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem new file mode 100644 index 0000000000..49f8879ed2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0jCCAbqgAwIBAgIURzatuu7JX78XkY/w99jKWmox0howDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGY2EtcnNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBIxEDAOBgNVBAMMB2ludC1yc2EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQF +MAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQAQ64v/9Z3EylV0 +lsRQI0PevDlAIEL8YHGBJWToq++WJGC3eemcoxyvvw1b9rvZgdkrrjx/+bjtOJci +7kloRJ2xiZOYQlqvnpwFcNqTlMDZnuWkPX50ZBUelqk4R6cwm0HB1VFIN+GOwCMD +zCC7t4a66HhAiqaejMDVcWMzw9VqytWgwm/isui/uBYQW84NGI1GKy1cIk770S6Q +J6HTKE6LM526ytMjIlGBtN9D7hl7K8AMuupKySA2QASodOrAJqoT5U2hlCl5OviF +OjmxnbgvveU6kdKN8a7z7y3uTkjhZpef81ImbF1jj8E1KtkC+b7Lm/CbK+IiEXxL +u9pvfao3 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem.certspec new file mode 100644 index 0000000000..a86d28b44a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/int-rsa.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca-rsa +subject:int-rsa +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem b/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem new file mode 100644 index 0000000000..ab896dbead --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBjzCCARWgAwIBAgIUMSRDv+0O5jNq1Obl2F8M+xzDNGUwCgYIKoZIzj0EAwIw +FzEVMBMGA1UEAwwMY2Etc2VjcDM4NHIxMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAy +MjAyMDUwMDAwMDBaMBgxFjAUBgNVBAMMDWludC1zZWNwMzg0cjEwdjAQBgcqhkjO +PQIBBgUrgQQAIgNiAAShaHJDNitcexiJ83kVRhWhxz+0je6GPgIpFdtgjiUt5LcT +LajOmOgxU05qnAwLCcjWOa3oMgbluoE0c6EfozDgXajJbkOD/ieHPalxA74oiM/w +AvBa9xof3cyDdKpuqc6jHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoG +CCqGSM49BAMCA2gAMGUCMQDtBic+oWg6VLTYGkN0hEiWPOY+voEXA+zXPXLwolQG +WdTsRUboVudeZVW3k6n3APMCMCNZB4rLFK+Njz93hs7gAv/HPo9isW3PSdPN7Dt6 +5lZVYZzti2Ram/Fr4ki+/pP+/g== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem.certspec b/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem.certspec new file mode 100644 index 0000000000..e002a1569a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/int-secp384r1.pem.certspec @@ -0,0 +1,7 @@ +issuer:ca-secp384r1 +subject:int-secp384r1 +issuerKey:secp384r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_cert_signatures/moz.build b/security/manager/ssl/tests/unit/test_cert_signatures/moz.build new file mode 100644 index 0000000000..f2bbe7a375 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_signatures/moz.build @@ -0,0 +1,20 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca-rsa.pem', +# 'ca-secp384r1.pem', +# 'ee-rsa-direct.pem', +# 'ee-rsa.pem', +# 'ee-secp384r1-direct.pem', +# 'ee-secp384r1.pem', +# 'int-rsa.pem', +# 'int-secp384r1.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_storage.js b/security/manager/ssl/tests/unit/test_cert_storage.js new file mode 100644 index 0000000000..ff0d1f24c8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage.js @@ -0,0 +1,286 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +"use strict"; + +// This test checks a number of things: +// * it ensures that data loaded from revocations.txt on startup is present +// * it ensures that data served from OneCRL are persisted correctly +// * it ensures that items in the CertBlocklist are seen as revoked by the +// cert verifier +// * it does a sanity check to ensure other cert verifier behavior is +// unmodified + +const { setTimeout } = ChromeUtils.import( + "resource://gre/modules/Timer.jsm", + {} +); +const { RemoteSecuritySettings } = ChromeUtils.import( + "resource://gre/modules/psm/RemoteSecuritySettings.jsm" +); + +// First, we need to setup appInfo for the blocklist service to work +var id = "xpcshell@tests.mozilla.org"; +var appName = "XPCShell"; +var version = "1"; +var platformVersion = "1.9.2"; +ChromeUtils.import("resource://testing-common/AppInfo.jsm", this); // Imported via AppInfo.jsm. +/* global updateAppInfo:false */ updateAppInfo({ + name: appName, + ID: id, + version, + platformVersion: platformVersion ? platformVersion : "1.0", + crashReporter: true, +}); + +// we need to ensure we setup revocation data before certDB, or we'll start with +// no revocation.txt in the profile +var gProfile = do_get_profile(); + +var gRevocations = gProfile.clone(); +gRevocations.append("revocations.txt"); +if (!gRevocations.exists()) { + let existing = do_get_file("test_onecrl/sample_revocations.txt", false); + existing.copyTo(gProfile, "revocations.txt"); +} + +var certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const certBlocklist = [ + // test with some bad data ... + { + issuerName: "Some nonsense in issuer", + serialNumber: "AkHVNA==", + }, + { + issuerName: "MA0xCzAJBgNVBAMMAmNh", + serialNumber: "some nonsense in serial", + }, + { + issuerName: "and serial", + serialNumber: "some nonsense in both issuer", + }, + // some mixed + // In these case, the issuer name and the valid serialNumber correspond + // to test-int.pem in bad_certs/ + { + issuerName: "MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=", + serialNumber: "oops! more nonsense.", + }, + { + issuerName: "MBIxEDAOBgNVBAMMB1Rlc3QgQ0E=", + serialNumber: "a0X7/7DlTaedpgrIJg25iBPOkIM=", + }, + // ... and some good + // In this case, the issuer name and the valid serialNumber correspond + // to other-test-ca.pem in bad_certs/ (for testing root revocation) + { + issuerName: "MBgxFjAUBgNVBAMMDU90aGVyIHRlc3QgQ0E=", + serialNumber: "Rym6o+VN9xgZXT/QLrvN/nv1ZN4=", + }, + // These items correspond to an entry in sample_revocations.txt where: + // isser name is the base-64 encoded subject DN for the shared Test + // Intermediate and the serialNumbers are base-64 encoded 78 and 31, + // respectively. + // We need this to ensure that existing items are retained if they're + // also in the blocklist + { + issuerName: "MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRl", + serialNumber: "Tg==", + }, + { + issuerName: "MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRl", + serialNumber: "Hw==", + }, + // This item revokes same-issuer-ee.pem by subject and pubKeyHash. + { + subject: "MCIxIDAeBgNVBAMMF0Fub3RoZXIgVGVzdCBFbmQtZW50aXR5", + pubKeyHash: "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8=", + }, +]; + +function verify_cert(file, expectedError) { + let ee = constructCertFromFile(file); + return checkCertErrorGeneric( + certDB, + ee, + expectedError, + certificateUsageSSLServer + ); +} + +// The certificate blocklist currently only applies to TLS server certificates. +async function verify_non_tls_usage_succeeds(file) { + let ee = constructCertFromFile(file); + await checkCertErrorGeneric( + certDB, + ee, + PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certDB, + ee, + PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certDB, + ee, + PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); +} + +function load_cert(cert, trust) { + let file = "bad_certs/" + cert + ".pem"; + addCertFromFile(certDB, file, trust); +} + +async function update_blocklist() { + const { OneCRLBlocklistClient } = RemoteSecuritySettings.init(); + + const fakeEvent = { + current: certBlocklist, // with old .txt revocations. + deleted: [], + created: certBlocklist, // with new cert storage. + updated: [], + }; + await OneCRLBlocklistClient.emit("sync", { data: fakeEvent }); + // Save the last check timestamp, used by cert_storage to assert + // if the blocklist is «fresh». + Services.prefs.setIntPref( + OneCRLBlocklistClient.lastCheckTimePref, + Math.floor(Date.now() / 1000) + ); +} + +function* generate_revocations_txt_lines() { + let profile = do_get_profile(); + let revocations = profile.clone(); + revocations.append("revocations.txt"); + ok(revocations.exists(), "the revocations file should exist"); + let inputStream = Cc[ + "@mozilla.org/network/file-input-stream;1" + ].createInstance(Ci.nsIFileInputStream); + inputStream.init(revocations, -1, -1, 0); + inputStream.QueryInterface(Ci.nsILineInputStream); + let hasmore = false; + do { + let line = {}; + hasmore = inputStream.readLine(line); + yield line.value; + } while (hasmore); +} + +function run_test() { + // import the certificates we need + load_cert("test-ca", "CTu,CTu,CTu"); + load_cert("test-int", ",,"); + load_cert("other-test-ca", "CTu,CTu,CTu"); + + let certList = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + + add_task(async function() { + // check some existing items in revocations.txt are blocked. + // This test corresponds to: + // issuer: MBIxEDAOBgNVBAMMB1Rlc3QgQ0E= (CN=Test CA) + // serial: Kg== (42) + let file = "test_onecrl/ee-revoked-by-revocations-txt.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // This test corresponds to: + // issuer: MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRl (CN=Test Intermediate) + // serial: Tg== (78) + file = "test_onecrl/another-ee-revoked-by-revocations-txt.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // And this test corresponds to: + // issuer: MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRl (CN=Test Intermediate) + // serial: Hw== (31) + // (we test this issuer twice to ensure we can read multiple serials) + file = "test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // Test that a certificate revoked by subject and public key hash in + // revocations.txt is revoked + // subject: MCsxKTAnBgNVBAMMIEVFIFJldm9rZWQgQnkgU3ViamVjdCBhbmQgUHViS2V5 + // (CN=EE Revoked By Subject and PubKey) + // pubkeyhash: VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8 (this is the + // shared RSA SPKI) + file = "test_onecrl/ee-revoked-by-subject-and-pubkey.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // Soon we'll load a blocklist which revokes test-int.pem, which issued + // test-int-ee.pem. + // Check the cert validates before we load the blocklist + file = "test_onecrl/test-int-ee.pem"; + await verify_cert(file, PRErrorCodeSuccess); + + // The blocklist also revokes other-test-ca.pem, which issued + // other-ca-ee.pem. Check the cert validates before we load the blocklist + file = "bad_certs/other-issuer-ee.pem"; + await verify_cert(file, PRErrorCodeSuccess); + + // The blocklist will revoke same-issuer-ee.pem via subject / pubKeyHash. + // Check the cert validates before we load the blocklist + file = "test_onecrl/same-issuer-ee.pem"; + await verify_cert(file, PRErrorCodeSuccess); + }); + + // blocklist load is async so we must use add_test from here + add_task(update_blocklist); + + add_task(async function() { + // The blocklist will be loaded now. Let's check the data is sane. + // In particular, we should still have the revoked issuer / serial pair + // that was in revocations.txt but not the blocklist. + let file = "test_onecrl/ee-revoked-by-revocations-txt.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // We should also still have the revoked issuer / serial pairs that were in + // revocations.txt and are also in the blocklist. + file = "test_onecrl/another-ee-revoked-by-revocations-txt.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + file = "test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // The cert revoked by subject and pubkeyhash should still be revoked. + file = "test_onecrl/ee-revoked-by-subject-and-pubkey.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + + // Check the blocklisted intermediate now causes a failure + file = "test_onecrl/test-int-ee.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + await verify_non_tls_usage_succeeds(file); + + // Check the ee with the blocklisted root also causes a failure + file = "bad_certs/other-issuer-ee.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + await verify_non_tls_usage_succeeds(file); + + // Check the ee blocked by subject / pubKey causes a failure + file = "test_onecrl/same-issuer-ee.pem"; + await verify_cert(file, SEC_ERROR_REVOKED_CERTIFICATE); + await verify_non_tls_usage_succeeds(file); + + // Check a non-blocklisted chain still validates OK + file = "bad_certs/default-ee.pem"; + await verify_cert(file, PRErrorCodeSuccess); + + // Check a bad cert is still bad (unknown issuer) + file = "bad_certs/unknownissuer.pem"; + await verify_cert(file, SEC_ERROR_UNKNOWN_ISSUER); + }); + + add_task(async function() { + ok(certList.isBlocklistFresh(), "Blocklist should be fresh."); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_cert_storage_broken_db.js b/security/manager/ssl/tests/unit/test_cert_storage_broken_db.js new file mode 100644 index 0000000000..070482f236 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_broken_db.js @@ -0,0 +1,95 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +"use strict"; + +// This file tests cert_storage's automatic database recreation mechanism. If +// opening the database for the first time fails, cert_storage will re-create +// it. + +function call_has_prior_data(certStorage, type) { + return new Promise(resolve => { + certStorage.hasPriorData(type, (rv, hasPriorData) => { + Assert.equal(rv, Cr.NS_OK, "hasPriorData should succeed"); + resolve(hasPriorData); + }); + }); +} + +async function check_has_prior_revocation_data(certStorage, expectedResult) { + let hasPriorRevocationData = await call_has_prior_data( + certStorage, + Ci.nsICertStorage.DATA_TYPE_REVOCATION + ); + Assert.equal( + hasPriorRevocationData, + expectedResult, + `should ${expectedResult ? "have" : "not have"} prior revocation data` + ); +} + +async function check_has_prior_cert_data(certStorage, expectedResult) { + let hasPriorCertData = await call_has_prior_data( + certStorage, + Ci.nsICertStorage.DATA_TYPE_CERTIFICATE + ); + Assert.equal( + hasPriorCertData, + expectedResult, + `should ${expectedResult ? "have" : "not have"} prior cert data` + ); +} + +async function check_has_prior_crlite_data(certStorage, expectedResult) { + let hasPriorCRLiteData = await call_has_prior_data( + certStorage, + Ci.nsICertStorage.DATA_TYPE_CRLITE + ); + Assert.equal( + hasPriorCRLiteData, + expectedResult, + `should ${expectedResult ? "have" : "not have"} prior CRLite data` + ); +} + +add_task(async function() { + // Create an invalid database. + let fileToCopy = do_get_file("test_cert_storage_broken_db.js"); + let dbDirectory = do_get_profile(); + dbDirectory.append("security_state"); + fileToCopy.copyTo(dbDirectory, "data.mdb"); + + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + check_has_prior_revocation_data(certStorage, false); + check_has_prior_cert_data(certStorage, false); + check_has_prior_crlite_data(certStorage, false); + + let result = await new Promise(resolve => { + certStorage.setRevocations([], resolve); + }); + Assert.equal(result, Cr.NS_OK, "setRevocations should succeed"); + + check_has_prior_revocation_data(certStorage, true); + check_has_prior_cert_data(certStorage, false); + check_has_prior_crlite_data(certStorage, false); + + result = await new Promise(resolve => { + certStorage.addCerts([], resolve); + }); + Assert.equal(result, Cr.NS_OK, "addCerts should succeed"); + + check_has_prior_revocation_data(certStorage, true); + check_has_prior_cert_data(certStorage, true); + check_has_prior_crlite_data(certStorage, false); + + result = await new Promise(resolve => { + certStorage.setCRLiteState([], resolve); + }); + Assert.equal(result, Cr.NS_OK, "setCRLiteState should succeed"); + check_has_prior_revocation_data(certStorage, true); + check_has_prior_cert_data(certStorage, true); + check_has_prior_crlite_data(certStorage, true); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct.js b/security/manager/ssl/tests/unit/test_cert_storage_direct.js new file mode 100644 index 0000000000..09d8a5bd17 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct.js @@ -0,0 +1,533 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +"use strict"; + +// This file consists of unit tests for cert_storage (whereas test_cert_storage.js is more of an +// integration test). + +do_get_profile(); + +this.certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage +); + +async function addCerts(certInfos) { + let result = await new Promise(resolve => { + certStorage.addCerts(certInfos, resolve); + }); + Assert.equal(result, Cr.NS_OK, "addCerts should succeed"); +} + +async function removeCertsByHashes(hashesBase64) { + let result = await new Promise(resolve => { + certStorage.removeCertsByHashes(hashesBase64, resolve); + }); + Assert.equal(result, Cr.NS_OK, "removeCertsByHashes should succeed"); +} + +function getLongString(uniquePart, length) { + return String(uniquePart).padStart(length, "0"); +} + +class CertInfo { + constructor(cert, subject) { + this.cert = btoa(cert); + this.subject = btoa(subject); + this.trust = Ci.nsICertStorage.TRUST_INHERIT; + } +} +CertInfo.prototype.QueryInterface = ChromeUtils.generateQI(["nsICertInfo"]); + +add_task(async function test_common_subject() { + let someCert1 = new CertInfo( + "some certificate bytes 1", + "some common subject" + ); + let someCert2 = new CertInfo( + "some certificate bytes 2", + "some common subject" + ); + let someCert3 = new CertInfo( + "some certificate bytes 3", + "some common subject" + ); + await addCerts([someCert1, someCert2, someCert3]); + let storedCerts = certStorage.findCertsBySubject( + stringToArray("some common subject") + ); + let storedCertsAsStrings = storedCerts.map(arrayToString); + let expectedCerts = [ + "some certificate bytes 1", + "some certificate bytes 2", + "some certificate bytes 3", + ]; + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should find expected certs" + ); + + await addCerts([ + new CertInfo("some other certificate bytes", "some other subject"), + ]); + storedCerts = certStorage.findCertsBySubject( + stringToArray("some common subject") + ); + storedCertsAsStrings = storedCerts.map(arrayToString); + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should still find expected certs" + ); + + let storedOtherCerts = certStorage.findCertsBySubject( + stringToArray("some other subject") + ); + let storedOtherCertsAsStrings = storedOtherCerts.map(arrayToString); + let expectedOtherCerts = ["some other certificate bytes"]; + Assert.deepEqual( + storedOtherCertsAsStrings, + expectedOtherCerts, + "should have other certificate" + ); +}); + +add_task(async function test_many_entries() { + const NUM_CERTS = 500; + const CERT_LENGTH = 3000; + const SUBJECT_LENGTH = 40; + let certs = []; + for (let i = 0; i < NUM_CERTS; i++) { + certs.push( + new CertInfo( + getLongString(i, CERT_LENGTH), + getLongString(i, SUBJECT_LENGTH) + ) + ); + } + await addCerts(certs); + for (let i = 0; i < NUM_CERTS; i++) { + let subject = stringToArray(getLongString(i, SUBJECT_LENGTH)); + let storedCerts = certStorage.findCertsBySubject(subject); + Assert.equal( + storedCerts.length, + 1, + "should have 1 certificate (lots of data test)" + ); + let storedCertAsString = arrayToString(storedCerts[0]); + Assert.equal( + storedCertAsString, + getLongString(i, CERT_LENGTH), + "certificate should be as expected (lots of data test)" + ); + } +}); + +add_task(async function test_removal() { + // As long as cert_storage is given valid base64, attempting to delete some nonexistent + // certificate will "succeed" (it'll do nothing). + await removeCertsByHashes([btoa("thishashisthewrongsize")]); + + let removalCert1 = new CertInfo( + "removal certificate bytes 1", + "common subject to remove" + ); + let removalCert2 = new CertInfo( + "removal certificate bytes 2", + "common subject to remove" + ); + let removalCert3 = new CertInfo( + "removal certificate bytes 3", + "common subject to remove" + ); + await addCerts([removalCert1, removalCert2, removalCert3]); + + let storedCerts = certStorage.findCertsBySubject( + stringToArray("common subject to remove") + ); + let storedCertsAsStrings = storedCerts.map(arrayToString); + let expectedCerts = [ + "removal certificate bytes 1", + "removal certificate bytes 2", + "removal certificate bytes 3", + ]; + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should find expected certs before removing them" + ); + + // echo -n "removal certificate bytes 2" | sha256sum | xxd -r -p | base64 + await removeCertsByHashes(["2nUPHwl5TVr1mAD1FU9FivLTlTb0BAdnVUhsYgBccN4="]); + storedCerts = certStorage.findCertsBySubject( + stringToArray("common subject to remove") + ); + storedCertsAsStrings = storedCerts.map(arrayToString); + expectedCerts = [ + "removal certificate bytes 1", + "removal certificate bytes 3", + ]; + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should only have first and third certificates now" + ); + + // echo -n "removal certificate bytes 1" | sha256sum | xxd -r -p | base64 + await removeCertsByHashes(["8zoRqHYrklr7Zx6UWpzrPuL+ol8KL1Ml6XHBQmXiaTY="]); + storedCerts = certStorage.findCertsBySubject( + stringToArray("common subject to remove") + ); + storedCertsAsStrings = storedCerts.map(arrayToString); + expectedCerts = ["removal certificate bytes 3"]; + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should only have third certificate now" + ); + + // echo -n "removal certificate bytes 3" | sha256sum | xxd -r -p | base64 + await removeCertsByHashes(["vZn7GwDSabB/AVo0T+N26nUsfSXIIx4NgQtSi7/0p/w="]); + storedCerts = certStorage.findCertsBySubject( + stringToArray("common subject to remove") + ); + Assert.equal(storedCerts.length, 0, "shouldn't have any certificates now"); + + // echo -n "removal certificate bytes 3" | sha256sum | xxd -r -p | base64 + // Again, removing a nonexistent certificate should "succeed". + await removeCertsByHashes(["vZn7GwDSabB/AVo0T+N26nUsfSXIIx4NgQtSi7/0p/w="]); +}); + +add_task(async function test_batched_removal() { + let removalCert1 = new CertInfo( + "batch removal certificate bytes 1", + "batch subject to remove" + ); + let removalCert2 = new CertInfo( + "batch removal certificate bytes 2", + "batch subject to remove" + ); + let removalCert3 = new CertInfo( + "batch removal certificate bytes 3", + "batch subject to remove" + ); + await addCerts([removalCert1, removalCert2, removalCert3]); + let storedCerts = certStorage.findCertsBySubject( + stringToArray("batch subject to remove") + ); + let storedCertsAsStrings = storedCerts.map(arrayToString); + let expectedCerts = [ + "batch removal certificate bytes 1", + "batch removal certificate bytes 2", + "batch removal certificate bytes 3", + ]; + Assert.deepEqual( + storedCertsAsStrings.sort(), + expectedCerts.sort(), + "should find expected certs before removing them" + ); + // echo -n "batch removal certificate bytes 1" | sha256sum | xxd -r -p | base64 + // echo -n "batch removal certificate bytes 2" | sha256sum | xxd -r -p | base64 + // echo -n "batch removal certificate bytes 3" | sha256sum | xxd -r -p | base64 + await removeCertsByHashes([ + "EOEEUTuanHZX9NFVCoMKVT22puIJC6g+ZuNPpJgvaa8=", + "Xz6h/Kvn35cCLJEZXkjPqk1GG36b56sreLyAXpO+0zg=", + "Jr7XdiTT8ZONUL+ogNNMW2oxKxanvYOLQPKBPgH/has=", + ]); + storedCerts = certStorage.findCertsBySubject( + stringToArray("batch subject to remove") + ); + Assert.equal(storedCerts.length, 0, "shouldn't have any certificates now"); +}); + +class CRLiteState { + constructor(subject, spkiHash, state) { + this.subject = btoa(subject); + this.spkiHash = spkiHash; + this.state = state; + } +} +CRLiteState.prototype.QueryInterface = ChromeUtils.generateQI([ + "nsICRLiteState", +]); + +async function addCRLiteState(state) { + let result = await new Promise(resolve => { + certStorage.setCRLiteState(state, resolve); + }); + Assert.equal(result, Cr.NS_OK, "setCRLiteState should succeed"); +} + +add_task(async function test_crlite_state() { + // echo -n "some spki 1" | sha256sum | xxd -r -p | base64 + let crliteState1 = new CRLiteState( + "some subject 1", + "bDlKlhR5ptlvuxclnZ3RQHznG8/3pgIybrRJ/Zvn9L8=", + Ci.nsICertStorage.STATE_ENFORCE + ); + // echo -n "some spki 2" | sha256sum | xxd -r -p | base64 + let crliteState2 = new CRLiteState( + "some subject 2", + "ZlXvlHhtdx4yKwkhZqg7Opv5T1ofwzorlsCoLf0wnlY=", + Ci.nsICertStorage.STATE_UNSET + ); + // echo -n "some spki 3" | sha256sum | xxd -r -p | base64 + let crliteState3 = new CRLiteState( + "some subject 3", + "pp1SRn6njaHX/c+b2uf82JPeBkWhPfTBp/Mxb3xkjRM=", + Ci.nsICertStorage.STATE_ENFORCE + ); + await addCRLiteState([crliteState1, crliteState2, crliteState3]); + + let state1 = certStorage.getCRLiteState( + stringToArray("some subject 1"), + stringToArray("some spki 1") + ); + Assert.equal(state1, Ci.nsICertStorage.STATE_ENFORCE); + let state2 = certStorage.getCRLiteState( + stringToArray("some subject 2"), + stringToArray("some spki 2") + ); + Assert.equal(state2, Ci.nsICertStorage.STATE_UNSET); + let state3 = certStorage.getCRLiteState( + stringToArray("some subject 3"), + stringToArray("some spki 3") + ); + Assert.equal(state3, Ci.nsICertStorage.STATE_ENFORCE); + + // Check that if we never set the state of a particular subject/spki pair, we get "unset" when we + // look it up. + let stateNeverSet = certStorage.getCRLiteState( + stringToArray("some unknown subject"), + stringToArray("some unknown spki") + ); + Assert.equal(stateNeverSet, Ci.nsICertStorage.STATE_UNSET); + + // "some subject 1"/"some spki 1" and "some subject 3"/"some spki 3" both have their CRLite state + // set. However, the combination of "some subject 3"/"some spki1" should not. + let stateDifferentSubjectSPKI = certStorage.getCRLiteState( + stringToArray("some subject 3"), + stringToArray("some spki 1") + ); + Assert.equal(stateDifferentSubjectSPKI, Ci.nsICertStorage.STATE_UNSET); + + let anotherStateDifferentSubjectSPKI = certStorage.getCRLiteState( + stringToArray("some subject 1"), + stringToArray("some spki 2") + ); + Assert.equal(anotherStateDifferentSubjectSPKI, Ci.nsICertStorage.STATE_UNSET); + let yetAnotherStateDifferentSubjectSPKI = certStorage.getCRLiteState( + stringToArray("some subject 2"), + stringToArray("some spki 1") + ); + Assert.equal( + yetAnotherStateDifferentSubjectSPKI, + Ci.nsICertStorage.STATE_UNSET + ); + + crliteState3 = new CRLiteState( + "some subject 3", + "pp1SRn6njaHX/c+b2uf82JPeBkWhPfTBp/Mxb3xkjRM=", + Ci.nsICertStorage.STATE_UNSET + ); + await addCRLiteState([crliteState3]); + state3 = certStorage.getCRLiteState( + stringToArray("some subject 3"), + stringToArray("some spki 3") + ); + Assert.equal(state3, Ci.nsICertStorage.STATE_UNSET); + + crliteState2 = new CRLiteState( + "some subject 2", + "ZlXvlHhtdx4yKwkhZqg7Opv5T1ofwzorlsCoLf0wnlY=", + Ci.nsICertStorage.STATE_ENFORCE + ); + await addCRLiteState([crliteState2]); + state2 = certStorage.getCRLiteState( + stringToArray("some subject 2"), + stringToArray("some spki 2") + ); + Assert.equal(state2, Ci.nsICertStorage.STATE_ENFORCE); + + // Inserting a subject/spki pair with a state value outside of our expected + // values will succeed. However, since our data type is a signed 16-bit value, + // values outside that range will be truncated. The least significant 16 bits + // of 2013003773 are FFFD, which when interpreted as a signed 16-bit integer + // comes out to -3. + // echo -n "some spki 4" | sha256sum | xxd -r -p | base64 + let bogusValueState = new CRLiteState( + "some subject 4", + "1eA0++hCqzt8vpzREYSqHAqpEOLchZca1Gx8viCVYzc=", + 2013003773 + ); + await addCRLiteState([bogusValueState]); + let bogusValueStateValue = certStorage.getCRLiteState( + stringToArray("some subject 4"), + stringToArray("some spki 4") + ); + Assert.equal(bogusValueStateValue, -3); +}); + +async function enrollCertForCRLite(nsCert) { + let { subjectString, spkiHashString } = getSubjectAndSPKIHash(nsCert); + let crliteState = new CRLiteState( + subjectString, + spkiHashString, + Ci.nsICertStorage.STATE_ENFORCE + ); + await addCRLiteState([crliteState]); +} + +add_task(async function test_crlite_filter() { + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let validCertIssuer = constructCertFromFile( + "test_cert_storage_direct/valid-cert-issuer.pem" + ); + await enrollCertForCRLite(validCertIssuer); + let validCert = constructCertFromFile( + "test_cert_storage_direct/valid-cert.pem" + ); + let revokedCertIssuer = constructCertFromFile( + "test_cert_storage_direct/revoked-cert-issuer.pem" + ); + await enrollCertForCRLite(revokedCertIssuer); + let revokedCert = constructCertFromFile( + "test_cert_storage_direct/revoked-cert.pem" + ); + + let filterFile = do_get_file( + "test_cert_storage_direct/test-filter.crlite", + false + ); + ok(filterFile.exists(), "test filter file should exist"); + let filterBytes = stringToArray(readFile(filterFile)); + // First simulate the filter being from before the certificates being tested are valid. With + // CRLite enabled, none of the certificates should appear to be revoked. + let setFullCRLiteFilterResult = await new Promise(resolve => { + certStorage.setFullCRLiteFilter( + filterBytes, + new Date("2017-10-28T00:00:00Z").getTime() / 1000, + resolve + ); + }); + Assert.equal( + setFullCRLiteFilterResult, + Cr.NS_OK, + "setFullCRLiteFilter should succeed" + ); + + Services.prefs.setIntPref( + "security.pki.crlite_mode", + CRLiteModeEnforcePrefValue + ); + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "skynew.jp", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "schunk-group.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + + // Now "replace" the filter with a more recent one. The revoked certificate should be revoked. + setFullCRLiteFilterResult = await new Promise(resolve => { + certStorage.setFullCRLiteFilter( + filterBytes, + new Date("2019-10-28T00:00:00Z").getTime() / 1000, + resolve + ); + }); + Assert.equal( + setFullCRLiteFilterResult, + Cr.NS_OK, + "setFullCRLiteFilter should succeed" + ); + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "skynew.jp", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "schunk-group.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + + // If we're only collecting telemetry, none of the certificates should appear to be revoked. + Services.prefs.setIntPref( + "security.pki.crlite_mode", + CRLiteModeTelemetryOnlyPrefValue + ); + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "skynew.jp", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "schunk-group.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + + // If CRLite is disabled, none of the certificates should appear to be revoked. + Services.prefs.setIntPref( + "security.pki.crlite_mode", + CRLiteModeDisabledPrefValue + ); + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "skynew.jp", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "schunk-group.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert-issuer.pem b/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert-issuer.pem new file mode 100644 index 0000000000..d775817b33 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert-issuer.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEoDCCA4igAwIBAgIQBpaPlkroI1bHThfCtTZbADANBgkqhkiG9w0BAQsFADBs +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j +ZSBFViBSb290IENBMB4XDTE3MTEwNjEyMjI1N1oXDTI3MTEwNjEyMjI1N1owXzEL +MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 +LmRpZ2ljZXJ0LmNvbTEeMBwGA1UEAxMVVGhhd3RlIEVWIFJTQSBDQSAyMDE4MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp0Cu52zmdJFnSezXMKvL0rso +WgA/1X7OxjMQHsAllID1eDG836ptJXSTPg+DoEenHfkKyw++wXobgahr0cU/2v8R +WR3fID53ZDhEGHzS+Ol7V+HRtZG5teMWCY7gldtBQH0r7xUEp/3ISVsZUVBqtUmL +VJlf9nxJD6Cxp4LBlcJJ8+N6kSkV+fA+WdQc0HYhXSg3PxJP7XSU28Wc7gf6y9kZ +zQhK4WrZLRrHHbHC2QXdqQYUxR927QV+UCNXnlbTcZy2QpxWTPLzK+/cKXX4cwP6 +MGF7+8RnUgHlij/5V2k/tIF9ep4B72ucqaS/UhEPpIN/T7A3OAw995yrB38glQID +AQABo4IBSTCCAUUwHQYDVR0OBBYEFOcB/AwWGMp9sozshyejb2GBO4Q5MB8GA1Ud +IwQYMBaAFLE+w2kD+L9HAdSYJhoIAu9jZCvDMA4GA1UdDwEB/wQEAwIBhjAdBgNV +HSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBADA0 +BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0 +LmNvbTBLBgNVHR8ERDBCMECgPqA8hjpodHRwOi8vY3JsMy5kaWdpY2VydC5jb20v +RGlnaUNlcnRIaWdoQXNzdXJhbmNlRVZSb290Q0EuY3JsMD0GA1UdIAQ2MDQwMgYE +VR0gADAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BT +MA0GCSqGSIb3DQEBCwUAA4IBAQAWGka+5ffLpfFuzT+WlwDRwhyTZSunnvecZWZT +PPKXipynjpXx5dK8YG+2XoH74285GR1UABuvHMFV94XeDET9Pzz5s/NHS1/eAr5e +GdwfBl80XwPkwXaYqzRtw6J4RAxeLqcbibhUQv9Iev9QcP0kNPyJu413Xov76mSu +JlGThKzcurJPive2eLmwmoIgTPH11N/IIO9nHLVe8KTkt+FGgZCOWHA3kbFBZR39 +Mn2hFS974rhUkM+VS9KbCiQQ5OwkfbZ/6BINkE1CMtiESZ2WkbxJKPsF3dN7p9DF +YWiQSbYjFP+rCT0/MkaHHYUkEvLNPgyJ6z29eMf0DjLu/SXJ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert.pem b/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert.pem new file mode 100644 index 0000000000..81e01bd783 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct/revoked-cert.pem @@ -0,0 +1,41 @@ +-----BEGIN CERTIFICATE----- +MIIHOzCCBiOgAwIBAgIQBi31aKBRMQgg1+xDJ+G6/TANBgkqhkiG9w0BAQsFADBf +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMR4wHAYDVQQDExVUaGF3dGUgRVYgUlNBIENBIDIwMTgw +HhcNMTgwNTI4MDAwMDAwWhcNMjAwNTIxMTIwMDAwWjCB6zEdMBsGA1UEDwwUUHJp +dmF0ZSBPcmdhbml6YXRpb24xEzARBgsrBgEEAYI3PAIBAxMCREUxFjAUBgsrBgEE +AYI3PAIBAhMFSGVzc2UxGDAWBgsrBgEEAYI3PAIBAQwHR2llw59lbjERMA8GA1UE +BRMISFJCIDY5MDIxCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZIZXNzZW4xFDASBgNV +BAcTC0hldWNoZWxoZWltMRQwEgYDVQQKEwtTY2h1bmsgR21iSDELMAkGA1UECxMC +SVQxGTAXBgNVBAMTEHNjaHVuay1ncm91cC5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQCvkuQZz2ExPv9paJb622OOk+o4bWnjDe1zHGK6qnK25mMT +Zldk74sXF+Wfr9lbwqHTcjGhQFwmVDqvtr55KVX8FOv0CSqNaewOrnNrFz8Xg4rn +OlIs3+MmqD5CIK+el0rA+xltEY8WvNlwZKG7yeJYrdsr+5DAThDuwCVe8bU7it4h +sjsMsof5ocee9zDkFThNVGR4sMk5EgBxb1Gt4n9wXUj4OBT78whhlkLH/pVZrrhs +tQwC3q90MOPC5RJcEolSCNjGdHCKRbexmRqJgbJj/qZ9JT+fQ+Ko6a+UAWvc2BUc +POnzGV2GzCdFFGOubJb6RjU0nuPG4Lmdc/BuS9kFAgMBAAGjggNkMIIDYDAfBgNV +HSMEGDAWgBTnAfwMFhjKfbKM7Icno29hgTuEOTAdBgNVHQ4EFgQUNb1SY8Bkil98 +tD8zoxE30jBA1NIwZwYDVR0RBGAwXoIQc2NodW5rLWdyb3VwLmNvbYIUd3d3LnNj +aHVuay1ncm91cC5jb22CG3NjaHVuay1jYXJib250ZWNobm9sb2d5LmNvbYIXc2No +dW5rLXNpbnRlcm1ldGFscy5jb20wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQG +CCsGAQUFBwMBBggrBgEFBQcDAjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vY2Rw +LnRoYXd0ZS5jb20vVGhhd3RlRVZSU0FDQTIwMTguY3JsMEsGA1UdIAREMEIwNwYJ +YIZIAYb9bAIBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNv +bS9DUFMwBwYFZ4EMAQEwcQYIKwYBBQUHAQEEZTBjMCQGCCsGAQUFBzABhhhodHRw +Oi8vc3RhdHVzLnRoYXd0ZS5jb20wOwYIKwYBBQUHMAKGL2h0dHA6Ly9jYWNlcnRz +LnRoYXd0ZS5jb20vVGhhd3RlRVZSU0FDQTIwMTguY3J0MAkGA1UdEwQCMAAwggF7 +BgorBgEEAdZ5AgQCBIIBawSCAWcBZQB1AKS5CZC0GFgUh7sTosxncAo8NZgE+Rvf +uON3zQ7IDdwQAAABY6Ze9XAAAAQDAEYwRAIgNUeXL3GwlpGQtTS/wKBlOkHJvHR5 +knSop0OPumeCfQECIEdxY7qr/WRVbWkQFvP48fgWkZHkd4vTq70Y0aaSZTbPAHUA +VhQGmi/XwuzT9eG9RLI+x0Z2ubyZEVzA75SYVdaJ0N0AAAFjpl71tQAABAMARjBE +AiAtxKdc/wum3TE7r9BoRd/gkrjYLWyqeLuL/opRBRy9xwIgPF6uEZxyhEoLZ+9G +AFBAP+X89zjZphVALjIXu0RRea4AdQC72d+8H4pxtZOUI5eqkntHOFeVCqtS6BqQ +lmQ2jh7RhQAAAWOmXvY1AAAEAwBGMEQCIHc04ERlUbIkVrlC+I89C9xtugvRCwbR +a7qZzSdqHltUAiBRVwTacf1dnO9AgLSgrxft5LV32DvH3qNT7pWYh8dFNjANBgkq +hkiG9w0BAQsFAAOCAQEARJ+tbnM+yS6chgpyzfB3e7IWPq2Den46Ja1H6/4qaKrd +nsbElcvd4cCQf1zYY6jlQkO6qtfMUChKrEar5aqqnyX8x/8T9PkpHp8XyUxgGlmT +hrnHML0gDJFS8O4MB5pFnGkgoOQa+OIQokWCXr4/a4AwsTG3Ms+lC+R+vRYz90lg +TEJLNHB2fSvQyvpXDUL9aAjACBp/9pKxfM9iq06MFO5jP483xJUfdqtVteHMw75w +1mb8IrM9R1dP47GsblTrf2rZYdaoxdyLjtJQG2aaOdU5unE6QeFrXbz0qeTPePs8 +ftuXSW9xb053HjAkCcVo48j07b2cHfU1hxzGGptVbQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.crlite b/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.crlite new file mode 100644 index 0000000000..34ced4b840 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.crlite differ diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.stash b/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.stash new file mode 100644 index 0000000000..1dbea0be47 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_storage_direct/test-filter.stash differ diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert-issuer.pem b/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert-issuer.pem new file mode 100644 index 0000000000..705827a85e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert-issuer.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEkDCCA3igAwIBAgIJIrmxUyPlrv3NMA0GCSqGSIb3DQEBCwUAMF0xCzAJBgNV +BAYTAkpQMSUwIwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScw +JQYDVQQLEx5TZWN1cml0eSBDb21tdW5pY2F0aW9uIFJvb3RDQTIwHhcNMTgwODIy +MDczMjI0WhcNMjgwODIyMDczMjI0WjBQMQswCQYDVQQGEwJKUDElMCMGA1UEChMc +U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEaMBgGA1UEAxMRQ3Jvc3NUcnVz +dCBEViBDQTUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnTNi5Kgrt +FL8qBuEmpL2gvLFY7f9MEgjzClvic/45ebM+DxZ2CMuqtMtImgf8XPIpLaFFbozx +3VgqH41cmGHbpAoDRKpwfF1f53peHYhRxpOVgcnsiVCPZJPBPCUM9St+cuEjfo0d +YGbr3aG5urdT2zeKIFyxKbggdkU0LVRHwvLFsIpXCn/YK/8Rmx87yW9VB80OXkzf +IQoZop83+aebq1VwzjNCN3u4bWSFLYDyJGqE40WlZ53NZh+TwBsa6gld9YXPGQfx +k8x38zkFXberlMQOYhX9KyuTOMdlFkbx6LfIUqVKJavpcr54+XPzVyeroNPpKxtZ +mEqUYiFjAqUVAgMBAAGjggFeMIIBWjAdBgNVHQ4EFgQUT4twz6lAHJbllF13rNZv +TS2b8ncwHwYDVR0jBBgwFoAUCoWpd2UFmHxAgfgPlyw48QrsPM8wEgYDVR0TAQH/ +BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwSQYDVR0fBEIwQDA+oDygOoY4aHR0 +cDovL3JlcG9zaXRvcnkuc2Vjb210cnVzdC5uZXQvU0MtUm9vdDIvU0NSb290MkNS +TC5jcmwwUgYDVR0gBEswSTBHBgoqgwiMmxtkhwUEMDkwNwYIKwYBBQUHAgEWK2h0 +dHBzOi8vcmVwb3NpdG9yeS5zZWNvbXRydXN0Lm5ldC9TQy1Sb290Mi8wQAYIKwYB +BQUHAQEENDAyMDAGCCsGAQUFBzABhiRodHRwOi8vc2Nyb290Y2EyLm9jc3Auc2Vj +b210cnVzdC5uZXQwEwYDVR0lBAwwCgYIKwYBBQUHAwEwDQYJKoZIhvcNAQELBQAD +ggEBABEDSrrhhR+Js5q45yih2Ne4cMLZmrH0AZwU3eM+7HZplzi1EhppgvcYk/2k +LM9haQGWnAZ5wiixLqKu7WlWrHgblZbXyCxALmMBK1rqeP0omxXExqKVqWNHU8KZ +t3jahH1wDYSzfetM7guWR+PAPpb9oQCtAx8DVyI/3Ocswvti/uWb517Bdo6Nd0+9 +mf0LiphNKcSzSFX0s1Cb47cJROYHGBe2J6NUSWR7wE0asPtKsznGyNO+NJCUR+0h +OLN2cA2KJwPhZjYJt8UkucAF/EE7qC0Fc8B9Q/gttQ52en5BZxdkDrHCi4qnsSvi +gueQme/RzYkEaQlNT1WCZ9AIgVE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert.pem b/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert.pem new file mode 100644 index 0000000000..195d2d8ca2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_direct/valid-cert.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF4DCCBMigAwIBAgIQC3d196+a5UJlyc0yVxB3jjANBgkqhkiG9w0BAQsFADBQ +MQswCQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4s +TFRELjEaMBgGA1UEAxMRQ3Jvc3NUcnVzdCBEViBDQTUwHhcNMTkwNjExMDUyMjEy +WhcNMjEwNjMwMTQ1OTU5WjAUMRIwEAYDVQQDEwlza3luZXcuanAwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDeciw7C297026HA4oIwc29vL2h29GVrRF7 +HGdeXzAJA7kh+qwo8rTBFfdX7sgHy6nnE1+flEtFt91Ss8i3BZMEqoFUZFb1jGXd +DbQtmIWxz7O5skkjR1gdKwt9GImy1hEPt8dwU52mwVsSUEKvlZlsjeofUPAEbnYY ++iA/nYaYXiXyCxJzk6Y09VlzghyMIhkLwDa7rL3S9FgUQI6tSUwsiNYNoQzlYgXF +yPfQfd57LbBwZJtqVPC6rjPOZZd0sw7uvrDNuxnAM2k2mzlML9Vwt8EvSlZX60xD +oGQCsQQ/ZgjEQTA8WRZ+fxW/LqQNYYm70KU/1M+e8o4MKmA9xkH5AgMBAAGjggLw +MIIC7DAfBgNVHSMEGDAWgBRPi3DPqUAcluWUXXes1m9NLZvydzA8BggrBgEFBQcB +AQQwMC4wLAYIKwYBBQUHMAGGIGh0dHA6Ly9kdmNhNS5vY3NwLnNlY29tdHJ1c3Qu +bmV0MCMGA1UdEQQcMBqCCXNreW5ldy5qcIINd3d3LnNreW5ldy5qcDBaBgNVHSAE +UzBRMEUGCiqDCIybG26BVQIwNzA1BggrBgEFBQcCARYpaHR0cHM6Ly9yZXBvMS5z +ZWNvbXRydXN0Lm5ldC9zcHBjYS94dGR2NS8wCAYGZ4EMAQIBMBMGA1UdJQQMMAoG +CCsGAQUFBwMBMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9yZXBvMS5zZWNvbXRy +dXN0Lm5ldC9zcHBjYS94dGR2NS9mdWxsY3JsLmNybDAdBgNVHQ4EFgQUuj9305tQ +JIeVAQtsz9JHx3PTqaQwDgYDVR0PAQH/BAQDAgWgMIIBfgYKKwYBBAHWeQIEAgSC +AW4EggFqAWgAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWtF +Bb6pAAAEAwBHMEUCIHUQkmFzUh01r1Px/zWMZSL21dNNQwM+rN1z0gutxV3JAiEA +jSb2/GAm4+2qiNWDtx1EkHsMXjNW+5S4GhJePexjJR8AdgDuS723dc5guuFCaR+r +4Z5mow9+X7By2IMAxHuJeqj9ywAAAWtFBcdeAAAEAwBHMEUCIDVHdfP9wnVgz45l +eX80DpRCRNEV/OCDwfW+B0g/dveYAiEArbpLQb5Z9hul3r00kF2LrivNuI7kwEBy +MpkYsLtSPJoAdgBvU3asMfAxGdiZAKRRFf93FRwR2QLBACkGjbIImjfZEwAAAWtF +BdCQAAAEAwBHMEUCIE2GUo6x3qDrIhacnCmjikBCHF2yT6Fv5GAehZB569YCAiEA +vXwMXV8+y3xNFys+A6u9EjKiy8CTKv+SQxqsJ4s6jK0wDQYJKoZIhvcNAQELBQAD +ggEBAAzlm9W+N5fviTJ9wDsc5nXKYur3744V/cm75+8dUM61Rko1isK6IZt5aNPN +wOfhBsTzHHSYmAFMR9Xjoq8iDYZtIk01IGI6LEWuls9F2hVcERiHMWJOLTiH35xN +vRNTG0AbBdIpTX2sURsoCPJ+8DTnVUr3pTzXnIY4EQ4UXfANuYwceOHShF6UJo/L +PK0uRdHcd5SmMa03gFUdkTc9gU6PIEO/UgubazGh9xDBHtHECeleL+gpSfOP3SkF +7W1RgmbE6WJdVPlto7FRQtl2xIzHs/gNaPezqNKPHgFlx4c+ECTjPLqoW8LdeXu+ +N8dueJg1+h+lQifkmgl23DqEIiI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting.js b/security/manager/ssl/tests/unit/test_cert_storage_preexisting.js new file mode 100644 index 0000000000..153fdc56f6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_preexisting.js @@ -0,0 +1,59 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +"use strict"; + +// This file tests that cert_storage correctly persists its "has prior data" +// information across runs of the browser. +// (The test DB files for this test were created by running the test +// `test_cert_storage_broken_db.js` and copying them from that test's profile +// directory.) + +/* eslint-disable no-unused-vars */ +add_task(async function() { + let dbDirectory = do_get_profile(); + dbDirectory.append("security_state"); + let dbFile = do_get_file("test_cert_storage_preexisting/data.safe.bin"); + dbFile.copyTo(dbDirectory, "data.safe.bin"); + + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + let hasPriorRevocationData = await new Promise(resolve => { + certStorage.hasPriorData( + Ci.nsICertStorage.DATA_TYPE_REVOCATION, + (rv, hasPriorData) => { + Assert.equal(rv, Cr.NS_OK, "hasPriorData should succeed"); + resolve(hasPriorData); + } + ); + }); + Assert.equal( + hasPriorRevocationData, + true, + "should have prior revocation data" + ); + + let hasPriorCertData = await new Promise(resolve => { + certStorage.hasPriorData( + Ci.nsICertStorage.DATA_TYPE_CERTIFICATE, + (rv, hasPriorData) => { + Assert.equal(rv, Cr.NS_OK, "hasPriorData should succeed"); + resolve(hasPriorData); + } + ); + }); + Assert.equal(hasPriorCertData, true, "should have prior cert data"); + + let hasPriorCRLiteData = await new Promise(resolve => { + certStorage.hasPriorData( + Ci.nsICertStorage.DATA_TYPE_CRLITE, + (rv, hasPriorData) => { + Assert.equal(rv, Cr.NS_OK, "hasPriorData should succeed"); + resolve(hasPriorData); + } + ); + }); + Assert.equal(hasPriorCRLiteData, true, "should have prior cert data"); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.mdb b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.mdb new file mode 100644 index 0000000000..df4cb182a7 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.mdb differ diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.safe.bin b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.safe.bin new file mode 100644 index 0000000000..011ed93484 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/data.safe.bin differ diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting/lock.mdb b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/lock.mdb new file mode 100644 index 0000000000..dc4b50fdfc Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_storage_preexisting/lock.mdb differ diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite.js b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite.js new file mode 100644 index 0000000000..0c6ffbd459 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite.js @@ -0,0 +1,71 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +"use strict"; + +// This file tests that cert_storage correctly persists its information across +// runs of the browser specifically in the case of CRLite. +// (The test DB files for this test were created by running the test +// `test_cert_storage_direct.js` and copying them from that test's profile +// directory.) + +/* eslint-disable no-unused-vars */ +add_task(async function() { + Services.prefs.setIntPref( + "security.pki.crlite_mode", + CRLiteModeEnforcePrefValue + ); + + let dbDirectory = do_get_profile(); + dbDirectory.append("security_state"); + let dbFile = do_get_file( + "test_cert_storage_preexisting_crlite/data.safe.bin" + ); + dbFile.copyTo(dbDirectory, "data.safe.bin"); + let crliteFile = do_get_file( + "test_cert_storage_preexisting_crlite/crlite.filter" + ); + crliteFile.copyTo(dbDirectory, "crlite.filter"); + + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let validCertIssuer = constructCertFromFile( + "test_cert_storage_direct/valid-cert-issuer.pem" + ); + let validCert = constructCertFromFile( + "test_cert_storage_direct/valid-cert.pem" + ); + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2019-10-28T00:00:00Z").getTime() / 1000, + false, + "skynew.jp", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + + let revokedCertIssuer = constructCertFromFile( + "test_cert_storage_direct/revoked-cert-issuer.pem" + ); + let revokedCert = constructCertFromFile( + "test_cert_storage_direct/revoked-cert.pem" + ); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2019-11-04T00:00:00Z").getTime() / 1000, + false, + "schunk-group.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/crlite.filter b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/crlite.filter new file mode 100644 index 0000000000..34ced4b840 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/crlite.filter differ diff --git a/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/data.safe.bin b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/data.safe.bin new file mode 100644 index 0000000000..d96571f128 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_cert_storage_preexisting_crlite/data.safe.bin differ diff --git a/security/manager/ssl/tests/unit/test_cert_storage_prefs.js b/security/manager/ssl/tests/unit/test_cert_storage_prefs.js new file mode 100644 index 0000000000..ca7e06ece9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_storage_prefs.js @@ -0,0 +1,34 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +"use strict"; + +// Tests that cert_storage properly handles its preference values. + +function run_test() { + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + // Since none of our prefs start with values, looking them up will fail. cert_storage should use + // safe fallbacks. + ok( + !certStorage.isBlocklistFresh(), + "checking blocklist freshness shouldn't crash" + ); + + // If we set nonsensical values, cert_storage should still use safe fallbacks. + Services.prefs.setIntPref("services.blocklist.onecrl.checked", -2); + Services.prefs.setIntPref("security.onecrl.maximum_staleness_in_seconds", -7); + ok( + !certStorage.isBlocklistFresh(), + "checking blocklist freshness still shouldn't crash" + ); + + // Clearing prefs shouldn't cause failures. + Services.prefs.clearUserPref("services.blocklist.onecrl.checked"); + ok( + !certStorage.isBlocklistFresh(), + "checking blocklist freshness again shouldn't crash" + ); +} diff --git a/security/manager/ssl/tests/unit/test_cert_trust.js b/security/manager/ssl/tests/unit/test_cert_trust.js new file mode 100644 index 0000000000..43fbaa6174 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust.js @@ -0,0 +1,324 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function load_cert(cert_name, trust_string) { + let cert_filename = cert_name + ".pem"; + return addCertFromFile( + certdb, + "test_cert_trust/" + cert_filename, + trust_string + ); +} + +function setup_basic_trusts(ca_cert, int_cert) { + certdb.setCertTrust( + ca_cert, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL | Ci.nsIX509CertDB.TRUSTED_EMAIL + ); + + certdb.setCertTrust(int_cert, Ci.nsIX509Cert.CA_CERT, 0); +} + +async function test_ca_distrust(ee_cert, cert_to_modify_trust, isRootCA) { + // On reset most usages are successful + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); + + // Test of active distrust. No usage should pass. + setCertTrust(cert_to_modify_trust, "p,p,p"); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageEmailRecipient + ); + + // Trust set to T - trusted CA to issue client certs, where client cert is + // usageSSLClient. + setCertTrust(cert_to_modify_trust, "T,T,T"); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageSSLServer + ); + + // XXX(Bug 982340) + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageSSLClient + ); + + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); + + // Now tests on the SSL trust bit + setCertTrust(cert_to_modify_trust, "p,C,C"); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageSSLServer + ); + + // XXX(Bug 982340) + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); + + // Inherited trust SSL + setCertTrust(cert_to_modify_trust, ",C,C"); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageSSLServer + ); + // XXX(Bug 982340) + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); + + // Now tests on the EMAIL trust bit + setCertTrust(cert_to_modify_trust, "C,p,C"); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_UNTRUSTED_ISSUER, + certificateUsageEmailRecipient + ); + + // inherited EMAIL Trust + setCertTrust(cert_to_modify_trust, "C,,C"); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + SEC_ERROR_CA_CERT_INVALID, + certificateUsageSSLCA + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + isRootCA ? SEC_ERROR_UNKNOWN_ISSUER : PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); +} + +add_task(async function() { + let certList = ["ca", "int", "ee"]; + let loadedCerts = []; + for (let certName of certList) { + loadedCerts.push(load_cert(certName, ",,")); + } + + let ca_cert = loadedCerts[0]; + notEqual(ca_cert, null, "CA cert should have successfully loaded"); + let int_cert = loadedCerts[1]; + notEqual(int_cert, null, "Intermediate cert should have successfully loaded"); + let ee_cert = loadedCerts[2]; + notEqual(ee_cert, null, "EE cert should have successfully loaded"); + + setup_basic_trusts(ca_cert, int_cert); + await test_ca_distrust(ee_cert, ca_cert, true); + + setup_basic_trusts(ca_cert, int_cert); + await test_ca_distrust(ee_cert, int_cert, false); + + // Reset trust to default ("inherit trust") + setCertTrust(ca_cert, ",,"); + setCertTrust(int_cert, ",,"); + + // End-entities can be trust anchors for interoperability with users who + // prefer not to build a hierarchy and instead directly trust a particular + // server certificate. + setCertTrust(ee_cert, "CTu,CTu,CTu"); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLClient + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailSigner + ); + await checkCertErrorGeneric( + certdb, + ee_cert, + PRErrorCodeSuccess, + certificateUsageEmailRecipient + ); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_trust/ca.pem b/security/manager/ssl/tests/unit/test_cert_trust/ca.pem new file mode 100644 index 0000000000..45de962523 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUVSmns5EZzUHKobrhxdpy/ZtJMucwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQATPLfx55bklmCWgjlOjZjD8EpY +fenI0HAkE0044+KmVlFSpsETog4OK0aZKYKwDysClM/ZipzBpmcZ4ZczM0TbtC7/ +d8nfUmT5R/sXBuMmeNIioAn6J5JaSctKQbsVta9GwIyJUBuYIvccL1c5wUuxV8xf +CaTrFgKWkDWkhOEY+TN/95l+Cm0Gwc3l+jom5UrPRyw9Cb5AhRiRc+x3HhgJ2hGe +kKo4K/AfH/jE7U0u4VM+VZTQf5K92aih3f54vPW+yFfMkgFgzHtwIrj1WStknR7u +yRjBCHfjuoOgQLm1svKtpgnMbRhucCkW+mifY+ZbE51vYMiRlK3sHj9hz3ol +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_trust/ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_trust/ca.pem.certspec new file mode 100644 index 0000000000..d809dbd635 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_cert_trust/ee.pem b/security/manager/ssl/tests/unit/test_cert_trust/ee.pem new file mode 100644 index 0000000000..37db649572 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4jCCAcqgAwIBAgIUKXfW0gwCmh3GP4O2Z+Kd/CYbINgwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMA0xCzAJBgNVBAMMAmVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozUwMzAxBgNVHSUEKjAoBggrBgEF +BQcDAQYIKwYBBQUHAwIGCCsGAQUFBwMEBggrBgEFBQcDAzANBgkqhkiG9w0BAQsF +AAOCAQEArrxwO26t+coTY3AKAoLTFj8Syt469PatjuQA911/QB64+YYrIEs4KTCZ +HHx4/WvWAttXNtYV7NYiLXJOTfJUYKr9MdoM6S4C9HHh3oBzkKvNyg7hM6RKr1va +qd/OVJMulsJ1oP2x2tHeK3k0GkG70yplUxFiaQZ4KVCHsfUo5GPergooQoM64jXC +ILBF/YJ3vtox2AiNCAA8Vv742CBavsq3bOVN2VxZ/B8yBd5D366UBP39TSRdWHH5 +X3dJWkJ1vkJMmWSbP03zNbqG4H0Qimq5Pywr4uUkmckx6ZclEoGbxozutdMx8u9B +erZH6etD3bj9ExPVUcf4qHfcJUrmdQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_trust/ee.pem.certspec b/security/manager/ssl/tests/unit/test_cert_trust/ee.pem.certspec new file mode 100644 index 0000000000..9666c18062 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:ee +extension:extKeyUsage:serverAuth,clientAuth,emailProtection,codeSigning diff --git a/security/manager/ssl/tests/unit/test_cert_trust/int.pem b/security/manager/ssl/tests/unit/test_cert_trust/int.pem new file mode 100644 index 0000000000..44e6a36efa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/int.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyjCCAbKgAwIBAgIUNbjVwdBjmiBHgijAyjyGIHuhJqQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDjEMMAoGA1UEAwwDaW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsG +A1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAO35vcl2OA9fAarEgTCrS42CL +5BeNfQLO7QCIdMZBfcIrQ6v5yw7i07pYGptagz/76OwYOsKO1lqb7sr2nTCNovVp +Co4dCAGQI460C6x3BOG7qyCFgZvf17xXl5filhMZw93LkWaeEIp8JmOTb511i1Bv +1akdFJ+xW40AuHE7EswLXzN0eu+tVAMJcsuxibK3jTkEdIjFCVwMD/7LC1rcoKcg +V18MHbh0zcDrXzo/jk8JfjqkOH5eylBtX2DH/9BjFcKzZDvZQFYlhsmADRHOmqvi +YoEXJj2A6fRzONsNKtQQbmVGvW/rHP7/YIiaAvn0kNb/FDtSqmTcLazSYpRewQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_trust/int.pem.certspec b/security/manager/ssl/tests/unit/test_cert_trust/int.pem.certspec new file mode 100644 index 0000000000..a7f6d81419 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/int.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_cert_trust/moz.build b/security/manager/ssl/tests/unit/test_cert_trust/moz.build new file mode 100644 index 0000000000..8338b13334 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_trust/moz.build @@ -0,0 +1,15 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'ee.pem', +# 'int.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_utf8.js b/security/manager/ssl/tests/unit/test_cert_utf8.js new file mode 100644 index 0000000000..caeddd8158 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_utf8.js @@ -0,0 +1,79 @@ +// -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- +// 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/. + +"use strict"; + +do_get_profile(); + +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function run_test() { + // This certificate has a number of placeholder byte sequences that we can + // replace with invalid UTF-8 to ensure that we handle these cases safely. + let certificateToAlterFile = do_get_file( + "test_cert_utf8/certificateToAlter.pem", + false + ); + let certificateBytesToAlter = atob( + pemToBase64(readFile(certificateToAlterFile)) + ); + testUTF8InField("issuerName", "ISSUER CN", certificateBytesToAlter); + testUTF8InField("issuerOrganization", "ISSUER O", certificateBytesToAlter); + testUTF8InField( + "issuerOrganizationUnit", + "ISSUER OU", + certificateBytesToAlter + ); + testUTF8InField("issuerCommonName", "ISSUER CN", certificateBytesToAlter); + testUTF8InField("organization", "SUBJECT O", certificateBytesToAlter); + testUTF8InField("organizationalUnit", "SUBJECT OU", certificateBytesToAlter); + testUTF8InField("subjectName", "SUBJECT CN", certificateBytesToAlter); + testUTF8InField("displayName", "SUBJECT CN", certificateBytesToAlter); + testUTF8InField("commonName", "SUBJECT CN", certificateBytesToAlter); + testUTF8InField( + "emailAddress", + "SUBJECT EMAILADDRESS", + certificateBytesToAlter + ); +} + +// Every (issuer, serial number) pair must be unique. If NSS ever encounters two +// different (in terms of encoding) certificates with the same values for this +// pair, it will refuse to import it (even as a temporary certificate). Since +// we're creating a number of different certificates, we need to ensure this +// pair is always unique. The easiest way to do this is to change the issuer +// distinguished name each time. To make sure this doesn't introduce additional +// UTF8 issues, always use a printable ASCII value. +var gUniqueIssuerCounter = 32; + +function testUTF8InField(field, replacementPrefix, certificateBytesToAlter) { + let toReplace = `${replacementPrefix} REPLACE ME`; + let replacement = ""; + for (let i = 0; i < toReplace.length; i++) { + replacement += "\xEB"; + } + let bytes = certificateBytesToAlter.replace(toReplace, replacement); + let uniqueIssuerReplacement = + "ALWAYS MAKE ME UNIQU" + String.fromCharCode(gUniqueIssuerCounter); + bytes = bytes.replace("ALWAYS MAKE ME UNIQUE", uniqueIssuerReplacement); + ok( + gUniqueIssuerCounter < 127, + "should have enough ASCII replacements to make a unique issuer DN" + ); + gUniqueIssuerCounter++; + let cert = gCertDB.constructX509(stringToArray(bytes)); + notEqual(cert[field], null, `accessing nsIX509Cert.${field} shouldn't fail`); + notEqual( + cert.getEmailAddresses(), + null, + "calling nsIX509Cert.getEmailAddresses() shouldn't assert" + ); + ok( + !cert.containsEmailAddress("test@test.test"), + "calling nsIX509Cert.containsEmailAddress() shouldn't assert" + ); +} diff --git a/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem b/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem new file mode 100644 index 0000000000..63ce6adb95 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIID7zCCAtegAwIBAgIUD0km5IZjROSFHzbVwqApAdud/iAwDQYJKoZIhvcNAQEL +BQAwfDEcMBoGA1UECgwTSVNTVUVSIE8gUkVQTEFDRSBNRTEdMBsGA1UECwwUSVNT +VUVSIE9VIFJFUExBQ0UgTUUxHTAbBgNVBAMMFElTU1VFUiBDTiBSRVBMQUNFIE1F +MR4wHAYDVQQHDBVBTFdBWVMgTUFLRSBNRSBVTklRVUUwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowgY8xHTAbBgNVBAoMFFNVQkpFQ1QgTyBSRVBM +QUNFIE1FMR4wHAYDVQQLDBVTVUJKRUNUIE9VIFJFUExBQ0UgTUUxHjAcBgNVBAMM +FVNVQkpFQ1QgQ04gUkVQTEFDRSBNRTEuMCwGCSqGSIb3DQEJARYfU1VCSkVDVCBF +TUFJTEFERFJFU1MgUkVQTEFDRSBNRTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNRME8wTQYDVR0RBEYwRIIeU1VC +SkVDVCBBTFQgRE5TTkFNRSBSRVBMQUNFIE1FgSJTVUJKRUNUIEFMVCBSRkM4MjJA +TkFNRSBSRVBMQUNFIE1FMA0GCSqGSIb3DQEBCwUAA4IBAQA1ZJfPm9pINBPkJ/hu +5we0GtnKeTaIQOvtVnOXIA8NQBDny3pAaGNEQTaf48PL7RViFmUNGubPVzx27ZC4 +HIsUV+fT6ASdkgj9HU3cV7vOIXTDWiZOm8pFoqwV9sbkFToUuEomIHAJ5qXnF7Fv +3O87ePTPf1s4bf8URK3Dn3cLY5N9P0o2wdUKj5Ey94ZMfGnqH7lZ0PSoDTRdzb8j +lHp1bskW/s9jsYqF7zSExur2OZ3DBwQptmoiK6jYu3h5M6+lV/euRjsJLqEIBSu9 +krgKiuGeiG2F8aR+Vi8agulxZnm3zmZPCgIxHOe2O85+Ak1GctL6mRopr4nYgc+P +dfBK +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem.certspec b/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem.certspec new file mode 100644 index 0000000000..6579ac5550 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_utf8/certificateToAlter.pem.certspec @@ -0,0 +1,3 @@ +issuer:/O=ISSUER O REPLACE ME/OU=ISSUER OU REPLACE ME/CN=ISSUER CN REPLACE ME/L=ALWAYS MAKE ME UNIQUE +subject:/O=SUBJECT O REPLACE ME/OU=SUBJECT OU REPLACE ME/CN=SUBJECT CN REPLACE ME/emailAddress=SUBJECT EMAILADDRESS REPLACE ME +extension:subjectAlternativeName:SUBJECT ALT DNSNAME REPLACE ME,SUBJECT ALT RFC822@NAME REPLACE ME diff --git a/security/manager/ssl/tests/unit/test_cert_utf8/moz.build b/security/manager/ssl/tests/unit/test_cert_utf8/moz.build new file mode 100644 index 0000000000..f96c97f0e6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_utf8/moz.build @@ -0,0 +1,13 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'certificateToAlter.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_version.js b/security/manager/ssl/tests/unit/test_cert_version.js new file mode 100644 index 0000000000..73b0f458f7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version.js @@ -0,0 +1,304 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +// Tests the interaction between the basic constraints extension and the +// certificate version field. In general, the testcases consist of verifying +// certificate chains of the form: +// +// end-entity (issued by) intermediate (issued by) trusted X509v3 root +// +// where the intermediate is one of X509 v1, v2, v3, or v4, and either does or +// does not have the basic constraints extension. If it has the extension, it +// either does or does not specify that it is a CA. +// +// To test cases where the trust anchor has a different version and/or does or +// does not have the basic constraint extension, there are testcases where the +// intermediate is trusted as an anchor and the verification is repeated. +// (Loading a certificate with trust "CTu,," means that it is a trust anchor +// for SSL. Loading a certificate with trust ",," means that it inherits its +// trust.) +// +// There are also testcases for end-entities issued by a trusted X509v3 root +// where the end-entities similarly cover the range of versions and basic +// constraint extensions. +// +// Finally, there are testcases for self-signed certificates that, again, cover +// the range of versions and basic constraint extensions. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function certFromFile(certName) { + return constructCertFromFile("test_cert_version/" + certName + ".pem"); +} + +function loadCertWithTrust(certName, trustString) { + addCertFromFile( + certdb, + "test_cert_version/" + certName + ".pem", + trustString + ); +} + +function checkEndEntity(cert, expectedResult) { + return checkCertErrorGeneric( + certdb, + cert, + expectedResult, + certificateUsageSSLServer + ); +} + +function checkIntermediate(cert, expectedResult) { + return checkCertErrorGeneric( + certdb, + cert, + expectedResult, + certificateUsageSSLCA + ); +} + +add_task(async function() { + loadCertWithTrust("ca", "CTu,,"); + + // Section for CAs lacking the basicConstraints extension entirely: + loadCertWithTrust("int-v1-noBC_ca", ",,"); + await checkIntermediate( + certFromFile("int-v1-noBC_ca"), + MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA + ); + await checkEndEntity( + certFromFile("ee_int-v1-noBC"), + MOZILLA_PKIX_ERROR_V1_CERT_USED_AS_CA + ); + // A v1 certificate with no basicConstraints extension may issue certificates + // if it is a trust anchor. + loadCertWithTrust("int-v1-noBC_ca", "CTu,,"); + await checkIntermediate(certFromFile("int-v1-noBC_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v1-noBC"), PRErrorCodeSuccess); + + loadCertWithTrust("int-v2-noBC_ca", ",,"); + await checkIntermediate( + certFromFile("int-v2-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v2-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v2-noBC_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v2-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v2-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + + loadCertWithTrust("int-v3-noBC_ca", ",,"); + await checkIntermediate( + certFromFile("int-v3-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v3-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v3-noBC_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v3-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v3-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + + loadCertWithTrust("int-v4-noBC_ca", ",,"); + await checkIntermediate( + certFromFile("int-v4-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v4-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v4-noBC_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v4-noBC_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v4-noBC"), + SEC_ERROR_CA_CERT_INVALID + ); + + // Section for CAs with basicConstraints not specifying cA: + loadCertWithTrust("int-v1-BC-not-cA_ca", ",,"); + await checkIntermediate( + certFromFile("int-v1-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v1-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v1-BC-not-cA_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v1-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v1-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + + loadCertWithTrust("int-v2-BC-not-cA_ca", ",,"); + await checkIntermediate( + certFromFile("int-v2-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v2-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v2-BC-not-cA_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v2-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v2-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + + loadCertWithTrust("int-v3-BC-not-cA_ca", ",,"); + await checkIntermediate( + certFromFile("int-v3-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v3-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v3-BC-not-cA_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v3-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v3-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + + loadCertWithTrust("int-v4-BC-not-cA_ca", ",,"); + await checkIntermediate( + certFromFile("int-v4-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v4-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + loadCertWithTrust("int-v4-BC-not-cA_ca", "CTu,,"); + await checkIntermediate( + certFromFile("int-v4-BC-not-cA_ca"), + SEC_ERROR_CA_CERT_INVALID + ); + await checkEndEntity( + certFromFile("ee_int-v4-BC-not-cA"), + SEC_ERROR_CA_CERT_INVALID + ); + + // Section for CAs with basicConstraints specifying cA: + loadCertWithTrust("int-v1-BC-cA_ca", ",,"); + await checkIntermediate(certFromFile("int-v1-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v1-BC-cA"), PRErrorCodeSuccess); + loadCertWithTrust("int-v1-BC-cA_ca", "CTu,,"); + await checkIntermediate(certFromFile("int-v1-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v1-BC-cA"), PRErrorCodeSuccess); + + loadCertWithTrust("int-v2-BC-cA_ca", ",,"); + await checkIntermediate(certFromFile("int-v2-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v2-BC-cA"), PRErrorCodeSuccess); + loadCertWithTrust("int-v2-BC-cA_ca", "CTu,,"); + await checkIntermediate(certFromFile("int-v2-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v2-BC-cA"), PRErrorCodeSuccess); + + loadCertWithTrust("int-v3-BC-cA_ca", ",,"); + await checkIntermediate(certFromFile("int-v3-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v3-BC-cA"), PRErrorCodeSuccess); + loadCertWithTrust("int-v3-BC-cA_ca", "CTu,,"); + await checkIntermediate(certFromFile("int-v3-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v3-BC-cA"), PRErrorCodeSuccess); + + loadCertWithTrust("int-v4-BC-cA_ca", ",,"); + await checkIntermediate(certFromFile("int-v4-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v4-BC-cA"), PRErrorCodeSuccess); + loadCertWithTrust("int-v4-BC-cA_ca", "CTu,,"); + await checkIntermediate(certFromFile("int-v4-BC-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee_int-v4-BC-cA"), PRErrorCodeSuccess); + + // Section for end-entity certificates with various basicConstraints: + await checkEndEntity(certFromFile("ee-v1-noBC_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v2-noBC_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v3-noBC_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v4-noBC_ca"), PRErrorCodeSuccess); + + await checkEndEntity(certFromFile("ee-v1-BC-not-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v2-BC-not-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v3-BC-not-cA_ca"), PRErrorCodeSuccess); + await checkEndEntity(certFromFile("ee-v4-BC-not-cA_ca"), PRErrorCodeSuccess); + + await checkEndEntity( + certFromFile("ee-v1-BC-cA_ca"), + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); + await checkEndEntity( + certFromFile("ee-v2-BC-cA_ca"), + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); + await checkEndEntity( + certFromFile("ee-v3-BC-cA_ca"), + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); + await checkEndEntity( + certFromFile("ee-v4-BC-cA_ca"), + MOZILLA_PKIX_ERROR_CA_CERT_USED_AS_END_ENTITY + ); + + // Section for self-signed certificates: + await checkEndEntity(certFromFile("ss-v1-noBC"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v2-noBC"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v3-noBC"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v4-noBC"), SEC_ERROR_UNKNOWN_ISSUER); + + await checkEndEntity( + certFromFile("ss-v1-BC-not-cA"), + SEC_ERROR_UNKNOWN_ISSUER + ); + await checkEndEntity( + certFromFile("ss-v2-BC-not-cA"), + SEC_ERROR_UNKNOWN_ISSUER + ); + await checkEndEntity( + certFromFile("ss-v3-BC-not-cA"), + SEC_ERROR_UNKNOWN_ISSUER + ); + await checkEndEntity( + certFromFile("ss-v4-BC-not-cA"), + SEC_ERROR_UNKNOWN_ISSUER + ); + + await checkEndEntity(certFromFile("ss-v1-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v2-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v3-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER); + await checkEndEntity(certFromFile("ss-v4-BC-cA"), SEC_ERROR_UNKNOWN_ISSUER); +}); diff --git a/security/manager/ssl/tests/unit/test_cert_version/ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ca.pem new file mode 100644 index 0000000000..1126badb9e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUX0wQbjf3LQAHIgB14ftnKbI1mekwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAsGA1UdDwQEAwIBBjAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA3q3li09bMd9Y57E2xPY9NdMiG +SA7DSsGnxOchtT06MfkP6lH4PlKDLATIEv2CSq2z25Thq6yYWyZnWXC+tOptACjQ +FDS5scNAI2KDwtK7pqx1+Tr606DQI9QUF1ZeaKo7DP1ibmwmDu3cY16RaowbgaCh +bU4ADBkZNAlRCvrRGCtBkdUl0hqVT6sW/eFkOK9vA5pDHZryQv/DZSg2bDeJIQBL +ElArPKv3DhETpuf580rkI84+w7HBiUSNHB2KPq7ctn4Zvsou/zxJ9x2px/7t+pLx +TPoYXl9QOgv2uqKqMr5dWMAgZXrFqvXVC01JHPbu4BJDKi5qyKcdZNcdl5pq +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ca.pem.certspec new file mode 100644 index 0000000000..8689ef9ea1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem new file mode 100644 index 0000000000..b39391ce2c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwDCCAagCFEmH4RSzGlM8deH3Cyvvc8BTUkK4MA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBYxFDASBgNVBAMMC2VlLXYxLUJDLWNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxAwDjAMBgNVHRMEBTADAQH/ +MA0GCSqGSIb3DQEBCwUAA4IBAQCe6J0atonkAikXwwKyUEier2uTl/M5H1JoJKQT +8FDYIgDKzZi2I0mt1OBd98r+SxCFEoF/r0Je1vwTzFnK9R460VdZY7kXzPOrQ3nP +3XCXS/sOK+c6BoWF1NsFBzVohgatObe5zMgV9s5xYZqXlmPFDBJicNyO2DkyWHbk +7sLMavGanKa1au1Zpn8GoAattNJW9ihqEZ1ZsXM8zgYzuRN850myynAYcIl9rsON +6mMFe1d1UiEplhAJGGD91A8RtokJlq32uGMWIw76lNbrCEjN6oB6XFS57PcOF+3b +5rVmgfY7IHbB2gjFSKcj8hFF8D0ISZn4mFRsJof62RwM8QCV +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..4570e6e3ff --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v1-BC-cA +version:1 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem new file mode 100644 index 0000000000..f099356266 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwTCCAakCFDvg2eVC0vnuGk65tm8Vzurs8Uj1MA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBoxGDAWBgNVBAMMD2VlLXYxLUJDLW5vdC1jQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMNMAswCQYDVR0TBAIw +ADANBgkqhkiG9w0BAQsFAAOCAQEAUnEgkyfbh+pY2ZAIpqUSRkMYv+NIXdcnTJZV +GmqhFJEakZ2hMBxELneaxbv49Lj7JyK09CVfBhWFEA0CjnmS+APb3rVozt9uN6yE +KCjGsmdUnthMG6E2D0VbLsNKq57m3naDVgDDedOhheAvsJyQvKubsQiMtuoJCdZO +obx+lYE+16m6+SzJPFt1yh5vn9+hBcTq1zmYQSKbAJXkrDMMQnjywzb77kBKYgyr +uQ3/SlwjzGojQFlWOhkRsQjcC+zz6lobziUeAQ1vXy8t8xaQQjTmwpVi+vVH7w+8 +ATJKEfIE4cl58aAEYHV7qv1fQ6NUQO0lsRumsgoR+E8PhPQKrQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..f4257841fe --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-BC-not-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v1-BC-not-cA +version:1 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem new file mode 100644 index 0000000000..08fce562e7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICrTCCAZUCFEmbMXhUIOtpbMU4ZOUHBaPfFSv9MA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBUxEzARBgNVBAMMCmVlLXYxLW5vQkMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw +ggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9 +sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5 +TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7 +xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHd +tMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l +8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEB +AJkjYBJWNRU/lCHANJUmnuRt7ignqJyGsYR/q5z31B6kWUA1TGX15iyWnmgtRqR3 +jDiZqh3ejnozXtbAHkGykndeY3jvHCMzCNNpAQZKd9hoCb9Ix9yK1zbqtGAuDgT6 +t0nfkvGK9qPulRZ/2cHHHEdryceX2B1aVxv8D2z4M1Fg2Ajplp269EFhd0T5sZL3 +9zlgv9JlcoUVdjlDQ95Kagv4jt0gG3mGci/Oj3pYwhe8bVUE3/vwetR+1akOaBcE +3YSvUW2EbQkGq5ghhIolF2K5DRGjsXkGrJQszRNRPTiEaexL3CV9r7lW0Re6z8Fs +c2TT9q6PeqCvNoM0K4ji8Ag= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem.certspec new file mode 100644 index 0000000000..48fe9e5416 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v1-noBC_ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-v1-noBC +version:1 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem new file mode 100644 index 0000000000..25c6102473 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxTCCAa2gAwIBAQIUTUkREc279H3wFGALzwJDTUzA5XYwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLZWUtdjItQkMtY0EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAOMAwGA1UdEwQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAG0viSnuppjnIHdiuApCFM55eBf71+Tc +g68DIa0yYtVylF6KAhFMCe7JPg+9viImNGeUktRSpwLtCc8w63gILGF8HhAcOScM +2uMCQMX0HqQqDxZdl1PmQv7oj0pPK4FWiyEXjYaHOaHO+qzo5hV3KUe2iaK0VHbk +vtyAhTrhkHrhLdpDGYtGErAj5E4hySfNW8tNdvrOge9n2SEshDiSr1G3NSQZwlGd +ZOPrOGbDNFGlqzKRwIdn8wz1NC8JUjMWZRI7opnqA59e6RXoosT6Ruycnx6qC6eu +gBKRYMtbVtYmaxHmTR7jKZLdmx+siIkt6nZZJ36sAiQvAd7pWdZrctU= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..f714725d2b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v2-BC-cA +version:2 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem new file mode 100644 index 0000000000..c100e8d026 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAQIUZUYdrYFQ0vpgwxOwG9WoaOfZlCQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGjEYMBYGA1UEAwwPZWUtdjItQkMtbm90LWNBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow0wCzAJBgNV +HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQCcsL4DBcZ9blKekKo3s0mhsNm056g4 +/QPMHfZ3V3Wtidz2VDp09LTuXaLDbfMYSlsR6p828rJmHrO1BhIvKKJ7SAfN3QXp +lntK2RzY0G53huTqs8u34DdHdubrG8TSFbq/pqa/2So1YfvVLMQYrkz1p9AxtFqN +/Ym1G33+1RIB5Shji8I8PyzKVL1ymlzfVLPP4jBkxopytZUykc6wPNRZl1FnbZV4 +0+ZFB01fOHmitHiLuPjIm5YYA48jArq6h589PUg3+WyNccd9MzRQgVdXNg5j88d5 +Ta2oXKAPmzTt0L+vkqkPyTYFT1gNAKg4eD6PdjxXtWDYwNtOqG827jfm +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..db72288814 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-BC-not-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v2-BC-not-cA +version:2 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem new file mode 100644 index 0000000000..74085ee898 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICsjCCAZqgAwIBAQIUY4fMtZjVWcwhTGK7pGcExmXLBzAwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFTETMBEGA1UEAwwKZWUtdjItbm9CQzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEAG+pHmRMmLdRIWHbG+CiU4jBFaTfjRHVOjt2diO4p60dZ5up2tp2KAnHy +U7OJmN0FcTl+7ydDWXyR3gRrR/rOGdx5inq3817+CotMkeai3dnKVjjLxDBCA8Ch +2mqDXR6wYyXccIMokJgVam2b/OHAfpWlphecReKr7kYA8j6Kg52IFZl7iX0l2tL6 +34TJnRdPyGz0AM5uP46pLn7P1zi1M/6+l0y8EnX7KL/k2Bxj2BWwWLJ8L7IXIret +f/zEM4EiHJHSC+HLq9r/XJFJGVXS6bNGPETQ96ySEvNPPQTRWLe8JBj5pUpe5LBj +hrv7fb16fTx/eVdVFmbmdFH6q9nNHA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem.certspec new file mode 100644 index 0000000000..cc304ab87e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v2-noBC_ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-v2-noBC +version:2 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem new file mode 100644 index 0000000000..480bed0f40 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxTCCAa2gAwIBAgIUGxHIJJyv/iJrELEMIQD1aphjDaowDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLZWUtdjMtQkMtY0EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAOMAwGA1UdEwQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBABwWiSkeHa9tiZRe2vCYFRgR9OEHPr+z +uN1PFpmLbofm4HTQ+FYD91QrYuDJPoO6+zBLRbZqkBZ8J3X6ts1uRr7qk6x9Cgq5 +ZJNUre5gW8wjZ/WiX2IoY7ucZXuTYKePPyd5RyfPYm+9p9960elo2uNLLG0Nmy1A +YlqjkhaFn6q2eNh/4c0tlRKIKpiUDnBa/ibsJPRzbTAhmIm6ooiphX6E6CG4sIWP +HhWvldTPETvF8PGe4BxqZRBbAzh892yh8FCGos8RLNOoFrr4k4Vysb94n4E1SKrv +ORfes12d6FmFdYlB4mjl50FJGh0hjPcP1tq78EbkipRGTJO/6Q3vcVE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..6f69c35743 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v3-BC-cA +version:3 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem new file mode 100644 index 0000000000..574ef68d5f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAgIUb4dXJa+wzvKsmCT/HB8Xu0Cp8YcwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGjEYMBYGA1UEAwwPZWUtdjMtQkMtbm90LWNBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow0wCzAJBgNV +HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQB0pTw1CI81i2uK8HfcfuljDfI1/thC +9QmV+nRLMic+82XNPHYjUBAS9r2kZvNEeSoQQThkefEzcRPP33hl4TbYXCKuFzpT +k0ssjzLAUIWUCaVWnV3p0aryGv/MBITNu4TWTnRwOIinWZ/cExO42iLTDiMbuhQp +b5IubLsj2+15aF56zuTFEqwB+O6D0L+r5uka7Q6I3T3kCrbDFqcjlosKxY67AqLG +dKMahrfX2D1hFIeVz8yMtYCAH0ZWt+ooJE1ntUksbwsQ2pA7AQwKl2ojiqI6FMRm +6jD0ydcYAGdNboNkL9fCC1oC7J66slt5a172GE8IGXVKqNZYLv2+0P+/ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..4a9de06358 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-BC-not-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v3-BC-not-cA +version:3 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem new file mode 100644 index 0000000000..88b8996d5b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICsjCCAZqgAwIBAgIUH6a1yPknNm4Zd5xhXtDsj5JWTVIwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFTETMBEGA1UEAwwKZWUtdjMtbm9CQzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEADZVMW87EF24I8XiCc+t0MG+vu8rcR1msyWAwtjxmYNbkt2Up+etwR0U/ +54zFmJiRagPnKZhd9pyp1rpej9nj1liL8mV5hLeX0Mlc6QnCo7gNIY0wWcwtsMXe +NDWBO2i1mTlTBLjJrrcmTd8dwKy4Pru2oQ2+6O3/m58oWtBqsAJp47o8qOTmjJvZ +IF2U6cOgoVNGeOmzq3QGGQnM3/9rXhD5DL3Trz2lCuy91fW0gMyFC3neaKdSDgoP +2cZtvs5plLwBNXMu6W89BZI08mrD/flo3VkUgkxVBDr3PUKdY60Xvpp+sJwEw0Ef +Yr9Zmb1FmDlwTjmAAZVo9OiAg7r2Jw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem.certspec new file mode 100644 index 0000000000..9d385900f0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v3-noBC_ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-v3-noBC +version:3 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem new file mode 100644 index 0000000000..ebb27c0de3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxTCCAa2gAwIBAwIUN2t/Wc6xThY3A8WTT8g4qc3BJccwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLZWUtdjQtQkMtY0EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAOMAwGA1UdEwQF +MAMBAf8wDQYJKoZIhvcNAQELBQADggEBAGcf/zc6xWE/038gQYOrWnTw5B65PsEi +iGWJQgeUOSCwADHJ3DYzf239OmBqhe30/fbT4Z5F9y4OjSGqzKhiAwq6rRCeybFQ +d/tQvT5F197q5b0ZgMSSbu9luGD8kNSrpzmIvqwEVrABbKTFUqaFpSumZKbCRuQ/ +2ReQ2W+nfnL/EDekytU9nDoIMULcCc5cPj8q+gEVPaMm94bDwYe+9vVRwf2JycWt +ldZbH6brAZ4dOpa+hXK4W4RqY0baTRYU/8wrihezQtVElJmXszOzcWveGg5cOGFC +vr1EgdFx4d/dj+Eh7HiMqSJqUlVQ9D84mR1C1NBJdDZESflVT26kB0k= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..1f44c1dd27 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v4-BC-cA +version:4 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem new file mode 100644 index 0000000000..adb901d1d2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxjCCAa6gAwIBAwIUXX5wI9ZLvqMcMEKuZ6ShXJ0XfY4wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGjEYMBYGA1UEAwwPZWUtdjQtQkMtbm90LWNBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow0wCzAJBgNV +HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAoqp9OCrEoIKeQG+2mtReILd2OW21v +sgvxqDP6MGYtdQ7HfZaHZuv1PZiVzxysqk/0nuUYWzbPh+7/xUWTa21YVjt2fhDV +wotDiE3iNOumE3Pbeg70MIRgQa00pYvjRse9748y4rLMSpZu9Dx8vPS6T2efrjI/ +JwMh0lqjsqGNdMEotfNFeGCrsjr3bjBj43RtRHpL00Cq3A276PmSyfs/r+raxJEU +BkKqjmry3AzOMTIyTxI7qe5/CMAm8GvfGdhr1tj7sh9lwS5oe8II4u4D/9tirHF9 +wTNAhSaTiAsUoynaJtBYTA/MxYvwJ6/qY69Q7oUkX/Gs7Pl9fryyDo05 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..e9659153e5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-BC-not-cA_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ee-v4-BC-not-cA +version:4 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem new file mode 100644 index 0000000000..e7c778415d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICsjCCAZqgAwIBAwIUB2z1TvAGiocHPPLxLlCE2W4kKrUwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFTETMBEGA1UEAwwKZWUtdjQtbm9CQzCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsF +AAOCAQEARifsn/PYmP30WdyRw3EBXEolSO+kqeY2fWM/4Qji7jUGLsgXRUt4zXbs +Wgwrvxk+iHlrDwN8ux6OZ0UteKBlWxN6vWUZO3QqCI2prkdzBtHkiBB/sbp6kJPR +IIBLPoXn8IOeV7xP7bjNHDqSqwDy4Ltm+0OmOBaONxhAjAyQPKZtuzLRUQzljLOZ +9vE4CXM3Q/ZugkKOFq4YcJ8fTRXT08Tqtfxn0IIYBsezTPw3kX4qcgiyaSLhCSKC +w1eb46+Kqe9FVC9pApbRFSsYm0guPnRRMASQSiHW3w+7KB35EFl4G5LlxzuZdZh5 +I3pv2YB2zXurIJ7IOizgX9GMVbOzjg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem.certspec new file mode 100644 index 0000000000..19229ba766 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee-v4-noBC_ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ee-v4-noBC +version:4 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem new file mode 100644 index 0000000000..c9fe2a1deb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIUYXRFk++ngkM7pfne+aGZuKsxTYUwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LXYxLUJDLWNBMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQCwvmF6hChs9K1PKjkg2daU5Lz2zAPhh1q7urmJu8gCWSTGz+PeJvKP +zFptbQNPqFnDG9FBXX1IDkMJuZinwyQb1zcLxUqycX4ZKd09BcRIeS/9BXnOy+Cp +1QFDj0R/wdMYnvh+yfMFOSLVBSFkGtHkvkDoaf7Sm9vzw8xVG8L2785tkfGVsyd4 +oqhDbRJ/RQu4wOjS8NmIRp8bAUg69YA1+wcc9cTbsp772sA529XzNDT6+IUV4H3b +TcDW8/Z/A28616soIN6F1KXmQrj9y1lcj7o4uuHPhlpoF+CQScZNCKE94QqHqHvY +yPuMZS8TZz0F31Jnb9sSncDWtK/MOyia +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem.certspec new file mode 100644 index 0000000000..6a7dc5c436 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v1-BC-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem new file mode 100644 index 0000000000..1cd6f09ca2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuDCCAaCgAwIBAgIUT5zJeVS8mAKQvZ177AdPjbMcSZkwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LXYxLUJDLW5vdC1jQTAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjANMQswCQYDVQQDDAJlZTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAjr1UeC96xOI/hocWQtnEJxO9+qxnlRzSuM0gZKvjRlaSsGyn +QmN+/hiYSl71Jq4IkLTxkDy+Fn6F/zb353+f0JMZDVjbBuBfr4HPMTdCHKLnNyoH +XkDwIc08bhoeVFj67OA0E/DxyDjoxZNOfvVALC/8xWlvfrik/N6NBNUS/CPCEFa6 +G/R2RPpea9Ftx5op5SMApctxGT5ZiYTSER44EFLJ2GVQWm8Tt/PNNXt+sYAaAESF +vuOYwiRp17TRPq7+ddE3omKB5xA8e51y/NSAtK8SAsE6nDnjJUmM8sBaitfX6vDY +ji8NYlIWVEMLkEPmg3dWiUz0WYG7Z7RkZ9yT2g== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..639f83d660 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-BC-not-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v1-BC-not-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem new file mode 100644 index 0000000000..22b86450e7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUc2AKlc7qreFiWgePu0YLMlgs/YwwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLaW50LXYxLW5vQkMwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowDTELMAkGA1UEAwwCZWUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBACgJObqHt39+EYoxXhZWuYTAWF7Kjt5jRxluishYoqZ2SKOvhxe0UJAK +ufWLYDbkE0rRW3SNmFxipkXO8ERztDIjc1tbmFJMQa/mC1A3N7YiCLHO8k7t97ie +diw7nEF6kxNp+OkOwZqWiH4siyTiFcAGArnh7j2FZt9dF03FgjmtqAtpB02fON0G +YXuIms0yWHfQv8kFuOmJ9ScBoDZu0layvueWnCfnejIEMyqynRR+ZkPeb5cGqRpL +HGjZnXYXTR2//DV71uUskCz3SGYwttthlDdaBM/AIg7GZIU4mL7iLSq3hxdpVQoM +QXbqnL6xZrDlSn3OmT7/cNrIxdf9qUU= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem.certspec new file mode 100644 index 0000000000..d704f3086d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v1-noBC.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v1-noBC +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem new file mode 100644 index 0000000000..f113c5d965 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIUATfzH/PSKv0xC89ayKzWGTWeIYQwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LXYyLUJDLWNBMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQAiY5jZpo5IV7FF4xLax2uq+WdCxUDJgYQeaTiu9RlJ84vEcHIuERwu +CaweD8T/4fE372XyivZlopfJ3QR1owqfjGBA67H50mJAurVIBpb+cBnHSxiSYezG +NNTrHwosfb1G8H/oT1/AQtjB4tMSuD8RkTQMwN2G0N9JAhoKL0EnNxKFzuW3IZrW +A9B5mxEe9LLo4JhiNFUtm2Cyh7KiOgOC4IqZfh+A2yrJYaJoBlc3KJx9EfhC/nnm +jsT4W2xxAXn3mNNKaaxnqF/e1jMSlxuKvXTYu1CssaixqQ3XvdmtGRcFoMSgS3RS +MBnffZz/68BbniBcHIgqUp5M7jMEx6lH +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem.certspec new file mode 100644 index 0000000000..5d3a65e650 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v2-BC-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem new file mode 100644 index 0000000000..b5768a0c01 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuDCCAaCgAwIBAgIUfU0RGDUqR251hZR7j7dGSVvLOCEwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LXYyLUJDLW5vdC1jQTAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjANMQswCQYDVQQDDAJlZTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAUzqCpvNWzcDl+DVO0zNcJ1YHLwCTGzD62ejKfjvSUFNloW1n +VYfWP3FN77vtfHdPWZOWcaPGOgvIAjtrovv8PAqE3zusM8ml+2XHYckXReOv+3xp +qMN+8uGgI/KjyYuuxUOcNnWjwEHs9aB5A2QznNfb73vorBoMGOsp/eRRu/88SIsm +Lb8faovBW/M82DddY01u4pQ7NRdk1lRJP7NDwyeJi0sp0Tt8vkqQmaWwVxJcECQ9 +pjyHdcV6I8X/0unB5aTDVNPk59FQ2mBnL49uhwDLPw/CfvIFUk5t4e5Y8fYENL1o +bCmQwdRtv2uvglGbduN14jNeWi2BrR97CwieaQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..591a16aca0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-BC-not-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v2-BC-not-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem new file mode 100644 index 0000000000..e63e7811e4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUH3fF+CwxPCO0p6f03bj8udeTCqMwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLaW50LXYyLW5vQkMwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowDTELMAkGA1UEAwwCZWUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBADV11pKOwjVQe19NU0Dm+mxFwfr3JtigZJTuqLkDuI1ZzoiLdy5Gm7N2 +HEzx+5A6XoV+HxAA3vgDXjcxqNoBlUFZSKcO3dME/YAwtE06y5R1o8xU2ySH6/Dp +N4Cg5hVPNDo/gomEsqDou3IlLXVQO64fBGFT/eK4fnv96jEMl9hkCbHUjrz9XODI +iEkz2wJSiBmrqKBG+ZB66HqvoqoCNTSfV/IHE85QEb9YanJOc+DR9CYN5S1FILEa +LMi/nVB2Ldn42kBFZjXxEdkQFIWPyKZIk4wFAJwsw6fNGUY6UAb7exLTEhkvP1nD +cgozZt5aezZOz8N+xKwseT66ebSnBhM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem.certspec new file mode 100644 index 0000000000..7f99393cf2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v2-noBC.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v2-noBC +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem new file mode 100644 index 0000000000..6c1a22262c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIUc1r1zrsB1TOy5rvPR+6sCmW3WLkwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LXYzLUJDLWNBMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQB8cqiLjiCQsWyha7QOnGpJVDbrZ050OuDNgg0RZ4h4+vtzvADZFr9T +bbDS5lBUwCipjySqJezUVAbjXLwFPVilc9HW/dZYQCrTHq1KsKma/hbS4+evrW32 +EbEIWLlSc/Dqh8TIwdPtFCtkaBDibIEw4NRjjr18qckN/QQRDRUTjWPFE3nSsSL8 +ywlfQN22LFZpz9mLDsR7hgHGVQ7lKSn7aFspCguu3Z4H3IotMZKd8HmoItayeOwT +5r/tid/uBWUMEV/8IevoJ97arusRZxpCkgrJLK0lRjYfpdO46G9xyEa9NV6R3I1L +OYG6w/XbJYyJujCE1G9tDGVVB88lR41Z +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem.certspec new file mode 100644 index 0000000000..13af934f29 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v3-BC-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem new file mode 100644 index 0000000000..5490b63b25 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuDCCAaCgAwIBAgIUMWZpljmNpyGng0Q4Nt3ZY0BTjjAwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LXYzLUJDLW5vdC1jQTAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjANMQswCQYDVQQDDAJlZTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAGx9iRA2sOhzEzfbU7jg502lVEAfj0HwJFRN+DVQNyVuNl4ik +QMVFHJvoMCFGu4loJRLqF/OuF/3tvUp4BC8QjbLqUj4wtSUCDZTF8o+Tjb9kTj3J +60VqqL5/HU1G6FaKPDOU/mvmGkiVUjOcrrUghv8urTpYvx8/7Z+u0WySrxSCPCZZ +mYv4LfCv4oEVpzpUBb4078qkntbezDQ5GAyzhpWHSo8qx0FTGnilyZ6Ql2RXItnf +ube5HxTETDYRqHu9E9GcraGKIgYY7vbG2nNOvl87zxU4lHIwpu1vZftpe3raGLqL +7nDqDqHC+9v64RDYH3U2yrl2SLzwsMR0by1otg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..8539715a03 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-BC-not-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v3-BC-not-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem new file mode 100644 index 0000000000..c6a4f4e8c5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUb5/nrEpBnFWFYMGAHbxheeinOLwwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLaW50LXYzLW5vQkMwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowDTELMAkGA1UEAwwCZWUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAFgzXwCceIuZFJ7jB2Fls1D1XvYiwhxeuSVZHsNz1kpCbpmZi1hnDYOY +gfr3FEpcFI3P93b3hHpl8w7DGJ6bvJDqnNxe/idDDg60jeghcmCsJKYUgyoqoYbo +kjHdg1ce+6xsf4n3of3Cr6xDCjpvTupXTf5zrUGtTAvE6XmQPTx1vOEXK/mOdsBb +6ZiVv726yukaCsBN+zuhIU+0eOj8+2kXeKc4C5S3OZ/48LydMRNxjPT4pZtsHfAe +NWy4hyTqfcKZfU31F5GzdXMgn0vvA/v2fssj+ke9sXhTnpNdI48Rp/l5koEBQBNQ +D2rvAdgdZEEQ9xrl5RkLjAXDpVbSoI4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem.certspec new file mode 100644 index 0000000000..a65e41cea5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v3-noBC.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v3-noBC +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem new file mode 100644 index 0000000000..dcb3b722aa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtDCCAZygAwIBAgIUG/xdmUZCt7ps5TMTVbvfWjJHuxMwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LXY0LUJDLWNBMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3DQEB +CwUAA4IBAQCrG/sSj1dbSebCi92T47mRiq8Pm1ovwfqvcuOAcdOELdpLocJMGlDn +7ywQFXRjWvSYHpnk6ekg1XrkHG/N8rUYijRJ0SyR5kpeqGfxiMxSGjxHtmA0sCuK +inqpZAa58v8nsUsFNH4iBWlRYxOAJ+KjwboTar59A5+gKXkxxmoy+4f+LgbyBBJM +EHp2lMg4Nce0/l7tBtNTw5kuozQ7ds0iRl0h++Aw0SjhpyWGP3WVGNa0z3WlBULx +FRqHLPV7yS0WN8A2j2rPanzIzNpka4QsnPQuDznnI3295k1aaTKXacMDnj10JNHh +VSNkPAii9GM0xubnEwvgioNrIePpRpPn +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem.certspec new file mode 100644 index 0000000000..35a3a9ff36 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v4-BC-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem new file mode 100644 index 0000000000..417e004719 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuDCCAaCgAwIBAgIUPbBY1V9XpHrNz4pW9hdLlHaE8wowDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LXY0LUJDLW5vdC1jQTAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjANMQswCQYDVQQDDAJlZTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG +9w0BAQsFAAOCAQEAbcIplVCPKWXW3FSoCRZE9gLtlnKN0aWmsqn9mbZij23ZbVXA +i8t+wu0SSbgeJ99YE36Z/NkKCx3pRIGbjdE1r08rTAhoHxbTdeIzD8K3P6JOSqY2 +7HHsNQxkroWB3Mf3iPW/P8/53Q8o3FYfZEmLO18i2PHw+Y9ZVwHSE7pbdwvTrlGq +MrGeSR57JJLHdZteMhr0A8w2qA2Cv+2NIKNLz0Tztvynmmu+laIMvfTpq9WJesmG +Y1CPXrC7y+Z2720LoxtXpxtVKxi88WFFOKVsBdEBfH9E34TSw5B84RWiaQaZfrDJ +Yd3E+Su7BkyfA89q1J8ITgHMEQdkceafCiQ0pA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..7627d3a8a2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-BC-not-cA.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v4-BC-not-cA +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem new file mode 100644 index 0000000000..238514cffe --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICszCCAZugAwIBAgIUM3CPGo7kDa/S240PLKd0jQ2d/SAwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLaW50LXY0LW5vQkMwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowDTELMAkGA1UEAwwCZWUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZIhvcNAQEL +BQADggEBAJBYwR2i3Y5sJp1o6Eo7Ue1eOpBLFGSuOz0HmQHrZG4dal1dfVrRkv8S +YV//loHyjmp80patejR3QylK1Y6ARQQm6Wn/fOSsUcy4KyWU+DQ5xSrWpRL1EA/7 +yMvK3uwKpoRGUCplLqpTnboRBuFvd6sqU2badeVBpOx/cJ5CBbTiHzudtoWs+O3x +Pv6rjRS8KPDh0qENyKi0JKALXWmO0eHGKPAlRKjx96/4wfj4nvnj6i+OlIbLNZJ3 +Ff8+KCt2xc6cToClZ7jD68eGRDhBd4r5HcUO9y85BOKLPepTM7gRd1FSVXjL21W2 +H+SGy+jOUZOMSiFpQW7Gohv47xa3s4M= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem.certspec new file mode 100644 index 0000000000..a780337539 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ee_int-v4-noBC.pem.certspec @@ -0,0 +1,2 @@ +issuer:int-v4-noBC +subject:ee diff --git a/security/manager/ssl/tests/unit/test_cert_version/generate.py b/security/manager/ssl/tests/unit/test_cert_version/generate.py new file mode 100755 index 0000000000..2afaace3b9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/generate.py @@ -0,0 +1,93 @@ +#!/usr/bin/env python +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python + +# 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/. + +# This file generates the certspec files for test_cert_version.js. The naming +# convention for those files is generally of the form +# "_.pem.certspec". End-entity +# certificates are generally called "ee". Intermediates are called +# "int". The root CA is called "ca" and self-signed certificates are called +# "ss". +# In the case that the subject and issuer are the same, the redundant part is +# not repeated. +# If there is nothing particularly special about a certificate, it has no +# description ("nothing particularly special" meaning the certificate is X509v3 +# and has or does not have the basic constraints extension as expected by where +# it is in the hierarchy). Otherwise, the description includes its version and +# details about the extension. If the extension is not present, the string +# "noBC" is used. If it is present but the cA bit is not asserted, the string +# "BC-not-cA" is used. If it is present with the cA bit asserted, the string +# "BC-cA" is used. +# For example, a v1 intermediate that does not have the extension that was +# issued by the root CA has the name "int-v1-noBC_ca.pem.certspec". +# A v4 end-entity that does have the extension but does not assert the cA bit +# that was issued by the root CA has the name +# "ee-v4-BC-not-cA_ca.pem.certspec". +# An end-entity issued by a v3 intermediate with the extension that asserts the +# cA bit has the name "ee_int-v3-BC-cA.pem.certspec". + +versions = {"v1": 1, "v2": 2, "v3": 3, "v4": 4} + +basicConstraintsTypes = { + "noBC": "", + "BC-not-cA": "extension:basicConstraints:,", + "BC-cA": "extension:basicConstraints:cA,", +} + + +def writeCertspec(issuer, subject, fields): + filename = "%s_%s.pem.certspec" % (subject, issuer) + if issuer == subject: + filename = "%s.pem.certspec" % subject + with open(filename, "w") as f: + f.write("issuer:%s\n" % issuer) + f.write("subject:%s\n" % subject) + for field in fields: + if len(field) > 0: + f.write("%s\n" % field) + + +keyUsage = "extension:keyUsage:keyCertSign,cRLSign" +basicConstraintsCA = "extension:basicConstraints:cA," + +writeCertspec("ca", "ca", [keyUsage, basicConstraintsCA]) + +for versionStr, versionVal in versions.iteritems(): + # intermediates + versionText = "version:%s" % versionVal + for ( + basicConstraintsType, + basicConstraintsExtension, + ) in basicConstraintsTypes.iteritems(): + intermediateName = "int-%s-%s" % (versionStr, basicConstraintsType) + writeCertspec( + "ca", intermediateName, [keyUsage, versionText, basicConstraintsExtension] + ) + writeCertspec(intermediateName, "ee", []) + + # end-entities + versionText = "version:%s" % versionVal + for ( + basicConstraintsType, + basicConstraintsExtension, + ) in basicConstraintsTypes.iteritems(): + writeCertspec( + "ca", + "ee-%s-%s" % (versionStr, basicConstraintsType), + [versionText, basicConstraintsExtension], + ) + + # self-signed certificates + versionText = "version:%s" % versionVal + for ( + basicConstraintsType, + basicConstraintsExtension, + ) in basicConstraintsTypes.iteritems(): + selfSignedName = "ss-%s-%s" % (versionStr, basicConstraintsType) + writeCertspec( + selfSignedName, selfSignedName, [versionText, basicConstraintsExtension] + ) diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem new file mode 100644 index 0000000000..8b635b1c33 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbYCFE3k+54zZHCkzie8w4rzHPcWCvpHMA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBcxFTATBgNVBAMMDGludC12MS1CQy1jQTCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODY +H72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk +27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A9 +0jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMM +kd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaL +L+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswCwYDVR0PBAQDAgEG +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACtj7FH0rKA0rkR4jE7D +IoflYPE7meH6vbDEb7m0kALj69+TH6pnBuKiaiWQwyhx4anAbu13JEEpACJoaNER +FtxsKL8y9j+tSbU5RFHx+6f7OOcz5SawscGEF+P3t0lJqU5d5sDs/frd9DZWu3Ho +lzTlbP2YQsqiRAT2Ryx1AN6hrZEDoQ8TEwXqSC3slSeDvC+pkSZbhSg/VlZ9vwjz +zZ/ukePXRg65AcBrlWhMuJoCCzkQk7lVt/oOHcrGl2AYzN+t04FXs+92/5Gr4Qcd +iCweQYIyHm8UKGsA8gNpFzt8jP5cDUNx11FRPA+N7lImdCas9GHwKTKIunsqW8zC +1lQ= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..77f3ae9147 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v1-BC-cA +extension:keyUsage:keyCertSign,cRLSign +version:1 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem new file mode 100644 index 0000000000..45db11b6be --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzzCCAbcCFE3ZspZvBnOAmWIh05fgdovmSbLrMA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBsxGTAXBgNVBAMMEGludC12MS1CQy1ub3QtY0EwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjGjAYMAsGA1UdDwQE +AwIBBjAJBgNVHRMEAjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAbIDFm/7bUqz+GPgQj +m5pCmxph7tF1Hfz1JMW/3Yi7bthN9ih9As18qgDOPVD3qrZFAUNM6mpvBo/UPb5V +vW8IgtvoNffhUKUjUiYDBcPNmhc2XPCQ9CyhCAF2T1dXftp2H+kQ1cu7N/Yq3vz/ +XkadGQphSs+IWNxYf5hAFU12ZnY5L5BJ3Sr0fjzKYdiyv8MbNqxf1NNlg6+gH0aR +qH+EjqJarw+VeGtwbQjiNCIqf60swE7Fj8hlnGXNlv3ISV0rY8Clfmpr9pG6YBZa +30y/XrwECMiCGlGyQKjKHmijFUF6h49fI1M94jhGDWCslhtvpusdZkaTwBfDEf7U +/5Ze +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..2a366535b6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-BC-not-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v1-BC-not-cA +extension:keyUsage:keyCertSign,cRLSign +version:1 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem new file mode 100644 index 0000000000..a3a7d3b154 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvzCCAacCFGUeQFCueydOeMy6qL1r3OWc72slMA0GCSqGSIb3DQEBCwUAMA0x +CzAJBgNVBAMMAmNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBa +MBYxFDASBgNVBAMMC2ludC12MS1ub0JDMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow8wDTALBgNVHQ8EBAMCAQYw +DQYJKoZIhvcNAQELBQADggEBABvfOrDhyQkVROM6IwTPmetz5M2MjZeQjOVYErgE +fUCE+z7EW5jXaMrcIbjpR+FnnJ3nB6d5vwx6Bzw2q127dUQZkWcI/soiL0ERr+Kv +e97+tPdLb5gL+6trnJb5enkfnGp+Ooo6NyBzUJT8EI326JCxkD3SrGBgLtxzd5hz +rkyjp7y6ypK8ihHGgL7fp4kCeM1NjAt3IPLym7yQOkFFivcKN3Wp7+9oN8t3yo3U +is9yEOmYE/VNRdm6nFnLbe+QQqAZwWQitadVVBHOcW9nIdB1e8VPO+1Dja0muX9K +cLt3twV8Yjk+aaAC3T/4ZTUWNdH80gEZE5Esy1PYeoV16iY= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem.certspec new file mode 100644 index 0000000000..63bf6ed737 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v1-noBC_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-v1-noBC +extension:keyUsage:keyCertSign,cRLSign +version:1 diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem new file mode 100644 index 0000000000..6250abda7a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAQIUf9E2zqRqLx+VENz/4+SpW+a1PeAwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMaW50LXYyLUJDLWNBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzALBgNVHQ8E +BAMCAQYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEANmkUyFb9kU1z +kMHtqom8a2oY76fmNcSyk2VbhodFyj4B9nl/wnHIUxFdL34lMHdxpkEKf2WlSWez +fIYU2JHwPA+iuRE0K0bFqyYt0Bpjt2r5faUzk0ELxYoxIRW7KOHutLBhk/gotgWa +7+HiVJrqfBXQlfWIcb+BNEMc+bzGkQDCdFuzxhUTdIY5monTTbHjF/PUhQ3l9Yql +GQ8IfFQYzaTvZN7kHetuG/gl2dcHA3Yv8IjfSr3/ElrVtF9Tp/c30m3i0Z5YMa9M +zyFYUxqNq5btZYqU7E5/9MXt1A45oet6QHO12E3m0816ooT7g9swJnIQ9CV21LYL +HEVn3xw7sg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..ca1bf67a7d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v2-BC-cA +extension:keyUsage:keyCertSign,cRLSign +version:2 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem new file mode 100644 index 0000000000..8deb1b0eaf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAQIUC1qc7IY2m7UMNztbSNKbdkpXSF0wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGzEZMBcGA1UEAwwQaW50LXYyLUJDLW5vdC1jQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwCwYD +VR0PBAQDAgEGMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAFSFOD3w2yEL +hJBjs6WtkQGAOLJ5Ip/2DI0W+XJAyCRF5nRVpakj8ub/Y/cGG1dLbXuOFoQFR0Hc +6m9hoNSn4Z0v84K5WEsKHtjawQ7DnXSYVyt3JVbtqtQLlVPgXhGqeuP4geF9Zu5+ +2hb6nkwg4bGkIumcx9WFDt0NI++UU9q7/Pw9CTjk86XGhwz1LlVA/RIfotsG3IeZ +IBoV6qT5URErFpOj1b96VnMQNtnjo2HMq6GhrtOqBxRzkjySJ+2JHRe4cf/Phg7h +DIkHTo+ueLrT9toHciMW5NXssUwuBtvhGyeCuzVTtYSnEKGHdnXcVUx6gB4F0PFI +JsD87eWyB5U= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..fc28ff150e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-BC-not-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v2-BC-not-cA +extension:keyUsage:keyCertSign,cRLSign +version:2 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem new file mode 100644 index 0000000000..273f23a8ba --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxDCCAaygAwIBAQIUVYXvMaxdKZ4YI73r4J7jv8+sslwwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLaW50LXYyLW5vQkMwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAsNqQCwIN/u9TAVkh8Hv4IcfsY8u7Ex+t +Z8kfW0rUz666kTRVGFQbM9gzgb+rqyou14vxHDuBx67kbJLKdJ8tUDoe8bcpWbGB +jLx/f6elA7D0eSArpEAheRgoqOJS05f6S9pOA9RnNySfFyV+ypZxBOEbrGOzdzNd +guwoBYS/CAx+TH/f4o92cdqBtm0psRkTp+Fj/qi6f2zetxNfLjFpy3Zog8GopCWK +Mhg0W8j9zeKDLf3NVFt8XMSW8DfwJrsY9enK6ISrdBjIdDqaFdzsXEykeiZgHemf +jBPdogIQD6ZsdlaFFWOq03DHLw4v9Sj0wgc9C8gtQDrL6K5fmfLXGA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem.certspec new file mode 100644 index 0000000000..2d3fe59ffa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v2-noBC_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-v2-noBC +extension:keyUsage:keyCertSign,cRLSign +version:2 diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem new file mode 100644 index 0000000000..d4b8eee198 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUH8RrlVV1Arzvq9vwD37aGxKswKMwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMaW50LXYzLUJDLWNBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzALBgNVHQ8E +BAMCAQYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAFLbj9FU+Oa8R +/9oGqUDa519Et6mg/euJ5tACGLozVoEGCGZN6raLMGlrGNSKLFZBKerg6CdvAuJj +EUNU1utJhH+XGz6ZCIr9SAsDQ3y19cF31WJ9sSamjmChoAsB0zl9EDIrurg5RPHD +wUaTGPLLieLzmAXYynsxIrKZbCCEmR0be2fPqGdkby3iuQnk/Punzluax/6d7pOV +wNbXlRVH9Tcagjcfv/VqPy+8Vt+iOySaAQSj+Mq4chu7wnDYpsDjtAiR6lou3gvt +tjYy66d0Az4SjJeE22r3Xbdz5fgcWyzkiTg0McHpzJqBjPHwONAgy711NOVUNrbM +3RRmkWzpmQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..56fcb21a03 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v3-BC-cA +extension:keyUsage:keyCertSign,cRLSign +version:3 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem new file mode 100644 index 0000000000..48b81adcf5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAgIUY/xRC7wQthFDkmcRdLMOkyv+UdwwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGzEZMBcGA1UEAwwQaW50LXYzLUJDLW5vdC1jQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwCwYD +VR0PBAQDAgEGMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAKvTbOiPSNbY +tvjAcbZPsk+XMNJgOsZ9Wv9RGl+Pc2uZQOKLeysL9bhxqI3Hfylma55t4HI2G7Z/ +AhzgkYBr8H0XPF5q0h66up4YJrDCY2goWjv1W2TmVxleQNQO+eXpP4PJqz/bZnB1 +cXj+olt4CjUtbJ99+RnPU2/7pjQ7D0XMnH5KEqoOrqZr4jVrb86kps9OVmvDr8bW +P7uzZywMNJfAuO9SYtSsqQMGz1SA/fDUK2Uhc3AeGyTU3ePAecABCVNaLnMlqR4L +mugayqLdU0OLuNPpo/bNdtyU5GC+wpSFF2jIkASK+4a7KFJq5SViOCT1BV1NoWMN +DzxXo1ODQjw= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..a2def8d323 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-BC-not-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v3-BC-not-cA +extension:keyUsage:keyCertSign,cRLSign +version:3 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem new file mode 100644 index 0000000000..8a97eaafc8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxDCCAaygAwIBAgIUC26qMXLsjLi4NxcXvpWLTZI5pyUwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLaW50LXYzLW5vQkMwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAkdjTbxvps6efTz63F1cnOMKU0NTgR+Qy +IrfrbMX00GOuABe4IoEiq5uuV0Lj0jkd0sKSc516oy79ZujJnow0sQp6igv3fBHz +6ZsQcHjULxd/PTsTGPp/NwLBsn49kXa/hwt1Us+59qH1oFtRPnQb4Hpr2QhXBR03 +DlhgsNHgaStKcfG37q1PIfDNENC4yM7mgQMvtqQX8QOmIEGAfnwBDLZAuD1GEZ5V +qxprydaCHommBoUKUOAxMnZudco9SDDHPI5IiM1kN/cQL+WDHVIJgWMURqS+Xrod +nkM5lFfdWGpU/79QLiCQC3mBpkyJ8Yu3bXCh4W4qxarC3n8QaCadjg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem.certspec new file mode 100644 index 0000000000..b336397ab6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v3-noBC_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-v3-noBC +extension:keyUsage:keyCertSign,cRLSign +version:3 diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem new file mode 100644 index 0000000000..000898b869 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAwIUD7Qul1mX5757Z6c1xfzbff8Bq3kwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMaW50LXY0LUJDLWNBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzALBgNVHQ8E +BAMCAQYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAX1ogR2JROTKS +BzUzJ8dsfds1qRR4THa+4+1YcuuTJ1P66dnhnRXJVAdJmJyeqezQf23M5O56h4fL +ilt20gptvf7bFd+DZCnV9iHQidQnukj7CweiHOs5xCdjz6+ozZfFpQZaRWX9/462 +VxYOLIWw8ft23liLUmBP/BhPn7W+ILpwvvqLamO3xm68yAGLOlGfz9FH65wupkq2 +wuXjh2XOVEKZ5RdUzXrF40nzVUBBWPwvQTLge+2wD07jXuDegMVrBKkbZDara9TO +HNXcfbT1+9BcRJXlQDJGPyw6oFWHqH+FilAtbXryw3lc9forDWy6nLFvBGW+Ed7a +lpGnStAJ4A== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem.certspec new file mode 100644 index 0000000000..12b94e63a5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v4-BC-cA +extension:keyUsage:keyCertSign,cRLSign +version:4 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem new file mode 100644 index 0000000000..46401840ab --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1DCCAbygAwIBAwIULzzqCIST7DXQ9SzN6d/zzUSfj+UwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGzEZMBcGA1UEAwwQaW50LXY0LUJDLW5vdC1jQTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwCwYD +VR0PBAQDAgEGMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAKlQRoxIy8+V +EtYKZJGAsUvfB4+3LRWZy+eD89bhPUzEgh77u2EZS8byT9/I2+1kv1jJ7I6+G2m2 +cOLGILJBinEB8J3tOZHoUdiwAuqD0+zNBq+6sbItvNlJ84fh66Q1PTNnLWiKaQmr +oIQJ+Nu7crZHkfUrCn8DxHgfaZqI+FV3mWie1AQYrsU9g5ZevWokQr4AH9X/jPrt +ECbGoD5tPF0D3bAy3HxS1kCvwFSh0/GSszffYIaPrcUgOcUGYNdQSstE0y+lKZ2M +ncYUxXd6JI/3OFDTMKRh37JcyPAozQyVecJQLjRc4ycB5uy99zdZzHB2DsMHu3aB +gC2zpGY6iL8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem.certspec new file mode 100644 index 0000000000..43a04f70fd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-BC-not-cA_ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-v4-BC-not-cA +extension:keyUsage:keyCertSign,cRLSign +version:4 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem b/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem new file mode 100644 index 0000000000..c77ad4f7d4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICxDCCAaygAwIBAwIUL9fvs2uc+o6yxIOieQDCERYiO0YwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFjEUMBIGA1UEAwwLaW50LXY0LW5vQkMwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjDzANMAsGA1UdDwQE +AwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAe6Q1mwKjfxiOiyvpExwNTAo48PGfDIAF +L9vF94d6fO7Z04Q5LeIMJwfXqb8sTJBBcsV51IYSMnK/EaVVf9vX7abcya6ku8VT +EF9THjT6+8gXKPj1v1te77kvu0tYRpDQeZ1Nhv7fRm8LsZFZPTKeT+ADR2qZo24J +K3073nn13fod1TnUYIWg5vjDezDUdgqWfRO35rPusy8DtIg3CqkYgXbQJQUnvEj+ +VDWbbmqc7tw3O0xFJVOPyo+/GAIqbSzmqJTzS9o3gBIzicBy8Q3B+s1F0+7qZELX +P8ZOSdY4L0iHKSVEZhFnEmcz/cySwTwt5ou90CdVaNCeOntga0e19A== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem.certspec new file mode 100644 index 0000000000..4970d1e945 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/int-v4-noBC_ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-v4-noBC +extension:keyUsage:keyCertSign,cRLSign +version:4 diff --git a/security/manager/ssl/tests/unit/test_cert_version/moz.build b/security/manager/ssl/tests/unit/test_cert_version/moz.build new file mode 100644 index 0000000000..2e2c294961 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/moz.build @@ -0,0 +1,61 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'ee_int-v1-BC-cA.pem', +# 'ee_int-v1-BC-not-cA.pem', +# 'ee_int-v1-noBC.pem', +# 'ee_int-v2-BC-cA.pem', +# 'ee_int-v2-BC-not-cA.pem', +# 'ee_int-v2-noBC.pem', +# 'ee_int-v3-BC-cA.pem', +# 'ee_int-v3-BC-not-cA.pem', +# 'ee_int-v3-noBC.pem', +# 'ee_int-v4-BC-cA.pem', +# 'ee_int-v4-BC-not-cA.pem', +# 'ee_int-v4-noBC.pem', +# 'ee-v1-BC-cA_ca.pem', +# 'ee-v1-BC-not-cA_ca.pem', +# 'ee-v1-noBC_ca.pem', +# 'ee-v2-BC-cA_ca.pem', +# 'ee-v2-BC-not-cA_ca.pem', +# 'ee-v2-noBC_ca.pem', +# 'ee-v3-BC-cA_ca.pem', +# 'ee-v3-BC-not-cA_ca.pem', +# 'ee-v3-noBC_ca.pem', +# 'ee-v4-BC-cA_ca.pem', +# 'ee-v4-BC-not-cA_ca.pem', +# 'ee-v4-noBC_ca.pem', +# 'int-v1-BC-cA_ca.pem', +# 'int-v1-BC-not-cA_ca.pem', +# 'int-v1-noBC_ca.pem', +# 'int-v2-BC-cA_ca.pem', +# 'int-v2-BC-not-cA_ca.pem', +# 'int-v2-noBC_ca.pem', +# 'int-v3-BC-cA_ca.pem', +# 'int-v3-BC-not-cA_ca.pem', +# 'int-v3-noBC_ca.pem', +# 'int-v4-BC-cA_ca.pem', +# 'int-v4-BC-not-cA_ca.pem', +# 'int-v4-noBC_ca.pem', +# 'ss-v1-BC-cA.pem', +# 'ss-v1-BC-not-cA.pem', +# 'ss-v1-noBC.pem', +# 'ss-v2-BC-cA.pem', +# 'ss-v2-BC-not-cA.pem', +# 'ss-v2-noBC.pem', +# 'ss-v3-BC-cA.pem', +# 'ss-v3-BC-not-cA.pem', +# 'ss-v3-noBC.pem', +# 'ss-v4-BC-cA.pem', +# 'ss-v4-BC-not-cA.pem', +# 'ss-v4-noBC.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem new file mode 100644 index 0000000000..cb9ec2ab97 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbECFHd1Crm+6DaFhkTjrm8a2lNZn96/MA0GCSqGSIb3DQEBCwUAMBYx +FDASBgNVBAMMC3NzLXYxLUJDLWNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBYxFDASBgNVBAMMC3NzLXYxLUJDLWNBMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxAwDjAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCbtlhHVoAs3xPSRAoXxOuUpyTB +MzQWcIvsS61mkueLRnhBVzkpR+fVlmLUObLpZkVvZpTwlzhutw8A18ALBTfme9vY +8zdzMR/sNDRNe5kFDFWyqRAw7MWKKT70ViM9jJflEpN58wuboB6trwWoGuep5YSG +Tzl9vnxxAPwlvUbMzktFHUYyVfXes5mvA1IjujgexuSLAQP494QWvgjUIIcvd+Vj +FNBhDgj+bt7fhzRc4PF123lFn1bDpl7qxavC6+e7xx0AL1OPbifHTJD9M2sjrHe8 +Jqbq31/YoFQqgI+CTKH2IVnvioacB+rV4AxODP+unfIwNzjef5Z0UM/aXlMO +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem.certspec new file mode 100644 index 0000000000..731396f034 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v1-BC-cA +subject:ss-v1-BC-cA +version:1 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem new file mode 100644 index 0000000000..0a9be9ba44 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbYCFHt8jLZUapQcsSi0Kh9mqYUtCnd8MA0GCSqGSIb3DQEBCwUAMBox +GDAWBgNVBAMMD3NzLXYxLUJDLW5vdC1jQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9zcy12MS1CQy1ub3QtY0EwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk +NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC +fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m +CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM +HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m +1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGj +DTALMAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAFjtTHvdBSPcrUxP3PMM +dnBxm/idtTvwhRcoskIXF/uHw39W9Md4lu9PT5AaSRFy+DCPG6WGuZW7z8qo9ECc +2GbeoBCroJ7yYLQL0avK5SfWsuT79kBBuFXCD8NbDXQGle3RkXg+MrkCsvagoXqt +8vexfNXMwPu6g+iAxZ7LdNjLVmHo8Q8vQKiAxDvjjmscxxrlGc6/biSEychTeEDK +/JQMsD6uSadFCLBcKnZvAox05AxDd08yvlFGtGUx4NFToixkBUJZ8vPL9c0pHXVm +YDKdib/UsN940D+chT7EI4fsolX4F4Ti2c3XbIHqF5yFbySODDKm9eVRCFxfLwrs +7U8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..20d716d494 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-BC-not-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v1-BC-not-cA +subject:ss-v1-BC-not-cA +version:1 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem new file mode 100644 index 0000000000..ca4d8e167a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtTCCAZ0CFCmTa/0HEBZWaC3cI4nBeSBnQgArMA0GCSqGSIb3DQEBCwUAMBUx +EzARBgNVBAMMCnNzLXYxLW5vQkMwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIw +NTAwMDAwMFowFTETMBEGA1UEAwwKc3MtdjEtbm9CQzCCASIwDQYJKoZIhvcNAQEB +BQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7 +wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCAp +k6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhh +eZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KW +EsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONssc +JAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAATANBgkqhkiG9w0B +AQsFAAOCAQEAGsjqQY3SWLufSRTl3mGq0Wv4rI5mSYOJlsZKCMtVXkMMs3QUNCcD +1a7Fnae6tFjcpBElxgFFISLdmQ8lZXa4Et7flcwwYiQO9Hfzwpz/onlq1Cl150a0 +okDieDL5cklYlCoR2KGgq5T56K9PRKsAHWNys5Uhxfo+ysK/R8oqEVOUpm3k/Nsh +k9EMx40a+T7idLj3z+D3hAOm9sus+TVSd0JXT0IFyJKf9+h7A6OCQasO9sTN7vpN +O9nJf2aCU2rFPoTxOShDGJRqIFPLK2F1Efib8VqfZ85VmkepxyyzSpYnLYYtPLkK +bpSqCfUSchX8syla2zeOldxUHWA2RjWYVw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem.certspec new file mode 100644 index 0000000000..58d2f0d7f5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v1-noBC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ss-v1-noBC +subject:ss-v1-noBC +version:1 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem new file mode 100644 index 0000000000..1442072cd4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbagAwIBAQIUQQKlrDt19yvMQsPwETMYCCytugwwDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLc3MtdjItQkMtY0EwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowFjEUMBIGA1UEAwwLc3MtdjItQkMtY0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAO +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHG8xQ7meUSvopihSREz +/svytvDvWFrlANJTBuUTDQUE/RR6uOgkJkSf3+je2Ngg4zCVkxqq+hSkbo+rQ+nA +MhcDpNDxqu0waYeujbFIPMQ5iapebD7GoGKYZjv8HOHcg+PDDClP5ANIfUJBuTEF +R9PePsHgnlF9wupRywfdd4E98psZmKhiHA7/rMiCmaf3lbxASVbqo2eWNMsBIzCb +FQXab4rplzcQ+B76IzTNWRv08x+K32dApNfirepO5yCE5aLXn3XrChzV8tHgPaco +gta9/I538U1xZOh3Z6qpQzksqL6r3inamvqvI10ZNB+/Mi0jUexPxyoj7MLCbtO1 +lI4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem.certspec new file mode 100644 index 0000000000..8dbb3a65ad --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v2-BC-cA +subject:ss-v2-BC-cA +version:2 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem new file mode 100644 index 0000000000..f78ceabdeb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAQIUNbZQDstJLaaiUaQfs27GbUHZ38UwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPc3MtdjItQkMtbm90LWNBMCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD3NzLXYyLUJDLW5vdC1jQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAJWGrrP8uHTXB +pIl5CU+IUk88BswSpETWnKenUqwyLfdQlr0fCzWPzZjZ+tbbtKLzHTdIhjAFqpwm +Q7fefDO/CNmmRb49OajJE8HO3cHltcWK8mbIUgMsdcWpCCNyUBmwuxsAMj4ggJHE +2p9KTvRorOj2Jzgvt2PktM7hV3Mh/hGP2VETMr4g1m87mSanFtmOUAX8BJ8Aemjj +HHwPzJMCjnnfDap6YpIzgQQoRK+f/X9PiAfxM1vzjVezdiXjB1WWxqKMf7AcyTbz +1QGA1bfMmJ1pRazpGqzeZmnADjvtcnmYKU0/MY5eAcmAVWRqbffg17Bgoj3ZKgc/ +sIiWXjciJA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..2b8f4bcc55 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-BC-not-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v2-BC-not-cA +subject:ss-v2-BC-not-cA +version:2 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem new file mode 100644 index 0000000000..46909ed0f8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICujCCAaKgAwIBAQIUFaBZ6C5ChVgFJTuYCY+Fv2HlV9UwDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKc3MtdjItbm9CQzAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAVMRMwEQYDVQQDDApzcy12Mi1ub0JDMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQBnZXBfG8G0KE0SXdrsOA1pD/WGg0vnlbEZyL2/NCBoyuNb +l57Ktb2ZtmSVgiAAtEnDDmeqUxkLKK0EVxyO1rRfWfgMf9C5+YwZvglnev0fZLN5 +k3+hQp3y4d15fURD70DbVajH4zk3S61GdlvUL4ic2qU4J6B1NudQSaDa8gn9sCBq +rLrwmozkBOqL47QrFzXqigakuV+6b7ZU3Dh3c5xs2LtNMMlblMU2Ib0o/wgF7J6g +bouwR3fbrBTmIwPCSsw/zM98H5v0xWYiKpGd8RKrazVpPnEmKzmud8aYhasRpTeB +yQ+yfqGfJjrEJ/TAz++I/0/lAu63V1pFQRsTejAW +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem.certspec new file mode 100644 index 0000000000..7656115a84 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v2-noBC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ss-v2-noBC +subject:ss-v2-noBC +version:2 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem new file mode 100644 index 0000000000..075d1f7071 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbagAwIBAgIUETSep9lFvjlmLDhUIYgZJ9C1AZ4wDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLc3MtdjMtQkMtY0EwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowFjEUMBIGA1UEAwwLc3MtdjMtQkMtY0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAO +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAAJA2yM4He8/hSksOiLp +3WCPkSxarm9MIbj/XbbKpiDw5OZLsbwZzth6d1KJ38q57j0boNHNEPM5AJwW0jep +izBQzVS+8Xy0x66MxEIoaxF/tVWNBnWnr6WPci8XpJl60XUcj/T8kPrncZ4jfu8I +99qeMHMsv8LG4BzCZGkiHdmxGFbKvn9Fl1Incq2yTu4jR5nn9AeoyksYbbtbEFIB +YUgWpmSj9Eu2g9JT1nq35ovOZ7wgcDXxnFiCHcULiMOw2ZrMViWhMRKOo5o93kZn +34b4sPJ0dOnKVnLM09wICdvq2c4aDGKy6lCVoZPBV8yjxeqGdUeTVeHMZBJHAZUV +FmQ= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem.certspec new file mode 100644 index 0000000000..df822e99b9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v3-BC-cA +subject:ss-v3-BC-cA +version:3 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem new file mode 100644 index 0000000000..897001600f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUCxOdFiOnJjGWpdtzdSkevnFmtiUwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPc3MtdjMtQkMtbm90LWNBMCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD3NzLXYzLUJDLW5vdC1jQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAsXgT1HoCwbXS +yEW8j3hk7f8XrtC+l5oXby/NtEEh0UqG5/gjkkoPUXKh3kU/EsmwzadFtr9j8H5i +Vy8+zr2rIkNzc8WkpXRLyvuwzRW04sIVmEnvvHWVnWIKoILk5XQ9wKKrXO40H4Jy +6Fva9+f31D5y1hsPbYfmfKZlNxPrM9Mvd+NG5N/PEkBDzHkqMTh0jTmUs99DcoyR +QVIta5ctnV8O+xWVTmKIte7hPGLnAUiDC54LNYkIXhevO6KbqpMvk74sKRPJRryt +2NiTaSKu9YxL+Nv5wWqh2quv8hp6y4kzGt/dp9CrE3GQXkCe/KrTJr4Z6EBQfglL +fy9XXKPejg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..0b2b575573 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-BC-not-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v3-BC-not-cA +subject:ss-v3-BC-not-cA +version:3 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem new file mode 100644 index 0000000000..41c6121a97 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICujCCAaKgAwIBAgIUK8t7xNHS43H4akDzvAdNmXRk9l0wDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKc3MtdjMtbm9CQzAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAVMRMwEQYDVQQDDApzcy12My1ub0JDMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQCh6MJjtVoXMs9CqIvFGOtC5xZBzApCyVVlO0sWRgdZ85Wr +n0vdkUsRk7TPTeRmxC9aNtUHAYv7PznW59b8Kt3eOC2datSCu/d4HLLZasuwk/ti +7ILH4wnLJx1NQJ/luax74pHmFR/ws+OomzL0IXu+nVsB/rv4OuNVZ2R4BlTsKdma +conhammBSvpgCwOAXnT8lZAY0z9jYZfWYqKFgTz3wj9kyocrlJZNshf5JULEK4KZ +tbJaVhFMv4BQK2ONaWj3fzjSVKW/lqUvd1P0c2Of/x48RXQlkZu5l87K/NQ99Nr5 +VprqZiNgNWMlOlMs+I2ooDjjdHLq/g5tlgF/kK48 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem.certspec new file mode 100644 index 0000000000..96314e51a7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v3-noBC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ss-v3-noBC +subject:ss-v3-noBC +version:3 diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem new file mode 100644 index 0000000000..b00a723c6c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbagAwIBAwIUGR1OiiW80EkYCQaIVEB2xPm51J8wDQYJKoZIhvcNAQEL +BQAwFjEUMBIGA1UEAwwLc3MtdjQtQkMtY0EwIhgPMjAxOTExMjgwMDAwMDBaGA8y +MDIyMDIwNTAwMDAwMFowFjEUMBIGA1UEAwwLc3MtdjQtQkMtY0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAO +MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBABE/8s/iuB1DHRKW7Odz +uv1MVeVgCYeWfVGJVZ9w5dMVvmng8/7tkSffzVmuKdbvcfugQ6QzTAXFaPeMzFa/ +djSrxTghal5rH36truQrNZKHkcMxzDkD1G7FuEYomZVuODWhRIQ1mZWS/AnyVoA0 +B4Dr7u1ULdDqaaWroxZX0i9UG2QtDX6DAytzeNJwxgJ0UhnHJ3b4uRJN92rObzQ9 +HwBwfWwFGfrjnO/DGn60NxDr6zdjNmK8pgzmEjgGxPE9lHsOkF4skq/9XnyUMh5N +41EXZL3PC7PwgG2nYeFEkUd0rP2HahxkBEIcO2iVWorqhfBWGLRQUzYtfd8V/5QU +B90= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem.certspec new file mode 100644 index 0000000000..54269184ed --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v4-BC-cA +subject:ss-v4-BC-cA +version:4 +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem new file mode 100644 index 0000000000..b5aa017f80 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAwIUISiwRjGQW0zDa8BcggTNw+Gw6EAwDQYJKoZIhvcNAQEL +BQAwGjEYMBYGA1UEAwwPc3MtdjQtQkMtbm90LWNBMCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD3NzLXY0LUJDLW5vdC1jQTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaMNMAswCQYDVR0TBAIwADANBgkqhkiG9w0BAQsFAAOCAQEAl20D6S5AemWE +GJMgprIXINyeCpH7K2umFjmzoVk73HosNjOaPDZPgk+v4n8Wf2CVg21uU4U3v5LK +1EHmNicbnI23fV/J/PPb1yy2YZ7+YPVolx8DwsxxYWH6N7aTGCdLwe6L44O91uQk +zCXNXD/mHyRraYb1xPFLIg1GzzIz8LVHrax9V7Jz/u3TlhSeSRORaUbvJgrCm9nX +V/7Ozc8czgtKfnTaeLz6791rK1my+gymoB01wbirqwxEzpWTlTFXUMCyzeLc/vuu +L9+vHAWT4pglrPMRCa4GqGlmIdXpTj65kiYMTVHOdP8xKZL9q6jfDYLB1buYt+pz +Nvh82338Bw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem.certspec new file mode 100644 index 0000000000..3d65335316 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-BC-not-cA.pem.certspec @@ -0,0 +1,4 @@ +issuer:ss-v4-BC-not-cA +subject:ss-v4-BC-not-cA +version:4 +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem new file mode 100644 index 0000000000..275306dc28 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICujCCAaKgAwIBAwIUAWcyAUceQlTM7+BoK8oA8uak6q0wDQYJKoZIhvcNAQEL +BQAwFTETMBEGA1UEAwwKc3MtdjQtbm9CQzAiGA8yMDE5MTEyODAwMDAwMFoYDzIw +MjIwMjA1MDAwMDAwWjAVMRMwEQYDVQQDDApzcy12NC1ub0JDMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqG +SIb3DQEBCwUAA4IBAQCiyfMdjGJ6o4Yw2Q3L5QbFRBijGCTVn1547HXPibTewg8G +Z0/2twX36MKwbUGvq/rWMhsKKMrdbf72W9pCvyPcRQKfxO2XFqfxUF8TDUI0DKw7 +Wj1+vmfsxu99bArAk6ESUgYoYHij+Y5OLIKjWYgqXQEOVx+/Ywtv4kQv+Hlc1kzg +0H3rQcLboya8NxX6zNqO+l7xpKw+eoiEyF+hqjrjbAzKgbQbOA1t9ts1xlFcfTJ1 +36DqE4eWsP+lNBHPAOXSMXUtFEjgXw7UA73zOxWJUqnPRvKjqpMEE8P84bt7PoEX +riT1RslyhX2zDCn4KhLzbqrHk+9hZQ+K+HB+E9r3 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem.certspec b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem.certspec new file mode 100644 index 0000000000..d02e04de51 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_cert_version/ss-v4-noBC.pem.certspec @@ -0,0 +1,3 @@ +issuer:ss-v4-noBC +subject:ss-v4-noBC +version:4 diff --git a/security/manager/ssl/tests/unit/test_constructX509FromBase64.js b/security/manager/ssl/tests/unit/test_constructX509FromBase64.js new file mode 100644 index 0000000000..7a4f3915af --- /dev/null +++ b/security/manager/ssl/tests/unit/test_constructX509FromBase64.js @@ -0,0 +1,90 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Checks that ConstructX509FromBase64() accepts valid input and rejects invalid +// input. + +do_get_profile(); // Must be called before getting nsIX509CertDB +const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function excMessage(e) { + if (e.message) { + let msg = e.message; + if (e.data) { + msg = msg + ": " + e.data; + } + return msg; + } + + return e.toString(); +} + +function testGood(data) { + try { + let cert = certDB.constructX509FromBase64(data.cert); + equal( + cert.commonName, + data.cn, + "Actual and expected commonName should match" + ); + } catch (e) { + info(`Exception: ${excMessage(e)}`); + ok(false, `Should not have gotten an exception for "CN=${data.cn}"`); + } +} + +function testBad(data) { + throws( + () => certDB.constructX509FromBase64(data.input), + data.result, + `Should get "${data.result}" for "${data.input}"` + ); +} + +function run_test() { + const badCases = [ + // Wrong type or too short + { input: null, result: /NS_ERROR_ILLEGAL_VALUE/ }, + { input: "", result: /NS_ERROR_ILLEGAL_VALUE/ }, + { input: "=", result: /NS_ERROR_ILLEGAL_VALUE/ }, + { input: "==", result: /NS_ERROR_ILLEGAL_VALUE/ }, + // Not base64 + { input: "forty-four dead stone lions", result: /NS_ERROR_ILLEGAL_VALUE/ }, + // Not a cert + { + input: "Zm9ydHktZm91ciBkZWFkIHN0b25lIGxpb25z", + result: /NS_ERROR_FAILURE/, + }, + ]; + + // Real certs with all three padding levels + const goodCases = [ + { + cn: "A", + cert: + "MIHhMIGcAgEAMA0GCSqGSIb3DQEBBQUAMAwxCjAIBgNVBAMTAUEwHhcNMTEwMzIzMjMyNTE3WhcNMTEwNDIyMjMyNTE3WjAMMQowCAYDVQQDEwFBMEwwDQYJKoZIhvcNAQEBBQADOwAwOAIxANFm7ZCfYNJViaDWTFuMClX3+9u18VFGiyLfM6xJrxir4QVtQC7VUC/WUGoBUs9COQIDAQABMA0GCSqGSIb3DQEBBQUAAzEAx2+gIwmuYjJO5SyabqIm4lB1MandHH1HQc0y0tUFshBOMESTzQRPSVwPn77a6R9t", + }, + { + cn: "Bo", + cert: + "MIHjMIGeAgEAMA0GCSqGSIb3DQEBBQUAMA0xCzAJBgNVBAMTAkJvMB4XDTExMDMyMzIzMjYwMloXDTExMDQyMjIzMjYwMlowDTELMAkGA1UEAxMCQm8wTDANBgkqhkiG9w0BAQEFAAM7ADA4AjEA1FoSl9w9HqMqVgk2K0J3OTiRsgHeNsQdPUl6S82ME33gH+E56PcWZA3nse+fpS3NAgMBAAEwDQYJKoZIhvcNAQEFBQADMQAo/e3BvQAmygiATljQ68tWPoWcbMwa1xxAvpWTEc1LOvMqeDBinBUqbAbSmPhGWb4=", + }, + { + cn: "Cid", + cert: + "MIHlMIGgAgEAMA0GCSqGSIb3DQEBBQUAMA4xDDAKBgNVBAMTA0NpZDAeFw0xMTAzMjMyMzI2MzJaFw0xMTA0MjIyMzI2MzJaMA4xDDAKBgNVBAMTA0NpZDBMMA0GCSqGSIb3DQEBAQUAAzsAMDgCMQDUUxlF5xKN+8KCSsR83sN+SRwJmZdliXsnBB7PU0OgbmOWN0u8yehRkmu39kN9tzcCAwEAATANBgkqhkiG9w0BAQUFAAMxAJ3UScNqRcjHFrNu4nuwRldZLJlVJvRYXp982V4/kYodQEGN4gJ+Qyj+HTsaXy5x/w==", + }, + ]; + + for (let badCase of badCases) { + testBad(badCase); + } + for (let goodCase of goodCases) { + testGood(goodCase); + } +} diff --git a/security/manager/ssl/tests/unit/test_content_signing.js b/security/manager/ssl/tests/unit/test_content_signing.js new file mode 100644 index 0000000000..e96db850b9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing.js @@ -0,0 +1,435 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +"use strict"; + +// These tests ensure content signatures are working correctly. + +// First, we need to set up some data +const PREF_SIGNATURE_ROOT = "security.content.signature.root_hash"; + +const TEST_DATA_DIR = "test_content_signing/"; + +const ONECRL_NAME = "oneCRL-signer.mozilla.org"; +const ABOUT_NEWTAB_NAME = "remotenewtab.content-signature.mozilla.org"; +var VERIFICATION_HISTOGRAM = Services.telemetry.getHistogramById( + "CONTENT_SIGNATURE_VERIFICATION_STATUS" +); +var ERROR_HISTOGRAM = Services.telemetry.getKeyedHistogramById( + "CONTENT_SIGNATURE_VERIFICATION_ERRORS" +); + +function getSignatureVerifier() { + return Cc["@mozilla.org/security/contentsignatureverifier;1"].getService( + Ci.nsIContentSignatureVerifier + ); +} + +function setRoot(filename) { + let cert = constructCertFromFile(filename); + Services.prefs.setCharPref(PREF_SIGNATURE_ROOT, cert.sha256Fingerprint); +} + +function getCertHash(name) { + let cert = constructCertFromFile(`test_content_signing/${name}.pem`); + return cert.sha256Fingerprint.replace(/:/g, ""); +} + +function loadChain(prefix, names) { + let chain = []; + for (let name of names) { + let filename = `${prefix}_${name}.pem`; + chain.push(readFile(do_get_file(filename))); + } + return chain; +} + +function check_telemetry(expected_index, expected, expectedId) { + for (let i = 0; i < 10; i++) { + let expected_value = 0; + if (i == expected_index) { + expected_value = expected; + } + let errorSnapshot = ERROR_HISTOGRAM.snapshot(); + for (let k in errorSnapshot) { + // We clear the histogram every time so there should be only this one + // category. + equal(k, expectedId); + equal(errorSnapshot[k].values[i] || 0, expected_value); + } + equal( + VERIFICATION_HISTOGRAM.snapshot().values[i] || 0, + expected_value, + "count " + + i + + ": " + + VERIFICATION_HISTOGRAM.snapshot().values[i] + + " expected " + + expected_value + ); + } + VERIFICATION_HISTOGRAM.clear(); + ERROR_HISTOGRAM.clear(); +} + +add_task(async function run_test() { + // set up some data + const DATA = readFile(do_get_file(TEST_DATA_DIR + "test.txt")); + const GOOD_SIGNATURE = + "p384ecdsa=" + + readFile(do_get_file(TEST_DATA_DIR + "test.txt.signature")).trim(); + + const BAD_SIGNATURE = + "p384ecdsa=WqRXFQ7tnlVufpg7A-ZavXvWd2Zln0o4woHBy26C2r" + + "UWM4GJke4pE8ecHiXoi-7KnZXty6Pe3s4o3yAIyKDP9jUC52Ek1G" + + "q25j_X703nP5rk5gM1qz5Fe-qCWakPPl6L"; + + let remoteNewTabChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "remote_newtab_ee", + "int", + "root", + ]); + + let oneCRLChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "onecrl_ee", + "int", + "root", + ]); + + let oneCRLBadKeyChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "onecrl_wrong_key_ee", + "int", + "root", + ]); + + let noSANChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "onecrl_no_SAN_ee", + "int", + "root", + ]); + + let expiredOneCRLChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "onecrl_ee_expired", + "int", + "root", + ]); + + let notValidYetOneCRLChain = loadChain(TEST_DATA_DIR + "content_signing", [ + "onecrl_ee_not_valid_yet", + "int", + "root", + ]); + + // Check signature verification works without error before the root is set + VERIFICATION_HISTOGRAM.clear(); + let chain1 = oneCRLChain.join("\n"); + let verifier = getSignatureVerifier(); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "Before the root is set, signatures should fail to verify but not throw." + ); + // Check for generic chain building error. + check_telemetry(6, 1, getCertHash("content_signing_onecrl_ee")); + + setRoot(TEST_DATA_DIR + "content_signing_root.pem"); + + // Check good signatures from good certificates with the correct SAN + ok( + await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + ), + "A OneCRL signature should verify with the OneCRL chain" + ); + let chain2 = remoteNewTabChain.join("\n"); + ok( + await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain2, + ABOUT_NEWTAB_NAME + ), + "A newtab signature should verify with the newtab chain" + ); + // Check for valid signature + check_telemetry(0, 2, getCertHash("content_signing_remote_newtab_ee")); + + // Check a bad signature when a good chain is provided + chain1 = oneCRLChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + BAD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "A bad signature should not verify" + ); + // Check for invalid signature + check_telemetry(1, 1, getCertHash("content_signing_onecrl_ee")); + + // Check a good signature from cert with good SAN but a different key than the + // one used to create the signature + let badKeyChain = oneCRLBadKeyChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + badKeyChain, + ONECRL_NAME + )), + "A signature should not verify if the signing key is wrong" + ); + // Check for wrong key in cert. + check_telemetry(9, 1, getCertHash("content_signing_onecrl_wrong_key_ee")); + + // Check a good signature from cert with good SAN but a different key than the + // one used to create the signature (this time, an RSA key) + let rsaKeyChain = oneCRLBadKeyChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + rsaKeyChain, + ONECRL_NAME + )), + "A signature should not verify if the signing key is wrong (RSA)" + ); + // Check for wrong key in cert. + check_telemetry(9, 1, getCertHash("content_signing_onecrl_wrong_key_ee")); + + // Check a good signature from cert with good SAN but with chain missing root + let missingRoot = [oneCRLChain[0], oneCRLChain[1]].join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + missingRoot, + ONECRL_NAME + )), + "A signature should not verify if the chain is incomplete (missing root)" + ); + // Check for generic chain building error. + check_telemetry(6, 1, getCertHash("content_signing_onecrl_ee")); + + // Check a good signature from cert with good SAN but with no path to root + let missingInt = [oneCRLChain[0], oneCRLChain[2]].join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + missingInt, + ONECRL_NAME + )), + "A signature should not verify if the chain is incomplete (missing int)" + ); + // Check for generic chain building error. + check_telemetry(6, 1, getCertHash("content_signing_onecrl_ee")); + + // Check good signatures from good certificates with the wrong SANs + chain1 = oneCRLChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + ABOUT_NEWTAB_NAME + )), + "A OneCRL signature should not verify if we require the newtab SAN" + ); + // Check for invalid EE cert. + check_telemetry(7, 1, getCertHash("content_signing_onecrl_ee")); + + chain2 = remoteNewTabChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain2, + ONECRL_NAME + )), + "A newtab signature should not verify if we require the OneCRL SAN" + ); + // Check for invalid EE cert. + check_telemetry(7, 1, getCertHash("content_signing_remote_newtab_ee")); + + // Check good signatures with good chains with some other invalid names + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + "" + )), + "A signature should not verify if the SANs do not match an empty name" + ); + // Check for invalid EE cert. + check_telemetry(7, 1, getCertHash("content_signing_onecrl_ee")); + + // Test expired certificate. + let chainExpired = expiredOneCRLChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chainExpired, + "" + )), + "A signature should not verify if the signing certificate is expired" + ); + // Check for expired cert. + check_telemetry(4, 1, getCertHash("content_signing_onecrl_ee_expired")); + + // Test not valid yet certificate. + let chainNotValidYet = notValidYetOneCRLChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chainNotValidYet, + "" + )), + "A signature should not verify if the signing certificate is not valid yet" + ); + // Check for not yet valid cert. + check_telemetry(5, 1, getCertHash("content_signing_onecrl_ee_not_valid_yet")); + + let relatedName = "subdomain." + ONECRL_NAME; + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + relatedName + )), + "A signature should not verify if the SANs do not match a related name" + ); + + let randomName = + "\xb1\x9bU\x1c\xae\xaa3\x19H\xdb\xed\xa1\xa1\xe0\x81\xfb" + + "\xb2\x8f\x1cP\xe5\x8b\x9c\xc2s\xd3\x1f\x8e\xbbN"; + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + randomName + )), + "A signature should not verify if the SANs do not match a random name" + ); + + // check good signatures with chains that have strange or missing SANs + chain1 = noSANChain.join("\n"); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "A signature should not verify if the SANs do not match a supplied name" + ); + + // Check malformed signature data + chain1 = oneCRLChain.join("\n"); + let bad_signatures = [ + // wrong length + "p384ecdsa=WqRXFQ7tnlVufpg7A-ZavXvWd2Zln0o4woHBy26C2rUWM4GJke4pE8ecHiXoi-" + + "7KnZXty6Pe3s4o3yAIyKDP9jUC52Ek1Gq25j_X703nP5rk5gM1qz5Fe-qCWakPPl6L==", + // incorrectly encoded + "p384ecdsa='WqRXFQ7tnlVufpg7A-ZavXvWd2Zln0o4woHBy26C2rUWM4GJke4pE8ecHiXoi" + + "-7KnZXty6Pe3s4o3yAIyKDP9jUC52Ek1Gq25j_X703nP5rk5gM1qz5Fe-qCWakPPl6L=", + // missing directive + "other_directive=WqRXFQ7tnlVufpg7A-ZavXvWd2Zln0o4woHBy26C2rUWM4GJke4pE8ec" + + "HiXoi-7KnZXty6Pe3s4o3yAIyKDP9jUC52Ek1Gq25j_X703nP5rk5gM1qz5Fe-qCWakPPl6L", + // actually sha256 with RSA + "p384ecdsa=XS_jiQsS5qlzQyUKaA1nAnQn_OvxhvDfKybflB8Xe5gNH1wNmPGK1qN-jpeTfK" + + "6ob3l3gCTXrsMnOXMeht0kPP3wLfVgXbuuO135pQnsv0c-ltRMWLe56Cm4S4Z6E7WWKLPWaj" + + "jhAcG5dZxjffP9g7tuPP4lTUJztyc4d1z_zQZakEG7R0vN7P5_CaX9MiMzP4R7nC3H4Ba6yi" + + "yjlGvsZwJ_C5zDQzWWs95czUbMzbDScEZ_7AWnidw91jZn-fUK3xLb6m-Zb_b4GAqZ-vnXIf" + + "LpLB1Nzal42BQZn7i4rhAldYdcVvy7rOMlsTUb5Zz6vpVW9LCT9lMJ7Sq1xbU-0g==", + ]; + for (let badSig of bad_signatures) { + await Assert.rejects( + verifier.asyncVerifyContentSignature(DATA, badSig, chain1, ONECRL_NAME), + /NS_ERROR/, + `Bad or malformed signature "${badSig}" should be rejected` + ); + } + + // Check malformed and missing certificate chain data + let chainSuffix = [oneCRLChain[1], oneCRLChain[2]].join("\n"); + let badChains = [ + // no data + "", + // completely wrong data + "blah blah \n blah", + ]; + + let badSections = [ + // data that looks like PEM but isn't + "-----BEGIN CERTIFICATE-----\nBSsPRlYp5+gaFMRIczwUzaioRfteCjr94xyz0g==\n", + // data that will start to parse but won't base64decode + "-----BEGIN CERTIFICATE-----\nnon-base64-stuff\n-----END CERTIFICATE-----", + // data with garbage outside of PEM sections + "this data is garbage\n-----BEGIN CERTIFICATE-----\nnon-base64-stuff\n" + + "-----END CERTIFICATE-----", + ]; + + for (let badSection of badSections) { + // ensure we test each bad section on its own... + badChains.push(badSection); + // ... and as part of a chain with good certificates + badChains.push(badSection + "\n" + chainSuffix); + } + + for (let badChain of badChains) { + await Assert.rejects( + verifier.asyncVerifyContentSignature( + DATA, + GOOD_SIGNATURE, + badChain, + ONECRL_NAME + ), + /NS_ERROR/, + `Bad chain data starting "${badChain.substring(0, 80)}" ` + + "should be rejected" + ); + } + + ok( + !(await verifier.asyncVerifyContentSignature( + DATA + "appended data", + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "A good signature should not verify if the data is tampered with (append)" + ); + ok( + !(await verifier.asyncVerifyContentSignature( + "prefixed data" + DATA, + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "A good signature should not verify if the data is tampered with (prefix)" + ); + ok( + !(await verifier.asyncVerifyContentSignature( + DATA.replace(/e/g, "i"), + GOOD_SIGNATURE, + chain1, + ONECRL_NAME + )), + "A good signature should not verify if the data is tampered with (modify)" + ); +}); diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem new file mode 100644 index 0000000000..e3d6133226 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC1TCCAb2gAwIBAgIUfypncvlf0ZBX1MQ7mXPauUSiPVMwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowETEPMA0GA1UEAwwGaW50LUNBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyUwIzAMBgNVHRMEBTADAQH/ +MBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IBAQA/uUqk6o66 +Hfkdkn/XZA7Wszvsz4k+eQEf/0Y15EqvjGPm1pS1qj/aQXhKqwA6kDaIP8urgUOu +53ikXeiSE1LDFYHlduem8MgHg7tJ0QjzSAzdgjslHUuF0umbemwnXAbwGYfMlJOQ +Pc2898QJoev+6YWC0Mb3nV86X0NwH9BTKVCqaxrQi0edqndxKv6VggfAyhPaw+TN +jO8z3Hvv9APY184Spg/ndPhZPJ3hGCve8eus0hRhpSoRpGH6cmCw0IedUVhDpR1R +StT5bZ2/XEGaKFGEIjYKzrreMIgdOfNQlsBB1iD/40qi+Mi1/m9ctYJv2RJaEjpw +gu6XceM2TJaJ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem.certspec new file mode 100644 index 0000000000..4134a73c6f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_int.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-CA +extension:basicConstraints:cA, +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem new file mode 100644 index 0000000000..0908caae85 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8TCCAdmgAwIBAgIUETmtBD+18aLFBIz4293Yn084a+MwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBExDzANBgNVBAMMBmVlLVJTQTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaM9MDswEwYDVR0lBAww +CgYIKwYBBQUHAwMwJAYDVR0RBB0wG4IZb25lQ1JMLXNpZ25lci5tb3ppbGxhLm9y +ZzANBgkqhkiG9w0BAQsFAAOCAQEAEnk3u7e+n8mGwAbfy3Wj3RiBhXkJEN31ClBG +/NsXUeRBv89rPb2m8DyLBcEWvyNgQ0woyUPmrP5vsIUYQ64mshWuLgSzEk5/lY2+ +Quro14NKCTWo4F/DNgra5lq7Q3S8tXhmM+mBlsxK5QN2kWQM0ODlZtMp3P9821DH +OqaRTDvqd9dO2lFwlZ3vW5w5Uq/HQxciSkea4D2l1PcoWaqI7Zze66jj3H5kBoMY +SN4n9+RqPXUyBuF1A0d3W/jIzSnW7f3F6Gwe8fzhNsiyVE71tRHNForx4KtDR6BG +lyapz8MMoaTCgaS6gbv6RshJkRusqBQxvBY6JVgYBbkXw/IWBw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem.certspec new file mode 100644 index 0000000000..7b2a02bdaf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_RSA_ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-CA +subject:ee-RSA +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:oneCRL-signer.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem new file mode 100644 index 0000000000..7dba148b87 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICPzCCASegAwIBAgIUKVuGEG5eiGwlJfVnv/ULDdeFL0gwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE +oWhyQzYrXHsYifN5FUYVocc/tI3uhj4CKRXbYI4lLeS3Ey2ozpjoMVNOapwMCwnI +1jmt6DIG5bqBNHOhH6Mw4F2oyW5Dg/4nhz2pcQO+KIjP8ALwWvcaH93Mg3SqbqnO +oz0wOzATBgNVHSUEDDAKBggrBgEFBQcDAzAkBgNVHREEHTAbghlvbmVDUkwtc2ln +bmVyLm1vemlsbGEub3JnMA0GCSqGSIb3DQEBCwUAA4IBAQA/Lumx62bij+HfehIY +6+jXkePuTOsaRpL1W5jk3ai78rWYRAVzDgM389kTBYJYCViHglgZQmQUeU8+sS46 +L/PO17BboOsCgqZt5QPSGPqSFvmqFgNOT2bl6rKtg6F5pM+orlCU816noIOCFOTJ +AHQHvK6qcy6SBGOn7BqvNMsRhGc7zqn2tTMt0FzjO7ULroR68aOLDCTzTgiDpz3A +DELgbpWFFE+W8flGnO1NRXwQDX3kEVlgVlOGrw5RsryE9HTYFhV4KXymxluKjL7C +oJFn115lsgbmbK38DKhjU4Sk0EHgFjC3K28fGaYtIBWoHAG3XGu1sBhWNCGCWqVH +Q7un +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem.certspec new file mode 100644 index 0000000000..ab22807b9e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:int-CA +subject:ee +subjectKey:secp384r1 +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:oneCRL-signer.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem new file mode 100644 index 0000000000..ef22669f4d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICTjCCATagAwIBAgIUOQNrYQz01j0SirgoHMLKbtGL9RowDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTMwMTAxMDAwMDAwWhgPMjAxNDAx +MDEwMDAwMDBaMBwxGjAYBgNVBAMMEWVlLWludC1DQS1leHBpcmVkMHYwEAYHKoZI +zj0CAQYFK4EEACIDYgAEoWhyQzYrXHsYifN5FUYVocc/tI3uhj4CKRXbYI4lLeS3 +Ey2ozpjoMVNOapwMCwnI1jmt6DIG5bqBNHOhH6Mw4F2oyW5Dg/4nhz2pcQO+KIjP +8ALwWvcaH93Mg3SqbqnOoz0wOzATBgNVHSUEDDAKBggrBgEFBQcDAzAkBgNVHREE +HTAbghlvbmVDUkwtc2lnbmVyLm1vemlsbGEub3JnMA0GCSqGSIb3DQEBCwUAA4IB +AQBZJPo4llgMe5588+BnRLnFguspIiwMWmTeqCfi8VQBx/tUwRiTizbU7J2Yh9bo +yZEPKfPSP2o8J0eSUgvXdVOxU1fNRuocsVfXUlveq5x10ddjXBT9X4AY1mtR7HJw +hl/7269N8b4itfrfvZmCBToJayjv0I2N84bqjpOnXJ/iB5YVdk8oZIJDXWi4SR3B +E9IejwA1fikpt++RjpJSZ1BSNU7FfiyGGUonxHDoP/29znaOJnpAqaH5LVJCRkfN +H12vePBbunZd+ay5r+mMJPaXR+V2sY8OaOfcrPSHQLa8Eb/EEhBuITMKkOucohjx +zqvM6S2iOI9GbwHClybEHRO7 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem.certspec new file mode 100644 index 0000000000..48fd9c8cc7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_expired.pem.certspec @@ -0,0 +1,6 @@ +issuer:int-CA +subject:ee-int-CA-expired +subjectKey:secp384r1 +validity:20130101-20140101 +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:oneCRL-signer.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem new file mode 100644 index 0000000000..6cf5c6a312 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICVDCCATygAwIBAgIUbV+rBAfhGRv/bU22A92xneoAy3owDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwNTAwMTAxMDAwMDAwWhgPMjA1MTAx +MDEwMDAwMDBaMCIxIDAeBgNVBAMMF2VlLWludC1DQS1ub3QteWV0LXZhbGlkMHYw +EAYHKoZIzj0CAQYFK4EEACIDYgAEoWhyQzYrXHsYifN5FUYVocc/tI3uhj4CKRXb +YI4lLeS3Ey2ozpjoMVNOapwMCwnI1jmt6DIG5bqBNHOhH6Mw4F2oyW5Dg/4nhz2p +cQO+KIjP8ALwWvcaH93Mg3SqbqnOoz0wOzATBgNVHSUEDDAKBggrBgEFBQcDAzAk +BgNVHREEHTAbghlvbmVDUkwtc2lnbmVyLm1vemlsbGEub3JnMA0GCSqGSIb3DQEB +CwUAA4IBAQAjXmLNn2kLa/FzNp7F3PqcSXuAO2jT31Y2g4pZnVqCDfMqplsl2ZFn +oam3wyQnepm3q9DD4BOAW9JFYR3wqnl9cBRNHlSGyjGM4qBpuSD6WxAz7EdFcRO6 +fcA50245fAuB45UJeYJ58QvIBv7AwoBGnqAI7ZDN3eIGopZIL56jiH7vO9WyQPWj +XZAWrXTG68rEf0RxXRtjUv9coFiuInT8+oyXB3NwK2EbaI5IeR+x3qIDEgNKk+t+ +PlE3NrtaAiK19p0s9RtQQilBKNmo+5irrUq/OD2H1aurDaAXpLTM5vLUpfyN3/qD +HzuZujaUIeMsRiXsIRDNql1S+nq4oNRy +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem.certspec new file mode 100644 index 0000000000..b2926dfc42 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_ee_not_valid_yet.pem.certspec @@ -0,0 +1,6 @@ +issuer:int-CA +subject:ee-int-CA-not-yet-valid +subjectKey:secp384r1 +validity:20500101-20510101 +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:oneCRL-signer.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem new file mode 100644 index 0000000000..defa2dca5d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICIDCCAQigAwIBAgIUQQefsZHHyGIzVRjWiIp+2Sojjt8wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBQxEjAQBgNVBAMMCWVlLW5vLVNBTjB2MBAGByqGSM49AgEGBSuB +BAAiA2IABKFockM2K1x7GInzeRVGFaHHP7SN7oY+AikV22COJS3ktxMtqM6Y6DFT +TmqcDAsJyNY5regyBuW6gTRzoR+jMOBdqMluQ4P+J4c9qXEDviiIz/AC8Fr3Gh/d +zIN0qm6pzqMXMBUwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQAD +ggEBAKT/ZTZsIyuxQFbK8CcN/DwFVxYfSDVLxDdv1hytINxuAHjpOF2kkcxHvUDf +pjXG6pMSFip2+dJp61qDrDzeb68K0bzYjGvalDbv9a8JDKUI+mhGTfm7wh2ZmxRm +SIZEP0fQ9TVB+h29bYqdBaanfWBAcvWKTKDIYE2visis8Jo29fBoeK6TC0fZpzzP +Y5tNZgbwHvMWW39lqTZj0FtKAN7jdRTM0O/KYNAqlbzmtf9gSDNCklxFLRZRlbqO +Z42M6FRc8k2ctbeFAGLZTF7ezolx8HlAUVbaptJPux7oj3dsCiq73aXExDPtiZj6 +9IX27OM4XsJhpS+RmI8GWqVSULI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem.certspec new file mode 100644 index 0000000000..4a9b9a3ceb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_no_SAN_ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-CA +subject:ee-no-SAN +subjectKey:secp384r1 +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem new file mode 100644 index 0000000000..ce04094e82 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICLDCCARSgAwIBAgIUeYPUd9Pk1MZC6Pv1MwwnCAybLMQwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBcxFTATBgNVBAMMDGVlLXdyb25nLWtleTBZMBMGByqGSM49AgEG +CCqGSM49AwEHA0IABE+/u7th4Pj5saYKWayHBOLsBQtCPjz3LpI/LE95S0VcKmnS +M0VsNsQRnQcG4A7tyNGTkNeZG3stB6ME6qBKpsCjPTA7MBMGA1UdJQQMMAoGCCsG +AQUFBwMDMCQGA1UdEQQdMBuCGW9uZUNSTC1zaWduZXIubW96aWxsYS5vcmcwDQYJ +KoZIhvcNAQELBQADggEBAAsDCFfikCk7qQayhqET9q5qHWiXv+0NuLW9j3zpqwQY +uRXfiY34JsSpNtR+AVICUcierAoKfqXe6HTtDtQfjef8viCaer40dfLI9P5gx1l7 +nwybFl0oRNSBo6CZTcLHEdWHXbQvogj27wt75pRP66e9hFnH9FdOqp5WtP1nBVJr +wF8tdRZHHSLlsrLPtCBXMBtZxCBB6grqeIiuP5qz/+ayRvv+be4D6rqJrizHYgnW +q4y0pxHZzOYwrv+cqzRYaVOlwH0oU6mm0d8QDiry4yIGdNSOtO8/a8cdmbQakFXI +XK62f8bnkuYvn6wp/81lyK5DzFQLVobPnNnwloCyjII= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem.certspec new file mode 100644 index 0000000000..fbc8e603f4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_onecrl_wrong_key_ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:int-CA +subject:ee-wrong-key +subjectKey:secp256r1 +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:oneCRL-signer.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem new file mode 100644 index 0000000000..a66b345a72 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICUDCCATigAwIBAgIUMX7ouKJot3CcYRs5Frqu4NZFy/wwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGaW50LUNBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMA0xCzAJBgNVBAMMAmVlMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE +oWhyQzYrXHsYifN5FUYVocc/tI3uhj4CKRXbYI4lLeS3Ey2ozpjoMVNOapwMCwnI +1jmt6DIG5bqBNHOhH6Mw4F2oyW5Dg/4nhz2pcQO+KIjP8ALwWvcaH93Mg3SqbqnO +o04wTDATBgNVHSUEDDAKBggrBgEFBQcDAzA1BgNVHREELjAsgipyZW1vdGVuZXd0 +YWIuY29udGVudC1zaWduYXR1cmUubW96aWxsYS5vcmcwDQYJKoZIhvcNAQELBQAD +ggEBAAgkFNZeQNsGbNCAAWxVpWDdSgvCOYemduVhNJQTLZiZJkDia6hR+tgGGcoB +dkCOjK38ipFeTttdeGTAGW7XwfM7ViB41sRTZnmkuPfAbiQfd4PjZQQ/KqfWipsZ +UQbsXnoCNA9OfeE3RHK+79n8F+Wx7l0ISskYfMxoFE2HF42FuaZ0zh3CnLKQG+gn +l8tiB1a1XgSBRNvXIgpqbyKD5YlHyhj7mW9SkhKfaFRnmktpQWqpmxczRFRNpMnd +BcZRsmkQ+Kye+blgiBLudWrU18yDArYDHWD8ObhlVq9DSBqq1ClWdhxmMUxE95D0 +Bare3XT1RUSTBIuSH9gJFiiUpUw= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem.certspec new file mode 100644 index 0000000000..81e1eefe1d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_remote_newtab_ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:int-CA +subject:ee +subjectKey:secp384r1 +extension:extKeyUsage:codeSigning +extension:subjectAlternativeName:remotenewtab.content-signature.mozilla.org diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem b/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem new file mode 100644 index 0000000000..d35153e96d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUG3upUKWDjbYJ8e8IBkIMf7SrvMMwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjJTAjMAwGA1UdEwQFMAMBAf8wEwYD +VR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAKaz+RKqMBowh2H1 +HBun9kma1zWzkKb4ZNjke2eza3NDWCcDipnpYGB+iNhtzWPc2SA53ZF/yn/xDpWW +zF0UyKsswTxRIS/FmOkXqqTu0bHU7kmdIb+cqSuuDZDshdONGRDspQD/aYPva499 +eKc/X9E96ICCyTAVaL0YQz6UMjPgiTrrP1O5cpYb2uGbny5+okw/Ir3rlKhw0SGb +QqHuXmixawRj3PNzO0B63B0HsMdn+hbybHaZIkgNFrZ4pRmjnbiywMQNsvFzETZc +mgX9vf9puBLgn/3qBpJrObuZ4xux4stfBumKXWQ2S/7HaGn8W1mjOV82TQSCvx4X +Re529ME= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem.certspec b/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem.certspec new file mode 100644 index 0000000000..f5e387b0c4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/content_signing_root.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/unit/test_content_signing/moz.build b/security/manager/ssl/tests/unit/test_content_signing/moz.build new file mode 100644 index 0000000000..0e09e729e5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'content_signing_int.pem', +# 'content_signing_onecrl_RSA_ee.pem', +# 'content_signing_onecrl_ee.pem', +# 'content_signing_onecrl_ee_expired.pem', +# 'content_signing_onecrl_ee_not_valid_yet.pem', +# 'content_signing_onecrl_no_SAN_ee.pem', +# 'content_signing_onecrl_wrong_key_ee.pem', +# 'content_signing_remote_newtab_ee.pem', +# 'content_signing_root.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_content_signing/pysign.py b/security/manager/ssl/tests/unit/test_content_signing/pysign.py new file mode 100644 index 0000000000..2d04cc40ff --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/pysign.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python +# +# 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/. + +""" +Create an ECDSA signature on the P-384 curve using the SHA-384 hash of data from +stdin. The key used for the signature is the secp384r1Encoded key used in pykey +and pycert. + +The certificates for the content signature tests make use of this program. +You can use pysign.py like this: + +cat test.txt | python pysign.py > test.txt.signature +""" + +import base64 +import binascii +import hashlib +import os +import six +import sys + +import ecdsa + +# For pykey +sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) +import pykey + +data = sys.stdin.buffer.read() + +key = pykey.ECCKey("secp384r1") +sig = key.signRaw(b"Content-Signature:\00" + data, pykey.HASH_SHA384) +print base64.b64encode(sig).replace("+", "-").replace("/", "_") diff --git a/security/manager/ssl/tests/unit/test_content_signing/test.txt b/security/manager/ssl/tests/unit/test_content_signing/test.txt new file mode 100644 index 0000000000..2daac1cb00 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/test.txt @@ -0,0 +1 @@ +This is a test file to test content-signature verification with a PKI. diff --git a/security/manager/ssl/tests/unit/test_content_signing/test.txt.signature b/security/manager/ssl/tests/unit/test_content_signing/test.txt.signature new file mode 100644 index 0000000000..e613981473 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_content_signing/test.txt.signature @@ -0,0 +1 @@ +hSvmvvA7_QLedDsjRJGBevqLwjPILx1EtWSPP4A0fepaWWPuuZRB8VfDT2j07bKDacRsbmJjmvg_R4CpKmnoWF8-2w5lSszlFFDqYSvQVQxpKhu-HMM_qquu_l0KecQ2 diff --git a/security/manager/ssl/tests/unit/test_crlite_filters.js b/security/manager/ssl/tests/unit/test_crlite_filters.js new file mode 100644 index 0000000000..17d65773cb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters.js @@ -0,0 +1,697 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +// Tests that CRLite filter downloading works correctly. + +"use strict"; +do_get_profile(); // must be called before getting nsIX509CertDB + +const { RemoteSettings } = ChromeUtils.import( + "resource://services-settings/remote-settings.js" +); +const { RemoteSecuritySettings } = ChromeUtils.import( + "resource://gre/modules/psm/RemoteSecuritySettings.jsm" +); +const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" +); + +const { + CRLiteFiltersClient, + IntermediatePreloadsClient, +} = RemoteSecuritySettings.init(); + +const CRLITE_FILTERS_ENABLED_PREF = + "security.remote_settings.crlite_filters.enabled"; +const INTERMEDIATES_ENABLED_PREF = + "security.remote_settings.intermediates.enabled"; +const INTERMEDIATES_DL_PER_POLL_PREF = + "security.remote_settings.intermediates.downloads_per_poll"; + +function getHashCommon(aStr, useBase64) { + let hasher = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hasher.init(Ci.nsICryptoHash.SHA256); + let stringStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + stringStream.data = aStr; + hasher.updateFromStream(stringStream, -1); + + return hasher.finish(useBase64); +} + +// Get a hexified SHA-256 hash of the given string. +function getHash(aStr) { + return hexify(getHashCommon(aStr, false)); +} + +// Get the name of the file in the test directory to serve as the attachment +// for the given filter. +function getFilenameForFilter(filter) { + if (filter.type == "full") { + return "20201017-0-filter"; + } + if (filter.id == "0001") { + return "20201017-1-filter.stash"; + } + // The addition of another stash file was written more than a month after + // other parts of this test. As such, the second stash file for October 17th, + // 2020 was not readily available. Since the structure of stash files don't + // depend on each other, though, any two stash files are compatible, and so + // this stash from December 1st is used instead. + return "20201201-3-filter.stash"; +} + +/** + * Simulate a Remote Settings synchronization by filling up the local data with + * fake records. + * + * @param {*} filters List of filters for which we will create records. + * @param {Boolean} clear Whether or not to clear the local DB first. Defaults + * to true. + */ +async function syncAndDownload(filters, clear = true) { + const localDB = await CRLiteFiltersClient.client.db; + if (clear) { + await localDB.clear(); + } + + for (let filter of filters) { + const filename = getFilenameForFilter(filter); + const file = do_get_file(`test_crlite_filters/${filename}`); + const fileBytes = readFile(file); + + const record = { + details: { + name: `${filter.timestamp}-${filter.type}`, + }, + attachment: { + hash: getHash(fileBytes), + size: fileBytes.length, + filename, + location: `security-state-workspace/cert-revocations/test_crlite_filters/${filename}`, + mimetype: "application/octet-stream", + }, + incremental: filter.type == "diff", + effectiveTimestamp: new Date(filter.timestamp).getTime(), + parent: filter.type == "diff" ? filter.parent : undefined, + id: filter.id, + }; + + await localDB.create(record); + } + // This promise will wait for the end of downloading. + let promise = TestUtils.topicObserved( + "remote-security-settings:crlite-filters-downloaded" + ); + // Simulate polling for changes, trigger the download of attachments. + Services.obs.notifyObservers(null, "remote-settings:changes-poll-end"); + let results = await promise; + return results[1]; // topicObserved gives back a 2-array +} + +add_task(async function test_crlite_filters_disabled() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, false); + + let result = await syncAndDownload([ + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + ]); + equal(result, "disabled", "CRLite filter download should not have run"); +}); + +add_task(async function test_crlite_no_filters() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([]); + equal( + result, + "unavailable", + "CRLite filter download should have run, but nothing was available" + ); +}); + +add_task(async function test_crlite_only_incremental_filters() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + { + timestamp: "2019-01-01T06:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + { + timestamp: "2019-01-01T18:00:00Z", + type: "diff", + id: "0002", + parent: "0001", + }, + { + timestamp: "2019-01-01T12:00:00Z", + type: "diff", + id: "0003", + parent: "0002", + }, + ]); + equal( + result, + "unavailable", + "CRLite filter download should have run, but no full filters were available" + ); +}); + +add_task(async function test_crlite_incremental_filters_with_wrong_parent() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + { + timestamp: "2019-01-01T06:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + { + timestamp: "2019-01-01T12:00:00Z", + type: "diff", + id: "0003", + parent: "0002", + }, + { + timestamp: "2019-01-01T18:00:00Z", + type: "diff", + id: "0004", + parent: "0003", + }, + ]); + let [status, filters] = result.split(";"); + equal(status, "finished", "CRLite filter download should have run"); + let filtersSplit = filters.split(","); + deepEqual( + filtersSplit, + ["2019-01-01T00:00:00Z-full", "2019-01-01T06:00:00Z-diff"], + "Should have downloaded the expected CRLite filters" + ); +}); + +add_task(async function test_crlite_incremental_filter_too_early() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + { timestamp: "2019-01-02T00:00:00Z", type: "full", id: "0000" }, + { + timestamp: "2019-01-01T00:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + ]); + equal( + result, + "finished;2019-01-02T00:00:00Z-full", + "CRLite filter download should have run" + ); +}); + +add_task(async function test_crlite_filters_basic() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + ]); + equal( + result, + "finished;2019-01-01T00:00:00Z-full", + "CRLite filter download should have run" + ); +}); + +add_task(async function test_crlite_filters_full_and_incremental() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + // These are deliberately listed out of order. + { + timestamp: "2019-01-01T06:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + { + timestamp: "2019-01-01T18:00:00Z", + type: "diff", + id: "0003", + parent: "0002", + }, + { + timestamp: "2019-01-01T12:00:00Z", + type: "diff", + id: "0002", + parent: "0001", + }, + ]); + let [status, filters] = result.split(";"); + equal(status, "finished", "CRLite filter download should have run"); + let filtersSplit = filters.split(","); + deepEqual( + filtersSplit, + [ + "2019-01-01T00:00:00Z-full", + "2019-01-01T06:00:00Z-diff", + "2019-01-01T12:00:00Z-diff", + "2019-01-01T18:00:00Z-diff", + ], + "Should have downloaded the expected CRLite filters" + ); +}); + +add_task(async function test_crlite_filters_multiple_days() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + // These are deliberately listed out of order. + { + timestamp: "2019-01-02T06:00:00Z", + type: "diff", + id: "0011", + parent: "0010", + }, + { + timestamp: "2019-01-03T12:00:00Z", + type: "diff", + id: "0022", + parent: "0021", + }, + { + timestamp: "2019-01-02T12:00:00Z", + type: "diff", + id: "0012", + parent: "0011", + }, + { + timestamp: "2019-01-03T18:00:00Z", + type: "diff", + id: "0023", + parent: "0022", + }, + { + timestamp: "2019-01-02T18:00:00Z", + type: "diff", + id: "0013", + parent: "0012", + }, + { timestamp: "2019-01-02T00:00:00Z", type: "full", id: "0010" }, + { timestamp: "2019-01-03T00:00:00Z", type: "full", id: "0020" }, + { + timestamp: "2019-01-01T06:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + { + timestamp: "2019-01-01T18:00:00Z", + type: "diff", + id: "0003", + parent: "0002", + }, + { + timestamp: "2019-01-01T12:00:00Z", + type: "diff", + id: "0002", + parent: "0001", + }, + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + { + timestamp: "2019-01-03T06:00:00Z", + type: "diff", + id: "0021", + parent: "0020", + }, + ]); + let [status, filters] = result.split(";"); + equal(status, "finished", "CRLite filter download should have run"); + let filtersSplit = filters.split(","); + deepEqual( + filtersSplit, + [ + "2019-01-03T00:00:00Z-full", + "2019-01-03T06:00:00Z-diff", + "2019-01-03T12:00:00Z-diff", + "2019-01-03T18:00:00Z-diff", + ], + "Should have downloaded the expected CRLite filters" + ); +}); + +function getCRLiteEnrollmentRecordFor(nsCert) { + let { subjectString, spkiHashString } = getSubjectAndSPKIHash(nsCert); + return { + subjectDN: btoa(subjectString), + pubKeyHash: spkiHashString, + crlite_enrolled: true, + }; +} + +add_task(async function test_crlite_filters_and_check_revocation() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + Services.prefs.setIntPref( + "security.pki.crlite_mode", + CRLiteModeEnforcePrefValue + ); + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let issuerCert = constructCertFromFile("test_crlite_filters/issuer.pem"); + let noSCTCertIssuer = constructCertFromFile( + "test_crlite_filters/no-sct-issuer.pem" + ); + + let crliteEnrollmentRecords = [ + getCRLiteEnrollmentRecordFor(issuerCert), + getCRLiteEnrollmentRecordFor(noSCTCertIssuer), + ]; + + await IntermediatePreloadsClient.onSync({ + data: { + current: crliteEnrollmentRecords, + created: crliteEnrollmentRecords, + updated: [], + deleted: [], + }, + }); + + let result = await syncAndDownload([ + { timestamp: "2020-10-17T00:00:00Z", type: "full", id: "0000" }, + ]); + equal( + result, + "finished;2020-10-17T00:00:00Z-full", + "CRLite filter download should have run" + ); + + let validCert = constructCertFromFile("test_crlite_filters/valid.pem"); + // NB: by not specifying Ci.nsIX509CertDB.FLAG_LOCAL_ONLY, this tests that + // the implementation does not fall back to OCSP fetching, because if it + // did, the implementation would attempt to connect to a server outside the + // test infrastructure, which would result in a crash in the test + // environment, which would be treated as a test failure. + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "vpn.worldofspeed.org", + 0 + ); + + let revokedCert = constructCertFromFile("test_crlite_filters/revoked.pem"); + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "us-datarecovery.com", + 0 + ); + + // Before any stashes are downloaded, this should verify successfully. + let revokedInStashCert = constructCertFromFile( + "test_crlite_filters/revoked-in-stash.pem" + ); + await checkCertErrorGenericAtTime( + certdb, + revokedInStashCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "stokedmoto.com", + 0 + ); + + result = await syncAndDownload( + [ + { + timestamp: "2020-10-17T03:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + ], + false + ); + equal( + result, + "finished;2020-10-17T03:00:00Z-diff", + "Should have downloaded the expected CRLite filters" + ); + + // After downloading the first stash, this should be revoked. + await checkCertErrorGenericAtTime( + certdb, + revokedInStashCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "stokedmoto.com", + 0 + ); + + // Before downloading the second stash, this should not be revoked. + let revokedInStash2Cert = constructCertFromFile( + "test_crlite_filters/revoked-in-stash-2.pem" + ); + await checkCertErrorGenericAtTime( + certdb, + revokedInStash2Cert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "icsreps.com", + 0 + ); + + result = await syncAndDownload( + [ + { + timestamp: "2020-10-17T06:00:00Z", + type: "diff", + id: "0002", + parent: "0001", + }, + ], + false + ); + equal( + result, + "finished;2020-10-17T06:00:00Z-diff", + "Should have downloaded the expected CRLite filters" + ); + + // After downloading the second stash, this should be revoked. + await checkCertErrorGenericAtTime( + certdb, + revokedInStash2Cert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "icsreps.com", + 0 + ); + + // The other certificates should still get the same results as they did before. + await checkCertErrorGenericAtTime( + certdb, + validCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "vpn.worldofspeed.org", + 0 + ); + + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "us-datarecovery.com", + 0 + ); + + await checkCertErrorGenericAtTime( + certdb, + revokedInStashCert, + SEC_ERROR_REVOKED_CERTIFICATE, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "stokedmoto.com", + 0 + ); + + // This certificate has no embedded SCTs, so it is not guaranteed to be in + // CT, so CRLite can't be guaranteed to give the correct answer, so it is + // not consulted, and the implementation falls back to OCSP. Since the real + // OCSP responder can't be reached, this results in a + // SEC_ERROR_OCSP_SERVER_ERROR. + let noSCTCert = constructCertFromFile("test_crlite_filters/no-sct.pem"); + // NB: this will cause an OCSP request to be sent to localhost:80, but + // since an OCSP responder shouldn't be running on that port, this should + // fail safely. + Services.prefs.setCharPref("network.dns.localDomains", "ocsp.digicert.com"); + Services.prefs.setBoolPref("security.OCSP.require", true); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + await checkCertErrorGenericAtTime( + certdb, + noSCTCert, + SEC_ERROR_OCSP_SERVER_ERROR, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "mail233.messagelabs.com", + 0 + ); + Services.prefs.clearUserPref("network.dns.localDomains"); + Services.prefs.clearUserPref("security.OCSP.require"); + Services.prefs.clearUserPref("security.OCSP.enabled"); + + // If the earliest certificate timestamp is within the merge delay of the + // logs for the filter we have, it won't be looked up, and thus won't be + // revoked. + // The earliest timestamp in this certificate is in August 2020, whereas + // the filter timestamp is in October 2020, so setting the merge delay to + // this large value simluates the situation being tested. + Services.prefs.setIntPref( + "security.pki.crlite_ct_merge_delay_seconds", + 60 * 60 * 24 * 60 + ); + // Since setting the merge delay parameter this way effectively makes this + // certificate "too new" to be covered by the filter, the implementation + // would fall back to OCSP fetching. Since this would result in a crash and + // test failure, the Ci.nsIX509CertDB.FLAG_LOCAL_ONLY is used. + await checkCertErrorGenericAtTime( + certdb, + revokedCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + new Date("2020-10-20T00:00:00Z").getTime() / 1000, + false, + "us-datarecovery.com", + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY + ); + Services.prefs.clearUserPref("security.pki.crlite_ct_merge_delay_seconds"); +}); + +add_task(async function test_crlite_filters_avoid_reprocessing_filters() { + Services.prefs.setBoolPref(CRLITE_FILTERS_ENABLED_PREF, true); + + let result = await syncAndDownload([ + { timestamp: "2019-01-01T00:00:00Z", type: "full", id: "0000" }, + { + timestamp: "2019-01-01T06:00:00Z", + type: "diff", + id: "0001", + parent: "0000", + }, + { + timestamp: "2019-01-01T12:00:00Z", + type: "diff", + id: "0002", + parent: "0001", + }, + { + timestamp: "2019-01-01T18:00:00Z", + type: "diff", + id: "0003", + parent: "0002", + }, + ]); + let [status, filters] = result.split(";"); + equal(status, "finished", "CRLite filter download should have run"); + let filtersSplit = filters.split(","); + deepEqual( + filtersSplit, + [ + "2019-01-01T00:00:00Z-full", + "2019-01-01T06:00:00Z-diff", + "2019-01-01T12:00:00Z-diff", + "2019-01-01T18:00:00Z-diff", + ], + "Should have downloaded the expected CRLite filters" + ); + // This simulates another poll without clearing the database first. The + // filter and stashes should not be re-downloaded. + result = await syncAndDownload([], false); + equal(result, "finished;"); + + // If a new stash is added, only it should be downloaded. + result = await syncAndDownload( + [ + { + timestamp: "2019-01-02T00:00:00Z", + type: "diff", + id: "0004", + parent: "0003", + }, + ], + false + ); + equal(result, "finished;2019-01-02T00:00:00Z-diff"); +}); + +let server; + +function run_test() { + server = new HttpServer(); + server.start(-1); + registerCleanupFunction(() => server.stop(() => {})); + + server.registerDirectory( + "/cdn/security-state-workspace/cert-revocations/", + do_get_file(".") + ); + + server.registerPathHandler("/v1/", (request, response) => { + response.write( + JSON.stringify({ + capabilities: { + attachments: { + base_url: `http://localhost:${server.identity.primaryPort}/cdn/`, + }, + }, + }) + ); + response.setHeader("Content-Type", "application/json; charset=UTF-8"); + response.setStatusLine(null, 200, "OK"); + }); + + Services.prefs.setCharPref( + "services.settings.server", + `http://localhost:${server.identity.primaryPort}/v1` + ); + + // Set intermediate preloading to download 0 intermediates at a time. + Services.prefs.setIntPref(INTERMEDIATES_DL_PER_POLL_PREF, 0); + + Services.prefs.setCharPref("browser.policies.loglevel", "debug"); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/20201017-0-filter b/security/manager/ssl/tests/unit/test_crlite_filters/20201017-0-filter new file mode 100644 index 0000000000..4da0a2ec14 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_crlite_filters/20201017-0-filter differ diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/20201017-1-filter.stash b/security/manager/ssl/tests/unit/test_crlite_filters/20201017-1-filter.stash new file mode 100644 index 0000000000..d43193a78c Binary files /dev/null and b/security/manager/ssl/tests/unit/test_crlite_filters/20201017-1-filter.stash differ diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/20201201-3-filter.stash b/security/manager/ssl/tests/unit/test_crlite_filters/20201201-3-filter.stash new file mode 100644 index 0000000000..52c9ee8d51 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_crlite_filters/20201201-3-filter.stash differ diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/issuer.pem b/security/manager/ssl/tests/unit/test_crlite_filters/issuer.pem new file mode 100644 index 0000000000..ead19e3c14 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/issuer.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIE0DCCA7igAwIBAgIBBzANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMx +EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoT +EUdvRGFkZHkuY29tLCBJbmMuMTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRp +ZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTExMDUwMzA3MDAwMFoXDTMxMDUwMzA3 +MDAwMFowgbQxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQH +EwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UE +CxMkaHR0cDovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQD +EypHbyBEYWRkeSBTZWN1cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC54MsQ1K92vdSTYuswZLiBCGzD +BNliF44v/z5lz4/OYuY8UhzaFkVLVat4a2ODYpDOD2lsmcgaFItMzEUz6ojcnqOv +K/6AYZ15V8TPLvQ/MDxdR/yaFrzDN5ZBUY4RS1T4KL7QjL7wMDge87Am+GZHY23e +cSZHjzhHU9FGHbTj3ADqRay9vHHZqm8A29vNMDp5T19MR/gd71vCxJ1gO7GyQ5HY +pDNO6rPWJ0+tJYqlxvTV0KaudAVkV4i1RFXULSo6Pvi4vekyCgKUZMQWOlDxSq7n +eTOvDCAHf+jfBDnCaQJsY1L6d8EbyHSHyLmTGFBUNUtpTrw700kuH9zB0lL7AgMB +AAGjggEaMIIBFjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNV +HQ4EFgQUQMK9J47MNIMwojPX+2yz8LQsgM4wHwYDVR0jBBgwFoAUOpqFBxBnKLbv +9r0FQW4gwZTaD94wNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8v +b2NzcC5nb2RhZGR5LmNvbS8wNQYDVR0fBC4wLDAqoCigJoYkaHR0cDovL2NybC5n +b2RhZGR5LmNvbS9nZHJvb3QtZzIuY3JsMEYGA1UdIAQ/MD0wOwYEVR0gADAzMDEG +CCsGAQUFBwIBFiVodHRwczovL2NlcnRzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkv +MA0GCSqGSIb3DQEBCwUAA4IBAQAIfmyTEMg4uJapkEv/oV9PBO9sPpyIBslQj6Zz +91cxG7685C/b+LrTW+C05+Z5Yg4MotdqY3MxtfWoSKQ7CC2iXZDXtHwlTxFWMMS2 +RJ17LJ3lXubvDGGqv+QqG+6EnriDfcFDzkSnE3ANkR/0yBOtg2DZ2HKocyQetawi +DsoXiWJYRBuriSUBAA/NxBti21G00w9RKpv0vHP8ds42pM3Z2Czqrpv1KrKQ0U11 +GIo/ikGQI31bS/6kA1ibRrLDYGCD+H1QQc7CoZDDu+8CL9IVVO5EFdkKrqeKM+2x +LXY2JtwE65/3YR8V3Idv7kaWKK2hJn0KCacuBKONvPi8BDAB +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/no-sct-issuer.pem b/security/manager/ssl/tests/unit/test_crlite_filters/no-sct-issuer.pem new file mode 100644 index 0000000000..70b86dfd71 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/no-sct-issuer.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIElDCCA3ygAwIBAgIQAf2j627KdciIQ4tyS8+8kTANBgkqhkiG9w0BAQsFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0xMzAzMDgxMjAwMDBaFw0yMzAzMDgxMjAwMDBaME0xCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxJzAlBgNVBAMTHkRpZ2lDZXJ0IFNIQTIg +U2VjdXJlIFNlcnZlciBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANyuWJBNwcQwFZA1W248ghX1LFy949v/cUP6ZCWA1O4Yok3wZtAKc24RmDYXZK83 +nf36QYSvx6+M/hpzTc8zl5CilodTgyu5pnVILR1WN3vaMTIa16yrBvSqXUu3R0bd +KpPDkC55gIDvEwRqFDu1m5K+wgdlTvza/P96rtxcflUxDOg5B6TXvi/TC2rSsd9f +/ld0Uzs1gN2ujkSYs58O09rg1/RrKatEp0tYhG2SS4HD2nOLEpdIkARFdRrdNzGX +kujNVA075ME/OV4uuPNcfhCOhkEAjUVmR7ChZc6gqikJTvOX6+guqw9ypzAO+sf0 +/RR3w6RbKFfCs/mC/bdFWJsCAwEAAaOCAVowggFWMBIGA1UdEwEB/wQIMAYBAf8C +AQAwDgYDVR0PAQH/BAQDAgGGMDQGCCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYY +aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMHsGA1UdHwR0MHIwN6A1oDOGMWh0dHA6 +Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RDQS5jcmwwN6A1 +oDOGMWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RD +QS5jcmwwPQYDVR0gBDYwNDAyBgRVHSAAMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8v +d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHQYDVR0OBBYEFA+AYRyCMWHVLyjnjUY4tCzh +xtniMB8GA1UdIwQYMBaAFAPeUDVW0Uy7ZvCj4hsbw5eyPdFVMA0GCSqGSIb3DQEB +CwUAA4IBAQAjPt9L0jFCpbZ+QlwaRMxp0Wi0XUvgBCFsS+JtzLHgl4+mUwnNqipl +5TlPHoOlblyYoiQm5vuh7ZPHLgLGTUq/sELfeNqzqPlt/yGFUzZgTHbO7Djc1lGA +8MXW5dRNJ2Srm8c+cftIl7gzbckTB+6WohsYFfZcTEDts8Ls/3HB40f/1LkAtDdC +2iDJ6m6K7hQGrn2iWZiIqBtvLfTyyRRfJs8sjX7tN8Cp1Tm5gr8ZDOo0rwAhaPit +c+LJMto4JQtV05od8GiG7S5BNO98pVAdvzr508EIDObtHopYJeS4d60tbvVS3bR0 +j6tJLp07kzQoH3jOlOrHvdPJbRzeXDLz +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/no-sct.pem b/security/manager/ssl/tests/unit/test_crlite_filters/no-sct.pem new file mode 100644 index 0000000000..a690a0ad0d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/no-sct.pem @@ -0,0 +1,33 @@ +-----BEGIN CERTIFICATE----- +MIIFpDCCBIygAwIBAgIQDVHBpbd6yyk2LgPoPr9QyjANBgkqhkiG9w0BAQsFADBN +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMScwJQYDVQQDEx5E +aWdpQ2VydCBTSEEyIFNlY3VyZSBTZXJ2ZXIgQ0EwHhcNMTkxMTE4MDAwMDAwWhcN +MjExMTE4MTIwMDAwWjCBlDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3Ju +aWExFjAUBgNVBAcTDU1vdW50YWluIFZpZXcxHTAbBgNVBAoTFFN5bWFudGVjIENv +cnBvcmF0aW9uMRcwFQYDVQQLEw5TeW1hbnRlYy5jbG91ZDEgMB4GA1UEAxMXbWFp +bDIzMy5tZXNzYWdlbGFicy5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQCyM1Fy9hAlahRqqeEnPKDWgUmsxofivWEWKNeSMEKcnXX3TCQOGbLQTthN +xfNU7IWY8ViTPwQ8JBWWDxNhd6dTYLNnytKrNRG8qDQ3rFMKJY4p0dZImMp55X3W +1xcKMxSOkPv0YUCGp7qlAHq6+N3YY1ILw6MRdJ75Njh4Kw8qe5F3rHLwD+AyYQmx +3WsMCRp5NZtWUcU5Vbc9ca/osrh9xBF7U3ZYR6GoPXQlizrNjXv7/BaKWWO5ChbD +iRI4Nj8d3HhWUHsJoGvYDof5Iudgtbubz3c5cwp6+VNNMas7izpvbixqW8zXdUug +8v5v47IkRNYnlma/zvv2IDC1dVlxAgMBAAGjggI2MIICMjAfBgNVHSMEGDAWgBQP +gGEcgjFh1S8o541GOLQs4cbZ4jAdBgNVHQ4EFgQUZnBdWwGQjkPX/+A2ZEYdUdnw +lN8wfQYDVR0RBHYwdIIbY2x1c3RlcjguZXUubWVzc2FnZWxhYnMuY29tgh5jbHVz +dGVyOG91dC5ldS5tZXNzYWdlbGFicy5jb22CHGNsdXN0ZXI4YS5ldS5tZXNzYWdl +bGFicy5jb22CF21haWwyMzMubWVzc2FnZWxhYnMuY29tMA4GA1UdDwEB/wQEAwIF +oDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwawYDVR0fBGQwYjAvoC2g +K4YpaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NzY2Etc2hhMi1nNi5jcmwwL6At +oCuGKWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zc2NhLXNoYTItZzYuY3JsMEwG +A1UdIARFMEMwNwYJYIZIAYb9bAEBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3 +LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQICMHwGCCsGAQUFBwEBBHAwbjAkBggr +BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEYGCCsGAQUFBzAChjpo +dHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyU2VjdXJlU2Vy +dmVyQ0EuY3J0MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggEBAK7vS/qDcGKb +QYu26+jGtBemopT3+2YJjtALeR62eNhF9LoHu+mnmNLvPI0M0NMhz56Ss/6sUHOz +hJgB98SLAQ5ElSWXrnZThLIjsiH5X5MYTD0Y8MqzoJSi2Lf2Muy/UpyrD3wB14E1 +kUYhvUnaWDDPIN81DCFzEosBmnsRqr5zlcZSKs0e1LVQ8cNkt8svVkiwFgeOIhwo +QF22GJAZPtRceSGlbRTFBYKh+u3KN8eNS/X+C935y+F4J/grufDCzRSGtRRseTcd +1QW49+QME/rx1mBb7id4iXNKxvGuJTivBlxaHWBQLh/RGk39DSdHfjAhYvt2gmxh +C3gxXMNrymE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash-2.pem b/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash-2.pem new file mode 100644 index 0000000000..9550453493 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash-2.pem @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGNTCCBR2gAwIBAgIIFn0oGKdatdgwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow +GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz +LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1 +cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMjAwOTI3MTE0MzI0WhcN +MjExMDI5MTE0MzI0WjA5MSEwHwYDVQQLExhEb21haW4gQ29udHJvbCBWYWxpZGF0 +ZWQxFDASBgNVBAMTC2ljc3JlcHMuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAydMKPhCqRWjy5h1aPUNdRb80kt0hP/g55ytjlSF04PG+1CbIcId1 +GJg1qkbTR1vqZyvaI8wjv3zdfvsvYbka9OQFJiOasJfeqmiA+sDd9AvFiD2EF5zN +D9uKHi+sF8Ut4JMl7jqaRAu/gbjBvY/9ammkz4sUiTlp1x4rteda3tuX9O7yMO7U +ldnyfabHgGmmm8KU3nvRAjNbHCq3J/V/zw8YeolXU5OpOeZMhI8KAGKpxk8tRiIb +LkdSdCTWoKgXO60extYcGTxIT8c8zfY6OoN0VaQY8HA1VyBZQIw2RTWivmI8le0J +ypXYxNcUtInS0ivO4ymiNnCjYR9pgQ6+tQIDAQABo4ICwzCCAr8wDAYDVR0TAQH/ +BAIwADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQD +AgWgMDgGA1UdHwQxMC8wLaAroCmGJ2h0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Rp +ZzJzMS0yMzM0LmNybDBdBgNVHSAEVjBUMEgGC2CGSAGG/W0BBxcBMDkwNwYIKwYB +BQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3NpdG9y +eS8wCAYGZ4EMAQIBMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDov +L29jc3AuZ29kYWRkeS5jb20vMEAGCCsGAQUFBzAChjRodHRwOi8vY2VydGlmaWNh +dGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RpZzIuY3J0MB8GA1UdIwQYMBaA +FEDCvSeOzDSDMKIz1/tss/C0LIDOMCcGA1UdEQQgMB6CC2ljc3JlcHMuY29tgg93 +d3cuaWNzcmVwcy5jb20wHQYDVR0OBBYEFEgqFQnM5zH3cKFGtFanJxxD9zdPMIIB +BAYKKwYBBAHWeQIEAgSB9QSB8gDwAHUA9lyUL9F3MCIUVBgIMJRWjuNNExkzv98M +LyALzE7xZOMAAAF0z1/40gAABAMARjBEAiADSOnqg/I15y+dJDSWta8NzBwE6Xti +UzyBKMT2OYHCYwIgb1aFpZxlkhx6XCCuniBLTcr5JbhigoM/lAfUmvvUqrIAdwBc +3EOS/uarRUSxXprUVuYQN/vV+kfcoXOUsl7m9scOygAAAXTPX/oBAAAEAwBIMEYC +IQD6WvavTba+Lydf6uhaaxcRmhuuPeddzSmC8t4+tBLGGgIhANJPxhRl1pGYm6WX +ay9jPCM2SqtBraOJYncaV6k37zGYMA0GCSqGSIb3DQEBCwUAA4IBAQA0IknIoU51 +FCBqpksgo7zR9OJj5MoQmlsQbzSFppdRKgyHhk8rW6IrBi3yrtWjo3HxcwihZlJQ +2AbinRTNnHvBpiiiXXxR5u9yVly+9l3KfF/uHIGMnIqsahaKXNOy5h98uq4o4N0+ +YCGu9wSeDwtaCzdT+V447Fq63nmW629pjwin8FYCz2S8RdztranPZuOgwYqBNlWu +u3Mi9DWIV2hP6eFwMZh7BWgbvnhWiI37TE74YQ+3cEVaLxLHJH9jkBjsel+ZwVIo +9xeE6kGsh5+D0uHS5NWf9zu+fvW0iTgsB8J4VX5OihAa1v4FS4IaF3snkaMa0PCd +MJMOgY5VkZiw +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash.pem b/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash.pem new file mode 100644 index 0000000000..1073159662 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/revoked-in-stash.pem @@ -0,0 +1,36 @@ +-----BEGIN CERTIFICATE----- +MIIGPTCCBSWgAwIBAgIJAJeW47AXop8NMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEa +MBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0 +cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2Vj +dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTIwMDgyMjIzMDI0NVoX +DTIxMDkyMTIxMTYxMVowPDEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRh +dGVkMRcwFQYDVQQDEw5zdG9rZWRtb3RvLmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBANLX8D4Cin6x2bmoSdgnuw9O+tGcD1x1S++3110NJVXUlpSc +3uSUwqpU4rMOkJlRnuaBtHXYUFG8NMMnbTJYY9JuuhAlnHzVqoRWmcTNRp72fpDA +XoD3U20spJeGQZXuQnGfe/k9EouvXt5du029YqItkFbjdbub4FP5MbIz1CWeelEn +fEwpe/peLVYEfKSyYf325tFI9wZhuIM/zTe9DE6lauznM8hg1ioiBujxzeWWSstZ +K2uJKaI8nlWkSr6vwPqJEBvvoShcWHFEmG8SWqPBy1tsNsLNjJkaHfD7gvG/J1Rc +G21D0XO2IA0rEo6lo8MNEkWoHZA/oHO1eHrCjNkCAwEAAaOCAscwggLDMAwGA1Ud +EwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4GA1UdDwEB +/wQEAwIFoDA4BgNVHR8EMTAvMC2gK6AphidodHRwOi8vY3JsLmdvZGFkZHkuY29t +L2dkaWcyczEtMjIzNy5jcmwwXQYDVR0gBFYwVDBIBgtghkgBhv1tAQcXATA5MDcG +CCsGAQUFBwIBFitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9z +aXRvcnkvMAgGBmeBDAECATB2BggrBgEFBQcBAQRqMGgwJAYIKwYBBQUHMAGGGGh0 +dHA6Ly9vY3NwLmdvZGFkZHkuY29tLzBABggrBgEFBQcwAoY0aHR0cDovL2NlcnRp +ZmljYXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5L2dkaWcyLmNydDAfBgNVHSME +GDAWgBRAwr0njsw0gzCiM9f7bLPwtCyAzjAtBgNVHREEJjAkgg5zdG9rZWRtb3Rv +LmNvbYISd3d3LnN0b2tlZG1vdG8uY29tMB0GA1UdDgQWBBTP8YI0WwVBgvg5GABQ +fUksbk6evjCCAQIGCisGAQQB1nkCBAIEgfMEgfAA7gB1APZclC/RdzAiFFQYCDCU +Vo7jTRMZM7/fDC8gC8xO8WTjAAABdBhpJtAAAAQDAEYwRAIgcrebTXyuMk/ciVyg +LMbbd6qbkyB3yRAY1QnBs5sGK1ICIGw6EpH/NMXcOfYdkuSmhSYgUx0AIDdT9QWH +rRIT50D3AHUAXNxDkv7mq0VEsV6a1FbmEDf71fpH3KFzlLJe5vbHDsoAAAF0GGko +AwAABAMARjBEAiBtzQQHVVML3yZhZRsLLhJkYcc11nXeU/S/rouOZCCZQQIgVYKY +jgjCU5HQyY6R5PZQTsCQGWiaOm1VguAIgPbvKzYwDQYJKoZIhvcNAQELBQADggEB +AH6jCZU9+5TMaR5XThGL/z8EYQ1uFVN0hlXXB+gP3IDQLmyxkqrk9cOSf1D6fLRT +5T4tGzPLvmReBLfrzQEkuqkXpUieortbpi116V82K+zBDT5s9Dol6+MxhwIZyZ7K +DkHSbcFyiV9hkr2bf8JZzjvpCOfw9kYZTcYv8M8kheIOQsONdfe/rqNQnMRy56UZ +OGZmxqDT2RwbewHEMAEb5ZsZ55/UHq08vZSVSA8qIqX/BU+7frwwt4vmv4WQ7AoJ +YNml0TdV4R27NlnvhbAclucuqEMBcBg8gNylvKD3Mid7O4c5gCX5Wuml6rLpOr05 +vpJJqSf0uy73EtNcyTqfwUQ= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/revoked.pem b/security/manager/ssl/tests/unit/test_crlite_filters/revoked.pem new file mode 100644 index 0000000000..ece7360def --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/revoked.pem @@ -0,0 +1,42 @@ +-----BEGIN CERTIFICATE----- +MIIHTjCCBjagAwIBAgIILTXKZQP7G6MwDQYJKoZIhvcNAQELBQAwgbQxCzAJBgNV +BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRow +GAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjEtMCsGA1UECxMkaHR0cDovL2NlcnRz +LmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMTMwMQYDVQQDEypHbyBEYWRkeSBTZWN1 +cmUgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IC0gRzIwHhcNMjAwODIyMjM0ODE1WhcN +MjEwMTE0MjEwMzAxWjBDMSEwHwYDVQQLExhEb21haW4gQ29udHJvbCBWYWxpZGF0 +ZWQxHjAcBgNVBAMMFSoudXMtZGF0YXJlY292ZXJ5LmNvbTCCAiIwDQYJKoZIhvcN +AQEBBQADggIPADCCAgoCggIBAKzuSr8LaH2Aw/G1aKN4URo0RwaFv4+7MzM0RVTB +189BdE8rgNRfxskoAVfte+iftO7P5qjg+1Jx8SCE1ZCNT2TGtcYwlsjyNLnbP3xV +Cq514bODlwimOKLhpUFH1/ofO4/enbU8E4hlxS4DPtOGbsjouTiRHAOLsi7D+WT3 +3pZelFa5Hgmed5dL/CCJTiwbF10lbTXNwLgI7efUqiwvHRwf/CXEW9IvKJ9HG2We +tT9ouQGOHfz4fyGOMN268dHqP89K+auCcf9b3BzzWOsknhmDisl+06WaIJe/W7Dn ++eG07nAuJLhE6nH9KLYiU2X5CHnLPvBTOPDdm/hzH84hnHkX2pSbst4d1aNtU4uP +hyQcE5aMfnV7Yr1ZQUlLreCKzwIAb6BKqF/gHMASXUX7Fw5OFUHxV1xcPbcHQLs6 +D3XAoLBzopTR4YjxIDqhS3pkxHu5u9OEzFfaeP5zYnrj69Bke3lrdbrKV8aXIxHn +xh9xJV4zAaPoHe8ze03zvdBXfu69DU+TTQkRfzJSZx/sXV6BHe15WGSHZxe0i61z +wA1Oi7QgySMKIKSs6dsPOqppmePc3seMJy7y0FSxF1Kq6a1tR+W3j2WT9nY1c4Wb +4LWc+0gDK3nvibJbFqCfnPznq/Q+q0V6m9BqBNjvqyyWXbgzCVn7qcT4apiP47IV ++MiBAgMBAAGjggLSMIICzjAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUF +BwMBBggrBgEFBQcDAjAOBgNVHQ8BAf8EBAMCBaAwOAYDVR0fBDEwLzAtoCugKYYn +aHR0cDovL2NybC5nb2RhZGR5LmNvbS9nZGlnMnMxLTIyMzcuY3JsMF0GA1UdIARW +MFQwSAYLYIZIAYb9bQEHFwEwOTA3BggrBgEFBQcCARYraHR0cDovL2NlcnRpZmlj +YXRlcy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzAIBgZngQwBAgEwdgYIKwYBBQUH +AQEEajBoMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5nb2RhZGR5LmNvbS8wQAYI +KwYBBQUHMAKGNGh0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20vcmVwb3Np +dG9yeS9nZGlnMi5jcnQwHwYDVR0jBBgwFoAUQMK9J47MNIMwojPX+2yz8LQsgM4w +NQYDVR0RBC4wLIIVKi51cy1kYXRhcmVjb3ZlcnkuY29tghN1cy1kYXRhcmVjb3Zl +cnkuY29tMB0GA1UdDgQWBBTooRcQfblnnD7pJFCZfGGcf4kD4jCCAQUGCisGAQQB +1nkCBAIEgfYEgfMA8QB3APZclC/RdzAiFFQYCDCUVo7jTRMZM7/fDC8gC8xO8WTj +AAABdBiSoGUAAAQDAEgwRgIhAI4Cd+FhKsWdUZkBugaburD9dzdlVHSxKq6oYNyI +vmIIAiEAwlmkvAiPb9nwDirqe7MZud5nu/lmq/Ip7M1xSKuraykAdgBc3EOS/uar +RUSxXprUVuYQN/vV+kfcoXOUsl7m9scOygAAAXQYkqGUAAAEAwBHMEUCIQCpYqq+ +Uc881tR+ikvsR97FRl6jBfxG50Sum+cdHEQkYQIgZJbGaeNoDS9+LAKI88NNRiCK +vtQZkwWigDYr+2dWguYwDQYJKoZIhvcNAQELBQADggEBAD+sj44+86AvdVUrAN9h +cU6kt4I6K1TM0KBmKg3rG8JEY7+Ec4Rztls3uviLR0ajH5tkQPwD7vRBVrLVDtQS +Ndt2StR38AXiBRWwewy/sPMz11YzOPLyHaTl4pJVfyzHJ+rPdWuFZLtpTras/MIK +IFnnbInlh5XtRhDCv6UEkAmGu5BeftA+9XxTuZlbwQlO5U1yg9Hqor9zANMqX9Ad +3omIZrPtBkTdVOwHRU8SoaS6XxQ9jxcmWRgNTVAhU1/J7Bgvg3CPSpcHyV78sXkS +D9bb1f4jdadaMKuJc0mTHBAxZenr3IFV8upf2FRTJnrCiS0jX8kKobN/+04Gbev6 +Tr0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_crlite_filters/valid.pem b/security/manager/ssl/tests/unit/test_crlite_filters/valid.pem new file mode 100644 index 0000000000..6769ba3d37 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_crlite_filters/valid.pem @@ -0,0 +1,39 @@ +-----BEGIN CERTIFICATE----- +MIIGyTCCBbGgAwIBAgIJANpPOSv9i86oMA0GCSqGSIb3DQEBCwUAMIG0MQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHQXJpem9uYTETMBEGA1UEBxMKU2NvdHRzZGFsZTEa +MBgGA1UEChMRR29EYWRkeS5jb20sIEluYy4xLTArBgNVBAsTJGh0dHA6Ly9jZXJ0 +cy5nb2RhZGR5LmNvbS9yZXBvc2l0b3J5LzEzMDEGA1UEAxMqR28gRGFkZHkgU2Vj +dXJlIENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTE4MTAxNTE5NTQxNFoX +DTIwMTAyNDE4MzczOFowQjEhMB8GA1UECxMYRG9tYWluIENvbnRyb2wgVmFsaWRh +dGVkMR0wGwYDVQQDExR2cG4ud29ybGRvZnNwZWVkLm9yZzCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBAKb1cjhtYv6yiyZa1feabWaSBOCmN0JuqXIMkX3r +4g+5heKAwPFlPFbZ3vZ3DQXiliV7jb5nhlx0O6nYG+MoGFmj6hEHDptCASAfdd3j +4tCxg0FlilXgrgMkJCg+SjW0npZ86jMkfc0WzufUyMjxv2pUUicPNXyWbaQr+PCq +zs6AsOkmuQ8RUUAqZ+Q0EJfQnjuhql7NCdByNui9S2LmrPcV6TAHHeTwKX733edv +zsNzaLNgE6TLGXSSRvsW/eZ/uNScPHLybE4wdxxCDwSYCPwaQq34csc3a8SUTWfS +4UkdbOn7j5sZPx7Jj0uUlm20ZDsj2FUi/0SXNvz5flFQbVsCAwEAAaOCA00wggNJ +MAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA4G +A1UdDwEB/wQEAwIFoDA3BgNVHR8EMDAuMCygKqAohiZodHRwOi8vY3JsLmdvZGFk +ZHkuY29tL2dkaWcyczEtODc4LmNybDBdBgNVHSAEVjBUMEgGC2CGSAGG/W0BBxcB +MDkwNwYIKwYBBQUHAgEWK2h0dHA6Ly9jZXJ0aWZpY2F0ZXMuZ29kYWRkeS5jb20v +cmVwb3NpdG9yeS8wCAYGZ4EMAQIBMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcw +AYYYaHR0cDovL29jc3AuZ29kYWRkeS5jb20vMEAGCCsGAQUFBzAChjRodHRwOi8v +Y2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvZ2RpZzIuY3J0MB8G +A1UdIwQYMBaAFEDCvSeOzDSDMKIz1/tss/C0LIDOMDkGA1UdEQQyMDCCFHZwbi53 +b3JsZG9mc3BlZWQub3Jnghh3d3cudnBuLndvcmxkb2ZzcGVlZC5vcmcwHQYDVR0O +BBYEFGjmOgodY5yPX19UPVcACFpVExz1MIIBfQYKKwYBBAHWeQIEAgSCAW0EggFp +AWcAdgCkuQmQtBhYFIe7E6LMZ3AKPDWYBPkb37jjd80OyA3cEAAAAWZ5SxEeAAAE +AwBHMEUCIEL5OLHwBpIALbEnLFQntFlGBe8Oko6U/arr15jU4sLDAiEA6uy8DEnh +PFLOxXDC3ZaeOlK2+cdx76IAr6M6As74ETEAdgDuS723dc5guuFCaR+r4Z5mow9+ +X7By2IMAxHuJeqj9ywAAAWZ5SxMzAAAEAwBHMEUCIFWIeePa6jdf6y9o/YYxoqWr +Je3j8W94e4f5bixaGPiyAiEA7aJRZI+aWCE/zz5DpvcyRgkIoSKS3+dKS2irf/mp +qx0AdQBep3P531bA57U2SH3QSeAyepGaDIShEhKEGHWWgXFFWAAAAWZ5SxPjAAAE +AwBGMEQCIEkYw6g/cIZBdOUh+ETwl2XX2S0Bv8iGGiaOKOoXqVK6AiAh3eqABfMc +9b/wLJZo186YgbzmbZB0N3y5TUJKK1oMYDANBgkqhkiG9w0BAQsFAAOCAQEAPEwx +d597oqiP9/TN8RDrZqhn4uLZ9K5mXOD93RorUN8T8O1kV0B4UcXM1CkU2zxv4a9S +tG3diHjmfJgcrhpa4i19sZD7+QpTU8j0e82JlsB3MpbtuaiBwqb979c5qNPixQlJ +kDs4DWf8kV+4B9/DWWLDKvs+FtL8ST8n+LfwstZqi2EyK+1ZyM0p9hkUAzrT/M2h +Ou1DYELbCt2HaKMHMPSlrkESG7Q9v9Ba23EXElG+oFXxgnPwk4n84rYG8lI8pPyA +clunJNqc2cISUTDMdgGctCFdSVGyEq+8VVG5Y6Od5LMwtOLKcv+VPi17+iGfxNt/ ++dAMbzGIlDuJELwn0g== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ct.js b/security/manager/ssl/tests/unit/test_ct.js new file mode 100644 index 0000000000..59db48f858 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct.js @@ -0,0 +1,75 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function expectCT(value) { + return securityInfo => { + Assert.equal( + securityInfo.certificateTransparencyStatus, + value, + "actual and expected CT status should match" + ); + }; +} + +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.pki.certificate_transparency.mode"); + let cert = constructCertFromFile("test_ct/ct-valid.example.com.pem"); + setCertTrust(cert, ",,"); +}); + +function run_test() { + Services.prefs.setIntPref("security.pki.certificate_transparency.mode", 1); + add_tls_server_setup("BadCertAndPinningServer", "test_ct"); + // These certificates have a validity period of 800 days, which is a little + // over 2 years and 2 months. This gets rounded down to 2 years (since it's + // less than 2 years and 3 months). Our policy requires N + 1 embedded SCTs, + // where N is 2 in this case. So, a policy-compliant certificate would have at + // least 3 SCTs. + add_connection_test( + "ct-valid.example.com", + PRErrorCodeSuccess, + null, + expectCT( + Ci.nsITransportSecurityInfo.CERTIFICATE_TRANSPARENCY_POLICY_COMPLIANT + ) + ); + // This certificate has only 2 embedded SCTs, and so is not policy-compliant. + add_connection_test( + "ct-insufficient-scts.example.com", + PRErrorCodeSuccess, + null, + expectCT( + Ci.nsITransportSecurityInfo + .CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS + ) + ); + + // Test that if an end-entity is marked as a trust anchor, CT verification + // returns a "not enough SCTs" result. + add_test(() => { + let cert = constructCertFromFile("test_ct/ct-valid.example.com.pem"); + setCertTrust(cert, "CTu,,"); + clearSessionCache(); + run_next_test(); + }); + add_connection_test( + "ct-valid.example.com", + PRErrorCodeSuccess, + null, + expectCT( + Ci.nsITransportSecurityInfo + .CERTIFICATE_TRANSPARENCY_POLICY_NOT_ENOUGH_SCTS + ) + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem b/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem new file mode 100644 index 0000000000..c015087e85 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIEsjCCA5qgAwIBAgIUD7pA2hQ6aiqRWzwjIb6zStU4wxMwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjArMSkwJwYDVQQDDCBjdC1pbnN1ZmZpY2llbnQtc2N0cy5leGFt +cGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaOCAeEwggHdMBgGA1UdEQQRMA+CDSouZXhhbXBsZS5jb20w +ggG/BgorBgEEAdZ5AgQCBIIBrwSCAasBqQB2ACq4MEQzuRTe0vMeQgfyUcF6N6CS +aFLZCAIG+F5XORYqAAABUfp73AAAAAQDAEcwRQIgXHVRnxMRUM1dit4go7wGMJH/ +snN1XzFk7P3LQoAKcOYCIQD0nA7JqwaCdhzWfXxdSrCk6FesmzZ8JJ9CHVN7JqEr +JAEvADEI9rbdchgH8BaVhE2FAla2cZNgg9u9OTSgUFJQGiiSAAABUfp73AAAAAQB +AQAJQ/auHYB8PHgYp6ApXGqdIPM6hRnYlX292tOXymT3atbxcBbrwCaW01Y3mU7F +ndLHBxnfcUdGK314D/GF+8Ez5k+/kWsKYkxH+pVFLcHuyJ6bVREfRkqEgwrenDlz +3NvxXGXUoWgYKfT9fWoMJui1IuRIbDjci0qBq+vT6GhcNJHdXHm41Yze+NjmsmKx +5XEwSQIqg/NeUwuDrsPU9LOcjZ3OVEAH1aVWY8cy5EhVA+Zojk9mTXVE/iuBCp/n +90V9dXyK+E7+ougZ+jnhrlcPCmULgW/Q8LNtRtR0KKexWMom2PSjs1GmbU/l8Wm3 +sv7vmhihg5SQsitmM4CHjxWtMA0GCSqGSIb3DQEBCwUAA4IBAQAeXJGA3UeqCgu4 +VXi8ZvPAmz2BXIfEiwtOXwvuvK1u0SsuwkLoSkKwk2Qr5/p69qn8mpQQmd5zSQ2v +sAAviWu0rl4ugfQr8DOHX1DUF0o82xNMhR/xvz4cpNr3SPrVJOgFqf2oKquo7dzI +kE5vYqACL9w/pRht2EUTJ1eWwNDoz9FCY9zmsvFAiCc2WLWWomKW0VmhxJ+8zLCO +Yk3PBHhipjjGobt6UcG4/QViwKZlRIUKyDMHJ16NhXmicmKWz7LVfkN1XtOpOPGh +v7AX58qHA4ZjBg3AOzfvew+pDdnrAIgrUqcatMqu31xieJVLHDGsg2c5ID3xPx+P +AHOmzcCa +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem.certspec b/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem.certspec new file mode 100644 index 0000000000..c40f26d5d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/ct-insufficient-scts.example.com.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:ct-insufficient-scts.example.com +extension:subjectAlternativeName:*.example.com +extension:embeddedSCTList:secp256r1:20160101,alternate:20160101 diff --git a/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem b/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem new file mode 100644 index 0000000000..f7c6ab8b0d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem @@ -0,0 +1,34 @@ +-----BEGIN CERTIFICATE----- +MIIF1zCCBL+gAwIBAgIUF5bjHB2T8yqxNGQJmDc0Cm6FVTYwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAfMR0wGwYDVQQDDBRjdC12YWxpZC5leGFtcGxlLmNvbTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaOCAxIwggMOMBgGA1UdEQQRMA+CDSouZXhhbXBsZS5jb20wggLwBgorBgEEAdZ5 +AgQCBIIC4ASCAtwC2gEvAFQiJZjzPTZIBULa7ODmuU3hXA7ujFkUykjXXjxIToA/ +AAABUfp73AAAAAQBAQANJRHiZJgVmreqeqGKEvgLaZbuVZyz5Vp1IfzawYVV2J5/ +mbvIxX9yQcJVQhHHdWgyc2WzYvgQTQ8XwUg12Xx2za7c8y0YvEbVfb0bPVDXRvWY +r8YaKgJJuAJO1SqR9lB8iDEz/6BahLGfM9C8ypXoCTtpQ14oV/qSsFzJhys9jlLI +p6AjXgNSqv/NVVMnvTWJ5AOzhIdJJQmVNZM0NXdDZmqlC4Wk8r8rJKYzGswm6CkC +JJ7+WCzuM0ufP5JyLGOp8AsEJvURajm19v09uifDieYysAlBAukPCur3ni8SIxS6 +12iFjawXIeQMkobGanZyKMFYsfeFnQCUBi6Kr1a4AHYAKrgwRDO5FN7S8x5CB/JR +wXo3oJJoUtkIAgb4Xlc5FioAAAFR+nvcAAAABAMARzBFAiBcdVGfExFQzV2K3iCj +vAYwkf+yc3VfMWTs/ctCgApw5gIhAJGsOl/pvErK6FvgTc4TNRBDdX2x37AhywuA +NtqY3PZhAS8AMQj2tt1yGAfwFpWETYUCVrZxk2CD2705NKBQUlAaKJIAAAFR+nvc +AAAABAEBAIAsvMMHiK9UjMgfOjdtLP2bJwLxQ6qHHgJ6IooQgq95gvXpZmhDhSrB +WzHtjSf0G8NrIYQLfGNqeUFjVq7Yby8FkOMrE/VbQrvSHOADJ65hqPesNfRLjWuD +1u9IjlTZFyIxZcrN2OqjWnBfsAylivHAHGj/1vbZqvOKWmQbBpuNW2P5p35uArEX +r5jhBxfM0HO07UgDJzt8oG3fK+iDV/wv3R6Y4LvO+SebnHiXg9HygwG0wi8bGMYK +2wXNUsQ3tdBq4WeJr9cxoH8Ke9l+sLUc9wZ1N7lV7p7hmZeN+nSt6aJny/DfCLoo +rG62y/At1y4l0FmXXvPftkv1QunvWj0wDQYJKoZIhvcNAQELBQADggEBAEFe0sch +6JG7g3uiNpomqOqNaBHnoe5qsYONRTRajDRl8/qyn9NwkMEks0bR6xwBQmBOpN5X ++0TLa43nv28V7B66Mfnpv9ISKdhOytQYN39us0LMBEP8dR/YK5Ux2JH/+iI6IHl0 +syErYIki6Wuz6NxVKAaQN7iB+Qw+pCSJLkbRojXCqSKUwP1uBrhMW1Oe3N2o/eZr +ZpS9IWYtBeb3zPKlMIQHLEUxOBq6SvrNrxcylNKPBXHWTfvFvZYVgLmqzIyti1mw +yC1fr2sMriB6cFd/7i+Mnh4vK31yH/c1KwxDnpOUCEToryH6z+1ydWxyoLgnO6Za +Vx9PmW79Rj2mSFM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem.certspec b/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem.certspec new file mode 100644 index 0000000000..0ecf46d89c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/ct-valid.example.com.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:ct-valid.example.com +extension:subjectAlternativeName:*.example.com +extension:embeddedSCTList:default:20160101,secp256r1:20160101,alternate:20160101 diff --git a/security/manager/ssl/tests/unit/test_ct/default-ee.key b/security/manager/ssl/tests/unit/test_ct/default-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_ct/default-ee.key.keyspec b/security/manager/ssl/tests/unit/test_ct/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_ct/default-ee.pem b/security/manager/ssl/tests/unit/test_ct/default-ee.pem new file mode 100644 index 0000000000..c85c051004 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/default-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUUwG2e1zCLPYPQc2aSZ4UsI/GiK0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcow +gccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tghUqLnBp +bm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu +ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCbcbjTQmzRu++LJ/R1KjA99THZ +aRGG7u0knPs40bz+rIOAR7SllYTvZ1g5HanNG3GZ5+DExVmVtixcrqJFTV0BJsi0 +rv8XR4F3Cdict+rJ+hCSBqu6BGNWdptsaSPiSm+eL//tgjGY1zm9ln1B/OvTYA/n +f+OV07v44pwRBUe8C9Awb2J3KMHATPciKTk0Pwmh0jXi4FN9ehG1rXZMY2daHoKq +hzbBc8EaGzPPAyFumHd6wNqWX+/chEtT00SlcJw/lbQZnK8XvUSOhRuUeRdCM5wX +3w+Gy4P/FrI5tePoR9606GR6plC8QZxT3+Z6lTyCHz3I05+PNXwfmZH3ABSg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ct/default-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ct/default-ee.pem.certspec new file mode 100644 index 0000000000..554339ff52 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/default-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test End-entity +extension:subjectAlternativeName:localhost,*.example.com,*.pinning.example.com,*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/test_ct/moz.build b/security/manager/ssl/tests/unit/test_ct/moz.build new file mode 100644 index 0000000000..d0fc04f747 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/moz.build @@ -0,0 +1,23 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ct-valid.example.com.pem', +# 'ct-insufficient-scts.example.com.pem', +# 'default-ee.pem', +# 'test-ca.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'default-ee.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_ct/test-ca.pem b/security/manager/ssl/tests/unit/test_ct/test-ca.pem new file mode 100644 index 0000000000..40515addbd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0zCCAbugAwIBAgIUZekW+kmMLmUyacMUQAExM6vEFpswDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjASMRAwDgYDVQQDDAdUZXN0IENBMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAoabyPFisrr0c +kmPrDCY8pyDZ6ScxE/ziG+5RG4yJzW0QLrnt6rusMdKuxwaLiTISsNI14vh9QQyG +XQsVeiGNGIwyJ9k2ZbLvw6pjdUeaswkthSqUDYwYgCljBwViuFkK4SAwya0Vb0p8 +pErDX8pzSF78inMB/7f0+DPdEQgtAGPYfB0gMRWOliyJSVoJXTgJ2B6PTMMvIcIO +OXcqjDvVYY4o9+YtsDfmzGOSa/YmbM4hO6lv/cO3zv3aT+szyQK8X44koSkvct2P +QL4cY3/incY0l0I12PaScOJDuvITiRNca7gxbUiT2jz1eqzGPIyVS6ku2cO0v9tP +TIiD5XDdFg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ct/test-ca.pem.certspec b/security/manager/ssl/tests/unit/test_ct/test-ca.pem.certspec new file mode 100644 index 0000000000..5d2435d7bb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ct/test-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test CA +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_db_format_pref_new.js b/security/manager/ssl/tests/unit/test_db_format_pref_new.js new file mode 100644 index 0000000000..b242ad0832 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_db_format_pref_new.js @@ -0,0 +1,22 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Tests that when PSM initializes, we create the sqlite-backed certificate and +// key databases. + +function run_test() { + let profileDir = do_get_profile(); + let certificateDBFile = profileDir.clone(); + certificateDBFile.append("cert9.db"); + ok(!certificateDBFile.exists(), "cert9.db should not exist beforehand"); + let keyDBFile = profileDir.clone(); + keyDBFile.append("key4.db"); + ok(!keyDBFile.exists(), "key4.db should not exist beforehand"); + // This should start PSM. + Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); + ok(certificateDBFile.exists(), "cert9.db should exist in the profile"); + ok(keyDBFile.exists(), "key4.db should exist in the profile"); +} diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials.js b/security/manager/ssl/tests/unit/test_delegated_credentials.js new file mode 100644 index 0000000000..a1623ddcb2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials.js @@ -0,0 +1,91 @@ +/* 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/. */ +"use strict"; + +// Tests handling of certificates marked as permitting delegated credentials + +function shouldBeDelegatedCredential(aTransportSecurityInfo) { + Assert.ok( + aTransportSecurityInfo.isDelegatedCredential, + "This host should have used a delegated credential" + ); +} + +function shouldNotBeDelegatedCredential(aTransportSecurityInfo) { + Assert.ok( + !aTransportSecurityInfo.isDelegatedCredential, + "This host should not have used a delegated credential" + ); +} + +do_get_profile(); + +add_tls_server_setup( + "DelegatedCredentialsServer", + "test_delegated_credentials" +); + +// Test: +// Server certificate supports DC +// Server DC support enabled +// Client DC support disabled +// Result: Successful connection without DC +add_test(function() { + clearSessionCache(); + Services.prefs.setBoolPref( + "security.tls.enable_delegated_credentials", + false + ); + run_next_test(); +}); +add_connection_test( + "delegated-enabled.example.com", + PRErrorCodeSuccess, + null, + shouldNotBeDelegatedCredential +); + +// Test: +// Server certificate does not support DC +// Server DC support enabled +// Client DC support enabled +// Result: SSL_ERROR_DC_INVALID_KEY_USAGE from client when +// checking DC against EE cert, no DC in aTransportSecurityInfo. +add_test(function() { + clearSessionCache(); + Services.prefs.setBoolPref("security.tls.enable_delegated_credentials", true); + run_next_test(); +}); +add_connection_test( + "standard-enabled.example.com", + SSL_ERROR_DC_INVALID_KEY_USAGE, + null, + // We'll never |mHaveCipherSuiteAndProtocol|, + // and therefore can't check IsDelegatedCredential + null +); + +// Test: +// Server certificate supports DC +// Server DC support disabled +// Client DC support enabled +// Result: Successful connection without DC +add_connection_test( + "delegated-disabled.example.com", + PRErrorCodeSuccess, + null, + shouldNotBeDelegatedCredential +); + +// Test: +// Server certificate supports DC +// Server DC support enabled +// Client DC support enabled +// Result: Successful connection with DC +add_connection_test( + "delegated-enabled.example.com", + PRErrorCodeSuccess, + null, + shouldBeDelegatedCredential +); diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key new file mode 100644 index 0000000000..a926a54efb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key @@ -0,0 +1,5 @@ +-----BEGIN EC PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgIZFAPVcQvxWiZYGM +1C7W/t8JrdkteLGOeh6f65VSRwKhRANCAARPv7u7YeD4+bGmClmshwTi7AULQj48 +9y6SPyxPeUtFXCpp0jNFbDbEEZ0HBuAO7cjRk5DXmRt7LQejBOqgSqbA +-----END EC PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key.keyspec b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key.keyspec new file mode 100644 index 0000000000..03c3ce198f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.key.keyspec @@ -0,0 +1 @@ +secp256r1 diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem new file mode 100644 index 0000000000..332793b89e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSDCCATCgAwIBAgIUNeh3F5ZVYezEJKXRBQTRiDY/isMwDQYJKoZIhvcNAQEL +BQAwLDEqMCgGA1UEAwwhZGVsZWdhdGVkLWNyZWRlbnRpYWwtaW50ZXJtZWRpYXRl +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMBUxEzARBgNVBAMM +CmRlZmF1bHQtZWUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARPv7u7YeD4+bGm +ClmshwTi7AULQj489y6SPyxPeUtFXCpp0jNFbDbEEZ0HBuAO7cjRk5DXmRt7LQej +BOqgSqbAo0AwPjATBgNVHSUEDDAKBggrBgEFBQcDATAnBgNVHREEIDAeghxzdGFu +ZGFyZC1lbmFibGVkLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQBqh2DB +lbCuX6H9CPsdgDLX3z4gS5ab/1g7J4az29EQuFgb2z6gHOOuMDkLgDPpq3Vz0mrk +emsoXToPdHsRZ4S57KeELRLT42bdyYkDR8yWTm588UhDNo3n492RD+dYHILmJdj0 +d9MWlMnl/jpXo8/a36ZJ2QgjSUyzwE/Nyxd8864Pk5ipUwyabSFjiEGcHsrfsSIQ +fqkBXG0UudjjWEPInSQIBNIwCZL3HDwoeV2SO3gjxDwyume2S0K6GGXWs8a+mLBn +Kks7nmQ8pEipNyHDt9TUS+Ywj6txK4cOp4WTh86q0h9mLWqqvg/DdTHLyFyzPWPa +LZl7VR1aKXr9IzE0 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem.certspec b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem.certspec new file mode 100644 index 0000000000..5ebe9b5ba7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/default-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:delegated-credential-intermediate +subjectKey:secp256r1 +subject:default-ee +extension:extKeyUsage:serverAuth +extension:subjectAlternativeName:standard-enabled.example.com diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem new file mode 100644 index 0000000000..ece3ae8834 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem @@ -0,0 +1,16 @@ +-----BEGIN CERTIFICATE----- +MIICiTCCAXGgAwIBAgIUV0N3VFQpvGVw2qP62b/L1yTchOIwDQYJKoZIhvcNAQEL +BQAwLDEqMCgGA1UEAwwhZGVsZWdhdGVkLWNyZWRlbnRpYWwtaW50ZXJtZWRpYXRl +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMBcxFTATBgNVBAMM +DGRlbGVnYXRlZC1lZTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/u7th4Pj5 +saYKWayHBOLsBQtCPjz3LpI/LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGTkNeZG3st +B6ME6qBKpsCjfzB9MBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGA1UdDwQEAwIFoDBI +BgNVHREEQTA/gh1kZWxlZ2F0ZWQtZW5hYmxlZC5leGFtcGxlLmNvbYIeZGVsZWdh +dGVkLWRpc2FibGVkLmV4YW1wbGUuY29tMA8GCSsGAQQBgtpLLAQCBQAwDQYJKoZI +hvcNAQELBQADggEBAIxXv51QQR9JwM+Q7kQnRpK41Xe4WCDSwoyD+eOgbKznTJvz +v3YDZKkO9cdQDGdd2GgMA/6/a0vc1wK1IO5eI2bAisIbublJ8xkuTeLyhdisGxMb +k0XLlcQ/KnXid3R6dccHguQPpdtDrf2kgKE8Wy9Gvg9LF3A6hIx5BtruInflvgp6 +jtUGlKrftPMhRIEP5FWy5KOJE8VW+ja4zBH6P36kDaNeWK3SrssyNAZmoDrxslJa +LDls1xZ4+ElGUjoywmEG0Fbbrv4mUiwCQ+4flHoopBGqs+3J0gY8SJndTZniSjSh +i7ivXTPlrU0Sm8jt1e/RYlnA6IyvQp8YbR+zX34= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem.certspec b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem.certspec new file mode 100644 index 0000000000..e90fa3b646 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated-ee.pem.certspec @@ -0,0 +1,7 @@ +issuer:delegated-credential-intermediate +subject:delegated-ee +subjectKey:secp256r1 +extension:extKeyUsage:serverAuth +extension:keyUsage:digitalSignature,keyEncipherment +extension:subjectAlternativeName:delegated-enabled.example.com,delegated-disabled.example.com +extension:delegationUsage: diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key new file mode 100644 index 0000000000..1c1af40bda --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDADXHobENn6/oN7ZK2S +8i9c7QeJGGU4ZptcbYcs7D2SYSKzk3crV2Av8xNl7+E5MkahZANiAAShaHJDNitc +exiJ83kVRhWhxz+0je6GPgIpFdtgjiUt5LcTLajOmOgxU05qnAwLCcjWOa3oMgbl +uoE0c6EfozDgXajJbkOD/ieHPalxA74oiM/wAvBa9xof3cyDdKpuqc4= +-----END EC PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key.keyspec b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key.keyspec new file mode 100644 index 0000000000..11f041d996 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/delegated.key.keyspec @@ -0,0 +1 @@ +secp384r1 diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/moz.build b/security/manager/ssl/tests/unit/test_delegated_credentials/moz.build new file mode 100644 index 0000000000..e6722917e1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'test-ca.pem', +# 'test-int.pem', +# 'delegated-ee.pem', +# 'default-ee.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'default-ee.key', +# 'delegated.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem b/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem new file mode 100644 index 0000000000..52e77a4498 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8zCCAdugAwIBAgIUXeumyyPJUORUNVVSf/2pTjEDxS4wDQYJKoZIhvcNAQEL +BQAwIjEgMB4GA1UEAwwXZGVsZWdhdGVkLWNyZWRlbnRpYWwtY2EwIhgPMjAxOTEx +MjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowIjEgMB4GA1UEAwwXZGVsZWdhdGVk +LWNyZWRlbnRpYWwtY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQD +AgEGMA0GCSqGSIb3DQEBCwUAA4IBAQCvQNfsGAcHMiKfrbxHpJVnmxTAzWBSqJnp +V924Ofy80m03jI+99SEi9blzfHhJxRFe3cZYK3Dh4lhR3/RMHfZsepsAMzplS+to +m1T7D9zwFpVuqfAOnlkPPneVf3hTvgmkQqiLWZUb/pWZ2fGWAKtDXPM5HHf6gBKY ++8VbTUpPHhwDH1MRauoK18QysMlBm90OwM6mnzCsJ6xwTDQkFAt4vQ+jS3AglhPd +D5xqKbHwHi//h1EeV6u9mIJuX8HIZl5AM0Be4XaYb9gZFriflIjWxqmgh1alhKUM +H2gTyrzG8NmD+J4CCLEygYdaFlj3QfBypdW/QpdOaV77u7dhmxzg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem.certspec b/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem.certspec new file mode 100644 index 0000000000..91227f5da0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/test-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:delegated-credential-ca +subject:delegated-credential-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem b/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem new file mode 100644 index 0000000000..2425254722 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgIUAcAYRaw4AL7AX+7V+/SNR/7bZ0QwDQYJKoZIhvcNAQEL +BQAwIjEgMB4GA1UEAwwXZGVsZWdhdGVkLWNyZWRlbnRpYWwtY2EwIhgPMjAxOTEx +MjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowLDEqMCgGA1UEAwwhZGVsZWdhdGVk +LWNyZWRlbnRpYWwtaW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/ +MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAgnn4xLqeQUJDkL2Vo5Xl +WYgCcmCa0n01OwenTjTtWyIkbXCLDvyA5F7E79pW+8RevUJkM/JUzo/ZR6qr2cnR +H7lg4EEjVUC8zI60jvFeFZAelCoz6W4C/A4Y9pqLkDgJMWfdOstAe2cescqQPwsY +AK0OtxhdB8x371vwL0hBDL1u6CV+s2TGBc5Pj9lTY6UEDSAXIww2DzipVzalctg9 +oiihe6KDJuN0vTTt46ImksVo05EWT+uq2mJvVMgpcOXShJCmjl/zSM0KVT2VFc6v +xyeWCmmyaem/m9Do7Gnq+DVPII153dWmy1Xr0vX31PhroRETFnY5eyyc8umDD4Qu +uA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem.certspec b/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem.certspec new file mode 100644 index 0000000000..64cc4e5693 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_delegated_credentials/test-int.pem.certspec @@ -0,0 +1,4 @@ +issuer:delegated-credential-ca +subject:delegated-credential-intermediate +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_der.js b/security/manager/ssl/tests/unit/test_der.js new file mode 100644 index 0000000000..bae18e98e3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_der.js @@ -0,0 +1,380 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Tests DER.jsm functionality. + +// Until DER.jsm is actually used in production code, this is where we have to +// import it from. +var { DER } = ChromeUtils.import("resource://gre/modules/psm/DER.jsm"); + +function run_simple_tests() { + throws( + () => new DER.DERDecoder("this is not an array"), + /invalid input/, + "should throw given non-array input" + ); + throws( + () => new DER.DERDecoder([0, "invalid input", 1]), + /invalid input/, + "should throw given non-byte data (string case)" + ); + throws( + () => new DER.DERDecoder([31, 1, {}]), + /invalid input/, + "should throw given non-byte data (object case)" + ); + throws( + () => new DER.DERDecoder([0.1, 3, 1]), + /invalid input/, + "should throw given non-byte data (non-integer case)" + ); + throws( + () => new DER.DERDecoder([1, 3, -1]), + /invalid input/, + "should throw given non-byte data (negative integer case)" + ); + throws( + () => new DER.DERDecoder([1, 300, 79]), + /invalid input/, + "should throw given non-byte data (large integer case)" + ); + + let testReadByte = new DER.DERDecoder([0x0a, 0x0b]); + equal(testReadByte.readByte(), 0x0a, "should read 0x0a"); + equal(testReadByte.readByte(), 0x0b, "should read 0x0b"); + throws( + () => testReadByte.readByte(), + /data truncated/, + "reading more data than is available should fail" + ); + + let testReadBytes = new DER.DERDecoder([0x0c, 0x0d, 0x0e]); + deepEqual( + testReadBytes.readBytes(3), + [0x0c, 0x0d, 0x0e], + "should read correct sequence of bytes" + ); + + let testReadNegativeBytes = new DER.DERDecoder([0xff, 0xaf]); + throws( + () => testReadNegativeBytes.readBytes(-4), + /invalid length/, + "reading a negative number of bytes should fail" + ); + + let testReadZeroBytes = new DER.DERDecoder([]); + equal( + testReadZeroBytes.readBytes(0).length, + 0, + "reading zero bytes should result in a zero-length array" + ); + + let testReadTooManyBytes = new DER.DERDecoder([0xab, 0xcd, 0xef]); + throws( + () => testReadTooManyBytes.readBytes(4), + /data truncated/, + "reading too many bytes should fail" + ); + + let testSEQUENCE = new DER.DERDecoder([0x30, 0x01, 0x01]); + let content = testSEQUENCE.readTagAndGetContents(DER.SEQUENCE); + equal(content.length, 1, "content should have length 1"); + equal(content[0], 1, "value of content should be [1]"); + ok(testSEQUENCE.atEnd(), "testSEQUENCE should be at the end of its input"); + testSEQUENCE.assertAtEnd(); + + // The length purports to be 4 bytes, but there are only 2 available. + let truncatedSEQUENCE = new DER.DERDecoder([0x30, 0x04, 0x00, 0x00]); + throws( + () => truncatedSEQUENCE.readTagAndGetContents(DER.SEQUENCE), + /data truncated/, + "should get 'data truncated' error" + ); + + // With 2 bytes of content, there is 1 remaining after reading the content. + let extraDataSEQUENCE = new DER.DERDecoder([0x30, 0x02, 0xab, 0xcd, 0xef]); + content = extraDataSEQUENCE.readTagAndGetContents(DER.SEQUENCE); + equal(content.length, 2, "content should have length 2"); + deepEqual(content, [0xab, 0xcd], "value of content should be [0xab, 0xcd]"); + ok( + !extraDataSEQUENCE.atEnd(), + "extraDataSEQUENCE should not be at the end of its input" + ); + throws( + () => extraDataSEQUENCE.assertAtEnd(), + /extra data/, + "should get 'extra data' error" + ); + + // The length of 0x81 0x01 is invalid because it could be encoded as just + // 0x01, which is shorter. + let invalidLengthSEQUENCE1 = new DER.DERDecoder([0x30, 0x81, 0x01, 0x00]); + throws( + () => invalidLengthSEQUENCE1.readTagAndGetContents(DER.SEQUENCE), + /invalid length/, + "should get 'invalid length' error" + ); + + // Similarly, 0x82 0x00 0x01 could be encoded as just 0x01, which is shorter. + let invalidLengthSEQUENCE2 = new DER.DERDecoder([ + 0x30, + 0x82, + 0x00, + 0x01, + 0x00, + ]); + throws( + () => invalidLengthSEQUENCE2.readTagAndGetContents(DER.SEQUENCE), + /invalid length/, + "should get 'invalid length' error" + ); + + // Lengths requiring 4 bytes to encode are not supported. + let unsupportedLengthSEQUENCE = new DER.DERDecoder([ + 0x30, + 0x83, + 0x01, + 0x01, + 0x01, + ]); + throws( + () => unsupportedLengthSEQUENCE.readTagAndGetContents(DER.SEQUENCE), + /unsupported length/, + "should get 'unsupported length' error" + ); + + // Indefinite lengths are not supported (and aren't DER anyway). + let unsupportedASN1SEQUENCE = new DER.DERDecoder([ + 0x30, + 0x80, + 0x01, + 0x00, + 0x00, + ]); + throws( + () => unsupportedASN1SEQUENCE.readTagAndGetContents(DER.SEQUENCE), + /unsupported asn.1/, + "should get 'unsupported asn.1' error" + ); + + let unexpectedTag = new DER.DERDecoder([0x31, 0x01, 0x00]); + throws( + () => unexpectedTag.readTagAndGetContents(DER.SEQUENCE), + /unexpected tag/, + "should get 'unexpected tag' error" + ); + + let readTLVTestcase = new DER.DERDecoder([0x02, 0x03, 0x45, 0x67, 0x89]); + let bytes = readTLVTestcase.readTLV(); + deepEqual( + bytes, + [0x02, 0x03, 0x45, 0x67, 0x89], + "bytes read with readTLV should be equal to expected value" + ); + + let peekTagTestcase = new DER.DERDecoder([0x30, 0x01, 0x00]); + ok( + peekTagTestcase.peekTag(DER.SEQUENCE), + "peekTag should return true for peeking with a SEQUENCE at a SEQUENCE" + ); + ok( + !peekTagTestcase.peekTag(DER.SET), + "peekTag should return false for peeking with a SET at a SEQUENCE" + ); + peekTagTestcase.readTLV(); + ok( + !peekTagTestcase.peekTag(DER.SEQUENCE), + "peekTag should return false for peeking at a DER with no more data" + ); + + let tlvChoiceTestcase = new DER.DERDecoder([0x31, 0x02, 0xaa, 0xbb]); + let tlvChoiceContents = tlvChoiceTestcase.readTLVChoice([DER.NULL, DER.SET]); + deepEqual( + tlvChoiceContents, + [0x31, 0x02, 0xaa, 0xbb], + "readTLVChoice should return expected bytes" + ); + + let tlvChoiceNoMatchTestcase = new DER.DERDecoder([0x30, 0x01, 0xff]); + throws( + () => tlvChoiceNoMatchTestcase.readTLVChoice([DER.NULL, DER.SET]), + /unexpected tag/, + "readTLVChoice should throw if no matching tag is found" + ); +} + +function run_bit_string_tests() { + let bitstringDER = new DER.DERDecoder([0x03, 0x04, 0x03, 0x01, 0x02, 0xf8]); + let bitstring = bitstringDER.readBIT_STRING(); + equal(bitstring.unusedBits, 3, "BIT STRING should have 3 unused bits"); + deepEqual( + bitstring.contents, + [0x01, 0x02, 0xf8], + "BIT STRING should have expected contents" + ); + + let bitstringTooManyUnusedBits = new DER.DERDecoder([0x03, 0x02, 0x08, 0x00]); + throws( + () => bitstringTooManyUnusedBits.readBIT_STRING(), + /invalid BIT STRING encoding/, + "BIT STRING with too many unused bits should throw" + ); + + // A BIT STRING must have the unused bits byte, and so its length must be at + // least one. + let bitstringMissingUnusedBits = new DER.DERDecoder([0x03, 0x00]); + throws( + () => bitstringMissingUnusedBits.readBIT_STRING(), + /invalid BIT STRING encoding/, + "BIT STRING with missing unused bits (and no contents) should throw" + ); + + // The minimal BIT STRING is 03 01 00 (zero bits of padding and zero bytes of + // content). + let minimalBitstringDER = new DER.DERDecoder([0x03, 0x01, 0x00]); + let minimalBitstring = minimalBitstringDER.readBIT_STRING(); + equal( + minimalBitstring.unusedBits, + 0, + "minimal BIT STRING should have 0 unused bits" + ); + equal( + minimalBitstring.contents.length, + 0, + "minimal BIT STRING should have empty contents" + ); + + // However, a BIT STRING with zero bytes of content can't have any padding, + // because that makes no sense. + let noContentsPaddedBitstringDER = new DER.DERDecoder([0x03, 0x01, 0x03]); + throws( + () => noContentsPaddedBitstringDER.readBIT_STRING(), + /invalid BIT STRING encoding/, + "BIT STRING with no contents with non-zero padding should throw" + ); +} + +function run_compound_tests() { + let derBytes = [ + 0x30, + 0x1a, // SEQUENCE + 0x02, + 0x02, + 0x77, + 0xff, // INTEGER + 0x06, + 0x03, + 0x2b, + 0x01, + 0x01, // OBJECT IDENTIFIER + 0x30, + 0x07, // SEQUENCE + 0x05, + 0x00, // NULL + 0x02, + 0x03, + 0x45, + 0x46, + 0x47, // INTEGER + 0x30, + 0x06, // SEQUENCE + 0x02, + 0x02, + 0x00, + 0xff, // INTEGER + 0x05, + 0x00, + ]; // NULL + let der = new DER.DERDecoder(derBytes); + let contents = new DER.DERDecoder(der.readTagAndGetContents(DER.SEQUENCE)); + let firstINTEGER = contents.readTagAndGetContents(DER.INTEGER); + deepEqual( + firstINTEGER, + [0x77, 0xff], + "first INTEGER should have expected value" + ); + let oid = contents.readTagAndGetContents(DER.OBJECT_IDENTIFIER); + deepEqual( + oid, + [0x2b, 0x01, 0x01], + "OBJECT IDENTIFIER should have expected value" + ); + + let firstNested = new DER.DERDecoder( + contents.readTagAndGetContents(DER.SEQUENCE) + ); + let firstNestedNULL = firstNested.readTagAndGetContents(DER.NULL); + equal( + firstNestedNULL.length, + 0, + "first nested NULL should have expected value (empty array)" + ); + let firstNestedINTEGER = firstNested.readTagAndGetContents(DER.INTEGER); + deepEqual( + firstNestedINTEGER, + [0x45, 0x46, 0x47], + "first nested INTEGER should have expected value" + ); + firstNested.assertAtEnd(); + + let secondNested = new DER.DERDecoder( + contents.readTagAndGetContents(DER.SEQUENCE) + ); + let secondNestedINTEGER = secondNested.readTagAndGetContents(DER.INTEGER); + deepEqual( + secondNestedINTEGER, + [0x00, 0xff], + "second nested INTEGER should have expected value" + ); + let secondNestedNULL = secondNested.readTagAndGetContents(DER.NULL); + equal( + secondNestedNULL.length, + 0, + "second nested NULL should have expected value (empty array)" + ); + secondNested.assertAtEnd(); + + contents.assertAtEnd(); + der.assertAtEnd(); + + let invalidDERBytes = [ + 0x30, + 0x06, // SEQUENCE + 0x30, + 0x02, // SEQUENCE + 0x02, + 0x01, // INTEGER (missing data) + 0x05, + 0x00, // NULL + 0x00, + 0x00, + ]; // (extra data) + let invalidDER = new DER.DERDecoder(invalidDERBytes); + let invalidContents = new DER.DERDecoder( + invalidDER.readTagAndGetContents(DER.SEQUENCE) + ); + let invalidContentsContents = new DER.DERDecoder( + invalidContents.readTagAndGetContents(DER.SEQUENCE) + ); + throws( + () => invalidContentsContents.readTagAndGetContents(DER.INTEGER), + /data truncated/, + "should throw due to missing data" + ); + let nestedNULL = invalidContents.readTagAndGetContents(DER.NULL); + equal(nestedNULL.length, 0, "nested NULL should have expected value"); + invalidContents.assertAtEnd(); + throws( + () => invalidDER.assertAtEnd(), + /extra data/, + "should throw due to extra data" + ); +} + +function run_test() { + run_simple_tests(); + run_bit_string_tests(); + run_compound_tests(); +} diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello.js b/security/manager/ssl/tests/unit/test_encrypted_client_hello.js new file mode 100644 index 0000000000..69d3df8645 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello.js @@ -0,0 +1,93 @@ +/* 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/. */ +"use strict"; + +// Tests handling of Encrypted Client Hello. These ECHConfigs +// can be regenerated by running EncryptedClientHelloServer +// and dumping the output of SSL_EncodeEchConfig. They do not +// expire. An update here is only needed if the host or ECH +// ciphersuite configuration changes, or if the keypair in +// EncryptedClientHelloServer.cpp is modified. + +// Public name: ech-public.example.com +const ECH_CONFIG_FIXED = + "AEr+CABGABZlY2gtcHVibGljLmV4YW1wbGUuY29tACCKB1Y5SfrGIyk27W82xPpzWTDs3q72c04xSurDWlb9CgAgAAQAAQADADIAAA=="; + +// Public name: ech-public.example.com, Unsupported AEAD to prompt retry_configs from a trusted host. +const ECH_CONFIG_TRUSTED_RETRY = + "AEr+CABGABZlY2gtcHVibGljLmV4YW1wbGUuY29tACCKB1Y5SfrGIyk27W82xPpzWTDs3q72c04xSurDWlb9CgAgAAQAAQABADIAAA=="; + +// Public name: selfsigned.example.com. Unsupported AEAD to prompt retry_configs from an untrusted host. +const ECH_CONFIG_UNTRUSTED_RETRY = + "AEr+CABGABZzZWxmc2lnbmVkLmV4YW1wbGUuY29tACCKB1Y5SfrGIyk27W82xPpzWTDs3q72c04xSurDWlb9CgAgAAQAAQABADIAAA=="; + +function shouldBeAcceptedEch(aTransportSecurityInfo) { + Assert.ok( + aTransportSecurityInfo.isAcceptedEch, + "This host should have accepted ECH" + ); +} + +function shouldBeRejectedEch(aTransportSecurityInfo) { + Assert.ok( + !aTransportSecurityInfo.isAcceptedEch, + "This host should have rejected ECH" + ); +} + +do_get_profile(); + +add_tls_server_setup( + "EncryptedClientHelloServer", + "test_encrypted_client_hello" +); + +// Connect directly without ECH first +add_connection_test( + "ech-public.example.com", + PRErrorCodeSuccess, + null, + shouldBeRejectedEch +); + +// Connect with ECH +add_connection_test( + "ech-private.example.com", + PRErrorCodeSuccess, + null, + shouldBeAcceptedEch, + null, + null, + ECH_CONFIG_FIXED +); + +// Trigger retry_configs by setting an ECHConfig with a different. +// AEAD than the server supports. +add_connection_test( + "ech-private.example.com", + SSL_ERROR_ECH_RETRY_WITH_ECH, + null, + null, + null, + null, + ECH_CONFIG_TRUSTED_RETRY +); + +// Trigger retry_configs, but from a host that is untrusted +// (due to a self-signed certificate for the public name). +// Retry_configs must not be used or reported as available. +add_connection_test( + "ech-private.example.com", + MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT, + null, + null, + null, + null, + ECH_CONFIG_UNTRUSTED_RETRY +); + +// A client-only (retry_without_ech) test is located in +// test_encrypted_client_hello_client_only.js We can't easily restart +// a different server (one without ECHConfigs) here, so put that +// test in a different file that launches a non-ECH server. diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key.keyspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem new file mode 100644 index 0000000000..c71005fc19 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4DCCAcigAwIBAgIUP5hH78XA0upQ7cmqNASOW6WqkoUwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZWNoLWNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBgxFjAUBgNVBAMMDWVjaC1wdWJsaWMtZWUwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjJTAjMCEG +A1UdEQQaMBiCFmVjaC1wdWJsaWMuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQAD +ggEBAIgqt32ojY+McIFUq57FIpI0FsDnY/L+GsmtUziUjM0rfNTuDP0r+CF/1emA +sTukf+YIiohoGjfRMebYdeWtpUjdG9O/Z1ygmGQNms6LP+xy6dPUM4G0sBpkfNdb +u74ymuru0kMopYpVXuDsaYOPTNj2W6a7gLpn3llk8K4SVFEogUTlzzOBtYobf8L5 +9tSDpsMrTPINVbyi8SQHONMrsuqMfMDSTCkQnZJDcbRW56T2+PgrWJnQ78NDM0GB +/KLRW6tIyyTco1IBrFC9+0j5jyHh4+3em0bT7sdcwidjZKipWsvcKK9DuycSSM6O +nL8vxqnekennEVLV7zm6rjB/wns= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem.certspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem.certspec new file mode 100644 index 0000000000..d5c332ceec --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/default-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ech-ca +subject:ech-public-ee +extension:subjectAlternativeName:ech-public.example.com diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/moz.build b/security/manager/ssl/tests/unit/test_encrypted_client_hello/moz.build new file mode 100644 index 0000000000..a3755e779b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'default-ee.pem', +# 'private-ee.pem', +# 'selfsigned.pem', +# 'test-ca.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'public-ee.key', +# 'private-ee.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key.keyspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem new file mode 100644 index 0000000000..258b0fc043 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4jCCAcqgAwIBAgIUSXmHaEjlH8Iry6lZ5kbx/TBwgI8wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZWNoLWNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBkxFzAVBgNVBAMMDmVjaC1wcml2YXRlLWVlMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1 +aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/we +adA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSS +pH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62W +YVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauR +CE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoyYwJDAi +BgNVHREEGzAZghdlY2gtcHJpdmF0ZS5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsF +AAOCAQEAI63cvfxAvxMKJBDTIle1hHjW9wf1FgRyus37hqdLatN3fa4o2vNRLfX7 +MITXlLcmqehrBj/Wi7thMOC77HGE3wGvUNog2Avk4exps/bR1ksTraY5cxM386he +FG2QJ8im2VavNyqwmu2IcbPpZk5MKYolptmRFvz/6XGtLQsRjdtABKoUBB1tXlT2 +go6VULbEQn62fAdBvb/1CO6+jDWIpPzbpFSdWTBSpY1IfhAjsEP6W5kkDaKYwf8G +IJslTTh+4v8Fq06ySdV1T8IYu29YuCye+sbWyWfcfPQqssaQzWpqAyBOO2kV3r3B +XsaWXLsuXMnzBDJ5PM6Wsp8dLFXFzg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem.certspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem.certspec new file mode 100644 index 0000000000..c152462f0d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/private-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:ech-ca +subject:ech-private-ee +extension:subjectAlternativeName:ech-private.example.com diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem b/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem new file mode 100644 index 0000000000..f7f7c6f2df --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDAzCCAeugAwIBAgIUKyuH4MWSNUsG95g0ExZZWo1i0tkwDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbU2VsZi1zaWduZWQgVGVzdCBFbmQtZW50aXR5MCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCYxJDAiBgNVBAMMG1NlbGYt +c2lnbmVkIFRlc3QgRW5kLWVudGl0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMlMCMwIQYDVR0RBBowGIIWc2Vs +ZnNpZ25lZC5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAqCxzMj+ECM64 +aG9XqCBHkrR45i6UO0jZkGGBRhUJunfSpK8g5jCuRH0wv4SPZG3tl7VgOtFHFhm5 +1SkEOstkShslHCWwEXoMuO9uvRGzjXl3bxES70ERHmcncp0yWXDT+QDyXM489X1M +UtEFzWLMv22BX6J6xrvyhJK3zodHXtBSphG2NUEARPsgxb3sMiQA9jTacsQHC9yZ +dmknp5zhYgCHntO8jFVc04O21wwMlzMB7IR/WFHs67opimHlQlBIWvRDOSsVvxdY +y8ybGmymQ8g3hxHlQ5fc+oX64SDuHQa6kw2ZWQEz3e4It+VU5Y93QhCLgKqijfBr +HRt0AadMpg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem.certspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem.certspec new file mode 100644 index 0000000000..438a08eba2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/selfsigned.pem.certspec @@ -0,0 +1,3 @@ +issuer:Self-signed Test End-entity +subject:Self-signed Test End-entity +extension:subjectAlternativeName:selfsigned.example.com diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem b/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem new file mode 100644 index 0000000000..00b43c3d66 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUYc9/sZ6jdK4/ErAKn9/aEFPSgxowDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZWNoLWNhMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBExDzANBgNVBAMMBmVjaC1jYTCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAFHcA3r+hl4tWZnO +tG1AsddSxeqxhFsZTNTwzLfnYRlFgxytmgE+r3pp5Aost6ZLhcagQT2uIklEBOnw +se2evClYtC4yVd/FOLaGdd9YCGCggYpoNgNhNMHXI5qS28kslZLnbcD4HScYan66 +KcxGDSBRPggdOkOjhBHax3nni1+kWbzNIFQ2SWR0V/C2pxZJXDGlkE/sggD0nqG+ +iQWJytyJQJsKskNdUOh4R0sANDMTYEQfMrDVuNS6poqRj1C98JyP8qP+jsZZ33WQ +brR7zbYDhBHdIi4MLZMgGCN+0VZ5PD26nT+9XekV8A/7+U29PxdviW6oZqpMT+sD +ne3P1JM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem.certspec b/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem.certspec new file mode 100644 index 0000000000..1735a15075 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello/test-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ech-ca +subject:ech-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_encrypted_client_hello_client_only.js b/security/manager/ssl/tests/unit/test_encrypted_client_hello_client_only.js new file mode 100644 index 0000000000..eb6cd40e26 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_encrypted_client_hello_client_only.js @@ -0,0 +1,33 @@ +/* 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/. */ +"use strict"; + +// Public Name = delegated-enabled.example.com +const ECH_CONFIG_FIXED = + "AFH+CABNAB1kZWxlZ2F0ZWQtZW5hYmxlZC5leGFtcGxlLmNvbQAgigdWOUn6xiMpNu1vNsT6c1kw7N6u9nNOMUrqw1pW/QoAIAAEAAEAAwAyAAA="; + +do_get_profile(); + +// An arbitrary, non-ECH server. +add_tls_server_setup( + "DelegatedCredentialsServer", + "test_delegated_credentials" +); + +add_test(function() { + clearSessionCache(); + run_next_test(); +}); + +// Connect, sending ECH. The server is not configured for it, +// but *is* authoritative for the public name. +add_connection_test( + "delegated-disabled.example.com", + SSL_ERROR_ECH_RETRY_WITHOUT_ECH, + null, + null, + null, + null, + ECH_CONFIG_FIXED +); diff --git a/security/manager/ssl/tests/unit/test_enterprise_roots.js b/security/manager/ssl/tests/unit/test_enterprise_roots.js new file mode 100644 index 0000000000..24537ccc41 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_enterprise_roots.js @@ -0,0 +1,82 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// Tests enterprise root certificate support. When configured to do so, the +// platform will attempt to find and import enterprise root certificates. This +// feature is specific to Windows. + +do_get_profile(); // must be called before getting nsIX509CertDB + +const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" +); + +async function check_no_enterprise_roots_imported( + nssComponent, + certDB, + dbKey = undefined +) { + let enterpriseRoots = nssComponent.getEnterpriseRoots(); + notEqual(enterpriseRoots, null, "enterprise roots list should not be null"); + equal( + enterpriseRoots.length, + 0, + "should not have imported any enterprise roots" + ); + if (dbKey) { + let cert = certDB.findCertByDBKey(dbKey); + // If the garbage-collector hasn't run, there may be reachable copies of + // imported enterprise root certificates. If so, they shouldn't be trusted + // to issue TLS server auth certificates. + if (cert) { + await asyncTestCertificateUsages(certDB, cert, []); + } + } +} + +async function check_some_enterprise_roots_imported(nssComponent, certDB) { + let enterpriseRoots = nssComponent.getEnterpriseRoots(); + notEqual(enterpriseRoots, null, "enterprise roots list should not be null"); + notEqual( + enterpriseRoots.length, + 0, + "should have imported some enterprise roots" + ); + let foundNonBuiltIn = false; + let savedDBKey = null; + for (let certDer of enterpriseRoots) { + let cert = certDB.constructX509(certDer); + notEqual(cert, null, "should be able to decode cert from DER"); + if (!cert.isBuiltInRoot && !savedDBKey) { + foundNonBuiltIn = true; + savedDBKey = cert.dbKey; + info("saving dbKey from " + cert.commonName); + await asyncTestCertificateUsages(certDB, cert, [certificateUsageSSLCA]); + break; + } + } + ok(foundNonBuiltIn, "should have found non-built-in root"); + return savedDBKey; +} + +add_task(async function run_test() { + let nssComponent = Cc["@mozilla.org/psm;1"].getService(Ci.nsINSSComponent); + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + nssComponent.getEnterpriseRoots(); // blocks until roots are loaded + Services.prefs.setBoolPref("security.enterprise_roots.enabled", false); + await check_no_enterprise_roots_imported(nssComponent, certDB); + Services.prefs.setBoolPref("security.enterprise_roots.enabled", true); + await TestUtils.topicObserved("psm:enterprise-certs-imported"); + let savedDBKey = await check_some_enterprise_roots_imported( + nssComponent, + certDB + ); + Services.prefs.setBoolPref("security.enterprise_roots.enabled", false); + await check_no_enterprise_roots_imported(nssComponent, certDB, savedDBKey); +}); diff --git a/security/manager/ssl/tests/unit/test_ev_certs.js b/security/manager/ssl/tests/unit/test_ev_certs.js new file mode 100644 index 0000000000..937e4509f3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs.js @@ -0,0 +1,437 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// Tests that end-entity certificates that should successfully verify as EV +// (Extended Validation) do so and that end-entity certificates that should not +// successfully verify as EV do not. Also tests related situations (e.g. that +// failure to fetch an OCSP response results in no EV treatment). +// +// A quick note about the certificates in these tests: generally, an EV +// certificate chain will have an end-entity with a specific policy OID followed +// by an intermediate with the anyPolicy OID chaining to a root with no policy +// OID (since it's a trust anchor, it can be omitted). In these tests, the +// specific policy OID is 1.3.6.1.4.1.13769.666.666.666.1.500.9.1 and is +// referred to as the test OID. In order to reflect what will commonly be +// encountered, the end-entity of any given test path will have the test OID +// unless otherwise specified in the name of the test path. Similarly, the +// intermediate will have the anyPolicy OID, again unless otherwise specified. +// For example, for the path where the end-entity does not have an OCSP URI +// (referred to as "no-ocsp-ee-path-{ee,int}", the end-entity has the test OID +// whereas the intermediate has the anyPolicy OID. +// For another example, for the test OID path ("test-oid-path-{ee,int}"), both +// the end-entity and the intermediate have the test OID. + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +registerCleanupFunction(() => { + Services.prefs.clearUserPref("network.dns.localDomains"); + Services.prefs.clearUserPref("security.OCSP.enabled"); +}); + +Services.prefs.setCharPref("network.dns.localDomains", "www.example.com"); +Services.prefs.setIntPref("security.OCSP.enabled", 1); +const evroot = addCertFromFile(certdb, "test_ev_certs/evroot.pem", "CTu,,"); +addCertFromFile(certdb, "test_ev_certs/non-evroot-ca.pem", "CTu,,"); + +const SERVER_PORT = 8888; + +function failingOCSPResponder() { + return getFailingHttpServer(SERVER_PORT, ["www.example.com"]); +} + +class EVCertVerificationResult { + constructor( + testcase, + expectedPRErrorCode, + expectedEV, + resolve, + ocspResponder + ) { + this.testcase = testcase; + this.expectedPRErrorCode = expectedPRErrorCode; + this.expectedEV = expectedEV; + this.resolve = resolve; + this.ocspResponder = ocspResponder; + } + + verifyCertFinished(prErrorCode, verifiedChain, hasEVPolicy) { + equal( + prErrorCode, + this.expectedPRErrorCode, + `${this.testcase} should have expected error code` + ); + equal( + hasEVPolicy, + this.expectedEV, + `${this.testcase} should result in expected EV status` + ); + this.ocspResponder.stop(this.resolve); + } +} + +function asyncTestEV( + cert, + expectedPRErrorCode, + expectedEV, + expectedOCSPRequestPaths, + ocspResponseTypes = undefined +) { + let now = Date.now() / 1000; + return new Promise((resolve, reject) => { + let ocspResponder = + expectedOCSPRequestPaths.length > 0 + ? startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_ev_certs", + expectedOCSPRequestPaths, + expectedOCSPRequestPaths.slice(), + null, + ocspResponseTypes + ) + : failingOCSPResponder(); + let result = new EVCertVerificationResult( + cert.subjectName, + expectedPRErrorCode, + expectedEV, + resolve, + ocspResponder + ); + certdb.asyncVerifyCertAtTime( + cert, + certificateUsageSSLServer, + 0, + "ev-test.example.com", + now, + result + ); + }); +} + +function ensureVerifiesAsEV(testcase) { + let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`); + addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,"); + let expectedOCSPRequestPaths = gEVExpected + ? [`${testcase}-int`, `${testcase}-ee`] + : [`${testcase}-ee`]; + return asyncTestEV( + cert, + PRErrorCodeSuccess, + gEVExpected, + expectedOCSPRequestPaths + ); +} + +function ensureVerifiesAsEVWithNoOCSPRequests(testcase) { + let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`); + addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,"); + return asyncTestEV(cert, PRErrorCodeSuccess, gEVExpected, []); +} + +function ensureVerifiesAsDV(testcase, expectedOCSPRequestPaths = undefined) { + let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`); + addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,"); + return asyncTestEV( + cert, + PRErrorCodeSuccess, + false, + expectedOCSPRequestPaths ? expectedOCSPRequestPaths : [`${testcase}-ee`] + ); +} + +function ensureVerificationFails(testcase, expectedPRErrorCode) { + let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`); + addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,"); + return asyncTestEV(cert, expectedPRErrorCode, false, []); +} + +function verifyWithFlags_LOCAL_ONLY_and_MUST_BE_EV(testcase, expectSuccess) { + let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`); + addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,"); + let now = Date.now() / 1000; + let expectedErrorCode = SEC_ERROR_POLICY_VALIDATION_FAILED; + if (expectSuccess && gEVExpected) { + expectedErrorCode = PRErrorCodeSuccess; + } + return new Promise((resolve, reject) => { + let ocspResponder = failingOCSPResponder(); + let result = new EVCertVerificationResult( + cert.subjectName, + expectedErrorCode, + expectSuccess && gEVExpected, + resolve, + ocspResponder + ); + let flags = + Ci.nsIX509CertDB.FLAG_LOCAL_ONLY | Ci.nsIX509CertDB.FLAG_MUST_BE_EV; + certdb.asyncVerifyCertAtTime( + cert, + certificateUsageSSLServer, + flags, + "ev-test.example.com", + now, + result + ); + }); +} + +function ensureNoOCSPMeansNoEV(testcase) { + return verifyWithFlags_LOCAL_ONLY_and_MUST_BE_EV(testcase, false); +} + +function ensureVerifiesAsEVWithFLAG_LOCAL_ONLY(testcase) { + return verifyWithFlags_LOCAL_ONLY_and_MUST_BE_EV(testcase, true); +} + +function ensureOneCRLSkipsOCSPForIntermediates(testcase) { + let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`); + addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,"); + return asyncTestEV(cert, PRErrorCodeSuccess, gEVExpected, [`${testcase}-ee`]); +} + +function verifyWithDifferentOCSPResponseTypes(testcase, responses, expectEV) { + let cert = constructCertFromFile(`test_ev_certs/${testcase}-ee.pem`); + addCertFromFile(certdb, `test_ev_certs/${testcase}-int.pem`, ",,"); + let expectedOCSPRequestPaths = gEVExpected + ? [`${testcase}-int`, `${testcase}-ee`] + : [`${testcase}-ee`]; + let ocspResponseTypes = gEVExpected ? responses : responses.slice(1); + return asyncTestEV( + cert, + PRErrorCodeSuccess, + gEVExpected && expectEV, + expectedOCSPRequestPaths, + ocspResponseTypes + ); +} + +function ensureVerifiesAsEVWithOldIntermediateOCSPResponse(testcase) { + return verifyWithDifferentOCSPResponseTypes( + testcase, + ["longvalidityalmostold", "good"], + true + ); +} + +function ensureVerifiesAsDVWithOldEndEntityOCSPResponse(testcase) { + return verifyWithDifferentOCSPResponseTypes( + testcase, + ["good", "longvalidityalmostold"], + false + ); +} + +function ensureVerifiesAsDVWithVeryOldEndEntityOCSPResponse(testcase) { + return verifyWithDifferentOCSPResponseTypes( + testcase, + ["good", "ancientstillvalid"], + false + ); +} + +// These should all verify as EV. +add_task(async function plainExpectSuccessEVTests() { + await ensureVerifiesAsEV("anyPolicy-int-path"); + await ensureVerifiesAsEV("test-oid-path"); + await ensureVerifiesAsEV("cabforum-oid-path"); + await ensureVerifiesAsEV("cabforum-and-test-oid-ee-path"); + await ensureVerifiesAsEV("test-and-cabforum-oid-ee-path"); + await ensureVerifiesAsEV("reverse-order-oids-path"); + // In this case, the end-entity has both the CA/B Forum OID and the test OID + // (in that order). The intermediate has the CA/B Forum OID. Since the + // implementation uses the first EV policy it encounters in the end-entity as + // the required one, this successfully verifies as EV. + await ensureVerifiesAsEV("cabforum-and-test-oid-ee-cabforum-oid-int-path"); +}); + +// These fail for various reasons to verify as EV, but fallback to DV should +// succeed. +add_task(async function expectDVFallbackTests() { + await ensureVerifiesAsDV("anyPolicy-ee-path"); + await ensureVerifiesAsDV("non-ev-root-path"); + await ensureVerifiesAsDV( + "no-ocsp-ee-path", + gEVExpected ? ["no-ocsp-ee-path-int"] : [] + ); + await ensureVerifiesAsDV("no-ocsp-int-path"); + // In this case, the end-entity has the test OID and the intermediate has the + // CA/B Forum OID. Since the CA/B Forum OID is not treated the same as the + // anyPolicy OID, this will not verify as EV. + await ensureVerifiesAsDV("test-oid-ee-cabforum-oid-int-path"); + // In this case, the end-entity has both the test OID and the CA/B Forum OID + // (in that order). The intermediate has only the CA/B Forum OID. Since the + // implementation uses the first EV policy it encounters in the end-entity as + // the required one, this fails to verify as EV. + await ensureVerifiesAsDV("test-and-cabforum-oid-ee-cabforum-oid-int-path"); +}); + +// Test that removing the trust bits from an EV root causes verifications +// relying on that root to fail (and then test that adding back the trust bits +// causes the verifications to succeed again). +add_task(async function evRootTrustTests() { + clearOCSPCache(); + info("untrusting evroot"); + certdb.setCertTrust( + evroot, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.UNTRUSTED + ); + await ensureVerificationFails("test-oid-path", SEC_ERROR_UNKNOWN_ISSUER); + info("re-trusting evroot"); + certdb.setCertTrust( + evroot, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL + ); + await ensureVerifiesAsEV("test-oid-path"); +}); + +// Test that if FLAG_LOCAL_ONLY and FLAG_MUST_BE_EV are specified, that no OCSP +// requests are made (this also means that nothing will verify as EV). +add_task(async function localOnlyMustBeEVTests() { + clearOCSPCache(); + await ensureNoOCSPMeansNoEV("anyPolicy-ee-path"); + await ensureNoOCSPMeansNoEV("anyPolicy-int-path"); + await ensureNoOCSPMeansNoEV("non-ev-root-path"); + await ensureNoOCSPMeansNoEV("no-ocsp-ee-path"); + await ensureNoOCSPMeansNoEV("no-ocsp-int-path"); + await ensureNoOCSPMeansNoEV("test-oid-path"); +}); + +// Under certain conditions, OneCRL allows us to skip OCSP requests for +// intermediates. +add_task(async function oneCRLTests() { + clearOCSPCache(); + + // enable OneCRL OCSP skipping - allow staleness of up to 30 hours + Services.prefs.setIntPref( + "security.onecrl.maximum_staleness_in_seconds", + 108000 + ); + // set the blocklist-background-update-timer value to the recent past + Services.prefs.setIntPref( + "services.settings.security.onecrl.checked", + Math.floor(Date.now() / 1000) - 1 + ); + Services.prefs.setIntPref( + "app.update.lastUpdateTime.blocklist-background-update-timer", + Math.floor(Date.now() / 1000) - 1 + ); + + await ensureOneCRLSkipsOCSPForIntermediates("anyPolicy-int-path"); + await ensureOneCRLSkipsOCSPForIntermediates("no-ocsp-int-path"); + await ensureOneCRLSkipsOCSPForIntermediates("test-oid-path"); + + clearOCSPCache(); + // disable OneCRL OCSP Skipping (no staleness allowed) + Services.prefs.setIntPref("security.onecrl.maximum_staleness_in_seconds", 0); + await ensureVerifiesAsEV("anyPolicy-int-path"); + // Because the intermediate in this case is missing an OCSP URI, it will not + // validate as EV, but it should fall back to DV. + await ensureVerifiesAsDV("no-ocsp-int-path"); + await ensureVerifiesAsEV("test-oid-path"); + + clearOCSPCache(); + // enable OneCRL OCSP skipping - allow staleness of up to 30 hours + Services.prefs.setIntPref( + "security.onecrl.maximum_staleness_in_seconds", + 108000 + ); + // set the blocklist-background-update-timer value to the more distant past + Services.prefs.setIntPref( + "services.settings.security.onecrl.checked", + Math.floor(Date.now() / 1000) - 108080 + ); + Services.prefs.setIntPref( + "app.update.lastUpdateTime.blocklist-background-update-timer", + Math.floor(Date.now() / 1000) - 108080 + ); + await ensureVerifiesAsEV("anyPolicy-int-path"); + await ensureVerifiesAsDV("no-ocsp-int-path"); + await ensureVerifiesAsEV("test-oid-path"); + + clearOCSPCache(); + // test the OCSP behavior when services.settings.security.onecrl.checked is in the + // distant past and blacklist-background-update-timer is recent + // enable OneCRL OCSP skipping - allow staleness of up to 30 hours + Services.prefs.setIntPref( + "security.onecrl.maximum_staleness_in_seconds", + 108000 + ); + // set the blocklist-background-update-timer value to the recent past + // (services.settings.security.onecrl.checked defaults to 0) + Services.prefs.setIntPref( + "app.update.lastUpdateTime.blocklist-background-update-timer", + Math.floor(Date.now() / 1000) - 1 + ); + + await ensureVerifiesAsEV("anyPolicy-int-path"); + await ensureVerifiesAsDV("no-ocsp-int-path"); + await ensureVerifiesAsEV("test-oid-path"); + + clearOCSPCache(); + // test the OCSP behavior when services.settings.security.onecrl.checked is recent + // enable OneCRL OCSP skipping - allow staleness of up to 30 hours + Services.prefs.setIntPref( + "security.onecrl.maximum_staleness_in_seconds", + 108000 + ); + // now set services.settings.security.onecrl.checked to a recent value + Services.prefs.setIntPref( + "services.settings.security.onecrl.checked", + Math.floor(Date.now() / 1000) - 1 + ); + await ensureOneCRLSkipsOCSPForIntermediates("anyPolicy-int-path"); + await ensureOneCRLSkipsOCSPForIntermediates("no-ocsp-int-path"); + await ensureOneCRLSkipsOCSPForIntermediates("test-oid-path"); + + Services.prefs.clearUserPref("security.onecrl.maximum_staleness_in_seconds"); + Services.prefs.clearUserPref("services.settings.security.onecrl.checked"); + Services.prefs.clearUserPref( + "app.update.lastUpdateTime.blocklist-background-update-timer" + ); +}); + +// Prime the OCSP cache and then ensure that we can validate certificates as EV +// without hitting the network. There's two cases here: one where we simply +// validate like normal and then check that the network was never accessed and +// another where we use flags to mandate that the network not be used. +add_task(async function ocspCachingTests() { + clearOCSPCache(); + + await ensureVerifiesAsEV("anyPolicy-int-path"); + await ensureVerifiesAsEV("test-oid-path"); + + await ensureVerifiesAsEVWithNoOCSPRequests("anyPolicy-int-path"); + await ensureVerifiesAsEVWithNoOCSPRequests("test-oid-path"); + + await ensureVerifiesAsEVWithFLAG_LOCAL_ONLY("anyPolicy-int-path"); + await ensureVerifiesAsEVWithFLAG_LOCAL_ONLY("test-oid-path"); +}); + +// Old-but-still-valid OCSP responses are accepted for intermediates but not +// end-entity certificates (because of OCSP soft-fail this results in DV +// fallback). +add_task(async function oldOCSPResponseTests() { + clearOCSPCache(); + + await ensureVerifiesAsEVWithOldIntermediateOCSPResponse("anyPolicy-int-path"); + await ensureVerifiesAsEVWithOldIntermediateOCSPResponse("test-oid-path"); + + clearOCSPCache(); + await ensureVerifiesAsDVWithOldEndEntityOCSPResponse("anyPolicy-int-path"); + await ensureVerifiesAsDVWithOldEndEntityOCSPResponse("test-oid-path"); + + clearOCSPCache(); + await ensureVerifiesAsDVWithVeryOldEndEntityOCSPResponse( + "anyPolicy-int-path" + ); + await ensureVerifiesAsDVWithVeryOldEndEntityOCSPResponse("test-oid-path"); +}); diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem new file mode 100644 index 0000000000..7326ef6d4e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVzCCAj+gAwIBAgIUQx+5x/tjsPB8QKeRGMqa5Xa/prYwDQYJKoZIhvcNAQEL +BQAwIDEeMBwGA1UEAwwVYW55UG9saWN5LWVlLXBhdGgtaW50MCIYDzIwMTkxMTI4 +MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMB8xHTAbBgNVBAMMFGFueVBvbGljeS1l +ZS1wYXRoLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABo4GFMIGCME0GCCsGAQUFBwEBBEEwPzA9BggrBgEFBQcw +AYYxaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2FueVBvbGljeS1lZS1wYXRo +LWVlLzARBgNVHSAECjAIMAYGBFUdIAAwHgYDVR0RBBcwFYITZXYtdGVzdC5leGFt +cGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEAM5dSETXj42Kai/sDKzZOaltmATbf +RDm9U8Pa1luk+m1Y2wgPDQfjcklPIkbyxsAwhdy1OCAUSVjWttAKs5w23TroT5Dq +tJAt823UD2xjwA3x1tTTmielwhc5cRL9uddrKAZ+EnRNLsI4wlTvjX1OBS61BgA6 +V/4//SJgS72Yj1Ebl9D5mA6iVHyUZblAwhsrogTwzWKMPzcAVgGp7YQK4b1yV4vc +zmcx9HrlsJuwpNwPQvysOhtOcbX1CbCdq9qzj6cCdIOZ3H5qzrr9swoZreVUsbic +xeHxhXGcp4+Bk+djBqlKvSGuw9FSlOSgpaB/K3ceDRjewje2rzTgAzSg7Q== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem.certspec new file mode 100644 index 0000000000..a9175c32ed --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:anyPolicy-ee-path-int +subject:anyPolicy-ee-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/anyPolicy-ee-path-ee/ +extension:certificatePolicies:any +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem new file mode 100644 index 0000000000..faaea5d176 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRDCCAiygAwIBAgIUR7Qq6/A9VAD2EfTAFB5di93IJx8wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCAxHjAcBgNVBAMMFWFueVBvbGljeS1lZS1wYXRoLWludDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaOBgDB+MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGME4GCCsGAQUFBwEBBEIw +QDA+BggrBgEFBQcwAYYyaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2FueVBv +bGljeS1lZS1wYXRoLWludC8wEQYDVR0gBAowCDAGBgRVHSAAMA0GCSqGSIb3DQEB +CwUAA4IBAQCCOVv8KxGwhAsLedhqkwyLkg7MnmFKYdGJo5LHXU5eszyRTHNy5L5/ +nvy6uCwA4h/FBL/XZb+VYIvbMpL8i7Oduf8kvWGWkfNPfUNgXK2ZdX3y1uBQda89 +kX2FTuP2ajdjZHkHPuA2wzpce8pDzlv0ULvIV4anOGgxuYqxKM1ihddYs/6LT/vs +cFjLJDLIvqv7heucPJ3ungJY4IEaYRv3zEXwrS3FY/zakfpEGLqTNlLOppp82LPB +7McNBxcxXrFdSfWqbLTl8U93Xe48utWl/qmUA/0+QBB7MvnaABss8pmzPGnC/FSV +AhS442Jz7DkpyTFzKuWarWdQN4ggoTIg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem.certspec new file mode 100644 index 0000000000..c49f6c4bcc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-ee-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:anyPolicy-ee-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/anyPolicy-ee-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem new file mode 100644 index 0000000000..8b2f95b556 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIUCeueEj6OFftd56Jw0VZ9VzHQVcowDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWYW55UG9saWN5LWludC1wYXRoLWludDAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAgMR4wHAYDVQQDDBVhbnlQb2xpY3kt +aW50LXBhdGgtZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjgZQwgZEwTgYIKwYBBQUHAQEEQjBAMD4GCCsGAQUF +BzABhjJodHRwOi8vd3d3LmV4YW1wbGUuY29tOjg4ODgvYW55UG9saWN5LWludC1w +YXRoLWVlLzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREE +FzAVghNldi10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAROBgq +JsnJtkdWyOTrG4jVhQ6WU6tmiUXEHGqDr8ARrRImX9+oekgKcGN7gyiDkvGq74rm +uqaeD4AlLkx9kXMKAd9Imr+efoOhzBbmZapCzeyrDFu343RIis2yjCSsjyLrNASZ +JWmuwsL44WOY/vSem7NIkbVEw6po0nxYpsNA94fgfPJA8Ut82vixr7+dnrCWlWM1 +7boWU8S56HuDi9TjiE4ADqmbJ+j+UZcEktCIFo9tVMh7tbd9KbO54/nDG+qgAfJU +yk8VJrYucrJa+Vtsa3CrCG640NcUD17618iwYw1c2Rseo/3yixTIQY8ujjSqC4j/ +oBiqhI8Wl7QOmX4h +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem.certspec new file mode 100644 index 0000000000..1c643c2f95 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:anyPolicy-int-path-int +subject:anyPolicy-int-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/anyPolicy-int-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem new file mode 100644 index 0000000000..bbb407b7d1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRjCCAi6gAwIBAgIUMw+R5DkD+4bOA7KD8UDYcG3RD2IwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCExHzAdBgNVBAMMFmFueVBvbGljeS1pbnQtcGF0aC1pbnQwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT +2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV +JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8N +jf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCA +BiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh +He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMB +AAGjgYEwfzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBPBggrBgEFBQcBAQRD +MEEwPwYIKwYBBQUHMAGGM2h0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9hbnlQ +b2xpY3ktaW50LXBhdGgtaW50LzARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcN +AQELBQADggEBAEHWJ58QNHayFGL5fxbvN66qffLJVpO5L+NM5MIaeEykSj7Weaem +8Fx6V8b+j6TKs6DD4yy7o/5PODbjc7v62a25XbTE4VrlG9T58hnxRpOXfMeHFu3L +oJajIIrJI4Am23rvHyQ/achk+cKqGIgBC6eBaEb5bV13OeM4dWM34Qo0VDmOAyo5 +Rgfeh0W5XBPi7fcnDhbIyJ3JQBhlHotR3krBv98nhy5mCi4bxTjERKMAgYaLvxUb +UOAT87BxNgHAiP4vvXbxl5T/TD1KLOFuypa0Q2LpUONbW6c4fcfKRoWkyA1u3+sE +RB/0RTleOS8Ekwzex8FgQMp9D5BrIA7JDbg= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem.certspec new file mode 100644 index 0000000000..5f5adacc7f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/anyPolicy-int-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:anyPolicy-int-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/anyPolicy-int-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem new file mode 100644 index 0000000000..c3a64d8890 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIUAXnU/fLGVanzfXZztetMUPvcgM0wDQYJKoZIhvcNAQEL +BQAwPTE7MDkGA1UEAwwyY2FiZm9ydW0tYW5kLXRlc3Qtb2lkLWVlLWNhYmZvcnVt +LW9pZC1pbnQtcGF0aC1pbnQwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowPDE6MDgGA1UEAwwxY2FiZm9ydW0tYW5kLXRlc3Qtb2lkLWVlLWNhYmZv +cnVtLW9pZC1pbnQtcGF0aC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab +bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts +Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI +H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8 +rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX +Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaOBuTCBtjBqBggrBgEFBQcBAQReMFww +WgYIKwYBBQUHMAGGTmh0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9jYWJmb3J1 +bS1hbmQtdGVzdC1vaWQtZWUtY2FiZm9ydW0tb2lkLWludC1wYXRoLWVlLzAoBgNV +HSAEITAfMAcGBWeBDAEBMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAV +ghNldi10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQBAyAiPnxab +CxbHi47hZ8xWcfpmyItTzPCzsKx9VGkbnFM7hA7p0CP116YlFny9wJoOi49+Qm3D +qyrnKPWme1tyW9DuDe0jz5eiUcBZ72jL5CZbXkQ1LfPKt1sGnwHoAu0NDNPeE/lQ +0RDSp/XW1kgjBDPDlTJ6k1MMdy9A0fEQosUH4bOpTOEeeTl3ZGVxJZmc2PcZebdV +Z/fizZ1JiKalKpYcAvgXGLw5HE+/OvGFlPrqxcQRa2f+MZFFDS/X7ZAiIFp7qqZg +h314bFrrPpB/v2oLMz2tdvTrIxJfj3+VXw19zkxuWavl6a/V5jiEZUQsJLgjLGdS +zQ9m/Jf6yLjU +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem.certspec new file mode 100644 index 0000000000..c72237e453 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:cabforum-and-test-oid-ee-cabforum-oid-int-path-int +subject:cabforum-and-test-oid-ee-cabforum-oid-int-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-and-test-oid-ee-cabforum-oid-int-path-ee/ +extension:certificatePolicies:2.23.140.1.1,1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem new file mode 100644 index 0000000000..b4728a8ea6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIUIejtPWmffl6VTrZjY+grxp67lQAwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMD0xOzA5BgNVBAMMMmNhYmZvcnVtLWFuZC10ZXN0LW9pZC1lZS1j +YWJmb3J1bS1vaWQtaW50LXBhdGgtaW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GfMIGcMAwGA1UdEwQFMAMB +Af8wCwYDVR0PBAQDAgEGMGsGCCsGAQUFBwEBBF8wXTBbBggrBgEFBQcwAYZPaHR0 +cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2NhYmZvcnVtLWFuZC10ZXN0LW9pZC1l +ZS1jYWJmb3J1bS1vaWQtaW50LXBhdGgtaW50LzASBgNVHSAECzAJMAcGBWeBDAEB +MA0GCSqGSIb3DQEBCwUAA4IBAQB/zhtz6FPxar2eL9imF0/5lchKCYPLoHtMkMPo +YPmyfsOODBw0MMTKlzvzYdy4hORU8zQ8JiKJa28GlyIf08fdtaIWPjf+PmNGhMex +pD0KTCfJrmOeDVNwf3lKwM5TrWnH7nNTQ4SfRQCPBR91H6XuwgmuD8vTe1oebuX5 +ziPsjHgKp6qR707qlNQ54JSkTEnY7iLSB8O033Nrzqbz1LtFTX1kGLy0h4F/DKIJ +q2yzixcU5mHwQHKKIiirjy6ZW25Acl5xsTc0Wj9zppbEItd+Jkma2rn4EvHeYAHa +YUDwnsCqVp0WIG4QFhjzJsxoHqCnJek83E/5Av9vZX1JTwMs +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem.certspec new file mode 100644 index 0000000000..92ebdb37fd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:cabforum-and-test-oid-ee-cabforum-oid-int-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-and-test-oid-ee-cabforum-oid-int-path-int/ +extension:certificatePolicies:2.23.140.1.1 diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem new file mode 100644 index 0000000000..51ee5e9861 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIUOXwNT5oauz67TgsKQiAb5GqLxy4wDQYJKoZIhvcNAQEL +BQAwLDEqMCgGA1UEAwwhY2FiZm9ydW0tYW5kLXRlc3Qtb2lkLWVlLXBhdGgtaW50 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCsxKTAnBgNVBAMM +IGNhYmZvcnVtLWFuZC10ZXN0LW9pZC1lZS1wYXRoLWVlMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GoMIGlMFkG +CCsGAQUFBwEBBE0wSzBJBggrBgEFBQcwAYY9aHR0cDovL3d3dy5leGFtcGxlLmNv +bTo4ODg4L2NhYmZvcnVtLWFuZC10ZXN0LW9pZC1lZS1wYXRoLWVlLzAoBgNVHSAE +ITAfMAcGBWeBDAEBMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAVghNl +di10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQCY5y+AbntV59z+ +5tR6RV3Qs1ibjC/83zG3iPXLv6QqTGTB9C93d0i/cN0f2j8QE11TpPUU7pHMmblk +ZDOVLpaZtv26viXCYHJaS7OMhusmVruOJ2AoSBRdX47Z7aZB8vbmGIdSB4p6ESet +eID6Wd73189xakvUAoxFB8+zEZo1pmuTJ11tQlyIDWKz6XDrO0cIHTjF+EAAeKnv +AanOis7N/UwYEau72cErZCAwsih3V3WZ6TIwA3BCt2XmrYKtTEtFMaJNg5pR3feI +e9ZqKKT2UO1YZykFLMEYUkCAUQMUdA13MSWiA2EjnYdVRieI5nHajNhmm8hipgnf +OBEt0Zw4 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem.certspec new file mode 100644 index 0000000000..36f80e017b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:cabforum-and-test-oid-ee-path-int +subject:cabforum-and-test-oid-ee-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-and-test-oid-ee-path-ee/ +extension:certificatePolicies:2.23.140.1.1,1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem new file mode 100644 index 0000000000..7a5a0914d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIUTSLwbOxOBuzeSe9coAOylouA6sEwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCwxKjAoBgNVBAMMIWNhYmZvcnVtLWFuZC10ZXN0LW9pZC1lZS1w +YXRoLWludDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaOBjTCBijAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBa +BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAGGPmh0dHA6Ly93d3cuZXhhbXBsZS5j +b206ODg4OC9jYWJmb3J1bS1hbmQtdGVzdC1vaWQtZWUtcGF0aC1pbnQvMBEGA1Ud +IAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsFAAOCAQEArzFPBw43mrcgEhmCcGAy +1eglq5KnMgtDY4lTYTfVLxrx4tOqQTDoKyMp63o6//KJxhPvEzuD6O4Gq+FMzlVu +MrGcRo78esgIkkp/I77L8YAoSALhmfBIQdiv1bC5xLWkk7MWyvHCUhQ91ZXXAOo9 +7kE/Jah0PqHZQ8GFZ50sJWaO7t1Werxw+H3uX0edUix9BhqUXt3eWxQ7f1rlcueE +poiqEhc4ECG5XVt77GswtIfTvlfXZ0iELV3BtWqgDUxBGNgmHf+k8XtN9uEIB1Lg +wJQ/zclk56ZrquaQLGm2GVIQIHQMHqkZQqWGr0SllsSXq72xX9k9WxHSGXqgfgRH +kQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem.certspec new file mode 100644 index 0000000000..79ae7ae801 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-and-test-oid-ee-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:cabforum-and-test-oid-ee-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-and-test-oid-ee-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem new file mode 100644 index 0000000000..dd103dcb7f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWDCCAkCgAwIBAgIUQzfIanDdubWVWC4810gYEPO4i0swDQYJKoZIhvcNAQEL +BQAwIDEeMBwGA1UEAwwVY2FiZm9ydW0tb2lkLXBhdGgtaW50MCIYDzIwMTkxMTI4 +MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMB8xHTAbBgNVBAMMFGNhYmZvcnVtLW9p +ZC1wYXRoLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABo4GGMIGDME0GCCsGAQUFBwEBBEEwPzA9BggrBgEFBQcw +AYYxaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2NhYmZvcnVtLW9pZC1wYXRo +LWVlLzASBgNVHSAECzAJMAcGBWeBDAEBMB4GA1UdEQQXMBWCE2V2LXRlc3QuZXhh +bXBsZS5jb20wDQYJKoZIhvcNAQELBQADggEBAJ9Md1ZCs0/Hr6gqayb9vBSGdX1i +vT8ufJef6ViOlW0L5RrH7cYU5tIDHIRTFy+KeOhL/CWbL7zVJKofw7RUYskPucwa +ll4SeMGFMT0vDADhec9WLd+F9D8YCVhbWkb+OxeoOs98nlGhrl3ZEVP+aH55DtqF +ufiUsl8cjHY2ye1pxkfv1IlNpjORi+xtsYkkCQvgY1B5KzGg9Fe5wIC8VtyslrR5 +f7EkfSnZjrQYEHNcJTvGojRniDXhKS/AGsyDYFMgUTd/Ur3l9Wn2WfzhyyeAO+vX +6YGyLnghtcx4pvEHaKpkhCoQskjkcGOQhlq3Fq48p12IyFMCQP1LdWnHzZA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem.certspec new file mode 100644 index 0000000000..86fd9aca39 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:cabforum-oid-path-int +subject:cabforum-oid-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-oid-path-ee/ +extension:certificatePolicies:2.23.140.1.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem new file mode 100644 index 0000000000..2476d73cde --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDRTCCAi2gAwIBAgIUHxkuPQNGVMkABbeiiiNkn5pyPdgwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCAxHjAcBgNVBAMMFWNhYmZvcnVtLW9pZC1wYXRoLWludDCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaOBgTB/MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGME4GCCsGAQUFBwEBBEIw +QDA+BggrBgEFBQcwAYYyaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2NhYmZv +cnVtLW9pZC1wYXRoLWludC8wEgYDVR0gBAswCTAHBgVngQwBATANBgkqhkiG9w0B +AQsFAAOCAQEAfOjhFxR9ILmgEhFc0QtS1QxamGbs4aEPLfJpIf//IOMubqpSVr+7 +nS8nL+Fnglx4eeql6+LZNL6NUHY4xGVH9a9+RVZcfsFeJxUI9KCKBPrkD5Xetat4 +GpoYqjKT41UdJq+dLmXAs1YmF7XAVJY4vjYpFUbjML4JKlOw79jO72VRQC7MKl7t +gxGq0/IPB3/zEVGtVdIWU73aFhvJ+2H3L4sFaVY5d9BTfYvOcQtebF3SWaVIDOlw +13OdogmB1kzb2gaLs6tZAXCCtG+mxkd/+mrUXXDCsnfY7IEGf82z5cmEFJorgwEH +uw/YpAPooZCMfvp5BNE6MIi6EYR/nHjCGw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem.certspec new file mode 100644 index 0000000000..343307164b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/cabforum-oid-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:cabforum-oid-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/cabforum-oid-path-int/ +extension:certificatePolicies:2.23.140.1.1 diff --git a/security/manager/ssl/tests/unit/test_ev_certs/evroot.key b/security/manager/ssl/tests/unit/test_ev_certs/evroot.key new file mode 100644 index 0000000000..1d88a930d5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/evroot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC1SYlcnQAQjRGh ++Z+HqePRpdtd+uzxiNpXv2QTaI8s5HIs/xCQOMF0Ask6Kkc9vShq7T/c02PPWikU +dwG92BjXYVv5NWvV08gzaqqMCXE2igbDzURhuT5RQk4XRLsuqtRqqzjOGWghlh+H +cUoWY2k/CXYc301roSXqzse+Jw04j3ifbN94rjFE7SjEXnkpOGOnoipImAo2pA5y +1XnJuSXf+MeTNi/9aJenwXVMXpfJZ8Pq3RquiqLMzjSKAWm4Diii1wwalgxvM18t +oJubZD9av7pJ6Kqpgelg4n2HSAvdVd2UF/oYUJ+7VUzPgaQ5fouoEoo0vfJ4ZcGJ +5XNPsikFAgMBAAECggEBAJg9VPlNb0x26yPW+T14UjUwz3Ow0WJUxueBdo1F9VaB +0dAvsr0qrGq8HDiYYJNcUqDY9BSCAQOUd4MUHYZL/zCANjilwBUlcK6dGPPYyhY+ ++0dbDd3zLn4W7HVl5rteAlxBxcZuV6A87eVUIh+DBFNHosTEUcPc5Ha3h84MBXJE +vp4E7xMRjbuz1eCmzIcCnq/Upp7ZsUdZsV452KmITlb1TS+asBPw0V8xipq2svc9 +HsPJ/idK6JQxoQZAvniZsAEcXlCToYNHCGid4QBjTaveYPvWqu+joz3zSh829gwE +MDa3SNHJ7pjEAxoK/sYO/aCpkL5ST1YU6sT9s0pS+VECgYEA6twssz5f8co3a72V +vWoXd9LPT6xHVF6S0RpiCbnV5N7UeDRYHBabPIhHQqCeoYdQXBylVBTY0ltJdjLV +7CqqBSM0MPrUmJJ3en1o4Dj1YaO4lp5gsKJj3vv9pIqbD/OdlbyIsVJnyK3pe1EH +lI5B5DMknYf32xCdXXRYTYa8wdcCgYEAxZrldqIWRwJI2USlW56b+TKZ2jQexW5V +jrqCGrzhv1e3nPQR0pBMd0+duh8VGF9gewV0oIIF1uwotmo21jQjLqry/qN1Yauv +nWRLaNs4yZZMuMluwKxh66ZNBbRGVC9COXb1rN5OzJVTbS31eJVPk/DP2cWPt4ui +p23VrChNyIMCgYEAwdLvOQYzHFKspkgR+f5CW+somDIvs9tRAyzo1+n8MiQL6SAZ +zySA/NXjKYNxJxGLKlmhv+BsiD46REfz8DHNmuvQuNNo/Hl0DSzOjq2zJN9/CR6v +4VZDYdVJILAbBHEjDl5H2T+O0zljxRe8T8ePbYsfnrqFvM7bcDMCZQjbYoUCgYEA +hSG421aU376ASjFfnvybZSdcVJCs8qNFbWXm5hC/n2R/xnUB1PV3LyMqxwzN75/C +pt+kFcfEG2r8evnQfDygP37ZPAnwuZ8sMEQ0Mi8QcXCbvBuqTJFXX6apWeB9SZaV +bZXiK1eTi25HyNUf/t/Jv4iM4NGj5CtlqJvtS5HT5fUCgYEA3El7BrkgyL4LAHe3 +mOl37vdEqQ7Cxdfmy7IkSPrHLagaMxgODYoC6DFGDH/H/TphL3uZMLYbeZ+OkI5j +LpugQJtqpwsDo7p4dCYmO1vVhD34R27bXRT2qGE+uvW5zVykL1+9KALgjk5J5XCf +UVFRDKpassHG6z7+kpXRbowlyRY= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/evroot.key.keyspec b/security/manager/ssl/tests/unit/test_ev_certs/evroot.key.keyspec new file mode 100644 index 0000000000..1a3d76a550 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/evroot.key.keyspec @@ -0,0 +1 @@ +ev diff --git a/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem b/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem new file mode 100644 index 0000000000..13c3031905 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUIZSHsVgzcvhPgdfrgdMGlpSfMegwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTUwMTAxMDAwMDAwWhgPMjAzNTAx +MDEwMDAwMDBaMBExDzANBgNVBAMMBmV2cm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALVJiVydABCNEaH5n4ep49Gl21367PGI2le/ZBNojyzkciz/ +EJA4wXQCyToqRz29KGrtP9zTY89aKRR3Ab3YGNdhW/k1a9XTyDNqqowJcTaKBsPN +RGG5PlFCThdEuy6q1GqrOM4ZaCGWH4dxShZjaT8JdhzfTWuhJerOx74nDTiPeJ9s +33iuMUTtKMReeSk4Y6eiKkiYCjakDnLVecm5Jd/4x5M2L/1ol6fBdUxel8lnw+rd +Gq6KoszONIoBabgOKKLXDBqWDG8zXy2gm5tkP1q/uknoqqmB6WDifYdIC91V3ZQX ++hhQn7tVTM+BpDl+i6gSijS98nhlwYnlc0+yKQUCAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABTOHA9XbfLv/C7+ +5KycYXToOIBRSjQ0j2nsiqFda4Jx+aKsvdpdrrbLHvhrpfsA3ZgB2+eKHunVc4fo +UHNqZllAs2nx+AEinq4GX8iya5BpiyTIxXWu8v06siGgz1GxlJw1cJ/ZnFEQ9IBf +cCAr5fCoZ4RC+2OVhiSTnYPCKM+zCyw3YpISjNOg1VVkp46Htp+831Eh12YfwvdY +Fgh1fc5ohYC5GCLRuXKc9PGTsr3gp7Y0liYbK7v0RBjd+GivNQ3dS3W+lB3Ow0LH +z/fc3qvrhsd58jHpb1QZQzd9bQjuIIM6Gij7TNdNNarEVZfSJjPYLfXosNdYh5fH +HmbOwao= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem.certspec new file mode 100644 index 0000000000..3121f3486e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/evroot.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:evroot +subjectKey:ev +issuerKey:ev +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_ev_certs/moz.build b/security/manager/ssl/tests/unit/test_ev_certs/moz.build new file mode 100644 index 0000000000..927fadf1d0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/moz.build @@ -0,0 +1,48 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'anyPolicy-ee-path-ee.pem', +# 'anyPolicy-ee-path-int.pem', +# 'anyPolicy-int-path-ee.pem', +# 'anyPolicy-int-path-int.pem', +# 'cabforum-and-test-oid-ee-cabforum-oid-int-path-ee.pem', +# 'cabforum-and-test-oid-ee-cabforum-oid-int-path-int.pem', +# 'cabforum-and-test-oid-ee-path-ee.pem', +# 'cabforum-and-test-oid-ee-path-int.pem', +# 'cabforum-oid-path-ee.pem', +# 'cabforum-oid-path-int.pem', +# 'evroot.pem', +# 'no-ocsp-ee-path-ee.pem', +# 'no-ocsp-ee-path-int.pem', +# 'no-ocsp-int-path-ee.pem', +# 'no-ocsp-int-path-int.pem', +# 'non-ev-root-path-ee.pem', +# 'non-ev-root-path-int.pem', +# 'non-evroot-ca.pem', +# 'reverse-order-oids-path-ee.pem', +# 'reverse-order-oids-path-int.pem', +# 'test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem', +# 'test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem', +# 'test-and-cabforum-oid-ee-path-ee.pem', +# 'test-and-cabforum-oid-ee-path-int.pem', +# 'test-oid-ee-cabforum-oid-int-path-ee.pem', +# 'test-oid-ee-cabforum-oid-int-path-int.pem', +# 'test-oid-path-ee.pem', +# 'test-oid-path-int.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'evroot.key', +# 'test-oid-path-int.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem new file mode 100644 index 0000000000..1eb17e0d4a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEDCCAfigAwIBAgIUEVaHlHZqtF7YUMSMX768HxJ2o6QwDQYJKoZIhvcNAQEL +BQAwHjEcMBoGA1UEAwwTbm8tb2NzcC1lZS1wYXRoLWludDAiGA8yMDE5MTEyODAw +MDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAdMRswGQYDVQQDDBJuby1vY3NwLWVlLXBh +dGgtZWUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAGjQzBBMB8GA1UdIAQYMBYwFAYSKwYBBAHrSYUahRqFGgGDdAkB +MB4GA1UdEQQXMBWCE2V2LXRlc3QuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQAD +ggEBAEOYKTjhumr1vgG+VTbI09KXlkdy40/PKEKx6qqgcPVzJdwv9zcrcC0diJGm +bgReRgaw7CauoL9iY/BaBI+awYfLeQR7+Sasyg3M7QPLHXTAvJYzjYWQrcI2Bq9f +FpF6vGdN3O6OEifA+cdNWMAXQi2KnFdxCrwV1isLFSnonk+2qhmQmGBUCqVzSC+I +09IzhxcZPtWYKPJL0Cfnx4r/+tLt/A+tfhUUcDxT3H6TgfhmN4oeMq01MQ/H/und +ARclew0opuHEUQg1UL5cYJUTO/+rbslcRbwDkJNbw2CN6u2CCtaYEjkZQlQ+rfd8 +5m9OsORT8NhDwyGkCNoqU0eTYPY= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem.certspec new file mode 100644 index 0000000000..ece1cf816f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:no-ocsp-ee-path-int +subject:no-ocsp-ee-path-ee +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem new file mode 100644 index 0000000000..7eea57927f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPzCCAiegAwIBAgIUO1Rn0qhER6ecygoAUilco/BzuwUwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMB4xHDAaBgNVBAMME25vLW9jc3AtZWUtcGF0aC1pbnQwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk +NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC +fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m +CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM +HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m +1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGj +fjB8MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMEwGCCsGAQUFBwEBBEAwPjA8 +BggrBgEFBQcwAYYwaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L25vLW9jc3At +ZWUtcGF0aC1pbnQvMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsFAAOC +AQEAkwxxKtURPe9v3BjIpNuig5QVEf5NXSoxqbScpEK/fumMsegQekfAqomKbmCn +O5B3Qhn146UclkoeKaJJQ+DpWcRDqg9pMkwWbJDd7SpBGqzo34juHR2q7mnBEXQM +jte6jJnV5XTNG0RSaBL523CcSByk0H6AtBI+vqYJlF2Ks7/9S94QD7fW7gvqBDPQ +zXMbO4qXl34sA8rpaDQBjOmwMl0JXtt0/CrbOTkb7GcaNGaoNORKey6MxMQCmVbD +KkMoU98lJwO5PMZkid03vN4ooTNoOFLevyDjP6dGBf3/+x7IASr7NQsdtXdWeSOs +W31qevNBQqgSY/vA2graLBoKGQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem.certspec new file mode 100644 index 0000000000..5eb952a9a7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-ee-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:no-ocsp-ee-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/no-ocsp-ee-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem new file mode 100644 index 0000000000..24c1a97670 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDYjCCAkqgAwIBAgIUU2GeukGa6dcsNWCnTyp5K0jKQO8wDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUbm8tb2NzcC1pbnQtcGF0aC1pbnQwIhgPMjAxOTExMjgw +MDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowHjEcMBoGA1UEAwwTbm8tb2NzcC1pbnQt +cGF0aC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaOBkjCBjzBMBggrBgEFBQcBAQRAMD4wPAYIKwYBBQUHMAGG +MGh0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9uby1vY3NwLWludC1wYXRoLWVl +LzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAVghNl +di10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAYiSEHOmStRPXW +y5vUwnM98/F1YLNse2fC8PSsG3i+74YRVmtCi+A+KSIwVH6bRVSZCAXn0Ie86sQh +UIty2qzWyn/nFrX3KS1N660GsSpvQmtnn31dMGGbEbEoLH5MOm1EPD/ydAdTZc9H ++Jg+0SSlELBTsdOI6mUj84JL4p8piYtIvgVWDUqn3d2Q4qp5m2IWsWJn/x/YrtJ9 +qcTHEYD1B3WGSg6LeUlqWCCmz/2CaYzd0SRSXPqOZpR5RCckoY5f7o1Lev+/yqLK +ExfJrMIg+encVBPvPxIZrNLa+8GT705rVvX4MbKP0tIpTzPv1DimxaKauytRNkgR +sN4lGvFc +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem.certspec new file mode 100644 index 0000000000..623057e9e9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:no-ocsp-int-path-int +subject:no-ocsp-int-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/no-ocsp-int-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem new file mode 100644 index 0000000000..51fbc28ed2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8jCCAdqgAwIBAgIUPy5yIOPguO2ZrWK+N5gQKt6P8vQwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMB8xHTAbBgNVBAMMFG5vLW9jc3AtaW50LXBhdGgtaW50MIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +ozAwLjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjARBgNVHSAECjAIMAYGBFUd +IAAwDQYJKoZIhvcNAQELBQADggEBAHLIQ3h5ckWiymYNqo255k6T/8bIupCPn6Z0 +qVoNmlb3s0XZfTy/64GRCqdRDMMhT80po7IVInalhfrxlBsoG4ASQ1Rc1HI3I1c5 +4umDOTxDrTIiCxJlMFGodb7ZWsrsIO0a9FpDAuuXRkl2wdqEo2UpfJBq3/LPhq4w +Uzv5KUFDo5frBytVJFR+qpnrSEeekORLqszUw5eYy50YegC1qlXca2Vk/m2oQGKC +4yAT+dS7i7WYrZ20aoAngBLrBr0EJuBjjDCpIGM3z41RcT7VOsezfmteGzoRoVBh +GjHgM7gesSuC8oOOr8i9aT1X5MQMhfVo/MdS/UDtLlSt5bCVwQo= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem.certspec new file mode 100644 index 0000000000..548241de3a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/no-ocsp-int-path-int.pem.certspec @@ -0,0 +1,6 @@ +issuer:evroot +subject:no-ocsp-int-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem new file mode 100644 index 0000000000..93139ba9db --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDYjCCAkqgAwIBAgIUd59Z/7YSXGFqK6Mbt0Q0cLiJV94wDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUbm9uLWV2LXJvb3QtcGF0aC1pbnQwIhgPMjAxOTExMjgw +MDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowHjEcMBoGA1UEAwwTbm9uLWV2LXJvb3Qt +cGF0aC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaOBkjCBjzBMBggrBgEFBQcBAQRAMD4wPAYIKwYBBQUHMAGG +MGh0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9ub24tZXYtcm9vdC1wYXRoLWVl +LzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAVghNl +di10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAlsnI1h5nJcbp2 +0qwOoxUZZhmztKVGp5Oy9ae0TbkEgqVYYRTnNSSVd82cULRrMY4p3kEaAwbU7ej7 +YhxsNIBf1f9pRozRIdY/SZv20nh2/r3N6RfjvxHXRcoav9dpEti8kLFsRDaEbxo9 +yxS+9vbEmg9iuVkvMHAd3tZ0lBg5lYFXVk6BKrJF9nqrOiZhl5//0+tUfCenvleJ +ngoB8MLZGR5Y25Vov0rSzj6HM3XLBoV5MIeFcB3n/JcBCXPPFwikQgIHTzInF4+H +UgQOhv7L1nzSrIAZjiGHbD3R4RNwMlkIAlt6nzWse7e2zwBedYjpcFy4qFN3sweU +91MM5I3h +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem.certspec new file mode 100644 index 0000000000..9895732b15 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:non-ev-root-path-int +subject:non-ev-root-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/non-ev-root-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem new file mode 100644 index 0000000000..74e5066cec --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSDCCAjCgAwIBAgIUCa1ByR+IaXRuP5HPyIyTz7ZjGSAwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNbm9uLWV2cm9vdC1jYTAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAfMR0wGwYDVQQDDBRub24tZXYtcm9vdC1wYXRoLWlu +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAAaN/MH0wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwTQYIKwYBBQUH +AQEEQTA/MD0GCCsGAQUFBzABhjFodHRwOi8vd3d3LmV4YW1wbGUuY29tOjg4ODgv +bm9uLWV2LXJvb3QtcGF0aC1pbnQvMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG +9w0BAQsFAAOCAQEAZU5zl2ENgMl0Y+Yvstp/aDqF1s8OTSEQgaYdRd5z5lh2tZKc +vQdj/eH9EuT9ao3HsYFLao79ukbvHBPmtU6snsbO82kf7fFO/LtaGoKYKWnTJVyF +1jOlQ1YCpntdkEdrdgSH1dbxQCqffvPQUxlHUYuhPXM/OyC6ZPuH3409bH7NFE8d +d9FzlOZu7wX+aIttXJUeH+QklPomOp2Ef0aZwj9TMi9yjRdomfD/amYPYKmvpXlN +Vem+Lx3O9sN6zsTcDs3tmY0pQ9GRAWPO9n8wv4drUVyhtF4LU87bShJ66zxW/lN4 +50jdCVPBizdvAbDB1iNVHBiagWX1rL4unY8g5w== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem.certspec new file mode 100644 index 0000000000..5ce035ae1e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-ev-root-path-int.pem.certspec @@ -0,0 +1,6 @@ +issuer:non-evroot-ca +subject:non-ev-root-path-int +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/non-ev-root-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem b/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem new file mode 100644 index 0000000000..c987c4826c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIUGVWjVL2eG3LHefW8SbN9qKKBkR8wDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNbm9uLWV2cm9vdC1jYTAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAYMRYwFAYDVQQDDA1ub24tZXZyb290LWNhMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +ox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AQEAIL1Lg6t9nhLv8OMt5Jupz2pz7r2l+OQOeVklrV4defOgh5GNA6Ib27iqbp3u +WiKHKHwUIjNUCbjYulnDqyQOugU7c3MCq4iy+rJhPECmTkrwTW8D3Rk0HtaABG3I +hlsf3ol+5TWP/84+eu3Re9GELv3ot9j9BGH29lW8wF6K2lw4Q61uXxTS1FZFfBw0 +fXxyQYeKLc/NXnde1I05/vgieogPJa8klb6IOhHgdnfyfFUyTSKRUTuchCNJWlua +cxuMEYDkbusVVN3mNaBanqSuP4o8LnyOXvxUhDIm9I8dpcYD45db+2Et5SwPq1jB +9Bm5lW6mnQkcBeSDAhXs8WjYWA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem.certspec new file mode 100644 index 0000000000..7b61447a80 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/non-evroot-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:non-evroot-ca +subject:non-evroot-ca +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem new file mode 100644 index 0000000000..80720f9856 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIUEXmqqsX9kzkkT1kcgsKRmjz4I3owDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbcmV2ZXJzZS1vcmRlci1vaWRzLXBhdGgtaW50MCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCUxIzAhBgNVBAMMGnJldmVy +c2Utb3JkZXItb2lkcy1wYXRoLWVlMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GiMIGfMFMGCCsGAQUFBwEBBEcw +RTBDBggrBgEFBQcwAYY3aHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L3JldmVy +c2Utb3JkZXItb2lkcy1wYXRoLWVlLzAoBgNVHSAEITAfMAcGBWeBDAEBMBQGEisG +AQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAVghNldi10ZXN0LmV4YW1wbGUuY29t +MA0GCSqGSIb3DQEBCwUAA4IBAQBUE1VSHa5kqgpWz91KR8zawKi+hFSszqXN8bFU +H5WEl7j7W0fCBmpqKTlz6V3HFuphFaE6kDctZ33H8TLVTROPusCxY28dgphJPZQG +LaOwdU0YcdCH20wEXgkoujM/cgnyNkTgBkRG5psvtAvTg28bsOWbqpgxiSaKBo0z +xYPMq+J+schGpK02zLlkbANZQdBYg37jBVFWCTW5/tGS4rPEDC/agn33y6Pvv6mq +XUrxOP0E8sZ3XPnjMBIXRI9NRm6urNMPQsteEHdhDVSo9LXV3d6GmlSW8xoGTmEA +G4HYR1A6+D7PGJDVyvWaGENkGEfJUi7ngfiMEvDTwbQLy08V +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem.certspec new file mode 100644 index 0000000000..31e3e69e53 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:reverse-order-oids-path-int +subject:reverse-order-oids-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/reverse-order-oids-path-ee/ +extension:certificatePolicies:2.23.140.1.1,1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem new file mode 100644 index 0000000000..17ccdcd549 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIUVyTXYnGBHJHjCi2C6eJVXi/iBbUwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCYxJDAiBgNVBAMMG3JldmVyc2Utb3JkZXItb2lkcy1wYXRoLWlu +dDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAAaOBnjCBmzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBUBggrBgEF +BQcBAQRIMEYwRAYIKwYBBQUHMAGGOGh0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4 +OC9yZXZlcnNlLW9yZGVyLW9pZHMtcGF0aC1pbnQvMCgGA1UdIAQhMB8wFAYSKwYB +BAHrSYUahRqFGgGDdAkBMAcGBWeBDAEBMA0GCSqGSIb3DQEBCwUAA4IBAQAWdeBD +aq3w2mJQWpFQLh9ilFWk0wR1wPTEu/G2sJlZiaj3hoQmjtAb2hzuoKorSDSv0z6l +mTrvT1CLztFJmTosimY+aoDolDJ07cqMQ5LrzSRMw48vhzeeyy13DX5uCYUxRK27 +EHAovqpg9AoPBlA0oSEM1FHxxzWmnh3eJRsos6TBIeryzX3U3j9yVkXALprWc26W +DK1SeAZjpALx2rapYRMKIypFmWmyYzOf2Ix5np6QwGCBnQyTvYSK2a8I4f4fGS2R +y+ZSyd1JwVMD7ok6zfG3+KjXRgbAL3UFkT45h/BghBfavAuJbbjzbnUwHzy8NwQh +e0303QOYHHq0vJIh +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem.certspec new file mode 100644 index 0000000000..a2b523073e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/reverse-order-oids-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:reverse-order-oids-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/reverse-order-oids-path-int/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1,2.23.140.1.1 diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem new file mode 100644 index 0000000000..3ef4e6ab5e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDxTCCAq2gAwIBAgIUY4rG8NqK821vmnElwuFYW26zGUEwDQYJKoZIhvcNAQEL +BQAwPTE7MDkGA1UEAwwydGVzdC1hbmQtY2FiZm9ydW0tb2lkLWVlLWNhYmZvcnVt +LW9pZC1pbnQtcGF0aC1pbnQwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowPDE6MDgGA1UEAwwxdGVzdC1hbmQtY2FiZm9ydW0tb2lkLWVlLWNhYmZv +cnVtLW9pZC1pbnQtcGF0aC1lZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab +bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts +Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI +H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8 +rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX +Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaOBuTCBtjBqBggrBgEFBQcBAQReMFww +WgYIKwYBBQUHMAGGTmh0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC90ZXN0LWFu +ZC1jYWJmb3J1bS1vaWQtZWUtY2FiZm9ydW0tb2lkLWludC1wYXRoLWVlLzAoBgNV +HSAEITAfMBQGEisGAQQB60mFGoUahRoBg3QJATAHBgVngQwBATAeBgNVHREEFzAV +ghNldi10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAd+Daw/djP +TluuhjaKDlybSeAF7k3Y7ndQXGkXHnnjyDSzVUsgaqZ5snUkYVLVFV5dG+IsYhhu +hhkXok4nq+6Jc9O08/Uu7kIpjf7Ouv5Z0OZBBojAvcaYDH98bjxxx5Lec0nV+GTP +PTh6BgJosCOTXEan6QzPHOV3xyNuDzrXMVDglyVFvBgOj8AavNUPiqi9lB9gN23w +AjzxSo3i5J0oEYfwUjnPlwI5zQ9yOKG1pnno4lBI7XMhDs5J7BEMt9fz+W5U+/2p +MAUkku6bPT94uOH4Lj6Chu2ppFo+herNAdNO1UznNWOcOkOap+SUQJubPqTwdf8c +BJ4WinbiDmDf +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem.certspec new file mode 100644 index 0000000000..edac2fc1ad --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:test-and-cabforum-oid-ee-cabforum-oid-int-path-int +subject:test-and-cabforum-oid-ee-cabforum-oid-int-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/test-and-cabforum-oid-ee-cabforum-oid-int-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1,2.23.140.1.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem new file mode 100644 index 0000000000..dc2d66256c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDgDCCAmigAwIBAgIUB38LWV7K1ZtRLJtMguF5H4CVwXAwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMD0xOzA5BgNVBAMMMnRlc3QtYW5kLWNhYmZvcnVtLW9pZC1lZS1j +YWJmb3J1bS1vaWQtaW50LXBhdGgtaW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4Ngf +vbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTb +uUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3S +O8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR +3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv +5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GfMIGcMAwGA1UdEwQFMAMB +Af8wCwYDVR0PBAQDAgEGMGsGCCsGAQUFBwEBBF8wXTBbBggrBgEFBQcwAYZPaHR0 +cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L3Rlc3QtYW5kLWNhYmZvcnVtLW9pZC1l +ZS1jYWJmb3J1bS1vaWQtaW50LXBhdGgtaW50LzASBgNVHSAECzAJMAcGBWeBDAEB +MA0GCSqGSIb3DQEBCwUAA4IBAQA2ga4887r55Lcv0LUHtIAd9DqcgqzY59nXDXOX +PnS5gR58r1LF/u/7jPSJ6K3qzON6ug+PDoJhUf1UXBWzXhWusm8Eb5Fxo9OJV521 +GqZVsPdt8c1rnRLlrNi2GsLmywhgAy1w3mAR33laYeuT9PPQokn1W8hnU7hdWEwV +V24CVsAK5YPH/BoSmnxVqG22/ZPbetqRKRzUanuOEOAuDBgPrt7NRm5djMpKyH4D +k3drl+ZM0HFy3zH5XHN+a93E+iWrLy9/+kDq/7/2BBnXFSa7bTq+d/aWFrIXfW57 +Qx0bLWxz1SbqIElXnUKWGwWHoWObMRw7nP6orVKBqefyqRLL +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem.certspec new file mode 100644 index 0000000000..68dfd00573 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-cabforum-oid-int-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:test-and-cabforum-oid-ee-cabforum-oid-int-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/test-and-cabforum-oid-ee-cabforum-oid-int-path-int/ +extension:certificatePolicies:2.23.140.1.1 diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem new file mode 100644 index 0000000000..6c746a4773 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkjCCAnqgAwIBAgIUTezLjnCdM9De3GXzBHXuGsNnVKowDQYJKoZIhvcNAQEL +BQAwLDEqMCgGA1UEAwwhdGVzdC1hbmQtY2FiZm9ydW0tb2lkLWVlLXBhdGgtaW50 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCsxKTAnBgNVBAMM +IHRlc3QtYW5kLWNhYmZvcnVtLW9pZC1lZS1wYXRoLWVlMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GoMIGlMFkG +CCsGAQUFBwEBBE0wSzBJBggrBgEFBQcwAYY9aHR0cDovL3d3dy5leGFtcGxlLmNv +bTo4ODg4L3Rlc3QtYW5kLWNhYmZvcnVtLW9pZC1lZS1wYXRoLWVlLzAoBgNVHSAE +ITAfMBQGEisGAQQB60mFGoUahRoBg3QJATAHBgVngQwBATAeBgNVHREEFzAVghNl +di10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQAYzsZA6rEPjGaO +3B9F7YLtYBFxtstq1++z+MRuLFXsXnaGgS65bP8C+phNNQQUYcTzjp/+nbA2HIVL +OOtf0Z0Ciqxb6ALXhuHnPYX8pSby7afY1I4NAOuEKA844TZ2hwf6hGxMGFYC1Khv ++k0iFMLLzYA0gvVRMnhRvhoPqVQL0CxO0TRiYpf0pmPPiTkop37eNbaHorEAnCtf +gZpfbDiYgh9USBGcfehKmwXjNRM0M+uVUdcsdzOwTHMeAUV5teRtf82D3j3moWhg +HUjGRNpVDZjSp+Wn7psAWtKLETJhmfWPu5/b6X91+N2L20oWYk4ONCEsKezqDMxS +Z5Ix+EJT +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem.certspec new file mode 100644 index 0000000000..affbd87458 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:test-and-cabforum-oid-ee-path-int +subject:test-and-cabforum-oid-ee-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/test-and-cabforum-oid-ee-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1,2.23.140.1.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem new file mode 100644 index 0000000000..3579205224 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDXTCCAkWgAwIBAgIUIQbkixAb+1Y/Mab1Sh8NPYs0GLgwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCwxKjAoBgNVBAMMIXRlc3QtYW5kLWNhYmZvcnVtLW9pZC1lZS1w +YXRoLWludDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaOBjTCBijAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBa +BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAGGPmh0dHA6Ly93d3cuZXhhbXBsZS5j +b206ODg4OC90ZXN0LWFuZC1jYWJmb3J1bS1vaWQtZWUtcGF0aC1pbnQvMBEGA1Ud +IAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQsFAAOCAQEAk6yOHhUbvCaulXNXvAUc +X97+o1CkeFk1QCavnZUURyGZQlGppyKXU+RuEITsiGbYU/eqOrTGsxmdbLQ3QsPc +hjiToDnXD7Bt7Nr98PDUFmIdh2sd++Wcjo9qjxoKrmxVvpxo8bdIRY3gVQaI/3Wy +Hz+/iBKYKO07b3ql3cApqnnl+DEi4KFIfHOca4iBricDWWUBuJUmhwIiKqxsP/yv +Y96xgMmO2/zVBG9bAwpbqnqygKoiaxZDEpFR7/4w0CKkgS85k6fVsE1Ozz8K8BZZ +xuLfgn9A6I4qjfCxCGfH9Gojh61BwlHIUIJ8Rjbpn5kt7E9V3WMGTcopQISRoKEN +vg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem.certspec new file mode 100644 index 0000000000..11630b4b4f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-and-cabforum-oid-ee-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:test-and-cabforum-oid-ee-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/test-and-cabforum-oid-ee-path-int/ +extension:certificatePolicies:any diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem new file mode 100644 index 0000000000..fa64ee0636 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDlTCCAn2gAwIBAgIUV330em+9Xec1DGZ4wJhdv0RjswMwDQYJKoZIhvcNAQEL +BQAwMDEuMCwGA1UEAwwldGVzdC1vaWQtZWUtY2FiZm9ydW0tb2lkLWludC1wYXRo +LWludDAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAvMS0wKwYD +VQQDDCR0ZXN0LW9pZC1lZS1jYWJmb3J1bS1vaWQtaW50LXBhdGgtZWUwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk +NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC +fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m +CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM +HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m +1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGj +gaMwgaAwXQYIKwYBBQUHAQEEUTBPME0GCCsGAQUFBzABhkFodHRwOi8vd3d3LmV4 +YW1wbGUuY29tOjg4ODgvdGVzdC1vaWQtZWUtY2FiZm9ydW0tb2lkLWludC1wYXRo +LWVlLzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAV +ghNldi10ZXN0LmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQCh1PqRvUqb +ZLTd7bxaQ//insQtmlqcflBQkPEkFLkyiyKOuBIeO5B+sgr2l8GsUfrVhqd6e2Xe +qL/6+RNlLGm5tKaTLgmXo9iG/oADW8WKyf6oCXuFMU7AiZH6cS4//ewcWdZxO7xz +vRfu5M6TDJMMEFk71wQSzx163/aidZ3u6tcPC+PSkCVD8vzQcJPBKcF+/hFyVOPT +PJgF/NvUY3CBykH54zm12SEFh+iOkrbQRlazlJfUTXX+dGD3iohZ+KlpQUZ8Yibk +OzHbgM5rggesRSvcu7Ud5e42XDdTq+gDVVbwEmYer6+h+qdT4WJ6bF3qNt7gKKf/ +FqqTAPIlcQFx +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem.certspec new file mode 100644 index 0000000000..bd0f955ada --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:test-oid-ee-cabforum-oid-int-path-int +subject:test-oid-ee-cabforum-oid-int-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/test-oid-ee-cabforum-oid-int-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem new file mode 100644 index 0000000000..a2c85f5efc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZjCCAk6gAwIBAgIUacgXv3Tmh0nRe3yh82VGGbTiqtkwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMDAxLjAsBgNVBAMMJXRlc3Qtb2lkLWVlLWNhYmZvcnVtLW9pZC1p +bnQtcGF0aC1pbnQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjgZIwgY8wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMC +AQYwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzABhkJodHRwOi8vd3d3LmV4YW1w +bGUuY29tOjg4ODgvdGVzdC1vaWQtZWUtY2FiZm9ydW0tb2lkLWludC1wYXRoLWlu +dC8wEgYDVR0gBAswCTAHBgVngQwBATANBgkqhkiG9w0BAQsFAAOCAQEAFRoD650v +OtuTmJQO9NepvUZl8M3FqcQhrzl5u1qH9fKhpWaK2oXCsxirquCTitnFvIHwRARW +2UUgGgngwKDVJ+c7ohRudQIrBaS4utKpIv6ljZQ/oF6W0Z+4SSkbv3wj1Aw0ThbQ +am4Jhpf7KsxSwwrFwXn+8vCWahQvk31vZTw0S9EGdEL9P8xyor/pcG4RDB7+WYDP +dHNdexGSYrnQINgQthPUSHfWJPI44CxyyACgpsu7zqd8UZ3BSP51wJARWBky5xhs +RoVs9yVmXeah7ejpFSdI+fAS9ZAfHs0owrD+fEa2+2jdhpPEyay5DdLsGn/mMJ+Q +K54zhyttXeyMtQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem.certspec new file mode 100644 index 0000000000..37d4d133a1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-ee-cabforum-oid-int-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:test-oid-ee-cabforum-oid-int-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/test-oid-ee-cabforum-oid-int-path-int/ +extension:certificatePolicies:2.23.140.1.1 diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem new file mode 100644 index 0000000000..6d9acef5b1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWTCCAkGgAwIBAgIUZWC2u4FJNGtmdv2n5Yk6Q7xQ8OQwDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRdGVzdC1vaWQtcGF0aC1pbnQwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowGzEZMBcGA1UEAwwQdGVzdC1vaWQtcGF0aC1l +ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAAaOBjzCBjDBJBggrBgEFBQcBAQQ9MDswOQYIKwYBBQUHMAGGLWh0dHA6 +Ly93d3cuZXhhbXBsZS5jb206ODg4OC90ZXN0LW9pZC1wYXRoLWVlLzAfBgNVHSAE +GDAWMBQGEisGAQQB60mFGoUahRoBg3QJATAeBgNVHREEFzAVghNldi10ZXN0LmV4 +YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IBAQB3iZ8RGk7s3jwZY1cgJyJfjWIb +A6DpKtL6KcvL/lcAF2VbrTdAHkEQ7TbSmDMZM484hRxckG7gs2C7rb+lUTDNk4JS +WGm+WhTGd98DDM2ZIY3UPrGEKycqfrFqdjaJhMwd/BcgQgw5DgHUWlfKO1utSDLh +vv212o2uzldYaGnVgyr6QK+kzpm+zLuveSxmiZSw3PE1+fZ8+yS5Ku6bo5yfdSg+ +jC9j6BZDiaf6B73offVyNlOMqD6LHczWENKCl7bCeLkH9OEl2eF7KMf3SL17b+fw +QXvNBwHcKkEd1ElqyZOadUtAtRvaF0bWjOJ5QirH3czhPaq4XZJI8KVQyeWz +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem.certspec new file mode 100644 index 0000000000..a9d62c65e9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-ee.pem.certspec @@ -0,0 +1,5 @@ +issuer:test-oid-path-int +subject:test-oid-path-ee +extension:authorityInformationAccess:http://www.example.com:8888/test-oid-path-ee/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 +extension:subjectAlternativeName:ev-test.example.com diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key.keyspec b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem new file mode 100644 index 0000000000..2be083fca1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIUEcfv2VQb1qigZ7waPro3Nb2Ury8wDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMBwxGjAYBgNVBAMMEXRlc3Qtb2lkLXBhdGgtaW50MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVK +tOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7N +Q/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39Zgsr +sCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxs +l62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYl +nauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GL +MIGIMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMEoGCCsGAQUFBwEBBD4wPDA6 +BggrBgEFBQcwAYYuaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L3Rlc3Qtb2lk +LXBhdGgtaW50LzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoBg3QJATANBgkq +hkiG9w0BAQsFAAOCAQEAJCZU0IPgdXwzNObNGVAa5SRNx3J9CZ9j6++cfitpaYc9 +sG6mdyyAjUbumaIgo84aH6dER+FxICt124AkAWFNPZtL+RVBV6/Y54KXSYKViXGl +DRWOYqrbF+RGELQr5OW2kTr/u1Fsd7DWBjPBRvxLHzgSXvu3+knjXo9Mfsw+tpkH +av8FGvxHvrj1Ad4tBXPL2MvwfT/KNtDLDVpWbkUW7sHhcEiVlitD6JONopiAmPEU +8yNUERTw2eTDO16UMmh205wI4Z2f4SnZqrsueCQv86Nr5i12V6TWiipVvNKJLjQU +UiBVkuFLI6o/rZMjJwgJrYgeeBmJa3E1Xa4cXf3Ehw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem.certspec b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem.certspec new file mode 100644 index 0000000000..53534eb526 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ev_certs/test-oid-path-int.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:test-oid-path-int +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/test-oid-path-int/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_forget_about_site_security_headers.js b/security/manager/ssl/tests/unit/test_forget_about_site_security_headers.js new file mode 100644 index 0000000000..cf697d94e7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_forget_about_site_security_headers.js @@ -0,0 +1,205 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=2 ts=2 sts=2 + * 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/. */ + +"use strict"; + +// Ensures that HSTS (HTTP Strict Transport Security) information is cleared +// when using "Forget About This Site". + +const { ForgetAboutSite } = ChromeUtils.import( + "resource://gre/modules/ForgetAboutSite.jsm" +); + +do_get_profile(); // must be done before instantiating nsIX509CertDB + +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.cert_pinning.enforcement_level"); +}); + +const GOOD_MAX_AGE_SECONDS = 69403; +const GOOD_MAX_AGE = `max-age=${GOOD_MAX_AGE_SECONDS};`; + +const sss = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService +); +const uri = Services.io.newURI("https://a.pinning.example.com"); + +function add_tests() { + let secInfo = null; + + add_connection_test( + "a.pinning.example.com", + PRErrorCodeSuccess, + undefined, + aSecInfo => { + secInfo = aSecInfo; + } + ); + + // Test the normal case of processing HSTS headers for a.pinning.example.com, + // using "Forget About Site" on a.pinning2.example.com, and then checking + // that the platform doesn't consider a.pinning.example.com to be HSTS any + // longer. + add_task(async function() { + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + GOOD_MAX_AGE, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + + Assert.ok( + sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "a.pinning.example.com should be HSTS" + ); + + await ForgetAboutSite.removeDataFromDomain("a.pinning.example.com"); + + Assert.ok( + !sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "a.pinning.example.com should not be HSTS now" + ); + }); + + // Test the case of processing HSTS headers for a.pinning.example.com, using + // "Forget About Site" on example.com, and then checking that the platform + // doesn't consider the subdomain to be HSTS any longer. Also test that + // unrelated sites don't also get removed. + add_task(async function() { + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + GOOD_MAX_AGE, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + + Assert.ok( + sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "a.pinning.example.com should be HSTS (subdomain case)" + ); + + // Add an unrelated site to HSTS. + let unrelatedURI = Services.io.newURI("https://example.org"); + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + unrelatedURI, + GOOD_MAX_AGE, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + Assert.ok( + sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, unrelatedURI, 0), + "example.org should be HSTS" + ); + + await ForgetAboutSite.removeDataFromDomain("example.com"); + + Assert.ok( + !sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "a.pinning.example.com should not be HSTS now (subdomain case)" + ); + + Assert.ok( + sss.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, unrelatedURI, 0), + "example.org should still be HSTS" + ); + }); + + // Test the case of processing HSTS headers for a.pinning.example.com with + // various originAttributes, using "Forget About Site" on example.com, and + // then checking that the platform doesn't consider the subdomain to be HSTS + // for any originAttributes any longer. Also test that unrelated sites don't + // also get removed. + add_task(async function() { + let originAttributesList = [ + {}, + { userContextId: 1 }, + { firstPartyDomain: "foo.com" }, + { userContextId: 1, firstPartyDomain: "foo.com" }, + ]; + + let unrelatedURI = Services.io.newURI("https://example.org"); + + for (let originAttributes of originAttributesList) { + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + GOOD_MAX_AGE, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, + originAttributes + ); + + Assert.ok( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes + ), + "a.pinning.example.com should be HSTS (originAttributes case)" + ); + + // Add an unrelated site to HSTS. + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + unrelatedURI, + GOOD_MAX_AGE, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, + originAttributes + ); + Assert.ok( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + unrelatedURI, + 0, + originAttributes + ), + "example.org should be HSTS (originAttributes case)" + ); + } + + await ForgetAboutSite.removeDataFromDomain("example.com"); + + for (let originAttributes of originAttributesList) { + Assert.ok( + !sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes + ), + "a.pinning.example.com should not be HSTS now " + + "(originAttributes case)" + ); + + Assert.ok( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + unrelatedURI, + 0, + originAttributes + ), + "example.org should still be HSTS (originAttributes case)" + ); + } + }); +} + +function run_test() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + add_tests(); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_hash_algorithms.js b/security/manager/ssl/tests/unit/test_hash_algorithms.js new file mode 100644 index 0000000000..ccdaf831e3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_hash_algorithms.js @@ -0,0 +1,158 @@ +"use strict"; + +// This file tests various aspects of the nsICryptoHash implementation for all +// of the supported algorithms. + +const messages = ["The quick brown fox jumps over the lazy dog", ""]; +const ALGORITHMS = [ + { + initString: "md5", + initConstant: Ci.nsICryptoHash.MD5, + hexHashes: [ + "9e107d9d372bb6826bd81d3542a419d6", + "d41d8cd98f00b204e9800998ecf8427e", + ], + b64Hashes: ["nhB9nTcrtoJr2B01QqQZ1g==", "1B2M2Y8AsgTpgAmY7PhCfg=="], + }, + { + initString: "sha1", + initConstant: Ci.nsICryptoHash.SHA1, + hexHashes: [ + "2fd4e1c67a2d28fced849ee1bb76e7391b93eb12", + "da39a3ee5e6b4b0d3255bfef95601890afd80709", + ], + b64Hashes: ["L9ThxnotKPzthJ7hu3bnORuT6xI=", "2jmj7l5rSw0yVb/vlWAYkK/YBwk="], + }, + { + initString: "sha256", + initConstant: Ci.nsICryptoHash.SHA256, + hexHashes: [ + "d7a8fbb307d7809469ca9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592", + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + ], + b64Hashes: [ + "16j7swfXgJRpypq8sAguT41WUeRtPNt2LQLQvzfJ5ZI=", + "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=", + ], + }, + { + initString: "sha384", + initConstant: Ci.nsICryptoHash.SHA384, + hexHashes: [ + "ca737f1014a48f4c0b6dd43cb177b0afd9e5169367544c494011e3317dbf9a509cb1e5dc1e85a941bbee3d7f2afbc9b1", + "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", + ], + b64Hashes: [ + "ynN/EBSkj0wLbdQ8sXewr9nlFpNnVExJQBHjMX2/mlCcseXcHoWpQbvuPX8q+8mx", + "OLBgp1GsljhM2TJ+sbHjaiH9txEUvgdDTAzHv2P24donTt6/529l+9Ua0vFImLlb", + ], + }, + { + initString: "sha512", + initConstant: Ci.nsICryptoHash.SHA512, + hexHashes: [ + "07e547d9586f6a73f73fbac0435ed76951218fb7d0c8d788a309d785436bbb642e93a252a954f23912547d1e8a3b5ed6e1bfd7097821233fa0538f3db854fee6", + "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", + ], + b64Hashes: [ + "B+VH2VhvanP3P7rAQ17XaVEhj7fQyNeIownXhUNru2Quk6JSqVTyORJUfR6KO17W4b/XCXghIz+gU489uFT+5g==", + "z4PhNX7vuL3xVChQ1m2AB9Yg5AULVxXcg/SpIdNs6c5H0NE8XYXysP+DGNKHfuwvY7kxvUdBeoGlODJ6+SfaPg==", + ], + }, +]; + +function doHash(algo, value, cmp) { + let hash = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hash.initWithString(algo); + + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "utf8"; + value = converter.convertToByteArray(value); + hash.update(value, value.length); + equal( + hexify(hash.finish(false)), + cmp, + `Actual and expected hash for ${algo} should match` + ); + + hash.initWithString(algo); + hash.update(value, value.length); + equal( + hexify(hash.finish(false)), + cmp, + `Actual and expected hash for ${algo} should match after re-init` + ); +} + +function doHashStream(algo, value, cmp) { + // TODO(Bug 459835): Make updateFromStream() accept zero length streams. + if (value.length == 0) { + return; + } + + let hash = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hash.initWithString(algo); + + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "utf8"; + let stream = converter.convertToInputStream(value); + hash.updateFromStream(stream, stream.available()); + equal( + hexify(hash.finish(false)), + cmp, + `Actual and expected hash for ${algo} should match updating from stream` + ); +} + +function testInitConstantAndBase64( + initConstant, + algoName, + message, + expectedOutput +) { + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "utf8"; + let value = converter.convertToByteArray(message); + + let hash = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hash.init(initConstant); + hash.update(value, value.length); + equal( + hash.finish(true), + expectedOutput, + `Actual and expected base64 hash for ${algoName} should match` + ); +} + +function run_test() { + for (let algo of ALGORITHMS) { + algo.hexHashes.forEach((hash, i) => { + doHash(algo.initString, messages[i], hash); + doHashStream(algo.initString, messages[i], hash); + }); + algo.b64Hashes.forEach((hash, i) => { + testInitConstantAndBase64( + algo.initConstant, + algo.initString, + messages[i], + hash + ); + }); + } + + // Our buffer size for working with streams is 4096 bytes. This tests we + // handle larger inputs. + doHashStream("md5", " ".repeat(4100), "59f337d82f9ef5c9571bec4d78d66641"); +} diff --git a/security/manager/ssl/tests/unit/test_hash_algorithms_wrap.js b/security/manager/ssl/tests/unit/test_hash_algorithms_wrap.js new file mode 100644 index 0000000000..f2b7016c05 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_hash_algorithms_wrap.js @@ -0,0 +1,5 @@ +"use strict"; + +function run_test() { + run_test_in_child("test_hash_algorithms.js"); +} diff --git a/security/manager/ssl/tests/unit/test_hmac.js b/security/manager/ssl/tests/unit/test_hmac.js new file mode 100644 index 0000000000..8bb6139133 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_hmac.js @@ -0,0 +1,157 @@ +"use strict"; + +// This file tests various aspects of the nsICryptoHMAC implementation for all +// of the supported algorithms. + +function getHMAC(data, key, alg, returnBase64) { + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "utf8"; + let dataArray = converter.convertToByteArray(data); + + let keyObject = Cc["@mozilla.org/security/keyobjectfactory;1"] + .getService(Ci.nsIKeyObjectFactory) + .keyFromString(Ci.nsIKeyObject.HMAC, key); + + let cryptoHMAC = Cc["@mozilla.org/security/hmac;1"].createInstance( + Ci.nsICryptoHMAC + ); + + cryptoHMAC.init(alg, keyObject); + cryptoHMAC.update(dataArray, dataArray.length); + let digest1 = cryptoHMAC.finish(returnBase64); + + cryptoHMAC.reset(); + cryptoHMAC.update(dataArray, dataArray.length); + let digest2 = cryptoHMAC.finish(returnBase64); + + let stream = converter.convertToInputStream(data); + cryptoHMAC.reset(); + cryptoHMAC.updateFromStream(stream, stream.available()); + let digestFromStream = cryptoHMAC.finish(returnBase64); + + equal( + digest1, + digest2, + "Initial digest and digest after calling reset() should match" + ); + + equal( + digest1, + digestFromStream, + "Digest from buffer and digest from stream should match" + ); + + return digest1; +} + +function testHMAC(alg) { + const key1 = "MyKey_ABCDEFGHIJKLMN"; + const key2 = "MyKey_01234567890123"; + + const dataA = "Secret message"; + const dataB = "Secres message"; + + let digest1a = getHMAC(key1, dataA, alg, false); + let digest2 = getHMAC(key2, dataA, alg, false); + let digest1b = getHMAC(key1, dataA, alg, false); + + equal( + digest1a, + digest1b, + "The digests for the same key, data and algorithm should match" + ); + notEqual( + digest1a, + digest2, + "The digests for different keys should not match" + ); + + let digest1 = getHMAC(key1, dataA, alg, false); + digest2 = getHMAC(key1, dataB, alg, false); + + notEqual(digest1, digest2, "The digests for different data should not match"); +} + +function testVectors() { + const keyTestVector = "Jefe"; + const dataTestVector = "what do ya want for nothing?"; + + // The base 64 values aren't in either of the RFCs below; they were just + // calculated using the hex vectors. + const vectors = [ + // RFC 2202 section 2 test case 2. + { + algoID: Ci.nsICryptoHMAC.MD5, + algoName: "MD5", + expectedDigest: "750c783e6ab0b503eaa86e310a5db738", + expectedBase64: "dQx4PmqwtQPqqG4xCl23OA==", + }, + // RFC 2202 section 2 test case 3. + { + algoID: Ci.nsICryptoHMAC.SHA1, + algoName: "SHA-1", + expectedDigest: "effcdf6ae5eb2fa2d27416d5f184df9c259a7c79", + expectedBase64: "7/zfauXrL6LSdBbV8YTfnCWafHk=", + }, + // RFC 4231 section 4.3. + { + algoID: Ci.nsICryptoHMAC.SHA256, + algoName: "SHA-256", + expectedDigest: + "5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843", + expectedBase64: "W9zBRr9gdU5qBCQmCJV1x1oAPwidJzmDnexYuWTsOEM=", + }, + { + algoID: Ci.nsICryptoHMAC.SHA384, + algoName: "SHA-384", + expectedDigest: + "af45d2e376484031617f78d2b58a6b1b9c7ef464f5a01b47e42ec3736322445e8e2240ca5e69e2c78b3239ecfab21649", + expectedBase64: + "r0XS43ZIQDFhf3jStYprG5x+9GT1oBtH5C7Dc2MiRF6OIkDKXmnix4syOez6shZJ", + }, + { + algoID: Ci.nsICryptoHMAC.SHA512, + algoName: "SHA-512", + expectedDigest: + "164b7a7bfcf819e2e395fbe73b56e0a387bd64222e831fd610270cd7ea2505549758bf75c05a994a6d034f65f8f0e6fdcaeab1a34d4a6b4b636e070a38bce737", + expectedBase64: + "Fkt6e/z4GeLjlfvnO1bgo4e9ZCIugx/WECcM1+olBVSXWL91wFqZSm0DT2X48Ob9yuqxo01Ka0tjbgcKOLznNw==", + }, + ]; + + for (let vector of vectors) { + let digest = getHMAC(dataTestVector, keyTestVector, vector.algoID, false); + equal( + hexify(digest), + vector.expectedDigest, + `Actual and expected ${vector.algoName} digests should match` + ); + let b64Digest = getHMAC(dataTestVector, keyTestVector, vector.algoID, true); + equal( + b64Digest, + vector.expectedBase64, + `Actual and expected ${vector.algoName} base64 digest should match` + ); + } +} + +function run_test() { + testVectors(); + + testHMAC(Ci.nsICryptoHMAC.MD5); + testHMAC(Ci.nsICryptoHMAC.SHA1); + testHMAC(Ci.nsICryptoHMAC.SHA256); + testHMAC(Ci.nsICryptoHMAC.SHA384); + testHMAC(Ci.nsICryptoHMAC.SHA512); + + // Our buffer size for working with streams is 4096 bytes. This tests we + // handle larger inputs. + let digest = getHMAC(" ".repeat(4100), "test", Ci.nsICryptoHMAC.MD5, false); + equal( + hexify(digest), + "befbc875f73a088cf04e77f2b1286010", + "Actual and expected digest for large stream should match" + ); +} diff --git a/security/manager/ssl/tests/unit/test_imminent_distrust.js b/security/manager/ssl/tests/unit/test_imminent_distrust.js new file mode 100644 index 0000000000..861269e784 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_imminent_distrust.js @@ -0,0 +1,39 @@ +/* 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/. */ +"use strict"; + +// Tests handling of certificates that are selected to emit a distrust warning +// to the console. + +function shouldBeImminentlyDistrusted(aTransportSecurityInfo) { + let isDistrust = + aTransportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_DISTRUST_IMMINENT; + Assert.ok(isDistrust, "This host should be imminently distrusted"); +} + +function shouldNotBeImminentlyDistrusted(aTransportSecurityInfo) { + let isDistrust = + aTransportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_DISTRUST_IMMINENT; + Assert.ok(!isDistrust, "This host should not be imminently distrusted"); +} + +do_get_profile(); + +add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + +add_connection_test( + "imminently-distrusted.example.com", + PRErrorCodeSuccess, + null, + shouldBeImminentlyDistrusted +); + +add_connection_test( + "include-subdomains.pinning.example.com", + PRErrorCodeSuccess, + null, + shouldNotBeImminentlyDistrusted +); diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js new file mode 100644 index 0000000000..5bb4b1cecb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints.js @@ -0,0 +1,138 @@ +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function load_cert(name, trust) { + let filename = "test_intermediate_basic_usage_constraints/" + name + ".pem"; + addCertFromFile(certdb, filename, trust); +} + +function test_cert_for_usages(certChainNicks, expected_usages) { + let certs = []; + for (let i in certChainNicks) { + let certNick = certChainNicks[i]; + let certPEM = readFile( + do_get_file( + "test_intermediate_basic_usage_constraints/" + certNick + ".pem" + ), + false + ); + certs.push(certdb.constructX509FromBase64(pemToBase64(certPEM))); + } + + let cert = certs[0]; + return asyncTestCertificateUsages(certdb, cert, expected_usages); +} + +add_task(async function() { + let ee_usages = [ + certificateUsageSSLClient, + certificateUsageSSLServer, + certificateUsageEmailSigner, + certificateUsageEmailRecipient, + ]; + let ca_usages = [certificateUsageSSLCA]; + let eku_usages = [certificateUsageSSLClient, certificateUsageSSLServer]; + + // Load the ca into mem + let ca_name = "ca"; + load_cert(ca_name, "CTu,CTu,CTu"); + await test_cert_for_usages([ca_name], ca_usages); + + // A certificate with no basicConstraints extension is considered an EE. + await test_cert_for_usages(["int-no-extensions"], ee_usages); + + // int-no-extensions is an EE (see previous case), so no certs can chain to + // it. + await test_cert_for_usages(["ee-int-no-extensions", "int-no-extensions"], []); + + // a certificate with basicConstraints.cA==false is considered an EE. + await test_cert_for_usages(["int-not-a-ca"], ee_usages); + + // int-not-a-ca is an EE (see previous case), so no certs can chain to it. + await test_cert_for_usages(["ee-int-not-a-ca", "int-not-a-ca"], []); + + // a certificate with basicConstraints.cA==false but with the keyCertSign + // key usage may not act as a CA (it can act like an end-entity). + await test_cert_for_usages(["int-cA-FALSE-asserts-keyCertSign"], ee_usages); + await test_cert_for_usages( + ["ee-int-cA-FALSE-asserts-keyCertSign", "int-cA-FALSE-asserts-keyCertSign"], + [] + ); + + // int-limited-depth has cA==true and a path length constraint of zero. + await test_cert_for_usages(["int-limited-depth"], ca_usages); + + // path length constraints do not affect the ability of a non-CA cert to + // chain to to the CA cert. + await test_cert_for_usages( + ["ee-int-limited-depth", "int-limited-depth"], + ee_usages + ); + + // ca + // int-limited-depth (cA==true, pathLenConstraint==0) + // int-limited-depth-invalid (cA==true) + // + await test_cert_for_usages( + ["int-limited-depth-invalid", "int-limited-depth"], + [] + ); + await test_cert_for_usages( + [ + "ee-int-limited-depth-invalid", + "int-limited-depth-invalid", + "int-limited-depth", + ], + [] + ); + + // int-valid-ku-no-eku has keyCertSign + await test_cert_for_usages(["int-valid-ku-no-eku"], ca_usages); + await test_cert_for_usages( + ["ee-int-valid-ku-no-eku", "int-valid-ku-no-eku"], + ee_usages + ); + + // int-bad-ku-no-eku has basicConstraints.cA==true and has a KU extension + // but the KU extension is missing keyCertSign. Note that mozilla::pkix + // doesn't validate certificates with basicConstraints.Ca==true for non-CA + // uses. + await test_cert_for_usages(["int-bad-ku-no-eku"], []); + await test_cert_for_usages(["ee-int-bad-ku-no-eku", "int-bad-ku-no-eku"], []); + + // int-no-ku-no-eku has basicConstraints.cA==true and no KU extension. + // We treat a missing KU as "any key usage is OK". + await test_cert_for_usages(["int-no-ku-no-eku"], ca_usages); + await test_cert_for_usages( + ["ee-int-no-ku-no-eku", "int-no-ku-no-eku"], + ee_usages + ); + + // int-valid-ku-server-eku has basicConstraints.cA==true, keyCertSign in KU, + // and EKU=={id-kp-serverAuth,id-kp-clientAuth}. + await test_cert_for_usages(["int-valid-ku-server-eku"], ca_usages); + await test_cert_for_usages( + ["ee-int-valid-ku-server-eku", "int-valid-ku-server-eku"], + eku_usages + ); + + // int-bad-ku-server-eku has basicConstraints.cA==true, a KU without + // keyCertSign, and EKU=={id-kp-serverAuth,id-kp-clientAuth}. + await test_cert_for_usages(["int-bad-ku-server-eku"], []); + await test_cert_for_usages( + ["ee-int-bad-ku-server-eku", "int-bad-ku-server-eku"], + [] + ); + + // int-bad-ku-server-eku has basicConstraints.cA==true, no KU, and + // EKU=={id-kp-serverAuth,id-kp-clientAuth}. + await test_cert_for_usages(["int-no-ku-server-eku"], ca_usages); + await test_cert_for_usages( + ["ee-int-no-ku-server-eku", "int-no-ku-server-eku"], + eku_usages + ); +}); diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem new file mode 100644 index 0000000000..a42c7532c4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICvDCCAaSgAwIBAgIUPbAn5aKDD+kIa7hReaL37pIRoqQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEDAOMAwGA1UdEwQFMAMBAf8wDQYJ +KoZIhvcNAQELBQADggEBAByxcmVDqkg7zc2gVsSg2E+gTXDjMWp/DvVlbjOQoek1 +eRR6SmEEYQ8yYC4FMemiy2b1BXHkbcu4RlKJ/sr5n3qd+eKF1hSiekl8IAVO46lk +I22qHCs3eRPkhSTXKfUqR8mOqLAMHNwmZ+4/S5xqrnSpq3+8q9o0a/A+osy1aj4K +JNA+/Ey9HyxjOwTeq44JiMWbotqFAtrr4yQO8BVh6Kdskcp81UtRbm2gRjXtbIjO +FSREK358HkIkcOYNT/qNgijwyJpQiWBUJ99dv3dgVXQpm+acsIgjQ8axT6Np+3+0 +f/kIT6Xl/umiMes/Q6auaRjdQMtok9nPTPFtWB0AlsM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem.certspec new file mode 100644 index 0000000000..eb7c4b4bee --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem new file mode 100644 index 0000000000..b78901e441 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5zCCAc+gAwIBAgIUJb+8nRpsie/LSW/e1iNkPRuYeGswDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRaW50LWJhZC1rdS1uby1la3UwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowHzEdMBsGA1UEAwwUZWUtaW50LWJhZC1rdS1u +by1la3UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgP4MA0GCSqGSIb3 +DQEBCwUAA4IBAQBOyG/keiC1S06CjERcBFMpKlu4iPclxxZi8kscxlhpCfqUUW/v +8bxR6AV7B5llfxW7fjxP1cx2tUzFMmipC6ShlO2M3Vfc4bxUy2plp0CVtt8099dR +uXcuLxohJNL+hMs2Unt3rC+S4sZUypnWvDXcwCYhrsBZNq7IQ5oXy6m2oMxwHq29 +qUdIIFCmJ/wci6q2EaZttmLD3BW0IuPt7Z14oeAODYnIpnAjCIlPYUNRkFFT/2Tw +cyEQlSeHqAc10dDuc7wLI8UMf0VOkxE5srTd3LPcXzrqBzeURwctZUFrwToE6Xk7 +g8czZIjwInmhjdES2r/iCLAlZX7/bl7tmDDS +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..390adf2344 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-no-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-bad-ku-no-eku +subject:ee-int-bad-ku-no-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem new file mode 100644 index 0000000000..4c2423e772 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7zCCAdegAwIBAgIUY4lZzPdovquC7Mbz72zTaN4o1y4wDQYJKoZIhvcNAQEL +BQAwIDEeMBwGA1UEAwwVaW50LWJhZC1rdS1zZXJ2ZXItZWt1MCIYDzIwMTkxMTI4 +MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCMxITAfBgNVBAMMGGVlLWludC1iYWQt +a3Utc2VydmVyLWVrdTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gw +DQYJKoZIhvcNAQELBQADggEBAEbel/uwJK/uVtGY33gMAcUi1M7dFeCrxbo51f3M +dWf+qG4rMpZ9Jh9oUAk2OUuhkDfu52Vh4y17hjcPirOxWcy05UutefuEqUTLsiZ/ +Ykg+2RUMLtMPCjMgIv6OxWzwiN7hjuHW3MDmkEkT7YNzJnTE0isLwtd3gKiRILsM +WtQ3AFdR1KK+CUj6pGht+yDYR0kTI7a/1d5fCcdWD6usuIWtJlzGTtA5X9KFaiB+ +40UZs0p5NAVq2jS6W+DMUjHfrH07e94R6cYHM0DFXQLqDJucpeOrBX1Pd6//Jl2h +NtimaXJoTWiUOqclQstkhPrSLtT1GWj9S9MjDmB9G3hsLYc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..32bb6c2485 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-bad-ku-server-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-bad-ku-server-eku +subject:ee-int-bad-ku-server-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem new file mode 100644 index 0000000000..7c670abd58 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBTCCAe2gAwIBAgIUd8ffH/82BvEHZUunrKaA0Zk6FG4wDQYJKoZIhvcNAQEL +BQAwKzEpMCcGA1UEAwwgaW50LWNBLUZBTFNFLWFzc2VydHMta2V5Q2VydFNpZ24w +IhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowLjEsMCoGA1UEAwwj +ZWUtaW50LWNBLUZBTFNFLWFzc2VydHMta2V5Q2VydFNpZ24wggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjGjAYMAkG +A1UdEwQCMAAwCwYDVR0PBAQDAgP4MA0GCSqGSIb3DQEBCwUAA4IBAQAVF9pewrYN +HHFzPaQg07aY2le/pM3MgH2srjfHC+AZxrz0BeN0HFgmOcE/gnbN0hMPayVld+bh +JvFFiHLTQ8/HyvcmGkHagHdcgjo+5NiD2baBWFPZ49Bj8N6XJyQKCyjF7YkOlpx1 +l6mte8APVgundg2iKXXVljIuJS+g3U6V6p7z5pkW/yU/Xbl+3GKYgPtGe/uIQA1S +3fchFO11b/XWHw4PBQGMRxQKhS+e3Ih1TXJq5SwFp50RotkG/fLLw/q++W42bgcQ +k+Eyww1HtI54wAC6AQyZ66pSkusk5OuQbs+dV83k5WEUnLFexImKUNIItCvM/2qq +rEfSyd/jN5A8 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem.certspec new file mode 100644 index 0000000000..9e0fb65fd6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-cA-FALSE-asserts-keyCertSign.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-cA-FALSE-asserts-keyCertSign +subject:ee-int-cA-FALSE-asserts-keyCertSign +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem new file mode 100644 index 0000000000..53160a7800 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9zCCAd+gAwIBAgIUPzIc4Q/DpFWUx8qcM7GOe4M/RF0wDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZaW50LWxpbWl0ZWQtZGVwdGgtaW52YWxpZDAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAnMSUwIwYDVQQDDBxlZS1pbnQt +bGltaXRlZC1kZXB0aC1pbnZhbGlkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoxowGDAJBgNVHRMEAjAAMAsGA1Ud +DwQEAwID+DANBgkqhkiG9w0BAQsFAAOCAQEAil4HrKZ8ZItNn8riFIoViEPt1aif +ATej/kVDhGRNOqqXIuR1+blS8VTbmKB4YA+HxyG4d2g4fZLPNbqRrNdFDIwRI08h +EPk0ScoS+xBks5MS6EVqy507nR1XYHXRMjr9xD1L+hhMr+I42gFNDOm6BUfY2eb1 +11BttnNXk3PSakwAkt3sg8aZFLrZs1eW0EPjdbdmJPNV52ToUo0exydabJDrrFl1 +t2QJZCoz9MR+N/QPZkxpvOxjzmOCEFVHU8I4FIH2ddJVacg9LOZgh4CdLson8ug7 +mehOK8yk+QnfjoC0hlXi4FJdsNQFSL6SiCzuFlxk5AGs08pEfZQ75CvfIQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem.certspec new file mode 100644 index 0000000000..f00b4d1591 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth-invalid.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-limited-depth-invalid +subject:ee-int-limited-depth-invalid +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem new file mode 100644 index 0000000000..d109bcd492 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5zCCAc+gAwIBAgIUV/tRlNSDvu7BruxM6b8StzTZACUwDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRaW50LWxpbWl0ZWQtZGVwdGgwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowHzEdMBsGA1UEAwwUZWUtaW50LWxpbWl0ZWQt +ZGVwdGgwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgP4MA0GCSqGSIb3 +DQEBCwUAA4IBAQATRYSRBITskOkSFUKBg9DCA4bHR63pNBlEwb4L+aJYZnSdd2kc +Cgz0x5GdoVdETz878x9O9yvNESspoASqwiobxFHsbWeW0h6eqt3LoVFI3Njt8OaG +1kxynlyBvx3Q8E/b6ZT0hAbhum8GLqTxE10PZecvOjfDgNovCIhHk4PXpeXZNKo+ +p1yaXB4brxwVBEhv8iSBXnT60bt7vbqbJWCE2ASF2bgXTuARX1onkJz5+LWuGSF1 +ng9glpgB10r2XmOb52Hdlb9K1P4MM+Nofsb5XZ5WgdSEQnBb1b3pHLAwHXkNto3T +E2AqOkV105ic8bkKGIMi/oCd06R0gZ7QO/u2 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem.certspec new file mode 100644 index 0000000000..df85342d98 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-limited-depth.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-limited-depth +subject:ee-int-limited-depth +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem new file mode 100644 index 0000000000..9bfb1203c5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5zCCAc+gAwIBAgIUX0rT0GAv2W7gbUOUYEYetQADH1wwDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRaW50LW5vLWV4dGVuc2lvbnMwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowHzEdMBsGA1UEAwwUZWUtaW50LW5vLWV4dGVu +c2lvbnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgP4MA0GCSqGSIb3 +DQEBCwUAA4IBAQAw74cGcE+TWUij1up8e6PZJpTX5JHgpYmtZcSVKR7gFKlfLxg0 +6oB6JKkN7EIfJ85FnG0vYu0yFAHZG2bZJrqE3vUCAkRe2Q3Q39g1CBrlTkNy13pm +U41KqojfAGCGR6iS0pjDbDqu5bIpPh/sX9bmiLBq3nv+xIHYNdRU36KaRAdJ9l6+ +VAjq1b7WvPN7mF0rWN5C35pqxXu50i2gejOxlsxM2hUEODCCZoAKAweSVO3qKGCv +093AQ/WiHpvSjvMdFO0aA+WvnIya7KRYI1lpERJltIJPBS2CNgkKOnKonGgVpBoh +nZm+5PMjIiDU/cIrgXU3DzY9hAXmlwuCOAzL +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem.certspec new file mode 100644 index 0000000000..c5279046d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-extensions.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-no-extensions +subject:ee-int-no-extensions +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem new file mode 100644 index 0000000000..2087990cc3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5TCCAc2gAwIBAgIUcw4XUsGVtCZtRXKmHHReaOglg8kwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQaW50LW5vLWt1LW5vLWVrdTAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjAeMRwwGgYDVQQDDBNlZS1pbnQtbm8ta3Utbm8t +ZWt1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62 +iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql +WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosq +Qe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ +ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8i +b2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoY +CjXtjQIDAQABoxowGDAJBgNVHRMEAjAAMAsGA1UdDwQEAwID+DANBgkqhkiG9w0B +AQsFAAOCAQEAG2jH13dTldiSOyQAtgKNJ8kv7zVK278ge0Dcihn5B1Q4JWgPCRn8 +d/RDDVajlBo3fIkQwlAnGU4YjSKDnjpSZoiU/qVmW7TGUZxY61nijgqgNMGBVO1z +/81w17YNSHI1r6TEFAYo/NNRDCBpR4J+u3tKgQ8ZKWUv7ZdJbhHTPD+LwcoY8G07 +s9QgXisyB1KTofQAvWb4p+arjtjciTPfLg0QIf6dXOowg1+29IaGimnpb2P7yKB8 ++Drg3VL+lnhDhDrTsS+VVbP7YRfI3nzTXmRTObukb9HCuT7AXacw0GbJvcNh7rFX +2LPgZelDL5Xy/+l0osIbklL+fkcRb41xcA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..92ee3cc6d6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-no-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-no-ku-no-eku +subject:ee-int-no-ku-no-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem new file mode 100644 index 0000000000..4ee9fa145b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7TCCAdWgAwIBAgIUSydkZNHcPpeuo7P9vZIuqBGKd6YwDQYJKoZIhvcNAQEL +BQAwHzEdMBsGA1UEAwwUaW50LW5vLWt1LXNlcnZlci1la3UwIhgPMjAxOTExMjgw +MDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowIjEgMB4GA1UEAwwXZWUtaW50LW5vLWt1 +LXNlcnZlci1la3UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGo +RI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9a +dWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6t +aRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8n +FthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kX +Dqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/py +UcQx1QOs2hgKNe2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgP4MA0G +CSqGSIb3DQEBCwUAA4IBAQBUaqs/EWro+OEULUWHRLBiLJCi1gA9tAHdxpisa0uT +/tyodyY4L1xbgQWwlA13R5AjaVn1RfDnPAn6o1q/Xqbf53CGmyOCDkxTSXZifJbJ +D4/4xF6ewsNPnERMkTjzBcrchIh8EbppoS9Bd1L3RVq1s6GOU6gVTF2BAXfpIwZo +9bqTBc+DrCbT8+PoaZY8UJl4M7oy11Ye/GbwNd2Gm0TZU2zWdi2tsVTb82nr9wET +BgDrwM63AdrrUQCaUC2I+vlOhuxWWboLl+W4XME22A+5t3S/+DBYyM8vf2S0SLyd +h7NX2YzfBY9WI0r/rMJ0ubH7mbk1hypPjldbsygel/vw +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..c148896710 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-no-ku-server-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-no-ku-server-eku +subject:ee-int-no-ku-server-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem new file mode 100644 index 0000000000..2392d94115 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3TCCAcWgAwIBAgIUUQAgWvrw7svP/y7EUHKfSCcVkjMwDQYJKoZIhvcNAQEL +BQAwFzEVMBMGA1UEAwwMaW50LW5vdC1hLWNhMCIYDzIwMTkxMTI4MDAwMDAwWhgP +MjAyMjAyMDUwMDAwMDBaMBoxGDAWBgNVBAMMD2VlLWludC1ub3QtYS1jYTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaMaMBgwCQYDVR0TBAIwADALBgNVHQ8EBAMCA/gwDQYJKoZIhvcNAQELBQADggEB +AAB8UNQ3JeAdPqtNhn1VFnZZzpLYcUGq1c+C8nQEOCmvy8s+QmdKsCKaO449t0fM +Q8JyMuuH/ObHE54YzSEg/FWNrnO6hzTf05k8bxoUsFutL+xXvsLa7VGftz0VL2IC +8xlYMvGDIZ3TGdU8B9D0B72Usn3nZvf+vbm/wZ5Wj3Bl//Fk8eqcosGJ6j5cQ1Bk +DUQceGm6pRYtBERqkOPct9G+FOrd51tZ0+vTelJKC8v3OfK8pGwYqSjonhI146bp +djCKAZsU9KynW1BZ61E0iU+D8/8F1ELi4SxTQtHeOWBkYq31mYnZO2ze3XYAE78C +kkbfT9Qy0fIb9EpNn9FqOtU= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem.certspec new file mode 100644 index 0000000000..a95b0dc260 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-not-a-ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-not-a-ca +subject:ee-int-not-a-ca +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem new file mode 100644 index 0000000000..c30fbe0dc2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6zCCAdOgAwIBAgIUFTa2zYscnDR5ILK/7lqO+cxtDUcwDQYJKoZIhvcNAQEL +BQAwHjEcMBoGA1UEAwwTaW50LXZhbGlkLWt1LW5vLWVrdTAiGA8yMDE5MTEyODAw +MDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAhMR8wHQYDVQQDDBZlZS1pbnQtdmFsaWQt +a3Utbm8tZWt1MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESO +FtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVr +amRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWka +sdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbY +VbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6n +aOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHE +MdUDrNoYCjXtjQIDAQABoxowGDAJBgNVHRMEAjAAMAsGA1UdDwQEAwID+DANBgkq +hkiG9w0BAQsFAAOCAQEAmTBGZeCTRdr342Ff+rQuMiGwBl9prO45VGzGcb+QPQVF +w1bubYX7lk9UlKNZZE4ZB8nBFDSNf7kMLn8T6MI8YYihOrUF1KxGCKmWgcSttmg0 +kZS02nrd+yVe+iYaWEK/VN8jQkyUyM5u8MJK0k0EEnljjnNs168I/pAWgcNf1zls +1S9D3azqB0MFHe1CQzRtK6iOjE2deZHyYBb6T1uH3Gm2nm5kkpRgJ9mPGbccJS7p +q903lUvxT7fmAj0ixaDABMggEU/hLNxNrCiV3XhxpNalNnBc1UiGJiPZBkHdSlAl +nA0Ov7XuvCDmty7h8vWyUfZo0gchx43WTZImokBz8g== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..89a66b9f97 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-no-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-valid-ku-no-eku +subject:ee-int-valid-ku-no-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem new file mode 100644 index 0000000000..5c10a70b41 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8zCCAdugAwIBAgIUR3XzgtGCKrGxY8HRXSHlPF7GxWUwDQYJKoZIhvcNAQEL +BQAwIjEgMB4GA1UEAwwXaW50LXZhbGlkLWt1LXNlcnZlci1la3UwIhgPMjAxOTEx +MjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowJTEjMCEGA1UEAwwaZWUtaW50LXZh +bGlkLWt1LXNlcnZlci1la3UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24a +hvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7t +FYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o +N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0d +JdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4 +s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQD +AgP4MA0GCSqGSIb3DQEBCwUAA4IBAQBE2wXCNaiIiuKCv3PV/jHaYR1VDcc6Ypsp +GrClISVncIlQ+vav7bRCBfNvog8YycfP/roevVWvvoBwryoHWBNj/g6N3Skrn3+P +510oo0GDJrh/X6ITRk3uqu+6DIGtK4FJ3IcKL51zJpyuOi/YbH9m3RC5zb74EdNJ +pT1AVdLkwn5JxKNQ+ydXuIskYtvyNQt1xcv3k/HgqBKx3A14MsKBfuMoJBkifxVh +EPgX4Q5rrSb9Ztdmhux13UsVvt2ECuF2MGW8E/VgKh/XcXBh2WNZ6xNIiPTBM6S8 +RGefE1lVOeVlH5a5h43mI09JWxISQr0wTFvaHrJhWgQ1gsIRgwFj +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..43e83a336e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/ee-int-valid-ku-server-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:int-valid-ku-server-eku +subject:ee-int-valid-ku-server-eku +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem new file mode 100644 index 0000000000..b41eb0ef1b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC2DCCAcCgAwIBAgIUZzy02i7tvAs/6RTdJfLYIt87D9cwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHDEaMBgGA1UEAwwRaW50LWJhZC1rdS1uby1la3UwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwG +A1UdEwQFMAMBAf8wCwYDVR0PBAQDAgH6MA0GCSqGSIb3DQEBCwUAA4IBAQAAHnJc +VICzmnlR5N8AZlWrRHq3cye+ScZEQUXZRwxg3nLPIDwoNu0bgVAcoY2slrQEQ3d6 +Jq5UyBh6E6gjy0p3dVXO5bVlTTfdpoN3TmLUNERAqCyqRUw+tZUqqqOeLi8CT3jI +JlW8usKSP4NaFZODWifLPQQ2DeQoBZbn6Em7YwalGqnA3Izb8zmMxPWZrwgWmYEa +PG50Q3oh9j2dnkR4EOU0saT+gen86NwbvHZLSyAiIGH9/IJw9b5YvetZNRQ+wVuQ +U7im69QqlZSTeDLq80YA2CCcVL617oKB+H+ChquMwnmTvviO2qnM7WcZK0Zqy9F3 +LpP0Hmpv067ExIdk +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..f6525449b4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-no-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-bad-ku-no-eku +extension:basicConstraints:cA, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,cRLSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem new file mode 100644 index 0000000000..3bd7dea894 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+zCCAeOgAwIBAgIUT+TsShZ32vzo05KpLbrZpGyUbCkwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowIDEeMBwGA1UEAwwVaW50LWJhZC1rdS1zZXJ2ZXItZWt1MIIBIjANBgkq +hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVK +tOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7N +Q/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39Zgsr +sCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxs +l62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYl +nauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozww +OjAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIB+jAdBgNVHSUEFjAUBggrBgEFBQcD +AQYIKwYBBQUHAwIwDQYJKoZIhvcNAQELBQADggEBADETpYdt9P1ael7B2UilTCIu +zaXfSBUZHAKidpNMENdqcYJScyLTrUSOsbHKzignTCoDN3NHVd7o/YJmV457yRKl +nvtBaJQFd/9ycLtEiiksxvca1Zp7QfIeRRzspW23/n+bPa6CYEudbIp5KTzgi0uL +1bEg52LoEM+ikrpT1QdgQ+q+v1Ao/BaybTumC+7nC3jvGj4itLsYTIskaacWEf/K +WSFZ/K6cWIgKS5iEI+fAhx2IyJp4kK1jdIvmvtCiOG61r2f4GkxDkrQ5I2lvLEPF +wS+S3scFNprbybPOpI7GAqSsewHWu+Ge81G2M+Z1ndBH9oV7qWhVlpvf2U/yXvg= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..2d324508d4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-bad-ku-server-eku.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-bad-ku-server-eku +extension:basicConstraints:cA, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,cRLSign +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem new file mode 100644 index 0000000000..efc707bb5e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5DCCAcygAwIBAgIUWz8ZXOO6fSSbmQau3JwsY5zTrDMwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowKzEpMCcGA1UEAwwgaW50LWNBLUZBTFNFLWFzc2VydHMta2V5Q2VydFNp +Z24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAGjGjAYMAkGA1UdEwQCMAAwCwYDVR0PBAQDAgH+MA0GCSqGSIb3DQEB +CwUAA4IBAQCv+2MLK5Sm5TWC9WmEbavSz9bW315LIy/09r6NFaCQksbZzZ01b0n7 +jsuq6ZIhVfaMepUF1Fc7K5avfCzyJlPiOGsm9SmfT4XFIX5Ugu5mEAGva8jYDeOn +3ie/VzwvQRPmb7fIDQ/in5siiQ3OcL3f7KaOZQM/zP34pxh2C2oZYz+xu/byaLhb +qPXoTM8wnqVeNP7wqZDmv7ZZFXDT0dEKqCRs+G3YzPmfk/9tBokFla7jrrtG1vHt +vWXmeRfJPzJq+bDDJo9BmzHjPWYTYajfDFTOs24AbNacZdyNdNnRLgXqKIn5slk7 +F2mjSU/KIeiQB9nGxC/nfqe1uAR5MdtY +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem.certspec new file mode 100644 index 0000000000..39785d8a48 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-cA-FALSE-asserts-keyCertSign.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-cA-FALSE-asserts-keyCertSign +extension:basicConstraints:, +extension:keyUsage:digitalSignature,nonRepudiation,keyEncipherment,dataEncipherment,keyAgreement,keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem new file mode 100644 index 0000000000..5eaf98add4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4jCCAcqgAwIBAgIULycRMzIhSjpkHsE2X111MeoH++4wDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRaW50LWxpbWl0ZWQtZGVwdGgwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowJDEiMCAGA1UEAwwZaW50LWxpbWl0ZWQtZGVw +dGgtaW52YWxpZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahE +jhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1 +a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1p +GrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW +2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcO +p2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJR +xDHVA6zaGAo17Y0CAwEAAaMQMA4wDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsF +AAOCAQEAQ20RfnhWErcr9Bvu6mjwrmB7WGXO+vvwODj2IeG+r9y+25ZClHYp/87p +dKUknyhmQ7O+lgKDp+lzNFkt92JaEW2im1gBPFN/ZZi/WCOS6y+s3r/2Ji/+6BHr +R+SXvrizmpyNEzlAHOiG6bKv4UuECM4kK656tJmH+dH0sGiYSdmhf9lwM1m6X3r6 +kTToN0G8rUJc6hS3WuVRoKNrtBZxq7f0Z+lcBtnnCH7PQc94Sm06bauo1WBGE0E+ +1CXmL8M/22hDDfyI1Ve0NMmrK1YGRCY3YD+A9dCnc6zM60YtXAXhsGA8Mh8mdIfV +8y8gFBiMrWlNnWB/AC4bea8HBguxqA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem.certspec new file mode 100644 index 0000000000..9fdb2a248a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth-invalid.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-limited-depth +subject:int-limited-depth-invalid +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem new file mode 100644 index 0000000000..39c00d26ce --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzjCCAbagAwIBAgIUcylHQcmSUhRsK5erE0SNaPg0+okwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHDEaMBgGA1UEAwwRaW50LWxpbWl0ZWQtZGVwdGgwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjEzARMA8G +A1UdEwQIMAYBAf8CAQAwDQYJKoZIhvcNAQELBQADggEBAHHwYSdzz1ScKu0ShKs/ +9CVPkIuGIYrMpyBYCarzkQOs+bQIV91JPpoUt2W6enHixZ54M8bdACKYC3CnBiYe +wbPcZP0thQB7Sd5yHI3uNT8JSvinVv2EXcCNlZSei2Y+agc8d/9KMYvBYMG7SMHX +Egp5L4xrwkKrWOQ88DnokFMHf650Ddq5A1b1NFBHAjkRIQGhjRnwlxuVGf1cAle+ +C6tDK7ptHQM5CtAEdzGmf51MoErFRH0RCxJmUcbGnHTiq7HBMWw6Q/8PMTUsndS6 +W9igwATnCJqLpynZ0SvaETMa42JFJ+goSOYKVZTy2/uhvRlW81ZaR2E3lqj4W6jB +Svc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem.certspec new file mode 100644 index 0000000000..64f54b0441 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-limited-depth.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:int-limited-depth +extension:basicConstraints:cA,0 diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem new file mode 100644 index 0000000000..90a2f26b95 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICuTCCAaGgAwIBAgIUYcfJhXqUXKOGw+E5MNKdPih6hZ8wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHDEaMBgGA1UEAwwRaW50LW5vLWV4dGVuc2lvbnMwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAEwDQYJKoZI +hvcNAQELBQADggEBAI7R3HB8uiokTZA8E4dciZE6IQXm+cwTwwC41KXk8gKwIdXN +wuJiYmpFJS+ckS2azp8prxw9oGk1rv5V3v1b3yQ1js1MAEOcGlhFG02OMoEegOVe +RI5p1WN0A6S8sf4HwvbyxBWgM0J+uFez+GKpX2X/UVGtG+YI9yZ0x5BGdUsdKbvS +KJVgYmAjOg9wfl2vM71mfzMTVSHk7Nva7c0qjC3tNtGpILWrZH9tyccdJqSRTZzO +Xge+BUCe5hiTpT+sAGij6ESR1QBe1F8U2QmQRUhy3K2s43JFxWu5gep0XBY/p6kR +6EXpbTn9mWFuRg7nLEcOwYtbAXA1mNtH9QXw6PE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem.certspec new file mode 100644 index 0000000000..c99626bd5a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-extensions.pem.certspec @@ -0,0 +1,2 @@ +issuer:ca +subject:int-no-extensions diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem new file mode 100644 index 0000000000..00f1d1ddfe --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyjCCAbKgAwIBAgIUQXSt+CjpOfyWdZcfjuLpGReDI5QwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowGzEZMBcGA1UEAwwQaW50LW5vLWt1LW5vLWVrdTCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMQMA4wDAYD +VR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEASpnks6qV+XZPFh2HPqCPcm9H +M4zZafwvx+OvwALtsu3goai06A2z2lWt/uGDNa773kkQI8rRBieuwjk7mUgAZFhm +HbcGmVaih01VYVrPzr5iKhoY0p3RVDxtPJusy8OXv4+jPEpQ8SnIUIPzpoSUhpA4 +ejH/rZNOUuKnz5aI01mmAq2Q0eUlQLFvjJPy4qfJ7R2vuhDi7T/Op3Fbd78a1A2I +/411XZ7rpjbh2tJVHI71kpaHGXGeppciYxPwjRG+hlebKFD9NVXldCcvVzy8DNzu +FjCMqGOsHm87uu6R6ZDekW+Zxy30Ui2qW74b06nxlxphHgO0LglFhwwKVhs3Dw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..306a218db9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-no-eku.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:int-no-ku-no-eku +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem new file mode 100644 index 0000000000..e2c2941f73 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7TCCAdWgAwIBAgIUe0/iqtgXpUCqSBbTkk3j6cHrF40wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHzEdMBsGA1UEAwwUaW50LW5vLWt1LXNlcnZlci1la3UwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjLzAt +MAwGA1UdEwQFMAMBAf8wHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMA0G +CSqGSIb3DQEBCwUAA4IBAQA66A/sfTMBP0yPBfI4TtxMv1Af0gpOchsekkY4lUxg +IgsSvqjrlW/r7oBVpucIqH03wlHZkoiY+rl2hokh5fVNmztaBSaSQSdzrwW7qpsS +0OFmUmPPcV4Kjy4EaaFXk2diNP/xCENwci6CN6iVvTrHt1Nu5DVEAbEwQVjN2Lme +f1prvxAcqkyoJqHNQyS5nr31Bc4OdBFEJJ4ZjMvJV0UfRH0fkwhutIW4kgYgHp6o +6BVpnDyqEN0yZaNHIQ8VP1hl+gSoHYmhX6BuF6vI739ACKlZXMCtGEEOi0o/oZb8 +GMUgv22QZFC5JMiWwhbcN6LJC5XpGEl9X/FwDndrv2JZ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..1482b627c7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-no-ku-server-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-no-ku-server-eku +extension:basicConstraints:cA, +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem new file mode 100644 index 0000000000..9857f050c3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICwzCCAaugAwIBAgIULcyFCPC5AqS4vb2uiw2vfP5d52swDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowFzEVMBMGA1UEAwwMaW50LW5vdC1hLWNhMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABow0wCzAJBgNVHRME +AjAAMA0GCSqGSIb3DQEBCwUAA4IBAQAib9DQGbyyJ/RSZet5VQiZ/1WLmOZNDU63 +1tmavPbUWtoV6ac2nvObfMBxiMfog51CyS9kys9umj5i4wBOFc07ADPnZvZ4JzCH +DMJqe83Q9DNMRqiUFgoioLmZM4+t6gOFdfv0Hcm1/dPrT7PAX/68aa2OP95vPrec +LTKHirbpV9BxgH2ZFWmiI/iMYlEJpb9BcJfpAV9VzmOAoXwuP87qqxdWUhMuE3V/ +Jopnz32iH/j6HEsmhG5cixmiDOoVcuKo0EpsZSAV6QjQJWZ0KYBfnFwqSkaNLAzd +Tsql/80wHPgrlb5G0na1VWqfzijcWrMM9GwYu2nliE0b8Erl70Wc +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem.certspec new file mode 100644 index 0000000000..3161680b1c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-not-a-ca.pem.certspec @@ -0,0 +1,3 @@ +issuer:ca +subject:int-not-a-ca +extension:basicConstraints:, diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem new file mode 100644 index 0000000000..b426d19e30 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC2jCCAcKgAwIBAgIUAQgTd7cj4mynq7/pBIjhOMglEsUwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowHjEcMBoGA1UEAwwTaW50LXZhbGlkLWt1LW5vLWVrdTCCASIwDQYJKoZI +hvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs +9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8 +HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7Ak +kqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJet +lmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2r +kQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBsw +DAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAgQwDQYJKoZIhvcNAQELBQADggEBAI+T +Z5fdjBIEKwA7tLJHWAkXLYYX2/NIjc3ZS5J1+LMpQXA+Rmw7T8zZ5Tecf7wvHJNd +qsjNFkOx9IkV3tiGPsv7J3B53Kk5qJ1LR3sNj99YW6zs0SpETYbVc0IY49ZP8eOA +BMS6eGrkSYgXXTWN6fu83gr+/QB6vCri8xkOw7NM0gnfoZhOAXmKkWILW3S1Arj0 +E6FpW88Pww6miceSa8ecdc4QL8qRIFKDZTXCIwykjeOLZgw3JTOr0YYGO0uBjspj +ASheUaiNfEGbLIU+PySMvgX3RRheSDMIxeoKCL8Wg5nyIg/6yE5vXipiTexqk9rR +0z/z588qvYn2g5AqUB0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem.certspec new file mode 100644 index 0000000000..d7f9b0387a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-no-eku.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int-valid-ku-no-eku +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem new file mode 100644 index 0000000000..834ea6ef65 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/TCCAeWgAwIBAgIUWWZayMVWHspFSBkAYaO7s8p84NAwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowIjEgMB4GA1UEAwwXaW50LXZhbGlkLWt1LXNlcnZlci1la3UwggEiMA0G +CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erk +NUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwC +fs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1m +CyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTM +HGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m +1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGj +PDA6MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgIEMB0GA1UdJQQWMBQGCCsGAQUF +BwMBBggrBgEFBQcDAjANBgkqhkiG9w0BAQsFAAOCAQEAud9bDsVnUs48CsoNie24 +ZnxZPn6RJe6JjZUDdAYwVVYVzJz4UqZF2kwwjXm0Dzs758WdbqgP22bBrs6sZZBI +39Rw74d2apnh8PpVzrsKVQSQqh8RAk38c6MDDRhYo859sTW2/Lvyo2PHr4wIR2jH ++awmkP3EEq7c1kt23q2c0u+rxKR20pYjJJ0br92b/buiOfjdA9q0pF/rRdm6/U4L +ApUHYzyXiuEoekLbLf5tIL3Xel/OkaD7jBrrEWll/vWj+RBI4B33LViDJ9lMjavP +KJHDM7PbzM1XKogapqmfqxYXzyY+ZtxurIXTkyWuuNfINd+OMOzRkvwDYkATNEGD +OQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem.certspec new file mode 100644 index 0000000000..84314bfa40 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/int-valid-ku-server-eku.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:int-valid-ku-server-eku +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign +extension:extKeyUsage:serverAuth,clientAuth diff --git a/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/moz.build b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/moz.build new file mode 100644 index 0000000000..e2b0dd7599 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_basic_usage_constraints/moz.build @@ -0,0 +1,35 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'ee-int-bad-ku-no-eku.pem', +# 'ee-int-bad-ku-server-eku.pem', +# 'ee-int-cA-FALSE-asserts-keyCertSign.pem', +# 'ee-int-limited-depth.pem', +# 'ee-int-limited-depth-invalid.pem', +# 'ee-int-no-extensions.pem', +# 'ee-int-no-ku-no-eku.pem', +# 'ee-int-no-ku-server-eku.pem', +# 'ee-int-not-a-ca.pem', +# 'ee-int-valid-ku-no-eku.pem', +# 'ee-int-valid-ku-server-eku.pem', +# 'int-bad-ku-no-eku.pem', +# 'int-bad-ku-server-eku.pem', +# 'int-cA-FALSE-asserts-keyCertSign.pem', +# 'int-limited-depth.pem', +# 'int-limited-depth-invalid.pem', +# 'int-no-extensions.pem', +# 'int-no-ku-no-eku.pem', +# 'int-no-ku-server-eku.pem', +# 'int-not-a-ca.pem', +# 'int-valid-ku-no-eku.pem', +# 'int-valid-ku-server-eku.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads.js b/security/manager/ssl/tests/unit/test_intermediate_preloads.js new file mode 100644 index 0000000000..1f8b289eb3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads.js @@ -0,0 +1,645 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; +do_get_profile(); // must be called before getting nsIX509CertDB + +const { RemoteSettings } = ChromeUtils.import( + "resource://services-settings/remote-settings.js" +); +const { RemoteSecuritySettings } = ChromeUtils.import( + "resource://gre/modules/psm/RemoteSecuritySettings.jsm" +); +const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" +); +const { TelemetryTestUtils } = ChromeUtils.import( + "resource://testing-common/TelemetryTestUtils.jsm" +); +const { IntermediatePreloadsClient } = RemoteSecuritySettings.init(); + +let server; + +let intermediate1Data; +let intermediate2Data; + +const INTERMEDIATES_DL_PER_POLL_PREF = + "security.remote_settings.intermediates.downloads_per_poll"; +const INTERMEDIATES_ENABLED_PREF = + "security.remote_settings.intermediates.enabled"; + +function getHashCommon(aStr, useBase64) { + let hasher = Cc["@mozilla.org/security/hash;1"].createInstance( + Ci.nsICryptoHash + ); + hasher.init(Ci.nsICryptoHash.SHA256); + let stringStream = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + stringStream.data = aStr; + hasher.updateFromStream(stringStream, -1); + + return hasher.finish(useBase64); +} + +// Get a hexified SHA-256 hash of the given string. +function getHash(aStr) { + return hexify(getHashCommon(aStr, false)); +} + +function countTelemetryReports(histogram) { + let count = 0; + for (let x in histogram.values) { + count += histogram.values[x]; + } + return count; +} + +function clearTelemetry() { + Services.telemetry.getHistogramById("INTERMEDIATE_PRELOADING_ERRORS").clear(); + Services.telemetry + .getHistogramById("INTERMEDIATE_PRELOADING_UPDATE_TIME_MS") + .clear(); + Services.telemetry.clearScalars(); +} + +function getSubjectBytes(certDERString) { + let bytes = stringToArray(certDERString); + let cert = new X509.Certificate(); + cert.parse(bytes); + return arrayToString(cert.tbsCertificate.subject._der._bytes); +} + +function getSPKIBytes(certDERString) { + let bytes = stringToArray(certDERString); + let cert = new X509.Certificate(); + cert.parse(bytes); + return arrayToString(cert.tbsCertificate.subjectPublicKeyInfo._der._bytes); +} + +/** + * Simulate a Remote Settings synchronization by filling up the + * local data with fake records. + * + * @param {*} filenames List of pem files for which we will create + * records. + * @param {*} options Options for records to generate. + */ +async function syncAndDownload(filenames, options = {}) { + const { + hashFunc = getHash, + lengthFunc = arr => arr.length, + clear = true, + } = options; + + const localDB = await IntermediatePreloadsClient.client.db; + if (clear) { + await localDB.clear(); + } + + let count = 1; + for (const filename of filenames) { + const file = do_get_file(`test_intermediate_preloads/${filename}`); + const certBytes = readFile(file); + const certDERBytes = atob(pemToBase64(certBytes)); + + const record = { + details: { + who: "", + why: "", + name: "", + created: "", + }, + derHash: getHashCommon(certDERBytes, true), + subject: "", + subjectDN: btoa(getSubjectBytes(certDERBytes)), + attachment: { + hash: hashFunc(certBytes), + size: lengthFunc(certBytes), + filename: `intermediate certificate #${count}.pem`, + location: `security-state-workspace/intermediates/${filename}`, + mimetype: "application/x-pem-file", + }, + whitelist: false, + pubKeyHash: getHashCommon(getSPKIBytes(certDERBytes), true), + crlite_enrolled: true, + }; + + await localDB.create(record); + count++; + } + // This promise will wait for the end of downloading. + const updatedPromise = TestUtils.topicObserved( + "remote-security-settings:intermediates-updated" + ); + // Simulate polling for changes, trigger the download of attachments. + Services.obs.notifyObservers(null, "remote-settings:changes-poll-end"); + const results = await updatedPromise; + return results[1]; // topicObserved gives back a 2-array +} + +/** + * Return the list of records whose attachment was downloaded. + */ +async function locallyDownloaded() { + return IntermediatePreloadsClient.client.get({ + filters: { cert_import_complete: true }, + syncIfEmpty: false, + }); +} + +add_task(async function test_preload_empty() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + // load the first root and end entity, ignore the initial intermediate + addCertFromFile(certDB, "test_intermediate_preloads/ca.pem", "CTu,,"); + + let ee_cert = constructCertFromFile( + "test_intermediate_preloads/default-ee.pem" + ); + notEqual(ee_cert, null, "EE cert should have successfully loaded"); + + equal( + await syncAndDownload([]), + "success", + "Preloading update should have run" + ); + + equal( + (await locallyDownloaded()).length, + 0, + "There should have been no downloads" + ); + + // check that ee cert 1 is unknown + await checkCertErrorGeneric( + certDB, + ee_cert, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); +}); + +add_task(async function test_preload_disabled() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, false); + + equal( + await syncAndDownload(["int.pem"]), + "disabled", + "Preloading update should not have run" + ); + + equal( + (await locallyDownloaded()).length, + 0, + "There should have been no downloads" + ); +}); + +add_task(async function test_preload_invalid_hash() { + // Enable the collection (during test) for all products so even products + // that don't collect the data will be able to run the test without failure. + Services.prefs.setBoolPref( + "toolkit.telemetry.testing.overrideProductsCheck", + true + ); + + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + const invalidHash = + "6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d"; + + clearTelemetry(); + + const result = await syncAndDownload(["int.pem"], { + hashFunc: () => invalidHash, + }); + equal(result, "success", "Preloading update should have run"); + + let errors_histogram = Services.telemetry + .getHistogramById("INTERMEDIATE_PRELOADING_ERRORS") + .snapshot(); + + equal( + countTelemetryReports(errors_histogram), + 1, + "There should be one error report" + ); + equal( + errors_histogram.values[7], + 1, + "There should be one invalid hash error" + ); + + equal( + (await locallyDownloaded()).length, + 0, + "There should be no local entry" + ); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + // load the first root and end entity, ignore the initial intermediate + addCertFromFile(certDB, "test_intermediate_preloads/ca.pem", "CTu,,"); + + let ee_cert = constructCertFromFile( + "test_intermediate_preloads/default-ee.pem" + ); + notEqual(ee_cert, null, "EE cert should have successfully loaded"); + + // We should still have a missing intermediate. + await checkCertErrorGeneric( + certDB, + ee_cert, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); +}); + +add_task(async function test_preload_invalid_length() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + + clearTelemetry(); + + const result = await syncAndDownload(["int.pem"], { + lengthFunc: () => 42, + }); + equal(result, "success", "Preloading update should have run"); + + let errors_histogram = Services.telemetry + .getHistogramById("INTERMEDIATE_PRELOADING_ERRORS") + .snapshot(); + + equal( + countTelemetryReports(errors_histogram), + 1, + "There should be only one error report" + ); + equal( + errors_histogram.values[7], + 1, + "There should be one invalid content hash error" + ); + + equal( + (await locallyDownloaded()).length, + 0, + "There should be no local entry" + ); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + // load the first root and end entity, ignore the initial intermediate + addCertFromFile(certDB, "test_intermediate_preloads/ca.pem", "CTu,,"); + + let ee_cert = constructCertFromFile( + "test_intermediate_preloads/default-ee.pem" + ); + notEqual(ee_cert, null, "EE cert should have successfully loaded"); + + // We should still have a missing intermediate. + await checkCertErrorGeneric( + certDB, + ee_cert, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); +}); + +add_task(async function test_preload_basic() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + Services.prefs.setIntPref(INTERMEDIATES_DL_PER_POLL_PREF, 100); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + + // load the first root and end entity, ignore the initial intermediate + addCertFromFile(certDB, "test_intermediate_preloads/ca.pem", "CTu,,"); + + let ee_cert = constructCertFromFile( + "test_intermediate_preloads/default-ee.pem" + ); + notEqual(ee_cert, null, "EE cert should have successfully loaded"); + + // load the second end entity, ignore both intermediate and root + let ee_cert_2 = constructCertFromFile("test_intermediate_preloads/ee2.pem"); + notEqual(ee_cert_2, null, "EE cert 2 should have successfully loaded"); + + // check that the missing intermediate causes an unknown issuer error, as + // expected, in both cases + await checkCertErrorGeneric( + certDB, + ee_cert, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); + await checkCertErrorGeneric( + certDB, + ee_cert_2, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); + + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + let intermediateBytes = readFile( + do_get_file("test_intermediate_preloads/int.pem") + ); + let intermediateDERBytes = atob(pemToBase64(intermediateBytes)); + let intermediateCert = new X509.Certificate(); + intermediateCert.parse(stringToArray(intermediateDERBytes)); + let crliteStateBefore = certStorage.getCRLiteState( + intermediateCert.tbsCertificate.subject._der._bytes, + intermediateCert.tbsCertificate.subjectPublicKeyInfo._der._bytes + ); + equal( + crliteStateBefore, + Ci.nsICertStorage.STATE_UNSET, + "crlite state should be unset before" + ); + + const result = await syncAndDownload(["int.pem", "int2.pem"]); + equal(result, "success", "Preloading update should have run"); + + equal( + (await locallyDownloaded()).length, + 2, + "There should have been 2 downloads" + ); + + // check that ee cert 1 verifies now the update has happened and there is + // an intermediate + + // First verify by connecting to a server that uses that end-entity + // certificate but doesn't send the intermediate. + await asyncStartTLSTestServer( + "BadCertAndPinningServer", + "test_intermediate_preloads" + ); + // This ensures the test server doesn't include the intermediate in the + // handshake. + let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + certDir.append("test_intermediate_preloads"); + Assert.ok(certDir.exists(), "test_intermediate_preloads should exist"); + let args = ["-D", "-n", "int"]; + // If the certdb is cached from a previous run, the intermediate will have + // already been deleted, so this may "fail". + run_certutil_on_directory(certDir.path, args, false); + let certsCachedPromise = TestUtils.topicObserved( + "psm:intermediate-certs-cached" + ); + await asyncConnectTo("ee.example.com", PRErrorCodeSuccess); + let subjectAndData = await certsCachedPromise; + Assert.equal(subjectAndData.length, 2, "expecting [subject, data]"); + // Since the intermediate is preloaded, we don't save it to the profile's + // certdb. + Assert.equal(subjectAndData[1], "0", `expecting "0" certs imported`); + + await checkCertErrorGeneric( + certDB, + ee_cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + + let localDB = await IntermediatePreloadsClient.client.db; + let data = await localDB.list(); + ok(data.length > 0, "should have some entries"); + // simulate a sync (syncAndDownload doesn't actually... sync.) + await IntermediatePreloadsClient.client.emit("sync", { + data: { + current: data, + created: data, + deleted: [], + updated: [], + }, + }); + + let crliteStateAfter = certStorage.getCRLiteState( + intermediateCert.tbsCertificate.subject._der._bytes, + intermediateCert.tbsCertificate.subjectPublicKeyInfo._der._bytes + ); + equal( + crliteStateAfter, + Ci.nsICertStorage.STATE_ENFORCE, + "crlite state should be set after" + ); + + // check that ee cert 2 does not verify - since we don't know the issuer of + // this certificate + await checkCertErrorGeneric( + certDB, + ee_cert_2, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLServer + ); +}); + +add_task(async function test_preload_200() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + Services.prefs.setIntPref(INTERMEDIATES_DL_PER_POLL_PREF, 100); + + const files = []; + for (let i = 0; i < 200; i++) { + files.push(["int.pem", "int2.pem"][i % 2]); + } + + clearTelemetry(); + + let result = await syncAndDownload(files); + equal(result, "success", "Preloading update should have run"); + + equal( + (await locallyDownloaded()).length, + 100, + "There should have been only 100 downloaded" + ); + + const scalars = TelemetryTestUtils.getProcessScalars("parent"); + TelemetryTestUtils.assertScalar( + scalars, + "security.intermediate_preloading_num_preloaded", + 100, + "Should have preloaded 100 certs" + ); + TelemetryTestUtils.assertScalar( + scalars, + "security.intermediate_preloading_num_pending", + 100, + "Should report 100 pending" + ); + + let time_histogram = Services.telemetry + .getHistogramById("INTERMEDIATE_PRELOADING_UPDATE_TIME_MS") + .snapshot(); + let errors_histogram = Services.telemetry + .getHistogramById("INTERMEDIATE_PRELOADING_ERRORS") + .snapshot(); + equal(countTelemetryReports(time_histogram), 1, "Should report time once"); + equal( + countTelemetryReports(errors_histogram), + 0, + "There should be no error reports" + ); + + // Re-run + result = await syncAndDownload([], { clear: false }); + equal(result, "success", "Preloading update should have run"); + + equal( + (await locallyDownloaded()).length, + 200, + "There should have been 200 downloaded" + ); +}); + +add_task(async function test_delete() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + Services.prefs.setIntPref(INTERMEDIATES_DL_PER_POLL_PREF, 100); + + let syncResult = await syncAndDownload(["int.pem", "int2.pem"]); + equal(syncResult, "success", "Preloading update should have run"); + + equal( + (await locallyDownloaded()).length, + 2, + "There should have been 2 downloads" + ); + + let localDB = await IntermediatePreloadsClient.client.db; + let data = await localDB.list(); + ok(data.length > 0, "should have some entries"); + let subject = data[0].subjectDN; + let certStorage = Cc["@mozilla.org/security/certstorage;1"].getService( + Ci.nsICertStorage + ); + let resultsBefore = certStorage.findCertsBySubject( + stringToArray(atob(subject)) + ); + equal( + resultsBefore.length, + 1, + "should find the intermediate in cert storage before" + ); + // simulate a sync where we deleted the entry + await IntermediatePreloadsClient.client.emit("sync", { + data: { + current: [], + created: [], + deleted: [data[0]], + updated: [], + }, + }); + let resultsAfter = certStorage.findCertsBySubject( + stringToArray(atob(subject)) + ); + equal( + resultsAfter.length, + 0, + "shouldn't find intermediate in cert storage now" + ); +}); + +function findCertByCommonName(certDB, commonName) { + for (let cert of certDB.getCerts()) { + if (cert.commonName == commonName) { + return cert; + } + } + return null; +} + +add_task(async function test_healer() { + Services.prefs.setBoolPref(INTERMEDIATES_ENABLED_PREF, true); + Services.prefs.setIntPref(INTERMEDIATES_DL_PER_POLL_PREF, 100); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + // Add an intermediate as if it had previously been cached. + addCertFromFile(certDB, "test_intermediate_preloads/int.pem", ",,"); + // Add an intermediate with non-default trust settings as if it had been added by the user. + addCertFromFile(certDB, "test_intermediate_preloads/int2.pem", "CTu,,"); + + let syncResult = await syncAndDownload(["int.pem", "int2.pem"]); + equal(syncResult, "success", "Preloading update should have run"); + + equal( + (await locallyDownloaded()).length, + 2, + "There should have been 2 downloads" + ); + + let healerRanPromise = TestUtils.topicObserved( + "psm:intermediate-preloading-healer-ran" + ); + Services.prefs.setIntPref( + "security.intermediate_preloading_healer.timer_interval_ms", + 500 + ); + Services.prefs.setBoolPref( + "security.intermediate_preloading_healer.enabled", + true + ); + await healerRanPromise; + Services.prefs.setBoolPref( + "security.intermediate_preloading_healer.enabled", + false + ); + + let intermediate = findCertByCommonName( + certDB, + "intermediate-preloading-intermediate" + ); + equal(intermediate, null, "should not find intermediate in NSS"); + let intermediate2 = findCertByCommonName( + certDB, + "intermediate-preloading-intermediate2" + ); + notEqual(intermediate2, null, "should find second intermediate in NSS"); +}); + +function run_test() { + server = new HttpServer(); + server.start(-1); + registerCleanupFunction(() => server.stop(() => {})); + + server.registerDirectory( + "/cdn/security-state-workspace/intermediates/", + do_get_file("test_intermediate_preloads") + ); + + server.registerPathHandler("/v1/", (request, response) => { + response.write( + JSON.stringify({ + capabilities: { + attachments: { + base_url: `http://localhost:${server.identity.primaryPort}/cdn/`, + }, + }, + }) + ); + response.setHeader("Content-Type", "application/json; charset=UTF-8"); + response.setStatusLine(null, 200, "OK"); + }); + + Services.prefs.setCharPref( + "services.settings.server", + `http://localhost:${server.identity.primaryPort}/v1` + ); + + Services.prefs.setCharPref("browser.policies.loglevel", "debug"); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem b/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem new file mode 100644 index 0000000000..680b068f34 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+TCCAeGgAwIBAgIUN/Y56TvJcL2liqk2Feh/QfKrlLwwDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50ZXJtZWRpYXRlLXByZWxvYWRpbmctY2EwIhgPMjAx +MDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAwMDAwMFowJTEjMCEGA1UEAwwaaW50ZXJt +ZWRpYXRlLXByZWxvYWRpbmctY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBSPwr2BfSHT3saxwx6YGEautZx +w/sdM9AJAubFLqDd3MYHtzCZcQXaeDGbAzvo8m/PKA4Yt+UYbKyDnRR8sLA4f/iu +z1zHeenlzBWpRVHu/++ZSk/ESwn0zLprIsOcXjaYkbfrqcEGNWvLJzpT4T36Gr9t +DvxHnpsaMsJviZS3WHzTSoioWkcRyF78bYa51ZJWYJHFKZQppqhJ+jcoJhiomRlc +WwhI8NAU3dOOFJuEg/z+vQpcEQi0rRW9J6X/15BUZRQlF5Hs2wilGa8ViNX2+B5I +kjbmNrdT5hcnGEfR7JpHFuihFdxQc4CFY87u1chI8yaHLhhriUP6Jq0+J5ur +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem.certspec new file mode 100644 index 0000000000..4ccabc25b3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:intermediate-preloading-ca +subject:intermediate-preloading-ca +validity:20100101-20500101 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key.keyspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem new file mode 100644 index 0000000000..1838ab40e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDDCCAfSgAwIBAgIUTw97bCabpmjf11gbMSrUIZkrl30wDQYJKoZIhvcNAQEL +BQAwLzEtMCsGA1UEAwwkaW50ZXJtZWRpYXRlLXByZWxvYWRpbmctaW50ZXJtZWRp +YXRlMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMBkxFzAVBgNV +BAMMDmVlLmV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC +AQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptu +Gobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO +7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgf +qDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/yt +HSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcx +uLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozIwMDATBgNVHSUEDDAKBggrBgEFBQcD +ATAZBgNVHREEEjAQgg5lZS5leGFtcGxlLmNvbTANBgkqhkiG9w0BAQsFAAOCAQEA +J7Ff5mE6qJuS+kszRFBNnD2OBj0ss6mrayQCqqJqeM01JHRFJ295iDvxHMbtzfYH +EMSytow8dZ8vWoxPSDSr3TV8kJOYYKXjW5ClYi6rWwHt6aC9zPTQ87AspBBKhf3q +2jX+fPoLIKzauktAnzYApvyTTe8fNE/LfLHpDpR2ipQBKTz1J2Pw9RHcp7WxC9rW +6PTH40kMLD2F3fRYdrsJ37nIe853MvUsH3Fa6oMfGxpvIpN3gJtj3w0OPj8rWq9X +gQbN/56afzE4zG0HhX+RP71LXpn1US0twQfP0GM0q6xh0P7pfWT8Z7lHk1j4j7u+ +3RU1do8+1Ak6TLrMnfkZBw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem.certspec new file mode 100644 index 0000000000..e9decb76dc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/default-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:intermediate-preloading-intermediate +subject:ee.example.com +extension:extKeyUsage:serverAuth +extension:subjectAlternativeName:ee.example.com diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem b/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem new file mode 100644 index 0000000000..dcb44b9953 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5zCCAc+gAwIBAgIUV3PLWwVDtiZkBpRLWYBIrcA3uowwDQYJKoZIhvcNAQEL +BQAwMDEuMCwGA1UEAwwlaW50ZXJtZWRpYXRlLXByZWxvYWRpbmctaW50ZXJtZWRp +YXRlMjAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAOMQwwCgYD +VQQDDANlZTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W +1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtq +ZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx +0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthV +t2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo +4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx +1QOs2hgKNe2NAgMBAAGjFzAVMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA0GCSqGSIb3 +DQEBCwUAA4IBAQBSxrC9YRPkmqYz2MsbyytjlG/f0g2uVv78Q3yR0tVsGW67VH0l +X3rUdqWXCrYi8NtmZjbwx/EERtXc4dLXmJ2DEaHWPygQ3zAiKBAEWh9COaz7b11/ +wHu3uZVOXsWKqt212FpjKob6n4ceQu2RlnYYX+VVSKrt4ct3ph5X31D/heerNvLp +Et6UETIAY6PhC982XC3wn/r0ykIPQygXKdMJ3Umvq+OzOObn7RTX10EPdOmyU9su +bmpR4oYBPB71GWGoeNpp17swOe9BVvQvIcnEwiWuVeWhaZvFAmrFe1484PnTgcjg +kLtYKtzg0Z8t1jWExmdb00A8CP92iHa2HGl+ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem.certspec new file mode 100644 index 0000000000..089ac63831 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/ee2.pem.certspec @@ -0,0 +1,3 @@ +issuer:intermediate-preloading-intermediate2 +subject:ee2 +extension:extKeyUsage:serverAuth diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem b/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem new file mode 100644 index 0000000000..ad98f78efd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDAzCCAeugAwIBAgIUHyDRZ9EprKjXteNSxinckLtLUqMwDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50ZXJtZWRpYXRlLXByZWxvYWRpbmctY2EwIhgPMjAx +OTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowLzEtMCsGA1UEAwwkaW50ZXJt +ZWRpYXRlLXByZWxvYWRpbmctaW50ZXJtZWRpYXRlMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRME +BTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEARadVY9uVwXt3 +8p81yXQxJ87Vyc02HL9qc1l1+ttJ0g0CL10pEJjT8rbXwghaGQ8Jw/GGhoYVy0VH ++5+uqnpvLaBgFX7noX5+eKABzVW3NfcD9705Ul3N8dFo11mGsvzL3+B5ucOyjY+9 +CPLIzYCBY5OnCIrsU+zkS9TcoqblvPQGkzVdHcNQLy01Fs6XJ4VQhoP6KZ2rsCJn +QcHlg5t5HXywCf5ihzXPqWB7Ib7GL7nLIv7ViyHK6QkEPpeHtSxcs2OiwkJCeKTs +v2HFnnLiKfF0zGhOp8nLaMXmFTCaNBLs7YaSbWqOYct9zNTBlDtO+GcYqDx74B6c ++W7hLcJ9aA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem.certspec new file mode 100644 index 0000000000..5863b3131f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/int.pem.certspec @@ -0,0 +1,4 @@ +issuer:intermediate-preloading-ca +subject:intermediate-preloading-intermediate +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem b/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem new file mode 100644 index 0000000000..c11853b08a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDBTCCAe2gAwIBAgIUb7hTHv3uBY6lDd0XbWQLu/+jjIQwDQYJKoZIhvcNAQEL +BQAwJjEkMCIGA1UEAwwbaW50ZXJtZWRpYXRlLXByZWxvYWRpbmctY2EyMCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMDAxLjAsBgNVBAMMJWludGVy +bWVkaWF0ZS1wcmVsb2FkaW5nLWludGVybWVkaWF0ZTIwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1Ud +EwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQBJYzhJ9SuX +sqKTHwITcbGmv30f1CFOE23Pwf1KSk/Rqw2yx7CCeobGpLQUlIU72lGqZ0W4BVGy +TJDwGOGTKtFYVtYddo5DXVuUREUcUeRzAwSZwEhm2ANyEXypRffmQNR+h4VH3skX +2pWfNH8TAes+z6Vz4HCkEOqa3uBUe9GMjbg8Gtrqsx2Vt3hJrg9dB2/0I5POMM95 +9nRtl6ZHx81DMccy6YT/lhsBDIA106u75THS45yuFNRtzPaL06/7iiNFjW+upsf7 +3Bg6x7VKBt2ZGFebHFiMnGyVPsMyXQw/i1w6yiXD04F9PHdYjMtY90hH69aGhQNk +Lgcw88dDaKaL +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem.certspec b/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem.certspec new file mode 100644 index 0000000000..27e9a008df --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/int2.pem.certspec @@ -0,0 +1,4 @@ +issuer:intermediate-preloading-ca2 +subject:intermediate-preloading-intermediate2 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_intermediate_preloads/moz.build b/security/manager/ssl/tests/unit/test_intermediate_preloads/moz.build new file mode 100644 index 0000000000..855b02df7f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_intermediate_preloads/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ca.pem', +# 'default-ee.pem', +# 'ee2.pem', +# 'int.pem', +# 'int2.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'default-ee.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_keysize.js b/security/manager/ssl/tests/unit/test_keysize.js new file mode 100644 index 0000000000..45066a3888 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize.js @@ -0,0 +1,204 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Checks that RSA certs with key sizes below 1024 bits are rejected. +// Checks that ECC certs using curves other than the NIST P-256, P-384 or P-521 +// curves are rejected. + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +/** + * Tests a cert chain. + * + * @param {String} rootKeyType + * The key type of the root certificate, or the name of an elliptic + * curve, as output by the 'openssl ecparam -list_curves' command. + * @param {Number} rootKeySize + * @param {String} intKeyType + * @param {Number} intKeySize + * @param {String} eeKeyType + * @param {Number} eeKeySize + * @param {PRErrorCode} eeExpectedError + * @return {Promise} a promise that will resolve when the verification has + * completed + */ +function checkChain( + rootKeyType, + rootKeySize, + intKeyType, + intKeySize, + eeKeyType, + eeKeySize, + eeExpectedError +) { + let rootName = "root_" + rootKeyType + "_" + rootKeySize; + let intName = "int_" + intKeyType + "_" + intKeySize; + let eeName = "ee_" + eeKeyType + "_" + eeKeySize; + + let intFullName = intName + "-" + rootName; + let eeFullName = eeName + "-" + intName + "-" + rootName; + + addCertFromFile(certdb, `test_keysize/${rootName}.pem`, "CTu,CTu,CTu"); + addCertFromFile(certdb, `test_keysize/${intFullName}.pem`, ",,"); + let eeCert = constructCertFromFile(`test_keysize/${eeFullName}.pem`); + + info("cert o=" + eeCert.organization); + info("cert issuer o=" + eeCert.issuerOrganization); + return checkCertErrorGeneric( + certdb, + eeCert, + eeExpectedError, + certificateUsageSSLServer + ); +} + +/** + * Tests various RSA chains. + * + * @param {Number} inadequateKeySize + * @param {Number} adequateKeySize + */ +async function checkRSAChains(inadequateKeySize, adequateKeySize) { + // Chain with certs that have adequate sizes for DV + await checkChain( + "rsa", + adequateKeySize, + "rsa", + adequateKeySize, + "rsa", + adequateKeySize, + PRErrorCodeSuccess + ); + + // Chain with a root cert that has an inadequate size for DV + await checkChain( + "rsa", + inadequateKeySize, + "rsa", + adequateKeySize, + "rsa", + adequateKeySize, + MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE + ); + + // Chain with an intermediate cert that has an inadequate size for DV + await checkChain( + "rsa", + adequateKeySize, + "rsa", + inadequateKeySize, + "rsa", + adequateKeySize, + MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE + ); + + // Chain with an end entity cert that has an inadequate size for DV + await checkChain( + "rsa", + adequateKeySize, + "rsa", + adequateKeySize, + "rsa", + inadequateKeySize, + MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE + ); +} + +async function checkECCChains() { + await checkChain( + "secp256r1", + 256, + "secp384r1", + 384, + "secp521r1", + 521, + PRErrorCodeSuccess + ); + await checkChain( + "secp256r1", + 256, + "secp224r1", + 224, + "secp256r1", + 256, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); + await checkChain( + "secp256r1", + 256, + "secp256r1", + 256, + "secp224r1", + 224, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); + await checkChain( + "secp224r1", + 224, + "secp256r1", + 256, + "secp256r1", + 256, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); + await checkChain( + "secp256r1", + 256, + "secp256r1", + 256, + "secp256k1", + 256, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); + await checkChain( + "secp256k1", + 256, + "secp256r1", + 256, + "secp256r1", + 256, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); +} + +async function checkCombinationChains() { + await checkChain( + "rsa", + 2048, + "secp256r1", + 256, + "secp384r1", + 384, + PRErrorCodeSuccess + ); + await checkChain( + "rsa", + 2048, + "secp256r1", + 256, + "secp224r1", + 224, + SEC_ERROR_UNSUPPORTED_ELLIPTIC_CURVE + ); + await checkChain( + "secp256r1", + 256, + "rsa", + 1016, + "secp256r1", + 256, + MOZILLA_PKIX_ERROR_INADEQUATE_KEY_SIZE + ); +} + +add_task(async function() { + await checkRSAChains(1016, 1024); + await checkECCChains(); + await checkCombinationChains(); +}); diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem new file mode 100644 index 0000000000..a505fe3b6c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4DCCAUmgAwIBAgIUP87ifngF30j5hBghK5jGe5gcLtswDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50X3JzYV8xMDI0LXJvb3RfcnNhXzEwMjQwIhgPMjAx +OTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowMTEvMC0GA1UEAwwmZWVfcnNh +XzEwMTYtaW50X3JzYV8xMDI0LXJvb3RfcnNhXzEwMjQwgZ4wDQYJKoZIhvcNAQEB +BQADgYwAMIGIAoGAANKbsS+4T93NKbOlGctmxDuNj4vlRbp5OEzmY+0D33WZFgDr +kgeQ0lMM7OVE25mnHwWJaj7SBxZVNKqZBX5HxH47yBrab6HhLjcmi1BGpVJo+drX +zLSF2BouGdUNTwtoVKyvbXvmnZoIMTbhWvqPU8HIyE/GB3J53Q5V1zaaW90CAwEA +ATANBgkqhkiG9w0BAQsFAAOBgQCiWMxWN4+CamDzXDW90neja5RHg/pDlBI9pI+Q +NRyUycpJwN5Flv+/C+OCdmxH/dd15SeGiXCrjJQcSXFBeMD/1JK427SR1acE6z+W +qY+rYzJ+b68Dybx/4cj2VeFWpdMhZtttgvNrGfwGMbHs9gWG7n6wPKjg6h0OuThf +2TfVIw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..7b86ef7861 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem.certspec @@ -0,0 +1,4 @@ +issuer:int_rsa_1024-root_rsa_1024 +subject:ee_rsa_1016-int_rsa_1024-root_rsa_1024 +issuerKey:rsa1024 +subjectKey:rsa1016 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem new file mode 100644 index 0000000000..dadab2f898 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4DCCAUqgAwIBAgIUFclsTfsYyWNzZajFqzlMZX7fOHswDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50X3JzYV8xMDE2LXJvb3RfcnNhXzEwMjQwIhgPMjAx +OTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowMTEvMC0GA1UEAwwmZWVfcnNh +XzEwMjQtaW50X3JzYV8xMDE2LXJvb3RfcnNhXzEwMjQwgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBANOpdEAQHrqMXflQPm+TXrUv/rPr6dDcXKzib5c8qUy8DZwx +1mwMATvOnILQ1IAyjfBftrzXmQpTEt2uYVKtbuYcjBvdhmPGi9NiJKmIKueOifVW +39vm9R2mESy/wnyKSTNrQa/bdTIbUrJKc0TRNI5kY1GlUcdXHM2guP419hp1AgMB +AAEwDQYJKoZIhvcNAQELBQADgYAAy04O696YrNhCjvlDn3FEPZ1Ce4dmSvJQzw3U +A6nAq3PLq16WwopAus+b3fEXke5k/u+pYfM4+5X7XRDNZW9i+5nUQVmGgiEzG3TU ++WYwGa5V0z6xMXl39i0tIaY4irYwzEpA+DvbJOz/gExQ9dpP/LW5Y8rE0kdMvBbZ +Gz6gjw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..326d665dcc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem.certspec @@ -0,0 +1,4 @@ +issuer:int_rsa_1016-root_rsa_1024 +subject:ee_rsa_1024-int_rsa_1016-root_rsa_1024 +issuerKey:rsa1016 +subjectKey:rsa1024 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem new file mode 100644 index 0000000000..f540304e90 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICRjCCAa+gAwIBAgIUU7Z8PfJj0EkU6p/oJRcYHJt+uckwDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50X3JzYV8xMDI0LXJvb3RfcnNhXzEwMTYwIhgPMjAx +OTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowEjEQMA4GA1UEAwwHcnNhMTAy +NDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAATANBgkqhkiG9w0BAQsFAAOBgQAr4tqhlbfFvYm2bAmba+gdsk6+EwQ7 +I4qed6vUQfzFcNMSOFBfFLo5q6CG+UsZ06/Hl3YXDHOhVhZC5QANZRO9tEV59eGS +Hbo3lfSQF8zXJ99vc0q3vNJejGgU/74FjTXX54Pe7KhdUSSjUPEapvpkc2/Y8SFF +CcL9Lsz8hh7dQw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem.certspec new file mode 100644 index 0000000000..c44a089ed6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem.certspec @@ -0,0 +1,4 @@ +issuer:int_rsa_1024-root_rsa_1016 +subject:ee_rsa_1024-int_rsa_1024-root_rsa_1016 +issuerKey:rsa1024 +subject:rsa1024 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem new file mode 100644 index 0000000000..d9c8f4ea0a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB4TCCAUqgAwIBAgIUcbFravMReDSDzA6Uxk8BzwUwF2MwDQYJKoZIhvcNAQEL +BQAwJTEjMCEGA1UEAwwaaW50X3JzYV8xMDI0LXJvb3RfcnNhXzEwMjQwIhgPMjAx +OTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowMTEvMC0GA1UEAwwmZWVfcnNh +XzEwMjQtaW50X3JzYV8xMDI0LXJvb3RfcnNhXzEwMjQwgZ8wDQYJKoZIhvcNAQEB +BQADgY0AMIGJAoGBANOpdEAQHrqMXflQPm+TXrUv/rPr6dDcXKzib5c8qUy8DZwx +1mwMATvOnILQ1IAyjfBftrzXmQpTEt2uYVKtbuYcjBvdhmPGi9NiJKmIKueOifVW +39vm9R2mESy/wnyKSTNrQa/bdTIbUrJKc0TRNI5kY1GlUcdXHM2guP419hp1AgMB +AAEwDQYJKoZIhvcNAQELBQADgYEABBfO6S+wGG0HKRb07V+bQpV8eiARnq5ZzoDV +EpfClXnyorjhuU4sYuzvTUMUcKF5lSmiCF9yl4zSoV8fiDJY2qScZ2C+xMSXnf/7 +plub8Pu0oaSb0KSWSSvon4DDbjSpNfQ/QZZkjvtj2wwK9XVK/7aiZ2e7NuGwOLrd +tTs3wec= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..a6ee408ec9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem.certspec @@ -0,0 +1,4 @@ +issuer:int_rsa_1024-root_rsa_1024 +subject:ee_rsa_1024-int_rsa_1024-root_rsa_1024 +issuerKey:rsa1024 +subjectKey:rsa1024 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem new file mode 100644 index 0000000000..20b43091bd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBXDCCAQOgAwIBAgIUOZ6qI6KmpVBIQuNSmsJSrHJ2W1gwCgYIKoZIzj0EAwIw +KjEoMCYGA1UEAwwfaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9yc2FfMjA0ODAiGA8y +MDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjA7MTkwNwYDVQQDDDBlZV9z +ZWNwMjI0cjFfMjI0LWludF9zZWNwMjU2cjFfMjU2LXJvb3RfcnNhXzIwNDgwTTAQ +BgcqhkjOPQIBBgUrgQQAIQM5AARmjXLMpv1qGzVXtTZhBNhECOy2N/COjIa7/4LM +6I8AZtevY8Mpi6N3NIoSArA7N/1rH/QVqjEeMAoGCCqGSM49BAMCA0cAMEQCIFx1 +UZ8TEVDNXYreIKO8BjCR/7JzdV8xZOz9y0KACnDmAiBvUw1d8jQrTL7jxcshvTvj +a/7XJT41KYCZC4kHc1sn8A== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem.certspec new file mode 100644 index 0000000000..87d2f67339 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_rsa_2048 +subject:ee_secp224r1_224-int_secp256r1_256-root_rsa_2048 +issuerKey:secp256r1 +subjectKey:secp224r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem new file mode 100644 index 0000000000..6e00e043be --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBZzCCAQ2gAwIBAgIUQd9nJAnSoGdsru1U5XzdnZSmQngwCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2cjFfMjU2 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3AyMjRyMV8yMjQtaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2 +cjFfMjU2ME0wEAYHKoZIzj0CAQYFK4EEACEDOQAEZo1yzKb9ahs1V7U2YQTYRAjs +tjfwjoyGu/+CzOiPAGbXr2PDKYujdzSKEgKwOzf9ax/0FaoxHjAKBggqhkjOPQQD +AgNIADBFAiBcdVGfExFQzV2K3iCjvAYwkf+yc3VfMWTs/ctCgApw5gIhAIgKiG6Y +Wn7JOkWTie+T+AVcLVZU1CT171W8r/AtOYkq +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..1aadce0765 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_secp256r1_256 +subject:ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp224r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem new file mode 100644 index 0000000000..0de0ebca77 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBbzCCARagAwIBAgIUF4GiHggPJErLtUU4O82JTDsn9/UwCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2cjFfMjU2 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3AyNTZrMV8yNTYtaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2 +cjFfMjU2MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAENe58conY/veoav5dpm2Lwuu2 +qFQ/0v6tCJ9FznrND6ZDgqlQDEHa13D/1LURv0tJLrEjiADDLE92xzo/MpTnxTAK +BggqhkjOPQQDAgNHADBEAiBcdVGfExFQzV2K3iCjvAYwkf+yc3VfMWTs/ctCgApw +5gIgUp27SDHsVOPJ3xOj87plJRqBLZ/mkOWbhZjp8SUTsVs= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..ba999e8f14 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_secp256r1_256 +subject:ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp256k1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem new file mode 100644 index 0000000000..083641b7c4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBqDCCARKgAwIBAgIUJd4SuF585qlYm74gqnZsBTfIYhQwDQYJKoZIhvcNAQEL +BQAwKjEoMCYGA1UEAwwfaW50X3JzYV8xMDE2LXJvb3Rfc2VjcDI1NnIxXzI1NjAi +GA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjA7MTkwNwYDVQQDDDBl +ZV9zZWNwMjU2cjFfMjU2LWludF9yc2FfMTAxNi1yb290X3NlY3AyNTZyMV8yNTYw +WTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARPv7u7YeD4+bGmClmshwTi7AULQj48 +9y6SPyxPeUtFXCpp0jNFbDbEEZ0HBuAO7cjRk5DXmRt7LQejBOqgSqbAMA0GCSqG +SIb3DQEBCwUAA4GAAH+y3CZOoy2Z3zegsj4EmKuwAYBRm7WjV7J7gM2Bak6JaycQ +NhA2hAd3z3vLEVNlgw0b/WM6lVBNH6fFXikKEzNBytofZtxFqRH66J0qc/CAbmw5 +fG8rkHL4vrDQ1vr3Lyh/qbGXZJxPd2lbFk029o8BkBZADra8QcPuD2EHmDk= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..1e2e0a3759 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem.certspec @@ -0,0 +1,4 @@ +issuer:int_rsa_1016-root_secp256r1_256 +subject:ee_secp256r1_256-int_rsa_1016-root_secp256r1_256 +issuerKey:rsa1016 +subjectKey:secp256r1 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem new file mode 100644 index 0000000000..1bf347fc08 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBazCCARmgAwIBAgIUF+3Ha/HblkQ9RVAnd5VUa5BPQ2YwCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AyMjRyMV8yMjQtcm9vdF9zZWNwMjU2cjFfMjU2 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3AyNTZyMV8yNTYtaW50X3NlY3AyMjRyMV8yMjQtcm9vdF9zZWNwMjU2 +cjFfMjU2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET7+7u2Hg+PmxpgpZrIcE +4uwFC0I+PPcukj8sT3lLRVwqadIzRWw2xBGdBwbgDu3I0ZOQ15kbey0HowTqoEqm +wDAKBggqhkjOPQQDAgNAADA9Ah0Amjxv8EbbcPJV9S/WmFIc1y28BSBjT5W2S7JS +VAIcL1LLWdbRbY2jphtXTfe1/t7vRvZlRgQPxxlSrg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..bd7bc770c7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp224r1_224-root_secp256r1_256 +subject:ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256 +issuerKey:secp224r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem new file mode 100644 index 0000000000..5f4a80948f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBcjCCARmgAwIBAgIUUfZawfrAes7uJnC3lbyou+3HboEwCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjI0cjFfMjI0 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3AyNTZyMV8yNTYtaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjI0 +cjFfMjI0MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET7+7u2Hg+PmxpgpZrIcE +4uwFC0I+PPcukj8sT3lLRVwqadIzRWw2xBGdBwbgDu3I0ZOQ15kbey0HowTqoEqm +wDAKBggqhkjOPQQDAgNHADBEAiBcdVGfExFQzV2K3iCjvAYwkf+yc3VfMWTs/ctC +gApw5gIgbc9p70u5ogMPqCSTG4IpDnjR+Cguf8a+8Erbgfur7Dg= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem.certspec new file mode 100644 index 0000000000..fe7b7f7482 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_secp224r1_224 +subject:ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224 +issuerKey:secp256r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem new file mode 100644 index 0000000000..b13b1fb264 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBcjCCARmgAwIBAgIUdduB4Waw8NoEQbwRm8oYqzYqyF8wCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2azFfMjU2 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3AyNTZyMV8yNTYtaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9zZWNwMjU2 +azFfMjU2MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET7+7u2Hg+PmxpgpZrIcE +4uwFC0I+PPcukj8sT3lLRVwqadIzRWw2xBGdBwbgDu3I0ZOQ15kbey0HowTqoEqm +wDAKBggqhkjOPQQDAgNHADBEAiBcdVGfExFQzV2K3iCjvAYwkf+yc3VfMWTs/ctC +gApw5gIgKk16br1bktVUX0hUgSKha7mCXqcLm2OqbEfhnnvTGQI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem.certspec new file mode 100644 index 0000000000..aefffd9810 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_secp256k1_256 +subject:ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256 +issuerKey:secp256r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem new file mode 100644 index 0000000000..a3aa1bccba --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBhTCCASygAwIBAgIUP57NpzW0TiQ7Dv+Eu/Jsec7uG1EwCgYIKoZIzj0EAwIw +KjEoMCYGA1UEAwwfaW50X3NlY3AyNTZyMV8yNTYtcm9vdF9yc2FfMjA0ODAiGA8y +MDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjA7MTkwNwYDVQQDDDBlZV9z +ZWNwMzg0cjFfMzg0LWludF9zZWNwMjU2cjFfMjU2LXJvb3RfcnNhXzIwNDgwdjAQ +BgcqhkjOPQIBBgUrgQQAIgNiAAShaHJDNitcexiJ83kVRhWhxz+0je6GPgIpFdtg +jiUt5LcTLajOmOgxU05qnAwLCcjWOa3oMgbluoE0c6EfozDgXajJbkOD/ieHPalx +A74oiM/wAvBa9xof3cyDdKpuqc4wCgYIKoZIzj0EAwIDRwAwRAIgXHVRnxMRUM1d +it4go7wGMJH/snN1XzFk7P3LQoAKcOYCIFJ475L6BSzMQmSQ4of5j0VvzGWLlc4p +P7WljL/PnuoG +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem.certspec new file mode 100644 index 0000000000..615818d08b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp256r1_256-root_rsa_2048 +subject:ee_secp384r1_384-int_secp256r1_256-root_rsa_2048 +issuerKey:secp256r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem new file mode 100644 index 0000000000..fa2b1196d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB1zCCAVygAwIBAgIUZSV+XPsVuShLaoK1fI9SUQtuqpUwCgYIKoZIzj0EAwIw +LzEtMCsGA1UEAwwkaW50X3NlY3AzODRyMV8zODQtcm9vdF9zZWNwMjU2cjFfMjU2 +MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEAxPjA8BgNVBAMM +NWVlX3NlY3A1MjFyMV81MjEtaW50X3NlY3AzODRyMV8zODQtcm9vdF9zZWNwMjU2 +cjFfMjU2MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBTNycrMR5QQlrycxmdS7C +f1l3NPpmxit5L4jFGdbTfw0W6hxIOhgnoBC5Eo46CAcMoz719Xg1t8G6JR9sw1Id +xCsBBlNFGYG0RdND7tN4KjXWz/D/SE9aiD0gnxuQQrcmcDVosvMm4YuDO92KoHND +krzRlQHhDWmKefU+EeCiK90qrZAwCgYIKoZIzj0EAwIDaQAwZgIxAO0GJz6haDpU +tNgaQ3SESJY85j6+gRcD7Nc9cvCiVAZZ1OxFRuhW515lVbeTqfcA8wIxAKIisY3l ++oJ2fwRVdjaU3+DIoB72CX208Piq2hSKjF8eVtEHV2liiAfQoH9ktR+0mw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..b2ae9d0c8f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem.certspec @@ -0,0 +1,5 @@ +issuer:int_secp384r1_384-root_secp256r1_256 +subject:ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256 +issuerKey:secp384r1 +subjectKey:secp521r1 +signature:ecdsaWithSHA256 diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem new file mode 100644 index 0000000000..c63c086abb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5jCCAU+gAwIBAgIUN856fz51l3lVM7u/s/R3tvFzxkgwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMTAyNDAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAlMSMwIQYDVQQDDBppbnRfcnNhXzEwMTYtcm9vdF9y +c2FfMTAyNDCBnjANBgkqhkiG9w0BAQEFAAOBjAAwgYgCgYAA0puxL7hP3c0ps6UZ +y2bEO42Pi+VFunk4TOZj7QPfdZkWAOuSB5DSUwzs5UTbmacfBYlqPtIHFlU0qpkF +fkfEfjvIGtpvoeEuNyaLUEalUmj52tfMtIXYGi4Z1Q1PC2hUrK9te+admggxNuFa ++o9TwcjIT8YHcnndDlXXNppb3QIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1Ud +DwQEAwIBBjANBgkqhkiG9w0BAQsFAAOBgQAwJyIekNQXnajDVspHOAAsNBkPw0MW +Q8r7OPH9Q9ZzXkz1oXHdwnEXyW4uIOhBYKRvtaqEEQI3SXvV72d5gKIXbP2cf/mQ +RLRS0GBsy1ulg2w4dSvkwkwFgeYZ+BxM5+esVECzFKZsXrPUcYraymqurqdZcAxy +0edmg/yt37w8zA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..c6e77116b7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_rsa_1024.pem.certspec @@ -0,0 +1,6 @@ +issuer:root_rsa_1024 +subject:int_rsa_1016-root_rsa_1024 +issuerKey:rsa1024 +subjectKey:rsa1016 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem new file mode 100644 index 0000000000..a47ac14370 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIBsDCCAVagAwIBAgIUe0w3IjAYBfw32mIJMH/pETsJGAcwCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2cjFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMCoxKDAmBgNVBAMMH2ludF9yc2FfMTAxNi1yb290 +X3NlY3AyNTZyMV8yNTYwgZ4wDQYJKoZIhvcNAQEBBQADgYwAMIGIAoGAANKbsS+4 +T93NKbOlGctmxDuNj4vlRbp5OEzmY+0D33WZFgDrkgeQ0lMM7OVE25mnHwWJaj7S +BxZVNKqZBX5HxH47yBrab6HhLjcmi1BGpVJo+drXzLSF2BouGdUNTwtoVKyvbXvm +nZoIMTbhWvqPU8HIyE/GB3J53Q5V1zaaW90CAwEAAaMdMBswDAYDVR0TBAUwAwEB +/zALBgNVHQ8EBAMCAQYwCgYIKoZIzj0EAwIDSAAwRQIgXHVRnxMRUM1dit4go7wG +MJH/snN1XzFk7P3LQoAKcOYCIQCPyLXUG26XZLO3nMf58EJ2Ej+o+gXDAllaLBW5 +2nS+jA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..27728ca374 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1016-root_secp256r1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256r1_256 +subject:int_rsa_1016-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:rsa1016 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem new file mode 100644 index 0000000000..812e259332 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5jCCAVCgAwIBAgIUeZhovVNDUuRN9h3SwWVSaVKNv14wDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMTAxNjAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAlMSMwIQYDVQQDDBppbnRfcnNhXzEwMjQtcm9vdF9y +c2FfMTAxNjCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06l0QBAeuoxd+VA+ +b5NetS/+s+vp0NxcrOJvlzypTLwNnDHWbAwBO86cgtDUgDKN8F+2vNeZClMS3a5h +Uq1u5hyMG92GY8aL02IkqYgq546J9Vbf2+b1HaYRLL/CfIpJM2tBr9t1MhtSskpz +RNE0jmRjUaVRx1cczaC4/jX2GnUCAwEAAaMdMBswDAYDVR0TBAUwAwEB/zALBgNV +HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYAAximjztC//bRBDGD/zQzHBU9DC2CR +cfdN0A7LgtHgyue5DFtdj1RRioj3ZLIfEgMLi+gESTmZPH1YkMExF2xCJRBdTu3O +dweani8aTdLWSF3ikt00jCSGH1kiPjWM9pRXhLEz62VW4yvxFt4eVB1xmM5VPOwZ +B9EHfdS8AeaNVw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem.certspec new file mode 100644 index 0000000000..fafb393bf9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1016.pem.certspec @@ -0,0 +1,6 @@ +issuer:root_rsa_1016 +subject:int_rsa_1024-root_rsa_1016 +issuerKey:rsa1016 +subjectKey:rsa1024 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem new file mode 100644 index 0000000000..45d9ac8ee2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem @@ -0,0 +1,13 @@ +-----BEGIN CERTIFICATE----- +MIIB5zCCAVCgAwIBAgIUYcS07xR3ydcgKjUYhNFcmIw+FKQwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMTAyNDAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAlMSMwIQYDVQQDDBppbnRfcnNhXzEwMjQtcm9vdF9y +c2FfMTAyNDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEA06l0QBAeuoxd+VA+ +b5NetS/+s+vp0NxcrOJvlzypTLwNnDHWbAwBO86cgtDUgDKN8F+2vNeZClMS3a5h +Uq1u5hyMG92GY8aL02IkqYgq546J9Vbf2+b1HaYRLL/CfIpJM2tBr9t1MhtSskpz +RNE0jmRjUaVRx1cczaC4/jX2GnUCAwEAAaMdMBswDAYDVR0TBAUwAwEB/zALBgNV +HQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADgYEAzgSst5WpRJFjBpDYQ+/oQE99sYmc +JZ6lA2Lf5kFDMXb/bF7jf0/FbEheFNRHs+I5kc95lPbwyzpA2bQ3TK9jzFpoDTjK +kPYnXKn0xa+H7mUS4V6VQh28GdBcWffLZC8vBkB+DKR6N3M2s7erDZjEA8PodKUd +dR5G85B8pwswVJM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..66891f9793 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_rsa_1024-root_rsa_1024.pem.certspec @@ -0,0 +1,6 @@ +issuer:root_rsa_1024 +subject:int_rsa_1024-root_rsa_1024 +issuerKey:rsa1024 +subjectKey:rsa1024 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem new file mode 100644 index 0000000000..04d2564718 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBYjCCAQmgAwIBAgIUZf9BUQycH51qhAjba7oMtj+YWtowCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2cjFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMjI0cjFfMjI0 +LXJvb3Rfc2VjcDI1NnIxXzI1NjBNMBAGByqGSM49AgEGBSuBBAAhAzkABGaNcsym +/WobNVe1NmEE2EQI7LY38I6Mhrv/gszojwBm169jwymLo3c0ihICsDs3/Wsf9BWq +MR6jHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoGCCqGSM49BAMCA0cA +MEQCIFx1UZ8TEVDNXYreIKO8BjCR/7JzdV8xZOz9y0KACnDmAiAgvRpeJMeD41PQ +ydWsdlfwmrgnjM+Vn+bBX0ty9NcEEA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..89d77d3b89 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp224r1_224-root_secp256r1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256r1_256 +subject:int_secp224r1_224-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp224r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem new file mode 100644 index 0000000000..e5e8f573fd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem @@ -0,0 +1,14 @@ +-----BEGIN CERTIFICATE----- +MIICJjCCAQ6gAwIBAgIUG/u+QDiBCAoaoWJYvqL0uwY1/iIwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMjA0ODAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAqMSgwJgYDVQQDDB9pbnRfc2VjcDI1NnIxXzI1Ni1y +b290X3JzYV8yMDQ4MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAET7+7u2Hg+Pmx +pgpZrIcE4uwFC0I+PPcukj8sT3lLRVwqadIzRWw2xBGdBwbgDu3I0ZOQ15kbey0H +owTqoEqmwKMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcN +AQELBQADggEBADJyKAFPb7ilK80rDDSGNqf7ls/rpElvmhpVJvivJ3Yv1DRm7EEM +38mwE14TcmayyOS+0avA4gDqH7T9du5NhNWMfluNediBjzl2CgFgXXjSsE7sr1py +RAi3nYSnUiih6k9Q4a69RteD6FigfSfO0w0nrmLi+njkSVqJ+0pSvnmvf2RKBK9H +i0VR2oFjoEM/cyxibv1ETqaT6V0CWZSAu6IMT7gpmvvkF5Ti7+KeXXkbuZuQTqIo +ow/zOhW7aMK24jGDKBLwunbh4EeLyWWtIy88ZNbdGmJkf7+s+/km6DziS9TkcQxn +tCUR7ze5cYRZ49TNfAcQC0ogdokgo1Cag+U= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem.certspec new file mode 100644 index 0000000000..44a65ef5a7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_rsa_2048.pem.certspec @@ -0,0 +1,5 @@ +issuer:root_rsa_2048 +subject:int_secp256r1_256-root_rsa_2048 +subjectKey:secp256r1 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem new file mode 100644 index 0000000000..d4d73c25da --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBaDCCARWgAwIBAgIULWja0CElNsf9uHoMLXihbb0y8dMwCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjI0cjFfMjI0MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMjU2cjFfMjU2 +LXJvb3Rfc2VjcDIyNHIxXzIyNDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/ +u7th4Pj5saYKWayHBOLsBQtCPjz3LpI/LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGT +kNeZG3stB6ME6qBKpsCjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoG +CCqGSM49BAMCA0EAMD4CHQCaPG/wRttw8lX1L9aYUhzXLbwFIGNPlbZLslJUAh0A +4ZWHxPcxexTE/kShvISJeBka5jGQ1baqxDM6ng== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem.certspec new file mode 100644 index 0000000000..66ebc1b93e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp224r1_224.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp224r1_224 +subject:int_secp256r1_256-root_secp224r1_224 +issuerKey:secp224r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem new file mode 100644 index 0000000000..8a69c3e52a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBbzCCARWgAwIBAgIUeQnFuTzLPx3FrBWD3ouZIpqXfFUwCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2azFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMjU2cjFfMjU2 +LXJvb3Rfc2VjcDI1NmsxXzI1NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/ +u7th4Pj5saYKWayHBOLsBQtCPjz3LpI/LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGT +kNeZG3stB6ME6qBKpsCjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoG +CCqGSM49BAMCA0gAMEUCIFuwodUwyOUnIR4KN5ZCSrU7y4iz4/1EWRdHm5kWKi8d +AiEA8M23PrqXz5+5jx1UeQEuaN+Q4ln3gT+XclPmR9P82tA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem.certspec new file mode 100644 index 0000000000..c7e190ab0b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256k1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256k1_256 +subject:int_secp256r1_256-root_secp256k1_256 +issuerKey:secp256k1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem new file mode 100644 index 0000000000..a060a6fe1c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBbjCCARWgAwIBAgIUS3I7amSSwFamYMLcx8D/W1zjoCowCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2cjFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMjU2cjFfMjU2 +LXJvb3Rfc2VjcDI1NnIxXzI1NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/ +u7th4Pj5saYKWayHBOLsBQtCPjz3LpI/LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGT +kNeZG3stB6ME6qBKpsCjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoG +CCqGSM49BAMCA0cAMEQCIFx1UZ8TEVDNXYreIKO8BjCR/7JzdV8xZOz9y0KACnDm +AiBnPZ/DApW1c90gQo+deVHt8TrmT4zNesvqmTzEpU4Tkg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..6854d21876 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp256r1_256-root_secp256r1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256r1_256 +subject:int_secp256r1_256-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem new file mode 100644 index 0000000000..8e43a8e0d6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE----- +MIIBizCCATKgAwIBAgIUIwvMnx4+Cfvo4LHUHSyx8+OIpLIwCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2cjFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMC8xLTArBgNVBAMMJGludF9zZWNwMzg0cjFfMzg0 +LXJvb3Rfc2VjcDI1NnIxXzI1NjB2MBAGByqGSM49AgEGBSuBBAAiA2IABKFockM2 +K1x7GInzeRVGFaHHP7SN7oY+AikV22COJS3ktxMtqM6Y6DFTTmqcDAsJyNY5regy +BuW6gTRzoR+jMOBdqMluQ4P+J4c9qXEDviiIz/AC8Fr3Gh/dzIN0qm6pzqMdMBsw +DAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwCgYIKoZIzj0EAwIDRwAwRAIgXHVR +nxMRUM1dit4go7wGMJH/snN1XzFk7P3LQoAKcOYCIEefciT9jaPnIvEiHC2ktArf +XGf7h0FGlxLkN9YhKmZ1 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..de8e851981 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/int_secp384r1_384-root_secp256r1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256r1_256 +subject:int_secp384r1_384-root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp384r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/moz.build b/security/manager/ssl/tests/unit/test_keysize/moz.build new file mode 100644 index 0000000000..80b3152dac --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/moz.build @@ -0,0 +1,41 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ee_rsa_1016-int_rsa_1024-root_rsa_1024.pem', +# 'ee_rsa_1024-int_rsa_1016-root_rsa_1024.pem', +# 'ee_rsa_1024-int_rsa_1024-root_rsa_1016.pem', +# 'ee_rsa_1024-int_rsa_1024-root_rsa_1024.pem', +# 'ee_secp224r1_224-int_secp256r1_256-root_rsa_2048.pem', +# 'ee_secp224r1_224-int_secp256r1_256-root_secp256r1_256.pem', +# 'ee_secp256k1_256-int_secp256r1_256-root_secp256r1_256.pem', +# 'ee_secp256r1_256-int_rsa_1016-root_secp256r1_256.pem', +# 'ee_secp256r1_256-int_secp224r1_224-root_secp256r1_256.pem', +# 'ee_secp256r1_256-int_secp256r1_256-root_secp224r1_224.pem', +# 'ee_secp256r1_256-int_secp256r1_256-root_secp256k1_256.pem', +# 'ee_secp384r1_384-int_secp256r1_256-root_rsa_2048.pem', +# 'ee_secp521r1_521-int_secp384r1_384-root_secp256r1_256.pem', +# 'int_rsa_1016-root_rsa_1024.pem', +# 'int_rsa_1016-root_secp256r1_256.pem', +# 'int_rsa_1024-root_rsa_1016.pem', +# 'int_rsa_1024-root_rsa_1024.pem', +# 'int_secp224r1_224-root_secp256r1_256.pem', +# 'int_secp256r1_256-root_rsa_2048.pem', +# 'int_secp256r1_256-root_secp224r1_224.pem', +# 'int_secp256r1_256-root_secp256k1_256.pem', +# 'int_secp256r1_256-root_secp256r1_256.pem', +# 'int_secp384r1_384-root_secp256r1_256.pem', +# 'root_rsa_1016.pem', +# 'root_rsa_1024.pem', +# 'root_rsa_2048.pem', +# 'root_secp224r1_224.pem', +# 'root_secp256k1_256.pem', +# 'root_secp256r1_256.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem new file mode 100644 index 0000000000..42064fb0b4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB2DCCAUKgAwIBAgIUbY90vJ4/+tgc8hsO+VMaaSWW1kgwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMTAxNjAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAYMRYwFAYDVQQDDA1yb290X3JzYV8xMDE2MIGeMA0G +CSqGSIb3DQEBAQUAA4GMADCBiAKBgADSm7EvuE/dzSmzpRnLZsQ7jY+L5UW6eThM +5mPtA991mRYA65IHkNJTDOzlRNuZpx8FiWo+0gcWVTSqmQV+R8R+O8ga2m+h4S43 +JotQRqVSaPna18y0hdgaLhnVDU8LaFSsr2175p2aCDE24Vr6j1PByMhPxgdyed0O +Vdc2mlvdAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqG +SIb3DQEBCwUAA4GAAIV+rBvvS1MrBSnjxfYBmX/Kp4bWEXtrStskD9xfyKkmWVxO +9NxHmA7L3NTqxkYgzfANE1OdFSd+mKK/Bx/xDCUgfRIQZCPZId4GLGl+gRq25R6X +V3IV53b8UHiGJP0ASJbXUqTQF/7fZvuvBLBDgg9nXObe3ZwHUgWfc3I974I= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem.certspec new file mode 100644 index 0000000000..b0b5ba8e5e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1016.pem.certspec @@ -0,0 +1,6 @@ +issuer:root_rsa_1016 +subject:root_rsa_1016 +issuerKey:rsa1016 +subjectKey:rsa1016 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem new file mode 100644 index 0000000000..7262a5cfb0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem @@ -0,0 +1,12 @@ +-----BEGIN CERTIFICATE----- +MIIB2jCCAUOgAwIBAgIUEWZ1ZXY8sKYaumyn9kCsWK1AEZMwDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMTAyNDAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAYMRYwFAYDVQQDDA1yb290X3JzYV8xMDI0MIGfMA0G +CSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTqXRAEB66jF35UD5vk161L/6z6+nQ3Fys +4m+XPKlMvA2cMdZsDAE7zpyC0NSAMo3wX7a815kKUxLdrmFSrW7mHIwb3YZjxovT +YiSpiCrnjon1Vt/b5vUdphEsv8J8ikkza0Gv23UyG1KySnNE0TSOZGNRpVHHVxzN +oLj+NfYadQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkq +hkiG9w0BAQsFAAOBgQBL16xkIAjU8a2lPy+Ax4N6OjeTrT+pBbj90/ynUiRuEYkI +GR0Qpv2vcKoFBGIywsJm61z6VRojuaoZGww4D1xlKaHp4R2DmPQYPG/EsUcPdyNK +MszBmNHK+gRG0HoR4XJUIFMIfnF2R9m9vpVK1XPikLA10UlETdnp9tGuYIXcQw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem.certspec new file mode 100644 index 0000000000..09cd420f70 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_1024.pem.certspec @@ -0,0 +1,6 @@ +issuer:root_rsa_1024 +subject:root_rsa_1024 +issuerKey:rsa1024 +subjectKey:rsa1024 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem b/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem new file mode 100644 index 0000000000..82c625161f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIUFbP+AdxwM3PsfxQino2TeiJLnW4wDQYJKoZIhvcNAQEL +BQAwGDEWMBQGA1UEAwwNcm9vdF9yc2FfMjA0ODAiGA8yMDE5MTEyODAwMDAwMFoY +DzIwMjIwMjA1MDAwMDAwWjAYMRYwFAYDVQQDDA1yb290X3JzYV8yMDQ4MIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +ox0wGzAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOC +AQEAt1vYMFhLBuETUi2evjncIdzhu8cAqvqnN9WdB/SWL/PsS3cwGb6zu03fxkvZ +/z07qSs/ojSUR1I70S23NDcmX5Q2vToo8H3Zks2MS+AI0BPVnxo+RllO+zOqMYOQ +LPGJ+o9M6TGbL/jzYRhCWdF64jOnzgRFN1LU56fWYJLXMwIBHMQ/qMokiDkfc4pG +O3TOeJHAlfm49pJ1VhTZv3otCel+EkTa7mv0TTaJ+su0/zxgNFtUYWGcCuBJ95hi +t6Zh6GpOq0ML6NtZK7vMB7BvCIwihU3Fq2ApAiIq/I4tk9ROTvwKCNW6THQ+3+YH +eSUgFEYNH1T1dcCjsdthf9sKJw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem.certspec new file mode 100644 index 0000000000..cebc2f8e6a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_rsa_2048.pem.certspec @@ -0,0 +1,4 @@ +issuer:root_rsa_2048 +subject:root_rsa_2048 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem b/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem new file mode 100644 index 0000000000..a3945cf4c9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem @@ -0,0 +1,9 @@ +-----BEGIN CERTIFICATE----- +MIIBSTCB96ADAgECAhRLUpJGgls27Ph+GqVq1TzwkXgSPTAKBggqhkjOPQQDAjAd +MRswGQYDVQQDDBJyb290X3NlY3AyMjRyMV8yMjQwIhgPMjAxOTExMjgwMDAwMDBa +GA8yMDIyMDIwNTAwMDAwMFowHTEbMBkGA1UEAwwScm9vdF9zZWNwMjI0cjFfMjI0 +ME0wEAYHKoZIzj0CAQYFK4EEACEDOQAEZo1yzKb9ahs1V7U2YQTYRAjstjfwjoyG +u/+CzOiPAGbXr2PDKYujdzSKEgKwOzf9ax/0FaoxHqMdMBswDAYDVR0TBAUwAwEB +/zALBgNVHQ8EBAMCAQYwCgYIKoZIzj0EAwIDQQAwPgIdAJo8b/BG23DyVfUv1phS +HNctvAUgY0+VtkuyUlQCHQDZkK9gapfJf6mFLQZOVyj5QrFII+O1AhmojjBO +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem.certspec new file mode 100644 index 0000000000..31370f6f73 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp224r1_224.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp224r1_224 +subject:root_secp224r1_224 +issuerKey:secp224r1 +subjectKey:secp224r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem b/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem new file mode 100644 index 0000000000..0067d0297c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBWjCCAQCgAwIBAgIUExiTXNGw/1/DWr3T+8iOfYQqhoYwCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2azFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMB0xGzAZBgNVBAMMEnJvb3Rfc2VjcDI1NmsxXzI1 +NjBWMBAGByqGSM49AgEGBSuBBAAKA0IABDXufHKJ2P73qGr+XaZti8LrtqhUP9L+ +rQifRc56zQ+mQ4KpUAxB2tdw/9S1Eb9LSS6xI4gAwyxPdsc6PzKU58WjHTAbMAwG +A1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoGCCqGSM49BAMCA0gAMEUCIFuwodUw +yOUnIR4KN5ZCSrU7y4iz4/1EWRdHm5kWKi8dAiEA5z1yM2Xj8Xz+mTzaSV3Ic3Xi +wEJTXssXlwfECKILxX8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem.certspec new file mode 100644 index 0000000000..c78aa61bba --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp256k1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256k1_256 +subject:root_secp256k1_256 +issuerKey:secp256k1 +subjectKey:secp256k1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem b/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem new file mode 100644 index 0000000000..c8e8fd20a4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBXDCCAQOgAwIBAgIUH8NJbu+U7yxLh2580Q2Bh0WUOX0wCgYIKoZIzj0EAwIw +HTEbMBkGA1UEAwwScm9vdF9zZWNwMjU2cjFfMjU2MCIYDzIwMTkxMTI4MDAwMDAw +WhgPMjAyMjAyMDUwMDAwMDBaMB0xGzAZBgNVBAMMEnJvb3Rfc2VjcDI1NnIxXzI1 +NjBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABE+/u7th4Pj5saYKWayHBOLsBQtC +Pjz3LpI/LE95S0VcKmnSM0VsNsQRnQcG4A7tyNGTkNeZG3stB6ME6qBKpsCjHTAb +MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoGCCqGSM49BAMCA0cAMEQCIFx1 +UZ8TEVDNXYreIKO8BjCR/7JzdV8xZOz9y0KACnDmAiA1QYiu/g1qUtMLwoIqOMYb +Qi7ckS6Dd1TkOR0kW1dGAw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem.certspec b/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem.certspec new file mode 100644 index 0000000000..4447fc4b47 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize/root_secp256r1_256.pem.certspec @@ -0,0 +1,7 @@ +issuer:root_secp256r1_256 +subject:root_secp256r1_256 +issuerKey:secp256r1 +subjectKey:secp256r1 +signature:ecdsaWithSHA256 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize_ev.js b/security/manager/ssl/tests/unit/test_keysize_ev.js new file mode 100644 index 0000000000..60ebf99f82 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev.js @@ -0,0 +1,171 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Checks that RSA certs with key sizes below 2048 bits when verifying for EV +// are rejected. + +do_get_profile(); // Must be called before getting nsIX509CertDB +const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const SERVER_PORT = 8888; + +function getOCSPResponder(expectedCertNames) { + let expectedPaths = expectedCertNames.slice(); + return startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_keysize_ev/", + expectedCertNames, + expectedPaths + ); +} + +function loadCert(certName, trustString) { + let certFilename = "test_keysize_ev/" + certName + ".pem"; + addCertFromFile(certDB, certFilename, trustString); + return constructCertFromFile(certFilename); +} + +/** + * Asynchronously runs a single EV key size test. + * + * @param {Array} expectedNamesForOCSP + * An array of nicknames of the certs to be responded to. + * @param {String} rootCertFileName + * The file name of the root cert. Can begin with ".." to reference + * certs in folders other than "test_keysize_ev/". + * @param {Array} intCertFileNames + * An array of file names of any intermediate certificates. + * @param {String} endEntityCertFileName + * The file name of the end entity cert. + * @param {Boolean} expectedResult + * Whether the chain is expected to validate as EV. + */ +async function keySizeTestForEV( + expectedNamesForOCSP, + rootCertFileName, + intCertFileNames, + endEntityCertFileName, + expectedResult +) { + clearOCSPCache(); + let ocspResponder = getOCSPResponder(expectedNamesForOCSP); + + loadCert(rootCertFileName, "CTu,CTu,CTu"); + for (let intCertFileName of intCertFileNames) { + loadCert(intCertFileName, ",,"); + } + await checkEVStatus( + certDB, + constructCertFromFile(`test_keysize_ev/${endEntityCertFileName}.pem`), + certificateUsageSSLServer, + expectedResult + ); + + await stopOCSPResponder(ocspResponder); +} + +/** + * For debug builds which have the test EV roots compiled in, checks RSA chains + * which contain certs with key sizes adequate for EV are validated as such, + * while chains that contain any cert with an inadequate key size fail EV and + * validate as DV. + * For opt builds which don't have the test EV roots compiled in, checks that + * none of the chains validate as EV. + * + * Note: This function assumes that the key size requirements for EV are greater + * than the requirements for DV. + * + * @param {Number} inadequateKeySize + * The inadequate key size of the generated certs. + * @param {Number} adequateKeySize + * The adequate key size of the generated certs. + */ +async function checkRSAChains(inadequateKeySize, adequateKeySize) { + // Reuse the existing test RSA EV root + let rootOKCertFileName = "../test_ev_certs/evroot"; + let rootOKName = "evroot"; + let rootNotOKName = "ev_root_rsa_" + inadequateKeySize; + let intOKName = "ev_int_rsa_" + adequateKeySize; + let intNotOKName = "ev_int_rsa_" + inadequateKeySize; + let eeOKName = "ev_ee_rsa_" + adequateKeySize; + let eeNotOKName = "ev_ee_rsa_" + inadequateKeySize; + + // Chain with certs that have adequate sizes for EV and DV + // In opt builds, this chain is only validated for DV. Hence, an OCSP fetch + // will for example not be done for the "ev_int_rsa_2048-evroot" intermediate + // in such a build. + let intFullName = intOKName + "-" + rootOKName; + let eeFullName = eeOKName + "-" + intOKName + "-" + rootOKName; + let expectedNamesForOCSP = gEVExpected + ? [intFullName, eeFullName] + : [eeFullName]; + await keySizeTestForEV( + expectedNamesForOCSP, + rootOKCertFileName, + [intFullName], + eeFullName, + gEVExpected + ); + + // Chain with a root cert that has an inadequate size for EV, but + // adequate size for DV + intFullName = intOKName + "-" + rootNotOKName; + eeFullName = eeOKName + "-" + intOKName + "-" + rootNotOKName; + expectedNamesForOCSP = [eeFullName]; + await keySizeTestForEV( + expectedNamesForOCSP, + rootNotOKName, + [intFullName], + eeFullName, + false + ); + + // Chain with an intermediate cert that has an inadequate size for EV, but + // adequate size for DV + intFullName = intNotOKName + "-" + rootOKName; + eeFullName = eeOKName + "-" + intNotOKName + "-" + rootOKName; + expectedNamesForOCSP = [eeFullName]; + await keySizeTestForEV( + expectedNamesForOCSP, + rootOKCertFileName, + [intFullName], + eeFullName, + false + ); + + // Chain with an end entity cert that has an inadequate size for EV, but + // adequate size for DV + intFullName = intOKName + "-" + rootOKName; + eeFullName = eeNotOKName + "-" + intOKName + "-" + rootOKName; + expectedNamesForOCSP = gEVExpected ? [intFullName, eeFullName] : [eeFullName]; + await keySizeTestForEV( + expectedNamesForOCSP, + rootOKCertFileName, + [intFullName], + eeFullName, + false + ); +} + +add_task(async function() { + Services.prefs.setCharPref("network.dns.localDomains", "www.example.com"); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + + let smallKeyEVRoot = constructCertFromFile( + "test_keysize_ev/ev_root_rsa_2040.pem" + ); + equal( + smallKeyEVRoot.sha256Fingerprint, + "40:AB:5D:A5:89:15:A9:4B:82:87:B8:A6:9A:84:B1:DB:" + + "7A:9D:DB:B8:4E:E1:23:E3:C6:64:E7:50:DC:35:8C:68", + "test sanity check: the small-key EV root must have the same " + + "fingerprint as the corresponding entry in ExtendedValidation.cpp" + ); + + await checkRSAChains(2040, 2048); +}); diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem new file mode 100644 index 0000000000..3df0d3dada --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZzCCAk+gAwIBAgIUY8VXvB5H7AGqWbz0hoVm0b7dAnIwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWZXZfaW50X3JzYV8yMDQ4LWV2cm9vdDAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAwMS4wLAYDVQQDDCVldl9lZV9yc2Ff +MjA0MC1ldl9pbnRfcnNhXzIwNDgtZXZyb290MIIBITANBgkqhkiG9w0BAQEFAAOC +AQ4AMIIBCQKCAQAAusBlL9+8AFWIL/uurO7Ij6LQg8KX3V1AZk3T2Q9S+aoCvYpQ ++6FuD9mRh470dfmzUNn44+sqvXF84yewl4hTHxPfjj5OO51ha7ikHlMG7tJHIWMW +EFEYASdqTrZvBzMbXLyLyucBao+bPU8qxFU8Ykz1JjvLNI6IQN5mEocJYKeSGRsT +j7IX92XOx7/46U8Ws5QZv3UExZp+T3m9bRc+nHvz2dKk5zzBgLBZCnPVhPt/ybVP +pURgflP8aFx6Vf1EqB1BQravUepvps6lKWWi6MXYTzygJNb7ubAFuWUc5dny7PQO +1ASYGp/8AmNuMRsJXGMyoMh9w5JxtVUUgXdLAgMBAAGjgYQwgYEwXgYIKwYBBQUH +AQEEUjBQME4GCCsGAQUFBzABhkJodHRwOi8vd3d3LmV4YW1wbGUuY29tOjg4ODgv +ZXZfZWVfcnNhXzIwNDAtZXZfaW50X3JzYV8yMDQ4LWV2cm9vdC8wHwYDVR0gBBgw +FjAUBhIrBgEEAetJhRqFGoUaAYN0CQEwDQYJKoZIhvcNAQELBQADggEBAJlhONR0 +b4Ov6D8ZLINHf06gcsvLXOHvK3UlbB2COdd6Oe1c5bePo6D+zU44vUH4rwb1z25k +OQt6d4LW1ISuw1Wf7HZN1PFwBpvQZ72JcvLwouSqCEuMz68tKTzZy9E9fbRdzMLo +8N5OKxPiTY9R3gziR0AXnadZ0P0yP2mT2Oro/o7+punU4kJsOxzcfu0nMaRTht22 +6XcF6goHUD74zGxwgSeCKdImN4JvA2GYVAniDyOvJCMCjyryxeETZlgsPmXZGAVH +hiGVhFrH1E6FVxagebdK6eB7UJ9Cau5tLefAEHpCr5Xut4QNj9ck0A1J/mj3dwl/ +wV5OZmqoCAEk2h4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem.certspec new file mode 100644 index 0000000000..e64c651bc7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem.certspec @@ -0,0 +1,5 @@ +issuer:ev_int_rsa_2048-evroot +subject:ev_ee_rsa_2040-ev_int_rsa_2048-evroot +subjectKey:rsa2040 +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_rsa_2040-ev_int_rsa_2048-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem new file mode 100644 index 0000000000..fdf7002fab --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDZzCCAlCgAwIBAgIUf03mHDtKgdbREowlJgpuQsbxVXQwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWZXZfaW50X3JzYV8yMDQwLWV2cm9vdDAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAwMS4wLAYDVQQDDCVldl9lZV9yc2Ff +MjA0OC1ldl9pbnRfcnNhXzIwNDAtZXZyb290MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo +4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD +SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX +kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx +owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/ +Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GEMIGBMF4GCCsGAQUF +BwEBBFIwUDBOBggrBgEFBQcwAYZCaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4 +L2V2X2VlX3JzYV8yMDQ4LWV2X2ludF9yc2FfMjA0MC1ldnJvb3QvMB8GA1UdIAQY +MBYwFAYSKwYBBAHrSYUahRqFGgGDdAkBMA0GCSqGSIb3DQEBCwUAA4IBAABud5gZ +fQFcRyWt2bw3rxs+c0/FsV7XSHnGxYX9DXUiGFL2glNmu4DVQEHYk3CDbAPafTBD +7143VCXQu97AuLl7OAApEbsteRtSX2uMjatA2xDFACUPWqTAVNjhs3/oumldK4GS +Fq7hrPrFim/OQ/pwRvIjE12fUhz4G5uClhCVArtDwCo+0SCWsPveBVVCPmgKM6TI +3t0b20Cya2H7XCB8HC61wftGw0dIjxw5MmA7VAQmoGAxD1DOh0UAXMgMaet93riI +96g8UETpPo89cdPSZ4tMM8JSvnyrc9bns8hvX1KxQyctjXKPgtfszd9pEYv/Aked +S82jJp6aPYt7DFA= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem.certspec new file mode 100644 index 0000000000..0b7bfd4269 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem.certspec @@ -0,0 +1,5 @@ +issuer:ev_int_rsa_2040-evroot +subject:ev_ee_rsa_2048-ev_int_rsa_2040-evroot +issuerKey:rsa2040 +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_rsa_2048-ev_int_rsa_2040-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem new file mode 100644 index 0000000000..c8c52a1d00 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDhjCCAm6gAwIBAgIUG40lfqXpVIsXGwWLss7U0Guh2lcwDQYJKoZIhvcNAQEL +BQAwKzEpMCcGA1UEAwwgZXZfaW50X3JzYV8yMDQ4LWV2X3Jvb3RfcnNhXzIwNDAw +IhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAwMDAwMFowOjE4MDYGA1UEAwwv +ZXZfZWVfcnNhXzIwNDgtZXZfaW50X3JzYV8yMDQ4LWV2X3Jvb3RfcnNhXzIwNDAw +ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQ +PTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH +9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw +4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86 +exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0 +ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2N +AgMBAAGjgY4wgYswaAYIKwYBBQUHAQEEXDBaMFgGCCsGAQUFBzABhkxodHRwOi8v +d3d3LmV4YW1wbGUuY29tOjg4ODgvZXZfZWVfcnNhXzIwNDgtZXZfaW50X3JzYV8y +MDQ4LWV2X3Jvb3RfcnNhXzIwNDAvMB8GA1UdIAQYMBYwFAYSKwYBBAHrSYUahRqF +GgGDdAkBMA0GCSqGSIb3DQEBCwUAA4IBAQAQWGc/1fHcFeIavOXfSSFDn+b9+saU +xIuK4SujRstki8AUxoFyLDa5Hm5aLIU4MTpOxDLBGjFVyv9hGi4aEKnZuzdUDrSe +6ezdNNfTuwgwU1VeivTDzm2lkj9C/F7MnOgste6MMcEj+Cun34ORh7F2adE8KRxU +RgGQYhlurmUEe14ewxyEZ9PZ210v7xSqa+XPg5GNjZHjPoNUYEliASnflJ1eSRqh +Xzm0HabdSJEoUBClQLp2m/BstlkzQgEe7m+S83XPVuRPe79Ey4BnzVYqkpFdeAGO +ffs15R7qbIbOG2DeU5mQFiEFnRTv+80MVHGz0gspMBiyYI1h4wItnYx4 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec new file mode 100644 index 0000000000..a36acf887d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec @@ -0,0 +1,4 @@ +issuer:ev_int_rsa_2048-ev_root_rsa_2040 +subject:ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040 +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem new file mode 100644 index 0000000000..389e359e93 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDaDCCAlCgAwIBAgIUSxuZebHYtwEQBNR2ItC9xEgw7CkwDQYJKoZIhvcNAQEL +BQAwITEfMB0GA1UEAwwWZXZfaW50X3JzYV8yMDQ4LWV2cm9vdDAiGA8yMDE5MTEy +ODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAwMS4wLAYDVQQDDCVldl9lZV9yc2Ff +MjA0OC1ldl9pbnRfcnNhXzIwNDgtZXZyb290MIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo +4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD +SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX +kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx +owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/ +Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GEMIGBMF4GCCsGAQUF +BwEBBFIwUDBOBggrBgEFBQcwAYZCaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4 +L2V2X2VlX3JzYV8yMDQ4LWV2X2ludF9yc2FfMjA0OC1ldnJvb3QvMB8GA1UdIAQY +MBYwFAYSKwYBBAHrSYUahRqFGgGDdAkBMA0GCSqGSIb3DQEBCwUAA4IBAQAMgEzp +6Q8vRl95TLzhiLXC/9otBQpV50iq8Waqf8B2JfOPIP0M/Emz9VKQxavw6iti3YPz +utsdGyIje2W0GhlJVtMKHfvfKYXCwtVEe/XNF/Ojz7znk8KEuUPBzjKTjBuICw4F +PnmKyzoYsD1HwkgrkoII9hr+WBqY5vWLNJA1IXyA2cc3u9oAM1+QqPWEwX+bKjai +4QbngYKTL2ybQbM7TcCkvY/dSOoyyF4K4Kz0eAFXrH1cLHlPj2wo5kgexXRWAgO0 +klZrS2b3C3cJVEWi/bYCg7E3I1noNsgnZ1zQgXqjf7frAUwZURoSSPVO3azM88UJ +FCh9RLnIOgbs7zos +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem.certspec new file mode 100644 index 0000000000..0b34be6db8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem.certspec @@ -0,0 +1,4 @@ +issuer:ev_int_rsa_2048-evroot +subject:ev_ee_rsa_2048-ev_int_rsa_2048-evroot +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_rsa_2048-ev_int_rsa_2048-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem new file mode 100644 index 0000000000..ad92bf75eb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVDCCAjygAwIBAgIUM/wVnL73PZefwiXVUHFwY4BBJGwwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCExHzAdBgNVBAMMFmV2X2ludF9yc2FfMjA0MC1ldnJvb3QwggEh +MA0GCSqGSIb3DQEBAQUAA4IBDgAwggEJAoIBAAC6wGUv37wAVYgv+66s7siPotCD +wpfdXUBmTdPZD1L5qgK9ilD7oW4P2ZGHjvR1+bNQ2fjj6yq9cXzjJ7CXiFMfE9+O +Pk47nWFruKQeUwbu0kchYxYQURgBJ2pOtm8HMxtcvIvK5wFqj5s9TyrEVTxiTPUm +O8s0johA3mYShwlgp5IZGxOPshf3Zc7Hv/jpTxazlBm/dQTFmn5Peb1tFz6ce/PZ +0qTnPMGAsFkKc9WE+3/JtU+lRGB+U/xoXHpV/USoHUFCtq9R6m+mzqUpZaLoxdhP +PKAk1vu5sAW5ZRzl2fLs9A7UBJgan/wCY24xGwlcYzKgyH3DknG1VRSBd0sCAwEA +AaOBkDCBjTAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjBPBggrBgEFBQcBAQRD +MEEwPwYIKwYBBQUHMAGGM2h0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9ldl9p +bnRfcnNhXzIwNDAtZXZyb290LzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUahRoB +g3QJATANBgkqhkiG9w0BAQsFAAOCAQEAWnghIlyjOs/GO6obJdu5wmjDghKBP/pQ +5L6yF9jTdfVaTudO/liGBeP1Lnor+0QbTNWlOE2MhPobve6WPbpcGbDoCk+QorFH +sgnLbMMlSUXPgvGt4yNJefsmy02G472T9kSn6KkoLM3Zzanv0crqOUYXsQVODs17 +NEvuWuxcvsA+tuuFxwVMUuBK4AWW64zOmio/xTNqxijV8/Cd7w/20ORDhExtzxsu +l3V04WcZp8GNk6PVbmSCyZ+Oqv8aoF3sI3JCHK0cKHdM5+sQzJyTbKZ1J7kfLE+4 +aB/LZyf3EHOS5/Qv5wCSBxIBHSmQL19l48IU6FBZ+65RtIooczs3bg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem.certspec new file mode 100644 index 0000000000..80be711742 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040-evroot.pem.certspec @@ -0,0 +1,8 @@ +issuer:evroot +subject:ev_int_rsa_2040-evroot +issuerKey:ev +subjectKey:rsa2040 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/ev_int_rsa_2040-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key new file mode 100644 index 0000000000..63b267865f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEtwIBADANBgkqhkiG9w0BAQEFAASCBKEwggSdAgEAAoIBAAC6wGUv37wAVYgv ++66s7siPotCDwpfdXUBmTdPZD1L5qgK9ilD7oW4P2ZGHjvR1+bNQ2fjj6yq9cXzj +J7CXiFMfE9+OPk47nWFruKQeUwbu0kchYxYQURgBJ2pOtm8HMxtcvIvK5wFqj5s9 +TyrEVTxiTPUmO8s0johA3mYShwlgp5IZGxOPshf3Zc7Hv/jpTxazlBm/dQTFmn5P +eb1tFz6ce/PZ0qTnPMGAsFkKc9WE+3/JtU+lRGB+U/xoXHpV/USoHUFCtq9R6m+m +zqUpZaLoxdhPPKAk1vu5sAW5ZRzl2fLs9A7UBJgan/wCY24xGwlcYzKgyH3DknG1 +VRSBd0sCAwEAAQKB/2A9smffl1VcvthrjfNVA0ryjx638+eCnSObzCc6fHppoQvo +8h8bbEsCxrrjcxwxWLW7/0YF9Xq3t7Kgy6LsAFottbHqbgrO6lvHRdzS0OnWuA1+ +sOorwIEnvONfpQxCzEEYcbpZHiO6ajhISjPv8TR/kH7ppakqIxG7C0NVEAIPeOO7 +AAmdtNEYKSgJZQX8uoTzyhI4/R66XuofORu7zFQksWgGP8F+HKbhkSzLpE+dApIw +ih/tuAYSUps59Z0KP4GAtbogETIZf5OlgV3tk43459k8mxV2ZYjzObtZEAr9pJSn +5FLX3UyaGc4uw6M6GLIPC02t4XK+4Z8m8Ny+QQKBgA7Dhpy5LUBsrd96MZqylEi8 +UFoFkTcHhzNh/FuYakmftl7rgVp+N2h9GfEoCHKJ2buIGOe8ylAsSQCtmuzhF5vh +L/PkZ9YG/IIOqPB6yev/4iNuOBaEEgKIIj5C2+aN/ZcqhaZEflFpXyNNp5EcZ8mr +lTHzPfO5lDLU7ojJpO+7AoGADKY5NFSehf6sjg9WBDA/0YSf6Ir0t/fhITKDu8ei +wqUJ+Sc8Qoxo3j25PmFF8bQAvW1KJiYU6QQ602LU66SmuZU5nIk0o5mRIZnoQdjo +2/8EifaeZjeWcwspgFMLMctwaVohYl6irczAnZMFFvqHIhGpHiLdif2et9qFdLci +NbECgYANfTp14X9l+KZYpIXECVwQpPZpeeK3O8qc+O8hJT4frKxtR5H1g5LOhlb4 +jxJAzJDCllPjEAxtejjtRLFjsznl87bjiRISbGmzzv8uUZJCbZZJtv/KGrt10rou +1tmiaqODxZc9ViFv8u25DM+Id0Kg8YOskslM8YdldkXHdy2a1wKBgAP1UBlMEX8k +vqKFsgkFgDL0KYX/Vazr6IsW35o3UntOYdyRpo28mmRRNFKM5fJIvaKJPJbLe+ee +5zmWx8Ild/bC95BAbzRyrbOyEbfpRJTzLFxvzAl4g5/kckwxsGMYokiVZ7T8oDN6 +yxuEEieqpfbHSACiMGkp8CzgOLrZQ99BAoGACAp9v6jCWEgUxxZkxW62LOTK8Wr+ +iNRJkVnWdHdKOj7N3xJWwC/JFSXFJ2kkItCrqU5cQe4S3HG7Zvhnn6F+CW8oCAhR +ugRusxiFwUFOiYWt5ZnZB68XRT0cyuosDQZEP4Nnpr4VSxJeOQ7g2Q90bwiAHdP1 +Nn9Z+6LlpnwF83U= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key.keyspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key.keyspec new file mode 100644 index 0000000000..f488e73a94 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2040.key.keyspec @@ -0,0 +1 @@ +rsa2040 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem new file mode 100644 index 0000000000..416ad67fa1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDcjCCAlugAwIBAgIUFdhUsJK/XuSsxS2GLAc6Q/dnYpowDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQZXZfcm9vdF9yc2FfMjA0MDAiGA8yMDE5MTEyODAwMDAw +MFoYDzIwMjIwMjA1MDAwMDAwWjArMSkwJwYDVQQDDCBldl9pbnRfcnNhXzIwNDgt +ZXZfcm9vdF9yc2FfMjA0MDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG +8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V +gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3 +04hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l +0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz +/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaOBmjCBlzAMBgNVHRMEBTADAQH/MAsGA1Ud +DwQEAwIBBjBZBggrBgEFBQcBAQRNMEswSQYIKwYBBQUHMAGGPWh0dHA6Ly93d3cu +ZXhhbXBsZS5jb206ODg4OC9ldl9pbnRfcnNhXzIwNDgtZXZfcm9vdF9yc2FfMjA0 +MC8wHwYDVR0gBBgwFjAUBhIrBgEEAetJhRqFGoUaAYN0CQEwDQYJKoZIhvcNAQEL +BQADggEAAJNwhipzaCUDddzc+heX+MgcJ9DcupEFuuSmEgdne3PgxhfhXrIqIT4X +4DpxmtUS4oB3FhhXLxlndiBVbC2GRzPN5Qhss3ULbyfVa3Bf45LyMpDNfjs2MozJ ++xLPjhQDJcMwq10RsDUhwQz4BCcCb5AoXHaMXZJe0J2ZhYBZMMZt/22an7mR9HRc +AOvnLXtzUEZSrIsIXC0LvnAcEMy6g3WPfeJCcJZ5cWw0DVabtGBTlPy7/dOFYtmI +2BHxsDj1pTKjitmgbVfA67u24Ct5glHzkVsQEPD4vB2J5Ptu0UidQ7fRyuZwpZuW +Q72nXFdSEs0UVGp8fSsQ8ORv2m21nQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec new file mode 100644 index 0000000000..5bc5674b2c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-ev_root_rsa_2040.pem.certspec @@ -0,0 +1,7 @@ +issuer:ev_root_rsa_2040 +subject:ev_int_rsa_2048-ev_root_rsa_2040 +issuerKey:evRSA2040 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/ev_int_rsa_2048-ev_root_rsa_2040/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem new file mode 100644 index 0000000000..1ab32ed4e2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVTCCAj2gAwIBAgIUO+CV3E1g9n7p1BWTj+qvQOZRjLUwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAy +MDUwMDAwMDBaMCExHzAdBgNVBAMMFmV2X2ludF9yc2FfMjA0OC1ldnJvb3QwggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT +2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV +JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8N +jf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCA +BiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh +He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMB +AAGjgZAwgY0wDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwTwYIKwYBBQUHAQEE +QzBBMD8GCCsGAQUFBzABhjNodHRwOi8vd3d3LmV4YW1wbGUuY29tOjg4ODgvZXZf +aW50X3JzYV8yMDQ4LWV2cm9vdC8wHwYDVR0gBBgwFjAUBhIrBgEEAetJhRqFGoUa +AYN0CQEwDQYJKoZIhvcNAQELBQADggEBAJ7HDMpaOr+hmteHqb414a3xwUpEO+X9 +Jh5zHvsAHG8DXXKu36Q25w+7joXsusD5GrDbZdXVEcNF3tpx+SqahzzDK0jzOIuO +26ZRVXxkJmhyI6WdMbIrm6fC0WjGeJl0ByHo3MYJrnOgNOrGxJy3Ecpk5ttlge41 +m8TzQIi7hXYmOLqmqJ0yQoyukfX7uSr/PZsKI3tjZ8Na/q/7HesgGVH4vdbzhlmu +lZP1MPPZmn9hWHkoLxjG4KI8hGAgaUlkwk2WKn5SC9IUuz52bm3Xz0rkK+C3RSQo +MJagAa0x+heCFeWJpuhiIOWKRCwol72o0Nm+mFKi4/qAxNWBI1kTD1A= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem.certspec new file mode 100644 index 0000000000..a0cb6250dc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048-evroot.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:ev_int_rsa_2048-evroot +issuerKey:ev +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/ev_int_rsa_2048-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key.keyspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_int_rsa_2048.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key new file mode 100644 index 0000000000..bcd996ab23 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEuQIBADANBgkqhkiG9w0BAQEFAASCBKMwggSfAgEAAoIBAADKcCDcIV9XkU00 +P65KAVERaXr5l6Xs6RhmSZ/CPxuIoRjL0wsQ2Rx7mg1O6JcvyuVsr1fyX8EnWipN +vLmCQowy71h78jh0EDMKD/sWuAKb14OWnvZ19t44wY9nGTy2wHL4sj0LM3QRJiel +e5AFV3HZ5iYD9TeI1/Y6+nJPXRCAlt8x+J8msetffENXmA4Aj81V2CfdJiOVyi9S +ageJfMQMWTs4cW68DKpZZxnG8prJtzp6lEdIo6o+CenrTUYeoAJ+VAkmYUcoudJD +l1z5oFQb79JedrUflREQsOdkT8fjhEF5G20iJzhMuABOIzQjcrHPXMPnPjG3u++h +YOaGLrsCAwEAAQKCAQAAstt0vOkjYqv3KVWmOK6HILowM7t/lxyvORiNdULqocGr +tdIFseIRH0eRwIkRouFB6M/XBUcC0jEAtWQsBuGjGxGK/R+aLzlsztQlxQHZFDXK +hlZ2bO0rk7u4Zp/Om6zXJ9Hayz2vq8MpPjU4nu+OoLWOGusaIOamH5/NRT91Z/4x +0SO2FqJv703x1sn3SQER0Cju/R2XIEWxokInPdemfr8RHbJ0GlqTx7IonMSiNvWp +mm7HqCBv2uHB0EvbsZgNSimMWhfa5BhkdKX3g12IK87ySu9O1vFJ+U2WyffXjmR/ +x3ipAX/yCNO0oXaLGCFiECzasDL6u6s41SAKMkZJAoGADzhE0NTU1qIazXam/DcL +hVDh1+xaYjQXLnkPACmuZR9tXFkzCrGYArnXogfeeh+3eON3T9vcQRdQYz2NGz/g +dQBv/P0dEOdjx6kifS1fDC2t4cnmWcNQoVnTa7mG8SY21PmUKyiLwP4h2oeZR3Fz +FEJJyi44nmxcJap4yMrX1N8CgYANTQvt0ZYvB6Hq1rI6TtZ66vEnDwUqbSm6B0lF +xjYaXE+PB7+FngZ67T9ObjI+8qqKas00CwvcfP5P0ynjyX+HDH93NXksaqnQ9+dU +KijtbwGw5VorjZwkplxtoxTJVIT1x8OVSoG7AWsH7RfumwYDlpW8oFmnn43CQj0y +jVJlpQKBgAnymi/wW+ipbWFLoxsIk1QgqGxrxCuZpmkuoNpXY/AeWWlZt93Oc++c +Lk9uW0BxCIdQDUS6DDzTEyy6J0dfOcLfdVLi0SOiSXpPlwZAKHaaSKNiRlf3K/U5 +89DeI0/szTvooKqQxr9umwvtQwcKJNBh/z7RdRo+8v9/a5C529X7AoGAAaZZ4XDK +wSCgO+HPj53xyqNTsDWTvXR25YU72HTChziGAcbDQc6dHShKXu8aOmadMrgWpers +2LeET+BwZLm8oMKzGNVAJ3s/fxUQ04a7NuA7BHceXSKeiIk+E7dTv7lFGLtjjiQE +vW5qmTwWaNk/wLgv8IqvNDR9P+g5cQjIfKUCgYAEAlfA1KIcC5hDKXxlZS22YwT7 +Jjdz1yi2q/oG03rAymLGKAI+CeN9wKkB5M4SJBgOJYKjqktqGnuY4r1wB3rsFKyK +tmp1XHHg/BAkcfm7wbRqlaoLZF8sOOdkUCiWGeo/XormEDe//PgknyKqTnbioBkJ +8/6ykM6T7fV7EOvnlg== +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key.keyspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key.keyspec new file mode 100644 index 0000000000..a85e16858b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.key.keyspec @@ -0,0 +1 @@ +evRSA2040 diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem new file mode 100644 index 0000000000..fe3abd78a8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4zCCAcygAwIBAgIUJ7nCMgtzNcSPG7jAh3CWzlTGHQgwDQYJKoZIhvcNAQEL +BQAwGzEZMBcGA1UEAwwQZXZfcm9vdF9yc2FfMjA0MDAiGA8yMDE1MDEwMTAwMDAw +MFoYDzIwMzUwMTAxMDAwMDAwWjAbMRkwFwYDVQQDDBBldl9yb290X3JzYV8yMDQw +MIIBITANBgkqhkiG9w0BAQEFAAOCAQ4AMIIBCQKCAQAAynAg3CFfV5FNND+uSgFR +EWl6+Zel7OkYZkmfwj8biKEYy9MLENkce5oNTuiXL8rlbK9X8l/BJ1oqTby5gkKM +Mu9Ye/I4dBAzCg/7FrgCm9eDlp72dfbeOMGPZxk8tsBy+LI9CzN0ESYnpXuQBVdx +2eYmA/U3iNf2OvpyT10QgJbfMfifJrHrX3xDV5gOAI/NVdgn3SYjlcovUmoHiXzE +DFk7OHFuvAyqWWcZxvKaybc6epRHSKOqPgnp601GHqACflQJJmFHKLnSQ5dc+aBU +G+/SXna1H5URELDnZE/H44RBeRttIic4TLgATiM0I3Kxz1zD5z4xt7vvoWDmhi67 +AgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEB +CwUAA4IBAAA/4/YVyeRLPr05Uw5j0JOCx5WNUv2HxemfvTZgF4QEg4vDt8ba3VDR +Xj3Z8hiGYG+s2Wz4k+82wCNRTglm3iutCJ/LbwOAZIa8dFyQUa03EssS0BBvVNhx +uu6+kYMqGteIX5Q94daqZe+0KM9xKbydNCQJKSMD8IV1YHKvotF91MFQHDdnVAZX +anpqDnw0j4YGknFHA1i++0GZC0aWxhRn6Epfza+bYCVogC5BviY6xYIg2kZE8kII +msQ6iUrKQ2OV7HmZ03BdpsGADorycyJ/wRGR3xDDg8RYUur80jU/D0eBq8BX1md8 +Rc+IyDmcFcs7hYRUaJAoxuLPvQ+/vy4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem.certspec new file mode 100644 index 0000000000..fd1ade8dea --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/ev_root_rsa_2040.pem.certspec @@ -0,0 +1,7 @@ +issuer:ev_root_rsa_2040 +subject:ev_root_rsa_2040 +issuerKey:evRSA2040 +subjectKey:evRSA2040 +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key new file mode 100644 index 0000000000..1d88a930d5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC1SYlcnQAQjRGh ++Z+HqePRpdtd+uzxiNpXv2QTaI8s5HIs/xCQOMF0Ask6Kkc9vShq7T/c02PPWikU +dwG92BjXYVv5NWvV08gzaqqMCXE2igbDzURhuT5RQk4XRLsuqtRqqzjOGWghlh+H +cUoWY2k/CXYc301roSXqzse+Jw04j3ifbN94rjFE7SjEXnkpOGOnoipImAo2pA5y +1XnJuSXf+MeTNi/9aJenwXVMXpfJZ8Pq3RquiqLMzjSKAWm4Diii1wwalgxvM18t +oJubZD9av7pJ6Kqpgelg4n2HSAvdVd2UF/oYUJ+7VUzPgaQ5fouoEoo0vfJ4ZcGJ +5XNPsikFAgMBAAECggEBAJg9VPlNb0x26yPW+T14UjUwz3Ow0WJUxueBdo1F9VaB +0dAvsr0qrGq8HDiYYJNcUqDY9BSCAQOUd4MUHYZL/zCANjilwBUlcK6dGPPYyhY+ ++0dbDd3zLn4W7HVl5rteAlxBxcZuV6A87eVUIh+DBFNHosTEUcPc5Ha3h84MBXJE +vp4E7xMRjbuz1eCmzIcCnq/Upp7ZsUdZsV452KmITlb1TS+asBPw0V8xipq2svc9 +HsPJ/idK6JQxoQZAvniZsAEcXlCToYNHCGid4QBjTaveYPvWqu+joz3zSh829gwE +MDa3SNHJ7pjEAxoK/sYO/aCpkL5ST1YU6sT9s0pS+VECgYEA6twssz5f8co3a72V +vWoXd9LPT6xHVF6S0RpiCbnV5N7UeDRYHBabPIhHQqCeoYdQXBylVBTY0ltJdjLV +7CqqBSM0MPrUmJJ3en1o4Dj1YaO4lp5gsKJj3vv9pIqbD/OdlbyIsVJnyK3pe1EH +lI5B5DMknYf32xCdXXRYTYa8wdcCgYEAxZrldqIWRwJI2USlW56b+TKZ2jQexW5V +jrqCGrzhv1e3nPQR0pBMd0+duh8VGF9gewV0oIIF1uwotmo21jQjLqry/qN1Yauv +nWRLaNs4yZZMuMluwKxh66ZNBbRGVC9COXb1rN5OzJVTbS31eJVPk/DP2cWPt4ui +p23VrChNyIMCgYEAwdLvOQYzHFKspkgR+f5CW+somDIvs9tRAyzo1+n8MiQL6SAZ +zySA/NXjKYNxJxGLKlmhv+BsiD46REfz8DHNmuvQuNNo/Hl0DSzOjq2zJN9/CR6v +4VZDYdVJILAbBHEjDl5H2T+O0zljxRe8T8ePbYsfnrqFvM7bcDMCZQjbYoUCgYEA +hSG421aU376ASjFfnvybZSdcVJCs8qNFbWXm5hC/n2R/xnUB1PV3LyMqxwzN75/C +pt+kFcfEG2r8evnQfDygP37ZPAnwuZ8sMEQ0Mi8QcXCbvBuqTJFXX6apWeB9SZaV +bZXiK1eTi25HyNUf/t/Jv4iM4NGj5CtlqJvtS5HT5fUCgYEA3El7BrkgyL4LAHe3 +mOl37vdEqQ7Cxdfmy7IkSPrHLagaMxgODYoC6DFGDH/H/TphL3uZMLYbeZ+OkI5j +LpugQJtqpwsDo7p4dCYmO1vVhD34R27bXRT2qGE+uvW5zVykL1+9KALgjk5J5XCf +UVFRDKpassHG6z7+kpXRbowlyRY= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key.keyspec b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key.keyspec new file mode 100644 index 0000000000..1a3d76a550 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.key.keyspec @@ -0,0 +1 @@ +ev diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem new file mode 100644 index 0000000000..13c3031905 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUIZSHsVgzcvhPgdfrgdMGlpSfMegwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTUwMTAxMDAwMDAwWhgPMjAzNTAx +MDEwMDAwMDBaMBExDzANBgNVBAMMBmV2cm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALVJiVydABCNEaH5n4ep49Gl21367PGI2le/ZBNojyzkciz/ +EJA4wXQCyToqRz29KGrtP9zTY89aKRR3Ab3YGNdhW/k1a9XTyDNqqowJcTaKBsPN +RGG5PlFCThdEuy6q1GqrOM4ZaCGWH4dxShZjaT8JdhzfTWuhJerOx74nDTiPeJ9s +33iuMUTtKMReeSk4Y6eiKkiYCjakDnLVecm5Jd/4x5M2L/1ol6fBdUxel8lnw+rd +Gq6KoszONIoBabgOKKLXDBqWDG8zXy2gm5tkP1q/uknoqqmB6WDifYdIC91V3ZQX ++hhQn7tVTM+BpDl+i6gSijS98nhlwYnlc0+yKQUCAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABTOHA9XbfLv/C7+ +5KycYXToOIBRSjQ0j2nsiqFda4Jx+aKsvdpdrrbLHvhrpfsA3ZgB2+eKHunVc4fo +UHNqZllAs2nx+AEinq4GX8iya5BpiyTIxXWu8v06siGgz1GxlJw1cJ/ZnFEQ9IBf +cCAr5fCoZ4RC+2OVhiSTnYPCKM+zCyw3YpISjNOg1VVkp46Htp+831Eh12YfwvdY +Fgh1fc5ohYC5GCLRuXKc9PGTsr3gp7Y0liYbK7v0RBjd+GivNQ3dS3W+lB3Ow0LH +z/fc3qvrhsd58jHpb1QZQzd9bQjuIIM6Gij7TNdNNarEVZfSJjPYLfXosNdYh5fH +HmbOwao= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem.certspec b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem.certspec new file mode 100644 index 0000000000..3121f3486e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/evroot.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:evroot +subjectKey:ev +issuerKey:ev +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_keysize_ev/moz.build b/security/manager/ssl/tests/unit/test_keysize_ev/moz.build new file mode 100644 index 0000000000..96ea30e1f9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_keysize_ev/moz.build @@ -0,0 +1,31 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ev_ee_rsa_2040-ev_int_rsa_2048-evroot.pem', +# 'ev_ee_rsa_2048-ev_int_rsa_2040-evroot.pem', +# 'ev_ee_rsa_2048-ev_int_rsa_2048-ev_root_rsa_2040.pem', +# 'ev_ee_rsa_2048-ev_int_rsa_2048-evroot.pem', +# 'ev_int_rsa_2040-evroot.pem', +# 'ev_int_rsa_2048-ev_root_rsa_2040.pem', +# 'ev_int_rsa_2048-evroot.pem', +# 'ev_root_rsa_2040.pem', +# 'evroot.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'ev_int_rsa_2040.key', +# 'ev_int_rsa_2048.key', +# 'ev_root_rsa_2040.key', +# 'evroot.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_local_cert.js b/security/manager/ssl/tests/unit/test_local_cert.js new file mode 100644 index 0000000000..2b0e804380 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_local_cert.js @@ -0,0 +1,87 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const certService = Cc["@mozilla.org/security/local-cert-service;1"].getService( + Ci.nsILocalCertService +); + +const gNickname = "local-cert-test"; + +function run_test() { + // Need profile dir to store the key / cert + do_get_profile(); + // Ensure PSM is initialized + Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); + run_next_test(); +} + +function getOrCreateCert(nickname) { + return new Promise((resolve, reject) => { + certService.getOrCreateCert(nickname, { + handleCert(c, rv) { + if (rv) { + reject(rv); + return; + } + resolve(c); + }, + }); + }); +} + +function removeCert(nickname) { + return new Promise((resolve, reject) => { + certService.removeCert(nickname, { + handleResult(rv) { + if (rv) { + reject(rv); + return; + } + resolve(); + }, + }); + }); +} + +add_task(async function() { + // No master password, so no prompt required here + ok(!certService.loginPromptRequired); + + let certA = await getOrCreateCert(gNickname); + // The local cert service implementation takes the given nickname and uses it + // as the common name for the certificate it creates. nsIX509Cert.displayName + // uses the common name if it is present, so these should match. Should either + // implementation change to do something else, this won't necessarily work. + equal(certA.displayName, gNickname); + + // Getting again should give the same cert + let certB = await getOrCreateCert(gNickname); + equal(certB.displayName, gNickname); + + // Should be matching instances + ok(certA.equals(certB)); + + // Check an expected attribute + equal(certA.certType, Ci.nsIX509Cert.USER_CERT); + + // New nickname should give a different cert + let diffNameCert = await getOrCreateCert("cool-stuff"); + ok(!diffNameCert.equals(certA)); + + // Remove the cert, and get a new one again + await removeCert(gNickname); + let newCert = await getOrCreateCert(gNickname); + ok(!newCert.equals(certA)); + + // Drop all cert references and GC + let serial = newCert.serialNumber; + certA = certB = diffNameCert = newCert = null; + Cu.forceGC(); + Cu.forceCC(); + + // Should still get the same cert back + let certAfterGC = await getOrCreateCert(gNickname); + equal(certAfterGC.serialNumber, serial); +}); diff --git a/security/manager/ssl/tests/unit/test_logoutAndTeardown.js b/security/manager/ssl/tests/unit/test_logoutAndTeardown.js new file mode 100644 index 0000000000..1546bd2cce --- /dev/null +++ b/security/manager/ssl/tests/unit/test_logoutAndTeardown.js @@ -0,0 +1,207 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ + +"use strict"; + +// This test ensures that in-progress https connections are cancelled when the +// user logs out of a PKCS#11 token. + +// Get a profile directory and ensure PSM initializes NSS. +do_get_profile(); +Cc["@mozilla.org/psm;1"].getService(Ci.nsISupports); + +function getCert() { + return new Promise((resolve, reject) => { + let certService = Cc[ + "@mozilla.org/security/local-cert-service;1" + ].getService(Ci.nsILocalCertService); + certService.getOrCreateCert("beConservative-test", { + handleCert: (c, rv) => { + if (rv) { + reject(rv); + return; + } + resolve(c); + }, + }); + }); +} + +class InputStreamCallback { + constructor(output) { + this.output = output; + this.stopped = false; + } + + onInputStreamReady(stream) { + info("input stream ready"); + if (this.stopped) { + info("input stream callback stopped - bailing"); + return; + } + let available = 0; + try { + available = stream.available(); + } catch (e) { + // onInputStreamReady may fire when the stream has been closed. + equal( + e.result, + Cr.NS_BASE_STREAM_CLOSED, + "error should be NS_BASE_STREAM_CLOSED" + ); + } + if (available > 0) { + let request = NetUtil.readInputStreamToString(stream, available, { + charset: "utf8", + }); + ok( + request.startsWith("GET / HTTP/1.1\r\n"), + "Should get a simple GET / HTTP/1.1 request" + ); + let response = + "HTTP/1.1 200 OK\r\n" + + "Content-Length: 2\r\n" + + "Content-Type: text/plain\r\n" + + "\r\nOK"; + let written = this.output.write(response, response.length); + equal( + written, + response.length, + "should have been able to write entire response" + ); + } + this.output.close(); + info("done with input stream ready"); + } + + stop() { + this.stopped = true; + this.output.close(); + } +} + +class TLSServerSecurityObserver { + constructor(input, output) { + this.input = input; + this.output = output; + this.callbacks = []; + this.stopped = false; + } + + onHandshakeDone(socket, status) { + info("TLS handshake done"); + info(`TLS version used: ${status.tlsVersionUsed}`); + + if (this.stopped) { + info("handshake done callback stopped - bailing"); + return; + } + + let callback = new InputStreamCallback(this.output); + this.callbacks.push(callback); + this.input.asyncWait(callback, 0, 0, Services.tm.currentThread); + + // We've set up everything needed for a successful request/response, + // but calling logoutAndTeardown should cause the request to be cancelled. + Cc["@mozilla.org/security/sdr;1"] + .getService(Ci.nsISecretDecoderRing) + .logoutAndTeardown(); + } + + stop() { + this.stopped = true; + this.input.close(); + this.output.close(); + this.callbacks.forEach(callback => { + callback.stop(); + }); + } +} + +class ServerSocketListener { + constructor() { + this.securityObservers = []; + } + + onSocketAccepted(socket, transport) { + info("accepted TLS client connection"); + let connectionInfo = transport.securityInfo.QueryInterface( + Ci.nsITLSServerConnectionInfo + ); + let input = transport.openInputStream(0, 0, 0); + let output = transport.openOutputStream(0, 0, 0); + let securityObserver = new TLSServerSecurityObserver(input, output); + this.securityObservers.push(securityObserver); + connectionInfo.setSecurityObserver(securityObserver); + } + + // For some reason we get input stream callback events after we've stopped + // listening, so this ensures we just drop those events. + onStopListening() { + info("onStopListening"); + this.securityObservers.forEach(observer => { + observer.stop(); + }); + } +} + +function getStartedServer(cert) { + let tlsServer = Cc["@mozilla.org/network/tls-server-socket;1"].createInstance( + Ci.nsITLSServerSocket + ); + tlsServer.init(-1, true, -1); + tlsServer.serverCert = cert; + tlsServer.setSessionTickets(false); + tlsServer.asyncListen(new ServerSocketListener()); + return tlsServer; +} + +const hostname = "example.com"; + +function storeCertOverride(port, cert) { + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + let overrideBits = + Ci.nsICertOverrideService.ERROR_UNTRUSTED | + Ci.nsICertOverrideService.ERROR_MISMATCH; + certOverrideService.rememberValidityOverride( + hostname, + port, + cert, + overrideBits, + true + ); +} + +function startClient(port) { + let req = new XMLHttpRequest(); + req.open("GET", `https://${hostname}:${port}`); + return new Promise((resolve, reject) => { + req.onload = () => { + ok(false, "should not have gotten load event"); + resolve(); + }; + req.onerror = () => { + ok(true, "should have gotten an error"); + resolve(); + }; + + req.send(); + }); +} + +add_task(async function() { + Services.prefs.setCharPref("network.dns.localDomains", hostname); + let cert = await getCert(); + + let server = getStartedServer(cert); + storeCertOverride(server.port, cert); + await startClient(server.port); + server.close(); +}); + +registerCleanupFunction(function() { + Services.prefs.clearUserPref("network.dns.localDomains"); +}); diff --git a/security/manager/ssl/tests/unit/test_missing_intermediate.js b/security/manager/ssl/tests/unit/test_missing_intermediate.js new file mode 100644 index 0000000000..2a22666369 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_missing_intermediate.js @@ -0,0 +1,95 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// Tests that if a server does not send a complete certificate chain, we can +// make use of cached intermediates to build a trust path. + +const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" +); + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +registerCleanupFunction(() => { + let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + certDir.append("bad_certs"); + Assert.ok(certDir.exists(), "bad_certs should exist"); + let args = ["-D", "-n", "manually-added-missing-intermediate"]; + run_certutil_on_directory(certDir.path, args, false); +}); + +function run_test() { + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + // If we don't know about the intermediate, we'll get an unknown issuer error. + add_connection_test( + "ee-from-missing-intermediate.example.com", + SEC_ERROR_UNKNOWN_ISSUER + ); + + // Make BadCertAndPinningServer aware of the intermediate. + add_test(() => { + let args = [ + "-A", + "-n", + "manually-added-missing-intermediate", + "-i", + "test_missing_intermediate/missing-intermediate.pem", + "-a", + "-t", + ",,", + ]; + let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + certDir.append("bad_certs"); + Assert.ok(certDir.exists(), "bad_certs should exist"); + run_certutil_on_directory(certDir.path, args); + run_next_test(); + }); + + // We have to start observing the topic before there's a chance it gets + // emitted. + add_test(() => { + TestUtils.topicObserved("psm:intermediate-certs-cached").then( + subjectAndData => { + Assert.equal(subjectAndData.length, 2, "expecting [subject, data]"); + Assert.equal(subjectAndData[1], "1", `expecting "1" cert imported`); + run_next_test(); + } + ); + run_next_test(); + }); + // Connect and cache the intermediate. + add_connection_test( + "ee-from-missing-intermediate.example.com", + PRErrorCodeSuccess + ); + + // Add a dummy test so that the only way we advance from here is by observing + // "psm:intermediate-certs-cached". + add_test(() => {}); + + // Delete the intermediate on the server again. + add_test(() => { + clearSessionCache(); + let certDir = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + certDir.append("bad_certs"); + Assert.ok(certDir.exists(), "bad_certs should exist"); + let args = ["-D", "-n", "manually-added-missing-intermediate"]; + run_certutil_on_directory(certDir.path, args); + run_next_test(); + }); + + // Since we cached the intermediate in gecko, this should succeed. + add_connection_test( + "ee-from-missing-intermediate.example.com", + PRErrorCodeSuccess + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem b/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem new file mode 100644 index 0000000000..985077c6b3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4DCCAcigAwIBAgIUVwdwwrCWfp82pGODTXMV35GajGQwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAfMR0wGwYDVQQDDBRNaXNzaW5nIEludGVybWVkaWF0ZTCCASIw +DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ +6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUk +nAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N +/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAG +JMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd +7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEA +AaMdMBswDAYDVR0TBAUwAwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQAD +ggEBAFDTK/9saOeJ3Sb0vjJ0ogp/E7WrpjHaMsx7janNrpaIGqn+vaICF30Muazb +/LywCjvXsJCFI1aPh+s4eavMPZVEdDIsoQIwdBLCU8u/s1wVlA+BHOy/M0u+7rGw ++F2AeKd4vUfZJ4jrxSorxqCuwyE606UXImSSngpJq4dRJul4cDcHOg6uSRl/hPU+ +sjGdo2DIJKiGquBwmMVgEwIF6qSP7iI+qguy2k6XykGnVSN/HASqB+0UfYvvHhkI +3sPcsU1LM3tW5hnM/81SE0JUHyvNgXEHHXO1FST2U6H6LyrTsem3Ga33yhBoayD/ +L1P2Qgq8tryeqcV4cqolR7MfYx4= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem.certspec b/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem.certspec new file mode 100644 index 0000000000..c21e757449 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_missing_intermediate/missing-intermediate.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Missing Intermediate +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_missing_intermediate/moz.build b/security/manager/ssl/tests/unit/test_missing_intermediate/moz.build new file mode 100644 index 0000000000..d9282b6044 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_missing_intermediate/moz.build @@ -0,0 +1,19 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# BadCertAndPinningServer takes as an argument a path to a directory and loads +# every key and certificate in it. We want to test what happens when a +# server doesn't include an intermediate that is necessary to build a +# complete trust path. The easiest way to do this right now is to put +# the intermediate in a different directory, so that BadCertAndPinningServer +# doesn't know about it and can't send it in the TLS handshake. +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'missing-intermediate.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_name_constraints.js b/security/manager/ssl/tests/unit/test_name_constraints.js new file mode 100644 index 0000000000..e04eb93b0c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints.js @@ -0,0 +1,71 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// This test tests two specific items: +// 1. Are name constraints properly enforced across the entire constructed +// certificate chain? This makes use of a certificate hierarchy like so: +// - (trusted) root CA with permitted subtree dNSName example.com +// - intermediate CA with permitted subtree dNSName example.org +// a. end-entity with dNSNames example.com and example.org +// (the first entry is allowed by the root but not by the intermediate, +// and the second entry is allowed by the intermediate but not by the +// root) +// b. end-entity with dNSName example.com (not allowed by the intermediate) +// c. end-entity with dNSName examle.org (not allowed by the root) +// d. end-entity with dNSName example.test (not allowed by either) +// All of these cases should fail to verify with the error that the +// end-entity is not in the name space permitted by the hierarchy. +// +// 2. Are externally-imposed name constraints properly enforced? This makes use +// of a certificate hierarchy rooted by a certificate with the same DN as an +// existing hierarchy that has externally-imposed name constraints (DCISS). + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function certFromFile(name) { + return constructCertFromFile(`test_name_constraints/${name}.pem`); +} + +function loadCertWithTrust(certName, trustString) { + addCertFromFile(certdb, `test_name_constraints/${certName}.pem`, trustString); +} + +function checkCertNotInNameSpace(cert) { + return checkCertErrorGeneric( + certdb, + cert, + SEC_ERROR_CERT_NOT_IN_NAME_SPACE, + certificateUsageSSLServer + ); +} + +function checkCertInNameSpace(cert) { + return checkCertErrorGeneric( + certdb, + cert, + PRErrorCodeSuccess, + certificateUsageSSLServer + ); +} + +add_task(async function() { + // Test that name constraints from the entire certificate chain are enforced. + loadCertWithTrust("ca-example-com-permitted", "CTu,,"); + loadCertWithTrust("int-example-org-permitted", ",,"); + await checkCertNotInNameSpace(certFromFile("ee-example-com-and-org")); + await checkCertNotInNameSpace(certFromFile("ee-example-com")); + await checkCertNotInNameSpace(certFromFile("ee-example-org")); + await checkCertNotInNameSpace(certFromFile("ee-example-test")); + + // Test that externally-imposed name constraints are enforced (DCISS tests). + loadCertWithTrust("dciss", "CTu,,"); + await checkCertInNameSpace(certFromFile("NameConstraints.dcissallowed")); + await checkCertNotInNameSpace(certFromFile("NameConstraints.dcissblocked")); +}); diff --git a/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem new file mode 100644 index 0000000000..819737c643 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVzCCAj+gAwIBAgIUH/IH7a1iPGpyhpstium2HZvHBr0wDQYJKoZIhvcNAQEL +BQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBh +cmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMF +SUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEExCzAJBgNVBAYTAlVTMQsw +CQYDVQQIDAJDQTEMMAoGA1UECgwDRm9vMRcwFQYDVQQDDA5mb28uZXhhbXBsZS5m +cjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogG +NhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqn +RYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHu +p3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQ +Lzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p +47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo1 +7Y0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEALZy0l4IRtgX2v24zAUssBpdMpfUt +2Evctbg02kRX3y1cWvoXMq4qrnoMhoaNBpdMf8m1kqbsirPaT5NHsr7V/NgJGPwA +cHBEb1oV+Smy8KfhqF12VD2gWYHxs9Ooc67+Bf90cZO9yPpOjiNqJeMtat/xVA+e +dG1kE6V5tMufIi4wARy4tjaMWoD2aw4oYFn1VREkOeyT79JzCTJMBR1bArVhas7D +mn+EON5e16oYmFPfSRT3oWmtEHa3Er0M5v0icSaEA7YFkPdoXLRNxstggh7IPcD4 +3dmH0xosUax8+E4gp0lVk+ok0nEvRNcw+KTopFSO83tPn/4yLQMGjGB8Rg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem.certspec new file mode 100644 index 0000000000..1a02a0cc1a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissallowed.pem.certspec @@ -0,0 +1,2 @@ +issuer:printableString/C=FR/ST=France/L=Paris/O=PM/SGDN/OU=DCSSI/CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr +subject:/C=US/ST=CA/O=Foo/CN=foo.example.fr diff --git a/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem new file mode 100644 index 0000000000..ac0349ac7b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDWDCCAkCgAwIBAgIUdb90UMieOa6hVljB8cPlSVhDhNUwDQYJKoZIhvcNAQEL +BQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBh +cmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMF +SUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMEIxCzAJBgNVBAYTAlVTMQsw +CQYDVQQIDAJDQTEMMAoGA1UECgwDRm9vMRgwFgYDVQQDDA9mb28uZXhhbXBsZS5j +b20wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAKIQo2A4GXqb8uYaOekw5f/SJBg4 +iPiOlhNNGEmczSCty8UbFDrd3L44EpH1Wi5YvuxnqWwHzLxU4Ze2aJIwIZ04godV +nHCd57qFsuakPdxesdGeFdeM/Ni2h6YhZkyoZzmUKtKbMcoCQOq/WPzXehU9/D2n +okuePkoXw92YVSFq/IBuKcPpQKIpKq+Oho9PbDXho3ZDYW5PVReif2I9Pp9mIIfN +rGkM/oSA+3brZGe8fXUIg6zXlTiXX70FdIuWeXcd5TjY141+27jshjXvIy+5ZZep +uPCx9jYjmOUklbf8hKeKZzFZfXo3Fg1QlXcMOmZbE4rgF7wKysux6jgnEo8= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem.certspec new file mode 100644 index 0000000000..eabee87e83 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/NameConstraints.dcissblocked.pem.certspec @@ -0,0 +1,2 @@ +issuer:printableString/C=FR/ST=France/L=Paris/O=PM/SGDN/OU=DCSSI/CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr +subject:/C=US/ST=CA/O=Foo/CN=foo.example.com diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem b/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem new file mode 100644 index 0000000000..efb0e9828c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAfmgAwIBAgIUW/imFdGk/JA1NKPzOw1+UoGjVIUwDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2EtZXhhbXBsZS1jb20tcGVybWl0dGVkMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCMxITAfBgNVBAMMGGNhLWV4YW1w +bGUtY29tLXBlcm1pdHRlZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG +8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0V +gg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g3 +04hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l +0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz +/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaM5MDcwDAYDVR0TBAUwAwEB/zALBgNVHQ8E +BAMCAQYwGgYDVR0eBBMwEaAPMA2CC2V4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUA +A4IBAQBCxftaoGEXtPvmno3v44S7ahV7PYR6kNE1VxZDifghRNneBc+um3r/S6Rz +Qfej9e+u6/pSNyW1laZE3EXCKX9za5LE//qbm4l7UaomqO95BD3oVNV5pVNuC5Hc +JyLLbFTT4QKi1pHoD/Wjv17f4rBl13MFqXB4Nt9KqvZOn1RGcU+dPgivuuNYXGEq +0REsQRqloVOdZ9WhF0lEUNDvWhxxZi1arLlv5UCrQZ+srvroZMrjyQJ9Wu3RH6Hm +HdpBkIkoghiykIILF23zWeb8tgqlakkTtuVU1dnzFhP8NZDMYG7Ms2vpTkbBjnwb +cYKuzvcsfwnFbmAN9v0/Hzo4zZrh +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem.certspec new file mode 100644 index 0000000000..1cc3c1d81b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ca-example-com-permitted.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca-example-com-permitted +subject:ca-example-com-permitted +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:nameConstraints:permitted:example.com diff --git a/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem b/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem new file mode 100644 index 0000000000..ae37ac46a1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDuzCCAqOgAwIBAgIUcxz6c/GMYB7/nrD4zXg4j6UrJckwDQYJKoZIhvcNAQEL +BQAwgYUxCzAJBgNVBAYTAkZSMQ8wDQYDVQQIEwZGcmFuY2UxDjAMBgNVBAcTBVBh +cmlzMRAwDgYDVQQKEwdQTS9TR0ROMQ4wDAYDVQQLEwVEQ1NTSTEOMAwGA1UEAxMF +SUdDL0ExIzAhBgkqhkiG9w0BCQEWFGlnY2FAc2dkbi5wbS5nb3V2LmZyMCIYDzIw +MTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMIGFMQswCQYDVQQGEwJGUjEP +MA0GA1UECBMGRnJhbmNlMQ4wDAYDVQQHEwVQYXJpczEQMA4GA1UEChMHUE0vU0dE +TjEOMAwGA1UECxMFRENTU0kxDjAMBgNVBAMTBUlHQy9BMSMwIQYJKoZIhvcNAQkB +FhRpZ2NhQHNnZG4ucG0uZ291di5mcjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72x +nAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lM +wmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF +4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20 +yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xx +j5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswDAYDVR0TBAUwAwEB/zAL +BgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBAKUhmbYZJnpAEOUHAxYTaGZD +0juaNppvdhTeI2T3bfIVgL3qFqPeom3pLNU+Rnl1hTplxl0C9wxIEl849nc9cWxa +EK/JCnGHrBCZ4qJn9xUN96AhGICE654c7CgBNLKs8KZ6tAunAGtxCR6c5R7L5G7m +fA7DWX9lEI0R9L0NJzWyhELsafoMlZGFTiIERiYGhotemxf+QEPWAWn3cfFgN0ma +aK23cFbzw6SXHbC2y9OCtz8nWgn417Los+H2emQrBqISdvPh54EU2uCb7vxH2/ly +KZW8QFo5M3/UCuy/X47y7gUTHQQ+BhX9Dz40sp7DP0pDSwt0fksVxXlZoldMppM= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem.certspec new file mode 100644 index 0000000000..5d53706bc5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/dciss.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=FR/ST=France/L=Paris/O=PM/SGDN/OU=DCSSI/CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr +subject:printableString/C=FR/ST=France/L=Paris/O=PM/SGDN/OU=DCSSI/CN=IGC/A/emailAddress=igca@sgdn.pm.gouv.fr +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem new file mode 100644 index 0000000000..10064a2c0b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIC/jCCAeagAwIBAgIUcVd3d0Lp6rsQX88nbU7VYHOOVKswDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZaW50LWV4YW1wbGUtb3JnLXBlcm1pdHRlZDAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAhMR8wHQYDVQQDDBZlZS1leGFt +cGxlLWNvbS1hbmQtb3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA +uohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGoby +a+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWC +D/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfT +iEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXT +Ce+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+ +SSP6clHEMdUDrNoYCjXtjQIDAQABoycwJTAjBgNVHREEHDAaggtleGFtcGxlLmNv +bYILZXhhbXBsZS5vcmcwDQYJKoZIhvcNAQELBQADggEBAKZjORSM/94cF9uzMJCX +MZ3JmZKiMRXCW9Y1mCKeimvV5LqFyRVMlE7DAHXuPwzaJVS1y/q99dUcUfMd5q1b +jEMdLc4qM+7JSpI1qxoeFQPym+3tCH15u6ZXkPzrAdGElVraCEYsCWjEmpMaZS6Q +Zfbe7mcBqIDiFKQma6tioiwfdg2KLKb/bFML/guxGVIYFla8UaiOFtQ0mLg6qMrp +1RdjqJhGqqD71IS+ez65W4gaizKgAyBmKqOqRoSjvF7lqrQNAOk7m+pY4Dzlxyg9 +iGYyNVWen1R436FLJEgdFQOefGY5vhtg5dVX+D/MH+vRX8apumQ3Q1sVMgoLb5v3 +yWw= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem.certspec new file mode 100644 index 0000000000..904ca65955 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com-and-org.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-example-org-permitted +subject:ee-example-com-and-org +extension:subjectAlternativeName:example.com,example.org diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem new file mode 100644 index 0000000000..3b04129003 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6TCCAdGgAwIBAgIULdge2q8uLXhglJkSVlCLPnl/KsswDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZaW50LWV4YW1wbGUtb3JnLXBlcm1pdHRlZDAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAZMRcwFQYDVQQDDA5lZS1leGFt +cGxlLWNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20wDQYJKoZI +hvcNAQELBQADggEBAKazM8Y0fbv4mYND26inNXWTooZz6G4zFxa9TDVEYYl0W5mS +kC0nE1L38cP7hFpuKwChl87UNHgkpxplSozadgSUg1yqyZ+F1KzpAs1647WHqAgB +cIPzhR1Y7d1v3/jkCxioYvwudeXwO8eqH3EPOz5h70U8LRY+Dney+qT9OLAvyAl/ +dpF3ZjT3AQRTT90ZL15I+rLR10kI4a2MwqUALaEmZtZAp1ecDoh/71VJF4CEPb3l +JE7rR/Ff5VHC6fNMJcoc9Ze6laEOH3+BK+l8wpf4ABGiCdkfUsHbO3W/g0h4QKhS +Me7tz24aSISqinNGxOGcFVBB//V1sPGkH3lFVTc= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem.certspec new file mode 100644 index 0000000000..46630c4a1a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-com.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-example-org-permitted +subject:ee-example-com +extension:subjectAlternativeName:example.com diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem new file mode 100644 index 0000000000..12545e3748 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6TCCAdGgAwIBAgIUd1DYJK/QJRwY0oGdFXeMsRKcwhAwDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZaW50LWV4YW1wbGUtb3JnLXBlcm1pdHRlZDAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAZMRcwFQYDVQQDDA5lZS1leGFt +cGxlLW9yZzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5vcmcwDQYJKoZI +hvcNAQELBQADggEBAJyjoYfBfON+x24YHczjV3ngQfTH0SZ4WzebR/lqsIrKKx08 +siDPKpdrkNGDyQ0A9pxaLMgDjl9e+7Z8aWLklzGYY1TN8/KWaQdqAN9VAL/9QfIz +qo5jxzEt29nNvO9NTc9sBQ/fPiTydI96JJgsWPg/ikw3y0c+1IPVYT0jSCxHc7qN +MLXtmDxl7ZoMyPKU9ZIACHSU3+BZee/TTqZT97TIEYkS39bJUyP6UwttTfh4Zm8l +3Eju6bMPrQGu/M1hy+n6bliY+qxnJ0TDaJcHfd6ox9SFGajjAvU2KMVfiG7NzzBP +qdmp5Hw6BIskbjzGD9TfOiQiDd/CqwfuoXStH1M= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem.certspec new file mode 100644 index 0000000000..6a24090e51 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-org.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-example-org-permitted +subject:ee-example-org +extension:subjectAlternativeName:example.org diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem new file mode 100644 index 0000000000..a15e04cf60 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6zCCAdOgAwIBAgIUMV6sDJo62fVf2QrGVmoUYUmkl5AwDQYJKoZIhvcNAQEL +BQAwJDEiMCAGA1UEAwwZaW50LWV4YW1wbGUtb3JnLXBlcm1pdHRlZDAiGA8yMDE5 +MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9lZS1leGFt +cGxlLXRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W +1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtq +ZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx +0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthV +t2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo +4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx +1QOs2hgKNe2NAgMBAAGjGzAZMBcGA1UdEQQQMA6CDGV4YW1wbGUudGVzdDANBgkq +hkiG9w0BAQsFAAOCAQEAZyhNrPkiThyQJBib0iYbXOP7NOEdenQzeyCRZJ5QcPZM +jO5iXpRRzyEqBDyOtnIG6UihP98qOmF7T8RTZmZ0Ex8Kzw5iHniXYDJPr5pnaTG+ +INyKLMMVr884xHEKKarX2sg52b+u01gAUBD6B9yQZ3MAdqjNyqcbYmOVzreFsYcL +ddhhC9/B0iE801OPf2/vbAIcLNKVXSkPJ0Xry3KeGqwc3v5a4SNmEGLYBZKdaIAb +q4a6ViUPFxS/MduXzXxzU8FaXDMZj8eGezExuDUWrZvWLjmfl5RaV+/JJbTRcMKR +xIVqTKtCbuXvNsetc0/IIQ4lz7eMniQrGQd6QM3HRg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem.certspec new file mode 100644 index 0000000000..0926ce477a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/ee-example-test.pem.certspec @@ -0,0 +1,3 @@ +issuer:int-example-org-permitted +subject:ee-example-test +extension:subjectAlternativeName:example.test diff --git a/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem b/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem new file mode 100644 index 0000000000..4c491d708c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDEjCCAfqgAwIBAgIUTwrMhhSd1s9Xs6fjDP+FeWX6YigwDQYJKoZIhvcNAQEL +BQAwIzEhMB8GA1UEAwwYY2EtZXhhbXBsZS1jb20tcGVybWl0dGVkMCIYDzIwMTkx +MTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCQxIjAgBgNVBAMMGWludC1leGFt +cGxlLW9yZy1wZXJtaXR0ZWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB +AQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24a +hvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7t +FYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+o +N9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0d +JdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4 +s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjOTA3MAwGA1UdEwQFMAMBAf8wCwYDVR0P +BAQDAgEGMBoGA1UdHgQTMBGgDzANggtleGFtcGxlLm9yZzANBgkqhkiG9w0BAQsF +AAOCAQEAoHM57NeL7TRmMXZ5eR6hep2vYELQ6x6OHIZQy6v/B9mDY5kdNkO3tcbW +jEbdL3wInvxxaUWgDfdHlW6isUDMWn9pqAejytzwQveCHHve+yPmaR5Kgnm/LR7U +ygE8f1CDpm/u/+q8UXzG7B8g3qwo1HRWx07G43ZXbMp/0BiBdA2Hjhj9drohosAY +g2aDqaRIUeq97PCarNztkzr//zt9eCXg8qQBjVSghB03ikFRBmkCBVBNLqq6iqN+ +wb6Crc5RKKEec8n1HHEBnl16sfF/W9Z3GYFXf/Oesnz9JyaLuns1MiZx+TEf9afn +sg4XFW8K1vQ+t/1CR+OB1sEhmgkd2A== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem.certspec b/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem.certspec new file mode 100644 index 0000000000..87e2cf8a56 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/int-example-org-permitted.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca-example-com-permitted +subject:int-example-org-permitted +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:nameConstraints:permitted:example.org diff --git a/security/manager/ssl/tests/unit/test_name_constraints/moz.build b/security/manager/ssl/tests/unit/test_name_constraints/moz.build new file mode 100644 index 0000000000..0bc6b1bb38 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_name_constraints/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'NameConstraints.dcissallowed.pem', +# 'NameConstraints.dcissblocked.pem', +# 'ca-example-com-permitted.pem', +# 'int-example-org-permitted.pem', +# 'ee-example-com-and-org.pem', +# 'ee-example-com.pem', +# 'ee-example-org.pem', +# 'ee-example-test.pem', +# 'dciss.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_nonascii_path.js b/security/manager/ssl/tests/unit/test_nonascii_path.js new file mode 100644 index 0000000000..cac942b212 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_nonascii_path.js @@ -0,0 +1,62 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// Tests to make sure that the certificate DB works with non-ASCII paths. + +// Append a single quote and non-ASCII characters to the profile path. +let env = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment +); +let profd = env.get("XPCSHELL_TEST_PROFILE_DIR"); +let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); +file.initWithPath(profd); +file.append("'÷1"); +env.set("XPCSHELL_TEST_PROFILE_DIR", file.path); + +file = do_get_profile(); // must be called before getting nsIX509CertDB +Assert.ok( + /[^\x20-\x7f]/.test(file.path), + "the profile path should contain a non-ASCII character" +); +if (mozinfo.os == "win") { + file.QueryInterface(Ci.nsILocalFileWin); + Assert.ok( + /[^\x20-\x7f]/.test(file.canonicalPath), + "the profile short path should contain a non-ASCII character" + ); +} + +// Restore the original value. +env.set("XPCSHELL_TEST_PROFILE_DIR", profd); + +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function load_cert(cert_name, trust_string) { + let cert_filename = cert_name + ".pem"; + return addCertFromFile( + certdb, + "test_cert_trust/" + cert_filename, + trust_string + ); +} + +function run_test() { + let certList = ["ca", "int", "ee"]; + let loadedCerts = []; + for (let certName of certList) { + loadedCerts.push(load_cert(certName, ",,")); + } + + let ca_cert = loadedCerts[0]; + notEqual(ca_cert, null, "CA cert should have successfully loaded"); + let int_cert = loadedCerts[1]; + notEqual(int_cert, null, "Intermediate cert should have successfully loaded"); + let ee_cert = loadedCerts[2]; + notEqual(ee_cert, null, "EE cert should have successfully loaded"); +} diff --git a/security/manager/ssl/tests/unit/test_nsCertType.js b/security/manager/ssl/tests/unit/test_nsCertType.js new file mode 100644 index 0000000000..8341575473 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_nsCertType.js @@ -0,0 +1,32 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +// +// While the Netscape certificate type extension is not a standard and has been +// discouraged from use for quite some time, it is still encountered. Thus, we +// handle it slightly differently from other unknown extensions. +// If it is not marked critical, we ignore it. +// If it is marked critical: +// If the basic constraints and extended key usage extensions are also +// present, we ignore it, because they are standardized and should convey the +// same information. +// Otherwise, we reject it with an error indicating an unknown critical +// extension. + +"use strict"; + +function run_test() { + do_get_profile(); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + add_connection_test("nsCertTypeNotCritical.example.com", PRErrorCodeSuccess); + add_connection_test( + "nsCertTypeCriticalWithExtKeyUsage.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "nsCertTypeCritical.example.com", + SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION + ); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_nsIX509CertValidity.js b/security/manager/ssl/tests/unit/test_nsIX509CertValidity.js new file mode 100644 index 0000000000..5febcbf169 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_nsIX509CertValidity.js @@ -0,0 +1,70 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// This file tests the nsIX509CertValidity implementation. + +function fuzzyEqual(attributeName, dateString, expectedTime) { + info(`${attributeName}: ${dateString}`); + let absTimeDiff = Math.abs(expectedTime - Date.parse(dateString)); + const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000; + lessOrEqual( + absTimeDiff, + ONE_DAY_IN_MS, + `Time difference for ${attributeName} should be <= one day` + ); +} + +function run_test() { + // Date.parse("2013-01-01T00:00:00Z") + const NOT_BEFORE_IN_MS = 1356998400000; + // Date.parse("2014-01-01T00:00:00Z") + const NOT_AFTER_IN_MS = 1388534400000; + let cert = constructCertFromFile("bad_certs/expired-ee.pem"); + + equal( + cert.validity.notBefore, + NOT_BEFORE_IN_MS * 1000, + "Actual and expected notBefore should be equal" + ); + equal( + cert.validity.notAfter, + NOT_AFTER_IN_MS * 1000, + "Actual and expected notAfter should be equal" + ); + + // The following tests rely on the implementation of nsIX509CertValidity + // providing long formatted dates to work. If this is not true, a returned + // short formatted date such as "12/31/12" may be interpreted as something + // other than the expected "December 31st, 2012". + // + // On Android, the implementation of nsIDateTimeFormat currently does not + // return a long formatted date even if it is asked to. This, combined with + // the reason above is why the following tests are disabled on Android. + if (AppConstants.platform != "android") { + fuzzyEqual( + "notBeforeLocalTime", + cert.validity.notBeforeLocalTime, + NOT_BEFORE_IN_MS + ); + fuzzyEqual( + "notBeforeLocalDay", + cert.validity.notBeforeLocalDay, + NOT_BEFORE_IN_MS + ); + fuzzyEqual("notBeforeGMT", cert.validity.notBeforeGMT, NOT_BEFORE_IN_MS); + + fuzzyEqual( + "notAfterLocalTime", + cert.validity.notAfterLocalTime, + NOT_AFTER_IN_MS + ); + fuzzyEqual( + "notAfterLocalDay", + cert.validity.notAfterLocalDay, + NOT_AFTER_IN_MS + ); + fuzzyEqual("notAfterGMT", cert.validity.notAfterGMT, NOT_AFTER_IN_MS); + } +} diff --git a/security/manager/ssl/tests/unit/test_nsIX509Cert_utf8.js b/security/manager/ssl/tests/unit/test_nsIX509Cert_utf8.js new file mode 100644 index 0000000000..6305b878b4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_nsIX509Cert_utf8.js @@ -0,0 +1,96 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Checks that various nsIX509Cert attributes correctly handle UTF-8. + +do_get_profile(); // Must be called before getting nsIX509CertDB +const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function run_test() { + let cert = certDB.constructX509FromBase64( + "MIIF3DCCBMSgAwIBAgIEAJiZbzANBgkqhkiG9w0BAQUFADCCAQ0xYTBfBgNVBAMM" + + "WEkuQ0EgLSBRdWFsaWZpZWQgcm9vdCBjZXJ0aWZpY2F0ZSAoa3ZhbGlmaWtvdmFu" + + "w70gY2VydGlmaWvDoXQgcG9za3l0b3ZhdGVsZSkgLSBQU0VVRE9OWU0xCzAJBgNV" + + "BAYTAkNaMS8wLQYDVQQHDCZQb2R2aW5uw70gbWzDvW4gMjE3OC82LCAxOTAgMDAg" + + "UHJhaGEgOTEsMCoGA1UECgwjUHJ2bsOtIGNlcnRpZmlrYcSNbsOtIGF1dG9yaXRh" + + "IGEucy4xPDA6BgNVBAsMM0FrcmVkaXRvdmFuw70gcG9za3l0b3ZhdGVsIGNlcnRp" + + "ZmlrYcSNbsOtY2ggc2x1xb5lYjAeFw0wMjEyMTIxMzMzNDZaFw0wMzEyMTIxMzMz" + + "NDZaMIIBFDELMAkGA1UEBhMCQ1oxHzAdBgNVBAMeFgBMAHUAZAEbAGsAIABSAGEB" + + "YQBlAGsxGTAXBgNVBAgeEABWAHkAcwBvAQ0AaQBuAGExLzAtBgNVBAceJgBQAGEA" + + "YwBvAHYALAAgAE4A4QBkAHIAYQF+AG4A7QAgADcANgA5MSUwIwYJKoZIhvcNAQkB" + + "FhZsdWRlay5yYXNla0BjZW50cnVtLmN6MRMwEQYDVQQqHgoATAB1AGQBGwBrMQ0w" + + "CwYDVQQrHgQATABSMR8wHQYDVQQpHhYATAB1AGQBGwBrACAAUgBhAWEAZQBrMRMw" + + "EQYDVQQEHgoAUgBhAWEAZQBrMRcwFQYDVQQFEw5JQ0EgLSAxMDAwMzc2OTCBnzAN" + + "BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAxc7dGd0cNlHZ7tUUl5k30bfYlY3lnOD0" + + "49JGbTXSt4jNFMRLj6s/777W3kcIdcIwdKxjQULBKgryDvZJ1DAWp2TwzhPDVYj3" + + "sU4Niqb7mOUcp/4ckteUxGF6FmXtJR9+XHTuLZ+omF9HOUefheBKnXvZuqrLM16y" + + "nbJn4sPwwdcCAwEAAaOCAbswggG3MCUGA1UdEQQeMBygGgYKKwMGAQQB3BkCAaAM" + + "DAoxNzYyODk2ODgzMGkGA1UdHwRiMGAwHqAcoBqGGGh0dHA6Ly9xLmljYS5jei9x" + + "aWNhLmNybDAeoBygGoYYaHR0cDovL2IuaWNhLmN6L3FpY2EuY3JsMB6gHKAahhho" + + "dHRwOi8vci5pY2EuY3ovcWljYS5jcmwwHwYDVR0jBBgwFoAUK1oKfvvlDYUsZTBy" + + "vGN701mca/UwHQYDVR0OBBYEFPAs70DB+LS0PnA6niPUfJ5wdQH5MIG4BgNVHSAE" + + "gbAwga0wgaoGCysGAQQBs2EBAQQEMIGaMC8GCCsGAQUFBwIBFiNodHRwOi8vd3d3" + + "LmljYS5jei9xY3AvY3BxcGljYTAyLnBkZjBnBggrBgEFBQcCAjBbGllUZW50byBj" + + "ZXJ0aWZpa2F0IGplIHZ5ZGFuIGpha28gS3ZhbGlmaWtvdmFueSBjZXJ0aWZpa2F0" + + "IHYgc291bGFkdSBzZSB6YWtvbmVtIDIyNy8yMDAwIFNiLjAYBggrBgEFBQcBAwQM" + + "MAowCAYGBACORgEBMA4GA1UdDwEB/wQEAwIE8DANBgkqhkiG9w0BAQUFAAOCAQEA" + + "v2V+nnYYMIgabmmgHx49CtlZIHdGS3TuWKXw130xFhbXDnNhEbx3alaskNsvjQQR" + + "Lqs1ZwKy58yynse+eJYHqenmHDACpAfVpCF9PXC/mDarVsoQw7NTcUpsAFhSd/zT" + + "v9jIf3twECyxx/RVzONVcob7nPePESHiKoG4FbtcuUh0wSHvCmTwRIQqPDCIuHcF" + + "StSt3Jr9iXcbXEhe4mSccOZ8N+r7Rv3ncKcevlRl7uFfDKDTyd43SZeRS/7J8KRf" + + "hD/h2nawrCFwc5gJW10aLJGFL/mcS7ViAIT9HCVk23j4TuBjsVmnZ0VKxB5edux+" + + "LIEqtU428UVHZWU/I5ngLw==" + ); + + equal( + cert.emailAddress, + "ludek.rasek@centrum.cz", + "Actual and expected emailAddress should match" + ); + equal( + cert.subjectName, + 'serialNumber=ICA - 10003769,SN=RaÅ¡ek,name=LudÄ›k RaÅ¡ek,initials=LR,givenName=LudÄ›k,E=ludek.rasek@centrum.cz,L="Pacov, Nádražní 769",ST=VysoÄina,CN=LudÄ›k RaÅ¡ek,C=CZ', + "Actual and expected subjectName should match" + ); + equal( + cert.commonName, + "LudÄ›k RaÅ¡ek", + "Actual and expected commonName should match" + ); + equal(cert.organization, "", "Actual and expected organization should match"); + equal( + cert.organizationalUnit, + "", + "Actual and expected organizationalUnit should match" + ); + equal( + cert.displayName, + "LudÄ›k RaÅ¡ek", + "Actual and expected displayName should match" + ); + equal( + cert.issuerName, + 'OU=Akreditovaný poskytovatel certifikaÄních služeb,O=První certifikaÄní autorita a.s.,L="Podvinný mlýn 2178/6, 190 00 Praha 9",C=CZ,CN=I.CA - Qualified root certificate (kvalifikovaný certifikát poskytovatele) - PSEUDONYM', + "Actual and expected issuerName should match" + ); + equal( + cert.issuerCommonName, + "I.CA - Qualified root certificate (kvalifikovaný certifikát poskytovatele) - PSEUDONYM", + "Actual and expected issuerCommonName should match" + ); + equal( + cert.issuerOrganization, + "První certifikaÄní autorita a.s.", + "Actual and expected issuerOrganization should match" + ); + equal( + cert.issuerOrganizationUnit, + "Akreditovaný poskytovatel certifikaÄních služeb", + "Actual and expected issuerOrganizationUnit should match" + ); +} diff --git a/security/manager/ssl/tests/unit/test_nss_shutdown.js b/security/manager/ssl/tests/unit/test_nss_shutdown.js new file mode 100644 index 0000000000..36cf283477 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_nss_shutdown.js @@ -0,0 +1,48 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +"use strict"; + +// This test attempts to ensure that PSM doesn't deadlock or crash when shutting +// down NSS while a background thread is attempting to use NSS. +// Uses test_signed_apps/app_mf-1_sf-1_p7-1.zip from test_signed_apps.js. + +function startAsyncNSSOperation(certdb, appFile) { + return new Promise((resolve, reject) => { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + appFile, + function(rv, aZipReader, aSignerCert) { + // rv will either indicate success (if NSS hasn't been shut down yet) or + // it will be some error code that varies depending on when NSS got shut + // down. As such, there's nothing really to check here. Just resolve the + // promise to continue execution. + resolve(); + } + ); + }); +} + +add_task(async function() { + do_get_profile(); + let psm = Cc["@mozilla.org/psm;1"] + .getService(Ci.nsISupports) + .QueryInterface(Ci.nsIObserver); + let certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let appFile = do_get_file("test_signed_apps/app_mf-1_sf-1_p7-1.zip"); + + let promises = []; + for (let i = 0; i < 25; i++) { + promises.push(startAsyncNSSOperation(certdb, appFile)); + } + // Trick PSM into thinking it should shut down NSS. If this test doesn't + // hang or crash, we're good. + psm.observe(null, "profile-before-change", null); + for (let i = 0; i < 25; i++) { + promises.push(startAsyncNSSOperation(certdb, appFile)); + } + await Promise.all(promises); +}); diff --git a/security/manager/ssl/tests/unit/test_ocsp_caching.js b/security/manager/ssl/tests/unit/test_ocsp_caching.js new file mode 100644 index 0000000000..68b3778bb9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_caching.js @@ -0,0 +1,406 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Checks various aspects of the OCSP cache, mainly to to ensure we do not fetch +// responses more than necessary. + +var gFetchCount = 0; +var gGoodOCSPResponse = null; +var gResponsePattern = []; +var gMessage = ""; + +function respondWithGoodOCSP(request, response) { + info("returning 200 OK"); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/ocsp-response"); + response.write(gGoodOCSPResponse); +} + +function respondWithSHA1OCSP(request, response) { + info("returning 200 OK with sha-1 delegated response"); + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/ocsp-response"); + + let args = [["good-delegated", "default-ee", "delegatedSHA1Signer", 0]]; + let responses = generateOCSPResponses(args, "ocsp_certs"); + response.write(responses[0]); +} + +function respondWithError(request, response) { + info("returning 500 Internal Server Error"); + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + let body = "Refusing to return a response"; + response.bodyOutputStream.write(body, body.length); +} + +function generateGoodOCSPResponse(thisUpdateSkew) { + let args = [["good", "default-ee", "unused", thisUpdateSkew]]; + let responses = generateOCSPResponses(args, "ocsp_certs"); + return responses[0]; +} + +function add_ocsp_test( + aHost, + aExpectedResult, + aResponses, + aMessage, + aOriginAttributes +) { + add_connection_test( + aHost, + aExpectedResult, + function() { + clearSessionCache(); + gFetchCount = 0; + gResponsePattern = aResponses; + gMessage = aMessage; + }, + function() { + // check the number of requests matches the size of aResponses + equal( + gFetchCount, + aResponses.length, + "should have made " + + aResponses.length + + " OCSP request" + + (aResponses.length == 1 ? "" : "s") + ); + }, + null, + aOriginAttributes + ); +} + +function run_test() { + do_get_profile(); + Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 4); + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + let ocspResponder = new HttpServer(); + ocspResponder.registerPrefixHandler("/", function(request, response) { + info("gFetchCount: " + gFetchCount); + let responseFunction = gResponsePattern[gFetchCount]; + Assert.notEqual(undefined, responseFunction); + + ++gFetchCount; + responseFunction(request, response); + }); + ocspResponder.start(8888); + + add_tests(); + + add_test(function() { + ocspResponder.stop(run_next_test); + }); + run_next_test(); +} + +function add_tests() { + // Test that verifying a certificate with a "short lifetime" doesn't result + // in OCSP fetching. Due to longevity requirements in our testing + // infrastructure, the certificate we encounter is valid for a very long + // time, so we have to define a "short lifetime" as something very long. + add_test(function() { + Services.prefs.setIntPref( + "security.pki.cert_short_lifetime_in_days", + 12000 + ); + run_next_test(); + }); + + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "expected zero OCSP requests for a short-lived certificate" + ); + + add_test(function() { + Services.prefs.setIntPref("security.pki.cert_short_lifetime_in_days", 100); + run_next_test(); + }); + + // If a "short lifetime" is something more reasonable, ensure that we do OCSP + // fetching for this long-lived certificate. + + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithError], + "expected one OCSP request for a long-lived certificate" + ); + add_test(function() { + Services.prefs.clearUserPref("security.pki.cert_short_lifetime_in_days"); + run_next_test(); + }); + // --------------------------------------------------------------------------- + + // Reset state + add_test(function() { + clearOCSPCache(); + run_next_test(); + }); + + // This test assumes that OCSPStaplingServer uses the same cert for + // ocsp-stapling-unknown.example.com and ocsp-stapling-none.example.com. + + // Get an Unknown response for the *.example.com cert and put it in the + // OCSP cache. + add_ocsp_test( + "ocsp-stapling-unknown.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + [], + "Stapled Unknown response -> a fetch should not have been attempted" + ); + + // A failure to retrieve an OCSP response must result in the cached Unknown + // response being recognized and honored. + add_ocsp_test( + "ocsp-stapling-none.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + [ + respondWithError, + respondWithError, + respondWithError, + respondWithError, + respondWithError, + respondWithError, + ], + "No stapled response -> a fetch should have been attempted" + ); + + // A valid Good response from the OCSP responder must override the cached + // Unknown response. + // + // Note that We need to make sure that the Unknown response and the Good + // response have different thisUpdate timestamps; otherwise, the Good + // response will be seen as "not newer" and it won't replace the existing + // entry. + add_test(function() { + gGoodOCSPResponse = generateGoodOCSPResponse(1200); + run_next_test(); + }); + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithGoodOCSP], + "Cached Unknown response, no stapled response -> a fetch" + + " should have been attempted" + ); + + // The Good response retrieved from the previous fetch must have replaced + // the Unknown response in the cache, resulting in the catched Good response + // being returned and no fetch. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "Cached Good response -> a fetch should not have been attempted" + ); + + // --------------------------------------------------------------------------- + + // Reset state + add_test(function() { + clearOCSPCache(); + run_next_test(); + }); + + // A failure to retrieve an OCSP response will result in an error entry being + // added to the cache. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithError], + "No stapled response -> a fetch should have been attempted" + ); + + // The error entry will prevent a fetch from happening for a while. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "Noted OCSP server failure -> a fetch should not have been attempted" + ); + + // The error entry must not prevent a stapled OCSP response from being + // honored. + add_ocsp_test( + "ocsp-stapling-revoked.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + [], + "Stapled Revoked response -> a fetch should not have been attempted" + ); + + // --------------------------------------------------------------------------- + + // Ensure OCSP responses from signers with SHA1 certificates are OK. This + // is included in the OCSP caching tests since there were OCSP cache-related + // regressions when sha-1 telemetry probes were added. + add_test(function() { + clearOCSPCache(); + // set security.OCSP.require so that checking the OCSP signature fails + Services.prefs.setBoolPref("security.OCSP.require", true); + run_next_test(); + }); + + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithSHA1OCSP], + "signing cert is good (though sha1) - should succeed" + ); + + add_test(function() { + Services.prefs.setBoolPref("security.OCSP.require", false); + run_next_test(); + }); + + // --------------------------------------------------------------------------- + + // Reset state + add_test(function() { + clearOCSPCache(); + run_next_test(); + }); + + // This test makes sure that OCSP cache are isolated by firstPartyDomain. + + let gObservedCnt = 0; + let protocolProxyService = Cc[ + "@mozilla.org/network/protocol-proxy-service;1" + ].getService(Ci.nsIProtocolProxyService); + + // Observe all channels and make sure the firstPartyDomain in their loadInfo's + // origin attributes are aFirstPartyDomain. + function startObservingChannels(aFirstPartyDomain) { + // We use a dummy proxy filter to catch all channels, even those that do not + // generate an "http-on-modify-request" notification. + let proxyFilter = { + applyFilter(aChannel, aProxy, aCallback) { + // We have the channel; provide it to the callback. + if (aChannel.originalURI.spec == "http://localhost:8888/") { + gObservedCnt++; + equal( + aChannel.loadInfo.originAttributes.firstPartyDomain, + aFirstPartyDomain, + "firstPartyDomain should match" + ); + } + // Pass on aProxy unmodified. + aCallback.onProxyFilterResult(aProxy); + }, + }; + protocolProxyService.registerChannelFilter(proxyFilter, 0); + // Return the stop() function: + return () => protocolProxyService.unregisterChannelFilter(proxyFilter); + } + + let stopObservingChannels; + add_test(function() { + stopObservingChannels = startObservingChannels("foo.com"); + run_next_test(); + }); + + // A good OCSP response will be cached. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithGoodOCSP], + "No stapled response (firstPartyDomain = foo.com) -> a fetch " + + "should have been attempted", + { firstPartyDomain: "foo.com" } + ); + + // The cache will prevent a fetch from happening. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "Noted OCSP server failure (firstPartyDomain = foo.com) -> a " + + "fetch should not have been attempted", + { firstPartyDomain: "foo.com" } + ); + + add_test(function() { + stopObservingChannels(); + equal(gObservedCnt, 1, "should have observed only 1 OCSP requests"); + gObservedCnt = 0; + run_next_test(); + }); + + add_test(function() { + stopObservingChannels = startObservingChannels("bar.com"); + run_next_test(); + }); + + // But using a different firstPartyDomain should result in a fetch. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithGoodOCSP], + "No stapled response (firstPartyDomain = bar.com) -> a fetch " + + "should have been attempted", + { firstPartyDomain: "bar.com" } + ); + + add_test(function() { + stopObservingChannels(); + equal(gObservedCnt, 1, "should have observed only 1 OCSP requests"); + gObservedCnt = 0; + run_next_test(); + }); + + // --------------------------------------------------------------------------- + + // Reset state + add_test(function() { + clearOCSPCache(); + run_next_test(); + }); + + // Test that the OCSP cache is not isolated by userContextId. + + // A good OCSP response will be cached. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [respondWithGoodOCSP], + "No stapled response (userContextId = 1) -> a fetch " + + "should have been attempted", + { userContextId: 1 } + ); + + // The cache will prevent a fetch from happening. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "Noted OCSP server failure (userContextId = 1) -> a " + + "fetch should not have been attempted", + { userContextId: 1 } + ); + + // Fetching is prevented even if in a different userContextId. + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + [], + "Noted OCSP server failure (userContextId = 2) -> a " + + "fetch should not have been attempted", + { userContextId: 2 } + ); + + // --------------------------------------------------------------------------- + + // Reset state + add_test(function() { + clearOCSPCache(); + run_next_test(); + }); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_enabled_pref.js b/security/manager/ssl/tests/unit/test_ocsp_enabled_pref.js new file mode 100644 index 0000000000..cf64ed17fb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_enabled_pref.js @@ -0,0 +1,150 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Checks that the security.OCSP.enabled pref correctly controls OCSP fetching +// behavior. + +do_get_profile(); // Must be called before getting nsIX509CertDB +const gCertDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const SERVER_PORT = 8888; + +function certFromFile(filename) { + return constructCertFromFile(`test_ev_certs/${filename}.pem`); +} + +function loadCert(certName, trustString) { + addCertFromFile(gCertDB, `test_ev_certs/${certName}.pem`, trustString); +} + +function getFailingOCSPResponder() { + return getFailingHttpServer(SERVER_PORT, ["www.example.com"]); +} + +function getOCSPResponder(expectedCertNames) { + return startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_ev_certs", + expectedCertNames, + [] + ); +} + +// Tests that in ocspOff mode, OCSP fetches are never done. +async function testOff() { + Services.prefs.setIntPref("security.OCSP.enabled", 0); + info("Setting security.OCSP.enabled to 0"); + + // EV chains should verify successfully but never get EV status. + clearOCSPCache(); + let ocspResponder = getFailingOCSPResponder(); + await checkEVStatus( + gCertDB, + certFromFile("test-oid-path-ee"), + certificateUsageSSLServer, + false + ); + await stopOCSPResponder(ocspResponder); + + // A DV chain should verify successfully. + clearOCSPCache(); + ocspResponder = getFailingOCSPResponder(); + await checkCertErrorGeneric( + gCertDB, + certFromFile("non-ev-root-path-ee"), + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await stopOCSPResponder(ocspResponder); +} + +// Tests that in ocspOn mode, OCSP fetches are done for both EV and DV certs. +async function testOn() { + Services.prefs.setIntPref("security.OCSP.enabled", 1); + info("Setting security.OCSP.enabled to 1"); + + // If a successful OCSP response is fetched, then an EV chain should verify + // successfully and get EV status as well. + clearOCSPCache(); + let ocspResponder = getOCSPResponder( + gEVExpected + ? ["test-oid-path-int", "test-oid-path-ee"] + : ["test-oid-path-ee"] + ); + await checkEVStatus( + gCertDB, + certFromFile("test-oid-path-ee"), + certificateUsageSSLServer, + gEVExpected + ); + await stopOCSPResponder(ocspResponder); + + // If a successful OCSP response is fetched, then a DV chain should verify + // successfully. + clearOCSPCache(); + ocspResponder = getOCSPResponder(["non-ev-root-path-ee"]); + await checkCertErrorGeneric( + gCertDB, + certFromFile("non-ev-root-path-ee"), + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await stopOCSPResponder(ocspResponder); +} + +// Tests that in ocspEVOnly mode, OCSP fetches are done for EV certs only. +async function testEVOnly() { + Services.prefs.setIntPref("security.OCSP.enabled", 2); + info("Setting security.OCSP.enabled to 2"); + + // If a successful OCSP response is fetched, then an EV chain should verify + // successfully and get EV status as well. + clearOCSPCache(); + let ocspResponder = gEVExpected + ? getOCSPResponder(["test-oid-path-int", "test-oid-path-ee"]) + : getFailingOCSPResponder(); + await checkEVStatus( + gCertDB, + certFromFile("test-oid-path-ee"), + certificateUsageSSLServer, + gEVExpected + ); + await stopOCSPResponder(ocspResponder); + + // A DV chain should verify successfully even without doing OCSP fetches. + clearOCSPCache(); + ocspResponder = getFailingOCSPResponder(); + await checkCertErrorGeneric( + gCertDB, + certFromFile("non-ev-root-path-ee"), + PRErrorCodeSuccess, + certificateUsageSSLServer + ); + await stopOCSPResponder(ocspResponder); +} + +add_task(async function() { + registerCleanupFunction(() => { + Services.prefs.clearUserPref("network.dns.localDomains"); + Services.prefs.clearUserPref("security.OCSP.enabled"); + Services.prefs.clearUserPref("security.OCSP.require"); + }); + Services.prefs.setCharPref("network.dns.localDomains", "www.example.com"); + // Enable hard fail to ensure chains that should only succeed because they get + // a good OCSP response do not succeed due to soft fail leniency. + Services.prefs.setBoolPref("security.OCSP.require", true); + + loadCert("evroot", "CTu,,"); + loadCert("test-oid-path-int", ",,"); + loadCert("non-evroot-ca", "CTu,,"); + loadCert("non-ev-root-path-int", ",,"); + + await testOff(); + await testOn(); + await testEVOnly(); +}); diff --git a/security/manager/ssl/tests/unit/test_ocsp_must_staple.js b/security/manager/ssl/tests/unit/test_ocsp_must_staple.js new file mode 100644 index 0000000000..46f6127c50 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_must_staple.js @@ -0,0 +1,160 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Tests OCSP Must Staple handling by connecting to various domains (as faked by +// a server running locally) that correspond to combinations of whether the +// extension is present in intermediate and end-entity certificates. + +var gExpectOCSPRequest; + +function add_ocsp_test( + aHost, + aExpectedResult, + aStaplingEnabled, + aExpectOCSPRequest = false, + aWithSecurityInfo = undefined +) { + add_connection_test( + aHost, + aExpectedResult, + function() { + gExpectOCSPRequest = aExpectOCSPRequest; + clearOCSPCache(); + clearSessionCache(); + Services.prefs.setBoolPref( + "security.ssl.enable_ocsp_stapling", + aStaplingEnabled + ); + }, + aWithSecurityInfo + ); +} + +function add_tests() { + // Next, a case where it's present in the intermediate, not the ee + add_ocsp_test( + "ocsp-stapling-plain-ee-with-must-staple-int.example.com", + MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING, + true + ); + + // We disable OCSP stapling in the next two tests so we can perform checks + // on TLS Features in the chain without needing to support the TLS + // extension values used. + // Test an issuer with multiple TLS features in matched in the EE + add_ocsp_test( + "multi-tls-feature-good.example.com", + PRErrorCodeSuccess, + false + ); + + // Finally, an issuer with multiple TLS features not matched by the EE. + add_ocsp_test( + "multi-tls-feature-bad.example.com", + MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING, + false + ); + + // Now a bunch of operations with only a must-staple ee + add_ocsp_test( + "ocsp-stapling-must-staple.example.com", + PRErrorCodeSuccess, + true + ); + + add_ocsp_test( + "ocsp-stapling-must-staple-revoked.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + true + ); + + add_ocsp_test( + "ocsp-stapling-must-staple-missing.example.com", + MOZILLA_PKIX_ERROR_REQUIRED_TLS_FEATURE_MISSING, + true, + true + ); + + add_ocsp_test( + "ocsp-stapling-must-staple-empty.example.com", + SEC_ERROR_OCSP_MALFORMED_RESPONSE, + true + ); + + add_ocsp_test( + "ocsp-stapling-must-staple-missing.example.com", + PRErrorCodeSuccess, + false, + true + ); + + // If the stapled response is expired, we will try to fetch a new one. + // If that fails, we should report the original error. + add_ocsp_test( + "ocsp-stapling-must-staple-expired.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + true, + true + ); + // Similarly with a "try server later" response. + add_ocsp_test( + "ocsp-stapling-must-staple-try-later.example.com", + SEC_ERROR_OCSP_TRY_SERVER_LATER, + true, + true + ); + // And again with an invalid OCSP response signing certificate. + add_ocsp_test( + "ocsp-stapling-must-staple-invalid-signer.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + + // check that disabling must-staple works + add_test(function() { + clearSessionCache(); + Services.prefs.setBoolPref("security.ssl.enable_ocsp_must_staple", false); + run_next_test(); + }); + + add_ocsp_test( + "ocsp-stapling-must-staple-missing.example.com", + PRErrorCodeSuccess, + true, + true + ); +} + +function run_test() { + do_get_profile(); + Services.prefs.setBoolPref("security.ssl.enable_ocsp_must_staple", true); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + // This test may sometimes fail on android due to an OCSP request timing out. + // That aspect of OCSP requests is not what we're testing here, so we can just + // bump the timeout and hopefully avoid these failures. + Services.prefs.setIntPref("security.OCSP.timeoutMilliseconds.soft", 5000); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + ok( + gExpectOCSPRequest, + "Should be getting an OCSP request only when expected" + ); + }); + fakeOCSPResponder.start(8888); + + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + add_tests(); + + add_test(function() { + fakeOCSPResponder.stop(run_next_test); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js b/security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js new file mode 100644 index 0000000000..1c9ba6dcce --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_no_hsts_upgrade.js @@ -0,0 +1,68 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// Test that if an OCSP request is made to a domain that (erroneously) +// has HSTS status, the request is not upgraded from HTTP to HTTPS. + +function run_test() { + do_get_profile(); + // OCSP required means this test will only pass if the request succeeds. + Services.prefs.setBoolPref("security.OCSP.require", true); + + // We don't actually make use of stapling in this test. This is just how we + // get a TLS connection. + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + let args = [["good", "default-ee", "unused", 0]]; + let ocspResponses = generateOCSPResponses(args, "ocsp_certs"); + let goodOCSPResponse = ocspResponses[0]; + + let ocspResponder = new HttpServer(); + ocspResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/ocsp-response"); + response.write(goodOCSPResponse); + }); + ocspResponder.start(8888); + + // ocsp-stapling-none.example.com does not staple an OCSP response in the + // handshake, so the revocation checking code will attempt to fetch one. + // Since the domain of the certificate's OCSP AIA URI is an HSTS host + // (as added in the setup of this test, below), a buggy implementation would + // upgrade the OCSP request to HTTPS. We specifically prevent this. This + // test demonstrates that our implementation is correct in this regard. + add_connection_test("ocsp-stapling-none.example.com", PRErrorCodeSuccess); + add_test(function() { + run_next_test(); + }); + + add_test(function() { + ocspResponder.stop(run_next_test); + }); + + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + let uri = Services.io.newURI("http://localhost"); + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + SSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=10000", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "Domain for the OCSP AIA URI should be considered a HSTS host, otherwise" + + " we wouldn't be testing what we think we're testing" + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_private_caching.js b/security/manager/ssl/tests/unit/test_ocsp_private_caching.js new file mode 100644 index 0000000000..a3ee41af3f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_private_caching.js @@ -0,0 +1,138 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// In which we connect to a host and encounter OCSP responses with the +// Cache-Control header set, which Necko will normally cache. We need to ensure +// that these responses aren't cached to disk when the original https request +// was in a private context. + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const SERVER_PORT = 8888; + +function start_ocsp_responder( + expectedCertNames, + expectedPaths, + expectedMethods +) { + return startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_ocsp_fetch_method", + expectedCertNames, + expectedPaths, + expectedMethods + ); +} + +function add_flush_cache() { + add_test(() => { + // This appears to either fire multiple times or fire once for every + // observer that has ever been passed to flush. To prevent multiple calls to + // run_next_test, keep track of if this observer has already called it. + let observed = false; + let observer = { + observe: () => { + if (!observed) { + observed = true; + run_next_test(); + } + }, + }; + Services.cache2.QueryInterface(Ci.nsICacheTesting).flush(observer); + }); +} + +function add_ocsp_necko_cache_test(loadContext, shouldFindEntry) { + // Pre-testcase cleanup/setup. + add_test(() => { + Services.cache2.clear(); + run_next_test(); + }); + add_flush_cache(); + + let responder; + add_test(() => { + clearOCSPCache(); + clearSessionCache(); + responder = startOCSPResponder( + SERVER_PORT, + "localhost", + "ocsp_certs", + ["default-ee"], + [], + [], + [], + [["Cache-Control", "max-age: 1000"]] + ); + run_next_test(); + }); + + // Prepare a connection that will cause an OCSP request. + add_connection_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + null, + null, + null, + loadContext.originAttributes + ); + + add_flush_cache(); + + // Traverse the cache and ensure the response made it into the cache with the + // appropriate properties (private or not private). + add_test(() => { + let foundEntry = false; + let visitor = { + onCacheStorageInfo() {}, + onCacheEntryInfo( + aURI, + aIdEnhance, + aDataSize, + aFetchCount, + aLastModifiedTime, + aExpirationTime, + aPinned, + aInfo + ) { + Assert.equal( + aURI.spec, + "http://localhost:8888/", + "expected OCSP request URI should match" + ); + foundEntry = true; + }, + onCacheEntryVisitCompleted() { + Assert.equal( + foundEntry, + shouldFindEntry, + "should only find a cached entry if we're expecting one" + ); + run_next_test(); + }, + QueryInterface: ChromeUtils.generateQI(["nsICacheStorageVisitor"]), + }; + Services.cache2.asyncVisitAllStorages(visitor, true); + }); + + // Clean up (stop the responder). + add_test(() => { + responder.stop(run_next_test); + }); +} + +function run_test() { + Services.prefs.setIntPref("security.OCSP.enabled", 1); + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + add_ocsp_necko_cache_test(Services.loadContextInfo.private, false); + add_ocsp_necko_cache_test(Services.loadContextInfo.default, true); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_required.js b/security/manager/ssl/tests/unit/test_ocsp_required.js new file mode 100644 index 0000000000..6e1c52a6eb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_required.js @@ -0,0 +1,74 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// In which we connect to a domain (as faked by a server running locally) and +// start up an OCSP responder (also basically faked) that gives a response with +// a bad signature (and later, an empty response). With security.OCSP.require +// set to true, these connections should fail (but they also shouldn't cause +// assertion failures). + +var gOCSPRequestCount = 0; +var gOCSPResponse; + +function run_test() { + do_get_profile(); + Services.prefs.setBoolPref("security.OCSP.require", true); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + + // We don't actually make use of stapling in this test. This is just how we + // get a TLS connection. + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + let args = [["bad-signature", "default-ee", "unused", 0]]; + let ocspResponses = generateOCSPResponses(args, "ocsp_certs"); + // Start by replying with a response with a bad signature. + gOCSPResponse = ocspResponses[0]; + + let ocspResponder = new HttpServer(); + ocspResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/ocsp-response"); + response.write(gOCSPResponse); + gOCSPRequestCount++; + }); + ocspResponder.start(8888); + + add_tests(); + + add_test(function() { + ocspResponder.stop(run_next_test); + }); + + run_next_test(); +} + +function add_tests() { + add_connection_test( + "ocsp-stapling-none.example.com", + SEC_ERROR_OCSP_BAD_SIGNATURE + ); + add_connection_test( + "ocsp-stapling-none.example.com", + SEC_ERROR_OCSP_BAD_SIGNATURE + ); + add_test(function() { + equal( + gOCSPRequestCount, + 1, + "OCSP request count should be 1 due to OCSP response caching" + ); + gOCSPRequestCount = 0; + // Now set the OCSP responder to reply with 200 OK but empty content. + gOCSPResponse = ""; + clearOCSPCache(); + run_next_test(); + }); + + add_connection_test( + "ocsp-stapling-none.example.com", + SEC_ERROR_OCSP_MALFORMED_RESPONSE + ); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_stapling.js b/security/manager/ssl/tests/unit/test_ocsp_stapling.js new file mode 100644 index 0000000000..a41610392b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_stapling.js @@ -0,0 +1,393 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// In which we connect to a number of domains (as faked by a server running +// locally) with and without OCSP stapling enabled to determine that good +// things happen and bad things don't. + +var gExpectOCSPRequest; + +function add_ocsp_test( + aHost, + aExpectedResult, + aStaplingEnabled, + aExpectOCSPRequest = false +) { + add_connection_test(aHost, aExpectedResult, function() { + gExpectOCSPRequest = aExpectOCSPRequest; + clearOCSPCache(); + clearSessionCache(); + Services.prefs.setBoolPref( + "security.ssl.enable_ocsp_stapling", + aStaplingEnabled + ); + }); +} + +function add_tests() { + // In the absence of OCSP stapling, these should actually all work. + add_ocsp_test( + "ocsp-stapling-good.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-revoked.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-good-other-ca.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-malformed.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-srverr.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-trylater.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-needssig.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-unauthorized.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-unknown.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-good-other.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-expired.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-skip-responseBytes.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-critical-extension.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-noncritical-extension.example.com", + PRErrorCodeSuccess, + false, + true + ); + add_ocsp_test( + "ocsp-stapling-empty-extensions.example.com", + PRErrorCodeSuccess, + false, + true + ); + + // Now test OCSP stapling + // The following error codes are defined in security/nss/lib/util/SECerrs.h + + add_ocsp_test("ocsp-stapling-good.example.com", PRErrorCodeSuccess, true); + + add_ocsp_test( + "ocsp-stapling-revoked.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + true + ); + + // This stapled response is from a CA that is untrusted and did not issue + // the server's certificate. + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let otherTestCA = constructCertFromFile("ocsp_certs/other-test-ca.pem"); + add_test(function() { + certDB.setCertTrust( + otherTestCA, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.UNTRUSTED + ); + run_next_test(); + }); + add_ocsp_test( + "ocsp-stapling-good-other-ca.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + + // The stapled response is from a CA that is trusted but did not issue the + // server's certificate. + add_test(function() { + certDB.setCertTrust( + otherTestCA, + Ci.nsIX509Cert.CA_CERT, + Ci.nsIX509CertDB.TRUSTED_SSL + ); + run_next_test(); + }); + // TODO(bug 979055): When using ByName instead of ByKey, the error here is + // SEC_ERROR_OCSP_UNAUTHORIZED_RESPONSE. We should be testing both cases. + add_ocsp_test( + "ocsp-stapling-good-other-ca.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + + // TODO: Test the case where the signing cert can't be found at all, which + // will result in SEC_ERROR_BAD_DATABASE in the NSS classic case. + + add_ocsp_test( + "ocsp-stapling-malformed.example.com", + SEC_ERROR_OCSP_MALFORMED_REQUEST, + true + ); + add_ocsp_test( + "ocsp-stapling-srverr.example.com", + SEC_ERROR_OCSP_SERVER_ERROR, + true + ); + add_ocsp_test( + "ocsp-stapling-trylater.example.com", + SEC_ERROR_OCSP_TRY_SERVER_LATER, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-needssig.example.com", + SEC_ERROR_OCSP_REQUEST_NEEDS_SIG, + true + ); + add_ocsp_test( + "ocsp-stapling-unauthorized.example.com", + SEC_ERROR_OCSP_UNAUTHORIZED_REQUEST, + true + ); + add_ocsp_test( + "ocsp-stapling-unknown.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + true + ); + add_ocsp_test( + "ocsp-stapling-good-other.example.com", + MOZILLA_PKIX_ERROR_OCSP_RESPONSE_FOR_CERT_MISSING, + true + ); + // If the server doesn't staple an OCSP response, we continue as normal + // (this means that even though stapling is enabled, we expect an OCSP + // request). + add_connection_test( + "ocsp-stapling-none.example.com", + PRErrorCodeSuccess, + function() { + gExpectOCSPRequest = true; + clearOCSPCache(); + clearSessionCache(); + Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true); + } + ); + add_ocsp_test( + "ocsp-stapling-empty.example.com", + SEC_ERROR_OCSP_MALFORMED_RESPONSE, + true + ); + + add_ocsp_test( + "ocsp-stapling-skip-responseBytes.example.com", + SEC_ERROR_OCSP_MALFORMED_RESPONSE, + true + ); + + add_ocsp_test( + "ocsp-stapling-critical-extension.example.com", + SEC_ERROR_UNKNOWN_CRITICAL_EXTENSION, + true + ); + add_ocsp_test( + "ocsp-stapling-noncritical-extension.example.com", + PRErrorCodeSuccess, + true + ); + // TODO(bug 997994): Disallow empty Extensions in responses + add_ocsp_test( + "ocsp-stapling-empty-extensions.example.com", + PRErrorCodeSuccess, + true + ); + + add_ocsp_test( + "ocsp-stapling-delegated-included.example.com", + PRErrorCodeSuccess, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-included-last.example.com", + PRErrorCodeSuccess, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-missing.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-missing-multiple.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-no-extKeyUsage.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-from-intermediate.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-keyUsage-crlSigning.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + add_ocsp_test( + "ocsp-stapling-delegated-wrong-extKeyUsage.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + + // ocsp-stapling-expired.example.com and + // ocsp-stapling-expired-fresh-ca.example.com are handled in + // test_ocsp_stapling_expired.js + + // Check that OCSP responder certificates with key sizes below 1024 bits are + // rejected, even when the main certificate chain keys are at least 1024 bits. + add_ocsp_test( + "keysize-ocsp-delegated.example.com", + SEC_ERROR_OCSP_INVALID_SIGNING_CERT, + true, + true + ); + + add_ocsp_test( + "revoked-ca-cert-used-as-end-entity.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + true + ); +} + +function check_ocsp_stapling_telemetry() { + let histogram = Services.telemetry + .getHistogramById("SSL_OCSP_STAPLING") + .snapshot(); + equal( + histogram.values[0], + 0, + "Should have 0 connections for unused histogram bucket 0" + ); + equal( + histogram.values[1], + 5, + "Actual and expected connections with a good response should match" + ); + equal( + histogram.values[2], + 18, + "Actual and expected connections with no stapled response should match" + ); + equal( + histogram.values[3] || 0, + 0, + "Actual and expected connections with an expired response should match" + ); + equal( + histogram.values[4], + 21, + "Actual and expected connections with bad responses should match" + ); + run_next_test(); +} + +function run_test() { + do_get_profile(); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + // This test may sometimes fail on android due to an OCSP request timing out. + // That aspect of OCSP requests is not what we're testing here, so we can just + // bump the timeout and hopefully avoid these failures. + Services.prefs.setIntPref("security.OCSP.timeoutMilliseconds.soft", 5000); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + ok( + gExpectOCSPRequest, + "Should be getting an OCSP request only when expected" + ); + }); + fakeOCSPResponder.start(8888); + + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + add_tests(); + + add_test(function() { + fakeOCSPResponder.stop(check_ocsp_stapling_telemetry); + }); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js b/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js new file mode 100644 index 0000000000..4e65baeb01 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_stapling_expired.js @@ -0,0 +1,319 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// In which we connect to a number of domains (as faked by a server running +// locally) with OCSP stapling enabled to determine that good things happen +// and bad things don't, specifically with respect to various expired OCSP +// responses (stapled and otherwise). +// According to RFC 6066, if a stapled OCSP response can't be satisfactorilly +// verified, the client should terminate the connection. Unfortunately, due to +// some bugs where servers will staple any old garbage without verifying it, we +// can't be this strict in practice. Originally this caveat only applied to +// expired responses, but recent high-profile failures have caused us to expand +// this to "try later" responses and responses where the signing certificate +// doesn't verify successfully. + +var gCurrentOCSPResponse = null; +var gOCSPRequestCount = 0; + +function add_ocsp_test( + aHost, + aExpectedResult, + aOCSPResponseToServe, + aExpectedRequestCount +) { + add_connection_test( + aHost, + aExpectedResult, + function() { + clearOCSPCache(); + clearSessionCache(); + gCurrentOCSPResponse = aOCSPResponseToServe; + gOCSPRequestCount = 0; + }, + function() { + equal( + gOCSPRequestCount, + aExpectedRequestCount, + "Should have made " + + aExpectedRequestCount + + " fallback OCSP request" + + (aExpectedRequestCount == 1 ? "" : "s") + ); + } + ); +} + +do_get_profile(); +Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true); +Services.prefs.setIntPref("security.OCSP.enabled", 1); +// Sometimes this test will fail on android due to an OCSP request timing out. +// That aspect of OCSP requests is not what we're testing here, so we can just +// bump the timeout and hopefully avoid these failures. +Services.prefs.setIntPref("security.OCSP.timeoutMilliseconds.soft", 5000); +Services.prefs.setIntPref("security.pki.sha1_enforcement_level", 4); +var args = [ + ["good", "default-ee", "unused", 0], + ["expiredresponse", "default-ee", "unused", 0], + ["oldvalidperiod", "default-ee", "unused", 0], + ["revoked", "default-ee", "unused", 0], + ["unknown", "default-ee", "unused", 0], + ["good", "must-staple-ee", "unused", 0], +]; +var ocspResponses = generateOCSPResponses(args, "ocsp_certs"); +// Fresh response, certificate is good. +var ocspResponseGood = ocspResponses[0]; +// Expired response, certificate is good. +var expiredOCSPResponseGood = ocspResponses[1]; +// Fresh signature, old validity period, certificate is good. +var oldValidityPeriodOCSPResponseGood = ocspResponses[2]; +// Fresh signature, certificate is revoked. +var ocspResponseRevoked = ocspResponses[3]; +// Fresh signature, certificate is unknown. +var ocspResponseUnknown = ocspResponses[4]; +var ocspResponseGoodMustStaple = ocspResponses[5]; + +// sometimes we expect a result without re-fetch +var willNotRetry = 1; +// but sometimes, since a bad response is in the cache, OCSP fetch will be +// attempted for each validation - in practice, for these test certs, this +// means 6 requests because various hash algorithm and key size combinations +// are tried. +var willRetry = 6; + +function run_test() { + let ocspResponder = new HttpServer(); + ocspResponder.registerPrefixHandler("/", function(request, response) { + if (gCurrentOCSPResponse) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/ocsp-response"); + response.write(gCurrentOCSPResponse); + } else { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + response.write("Internal Server Error"); + } + gOCSPRequestCount++; + }); + ocspResponder.start(8888); + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + // In these tests, the OCSP stapling server gives us a stapled + // response based on the host name ("ocsp-stapling-expired" or + // "ocsp-stapling-expired-fresh-ca"). We then ensure that we're + // properly falling back to fetching revocation information. + // For ocsp-stapling-expired.example.com, the OCSP stapling server + // staples an expired OCSP response. The certificate has not expired. + // For ocsp-stapling-expired-fresh-ca.example.com, the OCSP stapling + // server staples an OCSP response with a recent signature but with an + // out-of-date validity period. The certificate has not expired. + add_ocsp_test( + "ocsp-stapling-expired.example.com", + PRErrorCodeSuccess, + ocspResponseGood, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + PRErrorCodeSuccess, + ocspResponseGood, + willNotRetry + ); + // if we can't fetch a more recent response when + // given an expired stapled response, we terminate the connection. + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + expiredOCSPResponseGood, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + expiredOCSPResponseGood, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + oldValidityPeriodOCSPResponseGood, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + oldValidityPeriodOCSPResponseGood, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + null, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_OCSP_OLD_RESPONSE, + null, + willNotRetry + ); + // Of course, if the newer response indicates Revoked or Unknown, + // that status must be returned. + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + ocspResponseRevoked, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + ocspResponseRevoked, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-expired.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + ocspResponseUnknown, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-expired-fresh-ca.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + ocspResponseUnknown, + willRetry + ); + + // If the response is expired but indicates Revoked or Unknown and a + // newer status can't be fetched, the Revoked or Unknown status will + // be returned. + add_ocsp_test( + "ocsp-stapling-revoked-old.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + null, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-unknown-old.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + null, + willNotRetry + ); + // If the response is expired but indicates Revoked or Unknown and + // a newer status can be fetched and successfully verified, this + // should result in a successful certificate verification. + add_ocsp_test( + "ocsp-stapling-revoked-old.example.com", + PRErrorCodeSuccess, + ocspResponseGood, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-unknown-old.example.com", + PRErrorCodeSuccess, + ocspResponseGood, + willNotRetry + ); + // If a newer status can be fetched but it fails to verify, the + // Revoked or Unknown status of the expired stapled response + // should be returned. + add_ocsp_test( + "ocsp-stapling-revoked-old.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + expiredOCSPResponseGood, + willRetry + ); + add_ocsp_test( + "ocsp-stapling-unknown-old.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + expiredOCSPResponseGood, + willRetry + ); + + // These tests are verifying that an valid but very old response + // is rejected as a valid stapled response, requiring a fetch + // from the ocsp responder. + add_ocsp_test( + "ocsp-stapling-ancient-valid.example.com", + PRErrorCodeSuccess, + ocspResponseGood, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-ancient-valid.example.com", + SEC_ERROR_REVOKED_CERTIFICATE, + ocspResponseRevoked, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-ancient-valid.example.com", + SEC_ERROR_OCSP_UNKNOWN_CERT, + ocspResponseUnknown, + willRetry + ); + + // Test how OCSP-must-staple (i.e. TLS feature) interacts with stapled OCSP + // responses that don't successfully verify. + // A strict reading of the relevant RFCs might say that these connections + // should all fail because a satisfactory stapled OCSP response is not + // present, but for compatibility reasons we fall back to active OCSP fetching + // in these situations. If the fetch succeeds, then connection succeeds. + add_ocsp_test( + "ocsp-stapling-must-staple-expired.example.com", + PRErrorCodeSuccess, + ocspResponseGoodMustStaple, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-must-staple-try-later.example.com", + PRErrorCodeSuccess, + ocspResponseGoodMustStaple, + willNotRetry + ); + add_ocsp_test( + "ocsp-stapling-must-staple-invalid-signer.example.com", + PRErrorCodeSuccess, + ocspResponseGoodMustStaple, + willNotRetry + ); + + add_test(function() { + ocspResponder.stop(run_next_test); + }); + add_test(check_ocsp_stapling_telemetry); + run_next_test(); +} + +function check_ocsp_stapling_telemetry() { + let histogram = Services.telemetry + .getHistogramById("SSL_OCSP_STAPLING") + .snapshot(); + equal( + histogram.values[0] || 0, + 0, + "Should have 0 connections for unused histogram bucket 0" + ); + equal( + histogram.values[1] || 0, + 0, + "Actual and expected connections with a good response should match" + ); + equal( + histogram.values[2] || 0, + 0, + "Actual and expected connections with no stapled response should match" + ); + equal( + histogram.values[3], + 22, + "Actual and expected connections with an expired response should match" + ); + equal( + histogram.values[4], + 2, + "Actual and expected connections with bad responses should match" + ); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js b/security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js new file mode 100644 index 0000000000..4fc8013ea9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_stapling_with_intermediate.js @@ -0,0 +1,48 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// In which we connect to a server that staples an OCSP response for a +// certificate signed by an intermediate that has an OCSP AIA to ensure +// that an OCSP request is not made for the intermediate. + +var gOCSPRequestCount = 0; + +function add_ocsp_test(aHost, aExpectedResult) { + add_connection_test(aHost, aExpectedResult, function() { + clearOCSPCache(); + clearSessionCache(); + }); +} + +function run_test() { + do_get_profile(); + Services.prefs.setBoolPref("security.ssl.enable_ocsp_stapling", true); + + let ocspResponder = new HttpServer(); + ocspResponder.registerPrefixHandler("/", function(request, response) { + gOCSPRequestCount++; + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + let body = "Refusing to return a response"; + response.bodyOutputStream.write(body, body.length); + }); + ocspResponder.start(8888); + + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + add_ocsp_test( + "ocsp-stapling-with-intermediate.example.com", + PRErrorCodeSuccess + ); + + add_test(function() { + ocspResponder.stop(run_next_test); + }); + add_test(function() { + equal(gOCSPRequestCount, 0, "No OCSP requests should have been made"); + run_next_test(); + }); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_timeout.js b/security/manager/ssl/tests/unit/test_ocsp_timeout.js new file mode 100644 index 0000000000..e06f064d04 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_timeout.js @@ -0,0 +1,100 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// This test connects to ocsp-stapling-none.example.com to test that OCSP +// requests are cancelled if they're taking too long. +// ocsp-stapling-none.example.com doesn't staple an OCSP response, so +// connecting to it will cause a request to the OCSP responder. As with all of +// these tests, the OCSP AIA (i.e. the url of the responder) in the certificate +// is http://localhost:8888. Since this test opens a TCP socket listening on +// port 8888 that just accepts connections and then ignores them (with +// connect/read/write timeouts of 30 seconds), the OCSP requests should cancel +// themselves. When OCSP hard-fail is enabled, connections will be terminated. +// Otherwise, they will succeed. + +var gSocketListener = { + onSocketAccepted(serverSocket, socketTransport) { + socketTransport.setTimeout(Ci.nsISocketTransport.TIMEOUT_CONNECT, 30); + socketTransport.setTimeout(Ci.nsISocketTransport.TIMEOUT_READ_WRITE, 30); + }, + + onStopListening(serverSocket, status) {}, +}; + +function run_test() { + do_get_profile(); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + + add_tls_server_setup("OCSPStaplingServer", "ocsp_certs"); + + let socket = Cc["@mozilla.org/network/server-socket;1"].createInstance( + Ci.nsIServerSocket + ); + socket.init(8888, true, -1); + socket.asyncListen(gSocketListener); + + add_one_test(false, "security.OCSP.timeoutMilliseconds.soft", 1000); + add_one_test(false, "security.OCSP.timeoutMilliseconds.soft", 2000); + add_one_test(false, "security.OCSP.timeoutMilliseconds.soft", 4000); + + add_one_test(true, "security.OCSP.timeoutMilliseconds.hard", 3000); + add_one_test(true, "security.OCSP.timeoutMilliseconds.hard", 10000); + add_one_test(true, "security.OCSP.timeoutMilliseconds.hard", 15000); + + add_test(function() { + socket.close(); + run_next_test(); + }); + run_next_test(); +} + +function add_one_test(useHardFail, timeoutPrefName, timeoutMilliseconds) { + let startTime; + add_test(function() { + Services.prefs.setBoolPref("security.OCSP.require", useHardFail); + Services.prefs.setIntPref(timeoutPrefName, timeoutMilliseconds); + startTime = new Date(); + run_next_test(); + }); + + add_connection_test( + "ocsp-stapling-none.example.com", + useHardFail ? SEC_ERROR_OCSP_SERVER_ERROR : PRErrorCodeSuccess, + clearSessionCache + ); + + add_test(function() { + let endTime = new Date(); + let timeDifference = endTime - startTime; + info(`useHardFail = ${useHardFail}`); + info(`startTime = ${startTime.getTime()} (${startTime})`); + info(`endTime = ${endTime.getTime()} (${endTime})`); + info(`timeDifference = ${timeDifference}ms`); + // Date() is not guaranteed to be monotonic, so add extra fuzz time to + // prevent intermittent failures (this only appeared to be a problem on + // Windows XP). See Bug 1121117. + const FUZZ_MS = 300; + ok( + timeDifference + FUZZ_MS > timeoutMilliseconds, + `OCSP timeout should be ~${timeoutMilliseconds}s for ` + + `${useHardFail ? "hard" : "soft"}-fail` + ); + // Make sure we didn't wait too long. + // (Unfortunately, we probably can't have a tight upper bound on + // how long is too long for this test, because we might be running + // on slow hardware.) + ok( + timeDifference < 60000, + "Automatic OCSP timeout shouldn't be more than 60s" + ); + + // Reset state + clearOCSPCache(); + Services.prefs.clearUserPref("security.OCSP.require"); + Services.prefs.clearUserPref(timeoutPrefName); + run_next_test(); + }); +} diff --git a/security/manager/ssl/tests/unit/test_ocsp_url.js b/security/manager/ssl/tests/unit/test_ocsp_url.js new file mode 100644 index 0000000000..b26d74b3b3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url.js @@ -0,0 +1,122 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// In which we try to validate several ocsp responses, checking in particular +// if the ocsp url is valid and the path expressed is correctly passed to +// the caller. + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const SERVER_PORT = 8888; + +function failingOCSPResponder() { + return getFailingHttpServer(SERVER_PORT, ["www.example.com"]); +} + +function start_ocsp_responder(expectedCertNames, expectedPaths) { + return startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_ocsp_url", + expectedCertNames, + expectedPaths + ); +} + +function check_cert_err(cert_name, expected_error) { + let cert = constructCertFromFile("test_ocsp_url/" + cert_name + ".pem"); + return checkCertErrorGeneric( + certdb, + cert, + expected_error, + certificateUsageSSLServer + ); +} + +add_task(async function() { + addCertFromFile(certdb, "test_ocsp_url/ca.pem", "CTu,CTu,CTu"); + addCertFromFile(certdb, "test_ocsp_url/int.pem", ",,"); + + // Enabled so that we can force ocsp failure responses. + Services.prefs.setBoolPref("security.OCSP.require", true); + + Services.prefs.setCharPref("network.dns.localDomains", "www.example.com"); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + + // Note: We don't test the case of a well-formed HTTP URL with an empty port + // because the OCSP code would then send a request to port 80, which we + // can't use in tests. + + clearOCSPCache(); + let ocspResponder = failingOCSPResponder(); + await check_cert_err("bad-scheme", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("empty-scheme-url", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("ftp-url", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("https-url", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = start_ocsp_responder(["hTTp-url"], ["hTTp-url"]); + await check_cert_err("hTTp-url", PRErrorCodeSuccess); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("negative-port", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("no-host-url", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = start_ocsp_responder(["no-path-url"], [""]); + await check_cert_err("no-path-url", PRErrorCodeSuccess); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err( + "no-scheme-host-port", + SEC_ERROR_CERT_BAD_ACCESS_LOCATION + ); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("no-scheme-url", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + clearOCSPCache(); + ocspResponder = failingOCSPResponder(); + await check_cert_err("unknown-scheme", SEC_ERROR_CERT_BAD_ACCESS_LOCATION); + await stopOCSPResponder(ocspResponder); + + // Note: We currently don't have anything that ensures user:pass sections + // weren't sent. The following test simply checks that such sections + // don't cause failures. + clearOCSPCache(); + ocspResponder = start_ocsp_responder(["user-pass"], [""]); + await check_cert_err("user-pass", PRErrorCodeSuccess); + await stopOCSPResponder(ocspResponder); +}); diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem new file mode 100644 index 0000000000..15a15922f2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC5jCCAc6gAwIBAgIUd7u/VsqA+jFMod09OYNM6n5mIjQwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBUxEzARBgNVBAMMCmJhZC1zY2hlbWUwggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HH +Jajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOr +IMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQ +sVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLA +dTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQE +LL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjMTAvMC0GCCsGAQUF +BwEBBCEwHzAdBggrBgEFBQcwAYYRL3d3dy5leGFtcGxlLmNvbS8wDQYJKoZIhvcN +AQELBQADggEBAKqR40rThjJ83dCqvxt2tqzfVWNsG8/j8Ylkh2PVe4duegymNbtx +lrGs7e+bR4s3HXwGdtCNqInFuFlZBK1j1LWZTd0o8o/p8VxXk3ZRyWFfaBM96mfM +EkbWSlmgraoS3OJXemV1mU8HpOnsN/P7jkTeAocf+UqXOuyg08f4qKlAwkkX4DIu +A6NHuFmPqDjj2uclq/e/xtL1Xah22kIkql00CmMqBdbtKYnYHd4k5wCWRkEiUzlc +Y8qBnTcamQiNYGgQUOHh/5J0mCrNDmh17A1rnJ4mjkAy4F+bDp2KFwzPtLJKhQeJ +jLclopcJHcmgn3hFbHMcgDwQxVl6UIZXOes= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem.certspec new file mode 100644 index 0000000000..12cc072792 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/bad-scheme.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:bad-scheme +extension:authorityInformationAccess:/www.example.com/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem new file mode 100644 index 0000000000..45de962523 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUVSmns5EZzUHKobrhxdpy/ZtJMucwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAwGA1UdEwQFMAMBAf8wCwYD +VR0PBAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IBAQATPLfx55bklmCWgjlOjZjD8EpY +fenI0HAkE0044+KmVlFSpsETog4OK0aZKYKwDysClM/ZipzBpmcZ4ZczM0TbtC7/ +d8nfUmT5R/sXBuMmeNIioAn6J5JaSctKQbsVta9GwIyJUBuYIvccL1c5wUuxV8xf +CaTrFgKWkDWkhOEY+TN/95l+Cm0Gwc3l+jom5UrPRyw9Cb5AhRiRc+x3HhgJ2hGe +kKo4K/AfH/jE7U0u4VM+VZTQf5K92aih3f54vPW+yFfMkgFgzHtwIrj1WStknR7u +yRjBCHfjuoOgQLm1svKtpgnMbRhucCkW+mifY+ZbE51vYMiRlK3sHj9hz3ol +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec new file mode 100644 index 0000000000..d809dbd635 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/ca.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:ca +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem new file mode 100644 index 0000000000..8fe9d26633 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8zCCAdugAwIBAgIUC7eHAf4GqnJKXvCpc9aTUTnkKgEwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBsxGTAXBgNVBAMMEGVtcHR5LXNjaGVtZS11cmwwggEiMA0GCSqGSIb3 +DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVo +V2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p +0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKk +fbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZh +W7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EI +TjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjODA2MDQG +CCsGAQUFBwEBBCgwJjAkBggrBgEFBQcwAYYYOi8vd3d3LmV4YW1wbGUuY29tOjg4 +ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCNWUubk4gbD3KqPPJW/vNw8LUHoQHjglk3 +6+RdbY/UCNfd6y3aGSrDLV8a/tVnV55UM9ADi4pd35Otu5i6fGunQcoL19QqFzDV +4dYC3WWGw+AqcF4pgqHBBBVtgDx+kZAS9NwwKCgaagPx7QOWJCDRgNxuol7q1UCI +vthWRt2PPIh4TCA5GDrFfrEYmVH6KgLKtHHr7TBrW0j3Cy6EIAsMMGXbj7z4DIxr +Lh0lP9sW87QJlU1cJF8VO1la9yDWvEQsETw5X5SYBdsG4y+AJ6dJI4872/fgAG7G +DP6nKhXuFvNbbpDTDKAwW2Xu4rVmPmUzv8G2+xis/u8jPhxv9zOS +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec new file mode 100644 index 0000000000..e8959653f3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/empty-scheme-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:empty-scheme-url +extension:authorityInformationAccess:://www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem new file mode 100644 index 0000000000..d582a2216a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7TCCAdWgAwIBAgIUPf/7zF8sBjFB4sd3ys4pW8gWQZAwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBIxEDAOBgNVBAMMB2Z0cC11cmwwggEiMA0GCSqGSIb3DQEBAQUAA4IB +DwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg +2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ +5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQ +PdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGj +DJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8W +iy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjOzA5MDcGCCsGAQUFBwEB +BCswKTAnBggrBgEFBQcwAYYbZnRwOi8vd3d3LmV4YW1wbGUuY29tOjg4ODgvMA0G +CSqGSIb3DQEBCwUAA4IBAQBoJzEDwSyDzVxFuPRiRs3kcxZBa9FKXJK472UKrwvc +w3xx8+TJPwMZorN/UMe+rxOBMORh1U3bx/nLqfyRB6VxGD2NO/JAUuaXsrEt5cD9 +RekCsFg/nZ4kjnFS8W0ImXGs5MaAEHKyVLaQFaCySpz3lSBd6laJOLpj1qkFIMuv +Z/AsflArUst/hZr+JbsPORu1TBOAWSUofKcfMEGs7WFZS5TwNOxFe0va1ejht7Bh +v1eohpaa5c9SA61Z5uD2vvT3+MiDDs7IAqb1m5hHWPVsgqxSbhzEdqwtR68NejLA +kCeintbVE3FgH/ZC5oT/DYo/9DqAD+CGlbIfORvK7rhJ +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem.certspec new file mode 100644 index 0000000000..9f50a7d792 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/ftp-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:ftp-url +extension:authorityInformationAccess:ftp://www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem new file mode 100644 index 0000000000..87efc65d28 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC9zCCAd+gAwIBAgIUFyY16h/GkLcgYETfxjsZRxt38JIwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBMxETAPBgNVBAMMCGhUVHAtdXJsMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo +4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDD +SeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFX +kD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUx +owyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/ +Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo0QwQjBABggrBgEFBQcB +AQQ0MDIwMAYIKwYBBQUHMAGGJGhUVHA6Ly93d3cuZXhhbXBsZS5jb206ODg4OC9o +VFRwLXVybDANBgkqhkiG9w0BAQsFAAOCAQEAg1XOX1zbHNpzMW9ivatvCMi9rMgQ +ZPFkuu6i4c5diLgo1VbzpM569nsfZnXkWGBv5hhGlFlJPRPc+q9joJMMsebnAlR+ +Q27kAqd/Q9kLQfA5x1Vail+7fin/cI5gR2XbmsXztbX7QYnE1lLSR1BWkJ99LNj4 +lfG5Ofu8CG0dBPfbO4+WtwNnije+J2O3iRc54EEv9kTBaieM34ejxPwg3WY/cUsw +h6UuRjOJf5Q/uhhRwzPZ4sphsdZcdzPhamIBSF2aCnUiFJlYLDV5eBLbr3GVAuFE +bJN5zNNCn2lzyo5dxbzuQO6VaGsZcI4/Y2gMn5Q9Gxym59qniVGLCmzTOg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem.certspec new file mode 100644 index 0000000000..10b1504b29 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/hTTp-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:hTTp-url +extension:authorityInformationAccess:hTTp://www.example.com:8888/hTTp-url diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem new file mode 100644 index 0000000000..16ce146d3c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+jCCAeKgAwIBAgIUL0PWDEnxL9Qrouxs08+j0g981AEwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBQxEjAQBgNVBAMMCWh0dHBzLXVybDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNGMEQwQgYIKwYBBQUH +AQEENjA0MDIGCCsGAQUFBzABhiZodHRwczovL3d3dy5leGFtcGxlLmNvbTo4ODg4 +L2h0dHBzLXVybDANBgkqhkiG9w0BAQsFAAOCAQEAXzQbnyFm4vlXOrCe9Pt42bt+ +6gg5UZieDPBYIiTBTfUY2e1EII4pxyRJJXjubbfajd+6bxRt38nd0/Ts56WljwiN +ZefieOoMVsRVrX6APHiMvkkZwmtqwOpAgxICpg/pRqEn2BAFIPB3Lrm5rfGHZhw2 +be+FJp4SbBHlnQUnG4oCl6yzR9hAcRssZL+6ewsWNet02aNJgDAVg00wLxNhCFAt +ZdtPq+E6l80/LYLYoVY6O+osC5eMR4Z48FoN8NQ8Yu/pe/t8Km/59NdyQxJFneXr +HXpcpdYsVOr4gzbNFO2552esXwx96tprehFtVc2ZxqnorfMayJz2uO/NVcrPxA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem.certspec new file mode 100644 index 0000000000..891005bf5c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/https-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:https-url +extension:authorityInformationAccess:https://www.example.com:8888/https-url diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/int.key b/security/manager/ssl/tests/unit/test_ocsp_url/int.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/int.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/int.key.keyspec b/security/manager/ssl/tests/unit/test_ocsp_url/int.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/int.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/int.pem b/security/manager/ssl/tests/unit/test_ocsp_url/int.pem new file mode 100644 index 0000000000..44e6a36efa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/int.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyjCCAbKgAwIBAgIUNbjVwdBjmiBHgijAyjyGIHuhJqQwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxOTExMjgwMDAwMDBaGA8yMDIyMDIwNTAw +MDAwMFowDjEMMAoGA1UEAwwDaW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB +CgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGc +BptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzC +a2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8Xg +uEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK +9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGP +mRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABox0wGzAMBgNVHRMEBTADAQH/MAsG +A1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAQEAO35vcl2OA9fAarEgTCrS42CL +5BeNfQLO7QCIdMZBfcIrQ6v5yw7i07pYGptagz/76OwYOsKO1lqb7sr2nTCNovVp +Co4dCAGQI460C6x3BOG7qyCFgZvf17xXl5filhMZw93LkWaeEIp8JmOTb511i1Bv +1akdFJ+xW40AuHE7EswLXzN0eu+tVAMJcsuxibK3jTkEdIjFCVwMD/7LC1rcoKcg +V18MHbh0zcDrXzo/jk8JfjqkOH5eylBtX2DH/9BjFcKzZDvZQFYlhsmADRHOmqvi +YoEXJj2A6fRzONsNKtQQbmVGvW/rHP7/YIiaAvn0kNb/FDtSqmTcLazSYpRewQ== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/int.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/int.pem.certspec new file mode 100644 index 0000000000..a7f6d81419 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/int.pem.certspec @@ -0,0 +1,4 @@ +issuer:ca +subject:int +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/moz.build b/security/manager/ssl/tests/unit/test_ocsp_url/moz.build new file mode 100644 index 0000000000..7863d3dff4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/moz.build @@ -0,0 +1,33 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'bad-scheme.pem', +# 'ca.pem', +# 'empty-scheme-url.pem', +# 'ftp-url.pem', +# 'hTTp-url.pem', +# 'https-url.pem', +# 'int.pem', +# 'negative-port.pem', +# 'no-host-url.pem', +# 'no-path-url.pem', +# 'no-scheme-host-port.pem', +# 'no-scheme-url.pem', +# 'unknown-scheme.pem', +# 'user-pass.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'int.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem new file mode 100644 index 0000000000..6827a1b6a7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8jCCAdqgAwIBAgIUe2K7ATAb5CY6+Kltt7J1qxX5Yn0wDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBgxFjAUBgNVBAMMDW5lZ2F0aXZlLXBvcnQwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjOjA4MDYGCCsG +AQUFBwEBBCowKDAmBggrBgEFBQcwAYYaaHR0cDovL3d3dy5leGFtcGxlLmNvbTot +MS8wDQYJKoZIhvcNAQELBQADggEBAJbJQ0Qp9K4dFRMu5te+e4MPi+zb9ZHa1nmE +wQLYKbmJ0/HSP7RjAnk2LqPi3Kej5aAqSWfd9x4pahEro9CEjVSrjD4y7iBTXbM8 +9jTyN01BJED2uHjVwOuaT6dVvx5I+QD7rAByxweQ0aoa14Rsf/odAszWmiburmar +3LuVBwfB3gyqBk8z6VdfqgUMjs+vi/DesvSZ5IvHwWGFok9uab8v5Ar8L0KoM5gT +1fAERsxk6W31SsDsSyd5si4dQo6tLJU6jVm2C+rEbt/iOU8CLHs/IozD0jXf1j9S +XeqFoTBvmJaUqpDdgjzXX/ZACz/s5YffRuDfrRqo7H7cBNaK1r0= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec new file mode 100644 index 0000000000..fce6d43848 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/negative-port.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:negative-port +extension:authorityInformationAccess:http://www.example.com:-1/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem new file mode 100644 index 0000000000..23b1b101e9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC4zCCAcugAwIBAgIUY6ACuApKijUD7p8u8yUDVv95Qr0wDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBYxFDASBgNVBAMMC25vLWhvc3QtdXJsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABoy0wKzApBggrBgEF +BQcBAQQdMBswGQYIKwYBBQUHMAGGDWh0dHA6Ly86ODg4OC8wDQYJKoZIhvcNAQEL +BQADggEBAKft+lbYDwaC4MkOViz/t9Zke8sOCkydLJ+gRhx7iaFjQ00VZOURHWrf +wbOKHaCe3WYofBMlmKARmCB5U8ohvnDqVuCnyt9hXKg3dhWLRGYZOxLEeToTddxc +OSyl736QFCT1GUtyzRE9fG7RZtSmTMrrhxDUkBf5wuwHboXEiN8pXEQY/L1wxze8 +lbGEBvUnQdTtMm2O9kz0Dg186BBw3Fi4yVcUU9COnvDRMfLt8Yt/MGbckfsdpRSn +qC80pJ3kFvJkzBF2MwkJVlZMBPFNexBovxAuVk48uyJLDyNp4J397h09JgvCl7Fl +FMhwIBglV3EvWERD9uq/7Hl1+zLD6GE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec new file mode 100644 index 0000000000..4ac76e7eb3 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-host-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-host-url +extension:authorityInformationAccess:http://:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem new file mode 100644 index 0000000000..76bd6d16dc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC8TCCAdmgAwIBAgIUE41GlTjHpx516QFRZ73bImTTVmwwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBYxFDASBgNVBAMMC25vLXBhdGgtdXJsMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozswOTA3BggrBgEF +BQcBAQQrMCkwJwYIKwYBBQUHMAGGG2h0dHA6Ly93d3cuZXhhbXBsZS5jb206ODg4 +ODANBgkqhkiG9w0BAQsFAAOCAQEARnXgGgNQHB4JClN93VLOVYzJoPkCtO70HjXc +nIuhAAwEISvIk9RWeDlE33x5T+g8SFaEOp/pqSZaa9FUr0y7PyxEwfF72JPQMff0 +L6dYtKiKS1+Uh5FNHC38ev4SJdOyGvD8k7og4+VVlitcDtQgVqiKxBoBCzl37wuK +s1aFx9a7FZcum3sdyFAQCwqpr9qWf9NBbiDdbZDTNyCg7zxk8olsr/DjQLKrAo40 +n2DPfYw+kAfXZgAi1XJjREe4BAaMJw9zCl7Ugsxl53YbUSl1CeicOH5yUiQ3vlCp +eW2QVjq/HRi6zUrSiOhgIzgVys4LivV3FgKIV/m4hgAGPHYLlw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec new file mode 100644 index 0000000000..497bb28796 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-path-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-path-url +extension:authorityInformationAccess:http://www.example.com:8888 diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem new file mode 100644 index 0000000000..035792b4af --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC3zCCAcegAwIBAgIUD/zYHQI03aXMAELGGvMX7vnOnyQwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMB4xHDAaBgNVBAMME25vLXNjaGVtZS1ob3N0LXBvcnQwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjITAf +MB0GCCsGAQUFBwEBBBEwDzANBggrBgEFBQcwAYYBLzANBgkqhkiG9w0BAQsFAAOC +AQEAddd/BUyk8OMHan7wrkL8m3euWJ7+UjxDP1yQL9Gehb34sHiSwr1pE3hfbmHU +Xc92MX9Fnm/M/uZRoMQqUqU0aqPr91rwwnf47+sd86yNvXxCgjAIN31W4wISDuqU +4j6dOYPyz0KGlD9qRJorJ4oxhnQfleTcvz3COrPrRypK4QuRJu3v7wR1qFvZP8Iq +loJ4cY8WwMMpaYecuZHrhfBpG8yO3wihc6IkXqWRWIzBia00v8DNSm+neEF5FTk5 +oCXNJAdh+qWwfzad5gUYGAlPaPdNxbO6G0SOfn7RRGSQj1Nb2Cl2RWzGAcGSGdfL +2h4H1w0XLwjStLtUM/8eQUvQrA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec new file mode 100644 index 0000000000..42a555e411 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-host-port.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-scheme-host-port +extension:authorityInformationAccess:/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem new file mode 100644 index 0000000000..ca639a4acb --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7TCCAdWgAwIBAgIUBziqKKOqXlKjkoU2XMzG67w9qZQwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBgxFjAUBgNVBAMMDW5vLXNjaGVtZS11cmwwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wk +e8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0Dgg +KZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmI +YXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7fi +lhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbL +HCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjNTAzMDEGCCsG +AQUFBwEBBCUwIzAhBggrBgEFBQcwAYYVd3d3LmV4YW1wbGUuY29tOjg4ODgvMA0G +CSqGSIb3DQEBCwUAA4IBAQB2TQq4V9zThvWdOYtaIGY/p3o6OHgtkU2n9RFVxImD +h+CObFyHbyDpbMMKghZOfdbI9Tl3QMk+d04TnMJRyiw/XhRJqoDY1fKv1N7AT3TM +Jmx3mR1wD1l9Zo/c4XOywljeypw++Z1DmtwP5TER0u4oLTklBzw9oTSR8snTyfSn +YA3gQL1jFVWwVKou1Gm4pZTavUdCpjJpF3Bp7QUKRFncTvYViVSibzVAIG+/PiY9 +K/EodGfokxgcKG2GUW6kUe2XadhJ8m2KSWtJrBKXnQ1pY8ZPbWHD/jfQsExRMGJL +wJx7HqA+8WNBPwqlqIbQejaieRIKOi++QIRuW4QPKA+6 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem.certspec new file mode 100644 index 0000000000..a82196a6d1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/no-scheme-url.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:no-scheme-url +extension:authorityInformationAccess:www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem new file mode 100644 index 0000000000..4717e6907a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7zCCAdegAwIBAgIUST8AviJzhAkMzTRIKaSHBtla3aEwDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBkxFzAVBgNVBAMMDnVua25vd24tc2NoZW1lMIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABozYwNDAyBggr +BgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFnR0cDovL3d3dy5leGFtcGxlLmNvbS8w +DQYJKoZIhvcNAQELBQADggEBALJakuxDp5Gpygxj3MY9tK33Dr/JrxN9NH0GmgcR +ruhT6DwStz7irOadxVUqNxxSIMf95QBHPEAWihXxn5qyrmH5Pz/M2H6H9xpWiK1r +fy5UTynUpcqZKVHHfER7tdw371XNdyPeGAfUKQwzO6LS4aBFhDssWxba0ZAt/iQU +Gqf0X9d73mfEvJZeiMJSqXReITRjTb+0f++0s95IfEhKs3YL9nbP/LHw9XxfmLU/ +2ZUvuAfOTq5U1XnoGIoqg2C8LtQxPXjvezAW/XQNcjQBwyYBxa64HFp5deWv7imf +QjF9yYYJOBz+BdyXCM+DZL+YJ/Ic6SpuEquVHewvegOpDDE= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec new file mode 100644 index 0000000000..0089455398 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/unknown-scheme.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:unknown-scheme +extension:authorityInformationAccess:ttp://www.example.com/ diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem b/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem new file mode 100644 index 0000000000..018f6d0614 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC+jCCAeKgAwIBAgIUc+MjmGMCD8xzGcHP2/uSyWK/9D4wDQYJKoZIhvcNAQEL +BQAwDjEMMAoGA1UEAwwDaW50MCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUw +MDAwMDBaMBQxEjAQBgNVBAMMCXVzZXItcGFzczCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNGMEQwQgYIKwYBBQUH +AQEENjA0MDIGCCsGAQUFBzABhiZodHRwOi8vdXNlcjpwYXNzQHd3dy5leGFtcGxl +LmNvbTo4ODg4LzANBgkqhkiG9w0BAQsFAAOCAQEAOZmeoErLJLw7l2J8terpOiFf +68YxI5/QZcRMZhVCMG71XjcZHj6mHLAgKi3Iw2iBeaUnfb5sfg5J7nOXUzebDoHD +j9W6h0tUxMyYDSdi8aXdvJ4WywPvYlJpWc33O+iDm3cLy224wF14eVD3rZcwroes +r/wf/86aszBY+xpkwHf/lD6KLNhmaAo0HKq8U4Ys6kJzLpvXMLcwnTs93lCE/VE3 +PYxzndXfRikAQ3j+e8KntIb99NeXMErjnq7vhrcjY7YPHTX60y8QC3fmX60qTAtV +YWYJusDKXiSDqo1wSHMgpgJ1EEptPsR/DdcCFLfg0PnAvYD8T7LI8jvJt8H8jw== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem.certspec b/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem.certspec new file mode 100644 index 0000000000..337e67e5f9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ocsp_url/user-pass.pem.certspec @@ -0,0 +1,3 @@ +issuer:int +subject:user-pass +extension:authorityInformationAccess:http://user:pass@www.example.com:8888/ diff --git a/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem new file mode 100644 index 0000000000..e963b71b90 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIBHzANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFUZXN0 +IEludGVybWVkaWF0ZTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAw +WjAwMS4wLAYDVQQDDCVBbm90aGVyIEVFIFJldm9rZWQgYnkgcmV2b2NhdGlvbnMu +dHh0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62 +iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql +WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosq +Qe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ +ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8i +b2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoY +CjXtjQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQCZh0XjjDVy1Ev/wSgS850t9KtD +YbFnqn3dCQjeECmXAH3BXAgb+hZwQEPvNcg1C7tzAowdZ+8h3+SbRLlEL50SkjXQ +euMrIOSBlJcOQTKYQrpTkbT68MhvFlLsM/BCjQ6lGRIKVGTGv4Q2k8NDF3+9N//Q +0QaTZ/3gZrmXSOGrbFUjiKrONMpQZhgVW8TMceJHnmOsxO5sQ4VPRVS3oYAbyoWU +JwWZYN/moFvQ/bE1ZceWhdyspzF3NVy0SP+eLQ/LznkZeQ+5ZVvNftwE8D3w+rYQ +t8ppnbaSPWQFgyL07OdFmhIpBWODrpjNQOq+ZmPkRBLKHiagw+c73gNbx5ui +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem.certspec new file mode 100644 index 0000000000..d3ba461104 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt-serial-2.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test Intermediate +subject:Another EE Revoked by revocations.txt +serialNumber:31 diff --git a/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem new file mode 100644 index 0000000000..7146aebe48 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIBTjANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFUZXN0 +IEludGVybWVkaWF0ZTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIwMjA1MDAwMDAw +WjAwMS4wLAYDVQQDDCVBbm90aGVyIEVFIFJldm9rZWQgYnkgcmV2b2NhdGlvbnMu +dHh0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62 +iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHql +WqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosq +Qe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ +ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8i +b2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoY +CjXtjQIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAGkBeSA8w5p5awb4t6gWXuXwpO ++N3LQcIAfdWcHuOXaYfWM6tuGRD7fumskMh1fp/7IcqxI0dvNd4iRuWm2IMypQN1 +rlYhkk6Z6N4Z2q8x+vlUl9cdFbXy8q3Iyo7dZflSkk/4vyWpIL6VBZEYs8wc+zJC +iEFFxjakhs8lNtFgJfcKDJGpb47q2burXP7D9rPkfYhNA8JnjSc2gXFd/wqP25ns +kmtUyjt/7kCKEtEsn2jLiIWOeASYMOzn10PVIrpX2hMphNw9DDljbIXbEbMat2p4 +GmN7xOLJgCFXZ1c1tGIxxbSsCjeHVjLY1j7D0ovOx5pn/+Fuga6FdWBdeTxC +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem.certspec new file mode 100644 index 0000000000..10f8f07cce --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/another-ee-revoked-by-revocations-txt.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test Intermediate +subject:Another EE Revoked by revocations.txt +serialNumber:78 diff --git a/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem new file mode 100644 index 0000000000..41d69f6b9a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICtzCCAZ+gAwIBAgIBKjANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdUZXN0 +IENBMCIYDzIwMTkxMTI4MDAwMDAwWhgPMjAyMjAyMDUwMDAwMDBaMCgxJjAkBgNV +BAMMHUVFIFJldm9rZWQgYnkgcmV2b2NhdGlvbnMudHh0MIIBIjANBgkqhkiG9w0B +AQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFds +JHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4 +ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25 +iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu3 +4pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42 +yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABMA0GCSqGSIb3 +DQEBCwUAA4IBAQCnVdUu30/kzE7JGkVtpRb/obsNkFySebWpr3gNfkHQJcwAXB+6 +jX6zluZW2e+2jdalTmJ7r1jfQnC76P/trz5GyWQGiM1ht50l1yZonTPtC1Qzkzfh +DPyqUr9PgeZZMdVPD8vaMqxYCqELRrCTxrUmC+vEjGKkBlvtY48ZBcEb/wrSm+4+ +j7vdHDpAxmg6dxZrWlvOBz7TOMwGWlF8loJD3bJYepV1w5N1LB5YR4rc6Peis3LA +EFHhbUFZlkbY7shChIh1S0PEiTSB5yFopC4iMkALBAJxfdPNKFUyzbVIZolpxA0m +Bk9uBCR3zv4lpm1JkUR/AOL8zXI7wrRvhh9F +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem.certspec new file mode 100644 index 0000000000..a2a67d909c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-revocations-txt.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test CA +subject:EE Revoked by revocations.txt +serialNumber:42 diff --git a/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem new file mode 100644 index 0000000000..3f6b4651ef --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIICzTCCAbWgAwIBAgIUZylsQT6JPUjiShyHn9bjtXVZ1BEwDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjArMSkwJwYDVQQDDCBFRSBSZXZva2VkIEJ5IFN1YmplY3QgYW5k +IFB1YktleTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbW +Qf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pk +cQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHT +AjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3 +ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jh +s3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHV +A6zaGAo17Y0CAwEAATANBgkqhkiG9w0BAQsFAAOCAQEAeMJzZMlfsHzM/gTj02WQ +scQ9rdvDSaPI52IWt0Dwu+Iv+nLCvn6Z2eL6E7DVp613u5y47GwtohTCvNoe9/Nt +SWKN5WlwaOLbRA5wmt5sbrB6w1z5qt+YDJuVvaw2OmLc7klBpF+ZXHufS7XIPg3e +xWyqnnJ7ewlYF7fMe8q6WhHlzZ5BYuhNXntpf3dvAA9xMxGYr5CQcXSDF9CqdaAF +n2P6ZgI7K7CpWzOqLinc+kTyJ8WmcW6WiHIN2ce2XFL49oRFXasjpJtGHmIr5ns4 +yGkHw9WKKzmMG5kgLy5Ar3PSdqAD51l4IGLPIzquhnlo/oTe/Lwi5fZIiHWOmr/z +1Q== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem.certspec new file mode 100644 index 0000000000..cadbcf9038 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/ee-revoked-by-subject-and-pubkey.pem.certspec @@ -0,0 +1,2 @@ +issuer:Test CA +subject:EE Revoked By Subject and PubKey diff --git a/security/manager/ssl/tests/unit/test_onecrl/moz.build b/security/manager/ssl/tests/unit/test_onecrl/moz.build new file mode 100644 index 0000000000..f01134991b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/moz.build @@ -0,0 +1,18 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'another-ee-revoked-by-revocations-txt-serial-2.pem', +# 'another-ee-revoked-by-revocations-txt.pem', +# 'ee-revoked-by-revocations-txt.pem', +# 'ee-revoked-by-subject-and-pubkey.pem', +# 'same-issuer-ee.pem', +# 'test-int-ee.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem b/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem new file mode 100644 index 0000000000..d48771c638 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDITCCAgmgAwIBAgIUB8T8WSJXA+AFg+rEJQ6d49gVhG4wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAiMSAwHgYDVQQDDBdBbm90aGVyIFRlc3QgRW5kLWVudGl0eTCC +ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9 +PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3 +HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3Dg +Dw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7 +EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SK +lWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0C +AwEAAaNbMFkwIwYDVR0RBBwwGoIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tMDIG +CCsGAQUFBwEBBCYwJDAiBggrBgEFBQcwAYYWaHR0cDovL2xvY2FsaG9zdDo4ODg4 +LzANBgkqhkiG9w0BAQsFAAOCAQEAXEPHIKtQkyoGnJ0TjHvybmECV9OKdmQg34JL +EZ276YtRZBfcPIlt6v0dTzYy8kS68OTjQ2wAa+jVyJRg24x7Jln0R2XVgyGX7FKJ +646dlYC5sqXPx1N7bh2Zh9aU6erBBbQZbBC3KGYT6pFxHcddmSFIlkxLREj10lr1 +CTVE7Xq5pel4jE9YS4Su/n0zVmMCLdEh2mOml+L0N2oxFchczJVcogi9iGVSElPx +PaQBsAtRW7Kl/yCEsENNXqYm/B+QaJd6c+MxYTd+DuKx3TZiT3Pk4xDGExdW+yUv +BvVaHBtavJYAw+IDzz6MxuUIiJ/wpUXP/CnsK8eD3ADyabxkFA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem.certspec new file mode 100644 index 0000000000..8b20f03f59 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/same-issuer-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Another Test End-entity +extension:subjectAlternativeName:localhost,*.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/test_onecrl/sample_revocations.txt b/security/manager/ssl/tests/unit/test_onecrl/sample_revocations.txt new file mode 100644 index 0000000000..8983eb65c7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/sample_revocations.txt @@ -0,0 +1,41 @@ +# a sample revocations.txt for tests +# Lines starting with '#' are ignored - as are empty lines like this: + +# otherwise: +# non-empty lines are treated as base-64 encoded DER DN data (e.g. issuer or +# subject) +# ...unless the line starts with a ' ' (space) character, in which case it's +# assumed to be base-64 encoded DER serial data, or +# the line starts with a '\t' (tab) character, in which case it's assumed to +# be a base-64 encoded SHA256 hash of a public key + +# First a serial with no issuer to ensure this doesn't cause parsing to fail +# (there should be an issuer first, but we need to test this won't fail) + dGVzdA== +# next, let's ensure data that isn't valid base64 doesn't cause breakage. + this serial isn't valid base64 (but then there's no issuer anyway) +Neither is this issuer, though the serial is fine + dGVzdA== +dGVzdA== + in this case, issuer is fine but not the serial +# Next two entries; we can add valid base-64 encoded data for some basic tests: +# issuer is the base-64 encoded subject DN for the shared Test CA +# serial is the base-64 encoded integer 42 +MBIxEDAOBgNVBAMMB1Rlc3QgQ0E= + Kg== +# issuer is the base-64 encoded subject DN for the shared Test Intermediate +# the first serial is the base-64 encoded integer 78 +# the second serial is the base-64 encoded integer 31 +MBwxGjAYBgNVBAMMEVRlc3QgSW50ZXJtZWRpYXRl + Tg== + Hw== + c2VyaWFsMi4= +# subject is base-64 encoded subject DN "CN=EE Revoked By Subject and PubKey" +# pubKeyHash is the base-64 encoded sha256 hash of the shared RSA SPKI +MCsxKTAnBgNVBAMMIEVFIFJldm9rZWQgQnkgU3ViamVjdCBhbmQgUHViS2V5 + VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8 +# and some more data to ensure that mixed items don't cause parsing failure +a DN + a serial + a hash + another serial diff --git a/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem b/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem new file mode 100644 index 0000000000..b7e0246486 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC6jCCAdKgAwIBAgIUE/Ee/Yl0qsBfU62Pa29Gu17/HNMwDQYJKoZIhvcNAQEL +BQAwHDEaMBgGA1UEAwwRVGVzdCBJbnRlcm1lZGlhdGUwIhgPMjAxOTExMjgwMDAw +MDBaGA8yMDIyMDIwNTAwMDAwMFowJDEiMCAGA1UEAwwZRUUgaXNzdWVkIGJ5IGlu +dGVybWVkaWF0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqIUahE +jhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvir1p1 +a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/xfq1p +GrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD7ycW +2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnvuRcO +p2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJR +xDHVA6zaGAo17Y0CAwEAAaMYMBYwFAYDVR0RBA0wC4IJbG9jYWxob3N0MA0GCSqG +SIb3DQEBCwUAA4IBAQAnJwAGpGTVIkzj1a9MyPYLMgy+36xRzYe6WmIgsFPV/51u +AZZqcxlI+haWQQf13erUoM2HnvQXw+h4cwWTqZ59NqrWeZWFtHiVFCQVip+/1+dX +IUmOJjgAOsKUtgg/plvp6mtaT/4ko8mA8dmhdOhASYpEocT4veDpovAQD00B2YCx +2qxRypDTSd4oM1RFf7KsKglFOPmi5lOjfvSGprIMbj6JgoplYk+vAZC53mK5UgF+ +qCnXGJr3dEpGy7uJHX69hBtZWom84a62YqTeUMRsMDcz15XS5L6Gdrc4YW0NHRci +lId9qfDpC7jhL1mWAPEBHOtKxsrCPjkToPND9WVz +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem.certspec b/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem.certspec new file mode 100644 index 0000000000..24792d540a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_onecrl/test-int-ee.pem.certspec @@ -0,0 +1,3 @@ +issuer:Test Intermediate +subject:EE issued by intermediate +extension:subjectAlternativeName:localhost diff --git a/security/manager/ssl/tests/unit/test_osclientcerts_module.js b/security/manager/ssl/tests/unit/test_osclientcerts_module.js new file mode 100644 index 0000000000..8ac31b648a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_osclientcerts_module.js @@ -0,0 +1,63 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that the platform can load the osclientcerts module. + +// Ensure that the appropriate initialization has happened. +Services.prefs.setBoolPref("security.osclientcerts.autoload", false); +do_get_profile(); + +const { TestUtils } = ChromeUtils.import( + "resource://testing-common/TestUtils.jsm" +); + +async function check_osclientcerts_module_loaded() { + // Loading happens asynchronously, so we have to wait for the notification. + await TestUtils.topicObserved("psm:load-os-client-certs-module-task-ran"); + let testModule = checkPKCS11ModuleExists( + "OS Client Cert Module", + "osclientcerts" + ); + + // Check that listing the slots for the osclientcerts module works. + let testModuleSlotNames = Array.from( + testModule.listSlots(), + slot => slot.name + ); + testModuleSlotNames.sort(); + const expectedSlotNames = [ + "OS Client Cert Slot (Legacy)", + "OS Client Cert Slot (Modern)", + ]; + deepEqual( + testModuleSlotNames, + expectedSlotNames, + "Actual and expected slot names should be equal" + ); +} + +add_task(async function run_test() { + // Check that if we haven't loaded the osclientcerts module, we don't find it + // in the module list. + checkPKCS11ModuleNotPresent("OS Client Cert Module", "osclientcerts"); + + // Check that enabling the pref that loads the osclientcerts module makes it + // appear in the module list. + Services.prefs.setBoolPref("security.osclientcerts.autoload", true); + await check_osclientcerts_module_loaded(); + + // Check that disabling the pref that loads the osclientcerts module (thus + // unloading the module) makes it disappear from the module list. + Services.prefs.setBoolPref("security.osclientcerts.autoload", false); + checkPKCS11ModuleNotPresent("OS Client Cert Module", "osclientcerts"); + + // Check that loading the module again succeeds. + Services.prefs.setBoolPref("security.osclientcerts.autoload", true); + await check_osclientcerts_module_loaded(); + + // And once more check that unloading succeeds. + Services.prefs.setBoolPref("security.osclientcerts.autoload", false); + checkPKCS11ModuleNotPresent("OS Client Cert Module", "osclientcerts"); +}); diff --git a/security/manager/ssl/tests/unit/test_oskeystore.js b/security/manager/ssl/tests/unit/test_oskeystore.js new file mode 100644 index 0000000000..5333cb27ea --- /dev/null +++ b/security/manager/ssl/tests/unit/test_oskeystore.js @@ -0,0 +1,413 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the methods and attributes for interfacing with nsIOSKeyStore. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +const LABELS = ["mylabel1", "mylabel2", "mylabel3"]; + +async function delete_all_secrets() { + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + for (let label of LABELS) { + if (await keystore.asyncSecretAvailable(label)) { + await keystore.asyncDeleteSecret(label); + ok( + !(await keystore.asyncSecretAvailable(label)), + label + " should be deleted now." + ); + } + } +} + +// Test that Firefox handles locking and unlocking of the OSKeyStore properly. +// Does so by mocking out the actual dialog and "filling in" the +// password. Also tests that providing an incorrect password will fail (well, +// technically the user will just get prompted again, but if they then cancel +// the dialog the overall operation will fail). + +var gMockPrompter = { + passwordToTry: null, + numPrompts: 0, + + // This intentionally does not use arrow function syntax to avoid an issue + // where in the context of the arrow function, |this != gMockPrompter| due to + // how objects get wrapped when going across xpcom boundaries. + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + this.numPrompts++; + equal( + text, + "Please enter your Primary Password.", + "password prompt text should be as expected" + ); + equal(checkMsg, null, "checkMsg should be null"); + ok(this.passwordToTry, "passwordToTry should be non-null"); + if (this.passwordToTry == "DontTryThisPassword") { + // Cancel the prompt in this case. + return false; + } + password.value = this.passwordToTry; + return true; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), +}; + +// Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt +// to call promptPassword. We return the mock one, above. +var gWindowWatcher = { + getNewPrompter: () => gMockPrompter, + QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]), +}; + +async function encrypt_decrypt_test() { + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + ok( + !(await keystore.asyncSecretAvailable(LABELS[0])), + "The secret should not be available yet." + ); + + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(recoveryPhrase, "A recovery phrase should've been created."); + let recoveryPhrase2 = await keystore.asyncGenerateSecret(LABELS[1]); + ok(recoveryPhrase2, "A recovery phrase should've been created."); + + let text = new Uint8Array([0x01, 0x00, 0x01]); + let ciphertext = ""; + try { + ciphertext = await keystore.asyncEncryptBytes(LABELS[0], text); + ok(ciphertext, "We should have a ciphertext now."); + } catch (e) { + ok(false, "Error encrypting " + e); + } + + // Decrypting should give us the plaintext bytes again. + try { + let plaintext = await keystore.asyncDecryptBytes(LABELS[0], ciphertext); + ok( + plaintext.toString() == text.toString(), + "Decrypted plaintext should be the same as text." + ); + } catch (e) { + ok(false, "Error decrypting ciphertext " + e); + } + + // Decrypting with a wrong key should throw an error. + try { + await keystore.asyncDecryptBytes(LABELS[1], ciphertext); + ok(false, "Decrypting with the wrong key should fail."); + } catch (e) { + ok(true, "Decrypting with the wrong key should fail " + e); + } +} + +add_task(async function() { + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + let windowWatcherCID; + if (keystore.isNSSKeyStore) { + windowWatcherCID = MockRegistrar.register( + "@mozilla.org/embedcomp/window-watcher;1", + gWindowWatcher + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(windowWatcherCID); + }); + } + + await delete_all_secrets(); + await encrypt_decrypt_test(); + await delete_all_secrets(); + + if ( + AppConstants.platform == "macosx" || + AppConstants.platform == "win" || + AppConstants.platform == "linux" + ) { + ok( + !keystore.isNSSKeyStore, + "OS X, Windows, and Linux should use the non-NSS implementation" + ); + } + + if (keystore.isNSSKeyStore) { + // If we use the NSS key store implementation test that everything works + // when a master password is set. + // Set an initial password. + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + let token = tokenDB.getInternalKeyToken(); + token.initPassword("hunter2"); + + // Lock the key store. This should be equivalent to token.logoutSimple() + await keystore.asyncLock(); + + // Set the correct password so that the test operations should succeed. + gMockPrompter.passwordToTry = "hunter2"; + await encrypt_decrypt_test(); + ok( + gMockPrompter.numPrompts == 1, + "There should've been one password prompt." + ); + await delete_all_secrets(); + } + + // Check lock/unlock behaviour. + // Unfortunately we can only test this automatically for the NSS key store. + // Uncomment the outer keystore.isNSSKeyStore to test other key stores manually. + if (keystore.isNSSKeyStore) { + await delete_all_secrets(); + await encrypt_decrypt_test(); + await keystore.asyncLock(); + info("Keystore should be locked. Cancel the login request."); + try { + if (keystore.isNSSKeyStore) { + gMockPrompter.passwordToTry = "DontTryThisPassword"; + } + await keystore.asyncUnlock(); + ok(false, "Unlock should've rejected."); + } catch (e) { + ok( + e.result == Cr.NS_ERROR_FAILURE || e.result == Cr.NS_ERROR_ABORT, + "Rejected login prompt." + ); + } + // clean up + if (keystore.isNSSKeyStore) { + gMockPrompter.passwordToTry = "hunter2"; + } + await delete_all_secrets(); + } +}); + +// Test that if we kick off a background operation and then call a synchronous function on the +// keystore, we don't deadlock. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(recoveryPhrase, "A recovery phrase should've been created."); + + try { + let text = new Uint8Array(8192); + let promise = keystore.asyncEncryptBytes(LABELS[0], text); + /* eslint-disable no-unused-expressions */ + keystore.isNSSKeyStore; // we don't care what this is - we just need to access it + /* eslint-enable no-unused-expressions */ + let ciphertext = await promise; + ok(ciphertext, "We should have a ciphertext now."); + } catch (e) { + ok(false, "Error encrypting " + e); + } + + await delete_all_secrets(); +}); + +// Test that using a recovery phrase works. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(recoveryPhrase, "A recovery phrase should've been created."); + + let text = new Uint8Array([0x01, 0x00, 0x01]); + let ciphertext = await keystore.asyncEncryptBytes(LABELS[0], text); + ok(ciphertext, "We should have a ciphertext now."); + + await keystore.asyncDeleteSecret(LABELS[0]); + // Decrypting should fail after deleting the secret. + await keystore + .asyncDecryptBytes(LABELS[0], ciphertext) + .then(() => + ok(false, "decrypting didn't throw as expected after deleting the secret") + ) + .catch(() => + ok(true, "decrypting threw as expected after deleting the secret") + ); + + await keystore.asyncRecoverSecret(LABELS[0], recoveryPhrase); + let plaintext = await keystore.asyncDecryptBytes(LABELS[0], ciphertext); + ok( + plaintext.toString() == text.toString(), + "Decrypted plaintext should be the same as text." + ); + + await delete_all_secrets(); +}); + +// Test that trying to use a non-base64 recovery phrase fails. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + await keystore + .asyncRecoverSecret(LABELS[0], "@##$^&*()#$^&*(@#%&*_") + .then(() => + ok(false, "base64-decoding non-base64 should have failed but didn't") + ) + .catch(() => ok(true, "base64-decoding non-base64 failed as expected")); + + ok( + !(await keystore.asyncSecretAvailable(LABELS[0])), + "we didn't recover a secret, so the secret shouldn't be available" + ); + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok( + recoveryPhrase && recoveryPhrase.length > 0, + "we should be able to re-use that label to generate a new secret" + ); + await delete_all_secrets(); +}); + +// Test that re-using a label overwrites any previously-stored secret. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(recoveryPhrase, "A recovery phrase should've been created."); + + let text = new Uint8Array([0x66, 0x6f, 0x6f, 0x66]); + let ciphertext = await keystore.asyncEncryptBytes(LABELS[0], text); + ok(ciphertext, "We should have a ciphertext now."); + + let newRecoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(newRecoveryPhrase, "A new recovery phrase should've been created."); + + // The new secret replaced the old one so we shouldn't be able to decrypt the ciphertext now. + await keystore + .asyncDecryptBytes(LABELS[0], ciphertext) + .then(() => + ok(false, "decrypting without the original key should have failed") + ) + .catch(() => + ok(true, "decrypting without the original key failed as expected") + ); + + await keystore.asyncRecoverSecret(LABELS[0], recoveryPhrase); + let plaintext = await keystore.asyncDecryptBytes(LABELS[0], ciphertext); + ok( + plaintext.toString() == text.toString(), + "Decrypted plaintext should be the same as text (once we have the original key again)." + ); + + await delete_all_secrets(); +}); + +// Test that re-using a label (this time using a recovery phrase) overwrites any previously-stored +// secret. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(recoveryPhrase, "A recovery phrase should've been created."); + + let newRecoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok(newRecoveryPhrase, "A new recovery phrase should've been created."); + + let text = new Uint8Array([0x66, 0x6f, 0x6f, 0x66]); + let ciphertext = await keystore.asyncEncryptBytes(LABELS[0], text); + ok(ciphertext, "We should have a ciphertext now."); + + await keystore.asyncRecoverSecret(LABELS[0], recoveryPhrase); + + // We recovered the old secret, so decrypting ciphertext that had been encrypted with the newer + // key should fail. + await keystore + .asyncDecryptBytes(LABELS[0], ciphertext) + .then(() => ok(false, "decrypting without the new key should have failed")) + .catch(() => ok(true, "decrypting without the new key failed as expected")); + + await keystore.asyncRecoverSecret(LABELS[0], newRecoveryPhrase); + let plaintext = await keystore.asyncDecryptBytes(LABELS[0], ciphertext); + ok( + plaintext.toString() == text.toString(), + "Decrypted plaintext should be the same as text (once we have the new key again)." + ); + + await delete_all_secrets(); +}); + +// Test that trying to use recovery phrases that are the wrong size fails. +add_task(async function() { + await delete_all_secrets(); + + let keystore = Cc["@mozilla.org/security/oskeystore;1"].getService( + Ci.nsIOSKeyStore + ); + + await keystore + .asyncRecoverSecret(LABELS[0], "") + .then(() => ok(false, "'recovering' with an empty key should have failed")) + .catch(() => ok(true, "'recovering' with an empty key failed as expected")); + ok( + !(await keystore.asyncSecretAvailable(LABELS[0])), + "we didn't recover a secret, so the secret shouldn't be available" + ); + + await keystore + .asyncRecoverSecret(LABELS[0], "AAAAAA") + .then(() => + ok(false, "recovering with a key that is too short should have failed") + ) + .catch(() => + ok(true, "recovering with a key that is too short failed as expected") + ); + ok( + !(await keystore.asyncSecretAvailable(LABELS[0])), + "we didn't recover a secret, so the secret shouldn't be available" + ); + + await keystore + .asyncRecoverSecret( + LABELS[0], + "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + ) + .then(() => + ok(false, "recovering with a key that is too long should have failed") + ) + .catch(() => + ok(true, "recovering with a key that is too long failed as expected") + ); + ok( + !(await keystore.asyncSecretAvailable(LABELS[0])), + "we didn't recover a secret, so the secret shouldn't be available" + ); + + let recoveryPhrase = await keystore.asyncGenerateSecret(LABELS[0]); + ok( + recoveryPhrase && recoveryPhrase.length > 0, + "we should be able to use that label to generate a new secret" + ); + ok( + await keystore.asyncSecretAvailable(LABELS[0]), + "the generated secret should now be available" + ); + + await delete_all_secrets(); +}); diff --git a/security/manager/ssl/tests/unit/test_osreauthenticator.js b/security/manager/ssl/tests/unit/test_osreauthenticator.js new file mode 100644 index 0000000000..01784a5fef --- /dev/null +++ b/security/manager/ssl/tests/unit/test_osreauthenticator.js @@ -0,0 +1,27 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests nsIOSReauthenticator.asyncReauthenticateUser(). +// As this gets implemented on various platforms, running this test +// will result in a prompt from the OS. Consequently, we won't be able +// to run this in automation, but it will help in testing locally. +add_task(async function test_asyncReauthenticateUser() { + const reauthenticator = Cc[ + "@mozilla.org/security/osreauthenticator;1" + ].getService(Ci.nsIOSReauthenticator); + ok(reauthenticator, "nsIOSReauthenticator should be available"); + const EXPECTED = false; // Change this variable to suit your needs while testing. + ok( + ( + await reauthenticator.asyncReauthenticateUser( + "this is the prompt string", + "this is the caption string", + null + ) + )[0] == EXPECTED, + "nsIOSReauthenticator.asyncReauthenticateUser should return a boolean array with the first item being the authentication result of: " + + EXPECTED + ); +}); diff --git a/security/manager/ssl/tests/unit/test_password_prompt.js b/security/manager/ssl/tests/unit/test_password_prompt.js new file mode 100644 index 0000000000..cf4c6db7bf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_password_prompt.js @@ -0,0 +1,87 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that PSM can successfully ask for a password from the user and relay it +// back to NSS. Does so by mocking out the actual dialog and "filling in" the +// password. Also tests that providing an incorrect password will fail (well, +// technically the user will just get prompted again, but if they then cancel +// the dialog the overall operation will fail). + +var gMockPrompter = { + passwordToTry: null, + numPrompts: 0, + + // This intentionally does not use arrow function syntax to avoid an issue + // where in the context of the arrow function, |this != gMockPrompter| due to + // how objects get wrapped when going across xpcom boundaries. + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + this.numPrompts++; + if (this.numPrompts > 1) { + // don't keep retrying a bad password + return false; + } + equal( + text, + "Please enter your Primary Password.", + "password prompt text should be as expected" + ); + equal(checkMsg, null, "checkMsg should be null"); + ok(this.passwordToTry, "passwordToTry should be non-null"); + password.value = this.passwordToTry; + return true; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), +}; + +// Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt +// to call promptPassword. We return the mock one, above. +var gWindowWatcher = { + getNewPrompter: () => gMockPrompter, + QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]), +}; + +function run_test() { + do_get_profile(); + + let windowWatcherCID = MockRegistrar.register( + "@mozilla.org/embedcomp/window-watcher;1", + gWindowWatcher + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(windowWatcherCID); + }); + + // Set an initial password. + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + let token = tokenDB.getInternalKeyToken(); + token.initPassword("hunter2"); + token.logoutSimple(); + + // Try with the correct password. + gMockPrompter.passwordToTry = "hunter2"; + // Using nsISecretDecoderRing will cause the password prompt to come up if the + // token has a password and is logged out. + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + sdr.encryptString("poke"); + equal(gMockPrompter.numPrompts, 1, "should have prompted for password once"); + + // Reset state. + gMockPrompter.numPrompts = 0; + token.logoutSimple(); + + // Try with an incorrect password. + gMockPrompter.passwordToTry = "*******"; + throws( + () => sdr.encryptString("poke2"), + /NS_ERROR_FAILURE/, + "logging in with the wrong password should fail" + ); + equal(gMockPrompter.numPrompts, 2, "should have prompted for password twice"); +} diff --git a/security/manager/ssl/tests/unit/test_pinning.js b/security/manager/ssl/tests/unit/test_pinning.js new file mode 100644 index 0000000000..89539ac2bf --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pinning.js @@ -0,0 +1,319 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +// +// For all cases, the acceptable pinset includes only certificates pinned to +// Test End Entity Cert (signed by issuer testCA). Other certificates +// are issued by otherCA, which is never in the pinset but is a user-specified +// trust anchor. This test covers multiple cases: +// +// Pinned domain include-subdomains.pinning.example.com includes subdomains +// - PASS: include-subdomains.pinning.example.com serves a correct cert +// - PASS: good.include-subdomains.pinning.example.com serves a correct cert +// - FAIL (strict): bad.include-subdomains.pinning.example.com serves a cert +// not in the pinset +// - PASS (mitm): bad.include-subdomains.pinning.example.com serves a cert not +// in the pinset, but issued by a user-specified trust domain +// +// Pinned domain exclude-subdomains.pinning.example.com excludes subdomains +// - PASS: exclude-subdomains.pinning.example.com serves a correct cert +// - FAIL: exclude-subdomains.pinning.example.com serves an incorrect cert +// (TODO: test using verifyCertNow) +// - PASS: sub.exclude-subdomains.pinning.example.com serves an incorrect cert + +"use strict"; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function add_clear_override(host) { + add_test(function() { + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride(host, 8443); + run_next_test(); + }); +} + +function test_strict() { + // In strict mode, we always evaluate pinning data, regardless of whether the + // issuer is a built-in trust anchor. We only enforce pins that are not in + // test mode. + add_test(function() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2); + run_next_test(); + }); + + // Normally this is overridable. But, since we have pinning information for + // this host, we don't allow overrides. + add_prevented_cert_override_test( + "unknownissuer.include-subdomains.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.include-subdomains.pinning.example.com"); + + // Issued by otherCA, which is not in the pinset for pinning.example.com. + add_connection_test( + "bad.include-subdomains.pinning.example.com", + MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE + ); + + // Check that using a FQDN doesn't bypass pinning. + add_connection_test( + "bad.include-subdomains.pinning.example.com.", + MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE + ); + // For some reason this is also navigable (see bug 1118522). + add_connection_test( + "bad.include-subdomains.pinning.example.com..", + MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE + ); + + // These domains serve certs that match the pinset. + add_connection_test( + "include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + // This domain serves a cert that doesn't match the pinset, but subdomains + // are excluded. + add_connection_test( + "sub.exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + // This domain's pinset is exactly the same as + // include-subdomains.pinning.example.com, serves the same cert as + // bad.include-subdomains.pinning.example.com, but it should pass because + // it's in test_mode. + add_connection_test("test-mode.pinning.example.com", PRErrorCodeSuccess); + // Similarly, this pin is in test-mode, so it should be overridable. + add_cert_override_test( + "unknownissuer.test-mode.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.test-mode.pinning.example.com"); +} + +function test_mitm() { + // In MITM mode, we allow pinning to pass if the chain resolves to any + // user-specified trust anchor, even if it is not in the pinset. + add_test(function() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 1); + run_next_test(); + }); + + add_connection_test( + "include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + // Normally this is overridable. But, since we have pinning information for + // this host, we don't allow overrides (since building a trusted chain fails, + // we have no reason to believe this was issued by a user-added trust + // anchor, so we can't allow overrides for it). + add_prevented_cert_override_test( + "unknownissuer.include-subdomains.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.include-subdomains.pinning.example.com"); + + // In this case, even though otherCA is not in the pinset, it is a + // user-specified trust anchor and the pinning check succeeds. + add_connection_test( + "bad.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + add_connection_test( + "exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "sub.exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test("test-mode.pinning.example.com", PRErrorCodeSuccess); + add_cert_override_test( + "unknownissuer.test-mode.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.test-mode.pinning.example.com"); +} + +function test_disabled() { + // Disable pinning. + add_test(function() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 0); + run_next_test(); + }); + + add_connection_test( + "include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "bad.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "sub.exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test("test-mode.pinning.example.com", PRErrorCodeSuccess); + + add_cert_override_test( + "unknownissuer.include-subdomains.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.include-subdomains.pinning.example.com"); + add_cert_override_test( + "unknownissuer.test-mode.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.test-mode.pinning.example.com"); +} + +function test_enforce_test_mode() { + // In enforce test mode, we always enforce all pins, even test pins. + add_test(function() { + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 3); + run_next_test(); + }); + + // Normally this is overridable. But, since we have pinning information for + // this host, we don't allow overrides. + add_prevented_cert_override_test( + "unknownissuer.include-subdomains.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.include-subdomains.pinning.example.com"); + + // Issued by otherCA, which is not in the pinset for pinning.example.com. + add_connection_test( + "bad.include-subdomains.pinning.example.com", + MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE + ); + + // These domains serve certs that match the pinset. + add_connection_test( + "include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + add_connection_test( + "exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + // This domain serves a cert that doesn't match the pinset, but subdomains + // are excluded. + add_connection_test( + "sub.exclude-subdomains.pinning.example.com", + PRErrorCodeSuccess + ); + + // This domain's pinset is exactly the same as + // include-subdomains.pinning.example.com, serves the same cert as + // bad.include-subdomains.pinning.example.com, is in test-mode, but we are + // enforcing test mode pins. + add_connection_test( + "test-mode.pinning.example.com", + MOZILLA_PKIX_ERROR_KEY_PINNING_FAILURE + ); + // Normally this is overridable. But, since we have pinning information for + // this host (and since we're enforcing test mode), we don't allow overrides. + add_prevented_cert_override_test( + "unknownissuer.test-mode.pinning.example.com", + Ci.nsICertOverrideService.ERROR_UNTRUSTED, + SEC_ERROR_UNKNOWN_ISSUER + ); + add_clear_override("unknownissuer.test-mode.pinning.example.com"); +} + +function check_pinning_telemetry() { + let prod_histogram = Services.telemetry + .getHistogramById("CERT_PINNING_RESULTS") + .snapshot(); + let test_histogram = Services.telemetry + .getHistogramById("CERT_PINNING_TEST_RESULTS") + .snapshot(); + // Because all of our test domains are pinned to user-specified trust + // anchors, effectively only strict mode and enforce test-mode get evaluated + equal( + prod_histogram.values[0], + 4, + "Actual and expected prod (non-Mozilla) failure count should match" + ); + equal( + prod_histogram.values[1], + 6, + "Actual and expected prod (non-Mozilla) success count should match" + ); + equal( + test_histogram.values[0], + 2, + "Actual and expected test (non-Mozilla) failure count should match" + ); + equal( + test_histogram.values[1] || 0, + 0, + "Actual and expected test (non-Mozilla) success count should match" + ); + + run_next_test(); +} + +function run_test() { + // Ensure that static pinning works when HPKP is disabled. + Services.prefs.setBoolPref("security.cert_pinning.hpkp.enabled", false); + + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + // Add a user-specified trust anchor. + addCertFromFile(certdb, "bad_certs/other-test-ca.pem", "CTu,u,u"); + + test_strict(); + test_mitm(); + test_disabled(); + test_enforce_test_mode(); + + add_test(function() { + check_pinning_telemetry(); + }); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_module.js b/security/manager/ssl/tests/unit/test_pkcs11_module.js new file mode 100644 index 0000000000..abad2dbb54 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_module.js @@ -0,0 +1,58 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the methods and attributes for interfacing with a PKCS #11 module and +// the module database. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +const gModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB +); + +function run_test() { + // Check that if we have never added the test module, that we don't find it + // in the module list. + checkPKCS11ModuleNotPresent("PKCS11 Test Module", "pkcs11testmodule"); + + // Check that adding the test module makes it appear in the module list. + let libraryFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + libraryFile.append("pkcs11testmodule"); + libraryFile.append(ctypes.libraryName("pkcs11testmodule")); + loadPKCS11Module(libraryFile, "PKCS11 Test Module", true); + let testModule = checkPKCS11ModuleExists( + "PKCS11 Test Module", + "pkcs11testmodule" + ); + + // Check that listing the slots for the test module works. + let testModuleSlotNames = Array.from( + testModule.listSlots(), + slot => slot.name + ); + testModuleSlotNames.sort(); + const expectedSlotNames = [ + "Empty PKCS11 Slot", + "Test PKCS11 Slot", + "Test PKCS11 Slot 二", + ]; + deepEqual( + testModuleSlotNames, + expectedSlotNames, + "Actual and expected slot names should be equal" + ); + + // Check that deleting the test module makes it disappear from the module list. + let pkcs11ModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + pkcs11ModuleDB.deleteModule("PKCS11 Test Module"); + checkPKCS11ModuleNotPresent("PKCS11 Test Module", "pkcs11testmodule"); + + // Check miscellaneous module DB methods and attributes. + ok(!gModuleDB.canToggleFIPS, "It should NOT be possible to toggle FIPS"); + ok(!gModuleDB.isFIPSEnabled, "FIPS should not be enabled"); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_moduleDB.js b/security/manager/ssl/tests/unit/test_pkcs11_moduleDB.js new file mode 100644 index 0000000000..52795ccd3c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_moduleDB.js @@ -0,0 +1,50 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that adding modules with invalid names are prevented. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +const gModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB +); + +function run_test() { + let libraryFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + libraryFile.append("pkcs11testmodule"); + libraryFile.append(ctypes.libraryName("pkcs11testmodule")); + ok(libraryFile.exists(), "The pkcs11testmodule file should exist"); + + let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + throws( + () => moduleDB.addModule("Root Certs", libraryFile.path, 0, 0), + /NS_ERROR_ILLEGAL_VALUE/, + "Adding a module named 'Root Certs' should fail." + ); + throws( + () => moduleDB.addModule("", libraryFile.path, 0, 0), + /NS_ERROR_ILLEGAL_VALUE/, + "Adding a module with an empty name should fail." + ); + + let bundle = Services.strings.createBundle( + "chrome://pipnss/locale/pipnss.properties" + ); + let rootsModuleName = bundle.GetStringFromName("RootCertModuleName"); + let foundRootsModule = false; + for (let module of moduleDB.listModules()) { + if (module.name == rootsModuleName) { + foundRootsModule = true; + break; + } + } + ok( + foundRootsModule, + "Should be able to find builtin roots module by localized name." + ); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_safe_mode.js b/security/manager/ssl/tests/unit/test_pkcs11_safe_mode.js new file mode 100644 index 0000000000..724b98d664 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_safe_mode.js @@ -0,0 +1,61 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* 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/. */ +"use strict"; + +// In safe mode, PKCS#11 modules should not be loaded. This test tests this by +// simulating starting in safe mode and then attempting to load a module. + +function run_test() { + do_get_profile(); + + // Simulate starting in safe mode. + let xulRuntime = { + inSafeMode: true, + logConsoleErrors: true, + OS: "XPCShell", + XPCOMABI: "noarch-spidermonkey", + invalidateCachesOnRestart: function invalidateCachesOnRestart() { + // Do nothing + }, + QueryInterface: ChromeUtils.generateQI(["nsIXULRuntime"]), + }; + + let xulRuntimeFactory = { + createInstance(outer, iid) { + if (outer != null) { + throw Components.Exception("", Cr.NS_ERROR_NO_AGGREGATION); + } + return xulRuntime.QueryInterface(iid); + }, + }; + + let registrar = Components.manager.QueryInterface(Ci.nsIComponentRegistrar); + const XULRUNTIME_CONTRACTID = "@mozilla.org/xre/runtime;1"; + const XULRUNTIME_CID = Components.ID( + "{f0f0b230-5525-4127-98dc-7bca39059e70}" + ); + registrar.registerFactory( + XULRUNTIME_CID, + "XULRuntime", + XULRUNTIME_CONTRACTID, + xulRuntimeFactory + ); + + // When starting in safe mode, the test module should fail to load. + let pkcs11ModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + let libraryName = ctypes.libraryName("pkcs11testmodule"); + let libraryFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + libraryFile.append("pkcs11testmodule"); + libraryFile.append(libraryName); + ok(libraryFile.exists(), "The pkcs11testmodule file should exist"); + throws( + () => + pkcs11ModuleDB.addModule("PKCS11 Test Module", libraryFile.path, 0, 0), + /NS_ERROR_FAILURE/, + "addModule should throw when in safe mode" + ); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_slot.js b/security/manager/ssl/tests/unit/test_pkcs11_slot.js new file mode 100644 index 0000000000..993a09d951 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_slot.js @@ -0,0 +1,135 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the methods and attributes for interfacing with a PKCS #11 slot. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +function find_slot_by_name(module, name) { + for (let slot of module.listSlots()) { + if (slot.name == name) { + return slot; + } + } + return null; +} + +function find_module_by_name(moduleDB, name) { + for (let slot of moduleDB.listModules()) { + if (slot.name == name) { + return slot; + } + } + return null; +} + +function run_test() { + let libraryFile = Services.dirsvc.get("CurWorkD", Ci.nsIFile); + libraryFile.append("pkcs11testmodule"); + libraryFile.append(ctypes.libraryName("pkcs11testmodule")); + loadPKCS11Module(libraryFile, "PKCS11 Test Module", false); + + let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService( + Ci.nsIPKCS11ModuleDB + ); + let testModule = find_module_by_name(moduleDB, "PKCS11 Test Module"); + notEqual(testModule, null, "should be able to find test module"); + let testSlot = find_slot_by_name(testModule, "Test PKCS11 Slot 二"); + notEqual(testSlot, null, "should be able to find 'Test PKCS11 Slot 二'"); + + equal( + testSlot.name, + "Test PKCS11 Slot 二", + "Actual and expected name should match" + ); + equal( + testSlot.desc, + "Test PKCS11 Slot 二", + "Actual and expected description should match" + ); + equal( + testSlot.manID, + "Test PKCS11 Manufacturer ID", + "Actual and expected manufacturer ID should match" + ); + equal( + testSlot.HWVersion, + "0.0", + "Actual and expected hardware version should match" + ); + equal( + testSlot.FWVersion, + "0.0", + "Actual and expected firmware version should match" + ); + equal( + testSlot.status, + Ci.nsIPKCS11Slot.SLOT_READY, + "Actual and expected status should match" + ); + equal( + testSlot.tokenName, + "Test PKCS11 Tokeñ 2 Label", + "Actual and expected token name should match" + ); + + let testToken = testSlot.getToken(); + notEqual(testToken, null, "getToken() should succeed"); + equal( + testToken.tokenName, + "Test PKCS11 Tokeñ 2 Label", + "Spot check: the actual and expected test token names should be equal" + ); + ok(!testToken.isInternalKeyToken, "This token is not the internal key token"); + + testSlot = find_slot_by_name(testModule, "Empty PKCS11 Slot"); + notEqual(testSlot, null, "should be able to find 'Empty PKCS11 Slot'"); + equal(testSlot.tokenName, null, "Empty slot is empty"); + equal( + testSlot.status, + Ci.nsIPKCS11Slot.SLOT_NOT_PRESENT, + "Actual and expected status should match" + ); + + let bundle = Services.strings.createBundle( + "chrome://pipnss/locale/pipnss.properties" + ); + let internalModule = find_module_by_name( + moduleDB, + "NSS Internal PKCS #11 Module" + ); + notEqual(internalModule, null, "should be able to find internal module"); + let cryptoSlot = find_slot_by_name( + internalModule, + bundle.GetStringFromName("TokenDescription") + ); + notEqual(cryptoSlot, "should be able to find internal crypto slot"); + equal( + cryptoSlot.desc, + bundle.GetStringFromName("SlotDescription"), + "crypto slot should have expected 'desc'" + ); + equal( + cryptoSlot.manID, + bundle.GetStringFromName("ManufacturerID"), + "crypto slot should have expected 'manID'" + ); + let keySlot = find_slot_by_name( + internalModule, + bundle.GetStringFromName("PrivateTokenDescription") + ); + notEqual(keySlot, "should be able to find internal key slot"); + equal( + keySlot.desc, + bundle.GetStringFromName("PrivateSlotDescription"), + "key slot should have expected 'desc'" + ); + equal( + keySlot.manID, + bundle.GetStringFromName("ManufacturerID"), + "key slot should have expected 'manID'" + ); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_token.js b/security/manager/ssl/tests/unit/test_pkcs11_token.js new file mode 100644 index 0000000000..06096eda96 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_token.js @@ -0,0 +1,149 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the methods and attributes for interfacing with a PKCS #11 token, using +// the internal key token. +// We don't use either of the test tokens in the test PKCS #11 module because: +// 1. Test token 1 cyclically inserts and removes itself in a tight loop. +// Using token 1 would complicate the test and introduce intermittent +// failures. +// 2. Neither test token implements login or password related functionality. +// We want to test such functionality. +// 3. Using the internal token lets us actually test the internal token works +// as expected. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +function checkBasicAttributes(token) { + let bundle = Services.strings.createBundle( + "chrome://pipnss/locale/pipnss.properties" + ); + + let expectedTokenName = bundle.GetStringFromName("PrivateTokenDescription"); + equal( + token.tokenName, + expectedTokenName, + "Actual and expected name should match" + ); + equal( + token.tokenManID, + bundle.GetStringFromName("ManufacturerID"), + "Actual and expected manufacturer ID should match" + ); + equal( + token.tokenHWVersion, + "0.0", + "Actual and expected hardware version should match" + ); + equal( + token.tokenFWVersion, + "0.0", + "Actual and expected firmware version should match" + ); + equal( + token.tokenSerialNumber, + "0000000000000000", + "Actual and expected serial number should match" + ); +} + +/** + * Checks the various password related features of the given token. + * The token should already have been init with a password and be logged into. + * The password of the token will be reset after calling this function. + * + * @param {nsIPK11Token} token + * The token to test. + * @param {String} initialPW + * The password that the token should have been init with. + */ +function checkPasswordFeaturesAndResetPassword(token, initialPW) { + ok( + !token.needsUserInit, + "Token should not need user init after setting a password" + ); + ok( + token.hasPassword, + "Token should have a password after setting a password" + ); + + ok( + token.checkPassword(initialPW), + "checkPassword() should succeed if the correct initial password is given" + ); + token.changePassword(initialPW, "newPW ÿ 一二三"); + ok( + token.checkPassword("newPW ÿ 一二三"), + "checkPassword() should succeed if the correct new password is given" + ); + + ok( + !token.checkPassword("wrongPW"), + "checkPassword() should fail if an incorrect password is given" + ); + ok( + !token.isLoggedIn(), + "Token should be logged out after an incorrect password was given" + ); + ok( + !token.needsUserInit, + "Token should still be init with a password even if an incorrect " + + "password was given" + ); + + token.reset(); + ok(token.needsUserInit, "Token should need password init after reset"); + ok(!token.hasPassword, "Token should not have a password after reset"); + ok(!token.isLoggedIn(), "Token should be logged out of after reset"); +} + +function run_test() { + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + let token = tokenDB.getInternalKeyToken(); + notEqual(token, null, "The internal token should be present"); + ok( + token.isInternalKeyToken, + "The internal token should be represented as such" + ); + + checkBasicAttributes(token); + + ok(!token.isLoggedIn(), "Token should not be logged into yet"); + // Test that attempting to log out even when the token was not logged into + // does not result in an error. + token.logoutSimple(); + ok(!token.isLoggedIn(), "Token should still not be logged into"); + ok( + !token.hasPassword, + "Token should not have a password before it has been set" + ); + + let initialPW = "foo 1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/? 一二三"; + token.initPassword(initialPW); + token.login(/* force */ false); + ok(token.isLoggedIn(), "Token should now be logged into"); + + checkPasswordFeaturesAndResetPassword(token, initialPW); + + // We reset the password previously, so we need to initialize again. + token.initPassword("arbitrary"); + ok( + token.isLoggedIn(), + "Token should be logged into after initializing password again" + ); + token.logoutSimple(); + ok( + !token.isLoggedIn(), + "Token should be logged out after calling logoutSimple()" + ); + + ok( + token.needsLogin(), + "The internal token should always need authentication" + ); +} diff --git a/security/manager/ssl/tests/unit/test_pkcs11_tokenDB.js b/security/manager/ssl/tests/unit/test_pkcs11_tokenDB.js new file mode 100644 index 0000000000..127c533439 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_pkcs11_tokenDB.js @@ -0,0 +1,20 @@ +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests the methods for interfacing with the PKCS #11 token database. + +// Ensure that the appropriate initialization has happened. +do_get_profile(); + +function run_test() { + let tokenDB = Cc["@mozilla.org/security/pk11tokendb;1"].getService( + Ci.nsIPK11TokenDB + ); + + notEqual( + tokenDB.getInternalKeyToken(), + null, + "The internal token should be non-null" + ); +} diff --git a/security/manager/ssl/tests/unit/test_sanctions/apple-ist-ca-8-g1-intermediate.pem b/security/manager/ssl/tests/unit/test_sanctions/apple-ist-ca-8-g1-intermediate.pem new file mode 100644 index 0000000000..29428ad015 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/apple-ist-ca-8-g1-intermediate.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVDCCAtugAwIBAgIQE1Iuv8HdXOEe8nZAdR/n3zAKBggqhkjOPQQDAzCBmDEL +MAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNVBAsTMChj +KSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ugb25seTE2 +MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0 +eSAtIEcyMB4XDTE2MDYwOTAwMDAwMFoXDTMxMDYwODIzNTk1OVowYjEcMBoGA1UE +AwwTQXBwbGUgSVNUIENBIDggLSBHMTEgMB4GA1UECwwXQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkxEzARBgNVBAoMCkFwcGxlIEluYy4xCzAJBgNVBAYTAlVTMFkwEwYH +KoZIzj0CAQYIKoZIzj0DAQcDQgAELVSOaLAQE+/0LdvYCbJD6J1lmW40uNSXyY7J +1qgiNzLIcWDusPHyxWT2ukdf/OYHeDIt9sqAIMn9cPhykyGIRaOCATowggE2MBIG +A1UdEwEB/wQIMAYBAf8CAQAwNgYDVR0fBC8wLTAroCmgJ4YlaHR0cDovL2cuc3lt +Y2IuY29tL0dlb1RydXN0UENBLUcyLmNybDAOBgNVHQ8BAf8EBAMCAQYwLgYIKwYB +BQUHAQEEIjAgMB4GCCsGAQUFBzABhhJodHRwOi8vZy5zeW1jZC5jb20wSQYDVR0g +BEIwQDA+BgZngQwBAgIwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2VvdHJ1 +c3QuY29tL3Jlc291cmNlcy9jcHMwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUF +BwMCMB0GA1UdDgQWBBTDxKRYBWPXgwa6lo3cso8y9ru3QTAfBgNVHSMEGDAWgBQV +XzVXUVX7JbKtA2n8AaP6vhFV1TAKBggqhkjOPQQDAwNnADBkAjBH2jMNybjCk3Ts +OidXxJX9YDPMd5S3KDCv8vyTdJGhtoly7fQJRNv5rnVz+6YGfsMCMEp6wyheL7NK +mqavsduix2R+j1B3wRjelzJYgXzgM3nwhQKKlJWxpF7IGHuva1taxg== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/default-ee.key b/security/manager/ssl/tests/unit/test_sanctions/default-ee.key new file mode 100644 index 0000000000..8af23e068d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/default-ee.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/security/manager/ssl/tests/unit/test_sanctions/default-ee.key.keyspec b/security/manager/ssl/tests/unit/test_sanctions/default-ee.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/default-ee.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem b/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem new file mode 100644 index 0000000000..c85c051004 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDiTCCAnGgAwIBAgIUUwG2e1zCLPYPQc2aSZ4UsI/GiK0wDQYJKoZIhvcNAQEL +BQAwEjEQMA4GA1UEAwwHVGVzdCBDQTAiGA8yMDE5MTEyODAwMDAwMFoYDzIwMjIw +MjA1MDAwMDAwWjAaMRgwFgYDVQQDDA9UZXN0IEVuZC1lbnRpdHkwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq0 +7PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D +/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuw +JJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyX +rZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWd +q5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjgcow +gccwgZAGA1UdEQSBiDCBhYIJbG9jYWxob3N0gg0qLmV4YW1wbGUuY29tghUqLnBp +bm5pbmcuZXhhbXBsZS5jb22CKCouaW5jbHVkZS1zdWJkb21haW5zLnBpbm5pbmcu +ZXhhbXBsZS5jb22CKCouZXhjbHVkZS1zdWJkb21haW5zLnBpbm5pbmcuZXhhbXBs +ZS5jb20wMgYIKwYBBQUHAQEEJjAkMCIGCCsGAQUFBzABhhZodHRwOi8vbG9jYWxo +b3N0Ojg4ODgvMA0GCSqGSIb3DQEBCwUAA4IBAQCbcbjTQmzRu++LJ/R1KjA99THZ +aRGG7u0knPs40bz+rIOAR7SllYTvZ1g5HanNG3GZ5+DExVmVtixcrqJFTV0BJsi0 +rv8XR4F3Cdict+rJ+hCSBqu6BGNWdptsaSPiSm+eL//tgjGY1zm9ln1B/OvTYA/n +f+OV07v44pwRBUe8C9Awb2J3KMHATPciKTk0Pwmh0jXi4FN9ehG1rXZMY2daHoKq +hzbBc8EaGzPPAyFumHd6wNqWX+/chEtT00SlcJw/lbQZnK8XvUSOhRuUeRdCM5wX +3w+Gy4P/FrI5tePoR9606GR6plC8QZxT3+Z6lTyCHz3I05+PNXwfmZH3ABSg +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem.certspec new file mode 100644 index 0000000000..554339ff52 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/default-ee.pem.certspec @@ -0,0 +1,4 @@ +issuer:Test CA +subject:Test End-entity +extension:subjectAlternativeName:localhost,*.example.com,*.pinning.example.com,*.include-subdomains.pinning.example.com,*.exclude-subdomains.pinning.example.com +extension:authorityInformationAccess:http://localhost:8888/ diff --git a/security/manager/ssl/tests/unit/test_sanctions/gspe72-4-ssl-ls-apple-com.pem b/security/manager/ssl/tests/unit/test_sanctions/gspe72-4-ssl-ls-apple-com.pem new file mode 100644 index 0000000000..ce7c05fd0c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/gspe72-4-ssl-ls-apple-com.pem @@ -0,0 +1,38 @@ +-----BEGIN CERTIFICATE----- +MIIGuzCCBmCgAwIBAgIQJwfBKDdrh96xNA/Wr1LyATAKBggqhkjOPQQDAjBiMRww +GgYDVQQDDBNBcHBsZSBJU1QgQ0EgOCAtIEcxMSAwHgYDVQQLDBdDZXJ0aWZpY2F0 +aW9uIEF1dGhvcml0eTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMw +HhcNMTkwMzExMjA1MDE0WhcNMjEwNDA5MjA1MDE0WjCBgjEiMCAGA1UEAwwZZ3Nw +ZTcyLTQtc3NsLmxzLmFwcGxlLmNvbTElMCMGA1UECwwcbWFuYWdlbWVudDppZG1z +Lmdyb3VwLjY2NTAzNTETMBEGA1UECgwKQXBwbGUgSW5jLjETMBEGA1UECAwKQ2Fs +aWZvcm5pYTELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATr +NqVhtJlzuIqo/qrkTFUFe8IRKh9sOr6HXrbvE1vUIbUcWcfhWs8dczP9RBCw6TNI +TGHAhuG2RZ/f9IrUjSldo4IE1TCCBNEwDAYDVR0TAQH/BAIwADAfBgNVHSMEGDAW +gBTDxKRYBWPXgwa6lo3cso8y9ru3QTB+BggrBgEFBQcBAQRyMHAwNAYIKwYBBQUH +MAKGKGh0dHA6Ly9jZXJ0cy5hcHBsZS5jb20vYXBwbGVpc3RjYThnMS5kZXIwOAYI +KwYBBQUHMAGGLGh0dHA6Ly9vY3NwLmFwcGxlLmNvbS9vY3NwMDMtYXBwbGVpc3Rj +YThnMTA1MCQGA1UdEQQdMBuCGWdzcGU3Mi00LXNzbC5scy5hcHBsZS5jb20wgf4G +A1UdIASB9jCB8zCB8AYKKoZIhvdjZAULBDCB4TCBpAYIKwYBBQUHAgIwgZcMgZRS +ZWxpYW5jZSBvbiB0aGlzIGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVz +IGFjY2VwdGFuY2Ugb2YgYW55IGFwcGxpY2FibGUgdGVybXMgYW5kIGNvbmRpdGlv +bnMgb2YgdXNlIGFuZC9vciBjZXJ0aWZpY2F0aW9uIHByYWN0aWNlIHN0YXRlbWVu +dHMuMDgGCCsGAQUFBwICMCwMKmh0dHA6Ly93d3cuYXBwbGUuY29tL2NlcnRpZmlj +YXRlYXV0aG9yaXR5LzAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwEwNwYD +VR0fBDAwLjAsoCqgKIYmaHR0cDovL2NybC5hcHBsZS5jb20vYXBwbGVpc3RjYThn +MS5jcmwwHQYDVR0OBBYEFNNlLsYlY4okSG2S2Gl2UMdPlkbzMA4GA1UdDwEB/wQE +AwIDiDCCAnAGCisGAQQB1nkCBAIEggJgBIICXAJaAHYAu9nfvB+KcbWTlCOXqpJ7 +RzhXlQqrUugakJZkNo4e0YUAAAFpbo5SYgAABAMARzBFAiATXJMIgS9+f9P92SWY +0oYi/vRuE4hTvLANoLv0FLE7WwIhAJBMLXnqV3k8R7yWdISnvRZF0/QBmMK632Cp +N/kcpd3SAHYApLkJkLQYWBSHuxOizGdwCjw1mAT5G9+443fNDsgN3BAAAAFpbo5S +WQAABAMARzBFAiBCsSdFBiDjDEMsKdI8FyXD0aS6fCZ9bAuNYIGNPfAGhQIhAJ/R +mCOrVp/GBOg0CLYrjJcBbIAGditNOg8Kd8WTP85fAHYA7ku9t3XOYLrhQmkfq+Ge +ZqMPfl+wctiDAMR7iXqo/csAAAFpbo5SXgAABAMARzBFAiEAvzTu/MJBrBuyhPCj +6R6qtyTLyTrin/HmOttlH6iJ4IsCICuqq2EK9+k8w0c6BuBtfK1BDw/lUUGqtSDZ +svcDKVkIAHcAVYHUwhaQNgFK6gubVzxT8MDkOHhwJQgXL6OqHQcT0wwAAAFpbo5U +5wAABAMASDBGAiEA92TvuiKRNcHjkIZlCo2TBW/ZFWvOoZwgoC6mB1CHmTcCIQDm +cHuw1Ap1MUC6W+s76Im/js9KBumICSxByBkjxI1w6AB3AG9Tdqwx8DEZ2JkApFEV +/3cVHBHZAsEAKQaNsgiaN9kTAAABaW6OVTEAAAQDAEgwRgIhAPaUtnaDmwkQvO3i +nzgdo7AOVh1DEco+axckyrcxJgAKAiEA++0eb4HftQ9rUh9oZNYvqnyVSwNZfZwW +5DYuKcTTRhswCgYIKoZIzj0EAwIDSQAwRgIhAJVASCnbb+d9zglT5b7wirXUxvEu +nkHBAsB7VcVNqBEfAiEAiAlD40/WXTh31J41SVyb4CaQDTn0V+MstUnS1h+M1Cg= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/moz.build b/security/manager/ssl/tests/unit/test_sanctions/moz.build new file mode 100644 index 0000000000..7318333a99 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/moz.build @@ -0,0 +1,21 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'default-ee.pem', +# 'symantec-ee-from-allowlist-after-cutoff.pem', +# 'symantec-ee-from-allowlist-before-cutoff.pem', +# 'symantec-ee-not-allowlisted-after-cutoff.pem', +# 'symantec-ee-not-allowlisted-before-cutoff.pem', +# 'symantec-intermediate-other.pem', +# 'symantec-intermediate-other-crossigned.pem', +# 'symantec-intermediate-allowlisted.pem', +# 'symantec-test-ca.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem new file mode 100644 index 0000000000..95316b235e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDPjCCAiagAwIBAgIUN+Dcp+HeMvZhIJ3BD5af4bwrj4IwDQYJKoZIhvcNAQEL +BQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMT +HEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwIhgPMjAxNjA2MDEwMDAwMDBa +GA8yMDUwMDEwMTAwMDAwMFowKTEnMCUGA1UEAwweZWUtZnJvbS1hbGxvd2xpc3Qt +YWZ0ZXItY3V0b2ZmMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR +qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv +WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+ +rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv +JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5 +Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6 +clHEMdUDrNoYCjXtjQIDAQABozowODA2BgNVHREELzAtgitzeW1hbnRlYy1hbGxv +d2xpc3QtYWZ0ZXItY3V0b2ZmLmV4YW1wbGUuY29tMA0GCSqGSIb3DQEBCwUAA4IB +AQB/2Pgyyje+T4uKkibYZ537NZB6OUvef4nrGtswjxKbUnHzrLK1kJd3mtyNpydK +fzW8WV1CR+nltFI5oaoOAf26FuQfaoCADmlmFlirgnm2fEH2xCokDCQHIgQxNwXr +Ok6JTHWeuaOsu+verDPjkuUATnONY+FRTBxfPh5B3OA+aBO62bAeNCAjIya1U60S +emAnleYtwhXs0Q9TLsR7O7aSYP3FgnqnWPuOkPF3wrUiE8Nrd3givz5OJW42IU63 +ijiojHtPpjAiudbzD8y1zuDcxTxiI4jEjTDS1kIqnvHd3f4bSxpgcQUPk44nu+wO +j5+as/TRu5dC+xHmWCVT10yd +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem.certspec new file mode 100644 index 0000000000..c8a4249dfc --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-after-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=US/O=Google Inc/CN=Google Internet Authority G2 +subject:ee-from-allowlist-after-cutoff +validity:20160601-20500101 +extension:subjectAlternativeName:symantec-allowlist-after-cutoff.example.com diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem new file mode 100644 index 0000000000..0c8a52b8d6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDQDCCAiigAwIBAgIUVWP+EbM7hYQLOXoABvWpRwoPWJ0wDQYJKoZIhvcNAQEL +BQAwSTELMAkGA1UEBhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMT +HEdvb2dsZSBJbnRlcm5ldCBBdXRob3JpdHkgRzIwIhgPMjAxNDA2MDEwMDAwMDBa +GA8yMDUwMDEwMTAwMDAwMFowKjEoMCYGA1UEAwwfZWUtZnJvbS1hbGxvd2xpc3Qt +YmVmb3JlLWN1dG9mZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaM7MDkwNwYDVR0RBDAwLoIsc3ltYW50ZWMtYWxs +b3dsaXN0LWJlZm9yZS1jdXRvZmYuZXhhbXBsZS5jb20wDQYJKoZIhvcNAQELBQAD +ggEBAFhn9xNv/Yp1Ua9OX7oXgbVgzxCIAm6/zDK7V4V37P5em/lI85OpbuuTO4ns +9VB2/nijkELhSkiyCjmCaxQhlUBzA/2wJeNIfaWu9Mq5MR6jWShhNXND66lTCDIQ +wGVQkBl8/3OqSD4IFI3pKAiPhCGsUnRIhGSARcrFMQpKssnN5XN1ump1YA7/u6Kv +apNbKccgKvLekO8/kUpFrpHt+uQaNS2IeVrmOnNh4GtyD3DG1ZDcZ1VgLAnzbVUg +xiUbs58mY0o1qumuzqJ0/ie5UPOjWnoXSNq6dd4jqsXcFeYXe106G6arV5BLN1Pa +gNxxfOfBcebE1OwxZpfQwNy3JxI= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem.certspec new file mode 100644 index 0000000000..51cecd1f8e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-from-allowlist-before-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=US/O=Google Inc/CN=Google Internet Authority G2 +subject:ee-from-allowlist-before-cutoff +validity:20140601-20500101 +extension:subjectAlternativeName:symantec-allowlist-before-cutoff.example.com diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem new file mode 100644 index 0000000000..65eab919b5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDSzCCAjOgAwIBAgIUNWWgyC4I0/jmqdamoCRL0qhP3QQwDQYJKoZIhvcNAQEL +BQAwTzELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0Fub3RoZXIgQ0EgSW5jLjEmMCQG +A1UEAxMdU29tZSBPdGhlciBDQSBUaGFuIFRoZSBPdGhlcnMwIhgPMjAxNjA2MDEw +MDAwMDBaGA8yMDUwMDEwMTAwMDAwMFowKjEoMCYGA1UEAwwfZWUtbm90LWFsbG93 +bGlzdGVkLWFmdGVyLWN1dG9mZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAab +bhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmts +Du0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhI +H6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8 +rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kX +Mbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaNAMD4wPAYDVR0RBDUwM4Ixc3ltYW50 +ZWMtbm90LWFsbG93bGlzdGVkLWFmdGVyLWN1dG9mZi5leGFtcGxlLmNvbTANBgkq +hkiG9w0BAQsFAAOCAQEARlQNYz+w2ekzdX8FKwlWoMX6Df5o4ZhXreRK9V4SuYJg +SvAucL35TuTKkBz9C5VPjAL/Qts4n5DKWaWQfsvoCJOGtTMEKd1MEL9RbMFOewI0 +tN9sV9aMNsmhNPL4PB3A7lKJb8gi/tyoN3BXjsaZBxmyi5A6Vt3lyybgMOSTdzR6 +u2XAPm+zNDrOzc2tavZEyhEKzptaJuCQrefcnAM9JTHtJhvJp30WWighJyclqmRX +bLDYaHRRuRI0jkgrrcUKolau8YKsSoIBoxP2aels8drZDH4UAC86GW2iF/tK+J65 ++JJ2Mk9erdcLoYGLxHZqQySpRaFtciSF+Uym1nmNxA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem.certspec new file mode 100644 index 0000000000..85edcf742d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-after-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=US/O=Another CA Inc./CN=Some Other CA Than The Others +subject:ee-not-allowlisted-after-cutoff +validity:20160601-20500101 +extension:subjectAlternativeName:symantec-not-allowlisted-after-cutoff.example.com diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem new file mode 100644 index 0000000000..23d6fec107 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDTTCCAjWgAwIBAgIUaxGuzjOrA/2qScMaz5tKQTUrvAYwDQYJKoZIhvcNAQEL +BQAwTzELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0Fub3RoZXIgQ0EgSW5jLjEmMCQG +A1UEAxMdU29tZSBPdGhlciBDQSBUaGFuIFRoZSBPdGhlcnMwIhgPMjAxNDA2MDEw +MDAwMDBaGA8yMDUwMDEwMTAwMDAwMFowKzEpMCcGA1UEAwwgZWUtbm90LWFsbG93 +bGlzdGVkLWJlZm9yZS1jdXRvZmYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjQTA/MD0GA1UdEQQ2MDSCMnN5bWFu +dGVjLW5vdC1hbGxvd2xpc3RlZC1iZWZvcmUtY3V0b2ZmLmV4YW1wbGUuY29tMA0G +CSqGSIb3DQEBCwUAA4IBAQBCkIIEXnX/3rv0JuF0FZEpROnQw8zoa4vZjwG1NmvH ++PwnTL7FvBg9QBK0n8ZKfCMqJU98jR5+x6V9Eo2amXEYRAsxCU6kY/Xz43OxGLQz +5cbr9eDswWmt7h/LXl0tsprpgfBNaQ9512UbPMkDG4MSwLjkuTgdnM4dBsLURrAU +5lcukutuNYJ7x92/Ah7hffouB6QHyP80onxqqQTQs2j/0MvJxlUWrnKBzk+B475W +/1iMOCE3r2q6+TVp1sun9mcn7UvRHQRPvjSdjujjJ++5fqH5s4cF2Sv4lv+dEGJn +xrr/a9GA3bUE6Iq9PbAeX3l7RaP+q/znSDBtaLYZ1Xau +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem.certspec new file mode 100644 index 0000000000..b736169a04 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-ee-not-allowlisted-before-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=US/O=Another CA Inc./CN=Some Other CA Than The Others +subject:ee-not-allowlisted-before-cutoff +validity:20140601-20500101 +extension:subjectAlternativeName:symantec-not-allowlisted-before-cutoff.example.com diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem new file mode 100644 index 0000000000..e912276ff2 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDkTCCAnmgAwIBAgIUWaPXi1S7qZSZ1omEbmdrNrvj/0MwDQYJKoZIhvcNAQEL +BQAwgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYD +VQQLEzAoYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxNjA0BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkgLSBHMjAiGA8yMDEwMDEwMTAwMDAwMFoYDzIwNTAwMTAxMDAwMDAw +WjBJMQswCQYDVQQGEwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMc +R29vZ2xlIEludGVybmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wccl +qODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sg +w0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCx +V5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1 +MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQs +vxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswCwYDVR0PBAQD +AgEGMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBALSeQ+T+3AVPidHI +Mk5D6qOJm57AQ1J5VWoD+S/vqO9jaBjXGtPfx1yBCgLfZvF5N9Wy/foNLhx49BXf +gwUZPXr5skG9TXPdiZinPW1Txfq/JfJPIeHKdL1eHCm9L/7HVAv1TNlfWFIukGOh +ZIuzBXID5MH9ubOpY1RcgAxa4wQknPAQ2ZPAcdTzEvKOOv6O78EHTv5TKU6/vk+B +COS3S86eInm0JcomC+L0H7JT0mCGAzFB7EgWEgnPH8hvi40H2Bml35a192VOdq3o +XZSoA0ZfARlpcetAu+PjPyoo6UwQ52p4ifXVJoOuZSsRsxmADJpjq1JwTQy3Axah +ELBHK0c= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem.certspec new file mode 100644 index 0000000000..745bd9436a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-allowlisted.pem.certspec @@ -0,0 +1,5 @@ +issuer:printableString/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 +subject:printableString/C=US/O=Google Inc/CN=Google Internet Authority G2 +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem new file mode 100644 index 0000000000..819d8a30da --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDFzCCAf+gAwIBAgIUBy1RVPb6jMqyBSQwtlK+jZftnKIwDQYJKoZIhvcNAQEL +BQAwGTEXMBUGA1UEAwwOVW5rbm93biBJc3N1ZXIwIhgPMjAxMDAxMDEwMDAwMDBa +GA8yMDUwMDEwMTAwMDAwMFowTzELMAkGA1UEBhMCVVMxGDAWBgNVBAoTD0Fub3Ro +ZXIgQ0EgSW5jLjEmMCQGA1UEAxMdU29tZSBPdGhlciBDQSBUaGFuIFRoZSBPdGhl +cnMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braI +BjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVa +p0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB +7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4C +kC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJv +aeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgK +Ne2NAgMBAAGjHTAbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4IBAQAs7dfRClCtgzMfYVRIciVqdjNR+jeFLmYFCDDqx5h6zve4VfxK +AEQPWNsIVdPlu+djILHHd9+RvLSHh5HqeXKppBevnux2SxwfXJQ3T+ysqGxH4tEQ +BCgXryt8v5q/DL9H2+T352NJCh7ZMkftEta3Hchtr4TSaT7udtib1uQ9JeLx97LJ +A6aI8SpfI/as1Ku1LAAV9rfhkJgMyeC0ppMfTVGj/gjgq8fL52/9Su9Id8l+SeYD +yLCXjPX0rhAjTeJyiOpAK9OPQgk7i3DRvdO/F+JCkTNE9V6PLX0J+30g+3YZND+a +R81zibhRfa6Ki5cqRflHYhAY4GCFk7mhHLsL +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem.certspec new file mode 100644 index 0000000000..fdcb287cd1 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other-crossigned.pem.certspec @@ -0,0 +1,5 @@ +issuer:Unknown Issuer +subject:printableString/C=US/O=Another CA Inc./CN=Some Other CA Than The Others +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem new file mode 100644 index 0000000000..fae3cd2055 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDlzCCAn+gAwIBAgIUcwyTGJUUq4KcHJ1Vb27ydVW1+8UwDQYJKoZIhvcNAQEL +BQAwgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYD +VQQLEzAoYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxNjA0BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkgLSBHMjAiGA8yMDEwMDEwMTAwMDAwMFoYDzIwNTAwMTAxMDAwMDAw +WjBPMQswCQYDVQQGEwJVUzEYMBYGA1UEChMPQW5vdGhlciBDQSBJbmMuMSYwJAYD +VQQDEx1Tb21lIE90aGVyIENBIFRoYW4gVGhlIE90aGVyczCCASIwDQYJKoZIhvcN +AQEBBQADggEPADCCAQoCggEBALqIUahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhX +bCR7wcclqODYH72xnAabbhqG8mvir1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQ +OCApk6sgw0nk27lMwmtsDu0Vgg/xfq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9 +uYhheZCxV5A90jvF4LhIH6g304hD7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFb +t+KWEsB1MaMMkd20yvf8rR0l0wnvuRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhO +NsscJAQsvxaLL+Xxj5kXMbiz/kkj+nJRxDHVA6zaGAo17Y0CAwEAAaMdMBswCwYD +VR0PBAQDAgEGMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAHO5Uxu5 +l0orJ5uxTWaaeRrrua66fnDWZoI4BLJ988CpNtZQ7eyXglg2CnSPdQ8GwDKY7JPl +WGXnXNjbkxW7Br705yFFQOglVyLErXqaqzaTMGNqqS2vxZe/msiKUbhQN66glCSV +2apocQceCIP9dvP7EZvnWcZFn/6/qjgfZ3E7VNTRC8hGcd9NI1rfreHWevBierDe +l9cNIta1Qjvj8qzHKDfsrxrk1UlDJemtLvBvE3aGU7YrtVcOZA3l8mnrtfbBgoTJ +FH3H5Z1rw7uY7TcHK8YSIr4BGh8AAYmx69w87tL6FpOTuJvfW24Fj3aIbm5C4JDP +Or8OZj97VdCJ9ds= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem.certspec new file mode 100644 index 0000000000..980edf8ac7 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-intermediate-other.pem.certspec @@ -0,0 +1,5 @@ +issuer:printableString/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 +subject:printableString/C=US/O=Another CA Inc./CN=Some Other CA Than The Others +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem b/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem new file mode 100644 index 0000000000..c9aba820ad --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIID4TCCAsmgAwIBAgIUdbQmR0wwLxnOuBWx8JRJkIlK0skwDQYJKoZIhvcNAQEL +BQAwgZgxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMTkwNwYD +VQQLEzAoYykgMjAwNyBHZW9UcnVzdCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxNjA0BgNVBAMTLUdlb1RydXN0IFByaW1hcnkgQ2VydGlmaWNhdGlvbiBB +dXRob3JpdHkgLSBHMjAiGA8yMDEwMDEwMTAwMDAwMFoYDzIwNTAwMTAxMDAwMDAw +WjCBmDELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUdlb1RydXN0IEluYy4xOTA3BgNV +BAsTMChjKSAyMDA3IEdlb1RydXN0IEluYy4gLSBGb3IgYXV0aG9yaXplZCB1c2Ug +b25seTE2MDQGA1UEAxMtR2VvVHJ1c3QgUHJpbWFyeSBDZXJ0aWZpY2F0aW9uIEF1 +dGhvcml0eSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohR +qESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+Kv +WnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+ +rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPv +JxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5 +Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6 +clHEMdUDrNoYCjXtjQIDAQABox0wGzALBgNVHQ8EBAMCAQYwDAYDVR0TBAUwAwEB +/zANBgkqhkiG9w0BAQsFAAOCAQEAMheHA8TX+WozmLeUr8J3FF+x2l2vGSWiW8W4 +wkC1ETDEc81FxEVip0EDpp6aFurIwOOejL8a8B3hEXd7rqCCsaO8yUYQxaQMPuB5 +4OtBuTcCtIpHeCfwCcUQPes12dCyf3v5stQl5tAF9S/ddEn84Rbntb2ZIRotQnof +MjpelWuZRmMRvTtQ9BIUID5GuZcMvCmRap011az1nGOJvSsOh2ag+Yz9tTOD3gDM +z0DIoUUGSQuu0Csw1nJiAIdtlBzwgy1g2YoGTEc3vuFp9KHywPDsdOytlLuIh03k +C5Vi3DQOO5elqy/I8eeM86PfO9lySyVF7wjiB//IFlQoyl8TMA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem.certspec b/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem.certspec new file mode 100644 index 0000000000..1367ecf53e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions/symantec-test-ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:printableString/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 +subject:printableString/C=US/O=GeoTrust Inc./OU=(c) 2007 GeoTrust Inc. - For authorized use only/CN=GeoTrust Primary Certification Authority - G2 +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_sanctions_symantec_apple_google.js b/security/manager/ssl/tests/unit/test_sanctions_symantec_apple_google.js new file mode 100644 index 0000000000..b94de49c41 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sanctions_symantec_apple_google.js @@ -0,0 +1,107 @@ +/* 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/. */ +"use strict"; + +// Tests handling of certificates issued by Symantec. If such certificates were +// issued by an Apple or Google intermediate, they are allowlisted. Otherwise, +// If they have a notBefore before 1 June 2016, they should be distrusted, while +// those from that date or later emit a warning to the console. + +function shouldBeImminentlyDistrusted(aTransportSecurityInfo) { + let isDistrust = + aTransportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_DISTRUST_IMMINENT; + Assert.ok(isDistrust, "This host should be imminently distrusted"); +} + +do_get_profile(); + +const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +add_tls_server_setup( + "SanctionsTestServer", + "test_sanctions", + /* Don't try to load non-existent test-ca.pem */ false +); + +addCertFromFile(certDB, "test_sanctions/symantec-test-ca.pem", "CTu,u,u"); + +// Add the necessary intermediates. This is important because the test server, +// though it will attempt to send along an intermediate, isn't able to reliably +// pick between the intermediate-other-crossigned and intermediate-other. +add_test(function() { + addCertFromFile( + certDB, + "test_sanctions/symantec-intermediate-allowlisted.pem", + ",," + ); + addCertFromFile( + certDB, + "test_sanctions/symantec-intermediate-other.pem", + ",," + ); + run_next_test(); +}); + +add_connection_test( + "symantec-not-allowlisted-before-cutoff.example.com", + MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED, + null, + null +); + +add_connection_test( + "symantec-not-allowlisted-after-cutoff.example.com", + MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED, + null, + null +); + +// Add a cross-signed intermediate into the database, and ensure we still get +// the expected error. +add_test(function() { + addCertFromFile( + certDB, + "test_sanctions/symantec-intermediate-other-crossigned.pem", + ",," + ); + run_next_test(); +}); + +add_connection_test( + "symantec-not-allowlisted-before-cutoff.example.com", + MOZILLA_PKIX_ERROR_ADDITIONAL_POLICY_CONSTRAINT_FAILED, + null, + null +); + +// Load the Apple EE cert and its intermediate, then verify +// it at a reasonable time and make sure the allowlists work +add_task(async function() { + addCertFromFile( + certDB, + "test_sanctions/apple-ist-ca-8-g1-intermediate.pem", + ",," + ); + let allowlistedCert = constructCertFromFile( + "test_sanctions/gspe72-4-ssl-ls-apple-com.pem" + ); + + // Since we don't want to actually try to fetch OCSP for this certificate, + // (as an external fetch is bad in the tests), disable OCSP first. + Services.prefs.setIntPref("security.OCSP.enabled", 0); + + // (new Date("2020-01-01")).getTime() / 1000 + const VALIDATION_TIME = 1577836800; + + await checkCertErrorGenericAtTime( + certDB, + allowlistedCert, + PRErrorCodeSuccess, + certificateUsageSSLServer, + VALIDATION_TIME + ); +}); diff --git a/security/manager/ssl/tests/unit/test_sdr.js b/security/manager/ssl/tests/unit/test_sdr.js new file mode 100644 index 0000000000..e9e477efc5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sdr.js @@ -0,0 +1,272 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests various aspects of the nsISecretDecoderRing implementation. + +do_get_profile(); + +let gSetPasswordShownCount = 0; + +// Mock implementation of nsITokenPasswordDialogs. +const gTokenPasswordDialogs = { + setPassword(ctx, tokenName) { + gSetPasswordShownCount++; + info(`setPassword() called; shown ${gSetPasswordShownCount} times`); + info(`tokenName: ${tokenName}`); + return false; // Returning false means "the user didn't cancel". + }, + + QueryInterface: ChromeUtils.generateQI(["nsITokenPasswordDialogs"]), +}; + +let gMockPrompter = { + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + // Returning false simulates the user canceling the password prompt. + return false; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), +}; + +// Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt +// to call promptPassword. We return the mock one, above. +let gWindowWatcher = { + getNewPrompter: () => gMockPrompter, + QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]), +}; + +add_task(function setup() { + let windowWatcherCID = MockRegistrar.register( + "@mozilla.org/embedcomp/window-watcher;1", + gWindowWatcher + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(windowWatcherCID); + }); +}); + +add_task(function testEncryptString() { + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + // Test valid inputs for encryptString() and decryptString(). + let inputs = [ + "", + " ", // First printable latin1 character (code point 32). + "foo", + "1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?", + "¡äöüÿ", // Misc + last printable latin1 character (code point 255). + "aaa 一二三", // Includes Unicode with code points outside [0, 255]. + ]; + for (let input of inputs) { + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "UTF-8"; + + let convertedInput = converter.ConvertFromUnicode(input); + convertedInput += converter.Finish(); + + let encrypted = sdr.encryptString(convertedInput); + + notEqual( + convertedInput, + encrypted, + "Encrypted input should not just be the input itself" + ); + + try { + atob(encrypted); + } catch (e) { + ok(false, `encryptString() should have returned Base64: ${e}`); + } + + equal( + convertedInput, + sdr.decryptString(encrypted), + "decryptString(encryptString(input)) should return input" + ); + } + + // Test invalid inputs for decryptString(). + throws( + () => sdr.decryptString("*"), + /NS_ERROR_ILLEGAL_VALUE/, + "decryptString() should throw if given non-Base64 input" + ); + + // Test calling changePassword() pops up the appropriate dialog. + // Note: On Android, nsITokenPasswordDialogs is apparently not implemented, + // which also seems to prevent us from mocking out the interface. + if (AppConstants.platform != "android") { + let tokenPasswordDialogsCID = MockRegistrar.register( + "@mozilla.org/nsTokenPasswordDialogs;1", + gTokenPasswordDialogs + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(tokenPasswordDialogsCID); + }); + + equal( + gSetPasswordShownCount, + 0, + "changePassword() dialog should have been shown zero times" + ); + sdr.changePassword(); + equal( + gSetPasswordShownCount, + 1, + "changePassword() dialog should have been shown exactly once" + ); + } +}); + +add_task(async function testAsyncEncryptStrings() { + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + // Test valid inputs for encryptString() and decryptString(). + let inputs = [ + "", + " ", // First printable latin1 character (code point 32). + "foo", + "1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?", + "¡äöüÿ", // Misc + last printable latin1 character (code point 255). + "aaa 一二三", // Includes Unicode with code points outside [0, 255]. + ]; + + let encrypteds = await sdr.asyncEncryptStrings(inputs); + for (let i = 0; i < inputs.length; i++) { + let encrypted = encrypteds[i]; + let input = inputs[i]; + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "UTF-8"; + + let convertedInput = converter.ConvertFromUnicode(input); + convertedInput += converter.Finish(); + notEqual( + convertedInput, + encrypted, + "Encrypted input should not just be the input itself" + ); + + try { + atob(encrypted); + } catch (e) { + ok(false, `encryptString() should have returned Base64: ${e}`); + } + + equal( + convertedInput, + sdr.decryptString(encrypted), + "decryptString(encryptString(input)) should return input" + ); + } +}); + +add_task(async function testAsyncDecryptStrings() { + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + // Test valid inputs for encryptString() and decryptString(). + let testCases = [ + "", + " ", // First printable latin1 character (code point 32). + "foo", + "1234567890`~!@#$%^&*()-_=+{[}]|\\:;'\",<.>/?", + "¡äöüÿ", // Misc + last printable latin1 character (code point 255). + "aaa 一二三", // Includes Unicode with code points outside [0, 255]. + ]; + + let convertedTestCases = testCases.map(tc => { + let converter = Cc[ + "@mozilla.org/intl/scriptableunicodeconverter" + ].createInstance(Ci.nsIScriptableUnicodeConverter); + converter.charset = "UTF-8"; + + let convertedInput = converter.ConvertFromUnicode(tc); + convertedInput += converter.Finish(); + return convertedInput; + }); + + let encryptedStrings = convertedTestCases.map(tc => sdr.encryptString(tc)); + let decrypteds = await sdr.asyncDecryptStrings(encryptedStrings); + for (let i = 0; i < encryptedStrings.length; i++) { + let decrypted = decrypteds[i]; + + equal( + decrypted, + testCases[i], + "decrypted string should match expected value" + ); + equal( + sdr.decryptString(encryptedStrings[i]), + convertedTestCases[i], + "decryptString(encryptString(input)) should return the initial decrypted string value" + ); + } +}); + +add_task(async function testAsyncDecryptInvalidStrings() { + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + // Test invalid inputs for sdr.asyncDecryptStrings + let testCases = [ + "~bmV0cGxheQ==", // invalid base64 encoding + "bmV0cGxheQ==", // valid base64 characters but not encrypted + "https://www.example.com", // website address from erroneous migration + ]; + + let decrypteds = await sdr.asyncDecryptStrings(testCases); + equal( + decrypteds.length, + testCases.length, + "each testcase should still return a response" + ); + for (let i = 0; i < decrypteds.length; i++) { + let decrypted = decrypteds[i]; + + equal( + decrypted, + "", + "decrypted string should be empty when trying to decrypt an invalid input with asyncDecryptStrings" + ); + + Assert.throws( + () => sdr.decryptString(testCases[i]), + /NS_ERROR_ILLEGAL_VALUE|NS_ERROR_FAILURE/, + `Check testcase would have thrown: ${testCases[i]}` + ); + } +}); + +add_task(async function testAsyncDecryptLoggedOut() { + // Set a master password. + let token = Cc["@mozilla.org/security/pk11tokendb;1"] + .getService(Ci.nsIPK11TokenDB) + .getInternalKeyToken(); + token.initPassword("password"); + token.logoutSimple(); + + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + await Assert.rejects( + sdr.asyncDecryptStrings(["irrelevant"]), + /NS_ERROR_NOT_AVAILABLE/, + "Check error is thrown instead of returning empty strings" + ); + + token.reset(); + token.initPassword(""); +}); diff --git a/security/manager/ssl/tests/unit/test_sdr_preexisting.js b/security/manager/ssl/tests/unit/test_sdr_preexisting.js new file mode 100644 index 0000000000..69b5c194df --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sdr_preexisting.js @@ -0,0 +1,79 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// Tests that the SDR implementation is able to decrypt strings encrypted using +// a preexisting NSS key database. Creating the database is straight-forward: +// simply run Firefox (or xpcshell) and encrypt something using +// nsISecretDecoderRing (e.g. by saving a password or directly using the +// interface). The resulting key4.db file (in the profile directory) now +// contains the private key used to encrypt the data. + +function run_test() { + const keyDBName = "key4.db"; + let profile = do_get_profile(); + let keyDBFile = do_get_file(`test_sdr_preexisting/${keyDBName}`); + keyDBFile.copyTo(profile, keyDBName); + + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + let testcases = [ + // a full padding block + { + ciphertext: + "MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECGeDHwVfyFqzBBAYvqMq/kDMsrARVNdC1C8d", + plaintext: "password", + }, + // 7 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECCAzLDVmYG2/BAh3IoIsMmT8dQ==", + plaintext: "a", + }, + // 6 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECPN8zlZzn8FdBAiu2acpT8UHsg==", + plaintext: "bb", + }, + // 1 byte of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECD5px1eMKkJQBAgUPp35GlrDvQ==", + plaintext: "!seven!", + }, + // 2 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECMh0hLtKDyUdBAixw9UZsMt+vA==", + plaintext: "sixsix", + }, + // long plaintext requiring more than two blocks + { + ciphertext: + "MFoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECDRX1qi+/FX1BDATFIcIneQjvBuq3wdFxzllJt2VtUD69ACdOKAXH3eA87oHDvuHqOeCDwRy4UzoG5s=", + plaintext: "thisismuchlongerandsotakesupmultipleblocks", + }, + // this differs from the previous ciphertext by one bit and demonstrates + // that this implementation does not enforce message integrity + { + ciphertext: + "MFoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECDRX1qi+/FX1BDAbFIcIneQjvBuq3wdFxzllJt2VtUD69ACdOKAXH3eA87oHDvuHqOeCDwRy4UzoG5s=", + plaintext: "nnLbuwLRkhlongerandsotakesupmultipleblocks", + }, + ]; + + for (let testcase of testcases) { + let decrypted = sdr.decryptString(testcase.ciphertext); + equal( + decrypted, + testcase.plaintext, + "decrypted ciphertext should match expected plaintext" + ); + } +} diff --git a/security/manager/ssl/tests/unit/test_sdr_preexisting/key4.db b/security/manager/ssl/tests/unit/test_sdr_preexisting/key4.db new file mode 100644 index 0000000000..8f320dfdbd Binary files /dev/null and b/security/manager/ssl/tests/unit/test_sdr_preexisting/key4.db differ diff --git a/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password.js b/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password.js new file mode 100644 index 0000000000..8502d88a40 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password.js @@ -0,0 +1,138 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// Tests that the SDR implementation is able to decrypt strings encrypted using +// a preexisting NSS key database that has a password. +// To create such a database, run Firefox (or xpcshell), set a primary +// password, and then encrypt something using nsISecretDecoderRing. + +var gMockPrompter = { + passwordToTry: "password", + numPrompts: 0, + + // This intentionally does not use arrow function syntax to avoid an issue + // where in the context of the arrow function, |this != gMockPrompter| due to + // how objects get wrapped when going across xpcom boundaries. + promptPassword(dialogTitle, text, password, checkMsg, checkValue) { + this.numPrompts++; + if (this.numPrompts > 1) { + // don't keep retrying a bad password + return false; + } + equal( + text, + "Please enter your Primary Password.", + "password prompt text should be as expected" + ); + equal(checkMsg, null, "checkMsg should be null"); + ok(this.passwordToTry, "passwordToTry should be non-null"); + password.value = this.passwordToTry; + return true; + }, + + QueryInterface: ChromeUtils.generateQI(["nsIPrompt"]), +}; + +// Mock nsIWindowWatcher. PSM calls getNewPrompter on this to get an nsIPrompt +// to call promptPassword. We return the mock one, above. +var gWindowWatcher = { + getNewPrompter: () => gMockPrompter, + QueryInterface: ChromeUtils.generateQI(["nsIWindowWatcher"]), +}; + +function run_test() { + let windowWatcherCID = MockRegistrar.register( + "@mozilla.org/embedcomp/window-watcher;1", + gWindowWatcher + ); + registerCleanupFunction(() => { + MockRegistrar.unregister(windowWatcherCID); + }); + + // Append a single quote and non-ASCII characters to the profile path. + let env = Cc["@mozilla.org/process/environment;1"].getService( + Ci.nsIEnvironment + ); + let profd = env.get("XPCSHELL_TEST_PROFILE_DIR"); + let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsIFile); + file.initWithPath(profd); + file.append("'÷1"); + env.set("XPCSHELL_TEST_PROFILE_DIR", file.path); + + let profile = do_get_profile(); // must be called before getting nsIX509CertDB + Assert.ok( + /[^\x20-\x7f]/.test(profile.path), + "the profile path should contain a non-ASCII character" + ); + + let key4DBFile = do_get_file("test_sdr_preexisting_with_password/key4.db"); + key4DBFile.copyTo(profile, "key4.db"); + + let sdr = Cc["@mozilla.org/security/sdr;1"].getService( + Ci.nsISecretDecoderRing + ); + + let testcases = [ + // a full padding block + { + ciphertext: + "MDoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECGeDHwVfyFqzBBAYvqMq/kDMsrARVNdC1C8d", + plaintext: "password", + }, + // 7 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECCAzLDVmYG2/BAh3IoIsMmT8dQ==", + plaintext: "a", + }, + // 6 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECPN8zlZzn8FdBAiu2acpT8UHsg==", + plaintext: "bb", + }, + // 1 byte of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECD5px1eMKkJQBAgUPp35GlrDvQ==", + plaintext: "!seven!", + }, + // 2 bytes of padding + { + ciphertext: + "MDIEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECMh0hLtKDyUdBAixw9UZsMt+vA==", + plaintext: "sixsix", + }, + // long plaintext requiring more than two blocks + { + ciphertext: + "MFoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECDRX1qi+/FX1BDATFIcIneQjvBuq3wdFxzllJt2VtUD69ACdOKAXH3eA87oHDvuHqOeCDwRy4UzoG5s=", + plaintext: "thisismuchlongerandsotakesupmultipleblocks", + }, + // this differs from the previous ciphertext by one bit and demonstrates + // that this implementation does not enforce message integrity + { + ciphertext: + "MFoEEPgAAAAAAAAAAAAAAAAAAAEwFAYIKoZIhvcNAwcECDRX1qi+/FX1BDAbFIcIneQjvBuq3wdFxzllJt2VtUD69ACdOKAXH3eA87oHDvuHqOeCDwRy4UzoG5s=", + plaintext: "nnLbuwLRkhlongerandsotakesupmultipleblocks", + }, + ]; + + for (let testcase of testcases) { + let decrypted = sdr.decryptString(testcase.ciphertext); + equal( + decrypted, + testcase.plaintext, + "decrypted ciphertext should match expected plaintext" + ); + } + equal( + gMockPrompter.numPrompts, + 1, + "Should have been prompted for a password once" + ); +} diff --git a/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password/key4.db b/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password/key4.db new file mode 100644 index 0000000000..959718da34 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_sdr_preexisting_with_password/key4.db differ diff --git a/security/manager/ssl/tests/unit/test_self_signed_certs.js b/security/manager/ssl/tests/unit/test_self_signed_certs.js new file mode 100644 index 0000000000..662cd59714 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_self_signed_certs.js @@ -0,0 +1,69 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +// This test uses a specially-crafted NSS cert DB containing 12 self-signed certificates that all +// have the same subject and issuer distinguished name. Since they all have different keys and none +// of them are trust anchors, there are a large number of potential trust paths that could be +// explored. If our trust domain were naive enough to allow mozilla::pkix to explore them all, it +// would take a long time to perform (mozilla::pkix does have the concept of a path-building budget, +// but even on a fast computer, it takes an unacceptable amount of time to exhaust). To prevent the +// full exploration of this space, NSSCertDBTrustDomain skips searching through self-signed +// certificates that aren't trust anchors, since those would never otherwise be essential to +// complete a path (note that this is only true as long as the extensions we support are restrictive +// rather than additive). +// When we try to verify one of these certificates in this test, we should finish relatively +// quickly, even on slow hardware. +// Should these certificates ever need regenerating, they were produced with the following commands: +// certutil -N -d . --empty-password +// for num in 00 01 02 03 04 05 06 07 08 09 10 11; do +// echo -ne "5\n6\n9\ny\ny\n\ny\n" | certutil -d . -S -s "CN=self-signed cert" -t ,, \ +// -q secp256r1 -x -k ec -z <(date +%s) -1 -2 -n cert$num; sleep 2; +// done + +add_task(async function run_test_no_overlong_path_building() { + let profile = do_get_profile(); + const CERT_DB_NAME = "cert9.db"; + let srcCertDBFile = do_get_file(`test_self_signed_certs/${CERT_DB_NAME}`); + srcCertDBFile.copyTo(profile, CERT_DB_NAME); + + let certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB + ); + let certToVerify = null; + for (let cert of certDB.getCerts()) { + if (cert.subjectName == "CN=self-signed cert") { + certToVerify = cert; + break; + } + } + notEqual( + certToVerify, + null, + "should have found one of the preloaded self-signed certs" + ); + let timeBefore = Date.now(); + // As mentioned above, mozilla::pkix limits how much it will search for a trusted path, even if a + // trust domain keeps providing potential issuers. So, if we only tried to verify a certificate + // once, this test could potentially pass on a fast computer even if we weren't properly skipping + // unnecessary paths. If we were to try and lower our time limit (the comparison with + // secondsElapsed, below), this test would intermittently fail on slow hardware. By trying to + // verify the certificate 10 times, we hopefully end up with a meaningful test (it should still + // fail on fast hardware if we don't properly skip unproductive paths) that won't intermittently + // time out on slow hardware. + for (let i = 0; i < 10; i++) { + let date = new Date("2019-05-15T00:00:00.000Z"); + await checkCertErrorGenericAtTime( + certDB, + certToVerify, + SEC_ERROR_UNKNOWN_ISSUER, + certificateUsageSSLCA, + date.getTime() / 1000 + ); + } + let timeAfter = Date.now(); + let secondsElapsed = (timeAfter - timeBefore) / 1000; + ok(secondsElapsed < 120, "verifications shouldn't take too long"); +}); diff --git a/security/manager/ssl/tests/unit/test_self_signed_certs/cert9.db b/security/manager/ssl/tests/unit/test_self_signed_certs/cert9.db new file mode 100644 index 0000000000..5450fe82e5 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_self_signed_certs/cert9.db differ diff --git a/security/manager/ssl/tests/unit/test_session_resumption.js b/security/manager/ssl/tests/unit/test_session_resumption.js new file mode 100644 index 0000000000..eb8e1796b5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_session_resumption.js @@ -0,0 +1,298 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that PSM makes the correct determination of the security status of +// loads involving session resumption (i.e. when a TLS handshake bypasses the +// AuthCertificate callback). + +do_get_profile(); +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.OCSP.enabled"); + Services.prefs.clearUserPref("network.ssl_tokens_cache_enabled"); +}); + +Services.prefs.setIntPref("security.OCSP.enabled", 1); + +addCertFromFile(certdb, "bad_certs/evroot.pem", "CTu,,"); +addCertFromFile(certdb, "bad_certs/ev-test-intermediate.pem", ",,"); + +// For expired.example.com, the platform will make a connection that will fail. +// Using information gathered at that point, an override will be added and +// another connection will be made. This connection will succeed. At that point, +// as long as the session cache isn't cleared, subsequent new connections should +// use session resumption, thereby bypassing the AuthCertificate hook. We need +// to ensure that the correct security state is propagated to the new connection +// information object. +function add_resume_non_ev_with_override_test() { + // This adds the override and makes one successful connection. + add_cert_override_test( + "expired.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_EXPIRED_CERTIFICATE + ); + + // This connects again, using session resumption. Note that we don't clear + // the TLS session cache between these operations (that would defeat the + // purpose). + add_connection_test( + "expired.example.com", + PRErrorCodeSuccess, + null, + transportSecurityInfo => { + ok( + transportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN, + "expired.example.com should have STATE_CERT_USER_OVERRIDDEN flag" + ); + equal( + transportSecurityInfo.succeededCertChain.length, + 0, + "ev-test.example.com should not have succeededCertChain set" + ); + ok( + !transportSecurityInfo.isDomainMismatch, + "expired.example.com should not have isDomainMismatch set" + ); + ok( + transportSecurityInfo.isNotValidAtThisTime, + "expired.example.com should have isNotValidAtThisTime set" + ); + ok( + !transportSecurityInfo.isUntrusted, + "expired.example.com should not have isUntrusted set" + ); + ok( + !transportSecurityInfo.isExtendedValidation, + "expired.example.com should not have isExtendedValidation set" + ); + + let certOverrideService = Cc[ + "@mozilla.org/security/certoverride;1" + ].getService(Ci.nsICertOverrideService); + certOverrideService.clearValidityOverride("expired.example.com", 8443); + } + ); +} + +// Helper function that adds a test that connects to ev-test.example.com and +// verifies that it validates as EV (or not, if we're running a non-debug +// build). This assumes that an appropriate OCSP responder is running or that +// good responses are cached. +function add_one_ev_test() { + add_connection_test( + "ev-test.example.com", + PRErrorCodeSuccess, + null, + transportSecurityInfo => { + ok( + !( + transportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN + ), + "ev-test.example.com should not have STATE_CERT_USER_OVERRIDDEN flag" + ); + ok( + transportSecurityInfo.succeededCertChain, + "ev-test.example.com should have succeededCertChain set" + ); + ok( + !transportSecurityInfo.isDomainMismatch, + "ev-test.example.com should not have isDomainMismatch set" + ); + ok( + !transportSecurityInfo.isNotValidAtThisTime, + "ev-test.example.com should not have isNotValidAtThisTime set" + ); + ok( + !transportSecurityInfo.isUntrusted, + "ev-test.example.com should not have isUntrusted set" + ); + ok( + !gEVExpected || transportSecurityInfo.isExtendedValidation, + "ev-test.example.com should have isExtendedValidation set " + + "(or this is a non-debug build)" + ); + } + ); +} + +// This test is similar, except with extended validation. We should connect +// successfully, and the certificate should be EV in debug builds. Without +// clearing the session cache, we should connect successfully again, this time +// with session resumption. The certificate should again be EV in debug builds. +function add_resume_ev_test() { + const SERVER_PORT = 8888; + let expectedRequestPaths = gEVExpected + ? ["ev-test-intermediate", "ev-test"] + : ["ev-test"]; + let responseTypes = gEVExpected ? ["good", "good"] : ["good"]; + // Since we cache OCSP responses, we only ever actually serve one set. + let ocspResponder; + // If we don't wrap this in an `add_test`, the OCSP responder will be running + // while we are actually running unrelated testcases, which can disrupt them. + add_test(() => { + ocspResponder = startOCSPResponder( + SERVER_PORT, + "localhost", + "bad_certs", + expectedRequestPaths, + expectedRequestPaths.slice(), + null, + responseTypes + ); + run_next_test(); + }); + // We should be able to connect and verify the certificate as EV (in debug + // builds). + add_one_ev_test(); + // We should be able to connect again (using session resumption). In debug + // builds, the certificate should be noted as EV. Again, it's important that + // nothing clears the TLS cache in between these two operations. + add_one_ev_test(); + + add_test(() => { + ocspResponder.stop(run_next_test); + }); +} + +const GOOD_DOMAIN = "good.include-subdomains.pinning.example.com"; + +// Helper function that adds a test that connects to a domain that should +// succeed (but isn't EV) and verifies that its succeededCertChain gets set +// appropriately. +function add_one_non_ev_test() { + add_connection_test( + GOOD_DOMAIN, + PRErrorCodeSuccess, + null, + transportSecurityInfo => { + ok( + !( + transportSecurityInfo.securityState & + Ci.nsIWebProgressListener.STATE_CERT_USER_OVERRIDDEN + ), + `${GOOD_DOMAIN} should not have STATE_CERT_USER_OVERRIDDEN flag` + ); + ok( + transportSecurityInfo.succeededCertChain, + `${GOOD_DOMAIN} should have succeededCertChain set` + ); + ok( + !transportSecurityInfo.isDomainMismatch, + `${GOOD_DOMAIN} should not have isDomainMismatch set` + ); + ok( + !transportSecurityInfo.isNotValidAtThisTime, + `${GOOD_DOMAIN} should not have isNotValidAtThisTime set` + ); + ok( + !transportSecurityInfo.isUntrusted, + `${GOOD_DOMAIN} should not have isUntrusted set` + ); + ok( + !transportSecurityInfo.isExtendedValidation, + `${GOOD_DOMAIN} should not have isExtendedValidation set` + ); + } + ); +} + +// This test is similar, except with non-extended validation. We should connect +// successfully, and the certificate should not be EV. Without clearing the +// session cache, we should connect successfully again, this time with session +// resumption. In this case, though, we want to ensure the succeededCertChain is +// set. +function add_resume_non_ev_test() { + add_one_non_ev_test(); + add_one_non_ev_test(); +} + +const statsPtr = getSSLStatistics(); +const toInt32 = ctypes.Int64.lo; + +// Connect to the same domain with two origin attributes and check if any ssl +// session is resumed. +function add_origin_attributes_test( + originAttributes1, + originAttributes2, + resumeExpected +) { + add_connection_test( + GOOD_DOMAIN, + PRErrorCodeSuccess, + clearSessionCache, + null, + null, + originAttributes1 + ); + + let hitsBeforeConnect; + let missesBeforeConnect; + let expectedHits = resumeExpected ? 1 : 0; + let expectedMisses = 1 - expectedHits; + + add_connection_test( + GOOD_DOMAIN, + PRErrorCodeSuccess, + function() { + // Add the hits and misses before connection. + let stats = statsPtr.contents; + hitsBeforeConnect = toInt32(stats.sch_sid_cache_hits); + missesBeforeConnect = toInt32(stats.sch_sid_cache_misses); + }, + function() { + let stats = statsPtr.contents; + equal( + toInt32(stats.sch_sid_cache_hits), + hitsBeforeConnect + expectedHits, + "Unexpected cache hits" + ); + equal( + toInt32(stats.sch_sid_cache_misses), + missesBeforeConnect + expectedMisses, + "Unexpected cache misses" + ); + }, + null, + originAttributes2 + ); +} + +function add_resumption_tests() { + add_resume_ev_test(); + add_resume_non_ev_test(); + add_resume_non_ev_with_override_test(); + add_origin_attributes_test({}, {}, true); + add_origin_attributes_test({ userContextId: 1 }, { userContextId: 2 }, false); + add_origin_attributes_test({ userContextId: 3 }, { userContextId: 3 }, true); + add_origin_attributes_test( + { firstPartyDomain: "foo.com" }, + { firstPartyDomain: "bar.com" }, + false + ); + add_origin_attributes_test( + { firstPartyDomain: "baz.com" }, + { firstPartyDomain: "baz.com" }, + true + ); +} + +function run_test() { + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + add_resumption_tests(); + // Enable external session cache and reset the status. + add_test(function() { + Services.prefs.setBoolPref("network.ssl_tokens_cache_enabled", true); + certdb.clearOCSPCache(); + run_next_test(); + }); + // Do tests again. + add_resumption_tests(); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_signed_apps.js b/security/manager/ssl/tests/unit/test_signed_apps.js new file mode 100644 index 0000000000..13f9a995fa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps.js @@ -0,0 +1,1013 @@ +"use strict"; + +// Tests the API nsIX509CertDB.openSignedAppFileAsync, which backs add-on +// signature verification. Testcases include various ways of tampering with +// add-ons as well as different hash algorithms used in the various +// signature/metadata files. + +// from prio.h +const PR_RDWR = 0x04; +const PR_CREATE_FILE = 0x08; +const PR_TRUNCATE = 0x20; +const PR_USEC_PER_MSEC = 1000; + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +// Creates a new app package based in the inFilePath package, with a set of +// modifications (including possibly deletions) applied to the existing entries, +// and/or a set of new entries to be included. +function tamper(inFilePath, outFilePath, modifications, newEntries) { + let writer = Cc["@mozilla.org/zipwriter;1"].createInstance(Ci.nsIZipWriter); + writer.open(outFilePath, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE); + try { + let reader = Cc["@mozilla.org/libjar/zip-reader;1"].createInstance( + Ci.nsIZipReader + ); + reader.open(inFilePath); + try { + for (let entryName of reader.findEntries("")) { + let inEntry = reader.getEntry(entryName); + let entryInput = reader.getInputStream(entryName); + try { + let f = modifications[entryName]; + let outEntry, outEntryInput; + if (f) { + [outEntry, outEntryInput] = f(inEntry, entryInput); + delete modifications[entryName]; + } else { + [outEntry, outEntryInput] = [inEntry, entryInput]; + } + // if f does not want the input entry to be copied to the output entry + // at all (i.e. it wants it to be deleted), it will return null. + if (outEntryInput) { + try { + writer.addEntryStream( + entryName, + outEntry.lastModifiedTime, + outEntry.compression, + outEntryInput, + false + ); + } finally { + if (entryInput != outEntryInput) { + outEntryInput.close(); + } + } + } + } finally { + entryInput.close(); + } + } + } finally { + reader.close(); + } + + // Any leftover modification means that we were expecting to modify an entry + // in the input file that wasn't there. + for (let name in modifications) { + if (modifications.hasOwnProperty(name)) { + throw new Error("input file was missing expected entries: " + name); + } + } + + // Now, append any new entries to the end + newEntries.forEach(function(newEntry) { + let sis = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + try { + sis.setData(newEntry.content, newEntry.content.length); + writer.addEntryStream( + newEntry.name, + new Date() * PR_USEC_PER_MSEC, + Ci.nsIZipWriter.COMPRESSION_BEST, + sis, + false + ); + } finally { + sis.close(); + } + }); + } finally { + writer.close(); + } +} + +function removeEntry(entry, entryInput) { + return [null, null]; +} + +function truncateEntry(entry, entryInput) { + if (entryInput.available() == 0) { + throw new Error( + "Truncating already-zero length entry will result in " + + "identical entry." + ); + } + + let content = Cc["@mozilla.org/io/string-input-stream;1"].createInstance( + Ci.nsIStringInputStream + ); + content.data = ""; + + return [entry, content]; +} + +function check_open_result(name, expectedRv) { + return function openSignedAppFileCallback(rv, aZipReader, aSignerCert) { + info("openSignedAppFileCallback called for " + name); + equal(rv, expectedRv, "Actual and expected return value should match"); + equal( + aZipReader != null, + Components.isSuccessCode(expectedRv), + "ZIP reader should be null only if the return value denotes failure" + ); + equal( + aSignerCert != null, + Components.isSuccessCode(expectedRv), + "Signer cert should be null only if the return value denotes failure" + ); + run_next_test(); + }; +} + +function original_app_path(test_name) { + return do_get_file("test_signed_apps/" + test_name + ".zip", false); +} + +function tampered_app_path(test_name) { + return FileUtils.getFile("TmpD", ["test_signed_app-" + test_name + ".zip"]); +} + +var hashTestcases = [ + // SHA-256 in PKCS#7 + SHA-256 present elsewhere => OK + { name: "app_mf-1-256_sf-1-256_p7-1-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-1-256_sf-1-256_p7-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-1-256_sf-256_p7-1-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-1-256_sf-256_p7-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-256_sf-1-256_p7-1-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-256_sf-1-256_p7-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-256_sf-256_p7-1-256", expectedResult: Cr.NS_OK }, + { name: "app_mf-256_sf-256_p7-256", expectedResult: Cr.NS_OK }, + + // SHA-1 in PKCS#7 + SHA-1 present elsewhere => OK + { name: "app_mf-1-256_sf-1-256_p7-1", expectedResult: Cr.NS_OK }, + { name: "app_mf-1-256_sf-1_p7-1", expectedResult: Cr.NS_OK }, + { name: "app_mf-1_sf-1-256_p7-1", expectedResult: Cr.NS_OK }, + { name: "app_mf-1_sf-1_p7-1", expectedResult: Cr.NS_OK }, + + // SHA-256 in PKCS#7 + SHA-256 not present elsewhere => INVALID + { + name: "app_mf-1-256_sf-1_p7-1-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1-256_sf-1_p7-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-1-256_p7-1-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-1-256_p7-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-1_p7-1-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-1_p7-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-256_p7-1-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-256_p7-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-256_sf-1_p7-1-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-256_sf-1_p7-256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + + // SHA-1 in PKCS#7 + SHA-1 not present elsewhere => INVALID + { + name: "app_mf-1-256_sf-256_p7-1", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-1_sf-256_p7-1", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-256_sf-1-256_p7-1", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-256_sf-1_p7-1", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, + { + name: "app_mf-256_sf-256_p7-1", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + }, +]; + +// Policy values for the preference "security.signed_app_signatures.policy" +const PKCS7WithSHA1OrSHA256 = 0b0; +const PKCS7WithSHA256 = 0b1; +const COSEAndPKCS7WithSHA1OrSHA256 = 0b10; +const COSEAndPKCS7WithSHA256 = 0b11; +const COSERequiredAndPKCS7WithSHA1OrSHA256 = 0b100; +const COSERequiredAndPKCS7WithSHA256 = 0b101; +const COSEOnly = 0b110; +const COSEOnlyAgain = 0b111; + +function add_signature_test(policy, test) { + // First queue up a test to set the desired policy: + add_test(function() { + Services.prefs.setIntPref("security.signed_app_signatures.policy", policy); + run_next_test(); + }); + // Then queue up the test itself: + add_test(test); +} + +for (let testcase of hashTestcases) { + add_signature_test(PKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path(testcase.name), + check_open_result(testcase.name, testcase.expectedResult) + ); + }); +} + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("empty_signerInfos"), + check_open_result( + "the signerInfos in the PKCS#7 signature is empty", + Cr.NS_ERROR_CMS_VERIFY_NOT_SIGNED + ) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("unsigned_app"), + check_open_result("unsigned", Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("unknown_issuer_app"), + check_open_result( + "unknown_issuer", + getXPCOMStatusFromNSS(SEC_ERROR_UNKNOWN_ISSUER) + ) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_signed_with_pkcs7"), + check_open_result("cose_signed_with_pkcs7", Cr.NS_OK) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-256_sf-256_p7-256"), + check_open_result("no COSE but correct PK#7", Cr.NS_OK) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-1_sf-256_p7-256"), + check_open_result( + "no COSE and wrong PK#7 hash", + Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID + ) + ); +}); + +add_signature_test(COSERequiredAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-256_sf-256_p7-256"), + check_open_result( + "COSE signature missing (SHA1 or 256)", + Cr.NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE + ) + ); +}); + +add_signature_test(COSERequiredAndPKCS7WithSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-256_sf-256_p7-256"), + check_open_result( + "COSE signature missing (SHA256)", + Cr.NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE + ) + ); +}); + +add_signature_test(COSERequiredAndPKCS7WithSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_signed"), + check_open_result( + "COSE signature only (PK#7 allowed, not present)", + Cr.NS_OK + ) + ); +}); + +add_signature_test(COSERequiredAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_signed"), + check_open_result( + "COSE signature only (PK#7 allowed, not present)", + Cr.NS_OK + ) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_multiple_signed_with_pkcs7"), + check_open_result("cose_multiple_signed_with_pkcs7", Cr.NS_OK) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_int_signed_with_pkcs7"), + check_open_result("COSE signed with an intermediate", Cr.NS_OK) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_signed"), + check_open_result( + "PK7 signature missing", + Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED + ) + ); +}); + +add_signature_test(COSEOnly, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_multiple_signed_with_pkcs7"), + check_open_result( + "Expected only COSE signature", + Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY + ) + ); +}); + +add_signature_test(COSEOnly, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_multiple_signed"), + check_open_result("only Multiple COSE signatures", Cr.NS_OK) + ); +}); + +add_signature_test(COSEOnly, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_signed"), + check_open_result("only_cose_signed", Cr.NS_OK) + ); +}); + +add_signature_test(COSEOnlyAgain, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("only_cose_signed"), + check_open_result("only_cose_signed (again)", Cr.NS_OK) + ); +}); + +add_signature_test(COSEOnly, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_signed_with_pkcs7"), + check_open_result( + "COSE only expected but also PK#7 signed", + Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY + ) + ); +}); + +// Sanity check to ensure a no-op tampering gives a valid result +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("identity_tampering"); + tamper(original_app_path("app_mf-1_sf-1_p7-1"), tampered, {}, []); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-1_sf-1_p7-1"), + check_open_result("identity_tampering", Cr.NS_OK) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("missing_rsa"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/A.RSA": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("missing_rsa", Cr.NS_ERROR_SIGNED_JAR_NOT_SIGNED) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("missing_sf"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/A.SF": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("missing_sf", Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("missing_manifest_mf"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/MANIFEST.MF": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "missing_manifest_mf", + Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID + ) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("missing_entry"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "manifest.json": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("missing_entry", Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("truncated_entry"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "manifest.json": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("truncated_entry", Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("truncated_manifestFile"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/MANIFEST.MF": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "truncated_manifestFile", + Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID + ) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("truncated_signatureFile"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/A.SF": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "truncated_signatureFile", + getXPCOMStatusFromNSS(SEC_ERROR_PKCS7_BAD_SIGNATURE) + ) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("truncated_pkcs7File"); + tamper( + original_app_path("app_mf-1_sf-1_p7-1"), + tampered, + { "META-INF/A.RSA": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("truncated_pkcs7File", Cr.NS_ERROR_CMS_VERIFY_NOT_SIGNED) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("unsigned_entry"); + tamper(original_app_path("app_mf-1_sf-1_p7-1"), tampered, {}, [ + { name: "unsigned.txt", content: "unsigned content!" }, + ]); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("unsigned_entry", Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY) + ); +}); + +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + let tampered = tampered_app_path("unsigned_metainf_entry"); + tamper(original_app_path("app_mf-1_sf-1_p7-1"), tampered, {}, [ + { name: "META-INF/unsigned.txt", content: "unsigned content!" }, + ]); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "unsigned_metainf_entry", + Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY + ) + ); +}); + +add_signature_test(PKCS7WithSHA256, function testSHA1Disabled() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-1_sf-1_p7-1"), + check_open_result( + "SHA-1 should not be accepted if disabled by policy", + Cr.NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE + ) + ); +}); + +add_signature_test(PKCS7WithSHA256, function testSHA256WorksWithSHA1Disabled() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-256_sf-256_p7-256"), + check_open_result( + "SHA-256 should work if SHA-1 is disabled by policy", + Cr.NS_OK + ) + ); +}); + +add_signature_test( + PKCS7WithSHA256, + function testMultipleSignaturesWorkWithSHA1Disabled() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("app_mf-1-256_sf-1-256_p7-1-256"), + check_open_result( + "Multiple signatures should work if SHA-1 is " + + "disabled by policy (if SHA-256 signature verifies)", + Cr.NS_OK + ) + ); + } +); + +var cosePolicies = [ + COSEAndPKCS7WithSHA1OrSHA256, + COSERequiredAndPKCS7WithSHA1OrSHA256, +]; + +// PS256 is not yet supported. +var coseTestcasesStage = [ + { + name: "autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-ES384", + expectedResult: Cr.NS_OK, + root: Ci.nsIX509CertDB.AddonsStageRoot, + }, + { + name: "autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-PS256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + root: Ci.nsIX509CertDB.AddonsStageRoot, + }, + { + name: "autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256", + expectedResult: Cr.NS_OK, + root: Ci.nsIX509CertDB.AddonsStageRoot, + }, + { + name: "autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-PS256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + root: Ci.nsIX509CertDB.AddonsStageRoot, + }, +]; + +var coseTestcasesProd = [ + { + name: "autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-ES384", + expectedResult: Cr.NS_OK, + root: Ci.nsIX509CertDB.AddonsPublicRoot, + }, + { + name: "autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-PS256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + root: Ci.nsIX509CertDB.AddonsPublicRoot, + }, + { + name: "autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256", + expectedResult: Cr.NS_OK, + root: Ci.nsIX509CertDB.AddonsPublicRoot, + }, + { + name: "autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-PS256", + expectedResult: Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID, + root: Ci.nsIX509CertDB.AddonsPublicRoot, + }, +]; + +for (let policy of cosePolicies) { + for (let testcase of coseTestcasesStage) { + add_signature_test(policy, function() { + certdb.openSignedAppFileAsync( + testcase.root, + original_app_path(testcase.name), + check_open_result(testcase.name, testcase.expectedResult) + ); + }); + } +} + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSESigTampered() { + let tampered = tampered_app_path("cose_sig_tampered"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "META-INF/cose.sig": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "cose_sig_tampered", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +// PKCS7 is processed before COSE, so if a COSE signature file is removed or +// tampered with, this appears as a PKCS7 signature verification failure. +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSESigRemoved() { + let tampered = tampered_app_path("cose_sig_removed"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "META-INF/cose.sig": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("cose_sig_removed", Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSEManifestTampered() { + let tampered = tampered_app_path("cose_manifest_tampered"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "META-INF/cose.manifest": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "cose_manifest_tampered", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSEManifestRemoved() { + let tampered = tampered_app_path("cose_manifest_removed"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "META-INF/cose.manifest": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "cose_manifest_removed", + Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING + ) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSEFileAdded() { + let tampered = tampered_app_path("cose_file_added"); + tamper(original_app_path("cose_signed_with_pkcs7"), tampered, {}, [ + { name: "unsigned.txt", content: "unsigned content!" }, + ]); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("cose_file_added", Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSEFileRemoved() { + let tampered = tampered_app_path("cose_file_removed"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "manifest.json": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result("cose_file_removed", Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING) + ); +}); + +add_signature_test(COSEAndPKCS7WithSHA256, function testCOSEFileTampered() { + let tampered = tampered_app_path("cose_file_tampered"); + tamper( + original_app_path("cose_signed_with_pkcs7"), + tampered, + { "manifest.json": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "cose_file_tampered", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSESigTampered() { + let tampered = tampered_app_path("only_cose_sig_tampered"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "META-INF/cose.sig": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_sig_tampered", + Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSESigRemoved() { + let tampered = tampered_app_path("only_cose_sig_removed"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "META-INF/cose.sig": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_sig_removed", + Cr.NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSEManifestTampered() { + let tampered = tampered_app_path("only_cose_manifest_tampered"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "META-INF/cose.manifest": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_manifest_tampered", + Cr.NS_ERROR_SIGNED_JAR_MANIFEST_INVALID + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSEManifestRemoved() { + let tampered = tampered_app_path("only_cose_manifest_removed"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "META-INF/cose.manifest": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_manifest_removed", + Cr.NS_ERROR_SIGNED_JAR_WRONG_SIGNATURE + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSEFileAdded() { + let tampered = tampered_app_path("only_cose_file_added"); + tamper(original_app_path("only_cose_signed"), tampered, {}, [ + { name: "unsigned.txt", content: "unsigned content!" }, + ]); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_file_added", + Cr.NS_ERROR_SIGNED_JAR_UNSIGNED_ENTRY + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSEFileRemoved() { + let tampered = tampered_app_path("only_cose_file_removed"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "manifest.json": removeEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_file_removed", + Cr.NS_ERROR_SIGNED_JAR_ENTRY_MISSING + ) + ); +}); + +add_signature_test(COSEOnly, function testOnlyCOSEFileTampered() { + let tampered = tampered_app_path("only_cose_file_tampered"); + tamper( + original_app_path("only_cose_signed"), + tampered, + { "manifest.json": truncateEntry }, + [] + ); + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + tampered, + check_open_result( + "only_cose_file_tampered", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +// This was signed with only COSE first, and then the contents were tampered +// with (making the signature invalid). Then, the file was signed with +// PKCS7/SHA1. We need to ensure that if we're configured to process COSE, this +// verification fails. +add_signature_test(COSEAndPKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_tampered_good_pkcs7"), + check_open_result( + "tampered COSE with good PKCS7 signature should fail " + + "when COSE and PKCS7 is processed", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +add_signature_test(COSEOnly, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_tampered_good_pkcs7"), + check_open_result( + "tampered COSE with good PKCS7 signature should fail " + + "when only COSE is processed", + Cr.NS_ERROR_SIGNED_JAR_MODIFIED_ENTRY + ) + ); +}); + +// If we're not processing COSE, this should verify successfully. +add_signature_test(PKCS7WithSHA1OrSHA256, function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("cose_tampered_good_pkcs7"), + check_open_result( + "tampered COSE with good PKCS7 signature should succeed" + + "when COSE is not processed", + Cr.NS_OK + ) + ); +}); + +add_test(function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("bug_1411458"), + check_open_result("bug 1411458", Cr.NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO) + ); +}); + +// This has a big manifest file (~2MB). It should verify correctly. +add_test(function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("big_manifest"), + check_open_result("add-on with big manifest file", Cr.NS_OK) + ); +}); + +// This has a huge manifest file (~10MB). Manifest files this large are not +// supported (8MB is the limit). It should not verify correctly. +add_test(function() { + certdb.openSignedAppFileAsync( + Ci.nsIX509CertDB.AppXPCShellRoot, + original_app_path("huge_manifest"), + check_open_result( + "add-on with huge manifest file", + Cr.NS_ERROR_SIGNED_JAR_ENTRY_INVALID + ) + ); +}); + +// TODO: tampered MF, tampered SF +// TODO: too-large MF, too-large RSA, too-large SF +// TODO: MF and SF that end immediately after the last main header +// (no CR nor LF) +// TODO: broken headers to exercise the parser diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app/README b/security/manager/ssl/tests/unit/test_signed_apps/app/README new file mode 100644 index 0000000000..4f4db4f73e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app/README @@ -0,0 +1 @@ +This is the readme for the test extension. diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app/data/image.png b/security/manager/ssl/tests/unit/test_signed_apps/app/data/image.png new file mode 100644 index 0000000000..f4a62faddf Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app/data/image.png differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app/manifest.json b/security/manager/ssl/tests/unit/test_signed_apps/app/manifest.json new file mode 100644 index 0000000000..eacaedfa7a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app/manifest.json @@ -0,0 +1,5 @@ +{ + "manifest_version": 2, + "name": "Test Extension", + "version": "0.0.1" +} diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.manifest b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.manifest new file mode 100644 index 0000000000..be5069f57b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.manifest @@ -0,0 +1,10 @@ +Manifest-Version: 1.0 + +Name: README +SHA256-Digest: bY0l9xqGJYCpqYeJ0K6q4DWUQqu0mNBFM4H4emhjiJg= + +Name: manifest.json +SHA256-Digest: BTnCpT154N26RZm8bhdD43WXd0tj5bg6ofM19NLI0OE= + +Name: data/image.png +SHA256-Digest: EPjkNZwya9X+pruLlxG+FACLwGC48XU4S9oZOA0lVVQ= diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.sig b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.sig new file mode 100644 index 0000000000..ee9f3e2ce9 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/META-INF/cose.sig differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/README b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/README new file mode 100644 index 0000000000..46217087d8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/README @@ -0,0 +1,2 @@ +This is the readme for the test extension. +This app was created by unzipping only_cose_signed.zip and adding this line (thus invalidating the COSE signature). diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/data/image.png b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/data/image.png new file mode 100644 index 0000000000..f4a62faddf Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/data/image.png differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/manifest.json b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/manifest.json new file mode 100644 index 0000000000..eacaedfa7a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/app_cose_tampered/manifest.json @@ -0,0 +1,5 @@ +{ + "manifest_version": 2, + "name": "Test Extension", + "version": "0.0.1" +} diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1-256.zip new file mode 100644 index 0000000000..47c40c6bd5 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1.zip new file mode 100644 index 0000000000..1420cd5579 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-1.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-256.zip new file mode 100644 index 0000000000..669b4d8a8b Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1-256_p7-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1-256.zip new file mode 100644 index 0000000000..f39b297300 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1.zip new file mode 100644 index 0000000000..710dc42788 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-1.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-256.zip new file mode 100644 index 0000000000..001b80177f Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-1_p7-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1-256.zip new file mode 100644 index 0000000000..b529044fcc Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1.zip new file mode 100644 index 0000000000..cdb365ae9c Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-1.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-256.zip new file mode 100644 index 0000000000..0e9eb538ec Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1-256_sf-256_p7-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1-256.zip new file mode 100644 index 0000000000..c94f001690 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1.zip new file mode 100644 index 0000000000..30c1a2f4c5 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-1.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-256.zip new file mode 100644 index 0000000000..20a6236356 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1-256_p7-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1-256.zip new file mode 100644 index 0000000000..6570b1afb2 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1.zip new file mode 100644 index 0000000000..413bcba3ef Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-1.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-256.zip new file mode 100644 index 0000000000..31a481c954 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-1_p7-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1-256.zip new file mode 100644 index 0000000000..850917b843 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1.zip new file mode 100644 index 0000000000..9b17b3b736 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-1.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-256.zip new file mode 100644 index 0000000000..9c2c8a6b8a Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-1_sf-256_p7-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1-256.zip new file mode 100644 index 0000000000..5795fe4f3d Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1.zip new file mode 100644 index 0000000000..3436f161ab Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-1.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-256.zip new file mode 100644 index 0000000000..d9f3fa9fca Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1-256_p7-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1-256.zip new file mode 100644 index 0000000000..8000501fd6 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1.zip new file mode 100644 index 0000000000..7c6f9bcbfa Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-1.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-256.zip new file mode 100644 index 0000000000..8a4509c112 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-1_p7-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1-256.zip new file mode 100644 index 0000000000..adc6ecf26c Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1.zip new file mode 100644 index 0000000000..abeaa61a81 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-1.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-256.zip b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-256.zip new file mode 100644 index 0000000000..3b90736b24 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/app_mf-256_sf-256_p7-256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-ES384.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-ES384.zip new file mode 100644 index 0000000000..40b4fc7857 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-ES384.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-PS256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-PS256.zip new file mode 100644 index 0000000000..d364e590e5 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256-PS256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256.zip new file mode 100644 index 0000000000..a4353bba19 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-ES256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-PS256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-PS256.zip new file mode 100644 index 0000000000..51ae592ee9 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-prod-tomato-clock-PKCS7-SHA1-PS256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-ES384.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-ES384.zip new file mode 100644 index 0000000000..b74e087620 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-ES384.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-PS256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-PS256.zip new file mode 100644 index 0000000000..772c42e494 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256-PS256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256.zip new file mode 100644 index 0000000000..b1d1999551 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-ES256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-PS256.zip b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-PS256.zip new file mode 100644 index 0000000000..0ce563680d Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/autograph-714ba248-stage-tomato-clock-PKCS7-SHA1-PS256.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/big_manifest.zip b/security/manager/ssl/tests/unit/test_signed_apps/big_manifest.zip new file mode 100644 index 0000000000..7a0ec4698c Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/big_manifest.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/bug_1411458.zip b/security/manager/ssl/tests/unit/test_signed_apps/bug_1411458.zip new file mode 100644 index 0000000000..0b296945ab Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/bug_1411458.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/cose_int_signed_with_pkcs7.zip b/security/manager/ssl/tests/unit/test_signed_apps/cose_int_signed_with_pkcs7.zip new file mode 100644 index 0000000000..d1fa6a7356 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/cose_int_signed_with_pkcs7.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/cose_multiple_signed_with_pkcs7.zip b/security/manager/ssl/tests/unit/test_signed_apps/cose_multiple_signed_with_pkcs7.zip new file mode 100644 index 0000000000..afd449fcb5 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/cose_multiple_signed_with_pkcs7.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/cose_signed_with_pkcs7.zip b/security/manager/ssl/tests/unit/test_signed_apps/cose_signed_with_pkcs7.zip new file mode 100644 index 0000000000..a1c3175e4f Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/cose_signed_with_pkcs7.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/cose_tampered_good_pkcs7.zip b/security/manager/ssl/tests/unit/test_signed_apps/cose_tampered_good_pkcs7.zip new file mode 100644 index 0000000000..bedc6a9c1a Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/cose_tampered_good_pkcs7.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/empty_signerInfos.zip b/security/manager/ssl/tests/unit/test_signed_apps/empty_signerInfos.zip new file mode 100644 index 0000000000..7a7432596b Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/empty_signerInfos.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/huge_manifest.zip b/security/manager/ssl/tests/unit/test_signed_apps/huge_manifest.zip new file mode 100644 index 0000000000..af2573abf7 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/huge_manifest.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/moz.build b/security/manager/ssl/tests/unit/test_signed_apps/moz.build new file mode 100644 index 0000000000..5d50d06e11 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/moz.build @@ -0,0 +1,72 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + + +@template +def SignedAppFile(name, flags, app_directory="app/"): + if not CONFIG["COMPILE_ENVIRONMENT"]: + return + + GENERATED_FILES += [name] + props = GENERATED_FILES[name] + props.script = "/security/manager/ssl/tests/unit/sign_app.py" + props.inputs = [app_directory] + props.flags = flags + # Turn RELATIVEDIR into list entry: like + # 'security/manager/ssl/tests/unit/test_signed_apps' -> + # TEST_HARNESS_FILES.xpcshell.security.manager.ssl.tests.unit.test_signed_apps. + files = TEST_HARNESS_FILES.xpcshell + for part in RELATIVEDIR.split("/"): + files = files[part] + files += ["!%s" % name] + + +# Except for unusual testcases (unknown issuer, unsigned app, empty +# signerInfos), the naming scheme is as follows: +# app_mf{-1,-256}_sf{-1,-256}_p7{-1,-256}.zip, where: +# "mf" refers to the manifest file, "sf" refers to the signature file, +# and "p7" refers to the pkcs#7 file. The "{-1,-256}" indicates which +# hash algorithms are present in the corresponding file (both may be +# present). +# For example, "app_mf-1_sf-1-256_p7-256.zip" means that the manifest +# file has sha-1 hashes, the signature file has sha-1 hashes and sha-256 +# hashes, and the pkcs#7 file only has sha-256. +# +# Temporarily disabled. See bug 1256495. +# signed_app_files = ( +# ['unknown_issuer_app.zip', '-i', 'unknown issuer', '-p', 'sha256'], +# ['unsigned_app.zip'], +# ['empty_signerInfos.zip', '-e'], +# ) +# +# for signed_app_file_params in signed_app_files: +# SignedAppFile(signed_app_file_params[0], signed_app_file_params[1:]) +# +# for mf_algs in [['1'], ['256'], ['1', '256']]: +# for sf_algs in [['1'], ['256'], ['1', '256']]: +# for p7_algs in [['1'], ['256'], ['1', '256']]: +# filename = "app_mf-%s_sf-%s_p7-%s.zip" % ('-'.join(mf_algs), '-'.join(sf_algs), '-'.join(p7_algs)) +# args = [] +# for mf_alg in mf_algs: +# args.append('-m') +# args.append('sha%s' % mf_alg) +# for sf_alg in sf_algs: +# args.append('-s') +# args.append('sha%s' % sf_alg) +# for p7_alg in p7_algs: +# args.append('-p') +# args.append('sha%s' % p7_alg) +# SignedAppFile(filename, args) +# +# COSE test-cases +# SignedAppFile('cose_signed_with_pkcs7.zip', ['-c', 'ES256', '-p', 'sha256']) +# SignedAppFile('cose_int_signed_with_pkcs7.zip', ['-c', 'ES256', '-r', 'xpcshell signed apps test root', '-p', 'sha256']) +# SignedAppFile('cose_multiple_signed_with_pkcs7.zip', ['-c', 'ES256', '-c', 'ES384', '-p', 'sha256']) +# SignedAppFile('only_cose_signed.zip', ['-c', 'ES256']) +# SignedAppFile('only_cose_multiple_signed.zip', ['-c', 'ES384', '-c', 'ES256']) +# SignedAppFile('cose_tampered_good_pkcs7.zip', ['-m', 'sha1', '-s', 'sha1', '-p', 'sha1'], 'app_cose_tampered/') +# SignedAppFile('big_manifest.zip', ['-p', 'sha256', '--pad-headers', '2']) +# SignedAppFile('huge_manifest.zip', ['-p', 'sha256', '--pad-headers', '10']) diff --git a/security/manager/ssl/tests/unit/test_signed_apps/only_cose_multiple_signed.zip b/security/manager/ssl/tests/unit/test_signed_apps/only_cose_multiple_signed.zip new file mode 100644 index 0000000000..3536354f37 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/only_cose_multiple_signed.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/only_cose_signed.zip b/security/manager/ssl/tests/unit/test_signed_apps/only_cose_signed.zip new file mode 100644 index 0000000000..4ff76efcb8 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/only_cose_signed.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/unknown_issuer_app.zip b/security/manager/ssl/tests/unit/test_signed_apps/unknown_issuer_app.zip new file mode 100644 index 0000000000..4fa533a77a Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/unknown_issuer_app.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/unsigned_app.zip b/security/manager/ssl/tests/unit/test_signed_apps/unsigned_app.zip new file mode 100644 index 0000000000..f28e5df226 Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/unsigned_app.zip differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.der b/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.der new file mode 100644 index 0000000000..3c1869b13b Binary files /dev/null and b/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.der differ diff --git a/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.pem.certspec b/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.pem.certspec new file mode 100644 index 0000000000..500c4185cd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_signed_apps/xpcshellTestRoot.pem.certspec @@ -0,0 +1,6 @@ +issuer:xpcshell signed apps test root +subject:xpcshell signed apps test root +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:keyEncipherment,keyCertSign +extension:extKeyUsage:codeSigning diff --git a/security/manager/ssl/tests/unit/test_ssl_status.js b/security/manager/ssl/tests/unit/test_ssl_status.js new file mode 100644 index 0000000000..16484ebb59 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_ssl_status.js @@ -0,0 +1,76 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. +"use strict"; + +do_get_profile(); + +function run_test() { + Services.prefs.setIntPref("security.OCSP.enabled", 1); + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + let fakeOCSPResponder = new HttpServer(); + fakeOCSPResponder.registerPrefixHandler("/", function(request, response) { + response.setStatusLine(request.httpVersion, 500, "Internal Server Error"); + }); + fakeOCSPResponder.start(8888); + + // Test successful connection (failedCertChain should be null, + // succeededCertChain should be set as expected) + add_connection_test( + "good.include-subdomains.pinning.example.com", + PRErrorCodeSuccess, + null, + function withSecurityInfo(aSecInfo) { + equal( + aSecInfo.failedCertChain.length, + 0, + "failedCertChain for a successful connection should be empty" + ); + ok( + areCertArraysEqual( + aSecInfo.succeededCertChain, + build_cert_chain(["default-ee", "test-ca"]) + ), + "succeededCertChain for a successful connection should be as expected" + ); + } + ); + + // Test failed connection (failedCertChain should be set as expected, + // succeededCertChain should be null) + add_connection_test( + "expired.example.com", + SEC_ERROR_EXPIRED_CERTIFICATE, + null, + function withSecurityInfo(aSecInfo) { + equal( + aSecInfo.succeededCertChain.length, + 0, + "succeededCertChain for a failed connection should be null" + ); + ok( + areCertArraysEqual( + aSecInfo.failedCertChain, + build_cert_chain(["expired-ee", "test-ca"]) + ), + "failedCertChain for a failed connection should be as expected" + ); + } + ); + + // Ensure the correct failed cert chain is set on cert override + let overrideStatus = { + failedCertChain: build_cert_chain(["expired-ee", "test-ca"]), + }; + add_cert_override_test( + "expired.example.com", + Ci.nsICertOverrideService.ERROR_TIME, + SEC_ERROR_EXPIRED_CERTIFICATE, + undefined, + overrideStatus + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_sss_enumerate.js b/security/manager/ssl/tests/unit/test_sss_enumerate.js new file mode 100644 index 0000000000..e039660f33 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_enumerate.js @@ -0,0 +1,101 @@ +/* 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/. */ +"use strict"; + +do_get_profile(); // must be done before instantiating nsIX509CertDB + +const SECS_IN_A_WEEK = 7 * 24 * 60 * 60 * 1000; +const TESTCASES = [ + { + hostname: "a.pinning.example.com", + includeSubdomains: true, + expireTime: Date.now() + 12 * SECS_IN_A_WEEK * 1000, + }, + { + hostname: "b.pinning.example.com", + includeSubdomains: false, + expireTime: Date.now() + 13 * SECS_IN_A_WEEK * 1000, + }, +].sort((a, b) => a.expireTime - b.expireTime); + +let sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService); + +function getEntries(type) { + return Array.from(sss.enumerate(type)); +} + +function checkSiteSecurityStateAttrs(entries) { + entries.sort((a, b) => a.expireTime - b.expireTime); + equal( + entries.length, + TESTCASES.length, + "Should get correct number of entries" + ); + for (let i = 0; i < TESTCASES.length; i++) { + equal(entries[i].hostname, TESTCASES[i].hostname, "Hostnames should match"); + equal( + entries[i].securityPropertyState, + Ci.nsISiteSecurityState.SECURITY_PROPERTY_SET, + "Entries should have security property set" + ); + equal( + entries[i].includeSubdomains, + TESTCASES[i].includeSubdomains, + "IncludeSubdomains should match" + ); + // There's a delay from our "now" and the "now" that the implementation uses. + less( + Math.abs(entries[i].expireTime - TESTCASES[i].expireTime), + 60000, + "ExpireTime should be within 60-second error" + ); + } +} + +function add_tests() { + sss.clearAll(); + + for (const testcase of TESTCASES) { + add_connection_test( + testcase.hostname, + PRErrorCodeSuccess, + undefined, + function insertEntry(secInfo) { + const uri = Services.io.newURI(`https://${testcase.hostname}`); + + // MaxAge is in seconds. + let maxAge = Math.round((testcase.expireTime - Date.now()) / 1000); + let header = `max-age=${maxAge}`; + if (testcase.includeSubdomains) { + header += "; includeSubdomains"; + } + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + header, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + } + ); + } + + add_task(() => { + let hstsEntries = getEntries(Ci.nsISiteSecurityService.HEADER_HSTS); + + checkSiteSecurityStateAttrs(hstsEntries); + + sss.clearAll(); + hstsEntries = getEntries(Ci.nsISiteSecurityService.HEADER_HSTS); + + equal(hstsEntries.length, 0, "Should clear all HSTS entries"); + }); +} + +function run_test() { + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + add_tests(); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_sss_eviction.js b/security/manager/ssl/tests/unit/test_sss_eviction.js new file mode 100644 index 0000000000..dbb0880064 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_eviction.js @@ -0,0 +1,100 @@ +/* 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/. */ +"use strict"; + +// The purpose of this test is to check that a frequently visited site +// will not be evicted over an infrequently visited site. + +var gSSService = null; +var gProfileDir = null; + +function do_state_written(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + let stateFile = gProfileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + ok(stateFile.exists()); + let stateFileContents = readFile(stateFile); + // the last part is removed because it's the empty string after the final \n + let lines = stateFileContents.split("\n").slice(0, -1); + // We can receive multiple data-storage-written events. In particular, we + // may receive one where DataStorage wrote out data before we were done + // processing all of our headers. In this case, the data may not be + // as we expect. We only care about the final one being correct, however, + // so we return and wait for the next event if things aren't as we expect. + // There should be 1024 entries. + if (lines.length != 1024) { + return; + } + + let foundLegitSite = false; + for (let line of lines) { + if (line.startsWith("frequentlyused.example.com:HSTS")) { + foundLegitSite = true; + break; + } + } + + ok(foundLegitSite); + do_test_finished(); +} + +function do_state_read(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://frequentlyused.example.com"), + 0 + ) + ); + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + for (let i = 0; i < 2000; i++) { + let uri = Services.io.newURI("http://bad" + i + ".example.com"); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + } + do_test_pending(); + Services.obs.addObserver(do_state_written, "data-storage-written"); + do_test_finished(); +} + +function run_test() { + Services.prefs.setIntPref("test.datastorage.write_timer_ms", 100); + gProfileDir = do_get_profile(); + let stateFile = gProfileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + let outputStream = FileUtils.openFileOutputStream(stateFile); + let now = new Date().getTime(); + let line = + "frequentlyused.example.com:HSTS\t4\t0\t" + (now + 100000) + ",1,0\n"; + outputStream.write(line, line.length); + outputStream.close(); + Services.obs.addObserver(do_state_read, "data-storage-ready"); + do_test_pending(); + gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(gSSService, null); +} diff --git a/security/manager/ssl/tests/unit/test_sss_originAttributes.js b/security/manager/ssl/tests/unit/test_sss_originAttributes.js new file mode 100644 index 0000000000..181a57ee28 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_originAttributes.js @@ -0,0 +1,179 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=2 ts=2 sts=2 + * 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/. */ + +"use strict"; + +// Ensures nsISiteSecurityService APIs respects origin attributes. + +const GOOD_MAX_AGE_SECONDS = 69403; +const GOOD_MAX_AGE = `max-age=${GOOD_MAX_AGE_SECONDS};`; + +do_get_profile(); // must be done before instantiating nsIX509CertDB + +let sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService); +let host = "a.pinning.example.com"; +let uri = Services.io.newURI("https://" + host); + +// Check if originAttributes1 and originAttributes2 are isolated with respect +// to HSTS storage. +function doTest(secInfo, originAttributes1, originAttributes2, shouldShare) { + sss.clearAll(); + let header = GOOD_MAX_AGE; + // Set HSTS for originAttributes1. + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + header, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, + originAttributes1 + ); + ok( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes1 + ), + "URI should be secure given original origin attributes" + ); + equal( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes2 + ), + shouldShare, + "URI should be secure given different origin attributes if and " + + "only if shouldShare is true" + ); + + if (!shouldShare) { + // Remove originAttributes2 from the storage. + sss.resetState( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes2 + ); + ok( + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes1 + ), + "URI should still be secure given original origin attributes" + ); + } + + // Remove originAttributes1 from the storage. + sss.resetState( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes1 + ); + ok( + !sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes1 + ), + "URI should not be secure after removeState" + ); + + sss.clearAll(); +} + +function testInvalidOriginAttributes(secInfo, originAttributes) { + let header = GOOD_MAX_AGE; + + let callbacks = [ + () => + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + header, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, + originAttributes + ), + () => + sss.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes + ), + () => + sss.resetState( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + 0, + originAttributes + ), + ]; + + for (let callback of callbacks) { + throws( + callback, + /NS_ERROR_ILLEGAL_VALUE/, + "Should get an error with invalid origin attributes" + ); + } +} + +function add_tests() { + sss.clearAll(); + + let secInfo = null; + add_connection_test( + "a.pinning.example.com", + PRErrorCodeSuccess, + undefined, + aSecInfo => { + secInfo = aSecInfo; + } + ); + + add_task(function() { + let originAttributesList = []; + for (let userContextId of [0, 1, 2]) { + for (let firstPartyDomain of ["", "foo.com", "bar.com"]) { + originAttributesList.push({ userContextId, firstPartyDomain }); + } + } + for (let attrs1 of originAttributesList) { + for (let attrs2 of originAttributesList) { + // SSS storage is not isolated by userContext + doTest( + secInfo, + attrs1, + attrs2, + attrs1.firstPartyDomain == attrs2.firstPartyDomain + ); + } + } + + testInvalidOriginAttributes(secInfo, undefined); + testInvalidOriginAttributes(secInfo, null); + testInvalidOriginAttributes(secInfo, 1); + testInvalidOriginAttributes(secInfo, "foo"); + }); +} + +function run_test() { + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + add_tests(); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_sss_readstate.js b/security/manager/ssl/tests/unit/test_sss_readstate.js new file mode 100644 index 0000000000..1f3951a3f0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_readstate.js @@ -0,0 +1,161 @@ +/* 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/. */ +"use strict"; + +// The purpose of this test is to create a site security service state file +// and see that the site security service reads it properly. + +var gSSService = null; + +function checkStateRead(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://expired.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://notexpired.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://incsubdomain.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.incsubdomain.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains2.preloaded.test"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains2.preloaded.test"), + 0 + ) + ); + + // Clearing the data should make everything go back to default. + gSSService.clearAll(); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://expired.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://notexpired.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://incsubdomain.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.incsubdomain.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains2.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sub.includesubdomains2.preloaded.test"), + 0 + ) + ); + do_test_finished(); +} + +function run_test() { + let profileDir = do_get_profile(); + let stateFile = profileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + let outputStream = FileUtils.openFileOutputStream(stateFile); + let now = Date.now(); + let lines = [ + `expired.example.com:HSTS\t0\t0\t${now - 100000},1,0`, + `notexpired.example.com:HSTS\t0\t0\t${now + 100000},1,0`, + // This overrides an entry on the preload list. + `includesubdomains.preloaded.test:HSTS\t0\t0\t${now + 100000},1,0`, + `incsubdomain.example.com:HSTS\t0\t0\t${now + 100000},1,1`, + // This overrides an entry on the preload list. + "includesubdomains2.preloaded.test:HSTS\t0\t0\t0,2,0", + ]; + writeLinesAndClose(lines, outputStream); + Services.obs.addObserver(checkStateRead, "data-storage-ready"); + do_test_pending(); + gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(gSSService, null); +} diff --git a/security/manager/ssl/tests/unit/test_sss_readstate_child.js b/security/manager/ssl/tests/unit/test_sss_readstate_child.js new file mode 100644 index 0000000000..e45fedd18d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_readstate_child.js @@ -0,0 +1,40 @@ +/* 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/. */ +"use strict"; + +// The purpose of this test is to create a site security service state file +// and see that the site security service reads it properly. We also verify +// that state changes are reflected in the child process. + +function start_test_in_child() { + run_test_in_child("sss_readstate_child_worker.js"); + do_test_finished(); +} + +function run_test() { + let profileDir = do_get_profile(); + let stateFile = profileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + let outputStream = FileUtils.openFileOutputStream(stateFile); + let now = Date.now(); + let lines = [ + `expired.example.com:HSTS\t0\t0\t${now - 100000},1,0`, + `notexpired.example.com:HSTS\t0\t0\t${now + 100000},1,0`, + // This overrides an entry on the preload list. + `includesubdomains.preloaded.test:HSTS\t0\t0\t${now + 100000},1,0`, + `incsubdomain.example.com:HSTS\t0\t0\t${now + 100000},1,1`, + // This overrides an entry on the preload list. + "includesubdomains2.preloaded.test:HSTS\t0\t0\t0,2,0", + ]; + writeLinesAndClose(lines, outputStream); + Services.obs.addObserver(start_test_in_child, "data-storage-ready"); + do_test_pending(); + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(SSService, null); +} diff --git a/security/manager/ssl/tests/unit/test_sss_readstate_empty.js b/security/manager/ssl/tests/unit/test_sss_readstate_empty.js new file mode 100644 index 0000000000..b1def6bdd8 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_readstate_empty.js @@ -0,0 +1,56 @@ +/* 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/. */ +"use strict"; + +// The purpose of this test is to create an empty site security service state +// file and see that the site security service doesn't fail when reading it. + +var gSSService = null; + +function checkStateRead(aSubject, aTopic, aData) { + // nonexistent.example.com should never be an HSTS host + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://nonexistent.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + // notexpired.example.com is an HSTS host in a different test - we + // want to make sure that test hasn't interfered with this one. + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://notexpired.example.com"), + 0 + ) + ); + do_test_finished(); +} + +function run_test() { + let profileDir = do_get_profile(); + let stateFile = profileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + stateFile.create(Ci.nsIFile.NORMAL_FILE_TYPE, 0x1a4); // 0x1a4 == 0o644 + ok(stateFile.exists()); + // Initialize nsISiteSecurityService after do_get_profile() so it + // can read the state file. + Services.obs.addObserver(checkStateRead, "data-storage-ready"); + do_test_pending(); + gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(gSSService, null); +} diff --git a/security/manager/ssl/tests/unit/test_sss_readstate_garbage.js b/security/manager/ssl/tests/unit/test_sss_readstate_garbage.js new file mode 100644 index 0000000000..94f1ca9e6b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_readstate_garbage.js @@ -0,0 +1,110 @@ +/* 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/. */ +"use strict"; + +// The purpose of this test is to create a mostly bogus site security service +// state file and see that the site security service handles it properly. + +var gSSService = null; + +function checkStateRead(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + const HSTS_HOSTS = [ + "https://example1.example.com", + "https://example2.example.com", + ]; + for (let host of HSTS_HOSTS) { + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI(host), + 0 + ), + `${host} should be HSTS enabled` + ); + } + + const NOT_HSTS_HOSTS = [ + "https://example.com", + "https://example3.example.com", + "https://extra.comma.example.com", + "https://empty.statestring.example.com", + "https://rubbish.statestring.example.com", + "https://spaces.statestring.example.com", + "https://invalid.expirytime.example.com", + "https://text.securitypropertystate.example.com", + "https://invalid.securitypropertystate.example.com", + "https://text.includesubdomains.example.com", + "https://invalid.includesubdomains.example.com", + ]; + for (let host of NOT_HSTS_HOSTS) { + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI(host), + 0 + ), + `${host} should not be HSTS enabled` + ); + } + + do_test_finished(); +} + +const PINNING_ROOT_KEY_HASH = "VCIlmPM9NkgFQtrs4Oa5TeFcDu6MWRTKSNdePEhOgD8="; +const BASE64_BUT_NOT_SHA256 = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; +const STARTS_WITH_NUMBER = "1ABC23defG/hiJKlmNoP+QRStuVwxYZ9a+bcD/+/EFg="; +const STARTS_WITH_SYMBOL = "+ABC23defG/hiJKlmNoP+QRStuVwxYZ9a+bcD/+/EFg="; +const MULTIPLE_KEYS = + PINNING_ROOT_KEY_HASH + STARTS_WITH_NUMBER + STARTS_WITH_SYMBOL; + +function run_test() { + Services.prefs.setBoolPref("security.cert_pinning.hpkp.enabled", true); + let profileDir = do_get_profile(); + let stateFile = profileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + let outputStream = FileUtils.openFileOutputStream(stateFile); + let expiryTime = Date.now() + 100000; + let lines = [ + // General state file entry tests. + `example1.example.com:HSTS\t0\t0\t${expiryTime},1,0`, + "I'm a lumberjack and I'm okay; I work all night and I sleep all day!", + "This is a totally bogus entry\t", + "0\t0\t0\t0\t", + "\t\t\t\t\t\t\t", + "example.com:HSTS\t\t\t\t\t\t\t", + "example3.example.com:HSTS\t0\t\t\t\t\t\t", + `example2.example.com:HSTS\t0\t0\t${expiryTime},1,0`, + // HSTS state string parsing tests + `extra.comma.example.com:HSTS\t0\t0\t${expiryTime},,1,0`, + "empty.statestring.example.com:HSTS\t0\t0\t", + "rubbish.statestring.example.com:HSTS\t0\t0\tfoobar", + `spaces.statestring.example.com:HSTS\t0\t0\t${expiryTime}, 1,0 `, + `invalid.expirytime.example.com:HSTS\t0\t0\t${expiryTime}foo123,1,0`, + `text.securitypropertystate.example.com:HSTS\t0\t0\t${expiryTime},1foo,0`, + `invalid.securitypropertystate.example.com:HSTS\t0\t0\t${expiryTime},999,0`, + `text.includesubdomains.example.com:HSTS\t0\t0\t${expiryTime},1,1foo`, + `invalid.includesubdomains.example.com:HSTS\t0\t0\t${expiryTime},1,0foo`, + ]; + writeLinesAndClose(lines, outputStream); + Services.obs.addObserver(checkStateRead, "data-storage-ready"); + do_test_pending(); + gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(gSSService, null); + + Services.prefs.setIntPref("security.cert_pinning.enforcement_level", 2); + registerCleanupFunction(() => { + Services.prefs.clearUserPref("security.cert_pinning.enforcement_level"); + }); +} diff --git a/security/manager/ssl/tests/unit/test_sss_readstate_huge.js b/security/manager/ssl/tests/unit/test_sss_readstate_huge.js new file mode 100644 index 0000000000..d0c7a7541d --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_readstate_huge.js @@ -0,0 +1,98 @@ +/* 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/. */ +"use strict"; + +// The purpose of this test is to create a site security service state file +// that is too large and see that the site security service reads it properly +// (this means discarding all entries after the 1024th). + +var gSSService = null; + +function checkStateRead(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example0.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example423.example.com"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example1023.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example1024.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example1025.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example9000.example.com"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://example99999.example.com"), + 0 + ) + ); + do_test_finished(); +} + +function run_test() { + let profileDir = do_get_profile(); + let stateFile = profileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + // Assuming we're working with a clean slate, the file shouldn't exist + // until we create it. + ok(!stateFile.exists()); + let outputStream = FileUtils.openFileOutputStream(stateFile); + let expiryTime = Date.now() + 100000; + let lines = []; + for (let i = 0; i < 10000; i++) { + // The 0s will all get squashed down into one 0 when they are read. + // This is just to make the file size large (>2MB). + lines.push( + `example${i}.example.com:HSTS\t` + + "0000000000000000000000000000000000000000000000000\t" + + "00000000000000000000000000000000000000\t" + + `${expiryTime},1,0000000000000000000000000000000000000000000000000000000000000000000000000` + ); + } + writeLinesAndClose(lines, outputStream); + Services.obs.addObserver(checkStateRead, "data-storage-ready"); + do_test_pending(); + gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + notEqual(gSSService, null); +} diff --git a/security/manager/ssl/tests/unit/test_sss_resetState.js b/security/manager/ssl/tests/unit/test_sss_resetState.js new file mode 100644 index 0000000000..1850442b64 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_resetState.js @@ -0,0 +1,113 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// Tests that resetting HSTS state in the way the "forget about this site" +// functionality does works as expected for preloaded and non-preloaded sites. + +do_get_profile(); + +var gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService +); + +function test_removeState(secInfo, type, flags) { + info(`running test_removeState(type=${type}, flags=${flags})`); + // Simulate visiting a non-preloaded site by processing an HSTS header check + // that the HSTS bit gets set, simulate "forget about this site" (call + // removeState), and then check that the HSTS bit isn't set. + let notPreloadedURI = Services.io.newURI("https://not-preloaded.example.com"); + ok(!gSSService.isSecureURI(type, notPreloadedURI, flags)); + gSSService.processHeader( + type, + notPreloadedURI, + "max-age=1000;", + secInfo, + flags, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(gSSService.isSecureURI(type, notPreloadedURI, flags)); + gSSService.resetState(type, notPreloadedURI, flags); + ok(!gSSService.isSecureURI(type, notPreloadedURI, flags)); + + // Simulate visiting a non-preloaded site that unsets HSTS by processing + // an HSTS header with "max-age=0", check that the HSTS bit isn't + // set, simulate "forget about this site" (call removeState), and then check + // that the HSTS bit isn't set. + gSSService.processHeader( + type, + notPreloadedURI, + "max-age=0;", + secInfo, + flags, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(!gSSService.isSecureURI(type, notPreloadedURI, flags)); + gSSService.resetState(type, notPreloadedURI, flags); + ok(!gSSService.isSecureURI(type, notPreloadedURI, flags)); + + // Simulate visiting a preloaded site by processing an HSTS header, check + // that the HSTS bit is still set, simulate "forget about this site" + // (call removeState), and then check that the HSTS bit is still set. + let preloadedHost = "includesubdomains.preloaded.test"; + let preloadedURI = Services.io.newURI(`https://${preloadedHost}`); + ok(gSSService.isSecureURI(type, preloadedURI, flags)); + gSSService.processHeader( + type, + preloadedURI, + "max-age=1000;", + secInfo, + flags, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(gSSService.isSecureURI(type, preloadedURI, flags)); + gSSService.resetState(type, preloadedURI, flags); + ok(gSSService.isSecureURI(type, preloadedURI, flags)); + + // Simulate visiting a preloaded site that unsets HSTS by processing an + // HSTS header with "max-age=0", check that the HSTS bit is what we + // expect (see below), simulate "forget about this site" (call removeState), + // and then check that the HSTS bit is set. + gSSService.processHeader( + type, + preloadedURI, + "max-age=0;", + secInfo, + flags, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(!gSSService.isSecureURI(type, preloadedURI, flags)); + gSSService.resetState(type, preloadedURI, flags); + ok(gSSService.isSecureURI(type, preloadedURI, flags)); +} + +function add_tests() { + let secInfo = null; + add_connection_test( + "not-preloaded.example.com", + PRErrorCodeSuccess, + undefined, + aSecInfo => { + secInfo = aSecInfo; + } + ); + + add_task(() => { + test_removeState(secInfo, Ci.nsISiteSecurityService.HEADER_HSTS, 0); + test_removeState( + secInfo, + Ci.nsISiteSecurityService.HEADER_HSTS, + Ci.nsISocketProvider.NO_PERMANENT_STORAGE + ); + }); +} + +function run_test() { + add_tls_server_setup("BadCertAndPinningServer", "bad_certs"); + + add_tests(); + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_sss_sanitizeOnShutdown.js b/security/manager/ssl/tests/unit/test_sss_sanitizeOnShutdown.js new file mode 100644 index 0000000000..6e1142b4b4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_sanitizeOnShutdown.js @@ -0,0 +1,72 @@ +/* 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/. */ +"use strict"; + +// The purpose of this test is to ensure that Firefox sanitizes site security +// service data on shutdown if configured to do so. + +XPCOMUtils.defineLazyModuleGetters(this, { + TestUtils: "resource://testing-common/TestUtils.jsm", + Sanitizer: "resource:///modules/Sanitizer.jsm", +}); + +Sanitizer.onStartup(); + +// This helps us away from test timed out. If service worker manager(swm) hasn't +// been initilaized before profile-change-teardown, this test would fail due to +// the shutdown blocker added by swm. Normally, swm should be initialized before +// that and the similar crash signatures are fixed. So, assume this cannot +// happen in the real world and initilaize swm here as a workaround. +const swm = Cc["@mozilla.org/serviceworkers/manager;1"].getService( + Ci.nsIServiceWorkerManager +); + +function getStateFileContents() { + let stateFile = do_get_profile(); + stateFile.append(SSS_STATE_FILE_NAME); + ok(stateFile.exists()); + return readFile(stateFile); +} + +add_task(async function run_test() { + Services.prefs.setIntPref("test.datastorage.write_timer_ms", 100); + do_get_profile(); + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + let header = "max-age=50000"; + SSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("http://example.com"), + header, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + await TestUtils.topicObserved( + "data-storage-written", + (_, data) => data == SSS_STATE_FILE_NAME + ); + let stateFileContents = getStateFileContents(); + ok( + stateFileContents.includes("example.com"), + "should have written out state file" + ); + + // Configure Firefox to clear this data on shutdown. + Services.prefs.setBoolPref( + Sanitizer.PREF_SHUTDOWN_BRANCH + "siteSettings", + true + ); + Services.prefs.setBoolPref(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN, true); + + // Simulate shutdown. + Services.obs.notifyObservers(null, "profile-change-teardown"); + Services.obs.notifyObservers(null, "profile-before-change"); + + equal(getStateFileContents(), "", "state file should be empty"); +}); diff --git a/security/manager/ssl/tests/unit/test_sss_savestate.js b/security/manager/ssl/tests/unit/test_sss_savestate.js new file mode 100644 index 0000000000..300afe4983 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sss_savestate.js @@ -0,0 +1,122 @@ +/* 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/. */ +"use strict"; + +// The purpose of this test is to see that the site security service properly +// writes its state file. + +const EXPECTED_ENTRIES = 5; +const EXPECTED_HSTS_COLUMNS = 4; +var gProfileDir = null; + +const NON_ISSUED_KEY_HASH = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; + +// For reference, the format of the state file is a list of: +// ,, +// separated by newlines ('\n') + +function checkStateWritten(aSubject, aTopic, aData) { + if (aData == PRELOAD_STATE_FILE_NAME || aData == CLIENT_AUTH_FILE_NAME) { + return; + } + + equal(aData, SSS_STATE_FILE_NAME); + + let stateFile = gProfileDir.clone(); + stateFile.append(SSS_STATE_FILE_NAME); + ok(stateFile.exists()); + let stateFileContents = readFile(stateFile); + // the last line is removed because it's just a trailing newline + let lines = stateFileContents.split("\n").slice(0, -1); + equal(lines.length, EXPECTED_ENTRIES); + let sites = {}; // a map of domain name -> [the entry in the state file] + for (let line of lines) { + let parts = line.split("\t"); + let host = parts[0]; + let entry = parts[3].split(","); + let expectedColumns = EXPECTED_HSTS_COLUMNS; + equal(entry.length, expectedColumns); + sites[host] = entry; + } + + // We can receive multiple data-storage-written events. In particular, we + // may receive one where DataStorage wrote out data before we were done + // processing all of our headers. In this case, the data may not be + // as we expect. We only care about the final one being correct, however, + // so we return and wait for the next event if things aren't as we expect. + // sites[url][1] corresponds to SecurityPropertySet (if 1) and + // SecurityPropertyUnset (if 0) + // sites[url][2] corresponds to includeSubdomains + if (sites["includesubdomains.preloaded.test:HSTS"][1] != 1) { + return; + } + if (sites["includesubdomains.preloaded.test:HSTS"][2] != 0) { + return; + } + if (sites["a.example.com:HSTS"][1] != 1) { + return; + } + if (sites["a.example.com:HSTS"][2] != 1) { + return; + } + if (sites["b.example.com:HSTS"][1] != 1) { + return; + } + if (sites["b.example.com:HSTS"][2] != 0) { + return; + } + if (sites["c.c.example.com:HSTS"][1] != 1) { + return; + } + if (sites["c.c.example.com:HSTS"][2] != 1) { + return; + } + if (sites["d.example.com:HSTS"][1] != 1) { + return; + } + if (sites["d.example.com:HSTS"][2] != 0) { + return; + } + + do_test_finished(); +} + +function run_test() { + Services.prefs.setBoolPref("security.cert_pinning.hpkp.enabled", true); + Services.prefs.setIntPref("test.datastorage.write_timer_ms", 100); + gProfileDir = do_get_profile(); + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + + let uris = [ + Services.io.newURI("http://includesubdomains.preloaded.test"), + Services.io.newURI("http://a.example.com"), + Services.io.newURI("http://b.example.com"), + Services.io.newURI("http://c.c.example.com"), + Services.io.newURI("http://d.example.com"), + ]; + + for (let i = 0; i < 1000; i++) { + let uriIndex = i % uris.length; + // vary max-age + let maxAge = "max-age=" + i * 1000; + // alternate setting includeSubdomains + let includeSubdomains = i % 2 == 0 ? "; includeSubdomains" : ""; + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + SSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uris[uriIndex], + maxAge + includeSubdomains, + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + } + + do_test_pending(); + Services.obs.addObserver(checkStateWritten, "data-storage-written"); +} diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign.js b/security/manager/ssl/tests/unit/test_startcom_wosign.js new file mode 100644 index 0000000000..1fda3a9a96 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign.js @@ -0,0 +1,67 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests handling of certificates issued by StartCom and WoSign. If such +// certificates have a notBefore before 21 October 2016, they are handled +// normally. Otherwise, they are treated as revoked. + +do_get_profile(); // must be called before getting nsIX509CertDB +const certdb = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +function loadCertWithTrust(certName, trustString) { + addCertFromFile( + certdb, + "test_startcom_wosign/" + certName + ".pem", + trustString + ); +} + +function certFromFile(certName) { + return constructCertFromFile("test_startcom_wosign/" + certName + ".pem"); +} + +function checkEndEntity(cert, expectedResult) { + // (new Date("2016-11-01")).getTime() / 1000 + const VALIDATION_TIME = 1477958400; + return checkCertErrorGenericAtTime( + certdb, + cert, + expectedResult, + certificateUsageSSLServer, + VALIDATION_TIME + ); +} + +add_task(async function() { + loadCertWithTrust("ca", "CTu,,"); + // This is not a real StartCom CA - it merely has the same distinguished name + // as one (namely "/C=IL/O=StartCom Ltd./CN=StartCom Certification Authority + // G2", encoded with PrintableStrings). By checking for specific DNs, we can + // enforce the date-based policy in a way that is testable. + loadCertWithTrust("StartComCA", ",,"); + await checkEndEntity( + certFromFile("StartCom-before-cutoff"), + PRErrorCodeSuccess + ); + await checkEndEntity( + certFromFile("StartCom-after-cutoff"), + SEC_ERROR_REVOKED_CERTIFICATE + ); + + // Similarly, this is not a real WoSign CA. It has the same distinguished name + // as "/C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign", + // encoded with PrintableStrings). + loadCertWithTrust("WoSignCA", ",,"); + await checkEndEntity( + certFromFile("WoSign-before-cutoff"), + PRErrorCodeSuccess + ); + await checkEndEntity( + certFromFile("WoSign-after-cutoff"), + SEC_ERROR_REVOKED_CERTIFICATE + ); +}); diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem new file mode 100644 index 0000000000..031b2e8674 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHzCCAgegAwIBAgIUMzsA8O2TjNkD5ARjfvom8NIOGV0wDQYJKoZIhvcNAQEL +BQAwUzELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xLDAqBgNV +BAMTI1N0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEcyMCIYDzIwMTYx +MDIyMDAwMDAwWhgPMjAxNzEwMjIwMDAwMDBaMCAxHjAcBgNVBAMMFVN0YXJ0Q29t +LWFmdGVyLWN1dG9mZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w +DQYJKoZIhvcNAQELBQADggEBAF45Nn67efx82OhjZ865DeQdHjTL4IhIo3dcZwf2 +1fLgV1+ZXDFUewnE0Sw7pR57uUKGmaISjoF2lXvNm0U/5Nq6dUbhN9KtnRifaM3x +NavEvpTZAwERnnphDJFlgSJAFSPWLGZDULl7JaZyLyQe0AoQXAFTyghkXrk/QA5m +1LfDYqLiwL1G4NHLGu7QRvLUZ/pxkLS3PaKfZVILCnKiOvI7bmPq+2U7H6ZgTPPP +24Sy/E9AKV5I6IEojGuM6qP+QYgLANOaGygWrIVJ+QpS36V8uRRbetzTcJUHDesw +iMJaepPkWnFNhz2CSS3HyoG9wu/RqfRwiLWqjsOs0dEZTRw= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem.certspec new file mode 100644 index 0000000000..9f0fe22fcd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-after-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 +subject:StartCom-after-cutoff +validity:20161022-20171022 +extension:subjectAlternativeName:example.com diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem new file mode 100644 index 0000000000..61ef3cbf72 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIUF7D74A6qEV/s6DRPxUqAk7N+bX8wDQYJKoZIhvcNAQEL +BQAwUzELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xLDAqBgNV +BAMTI1N0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEcyMCIYDzIwMTUx +MDIyMDAwMDAwWhgPMjAxNzEwMjIwMDAwMDBaMCExHzAdBgNVBAMMFlN0YXJ0Q29t +LWJlZm9yZS1jdXRvZmYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjGjAYMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29t +MA0GCSqGSIb3DQEBCwUAA4IBAQB2r07MUxWXUj7gAlQJUKNhNJ9Fqlt13751C4Lo +KL9TeUeROqDviPtpwoigG0NV+IMWdXJorRmbkcFmgBOFOZmhyspi2BJ4rCCWC1FI +WFe9SlFsuka7a7sAov9B3ClLJE+JX48H84kZ1yMq1jQmv0tAko9di3d7oMhHpLMp +tBzOQUnuq/kBeS5VlHxyZoRxj7U0MSIORhIOkih/pRzmeLDnn7xBj9FZ6ipoukRL +n3l3wTmj9/aar7DhhgA8QvD6ZtNHXP8ZnheVqW07OZVjWcrzg7nID3+j4LWOZNq/ +hdm1nZG5DltMk7JqIGuA4PmdStXQNftEVbeWMzdQ+8cb/wmC +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem.certspec new file mode 100644 index 0000000000..b7fbd4954e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartCom-before-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 +subject:StartCom-before-cutoff +validity:20151022-20171022 +extension:subjectAlternativeName:example.com diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem new file mode 100644 index 0000000000..98ce37dabe --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDDzCCAfegAwIBAgIUY5ffXJsiXdmKh2ybX2nxSg57mRwwDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAw +MDAwMFowUzELMAkGA1UEBhMCSUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xLDAq +BgNVBAMTI1N0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEcyMIIBIjAN +BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq +5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SSc +An7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39 +ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYk +zBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3u +JtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQAB +ox0wGzALBgNVHQ8EBAMCAQYwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQsFAAOC +AQEAe6mpnTBxkfYlTrzuvtKQ73A5KCEBfmtRGZaMRPh8rSxdnd8Zf2zTl3eUHYX1 +y+pqY1U9YJOkR1TKfbtvQll7bnD5RJ+FJD6eA9QEwSpII7v66teRS7wBPxQrvsrq +SWVZuHyKMpBG3148/nmrPvaIB5kAO5fdedIET88PL3K8LM1XzoVZc272V577pmeD +4N116ghEIz7rhrR6yoGVN0s2TXT7H5AlOscZuVRkirickVUbjSWZma+mYJWdd8hi +Cjufl43OY4EY31w9qO8BKxx8ZugmoSmp93VyMvqWZAV1AoxgxMpOsC9e7ZB83yrU +luXN7wik7bf+xNz78Be6XhBOBA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem.certspec new file mode 100644 index 0000000000..d1e3c4c4f4 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/StartComCA.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:printableString/C=IL/O=StartCom Ltd./CN=StartCom Certification Authority G2 +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem new file mode 100644 index 0000000000..dc976c7c61 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHzCCAgegAwIBAgIUC57N1fgWjCRoz95Wt5tIBI4U+AMwDQYJKoZIhvcNAQEL +BQAwVTELMAkGA1UEBhMCQ04xGjAYBgNVBAoTEVdvU2lnbiBDQSBMaW1pdGVkMSow +KAYDVQQDEyFDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBvZiBXb1NpZ24wIhgPMjAx +NjEwMjIwMDAwMDBaGA8yMDE3MTAyMjAwMDAwMFowHjEcMBoGA1UEAwwTV29TaWdu +LWFmdGVyLWN1dG9mZjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqI +UahEjhbWQf1utogGNhA9PBPZ6uQ1SrTs9WhXbCR7wcclqODYH72xnAabbhqG8mvi +r1p1a2pkcQh6pVqnRYf3HNUknAJ+zUP8HmnQOCApk6sgw0nk27lMwmtsDu0Vgg/x +fq1pGrHTAjqLKkHup3DgDw2N/WYLK7AkkqR9uYhheZCxV5A90jvF4LhIH6g304hD +7ycW2FW3ZlqqfgKQLzp7EIAGJMwcbJetlmFbt+KWEsB1MaMMkd20yvf8rR0l0wnv +uRcOp2jhs3svIm9p47SKlWEd7ibWJZ2rkQhONsscJAQsvxaLL+Xxj5kXMbiz/kkj ++nJRxDHVA6zaGAo17Y0CAwEAAaMaMBgwFgYDVR0RBA8wDYILZXhhbXBsZS5jb20w +DQYJKoZIhvcNAQELBQADggEBAK+d8oCtnO+HwtV1nEqKAd1/3ATIGmbDJn5kQWKY +m5cVi4NO6UivqhQO7Z8if+sO5DuX/VoodC+LESuv8NQdn8pDH1Ou7WUtm9xyG5Ly +j+D+WgpjmxKfBfD2L0Pd4b8ZrCg8Az3wmz6Jz7MwEU8FqmScQkxJN4JH7S2QlmLa +asrPwrFKy9uOD3jSW6d5H3gv+nV7thIiMASor3up5KV//UdVqWTISOpBZdJKE8wp +QtlPfvIgP5DbrfhtOzDYLuPnO3WzT7oC4Pau0eMXlT5EKC41p+fXGqtU402H0xMB +5ftgAboQ42FDDkp+y13a7wfm1KqcaahWR9CQKrO1ag7Mspk= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem.certspec new file mode 100644 index 0000000000..2afb5d6ea6 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-after-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign +subject:WoSign-after-cutoff +validity:20161022-20171022 +extension:subjectAlternativeName:example.com diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem new file mode 100644 index 0000000000..8dc84c549c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDIDCCAgigAwIBAgIUI4ScwRAmd+wFemr14yqwfKljyEswDQYJKoZIhvcNAQEL +BQAwVTELMAkGA1UEBhMCQ04xGjAYBgNVBAoTEVdvU2lnbiBDQSBMaW1pdGVkMSow +KAYDVQQDEyFDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBvZiBXb1NpZ24wIhgPMjAx +NTEwMjIwMDAwMDBaGA8yMDE3MTAyMjAwMDAwMFowHzEdMBsGA1UEAwwUV29TaWdu +LWJlZm9yZS1jdXRvZmYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6 +iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr +4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP +8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OI +Q+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ +77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5J +I/pyUcQx1QOs2hgKNe2NAgMBAAGjGjAYMBYGA1UdEQQPMA2CC2V4YW1wbGUuY29t +MA0GCSqGSIb3DQEBCwUAA4IBAQAtq4bkF5Dh+Gouc8D+v4c5Siol9ucFZziegFTe +CwCel//tShZwFSObespSLFVjrPPrEhdv+9Wl7/faHaFEIYjX/xBJ+ZsdKal56E/+ +hnuXzCWhojpnMcMzWRVPBzKo0KD3g673pdC6m86r78eXDwG+8zYak+IQ4CJAaUOd +hT23GDajLjBbUNdT1pBjIKxYa2iNJOyQ8SVil18r2c1/AtoejS0xZda2MO+FDnf5 +01413PgAU1Lf1C6tEQNnncLtMQhT+LKlDIMo9PolJcvMto57f/awQhyiYMLvIAE+ +O8NIYXn0cyn+dbpaL59hmx1AJJwtyn3RsskVKQjle7ky3gt7 +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem.certspec new file mode 100644 index 0000000000..224522bf01 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSign-before-cutoff.pem.certspec @@ -0,0 +1,4 @@ +issuer:printableString/C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign +subject:WoSign-before-cutoff +validity:20151022-20171022 +extension:subjectAlternativeName:example.com diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem new file mode 100644 index 0000000000..490e22cfdd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDETCCAfmgAwIBAgIUYx3n8sfSMjvHAMPX4R896bPDFB4wDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAw +MDAwMFowVTELMAkGA1UEBhMCQ04xGjAYBgNVBAoTEVdvU2lnbiBDQSBMaW1pdGVk +MSowKAYDVQQDEyFDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBvZiBXb1NpZ24wggEi +MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6iFGoRI4W1kH9braIBjYQPTwT +2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEIeqVap0WH9xzV +JJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6iypB7qdw4A8N +jf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCA +BiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVh +He4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMB +AAGjHTAbMAsGA1UdDwQEAwIBBjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBCwUA +A4IBAQABpMKSJzIqD+0DHDAzcBl99nTDTYalGAbYvKvnxKOiD0WVw8K/Lp+Ofoh2 +ZicDP35liyEPiyZMfR5IIyfPwPkgvRTIrZtX87SFxHcrsvZHVj+ilijOSWBx9Tgy +z1PhkAdTg49ljzsKa77+nEKDkRXSWIbmt3MUymvCSMq1HXUFOwpPSqB98ssvjMhs +acKcMnpSe5m39Z9OIAczhsR64otg+flV4XH2ocdE0ywBzMnw4HVY49TXEkojs1bY +aXgkTEaFrFKj45UeGw2yBbftZB18bhPemOtkxiMR7ChOtilMKHGI/qH5rvQJXuwV +HkC3s3YcMbHtx0w3aYSC8caspSxt +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem.certspec new file mode 100644 index 0000000000..8c293bf9b5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/WoSignCA.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:printableString/C=CN/O=WoSign CA Limited/CN=Certification Authority of WoSign +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem b/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem new file mode 100644 index 0000000000..560684144f --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICyTCCAbGgAwIBAgIUGUKJPXqFyHlaMLy7vfWOkCn+6RswDQYJKoZIhvcNAQEL +BQAwDTELMAkGA1UEAwwCY2EwIhgPMjAxMDAxMDEwMDAwMDBaGA8yMDUwMDEwMTAw +MDAwMFowDTELMAkGA1UEAwwCY2EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQC6iFGoRI4W1kH9braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwG +m24ahvJr4q9adWtqZHEIeqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJr +bA7tFYIP8X6taRqx0wI6iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4 +SB+oN9OIQ+8nFthVt2Zaqn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3 +/K0dJdMJ77kXDqdo4bN7LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+Z +FzG4s/5JI/pyUcQx1QOs2hgKNe2NAgMBAAGjHTAbMAsGA1UdDwQEAwIBBjAMBgNV +HRMEBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQCV2ftsqVDw6pxfW7ToIowvicAL +H1Gwj5AL1aVpPOBFHXJGkKbYkAVl62t2R8OTJzrqjNo9D4sgRKKtqJXwmqlAEyuk +dsA18pA/0/jIEU12/Oq68ra6HB+efTfxQrm4/uU2Yr2UNcCcAo8nKtzxsPsPAiMm +hqKCRkCtYZjGRk18S2y85XihanfTkAqBGlI4GC7q4Otnq7j7y9FwtiQ7iWP+IYQv +OlS+FwCoctrNLGOQE9Jzc4GRD2zlwsbWfHDQUvB1p3tjKwtT35EtWf6F5NpKLWTm +m3SmHIG6pvIePX0zhlac1tR/uvCSpyFAiQ7nG4XDpNyPle1WEFreiS8+ITeM +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem.certspec b/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem.certspec new file mode 100644 index 0000000000..efd24b1532 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/ca.pem.certspec @@ -0,0 +1,5 @@ +issuer:ca +subject:ca +validity:20100101-20500101 +extension:keyUsage:keyCertSign,cRLSign +extension:basicConstraints:cA, diff --git a/security/manager/ssl/tests/unit/test_startcom_wosign/moz.build b/security/manager/ssl/tests/unit/test_startcom_wosign/moz.build new file mode 100644 index 0000000000..657bcf6bed --- /dev/null +++ b/security/manager/ssl/tests/unit/test_startcom_wosign/moz.build @@ -0,0 +1,19 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'StartCom-after-cutoff.pem', +# 'StartCom-before-cutoff.pem', +# 'StartComCA.pem', +# 'WoSign-after-cutoff.pem', +# 'WoSign-before-cutoff.pem', +# 'WoSignCA.pem', +# 'ca.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) diff --git a/security/manager/ssl/tests/unit/test_sts_fqdn.js b/security/manager/ssl/tests/unit/test_sts_fqdn.js new file mode 100644 index 0000000000..d8ecbf1530 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_fqdn.js @@ -0,0 +1,50 @@ +/* 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/. + */ +"use strict"; + +function run_test() { + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + let uri = Services.io.newURI("https://example.com"); + let uri1 = Services.io.newURI("https://example.com."); + let uri2 = Services.io.newURI("https://example.com.."); + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0)); + // These cases are only relevant as long as bug 1118522 hasn't been fixed. + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri2, 0)); + + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + SSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000;includeSubdomains", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0)); + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri2, 0)); + + SSService.resetState(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0); + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri1, 0)); + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri2, 0)); + + // Somehow creating this malformed URI succeeds - we need to handle it + // gracefully. + uri = Services.io.newURI("https://../foo"); + equal(uri.host, ".."); + throws( + () => { + SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0); + }, + /NS_ERROR_UNEXPECTED/, + "Malformed URI should be rejected" + ); +} diff --git a/security/manager/ssl/tests/unit/test_sts_ipv4_ipv6.js b/security/manager/ssl/tests/unit/test_sts_ipv4_ipv6.js new file mode 100644 index 0000000000..1950d7b1bd --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_ipv4_ipv6.js @@ -0,0 +1,59 @@ +"use strict"; + +function check_ip(s, v, ip) { + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + + let str = "https://"; + if (v == 6) { + str += "["; + } + str += ip; + if (v == 6) { + str += "]"; + } + str += "/"; + + let uri = Services.io.newURI(str); + ok(!s.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + let parsedMaxAge = {}; + let parsedIncludeSubdomains = {}; + s.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000;includeSubdomains", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST, + {}, + parsedMaxAge, + parsedIncludeSubdomains + ); + ok( + !s.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0), + "URI should not be secure if it contains an IP address" + ); + + /* Test that processHeader will ignore headers for an uri, if the uri + * contains an IP address not a hostname. + * If processHeader indeed ignore the header, then the output parameters will + * remain empty, and we shouldn't see the values passed as the header. + */ + notEqual(parsedMaxAge.value, 1000); + notEqual(parsedIncludeSubdomains.value, true); + notEqual(parsedMaxAge.value, undefined); + notEqual(parsedIncludeSubdomains.value, undefined); +} + +function run_test() { + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + + check_ip(SSService, 4, "127.0.0.1"); + check_ip(SSService, 4, "10.0.0.1"); + check_ip(SSService, 6, "2001:db8::1"); + check_ip(SSService, 6, "1080::8:800:200C:417A"); +} diff --git a/security/manager/ssl/tests/unit/test_sts_parser.js b/security/manager/ssl/tests/unit/test_sts_parser.js new file mode 100644 index 0000000000..8475d2e558 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_parser.js @@ -0,0 +1,146 @@ +/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- + * vim: sw=2 ts=2 sts=2 + * 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/. */ + +"use strict"; + +// STS parser tests + +let sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService); +let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" +].createInstance(Ci.nsITransportSecurityInfo); + +function testSuccess(header, expectedMaxAge, expectedIncludeSubdomains) { + let dummyUri = Services.io.newURI("https://foo.com/bar.html"); + let maxAge = {}; + let includeSubdomains = {}; + + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + dummyUri, + header, + secInfo, + 0, + sss.SOURCE_ORGANIC_REQUEST, + {}, + maxAge, + includeSubdomains + ); + + equal(maxAge.value, expectedMaxAge, "Did not correctly parse maxAge"); + equal( + includeSubdomains.value, + expectedIncludeSubdomains, + "Did not correctly parse presence/absence of includeSubdomains" + ); +} + +function testFailure(header) { + let dummyUri = Services.io.newURI("https://foo.com/bar.html"); + let maxAge = {}; + let includeSubdomains = {}; + + throws( + () => { + sss.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + dummyUri, + header, + secInfo, + 0, + sss.SOURCE_ORGANIC_REQUEST, + {}, + maxAge, + includeSubdomains + ); + }, + /NS_ERROR_FAILURE/, + "Parsed invalid header: " + header + ); +} + +function run_test() { + // SHOULD SUCCEED: + testSuccess("max-age=100", 100, false); + testSuccess("max-age =100", 100, false); + testSuccess(" max-age=100", 100, false); + testSuccess("max-age = 100 ", 100, false); + testSuccess('max-age = "100" ', 100, false); + testSuccess('max-age="100"', 100, false); + testSuccess(' max-age ="100" ', 100, false); + testSuccess('\tmax-age\t=\t"100"\t', 100, false); + testSuccess("max-age = 100 ", 100, false); + + testSuccess("maX-aGe=100", 100, false); + testSuccess("MAX-age =100", 100, false); + testSuccess("max-AGE=100", 100, false); + testSuccess("Max-Age = 100 ", 100, false); + testSuccess("MAX-AGE = 100 ", 100, false); + + testSuccess("max-age=100;includeSubdomains", 100, true); + testSuccess("max-age=100\t; includeSubdomains", 100, true); + testSuccess(" max-age=100; includeSubdomains", 100, true); + testSuccess("max-age = 100 ; includeSubdomains", 100, true); + testSuccess( + "max-age = 100 ; includeSubdomains", + 100, + true + ); + + testSuccess("maX-aGe=100; includeSUBDOMAINS", 100, true); + testSuccess("MAX-age =100; includeSubDomains", 100, true); + testSuccess("max-AGE=100; iNcLuDeSuBdoMaInS", 100, true); + testSuccess("Max-Age = 100; includesubdomains ", 100, true); + testSuccess("INCLUDESUBDOMAINS;MaX-AgE = 100 ", 100, true); + // Turns out, the actual directive is entirely optional (hence the + // trailing semicolon) + testSuccess("max-age=100;includeSubdomains;", 100, true); + + // these are weird tests, but are testing that some extended syntax is + // still allowed (but it is ignored) + testSuccess("max-age=100 ; includesubdomainsSomeStuff", 100, false); + testSuccess( + "\r\n\t\t \tcompletelyUnrelated = foobar; max-age= 34520103" + + "\t \t; alsoUnrelated;asIsThis;\tincludeSubdomains\t\t \t", + 34520103, + true + ); + testSuccess('max-age=100; unrelated="quoted \\"thingy\\""', 100, false); + + // SHOULD FAIL: + // invalid max-ages + testFailure("max-age"); + testFailure("max-age "); + testFailure("max-age=p"); + testFailure("max-age=*1p2"); + testFailure("max-age=.20032"); + testFailure("max-age=!20032"); + testFailure("max-age==20032"); + + // invalid headers + testFailure("foobar"); + testFailure("maxage=100"); + testFailure("maxa-ge=100"); + testFailure("max-ag=100"); + testFailure("includesubdomains"); + testFailure(";"); + testFailure('max-age="100'); + // The max-age directive here doesn't conform to the spec, so it MUST + // be ignored. Consequently, the REQUIRED max-age directive is not + // present in this header, and so it is invalid. + testFailure("max-age=100, max-age=200; includeSubdomains"); + testFailure("max-age=100 includesubdomains"); + testFailure("max-age=100 bar foo"); + testFailure("max-age=100randomstuffhere"); + // All directives MUST appear only once in an STS header field. + testFailure("max-age=100; max-age=200"); + testFailure("includeSubdomains; max-age=200; includeSubdomains"); + testFailure("max-age=200; includeSubdomains; includeSubdomains"); + // The includeSubdomains directive is valueless. + testFailure("max-age=100; includeSubdomains=unexpected"); + // LWS must have at least one space or horizontal tab + testFailure("\r\nmax-age=200"); +} diff --git a/security/manager/ssl/tests/unit/test_sts_preload_dynamic.js b/security/manager/ssl/tests/unit/test_sts_preload_dynamic.js new file mode 100644 index 0000000000..f66f13ddd9 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_preload_dynamic.js @@ -0,0 +1,86 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// 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/. + +"use strict"; + +// Tests the dynamic preloading of HPKP hosts: +// * checks that preloads can be set +// * checks that includeSubdomains is honored +// * checks that clearing preloads works correctly +// * checks that clearing a host's HSTS state via a header correctly +// overrides dynamic preload entries + +function run_test() { + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + let secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" + ].createInstance(Ci.nsITransportSecurityInfo); + let unlikelyHost = "highlyunlikely.example.com"; + let uri = Services.io.newURI("https://" + unlikelyHost); + let subDomainUri = Services.io.newURI("https://subdomain." + unlikelyHost); + + // first check that a host probably not on the preload list is not identified + // as an sts host + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // now add a preload entry for this host + SSService.setHSTSPreload(unlikelyHost, false, Date.now() + 60000); + + // check that it's now an STS host + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // check that it's honoring the fact we set includeSubdomains to false + ok( + !SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + 0 + ) + ); + + // clear the non-preloaded entries + SSService.clearAll(); + + // check that it's still an STS host + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // clear the preloads + SSService.clearPreloads(); + + // Check that it's no longer an STS host now that the preloads have been + // cleared + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // Now let's do the same, this time with includeSubdomains on + SSService.setHSTSPreload(unlikelyHost, true, Date.now() + 60000); + + // check that it's now an STS host + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // check that it's now including subdomains + ok( + SSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + 0 + ) + ); + + // Now let's simulate overriding the entry by setting an entry from a header + // with max-age set to 0 + SSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + + // this should no longer be an HSTS host + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); +} diff --git a/security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js b/security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js new file mode 100644 index 0000000000..142825829e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_preloadlist_perwindowpb.js @@ -0,0 +1,455 @@ +"use strict"; + +var gSSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService +); + +function Observer() {} +Observer.prototype = { + observe(subject, topic, data) { + if (topic == "last-pb-context-exited") { + run_next_test(); + } + }, +}; + +var gObserver = new Observer(); +var secInfo = Cc[ + "@mozilla.org/security/transportsecurityinfo;1" +].createInstance(Ci.nsITransportSecurityInfo); + +function cleanup() { + Services.obs.removeObserver(gObserver, "last-pb-context-exited"); + gSSService.clearAll(); +} + +function run_test() { + do_get_profile(); + + registerCleanupFunction(cleanup); + Services.obs.addObserver(gObserver, "last-pb-context-exited"); + + add_test(test_part1); + add_test(test_private_browsing1); + add_test(test_private_browsing2); + + run_next_test(); +} + +function test_part1() { + // check that a host not in the list is not identified as an sts host + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://nonexistent.example.com"), + 0 + ) + ); + + // check that an ancestor domain is not identified as an sts host + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://com"), + 0 + ) + ); + + // check that the pref to toggle using the preload list works + Services.prefs.setBoolPref( + "network.stricttransportsecurity.preloadlist", + false + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + Services.prefs.setBoolPref( + "network.stricttransportsecurity.preloadlist", + true + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + + // check that a subdomain is an sts host (includeSubdomains is set) + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://subdomain.includesubdomains.preloaded.test"), + 0 + ) + ); + + // check that another subdomain is an sts host (includeSubdomains is set) + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://a.b.c.def.includesubdomains.preloaded.test"), + 0 + ) + ); + + // check that a subdomain is not an sts host (includeSubdomains is not set) + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI( + "https://subdomain.noincludesubdomains.preloaded.test" + ), + 0 + ) + ); + + // check that a host with a dot on the end won't break anything + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://notsts.nonexistent.example.com."), + 0 + ) + ); + + // check that processing a header with max-age: 0 will remove a preloaded + // site from the list + let uri = Services.io.newURI("https://includesubdomains.preloaded.test"); + let subDomainUri = Services.io.newURI( + "https://subdomain.includesubdomains.preloaded.test" + ); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + 0 + ) + ); + // check that processing another header (with max-age non-zero) will + // re-enable a site's sts status + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + // but this time include subdomains was not set, so test for that + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + 0 + ) + ); + gSSService.clearAll(); + + // check that processing a header with max-age: 0 from a subdomain of a site + // will not remove that (ancestor) site from the list + uri = Services.io.newURI( + "https://subdomain.noincludesubdomains.preloaded.test" + ); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://noincludesubdomains.preloaded.test"), + 0 + ) + ); + ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + uri = Services.io.newURI( + "https://subdomain.includesubdomains.preloaded.test" + ); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + // we received a header with "max-age=0", so we have "no information" + // regarding the sts state of subdomain.includesubdomains.preloaded.test specifically, + // but it is actually still an STS host, because of the preloaded + // includesubdomains.preloaded.test including subdomains. + // Here's a drawing: + // |-- includesubdomains.preloaded.test (in preload list, includes subdomains) IS sts host + // |-- subdomain.includesubdomains.preloaded.test IS sts host + // | `-- another.subdomain.includesubdomains.preloaded.test IS sts host + // `-- sibling.includesubdomains.preloaded.test IS sts host + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://subdomain.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sibling.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI( + "https://another.subdomain.includesubdomains.preloaded.test" + ), + 0 + ) + ); + + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + // Here's what we have now: + // |-- includesubdomains.preloaded.test (in preload list, includes subdomains) IS sts host + // |-- subdomain.includesubdomains.preloaded.test (include subdomains is false) IS sts host + // | `-- another.subdomain.includesubdomains.preloaded.test IS NOT sts host + // `-- sibling.includesubdomains.preloaded.test IS sts host + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://subdomain.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://sibling.includesubdomains.preloaded.test"), + 0 + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI( + "https://another.subdomain.includesubdomains.preloaded.test" + ), + 0 + ) + ); + + // Test that an expired non-private browsing entry results in correctly + // identifying a host that is on the preload list as no longer sts. + // (This happens when we're in regular browsing mode, we get a header from + // a site on the preload list, and that header later expires. We need to + // then treat that host as no longer an sts host.) + // (sanity check first - this should be in the preload list) + uri = Services.io.newURI("https://includesubdomains2.preloaded.test"); + ok(gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1", + secInfo, + 0, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + do_timeout(1250, function() { + ok(!gSSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + run_next_test(); + }); +} + +const IS_PRIVATE = Ci.nsISocketProvider.NO_PERMANENT_STORAGE; + +function test_private_browsing1() { + gSSService.clearAll(); + let uri = Services.io.newURI("https://includesubdomains.preloaded.test"); + let subDomainUri = Services.io.newURI( + "https://a.b.c.subdomain.includesubdomains.preloaded.test" + ); + // sanity - includesubdomains.preloaded.test is preloaded, includeSubdomains set + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + IS_PRIVATE + ) + ); + + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + IS_PRIVATE, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + IS_PRIVATE + ) + ); + + // check adding it back in + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1000", + secInfo, + IS_PRIVATE, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + // but no includeSubdomains this time + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + IS_PRIVATE + ) + ); + + // do the hokey-pokey... + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=0", + secInfo, + IS_PRIVATE, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + subDomainUri, + IS_PRIVATE + ) + ); + + // Test that an expired private browsing entry results in correctly + // identifying a host that is on the preload list as no longer sts. + // (This happens when we're in private browsing mode, we get a header from + // a site on the preload list, and that header later expires. We need to + // then treat that host as no longer an sts host.) + // (sanity check first - this should be in the preload list) + uri = Services.io.newURI("https://includesubdomains2.preloaded.test"); + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + gSSService.processHeader( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + "max-age=1", + secInfo, + IS_PRIVATE, + Ci.nsISiteSecurityService.SOURCE_ORGANIC_REQUEST + ); + do_timeout(1250, function() { + ok( + !gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + uri, + IS_PRIVATE + ) + ); + // Simulate leaving private browsing mode + Services.obs.notifyObservers(null, "last-pb-context-exited"); + }); +} + +function test_private_browsing2() { + // if this test gets this far, it means there's a private browsing service + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains.preloaded.test"), + 0 + ) + ); + // the includesubdomains.preloaded.test entry has includeSubdomains set + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://subdomain.includesubdomains.preloaded.test"), + 0 + ) + ); + + // Now that we're out of private browsing mode, we need to make sure + // we've "forgotten" that we "forgot" this site's sts status. + ok( + gSSService.isSecureURI( + Ci.nsISiteSecurityService.HEADER_HSTS, + Services.io.newURI("https://includesubdomains2.preloaded.test"), + 0 + ) + ); + + run_next_test(); +} diff --git a/security/manager/ssl/tests/unit/test_sts_preloadlist_selfdestruct.js b/security/manager/ssl/tests/unit/test_sts_preloadlist_selfdestruct.js new file mode 100644 index 0000000000..897fcbd3be --- /dev/null +++ b/security/manager/ssl/tests/unit/test_sts_preloadlist_selfdestruct.js @@ -0,0 +1,22 @@ +"use strict"; + +function run_test() { + let SSService = Cc["@mozilla.org/ssservice;1"].getService( + Ci.nsISiteSecurityService + ); + let uri = Services.io.newURI("https://includesubdomains.preloaded.test"); + + // check that a host on the preload list is identified as an sts host + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // now simulate that it's 19 weeks later than it actually is + let offsetSeconds = 19 * 7 * 24 * 60 * 60; + Services.prefs.setIntPref("test.currentTimeOffsetSeconds", offsetSeconds); + + // check that the preloaded host is no longer considered sts + ok(!SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); + + // just make sure we can get everything back to normal + Services.prefs.clearUserPref("test.currentTimeOffsetSeconds"); + ok(SSService.isSecureURI(Ci.nsISiteSecurityService.HEADER_HSTS, uri, 0)); +} diff --git a/security/manager/ssl/tests/unit/test_validity.js b/security/manager/ssl/tests/unit/test_validity.js new file mode 100644 index 0000000000..1809faf24c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity.js @@ -0,0 +1,108 @@ +// -*- indent-tabs-mode: nil; js-indent-level: 2 -*- +// Any copyright is dedicated to the Public Domain. +// http://creativecommons.org/publicdomain/zero/1.0/ +"use strict"; + +// Tests that chains containing an end-entity cert with an overly long validity +// period are rejected. + +do_get_profile(); // Must be called before getting nsIX509CertDB +const certDB = Cc["@mozilla.org/security/x509certdb;1"].getService( + Ci.nsIX509CertDB +); + +const SERVER_PORT = 8888; + +function getOCSPResponder(expectedCertNames) { + let expectedPaths = expectedCertNames.slice(); + return startOCSPResponder( + SERVER_PORT, + "www.example.com", + "test_validity", + expectedCertNames, + expectedPaths + ); +} + +function certFromFile(filename) { + return constructCertFromFile(`test_validity/${filename}`); +} + +function loadCert(certFilename, trustString) { + addCertFromFile(certDB, `test_validity/${certFilename}`, trustString); +} + +/** + * Asynchronously runs a single EV test. + * + * @param {Array} expectedNamesForOCSP + * An array of nicknames of the certs to be responded to. + * @param {String} rootCertFileName + * The file name of the root cert. Can begin with ".." to reference + * certs in folders other than "test_validity/". + * @param {Array} intCertFileNames + * An array of file names of any intermediate certificates. + * @param {String} endEntityCertFileName + * The file name of the end entity cert. + * @param {Boolean} expectedResult + * Whether the chain is expected to validate as EV. + */ +async function doEVTest( + expectedNamesForOCSP, + rootCertFileName, + intCertFileNames, + endEntityCertFileName, + expectedResult +) { + clearOCSPCache(); + let ocspResponder = getOCSPResponder(expectedNamesForOCSP); + + loadCert(`${rootCertFileName}.pem`, "CTu,CTu,CTu"); + for (let intCertFileName of intCertFileNames) { + loadCert(`${intCertFileName}.pem`, ",,"); + } + await checkEVStatus( + certDB, + certFromFile(`${endEntityCertFileName}.pem`), + certificateUsageSSLServer, + expectedResult + ); + + await stopOCSPResponder(ocspResponder); +} + +async function checkEVChains() { + // Chain with an end entity cert with a validity period that is acceptable + // for EV. + const intFullName = "ev_int_60_months-evroot"; + let eeFullName = `ev_ee_27_months-${intFullName}`; + let expectedNamesForOCSP = gEVExpected + ? [intFullName, eeFullName] + : [eeFullName]; + await doEVTest( + expectedNamesForOCSP, + "../test_ev_certs/evroot", + [intFullName], + eeFullName, + gEVExpected + ); + + // Chain with an end entity cert with a validity period that is too long + // for EV. + eeFullName = `ev_ee_28_months-${intFullName}`; + expectedNamesForOCSP = gEVExpected ? [intFullName, eeFullName] : [eeFullName]; + await doEVTest( + expectedNamesForOCSP, + "../test_ev_certs/evroot", + [intFullName], + eeFullName, + false + ); +} + +add_task(async function() { + Services.prefs.setCharPref("network.dns.localDomains", "www.example.com"); + Services.prefs.setIntPref("security.OCSP.enabled", 1); + + await checkEVChains(); +}); diff --git a/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem b/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem new file mode 100644 index 0000000000..ea41b00545 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIUYYDQjys/AnzMoLUwrnp0+jqAmQMwDQYJKoZIhvcNAQEL +BQAwIjEgMB4GA1UEAwwXZXZfaW50XzYwX21vbnRocy1ldnJvb3QwIhgPMjAxOTEx +MTYxMjAwMDBaGA8yMDIyMDIxNjEyMDAwMFowMjEwMC4GA1UEAwwnZXZfZWVfMjdf +bW9udGhzLWV2X2ludF82MF9tb250aHMtZXZyb290MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GGMIGDMGAGCCsG +AQUFBwEBBFQwUjBQBggrBgEFBQcwAYZEaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4 +ODg4L2V2X2VlXzI3X21vbnRocy1ldl9pbnRfNjBfbW9udGhzLWV2cm9vdC8wHwYD +VR0gBBgwFjAUBhIrBgEEAetJhRqFGoUaAYN0CQEwDQYJKoZIhvcNAQELBQADggEB +AIP1/h4cT0t0hvLupI1lMwefjvlUtiXfTLW8u6BU8kEaENJybcWbIsCnPM2Bi2bz +AwxQ6ByBMyicnxzgiHZofC9ATxXUrIKHLOk5I8aW6FNvEcD4KdJoju3u/EmbaDjP +ORijvoa9gm9FQjl9SKYohfnjmOfNKcHQDQafnm4GHJV4nh7cIPfzl9kLrFYD9Hsu +Ct2Yo8qEaWltZ84JqZX2GYD0eNLDt6WSxhIDB1WcRhMsa/XNBm5TwzfGt1yx/Mqb +SHOKviSFUv5HTjJ/l5NDtzvUV+KVEcTA99Ve12Ok74JO7ChRG1U3nHONRKcfJWu9 +7va//Iq102BI6uilMkbGjlQ= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem.certspec new file mode 100644 index 0000000000..d2c7fa1275 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_ee_27_months-ev_int_60_months-evroot.pem.certspec @@ -0,0 +1,5 @@ +issuer:ev_int_60_months-evroot +subject:ev_ee_27_months-ev_int_60_months-evroot +validity:823 +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_27_months-ev_int_60_months-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem b/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem new file mode 100644 index 0000000000..672175fe84 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem @@ -0,0 +1,21 @@ +-----BEGIN CERTIFICATE----- +MIIDbTCCAlWgAwIBAgIUD55RmXcxc2Ubvzh7CUeXD5mJm20wDQYJKoZIhvcNAQEL +BQAwIjEgMB4GA1UEAwwXZXZfaW50XzYwX21vbnRocy1ldnJvb3QwIhgPMjAxOTEx +MDEwMDAwMDBaGA8yMDIyMDMwNDAwMDAwMFowMjEwMC4GA1UEAwwnZXZfZWVfMjhf +bW9udGhzLWV2X2ludF82MF9tb250aHMtZXZyb290MIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08E9nq5DVKtOz1aFdsJHvB +xyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc1SScAn7NQ/weadA4ICmT +qyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAPDY39ZgsrsCSSpH25iGF5 +kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQgAYkzBxsl62WYVu34pYS +wHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqVYR3uJtYlnauRCE42yxwk +BCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQIDAQABo4GGMIGDMGAGCCsG +AQUFBwEBBFQwUjBQBggrBgEFBQcwAYZEaHR0cDovL3d3dy5leGFtcGxlLmNvbTo4 +ODg4L2V2X2VlXzI4X21vbnRocy1ldl9pbnRfNjBfbW9udGhzLWV2cm9vdC8wHwYD +VR0gBBgwFjAUBhIrBgEEAetJhRqFGoUaAYN0CQEwDQYJKoZIhvcNAQELBQADggEB +AF1J9oNzg5u2a/E4nHHY1WgEPrMD3A4KFgprQxzzyebOqypMWK3+jXNdloF8AS8u +5mIQoLNNw/bCFb0zgpK+0qKwxGHkreN+eJyfoi+zJr2Ygf4BmRlb02t79v4mYcFN +rfCFSyvgwOI5aUr5n/BYFkUn38IAllJDn5igGGeROHSyOYZa9lOQZRAsh4vnas99 +V1RWo9E+hOmDH5be67HqJw4DHJ0sld8SWDxtjyXd6RbdJd4VIXScp2sk1W6F49Av +otRZSrZFaZeS95a9SmN+xhCfpL3VNF3YdHCbfYeam/A/AUlD0TFBSoqJo6l9nT1c +Of56pBg7jLup+dDdx7whu/w= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem.certspec new file mode 100644 index 0000000000..2dcfb2e29c --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_ee_28_months-ev_int_60_months-evroot.pem.certspec @@ -0,0 +1,5 @@ +issuer:ev_int_60_months-evroot +subject:ev_ee_28_months-ev_int_60_months-evroot +validity:854 +extension:authorityInformationAccess:http://www.example.com:8888/ev_ee_28_months-ev_int_60_months-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key new file mode 100644 index 0000000000..09e044f5e0 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC6iFGoRI4W1kH9 +braIBjYQPTwT2erkNUq07PVoV2wke8HHJajg2B+9sZwGm24ahvJr4q9adWtqZHEI +eqVap0WH9xzVJJwCfs1D/B5p0DggKZOrIMNJ5Nu5TMJrbA7tFYIP8X6taRqx0wI6 +iypB7qdw4A8Njf1mCyuwJJKkfbmIYXmQsVeQPdI7xeC4SB+oN9OIQ+8nFthVt2Za +qn4CkC86exCABiTMHGyXrZZhW7filhLAdTGjDJHdtMr3/K0dJdMJ77kXDqdo4bN7 +LyJvaeO0ipVhHe4m1iWdq5EITjbLHCQELL8Wiy/l8Y+ZFzG4s/5JI/pyUcQx1QOs +2hgKNe2NAgMBAAECggEBAJ7LzjhhpFTsseD+j4XdQ8kvWCXOLpl4hNDhqUnaosWs +VZskBFDlrJ/gw+McDu+mUlpl8MIhlABO4atGPd6e6CKHzJPnRqkZKcXmrD2IdT9s +JbpZeec+XY+yOREaPNq4pLDN9fnKsF8SM6ODNcZLVWBSXn47kq18dQTPHcfLAFeI +r8vh6Pld90AqFRUw1YCDRoZOs3CqeZVqWHhiy1M3kTB/cNkcltItABppAJuSPGgz +iMnzbLm16+ZDAgQceNkIIGuHAJy4yrrK09vbJ5L7kRss9NtmA1hb6a4Mo7jmQXqg +SwbkcOoaO1gcoDpngckxW2KzDmAR8iRyWUbuxXxtlEECgYEA3W4dT//r9o2InE0R +TNqqnKpjpZN0KGyKXCmnF7umA3VkTVyqZ0xLi8cyY1hkYiDkVQ12CKwn1Vttt0+N +gSfvj6CQmLaRR94GVXNEfhg9Iv59iFrOtRPZWB3V4HwakPXOCHneExNx7O/JznLp +xD3BJ9I4GQ3oEXc8pdGTAfSMdCsCgYEA16dz2evDgKdn0v7Ak0rU6LVmckB3Gs3r +ta15b0eP7E1FmF77yVMpaCicjYkQL63yHzTi3UlA66jAnW0fFtzClyl3TEMnXpJR +3b5JCeH9O/Hkvt9Go5uLODMo70rjuVuS8gcK8myefFybWH/t3gXo59hspXiG+xZY +EKd7mEW8MScCgYEAlkcrQaYQwK3hryJmwWAONnE1W6QtS1oOtOnX6zWBQAul3RMs +2xpekyjHu8C7sBVeoZKXLt+X0SdR2Pz2rlcqMLHqMJqHEt1OMyQdse5FX8CT9byb +WS11bmYhR08ywHryL7J100B5KzK6JZC7smGu+5WiWO6lN2VTFb6cJNGRmS0CgYAo +tFCnp1qFZBOyvab3pj49lk+57PUOOCPvbMjo+ibuQT+LnRIFVA8Su+egx2got7pl +rYPMpND+KiIBFOGzXQPVqFv+Jwa9UPzmz83VcbRspiG47UfWBbvnZbCqSgZlrCU2 +TaIBVAMuEgS4VZ0+NPtbF3yaVv+TUQpaSmKHwVHeLQKBgCgGe5NVgB0u9S36ltit +tYlnPPjuipxv9yruq+nva+WKT0q/BfeIlH3IUf2qNFQhR6caJGv7BU7naqNGq80m +ks/J5ExR5vBpxzXgc7oBn2pyFJYckbJoccrqv48GRBigJpDjmo1f8wZ7fNt/ULH1 +NBinA5ZsT8d0v3QCr2xDJH9D +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key.keyspec b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key.keyspec new file mode 100644 index 0000000000..4ad96d5159 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.key.keyspec @@ -0,0 +1 @@ +default diff --git a/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem new file mode 100644 index 0000000000..6fc6bdeec5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDVzCCAj+gAwIBAgIUGWNNFPvyjk63DRepZV/gB/+L1VUwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTgwNzAzMTIwMDAwWhgPMjAyMzA3 +MDIxMjAwMDBaMCIxIDAeBgNVBAMMF2V2X2ludF82MF9tb250aHMtZXZyb290MIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuohRqESOFtZB/W62iAY2ED08 +E9nq5DVKtOz1aFdsJHvBxyWo4NgfvbGcBptuGobya+KvWnVramRxCHqlWqdFh/cc +1SScAn7NQ/weadA4ICmTqyDDSeTbuUzCa2wO7RWCD/F+rWkasdMCOosqQe6ncOAP +DY39ZgsrsCSSpH25iGF5kLFXkD3SO8XguEgfqDfTiEPvJxbYVbdmWqp+ApAvOnsQ +gAYkzBxsl62WYVu34pYSwHUxowyR3bTK9/ytHSXTCe+5Fw6naOGzey8ib2njtIqV +YR3uJtYlnauRCE42yxwkBCy/Fosv5fGPmRcxuLP+SSP6clHEMdUDrNoYCjXtjQID +AQABo4GRMIGOMAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMFAGCCsGAQUFBwEB +BEQwQjBABggrBgEFBQcwAYY0aHR0cDovL3d3dy5leGFtcGxlLmNvbTo4ODg4L2V2 +X2ludF82MF9tb250aHMtZXZyb290LzAfBgNVHSAEGDAWMBQGEisGAQQB60mFGoUa +hRoBg3QJATANBgkqhkiG9w0BAQsFAAOCAQEADae0P+9+rtDogzf5zQega4VLX+Nj +tUru5/tU1IKifEGO1UibkrACklVZPh5I8A0scUNQVuvsSTmRSR3np25bhFtibs0T +7cx4x9Uwuk/KO2257NUJwj1tZFMdTCxkcIDOujU5XIWo3q1+b2MMgzwgcESjSV8K +1dUi0mDbhut9SjfimmUgfB+53ZVJDk40RTQIZYFvQy1XKnFpd0R/FXxz3YTZkICm +E0fAuSsif/wjopUgMnjgXHxA7bZYAuWQxgcZ28MRuqI9JESDZ3eH2oPUkYcpR8DK +FGd5wcJGvQtR2u/e3EmzcC9jZzBzZE7rvXuyl+AAwXhC25eq1Tqg/7XxjA== +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem.certspec b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem.certspec new file mode 100644 index 0000000000..e169514ffa --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/ev_int_60_months-evroot.pem.certspec @@ -0,0 +1,8 @@ +issuer:evroot +subject:ev_int_60_months-evroot +issuerKey:ev +validity:1825 +extension:basicConstraints:cA, +extension:keyUsage:cRLSign,keyCertSign +extension:authorityInformationAccess:http://www.example.com:8888/ev_int_60_months-evroot/ +extension:certificatePolicies:1.3.6.1.4.1.13769.666.666.666.1.500.9.1 diff --git a/security/manager/ssl/tests/unit/test_validity/evroot.key b/security/manager/ssl/tests/unit/test_validity/evroot.key new file mode 100644 index 0000000000..1d88a930d5 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/evroot.key @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEwAIBADANBgkqhkiG9w0BAQEFAASCBKowggSmAgEAAoIBAQC1SYlcnQAQjRGh ++Z+HqePRpdtd+uzxiNpXv2QTaI8s5HIs/xCQOMF0Ask6Kkc9vShq7T/c02PPWikU +dwG92BjXYVv5NWvV08gzaqqMCXE2igbDzURhuT5RQk4XRLsuqtRqqzjOGWghlh+H +cUoWY2k/CXYc301roSXqzse+Jw04j3ifbN94rjFE7SjEXnkpOGOnoipImAo2pA5y +1XnJuSXf+MeTNi/9aJenwXVMXpfJZ8Pq3RquiqLMzjSKAWm4Diii1wwalgxvM18t +oJubZD9av7pJ6Kqpgelg4n2HSAvdVd2UF/oYUJ+7VUzPgaQ5fouoEoo0vfJ4ZcGJ +5XNPsikFAgMBAAECggEBAJg9VPlNb0x26yPW+T14UjUwz3Ow0WJUxueBdo1F9VaB +0dAvsr0qrGq8HDiYYJNcUqDY9BSCAQOUd4MUHYZL/zCANjilwBUlcK6dGPPYyhY+ ++0dbDd3zLn4W7HVl5rteAlxBxcZuV6A87eVUIh+DBFNHosTEUcPc5Ha3h84MBXJE +vp4E7xMRjbuz1eCmzIcCnq/Upp7ZsUdZsV452KmITlb1TS+asBPw0V8xipq2svc9 +HsPJ/idK6JQxoQZAvniZsAEcXlCToYNHCGid4QBjTaveYPvWqu+joz3zSh829gwE +MDa3SNHJ7pjEAxoK/sYO/aCpkL5ST1YU6sT9s0pS+VECgYEA6twssz5f8co3a72V +vWoXd9LPT6xHVF6S0RpiCbnV5N7UeDRYHBabPIhHQqCeoYdQXBylVBTY0ltJdjLV +7CqqBSM0MPrUmJJ3en1o4Dj1YaO4lp5gsKJj3vv9pIqbD/OdlbyIsVJnyK3pe1EH +lI5B5DMknYf32xCdXXRYTYa8wdcCgYEAxZrldqIWRwJI2USlW56b+TKZ2jQexW5V +jrqCGrzhv1e3nPQR0pBMd0+duh8VGF9gewV0oIIF1uwotmo21jQjLqry/qN1Yauv +nWRLaNs4yZZMuMluwKxh66ZNBbRGVC9COXb1rN5OzJVTbS31eJVPk/DP2cWPt4ui +p23VrChNyIMCgYEAwdLvOQYzHFKspkgR+f5CW+somDIvs9tRAyzo1+n8MiQL6SAZ +zySA/NXjKYNxJxGLKlmhv+BsiD46REfz8DHNmuvQuNNo/Hl0DSzOjq2zJN9/CR6v +4VZDYdVJILAbBHEjDl5H2T+O0zljxRe8T8ePbYsfnrqFvM7bcDMCZQjbYoUCgYEA +hSG421aU376ASjFfnvybZSdcVJCs8qNFbWXm5hC/n2R/xnUB1PV3LyMqxwzN75/C +pt+kFcfEG2r8evnQfDygP37ZPAnwuZ8sMEQ0Mi8QcXCbvBuqTJFXX6apWeB9SZaV +bZXiK1eTi25HyNUf/t/Jv4iM4NGj5CtlqJvtS5HT5fUCgYEA3El7BrkgyL4LAHe3 +mOl37vdEqQ7Cxdfmy7IkSPrHLagaMxgODYoC6DFGDH/H/TphL3uZMLYbeZ+OkI5j +LpugQJtqpwsDo7p4dCYmO1vVhD34R27bXRT2qGE+uvW5zVykL1+9KALgjk5J5XCf +UVFRDKpassHG6z7+kpXRbowlyRY= +-----END PRIVATE KEY----- diff --git a/security/manager/ssl/tests/unit/test_validity/evroot.key.keyspec b/security/manager/ssl/tests/unit/test_validity/evroot.key.keyspec new file mode 100644 index 0000000000..1a3d76a550 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/evroot.key.keyspec @@ -0,0 +1 @@ +ev diff --git a/security/manager/ssl/tests/unit/test_validity/evroot.pem b/security/manager/ssl/tests/unit/test_validity/evroot.pem new file mode 100644 index 0000000000..13c3031905 --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/evroot.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC0TCCAbmgAwIBAgIUIZSHsVgzcvhPgdfrgdMGlpSfMegwDQYJKoZIhvcNAQEL +BQAwETEPMA0GA1UEAwwGZXZyb290MCIYDzIwMTUwMTAxMDAwMDAwWhgPMjAzNTAx +MDEwMDAwMDBaMBExDzANBgNVBAMMBmV2cm9vdDCCASIwDQYJKoZIhvcNAQEBBQAD +ggEPADCCAQoCggEBALVJiVydABCNEaH5n4ep49Gl21367PGI2le/ZBNojyzkciz/ +EJA4wXQCyToqRz29KGrtP9zTY89aKRR3Ab3YGNdhW/k1a9XTyDNqqowJcTaKBsPN +RGG5PlFCThdEuy6q1GqrOM4ZaCGWH4dxShZjaT8JdhzfTWuhJerOx74nDTiPeJ9s +33iuMUTtKMReeSk4Y6eiKkiYCjakDnLVecm5Jd/4x5M2L/1ol6fBdUxel8lnw+rd +Gq6KoszONIoBabgOKKLXDBqWDG8zXy2gm5tkP1q/uknoqqmB6WDifYdIC91V3ZQX ++hhQn7tVTM+BpDl+i6gSijS98nhlwYnlc0+yKQUCAwEAAaMdMBswDAYDVR0TBAUw +AwEB/zALBgNVHQ8EBAMCAQYwDQYJKoZIhvcNAQELBQADggEBABTOHA9XbfLv/C7+ +5KycYXToOIBRSjQ0j2nsiqFda4Jx+aKsvdpdrrbLHvhrpfsA3ZgB2+eKHunVc4fo +UHNqZllAs2nx+AEinq4GX8iya5BpiyTIxXWu8v06siGgz1GxlJw1cJ/ZnFEQ9IBf +cCAr5fCoZ4RC+2OVhiSTnYPCKM+zCyw3YpISjNOg1VVkp46Htp+831Eh12YfwvdY +Fgh1fc5ohYC5GCLRuXKc9PGTsr3gp7Y0liYbK7v0RBjd+GivNQ3dS3W+lB3Ow0LH +z/fc3qvrhsd58jHpb1QZQzd9bQjuIIM6Gij7TNdNNarEVZfSJjPYLfXosNdYh5fH +HmbOwao= +-----END CERTIFICATE----- diff --git a/security/manager/ssl/tests/unit/test_validity/evroot.pem.certspec b/security/manager/ssl/tests/unit/test_validity/evroot.pem.certspec new file mode 100644 index 0000000000..3121f3486e --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/evroot.pem.certspec @@ -0,0 +1,7 @@ +issuer:evroot +subject:evroot +subjectKey:ev +issuerKey:ev +validity:20150101-20350101 +extension:basicConstraints:cA, +extension:keyUsage:keyCertSign,cRLSign diff --git a/security/manager/ssl/tests/unit/test_validity/moz.build b/security/manager/ssl/tests/unit/test_validity/moz.build new file mode 100644 index 0000000000..9121c4e49b --- /dev/null +++ b/security/manager/ssl/tests/unit/test_validity/moz.build @@ -0,0 +1,24 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# Temporarily disabled. See bug 1256495. +# test_certificates = ( +# 'ev_ee_27_months-ev_int_60_months-evroot.pem', +# 'ev_ee_28_months-ev_int_60_months-evroot.pem', +# 'ev_int_60_months-evroot.pem', +# 'evroot.pem', +# ) +# +# for test_certificate in test_certificates: +# GeneratedTestCertificate(test_certificate) +# +# test_keys = ( +# 'ev_int_60_months-evroot.key', +# 'evroot.key', +# ) +# +# for test_key in test_keys: +# GeneratedTestKey(test_key) diff --git a/security/manager/ssl/tests/unit/test_x509.js b/security/manager/ssl/tests/unit/test_x509.js new file mode 100644 index 0000000000..73eb4ed97a --- /dev/null +++ b/security/manager/ssl/tests/unit/test_x509.js @@ -0,0 +1,142 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +// Tests X509.jsm functionality. + +function stringToArray(s) { + let b = []; + for (let i = 0; i < s.length; i++) { + b.push(s.charCodeAt(i)); + } + return b; +} + +function readPEMToBytes(filename) { + return stringToArray(atob(pemToBase64(readFile(do_get_file(filename))))); +} + +function run_test() { + let certificate = new X509.Certificate(); + // We use this certificate because it has a set validity period, which means that when + // the test certificates get regenerated each year, the values in this test won't change. + certificate.parse(readPEMToBytes("bad_certs/expired-ee.pem")); + + equal( + certificate.tbsCertificate.version, + 3, + "expired-ee.pem should be x509v3" + ); + + // serialNumber + deepEqual( + certificate.tbsCertificate.serialNumber, + [ + 0x63, + 0xd1, + 0x11, + 0x00, + 0x82, + 0xa3, + 0xd2, + 0x3b, + 0x3f, + 0x61, + 0xb8, + 0x49, + 0xa0, + 0xca, + 0xdc, + 0x2e, + 0x78, + 0xfe, + 0xfa, + 0xea, + ], + "expired-ee.pem should have expected serialNumber" + ); + + deepEqual( + certificate.tbsCertificate.signature.algorithm._values, + [1, 2, 840, 113549, 1, 1, 11], // sha256WithRSAEncryption + "expired-ee.pem should have sha256WithRSAEncryption signature" + ); + deepEqual( + certificate.tbsCertificate.signature.parameters._contents, + [], + "expired-ee.pem should have NULL parameters for signature" + ); + + equal( + certificate.tbsCertificate.issuer.rdns.length, + 1, + "expired-ee.pem should have one RDN in issuer" + ); + equal( + certificate.tbsCertificate.issuer.rdns[0].avas.length, + 1, + "expired-ee.pem should have one AVA in RDN in issuer" + ); + deepEqual( + certificate.tbsCertificate.issuer.rdns[0].avas[0].value.value, + stringToArray("Test CA"), + "expired-ee.pem should have issuer 'Test CA'" + ); + + equal( + certificate.tbsCertificate.validity.notBefore.time.getTime(), + Date.parse("2013-01-01T00:00:00.000Z"), + "expired-ee.pem should have the correct value for notBefore" + ); + equal( + certificate.tbsCertificate.validity.notAfter.time.getTime(), + Date.parse("2014-01-01T00:00:00.000Z"), + "expired-ee.pem should have the correct value for notAfter" + ); + + equal( + certificate.tbsCertificate.subject.rdns.length, + 1, + "expired-ee.pem should have one RDN in subject" + ); + equal( + certificate.tbsCertificate.subject.rdns[0].avas.length, + 1, + "expired-ee.pem should have one AVA in RDN in subject" + ); + deepEqual( + certificate.tbsCertificate.subject.rdns[0].avas[0].value.value, + stringToArray("Expired Test End-entity"), + "expired-ee.pem should have subject 'Expired Test End-entity'" + ); + + deepEqual( + certificate.tbsCertificate.subjectPublicKeyInfo.algorithm.algorithm._values, + [1, 2, 840, 113549, 1, 1, 1], // rsaEncryption + "expired-ee.pem should have a spki algorithm of rsaEncryption" + ); + + equal( + certificate.tbsCertificate.extensions.length, + 2, + "expired-ee.pem should have two extensions" + ); + + deepEqual( + certificate.signatureAlgorithm.algorithm._values, + [1, 2, 840, 113549, 1, 1, 11], // sha256WithRSAEncryption + "expired-ee.pem should have sha256WithRSAEncryption signatureAlgorithm" + ); + deepEqual( + certificate.signatureAlgorithm.parameters._contents, + [], + "expired-ee.pem should have NULL parameters for signatureAlgorithm" + ); + + equal( + certificate.signatureValue.length, + 2048 / 8, + "length of signature on expired-ee.pem should be 2048 bits" + ); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertAndPinningServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertAndPinningServer.cpp new file mode 100644 index 0000000000..b13d2e9e61 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertAndPinningServer.cpp @@ -0,0 +1,140 @@ +/* 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/. */ + +// This is a standalone server that uses various bad certificates. +// The client is expected to connect, initiate an SSL handshake (with SNI +// to indicate which "server" to connect to), and verify the certificate. +// If all is good, the client then sends one encrypted byte and receives that +// same byte back. +// This server also has the ability to "call back" another process waiting on +// it. That is, when the server is all set up and ready to receive connections, +// it will connect to a specified port and issue a simple HTTP request. + +#include + +#include "TLSServer.h" + +using namespace mozilla; +using namespace mozilla::test; + +struct BadCertAndPinningHost { + const char* mHostName; + const char* mCertName; +}; + +// Hostname, cert nickname pairs. +const BadCertAndPinningHost sBadCertAndPinningHosts[] = { + {"expired.example.com", "expired-ee"}, + {"notyetvalid.example.com", "notYetValid"}, + {"before-epoch.example.com", "beforeEpoch"}, + {"selfsigned.example.com", "selfsigned"}, + {"unknownissuer.example.com", "unknownissuer"}, + {"mismatch.example.com", "mismatch"}, + {"mismatch-CN.example.com", "mismatchCN"}, + {"mitm.example.com", "mitm"}, + {"expiredissuer.example.com", "expiredissuer"}, + {"notyetvalidissuer.example.com", "notYetValidIssuer"}, + {"before-epoch-issuer.example.com", "beforeEpochIssuer"}, + {"md5signature.example.com", "md5signature"}, + {"untrusted.example.com", "default-ee"}, + {"untrustedissuer.example.com", "untrustedissuer"}, + {"mismatch-expired.example.com", "mismatch-expired"}, + {"mismatch-notYetValid.example.com", "mismatch-notYetValid"}, + {"mismatch-untrusted.example.com", "mismatch-untrusted"}, + {"untrusted-expired.example.com", "untrusted-expired"}, + {"md5signature-expired.example.com", "md5signature-expired"}, + {"mismatch-untrusted-expired.example.com", "mismatch-untrusted-expired"}, + {"inadequatekeyusage.example.com", "inadequatekeyusage-ee"}, + {"selfsigned-inadequateEKU.example.com", "selfsigned-inadequateEKU"}, + {"self-signed-end-entity-with-cA-true.example.com", + "self-signed-EE-with-cA-true"}, + {"ca-used-as-end-entity.example.com", "ca-used-as-end-entity"}, + {"ca-used-as-end-entity-name-mismatch.example.com", + "ca-used-as-end-entity"}, + // All of include-subdomains.pinning.example.com is pinned to End Entity + // Test Cert with nick default-ee. Any other nick will only + // pass pinning when security.cert_pinning.enforcement.level != strict and + // otherCA is added as a user-specified trust anchor. See StaticHPKPins.h. + {"include-subdomains.pinning.example.com", "default-ee"}, + {"good.include-subdomains.pinning.example.com", "default-ee"}, + {"bad.include-subdomains.pinning.example.com", "other-issuer-ee"}, + {"bad.include-subdomains.pinning.example.com.", "other-issuer-ee"}, + {"bad.include-subdomains.pinning.example.com..", "other-issuer-ee"}, + {"exclude-subdomains.pinning.example.com", "default-ee"}, + {"sub.exclude-subdomains.pinning.example.com", "other-issuer-ee"}, + {"test-mode.pinning.example.com", "other-issuer-ee"}, + {"unknownissuer.include-subdomains.pinning.example.com", "unknownissuer"}, + {"unknownissuer.test-mode.pinning.example.com", "unknownissuer"}, + {"nsCertTypeNotCritical.example.com", "nsCertTypeNotCritical"}, + {"nsCertTypeCriticalWithExtKeyUsage.example.com", + "nsCertTypeCriticalWithExtKeyUsage"}, + {"nsCertTypeCritical.example.com", "nsCertTypeCritical"}, + {"end-entity-issued-by-v1-cert.example.com", "eeIssuedByV1Cert"}, + {"end-entity-issued-by-non-CA.example.com", "eeIssuedByNonCA"}, + {"inadequate-key-size-ee.example.com", "inadequateKeySizeEE"}, + {"badSubjectAltNames.example.com", "badSubjectAltNames"}, + {"ipAddressAsDNSNameInSAN.example.com", "ipAddressAsDNSNameInSAN"}, + {"noValidNames.example.com", "noValidNames"}, + {"bug413909.xn--hxajbheg2az3al.xn--jxalpdlp", "idn-certificate"}, + {"emptyissuername.example.com", "emptyIssuerName"}, + {"ev-test.example.com", "ev-test"}, + {"ee-from-missing-intermediate.example.com", + "ee-from-missing-intermediate"}, + {"imminently-distrusted.example.com", "ee-imminently-distrusted"}, + {"localhost", "unknownissuer"}, + {"a.pinning.example.com", "default-ee"}, + {"b.pinning.example.com", "default-ee"}, + {"not-preloaded.example.com", "default-ee"}, + {"ee.example.com", "default-ee"}, + {nullptr, nullptr}}; + +int32_t DoSNISocketConfigBySubjectCN(PRFileDesc* aFd, + const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize) { + for (uint32_t i = 0; i < aSrvNameArrSize; i++) { + UniquePORTString name( + static_cast(PORT_ZAlloc(aSrvNameArr[i].len + 1))); + if (name) { + PORT_Memcpy(name.get(), aSrvNameArr[i].data, aSrvNameArr[i].len); + if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr, + nullptr) == SECSuccess) { + return 0; + } + } + } + + return SSL_SNI_SEND_ALERT; +} + +int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, void* aArg) { + const BadCertAndPinningHost* host = + GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sBadCertAndPinningHosts); + if (!host) { + // No static cert <-> hostname mapping found. This happens when we use a + // collection of certificates in a given directory and build a cert DB at + // runtime, rather than using an NSS cert DB populated at build time. + // (This will be the default in the future.) + // For all given server names, check if the runtime-built cert DB contains + // a certificate with a matching subject CN. + return DoSNISocketConfigBySubjectCN(aFd, aSrvNameArr, aSrvNameArrSize); + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); + } + + UniqueCERTCertificate cert; + SSLKEAType certKEA; + if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert, + &certKEA, nullptr)) { + return SSL_SNI_SEND_ALERT; + } + + return 0; +} + +int main(int argc, char* argv[]) { + return StartServer(argc, argv, DoSNISocketConfig, nullptr); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/DelegatedCredentialsServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/DelegatedCredentialsServer.cpp new file mode 100644 index 0000000000..5f12756425 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/DelegatedCredentialsServer.cpp @@ -0,0 +1,142 @@ +/* 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/. */ + +// This is a standalone server used to test Delegated Credentials +// (see: https://tools.ietf.org/html/draft-ietf-tls-subcerts-03). +// +// The client is expected to connect, initiate an SSL handshake (with SNI +// to indicate which "server" to connect to), and verify the certificate. +// If all is good, the client then sends one encrypted byte and receives that +// same byte back. +// This server also has the ability to "call back" another process waiting on +// it. That is, when the server is all set up and ready to receive connections, +// it will connect to a specified port and issue a simple HTTP request. + +#include + +#include "TLSServer.h" + +#include "sslexp.h" + +using namespace mozilla; +using namespace mozilla::test; + +struct DelegatedCertHost { + const char* mHostName; + const char* mCertName; + const char* mDCKeyNick; + bool mEnableDelegatedCredentials; +}; + +const PRUint32 kDCValidFor = 60 * 60 * 24 * 7 /* 1 week (seconds) */; + +// {host, eeCert, dcCert, enableDC} +const DelegatedCertHost sDelegatedCertHosts[] = { + {"delegated-enabled.example.com", "delegated-ee", "delegated.key", true}, + {"standard-enabled.example.com", "default-ee", "delegated.key", true}, + {"delegated-disabled.example.com", "delegated-ee", + /* anything non-null */ "delegated.key", false}, + {nullptr, nullptr, nullptr, false}}; + +int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, void* aArg) { + const DelegatedCertHost* host = + GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sDelegatedCertHosts); + if (!host) { + return SSL_SNI_SEND_ALERT; + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + std::cerr << "Identified host " << host->mHostName << std::endl; + } + + UniqueCERTCertificate delegatorCert( + PK11_FindCertFromNickname(host->mCertName, nullptr)); + if (!delegatorCert) { + PrintPRError("PK11_FindCertFromNickname failed"); + return SSL_SNI_SEND_ALERT; + } + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return SSL_SNI_SEND_ALERT; + } + + SSLExtraServerCertData extra_data = {ssl_auth_null, + /* Filled in by callee */ nullptr, + nullptr, + nullptr, + /* DC */ nullptr, + /* DC PrivKey */ nullptr}; + + UniqueSECKEYPrivateKey delegatorPriv( + PK11_FindKeyByDERCert(slot.get(), delegatorCert.get(), nullptr)); + if (!delegatorPriv) { + PrintPRError("PK11_FindKeyByDERCert failed"); + return SSL_SNI_SEND_ALERT; + } + + // Find the DC keypair by the file (nick) name. + ScopedAutoSECItem dc; + UniqueSECKEYPrivateKey dcPriv; + if (host->mEnableDelegatedCredentials) { + if (gDebugLevel >= DEBUG_VERBOSE) { + std::cerr << "Enabling a delegated credential for host " + << host->mHostName << std::endl; + } + + if (PK11_NeedLogin(slot.get())) { + SECStatus rv = PK11_Authenticate(slot.get(), PR_TRUE, nullptr); + if (rv != SECSuccess) { + PrintPRError("PK11_Authenticate failed"); + return SSL_SNI_SEND_ALERT; + } + } + UniqueSECKEYPrivateKeyList list(PK11_ListPrivKeysInSlot( + slot.get(), const_cast(host->mDCKeyNick), nullptr)); + if (!list) { + PrintPRError("PK11_ListPrivKeysInSlot failed"); + return SSL_SNI_SEND_ALERT; + } + SECKEYPrivateKeyListNode* node = PRIVKEY_LIST_HEAD(list); + + dcPriv.reset(SECKEY_CopyPrivateKey(node->key)); + if (!dcPriv) { + PrintPRError("PK11_ListPrivKeysInSlot could not find dcPriv"); + return SSL_SNI_SEND_ALERT; + } + + UniqueSECKEYPublicKey dcPub(SECKEY_ConvertToPublicKey(dcPriv.get())); + if (!dcPub) { + PrintPRError("SECKEY_ConvertToPublicKey failed"); + return SSL_SNI_SEND_ALERT; + } + + // Create and set the DC. + if (SSL_DelegateCredential(delegatorCert.get(), delegatorPriv.get(), + dcPub.get(), ssl_sig_ecdsa_secp384r1_sha384, + kDCValidFor, PR_Now(), &dc) != SECSuccess) { + PrintPRError("SSL_DelegateCredential failed"); + return SSL_SNI_SEND_ALERT; + } + extra_data.delegCred = &dc; + extra_data.delegCredPrivKey = dcPriv.get(); + + // The list should only have a single key. + PORT_Assert(PRIVKEY_LIST_END(PRIVKEY_LIST_NEXT(node), list)); + } + + if (ConfigSecureServerWithNamedCert(aFd, host->mCertName, nullptr, nullptr, + &extra_data) != SECSuccess) { + PrintPRError("ConfigSecureServerWithNamedCert failed"); + return SSL_SNI_SEND_ALERT; + } + + return 0; +} + +int main(int argc, char* argv[]) { + return StartServer(argc, argv, DoSNISocketConfig, nullptr); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/EncryptedClientHelloServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/EncryptedClientHelloServer.cpp new file mode 100644 index 0000000000..f768b888f6 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/EncryptedClientHelloServer.cpp @@ -0,0 +1,143 @@ +/* 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/. */ + +// This is a standalone server that offers TLS 1.3 Encrypted +// Client Hello support. + +#include + +#include "nspr.h" +#include "ScopedNSSTypes.h" +#include "ssl.h" +#include "sslexp.h" +#include "TLSServer.h" +#include +#include + +using namespace mozilla; +using namespace mozilla::test; + +struct EchHost { + const char* mHostName; + const char* mCertName; +}; + +const std::vector kSuiteChaCha = { + (static_cast(HpkeKdfHkdfSha256) << 16) | + HpkeAeadChaCha20Poly1305}; + +// Hostname, cert nickname pairs. +const EchHost sEchHosts[] = {{"ech-public.example.com", "default-ee"}, + {"ech-private.example.com", "private-ee"}, + {"selfsigned.example.com", "selfsigned"}, + {nullptr, nullptr}}; + +int32_t DoSNISocketConfigBySubjectCN(PRFileDesc* aFd, + const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize) { + for (uint32_t i = 0; i < aSrvNameArrSize; i++) { + UniquePORTString name( + static_cast(PORT_ZAlloc(aSrvNameArr[i].len + 1))); + if (name) { + PORT_Memcpy(name.get(), aSrvNameArr[i].data, aSrvNameArr[i].len); + if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr, + nullptr) == SECSuccess) { + return 0; + } + } + } + + return SSL_SNI_SEND_ALERT; +} + +int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, void* aArg) { + const EchHost* host = GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sEchHosts); + if (!host) { + PrintPRError("No cert found for hostname"); + return SSL_SNI_SEND_ALERT; + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); + } + + UniqueCERTCertificate cert; + SSLKEAType certKEA; + if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert, + &certKEA, nullptr)) { + return SSL_SNI_SEND_ALERT; + } + + return 0; +} + +SECStatus ConfigureServer(PRFileDesc* aFd) { + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return SECFailure; + } + + UniqueSECKEYPublicKey pubKey; + UniqueSECKEYPrivateKey privKey; + SECKEYPublicKey* tmpPubKey = nullptr; + SECKEYPrivateKey* tmpPrivKey = nullptr; + + static const std::vector pkcs8{ + 0x30, 0x67, 0x02, 0x01, 0x00, 0x30, 0x14, 0x06, 0x07, 0x2a, 0x86, 0x48, + 0xce, 0x3d, 0x02, 0x01, 0x06, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, + 0x47, 0x0f, 0x01, 0x04, 0x4c, 0x30, 0x4a, 0x02, 0x01, 0x01, 0x04, 0x20, + 0x8c, 0x49, 0x0e, 0x5b, 0x0c, 0x7d, 0xbe, 0x0c, 0x6d, 0x21, 0x92, 0x48, + 0x4d, 0x2b, 0x7a, 0x04, 0x23, 0xb3, 0xb4, 0x54, 0x4f, 0x24, 0x81, 0x09, + 0x5a, 0x99, 0xdb, 0xf2, 0x38, 0xfb, 0x35, 0x0f, 0xa1, 0x23, 0x03, 0x21, + 0x00, 0x8a, 0x07, 0x56, 0x39, 0x49, 0xfa, 0xc6, 0x23, 0x29, 0x36, 0xed, + 0x6f, 0x36, 0xc4, 0xfa, 0x73, 0x59, 0x30, 0xec, 0xde, 0xae, 0xf6, 0x73, + 0x4e, 0x31, 0x4a, 0xea, 0xc3, 0x5a, 0x56, 0xfd, 0x0a}; + + SECItem pkcs8Item = {siBuffer, const_cast(pkcs8.data()), + static_cast(pkcs8.size())}; + SECStatus rv = PK11_ImportDERPrivateKeyInfoAndReturnKey( + slot.get(), &pkcs8Item, nullptr, nullptr, false, false, KU_ALL, + &tmpPrivKey, nullptr); + + if (rv != SECSuccess) { + PrintPRError("PK11_ImportDERPrivateKeyInfoAndReturnKey failed"); + return SECFailure; + } + privKey.reset(tmpPrivKey); + tmpPubKey = SECKEY_ConvertToPublicKey(privKey.get()); + pubKey.reset(tmpPubKey); + + if (!privKey || !pubKey) { + PrintPRError("ECH/HPKE Public or Private key is null!"); + return SECFailure; + } + + std::vector echConfig(1000, 0); + unsigned int len = 0; + rv = SSL_EncodeEchConfig("ech-public.example.com", kSuiteChaCha.data(), 1, + HpkeDhKemX25519Sha256, pubKey.get(), 50, + echConfig.data(), &len, echConfig.size()); + if (rv != SECSuccess) { + PrintPRError("SSL_EncodeEchConfig failed"); + return rv; + } + + rv = SSL_SetServerEchConfigs(aFd, pubKey.get(), privKey.get(), + echConfig.data(), len); + if (rv != SECSuccess) { + PrintPRError("SSL_SetServerEchConfigs failed"); + return rv; + } + + return SECSuccess; +} + +int main(int argc, char* argv[]) { + int rv = StartServer(argc, argv, DoSNISocketConfig, nullptr, ConfigureServer); + if (rv < 0) { + return rv; + } +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp new file mode 100644 index 0000000000..113e668f89 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/GenerateOCSPResponse.cpp @@ -0,0 +1,168 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 tw=80 et: */ +/* 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/. */ + +/* This simple program takes a database directory, and one or more tuples like + * + * to generate (one or more) ocsp responses. + */ + +#include +#include +#include + +#include "mozilla/ArrayUtils.h" + +#include "cert.h" +#include "nspr.h" +#include "nss.h" +#include "plarenas.h" +#include "prerror.h" +#include "ssl.h" +#include "secerr.h" + +#include "OCSPCommon.h" +#include "ScopedNSSTypes.h" +#include "TLSServer.h" + +using namespace mozilla; +using namespace mozilla::test; + +struct OCSPResponseName { + const char* mTypeString; + const OCSPResponseType mORT; +}; + +const static OCSPResponseName kOCSPResponseNameList[] = { + {"good", ORTGood}, // the certificate is good + {"good-delegated", ORTDelegatedIncluded}, // the certificate is good, using + // a delegated signer + {"revoked", ORTRevoked}, // the certificate has been revoked + {"unknown", ORTUnknown}, // the responder doesn't know if the + // cert is good + {"goodotherca", ORTGoodOtherCA}, // the wrong CA has signed the + // response + {"expiredresponse", ORTExpired}, // the signature on the response has + // expired + {"oldvalidperiod", ORTExpiredFreshCA}, // fresh signature, but old validity + // period + {"empty", ORTEmpty}, // an empty stapled response + + {"malformed", ORTMalformed}, // the response from the responder + // was malformed + {"serverr", ORTSrverr}, // the response indicates there was a + // server error + {"trylater", ORTTryLater}, // the responder replied with + // "try again later" + {"resp-unsigned", ORTNeedsSig}, // the response needs a signature + {"unauthorized", ORTUnauthorized}, // the responder does not know about + // the cert + {"bad-signature", ORTBadSignature}, // the response has a bad signature + {"longvalidityalmostold", + ORTLongValidityAlmostExpired}, // the response is + // still valid, but the generation + // is almost a year old + {"ancientstillvalid", ORTAncientAlmostExpired}, // The response is still + // valid but the generation + // is almost two years old +}; + +bool StringToOCSPResponseType(const char* respText, + /*out*/ OCSPResponseType* OCSPType) { + if (!OCSPType) { + return false; + } + for (auto ocspResponseName : kOCSPResponseNameList) { + if (strcmp(respText, ocspResponseName.mTypeString) == 0) { + *OCSPType = ocspResponseName.mORT; + return true; + } + } + return false; +} + +bool WriteResponse(const char* filename, const SECItem* item) { + if (!filename || !item || !item->data) { + PR_fprintf(PR_STDERR, "invalid parameters to WriteResponse"); + return false; + } + + UniquePRFileDesc outFile( + PR_Open(filename, PR_WRONLY | PR_CREATE_FILE | PR_TRUNCATE, 0644)); + if (!outFile) { + PrintPRError("cannot open file for writing"); + return false; + } + int32_t rv = PR_Write(outFile.get(), item->data, item->len); + if (rv < 0 || (uint32_t)rv != item->len) { + PrintPRError("File write failure"); + return false; + } + + return true; +} + +int main(int argc, char* argv[]) { + if (argc < 7 || (argc - 7) % 5 != 0) { + PR_fprintf( + PR_STDERR, + "usage: %s " + " [ " + " ]* \n", + argv[0]); + exit(EXIT_FAILURE); + } + SECStatus rv = InitializeNSS(argv[1]); + if (rv != SECSuccess) { + PR_fprintf(PR_STDERR, "Failed to initialize NSS\n"); + exit(EXIT_FAILURE); + } + UniquePLArenaPool arena(PORT_NewArena(256 * argc)); + if (!arena) { + PrintPRError("PORT_NewArena failed"); + exit(EXIT_FAILURE); + } + + for (int i = 2; i + 3 < argc; i += 5) { + const char* ocspTypeText = argv[i]; + const char* certNick = argv[i + 1]; + const char* extraCertname = argv[i + 2]; + const char* skewChars = argv[i + 3]; + const char* filename = argv[i + 4]; + + OCSPResponseType ORT; + if (!StringToOCSPResponseType(ocspTypeText, &ORT)) { + PR_fprintf(PR_STDERR, "Cannot generate OCSP response of type %s\n", + ocspTypeText); + exit(EXIT_FAILURE); + } + + UniqueCERTCertificate cert(PK11_FindCertFromNickname(certNick, nullptr)); + if (!cert) { + PrintPRError("PK11_FindCertFromNickname failed"); + PR_fprintf(PR_STDERR, "Failed to find certificate with nick '%s'\n", + certNick); + exit(EXIT_FAILURE); + } + + time_t skew = static_cast(atoll(skewChars)); + + SECItemArray* response = + GetOCSPResponseForType(ORT, cert, arena, extraCertname, skew); + if (!response) { + PR_fprintf(PR_STDERR, + "Failed to generate OCSP response of type %s " + "for %s\n", + ocspTypeText, certNick); + exit(EXIT_FAILURE); + } + + if (!WriteResponse(filename, &response->items[0])) { + PR_fprintf(PR_STDERR, "Failed to write file %s\n", filename); + exit(EXIT_FAILURE); + } + } + return 0; +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp new file mode 100644 index 0000000000..b35484572f --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/OCSPStaplingServer.cpp @@ -0,0 +1,153 @@ +/* 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/. */ + +// This is a standalone server that delivers various stapled OCSP responses. +// The client is expected to connect, initiate an SSL handshake (with SNI +// to indicate which "server" to connect to), and verify the OCSP response. +// If all is good, the client then sends one encrypted byte and receives that +// same byte back. +// This server also has the ability to "call back" another process waiting on +// it. That is, when the server is all set up and ready to receive connections, +// it will connect to a specified port and issue a simple HTTP request. + +#include + +#include "OCSPCommon.h" +#include "TLSServer.h" + +using namespace mozilla; +using namespace mozilla::test; + +const OCSPHost sOCSPHosts[] = { + {"ocsp-stapling-good.example.com", ORTGood, nullptr, nullptr}, + {"ocsp-stapling-revoked.example.com", ORTRevoked, nullptr, nullptr}, + {"ocsp-stapling-revoked-old.example.com", ORTRevokedOld, nullptr, nullptr}, + {"ocsp-stapling-unknown.example.com", ORTUnknown, nullptr, nullptr}, + {"ocsp-stapling-unknown-old.example.com", ORTUnknownOld, nullptr, nullptr}, + {"ocsp-stapling-good-other.example.com", ORTGoodOtherCert, + "ocspOtherEndEntity", nullptr}, + {"ocsp-stapling-good-other-ca.example.com", ORTGoodOtherCA, "other-test-ca", + nullptr}, + {"ocsp-stapling-expired.example.com", ORTExpired, nullptr, nullptr}, + {"ocsp-stapling-expired-fresh-ca.example.com", ORTExpiredFreshCA, nullptr, + nullptr}, + {"ocsp-stapling-none.example.com", ORTNone, nullptr, nullptr}, + {"ocsp-stapling-empty.example.com", ORTEmpty, nullptr, nullptr}, + {"ocsp-stapling-malformed.example.com", ORTMalformed, nullptr, nullptr}, + {"ocsp-stapling-srverr.example.com", ORTSrverr, nullptr, nullptr}, + {"ocsp-stapling-trylater.example.com", ORTTryLater, nullptr, nullptr}, + {"ocsp-stapling-needssig.example.com", ORTNeedsSig, nullptr, nullptr}, + {"ocsp-stapling-unauthorized.example.com", ORTUnauthorized, nullptr, + nullptr}, + {"ocsp-stapling-with-intermediate.example.com", ORTGood, nullptr, + "ocspEEWithIntermediate"}, + {"ocsp-stapling-bad-signature.example.com", ORTBadSignature, nullptr, + nullptr}, + {"ocsp-stapling-skip-responseBytes.example.com", ORTSkipResponseBytes, + nullptr, nullptr}, + {"ocsp-stapling-critical-extension.example.com", ORTCriticalExtension, + nullptr, nullptr}, + {"ocsp-stapling-noncritical-extension.example.com", ORTNoncriticalExtension, + nullptr, nullptr}, + {"ocsp-stapling-empty-extensions.example.com", ORTEmptyExtensions, nullptr, + nullptr}, + {"ocsp-stapling-delegated-included.example.com", ORTDelegatedIncluded, + "delegatedSigner", nullptr}, + {"ocsp-stapling-delegated-included-last.example.com", + ORTDelegatedIncludedLast, "delegatedSigner", nullptr}, + {"ocsp-stapling-delegated-missing.example.com", ORTDelegatedMissing, + "delegatedSigner", nullptr}, + {"ocsp-stapling-delegated-missing-multiple.example.com", + ORTDelegatedMissingMultiple, "delegatedSigner", nullptr}, + {"ocsp-stapling-delegated-no-extKeyUsage.example.com", ORTDelegatedIncluded, + "invalidDelegatedSignerNoExtKeyUsage", nullptr}, + {"ocsp-stapling-delegated-from-intermediate.example.com", + ORTDelegatedIncluded, "invalidDelegatedSignerFromIntermediate", nullptr}, + {"ocsp-stapling-delegated-keyUsage-crlSigning.example.com", + ORTDelegatedIncluded, "invalidDelegatedSignerKeyUsageCrlSigning", nullptr}, + {"ocsp-stapling-delegated-wrong-extKeyUsage.example.com", + ORTDelegatedIncluded, "invalidDelegatedSignerWrongExtKeyUsage", nullptr}, + {"ocsp-stapling-ancient-valid.example.com", ORTAncientAlmostExpired, + nullptr, nullptr}, + {"keysize-ocsp-delegated.example.com", ORTDelegatedIncluded, + "rsa-1016-keysizeDelegatedSigner", nullptr}, + {"revoked-ca-cert-used-as-end-entity.example.com", ORTRevoked, + "ca-used-as-end-entity", nullptr}, + {"ocsp-stapling-must-staple.example.com", ORTGood, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-revoked.example.com", ORTRevoked, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-missing.example.com", ORTNone, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-empty.example.com", ORTEmpty, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-ee-with-must-staple-int.example.com", ORTGood, + nullptr, "must-staple-ee-with-must-staple-int"}, + {"ocsp-stapling-plain-ee-with-must-staple-int.example.com", ORTGood, + nullptr, "must-staple-missing-ee"}, + {"ocsp-stapling-must-staple-expired.example.com", ORTExpired, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-try-later.example.com", ORTTryLater, nullptr, + "must-staple-ee"}, + {"ocsp-stapling-must-staple-invalid-signer.example.com", ORTGoodOtherCA, + "other-test-ca", "must-staple-ee"}, + {"multi-tls-feature-good.example.com", ORTNone, nullptr, + "multi-tls-feature-good-ee"}, + {"multi-tls-feature-bad.example.com", ORTNone, nullptr, + "multi-tls-feature-bad-ee"}, + {nullptr, ORTNull, nullptr, nullptr}}; + +int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, void* aArg) { + const OCSPHost* host = + GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sOCSPHosts); + if (!host) { + return SSL_SNI_SEND_ALERT; + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); + } + + const char* certNickname = + host->mServerCertName ? host->mServerCertName : DEFAULT_CERT_NICKNAME; + + UniqueCERTCertificate cert; + SSLKEAType certKEA; + if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, certNickname, &cert, + &certKEA, nullptr)) { + return SSL_SNI_SEND_ALERT; + } + + // If the OCSP response type is "none", don't staple a response. + if (host->mORT == ORTNone) { + return 0; + } + + UniquePLArenaPool arena(PORT_NewArena(1024)); + if (!arena) { + PrintPRError("PORT_NewArena failed"); + return SSL_SNI_SEND_ALERT; + } + + // response is contained by the arena - freeing the arena will free it + SECItemArray* response = GetOCSPResponseForType(host->mORT, cert, arena, + host->mAdditionalCertName, 0); + if (!response) { + return SSL_SNI_SEND_ALERT; + } + + // SSL_SetStapledOCSPResponses makes a deep copy of response + SECStatus st = SSL_SetStapledOCSPResponses(aFd, response, certKEA); + if (st != SECSuccess) { + PrintPRError("SSL_SetStapledOCSPResponses failed"); + return SSL_SNI_SEND_ALERT; + } + + return 0; +} + +int main(int argc, char* argv[]) { + return StartServer(argc, argv, DoSNISocketConfig, nullptr); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/SanctionsTestServer.cpp b/security/manager/ssl/tests/unit/tlsserver/cmd/SanctionsTestServer.cpp new file mode 100644 index 0000000000..9371617305 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/SanctionsTestServer.cpp @@ -0,0 +1,87 @@ +/* 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/. */ + +// This is a standalone server that uses various bad certificates. +// The client is expected to connect, initiate an SSL handshake (with SNI +// to indicate which "server" to connect to), and verify the certificate. +// If all is good, the client then sends one encrypted byte and receives that +// same byte back. +// This server also has the ability to "call back" another process waiting on +// it. That is, when the server is all set up and ready to receive connections, +// it will connect to a specified port and issue a simple HTTP request. + +#include + +#include "TLSServer.h" + +using namespace mozilla; +using namespace mozilla::test; + +struct SanctionsCertHost { + const char* mHostName; + const char* mCertName; +}; + +// Hostname, cert nickname pairs. +const SanctionsCertHost sSanctionsCertHosts[] = { + {"symantec-allowlist-after-cutoff.example.com", + "symantec-ee-from-allowlist-after-cutoff"}, + {"symantec-allowlist-before-cutoff.example.com", + "symantec-ee-from-allowlist-before-cutoff"}, + {"symantec-not-allowlisted-after-cutoff.example.com", + "symantec-ee-not-allowlisted-after-cutoff"}, + {"symantec-not-allowlisted-before-cutoff.example.com", + "symantec-ee-not-allowlisted-before-cutoff"}, + {"symantec-unaffected.example.com", "symantec-ee-unaffected"}, + {nullptr, nullptr}}; + +int32_t DoSNISocketConfigBySubjectCN(PRFileDesc* aFd, + const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize) { + for (uint32_t i = 0; i < aSrvNameArrSize; i++) { + UniquePORTString name( + static_cast(PORT_ZAlloc(aSrvNameArr[i].len + 1))); + if (name) { + PORT_Memcpy(name.get(), aSrvNameArr[i].data, aSrvNameArr[i].len); + if (ConfigSecureServerWithNamedCert(aFd, name.get(), nullptr, nullptr, + nullptr) == SECSuccess) { + return 0; + } + } + } + + return SSL_SNI_SEND_ALERT; +} + +int32_t DoSNISocketConfig(PRFileDesc* aFd, const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, void* aArg) { + const SanctionsCertHost* host = + GetHostForSNI(aSrvNameArr, aSrvNameArrSize, sSanctionsCertHosts); + if (!host) { + // No static cert <-> hostname mapping found. This happens when we use a + // collection of certificates in a given directory and build a cert DB at + // runtime, rather than using an NSS cert DB populated at build time. + // (This will be the default in the future.) + // For all given server names, check if the runtime-built cert DB contains + // a certificate with a matching subject CN. + return DoSNISocketConfigBySubjectCN(aFd, aSrvNameArr, aSrvNameArrSize); + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); + } + + UniqueCERTCertificate cert; + SSLKEAType certKEA; + if (SECSuccess != ConfigSecureServerWithNamedCert(aFd, host->mCertName, &cert, + &certKEA, nullptr)) { + return SSL_SNI_SEND_ALERT; + } + + return 0; +} + +int main(int argc, char* argv[]) { + return StartServer(argc, argv, DoSNISocketConfig, nullptr); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/cmd/moz.build b/security/manager/ssl/tests/unit/tlsserver/cmd/moz.build new file mode 100644 index 0000000000..5c6dbadc71 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/moz.build @@ -0,0 +1,30 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +GeckoSimplePrograms( + [ + "BadCertAndPinningServer", + "DelegatedCredentialsServer", + "EncryptedClientHelloServer", + "GenerateOCSPResponse", + "OCSPStaplingServer", + "SanctionsTestServer", + ], + linkage=None, +) + +LOCAL_INCLUDES += [ + "../lib", +] + +USE_LIBS += [ + "mozpkix", + "nspr", + "nss", + "tlsserver", +] + +CXXFLAGS += CONFIG["TK_CFLAGS"] diff --git a/security/manager/ssl/tests/unit/tlsserver/default-ee.der b/security/manager/ssl/tests/unit/tlsserver/default-ee.der new file mode 100644 index 0000000000..3a9b8fa9bc --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/default-ee.der @@ -0,0 +1,3 @@ +This is now an unused file. It exists to ease the coordination between gecko +development trees and the automation infrastructure that runs periodic updates. +See bug 1203312 and bug 1205406. diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp new file mode 100644 index 0000000000..be9a9af9b1 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.cpp @@ -0,0 +1,204 @@ +/* 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/. */ + +#include "OCSPCommon.h" + +#include + +#include "mozpkix/test/pkixtestutil.h" +#include "mozpkix/test/pkixtestnss.h" +#include "TLSServer.h" +#include "secder.h" +#include "secerr.h" + +using namespace mozilla; +using namespace mozilla::pkix; +using namespace mozilla::pkix::test; +using namespace mozilla::test; + +static TestKeyPair* CreateTestKeyPairFromCert( + const UniqueCERTCertificate& cert) { + ScopedSECKEYPrivateKey privateKey(PK11_FindKeyByAnyCert(cert.get(), nullptr)); + if (!privateKey) { + return nullptr; + } + ScopedSECKEYPublicKey publicKey(CERT_ExtractPublicKey(cert.get())); + if (!publicKey) { + return nullptr; + } + return CreateTestKeyPair(RSA_PKCS1(), publicKey, privateKey); +} + +SECItemArray* GetOCSPResponseForType(OCSPResponseType aORT, + const UniqueCERTCertificate& aCert, + const UniquePLArenaPool& aArena, + const char* aAdditionalCertName, + time_t aThisUpdateSkew) { + MOZ_ASSERT(aArena); + MOZ_ASSERT(aCert); + // Note: |aAdditionalCertName| may or may not need to be non-null depending + // on the |aORT| value given. + + if (aORT == ORTNone) { + if (gDebugLevel >= DEBUG_WARNINGS) { + fprintf(stderr, + "GetOCSPResponseForType called with type ORTNone, " + "which makes no sense.\n"); + } + return nullptr; + } + + if (aORT == ORTEmpty) { + SECItemArray* arr = SECITEM_AllocArray(aArena.get(), nullptr, 1); + arr->items[0].data = nullptr; + arr->items[0].len = 0; + return arr; + } + + time_t now = time(nullptr) + aThisUpdateSkew; + time_t oldNow = now - (8 * Time::ONE_DAY_IN_SECONDS); + + mozilla::UniqueCERTCertificate cert(CERT_DupCertificate(aCert.get())); + + if (aORT == ORTGoodOtherCert) { + cert.reset(PK11_FindCertFromNickname(aAdditionalCertName, nullptr)); + if (!cert) { + PrintPRError("PK11_FindCertFromNickname failed"); + return nullptr; + } + } + // XXX CERT_FindCertIssuer uses the old, deprecated path-building logic + mozilla::UniqueCERTCertificate issuerCert( + CERT_FindCertIssuer(aCert.get(), PR_Now(), certUsageSSLCA)); + if (!issuerCert) { + PrintPRError("CERT_FindCertIssuer failed"); + return nullptr; + } + Input issuer; + if (issuer.Init(cert->derIssuer.data, cert->derIssuer.len) != Success) { + return nullptr; + } + Input issuerPublicKey; + if (issuerPublicKey.Init(issuerCert->derPublicKey.data, + issuerCert->derPublicKey.len) != Success) { + return nullptr; + } + Input serialNumber; + if (serialNumber.Init(cert->serialNumber.data, cert->serialNumber.len) != + Success) { + return nullptr; + } + CertID certID(issuer, issuerPublicKey, serialNumber); + OCSPResponseContext context(certID, now); + + mozilla::UniqueCERTCertificate signerCert; + if (aORT == ORTGoodOtherCA || aORT == ORTDelegatedIncluded || + aORT == ORTDelegatedIncludedLast || aORT == ORTDelegatedMissing || + aORT == ORTDelegatedMissingMultiple) { + signerCert.reset(PK11_FindCertFromNickname(aAdditionalCertName, nullptr)); + if (!signerCert) { + PrintPRError("PK11_FindCertFromNickname failed"); + return nullptr; + } + } + + ByteString certs[5]; + + if (aORT == ORTDelegatedIncluded) { + certs[0].assign(signerCert->derCert.data, signerCert->derCert.len); + context.certs = certs; + } + if (aORT == ORTDelegatedIncludedLast || aORT == ORTDelegatedMissingMultiple) { + certs[0].assign(issuerCert->derCert.data, issuerCert->derCert.len); + certs[1].assign(cert->derCert.data, cert->derCert.len); + certs[2].assign(issuerCert->derCert.data, issuerCert->derCert.len); + if (aORT != ORTDelegatedMissingMultiple) { + certs[3].assign(signerCert->derCert.data, signerCert->derCert.len); + } + context.certs = certs; + } + + switch (aORT) { + case ORTMalformed: + context.responseStatus = 1; + break; + case ORTSrverr: + context.responseStatus = 2; + break; + case ORTTryLater: + context.responseStatus = 3; + break; + case ORTNeedsSig: + context.responseStatus = 5; + break; + case ORTUnauthorized: + context.responseStatus = 6; + break; + default: + // context.responseStatus is 0 in all other cases, and it has + // already been initialized in the constructor. + break; + } + if (aORT == ORTSkipResponseBytes) { + context.skipResponseBytes = true; + } + if (aORT == ORTExpired || aORT == ORTExpiredFreshCA || + aORT == ORTRevokedOld || aORT == ORTUnknownOld) { + context.thisUpdate = oldNow; + context.nextUpdate = oldNow + Time::ONE_DAY_IN_SECONDS; + } + if (aORT == ORTLongValidityAlmostExpired) { + context.thisUpdate = now - (320 * Time::ONE_DAY_IN_SECONDS); + } + if (aORT == ORTAncientAlmostExpired) { + context.thisUpdate = now - (640 * Time::ONE_DAY_IN_SECONDS); + } + if (aORT == ORTRevoked || aORT == ORTRevokedOld) { + context.certStatus = 1; + } + if (aORT == ORTUnknown || aORT == ORTUnknownOld) { + context.certStatus = 2; + } + if (aORT == ORTBadSignature) { + context.badSignature = true; + } + OCSPResponseExtension extension; + if (aORT == ORTCriticalExtension || aORT == ORTNoncriticalExtension) { + // python DottedOIDToCode.py --tlv + // some-Mozilla-OID 1.3.6.1.4.1.13769.666.666.666.1.500.9.2 + static const uint8_t tlv_some_Mozilla_OID[] = { + 0x06, 0x12, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xeb, 0x49, 0x85, + 0x1a, 0x85, 0x1a, 0x85, 0x1a, 0x01, 0x83, 0x74, 0x09, 0x02}; + + extension.id.assign(tlv_some_Mozilla_OID, sizeof(tlv_some_Mozilla_OID)); + extension.critical = (aORT == ORTCriticalExtension); + extension.value.push_back(0x05); // tag: NULL + extension.value.push_back(0x00); // length: 0 + extension.next = nullptr; + context.responseExtensions = &extension; + } + if (aORT == ORTEmptyExtensions) { + context.includeEmptyExtensions = true; + } + + if (!signerCert) { + signerCert.reset(CERT_DupCertificate(issuerCert.get())); + } + context.signerKeyPair.reset(CreateTestKeyPairFromCert(signerCert)); + if (!context.signerKeyPair) { + PrintPRError("PK11_FindKeyByAnyCert failed"); + return nullptr; + } + + ByteString response(CreateEncodedOCSPResponse(context)); + if (ENCODING_FAILED(response)) { + PrintPRError("CreateEncodedOCSPResponse failed"); + return nullptr; + } + + SECItem item = {siBuffer, const_cast(response.data()), + static_cast(response.length())}; + SECItemArray arr = {&item, 1}; + return SECITEM_DupArray(aArena.get(), &arr); +} diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h new file mode 100644 index 0000000000..c72eae6a8e --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/lib/OCSPCommon.h @@ -0,0 +1,66 @@ +/* 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/. */ + +// Implements generating OCSP responses of various types. Used by the +// programs in tlsserver/cmd. + +#ifndef OCSPCommon_h +#define OCSPCommon_h + +#include "ScopedNSSTypes.h" +#include "certt.h" +#include "seccomon.h" + +enum OCSPResponseType { + ORTNull = 0, + ORTGood, // the certificate is good + ORTRevoked, // the certificate has been revoked + ORTRevokedOld, // same, but the response is old + ORTUnknown, // the responder doesn't know if the cert is good + ORTUnknownOld, // same, but the response is old + ORTGoodOtherCert, // the response references a different certificate + ORTGoodOtherCA, // the wrong CA has signed the response + ORTExpired, // the signature on the response has expired + ORTExpiredFreshCA, // fresh signature, but old validity period + ORTNone, // no stapled response + ORTEmpty, // an empty stapled response + ORTMalformed, // the response from the responder was malformed + ORTSrverr, // the response indicates there was a server error + ORTTryLater, // the responder replied with "try again later" + ORTNeedsSig, // the response needs a signature + ORTUnauthorized, // the responder is not authorized for this certificate + ORTBadSignature, // the response has a signature that does not verify + ORTSkipResponseBytes, // the response does not include responseBytes + ORTCriticalExtension, // the response includes a critical extension + ORTNoncriticalExtension, // the response includes an extension that is not + // critical + ORTEmptyExtensions, // the response includes a SEQUENCE OF Extension that is + // empty + ORTDelegatedIncluded, // the response is signed by an included delegated + // responder + ORTDelegatedIncludedLast, // same, but multiple other certificates are + // included + ORTDelegatedMissing, // the response is signed by a not included delegated + // responder + ORTDelegatedMissingMultiple, // same, but multiple other certificates are + // included + ORTLongValidityAlmostExpired, // a good response, but that was generated a + // almost a year ago + ORTAncientAlmostExpired, // a good response, with a validity of almost two + // years almost expiring +}; + +struct OCSPHost { + const char* mHostName; + OCSPResponseType mORT; + const char* mAdditionalCertName; // useful for ORTGoodOtherCert, etc. + const char* mServerCertName; +}; + +SECItemArray* GetOCSPResponseForType( + OCSPResponseType aORT, const mozilla::UniqueCERTCertificate& aCert, + const mozilla::UniquePLArenaPool& aArena, const char* aAdditionalCertName, + time_t aThisUpdateSkew); + +#endif // OCSPCommon_h diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp new file mode 100644 index 0000000000..463f865411 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.cpp @@ -0,0 +1,669 @@ +/* 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/. */ + +#include "TLSServer.h" + +#include +#include +#include +#include +#include +#include +#ifdef XP_WIN +# include +#else +# include +#endif + +#include + +#include "base64.h" +#include "mozilla/Sprintf.h" +#include "nspr.h" +#include "nss.h" +#include "plarenas.h" +#include "prenv.h" +#include "prerror.h" +#include "prnetdb.h" +#include "prtime.h" +#include "ssl.h" +#include "sslproto.h" + +namespace mozilla { +namespace test { + +static const uint16_t LISTEN_PORT = 8443; + +DebugLevel gDebugLevel = DEBUG_ERRORS; +uint16_t gCallbackPort = 0; + +const std::string kPEMBegin = "-----BEGIN "; +const std::string kPEMEnd = "-----END "; +const char DEFAULT_CERT_NICKNAME[] = "default-ee"; + +struct Connection { + PRFileDesc* mSocket; + char mByte; + + explicit Connection(PRFileDesc* aSocket); + ~Connection(); +}; + +Connection::Connection(PRFileDesc* aSocket) : mSocket(aSocket), mByte(0) {} + +Connection::~Connection() { + if (mSocket) { + PR_Close(mSocket); + } +} + +void PrintPRError(const char* aPrefix) { + const char* err = PR_ErrorToName(PR_GetError()); + if (err) { + if (gDebugLevel >= DEBUG_ERRORS) { + fprintf(stderr, "%s: %s\n", aPrefix, err); + } + } else { + if (gDebugLevel >= DEBUG_ERRORS) { + fprintf(stderr, "%s\n", aPrefix); + } + } +} + +// This decodes a PEM file into `item`. The line endings need to be +// UNIX-style, or there will be cross-platform issues. +static bool DecodePEMFile(const std::string& filename, SECItem* item) { + std::ifstream in(filename); + if (in.bad()) { + return false; + } + + char buf[1024]; + in.getline(buf, sizeof(buf)); + if (in.bad()) { + return false; + } + + if (strncmp(buf, kPEMBegin.c_str(), kPEMBegin.size()) != 0) { + return false; + } + + std::string value; + for (;;) { + in.getline(buf, sizeof(buf)); + if (in.bad()) { + return false; + } + + if (strncmp(buf, kPEMEnd.c_str(), kPEMEnd.size()) == 0) { + break; + } + + value += buf; + } + + unsigned int binLength; + UniquePORTString bin(BitwiseCast( + ATOB_AsciiToData(value.c_str(), &binLength))); + if (!bin || binLength == 0) { + PrintPRError("ATOB_AsciiToData failed"); + return false; + } + + if (SECITEM_AllocItem(nullptr, item, binLength) == nullptr) { + return false; + } + + PORT_Memcpy(item->data, bin.get(), binLength); + return true; +} + +static SECStatus AddKeyFromFile(const std::string& path, + const std::string& filename) { + ScopedAutoSECItem item; + + std::string file = path + "/" + filename; + if (!DecodePEMFile(file, &item)) { + return SECFailure; + } + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return SECFailure; + } + + if (PK11_NeedUserInit(slot.get())) { + if (PK11_InitPin(slot.get(), nullptr, nullptr) != SECSuccess) { + PrintPRError("PK11_InitPin failed"); + return SECFailure; + } + } + + SECKEYPrivateKey* privateKey = nullptr; + SECItem nick = {siBuffer, + BitwiseCast(filename.data()), + static_cast(filename.size())}; + if (PK11_ImportDERPrivateKeyInfoAndReturnKey( + slot.get(), &item, &nick, nullptr, true, false, KU_ALL, &privateKey, + nullptr) != SECSuccess) { + PrintPRError("PK11_ImportDERPrivateKeyInfoAndReturnKey failed"); + return SECFailure; + } + + SECKEY_DestroyPrivateKey(privateKey); + return SECSuccess; +} + +static SECStatus AddCertificateFromFile(const std::string& path, + const std::string& filename) { + ScopedAutoSECItem item; + + std::string file = path + "/" + filename; + if (!DecodePEMFile(file, &item)) { + return SECFailure; + } + + UniqueCERTCertificate cert(CERT_NewTempCertificate( + CERT_GetDefaultCertDB(), &item, nullptr, false, true)); + if (!cert) { + PrintPRError("CERT_NewTempCertificate failed"); + return SECFailure; + } + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return SECFailure; + } + // The nickname is the filename without '.pem'. + std::string nickname = filename.substr(0, filename.length() - 4); + SECStatus rv = PK11_ImportCert(slot.get(), cert.get(), CK_INVALID_HANDLE, + nickname.c_str(), false); + if (rv != SECSuccess) { + PrintPRError("PK11_ImportCert failed"); + return rv; + } + + return SECSuccess; +} + +SECStatus LoadCertificatesAndKeys(const char* basePath) { + // The NSS cert DB path could have been specified as "sql:path". Trim off + // the leading "sql:" if so. + if (strncmp(basePath, "sql:", 4) == 0) { + basePath = basePath + 4; + } + + UniquePRDir fdDir(PR_OpenDir(basePath)); + if (!fdDir) { + PrintPRError("PR_OpenDir failed"); + return SECFailure; + } + // On the B2G ICS emulator, operations taken in AddCertificateFromFile + // appear to interact poorly with readdir (more specifically, something is + // causing readdir to never return null - it indefinitely loops through every + // file in the directory, which causes timeouts). Rather than waste more time + // chasing this down, loading certificates and keys happens in two phases: + // filename collection and then loading. (This is probably a good + // idea anyway because readdir isn't reentrant. Something could change later + // such that it gets called as a result of calling AddCertificateFromFile or + // AddKeyFromFile.) + std::vector certificates; + std::vector keys; + for (PRDirEntry* dirEntry = PR_ReadDir(fdDir.get(), PR_SKIP_BOTH); dirEntry; + dirEntry = PR_ReadDir(fdDir.get(), PR_SKIP_BOTH)) { + size_t nameLength = strlen(dirEntry->name); + if (nameLength > 4) { + if (strncmp(dirEntry->name + nameLength - 4, ".pem", 4) == 0) { + certificates.push_back(dirEntry->name); + } else if (strncmp(dirEntry->name + nameLength - 4, ".key", 4) == 0) { + keys.push_back(dirEntry->name); + } + } + } + SECStatus rv; + for (std::string& certificate : certificates) { + rv = AddCertificateFromFile(basePath, certificate.c_str()); + if (rv != SECSuccess) { + return rv; + } + } + for (std::string& key : keys) { + rv = AddKeyFromFile(basePath, key.c_str()); + if (rv != SECSuccess) { + return rv; + } + } + return SECSuccess; +} + +SECStatus InitializeNSS(const char* nssCertDBDir) { + // Try initializing an existing DB. + if (NSS_Init(nssCertDBDir) == SECSuccess) { + return SECSuccess; + } + + // Create a new DB if there is none... + SECStatus rv = NSS_Initialize(nssCertDBDir, nullptr, nullptr, nullptr, 0); + if (rv != SECSuccess) { + return rv; + } + + // ...and load all certificates into it. + return LoadCertificatesAndKeys(nssCertDBDir); +} + +nsresult SendAll(PRFileDesc* aSocket, const char* aData, size_t aDataLen) { + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "sending '%s'\n", aData); + } + + while (aDataLen > 0) { + int32_t bytesSent = + PR_Send(aSocket, aData, aDataLen, 0, PR_INTERVAL_NO_TIMEOUT); + if (bytesSent == -1) { + PrintPRError("PR_Send failed"); + return NS_ERROR_FAILURE; + } + + aDataLen -= bytesSent; + aData += bytesSent; + } + + return NS_OK; +} + +nsresult ReplyToRequest(Connection* aConn) { + // For debugging purposes, SendAll can print out what it's sending. + // So, any strings we give to it to send need to be null-terminated. + char buf[2] = {aConn->mByte, 0}; + return SendAll(aConn->mSocket, buf, 1); +} + +nsresult SetupTLS(Connection* aConn, PRFileDesc* aModelSocket) { + PRFileDesc* sslSocket = SSL_ImportFD(aModelSocket, aConn->mSocket); + if (!sslSocket) { + PrintPRError("SSL_ImportFD failed"); + return NS_ERROR_FAILURE; + } + aConn->mSocket = sslSocket; + + SSL_OptionSet(sslSocket, SSL_SECURITY, true); + SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_CLIENT, false); + SSL_OptionSet(sslSocket, SSL_HANDSHAKE_AS_SERVER, true); + + SSL_ResetHandshake(sslSocket, /* asServer */ 1); + + return NS_OK; +} + +nsresult ReadRequest(Connection* aConn) { + int32_t bytesRead = + PR_Recv(aConn->mSocket, &aConn->mByte, 1, 0, PR_INTERVAL_NO_TIMEOUT); + if (bytesRead < 0) { + PrintPRError("PR_Recv failed"); + return NS_ERROR_FAILURE; + } else if (bytesRead == 0) { + PR_SetError(PR_IO_ERROR, 0); + PrintPRError("PR_Recv EOF in ReadRequest"); + return NS_ERROR_FAILURE; + } else { + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "read '0x%hhx'\n", aConn->mByte); + } + } + return NS_OK; +} + +void HandleConnection(PRFileDesc* aSocket, + const UniquePRFileDesc& aModelSocket) { + Connection conn(aSocket); + nsresult rv = SetupTLS(&conn, aModelSocket.get()); + if (NS_FAILED(rv)) { + PR_SetError(PR_INVALID_STATE_ERROR, 0); + PrintPRError("PR_Recv failed"); + exit(1); + } + + // TODO: On tests that are expected to fail (e.g. due to a revoked + // certificate), the client will close the connection wtihout sending us the + // request byte. In those cases, we should keep going. But, in the cases + // where the connection is supposed to suceed, we should verify that we + // successfully receive the request and send the response. + rv = ReadRequest(&conn); + if (NS_SUCCEEDED(rv)) { + rv = ReplyToRequest(&conn); + } +} + +// returns 0 on success, non-zero on error +int DoCallback() { + UniquePRFileDesc socket(PR_NewTCPSocket()); + if (!socket) { + PrintPRError("PR_NewTCPSocket failed"); + return 1; + } + + PRNetAddr addr; + PR_InitializeNetAddr(PR_IpAddrLoopback, gCallbackPort, &addr); + if (PR_Connect(socket.get(), &addr, PR_INTERVAL_NO_TIMEOUT) != PR_SUCCESS) { + PrintPRError("PR_Connect failed"); + return 1; + } + + const char* request = "GET / HTTP/1.0\r\n\r\n"; + SendAll(socket.get(), request, strlen(request)); + char buf[4096]; + memset(buf, 0, sizeof(buf)); + int32_t bytesRead = + PR_Recv(socket.get(), buf, sizeof(buf) - 1, 0, PR_INTERVAL_NO_TIMEOUT); + if (bytesRead < 0) { + PrintPRError("PR_Recv failed 1"); + return 1; + } + if (bytesRead == 0) { + fprintf(stderr, "PR_Recv eof 1\n"); + return 1; + } + fprintf(stderr, "%s\n", buf); + return 0; +} + +SECStatus ConfigSecureServerWithNamedCert( + PRFileDesc* fd, const char* certName, + /*optional*/ UniqueCERTCertificate* certOut, + /*optional*/ SSLKEAType* keaOut, + /*optional*/ SSLExtraServerCertData* extraData) { + UniqueCERTCertificate cert(PK11_FindCertFromNickname(certName, nullptr)); + if (!cert) { + PrintPRError("PK11_FindCertFromNickname failed"); + return SECFailure; + } + // If an intermediate certificate issued the server certificate (rather than + // directly by a trust anchor), we want to send it along in the handshake so + // we don't encounter unknown issuer errors when that's not what we're + // testing. + UniqueCERTCertificateList certList; + UniqueCERTCertificate issuerCert( + CERT_FindCertByName(CERT_GetDefaultCertDB(), &cert->derIssuer)); + // If we can't find the issuer cert, continue without it. + if (issuerCert) { + // Sadly, CERTCertificateList does not have a CERT_NewCertificateList + // utility function, so we must create it ourselves. This consists + // of creating an arena, allocating space for the CERTCertificateList, + // and then transferring ownership of the arena to that list. + UniquePLArenaPool arena(PORT_NewArena(DER_DEFAULT_CHUNKSIZE)); + if (!arena) { + PrintPRError("PORT_NewArena failed"); + return SECFailure; + } + certList.reset(static_cast( + PORT_ArenaAlloc(arena.get(), sizeof(CERTCertificateList)))); + if (!certList) { + PrintPRError("PORT_ArenaAlloc failed"); + return SECFailure; + } + certList->arena = arena.release(); + // We also have to manually copy the certificates we care about to the + // list, because there aren't any utility functions for that either. + certList->certs = static_cast( + PORT_ArenaAlloc(certList->arena, 2 * sizeof(SECItem))); + if (SECITEM_CopyItem(certList->arena, certList->certs, &cert->derCert) != + SECSuccess) { + PrintPRError("SECITEM_CopyItem failed"); + return SECFailure; + } + if (SECITEM_CopyItem(certList->arena, certList->certs + 1, + &issuerCert->derCert) != SECSuccess) { + PrintPRError("SECITEM_CopyItem failed"); + return SECFailure; + } + certList->len = 2; + } + + UniquePK11SlotInfo slot(PK11_GetInternalKeySlot()); + if (!slot) { + PrintPRError("PK11_GetInternalKeySlot failed"); + return SECFailure; + } + UniqueSECKEYPrivateKey key( + PK11_FindKeyByDERCert(slot.get(), cert.get(), nullptr)); + if (!key) { + PrintPRError("PK11_FindKeyByDERCert failed"); + return SECFailure; + } + + if (extraData) { + SSLExtraServerCertData dataCopy = {ssl_auth_null, nullptr, nullptr, + nullptr, nullptr, nullptr}; + memcpy(&dataCopy, extraData, sizeof(dataCopy)); + dataCopy.certChain = certList.get(); + + if (SSL_ConfigServerCert(fd, cert.get(), key.get(), &dataCopy, + sizeof(dataCopy)) != SECSuccess) { + PrintPRError("SSL_ConfigServerCert failed"); + return SECFailure; + } + + } else { + // This is the deprecated setup mechanism, to be cleaned up in Bug 1569222 + SSLKEAType certKEA = NSS_FindCertKEAType(cert.get()); + if (SSL_ConfigSecureServerWithCertChain(fd, cert.get(), certList.get(), + key.get(), certKEA) != SECSuccess) { + PrintPRError("SSL_ConfigSecureServer failed"); + return SECFailure; + } + + if (keaOut) { + *keaOut = certKEA; + } + } + + if (certOut) { + *certOut = std::move(cert); + } + + SSL_OptionSet(fd, SSL_NO_CACHE, false); + SSL_OptionSet(fd, SSL_ENABLE_SESSION_TICKETS, true); + + return SECSuccess; +} + +#ifdef XP_WIN +using PidType = DWORD; +constexpr bool IsValidPid(long long pid) { + // Excluding `(DWORD)-1` because it is not a valid process ID. + // See https://devblogs.microsoft.com/oldnewthing/20040223-00/?p=40503 + return pid > 0 && pid < std::numeric_limits::max(); +} +#else +using PidType = pid_t; +constexpr bool IsValidPid(long long pid) { + return pid > 0 && pid <= std::numeric_limits::max(); +} +#endif + +PidType ConvertPid(const char* pidStr) { + long long pid = strtoll(pidStr, nullptr, 10); + if (!IsValidPid(pid)) { + return 0; + } + return static_cast(pid); +} + +int StartServer(int argc, char* argv[], SSLSNISocketConfig sniSocketConfig, + void* sniSocketConfigArg, ServerConfigFunc configFunc) { + if (argc != 3) { + fprintf(stderr, "usage: %s \n", argv[0]); + return 1; + } + const char* nssCertDBDir = argv[1]; + PidType ppid = ConvertPid(argv[2]); + + const char* debugLevel = PR_GetEnv("MOZ_TLS_SERVER_DEBUG_LEVEL"); + if (debugLevel) { + int level = atoi(debugLevel); + switch (level) { + case DEBUG_ERRORS: + gDebugLevel = DEBUG_ERRORS; + break; + case DEBUG_WARNINGS: + gDebugLevel = DEBUG_WARNINGS; + break; + case DEBUG_VERBOSE: + gDebugLevel = DEBUG_VERBOSE; + break; + default: + PrintPRError("invalid MOZ_TLS_SERVER_DEBUG_LEVEL"); + return 1; + } + } + + const char* callbackPort = PR_GetEnv("MOZ_TLS_SERVER_CALLBACK_PORT"); + if (callbackPort) { + gCallbackPort = atoi(callbackPort); + } + + if (InitializeNSS(nssCertDBDir) != SECSuccess) { + PR_fprintf(PR_STDERR, "InitializeNSS failed"); + return 1; + } + + if (NSS_SetDomesticPolicy() != SECSuccess) { + PrintPRError("NSS_SetDomesticPolicy failed"); + return 1; + } + + if (SSL_ConfigServerSessionIDCache(0, 0, 0, nullptr) != SECSuccess) { + PrintPRError("SSL_ConfigServerSessionIDCache failed"); + return 1; + } + + UniquePRFileDesc serverSocket(PR_NewTCPSocket()); + if (!serverSocket) { + PrintPRError("PR_NewTCPSocket failed"); + return 1; + } + + PRSocketOptionData socketOption; + socketOption.option = PR_SockOpt_Reuseaddr; + socketOption.value.reuse_addr = true; + PR_SetSocketOption(serverSocket.get(), &socketOption); + + PRNetAddr serverAddr; + PR_InitializeNetAddr(PR_IpAddrLoopback, LISTEN_PORT, &serverAddr); + if (PR_Bind(serverSocket.get(), &serverAddr) != PR_SUCCESS) { + PrintPRError("PR_Bind failed"); + return 1; + } + + if (PR_Listen(serverSocket.get(), 1) != PR_SUCCESS) { + PrintPRError("PR_Listen failed"); + return 1; + } + + UniquePRFileDesc rawModelSocket(PR_NewTCPSocket()); + if (!rawModelSocket) { + PrintPRError("PR_NewTCPSocket failed for rawModelSocket"); + return 1; + } + + UniquePRFileDesc modelSocket(SSL_ImportFD(nullptr, rawModelSocket.release())); + if (!modelSocket) { + PrintPRError("SSL_ImportFD of rawModelSocket failed"); + return 1; + } + + SSLVersionRange range = {0, 0}; + if (SSL_VersionRangeGet(modelSocket.get(), &range) != SECSuccess) { + PrintPRError("SSL_VersionRangeGet failed"); + return 1; + } + + if (range.max < SSL_LIBRARY_VERSION_TLS_1_3) { + range.max = SSL_LIBRARY_VERSION_TLS_1_3; + if (SSL_VersionRangeSet(modelSocket.get(), &range) != SECSuccess) { + PrintPRError("SSL_VersionRangeSet failed"); + return 1; + } + } + + if (SSL_SNISocketConfigHook(modelSocket.get(), sniSocketConfig, + sniSocketConfigArg) != SECSuccess) { + PrintPRError("SSL_SNISocketConfigHook failed"); + return 1; + } + + // We have to configure the server with a certificate, but it's not one + // we're actually going to end up using. In the SNI callback, we pick + // the right certificate for the connection. + // + // Provide an empty |extra_data| to force config via SSL_ConfigServerCert. + // This is a temporary mechanism to work around inconsistent setting of + // |authType| in the deprecated API (preventing the default cert from + // being removed in favor of the SNI-selected cert). This may be removed + // after Bug 1569222 removes the deprecated mechanism. + SSLExtraServerCertData extra_data = {ssl_auth_null, nullptr, nullptr, + nullptr, nullptr, nullptr}; + if (ConfigSecureServerWithNamedCert(modelSocket.get(), DEFAULT_CERT_NICKNAME, + nullptr, nullptr, + &extra_data) != SECSuccess) { + return 1; + } + + // Call back to implementation-defined configuration func, if provided. + if (configFunc) { + if (((configFunc)(modelSocket.get())) != SECSuccess) { + PrintPRError("configFunc failed"); + return 1; + } + } + + if (gCallbackPort != 0) { + if (DoCallback()) { + return 1; + } + } + + std::thread([ppid] { + if (!ppid) { + if (gDebugLevel >= DEBUG_ERRORS) { + fprintf(stderr, "invalid ppid\n"); + } + return; + } +#ifdef XP_WIN + HANDLE parent = OpenProcess(SYNCHRONIZE, false, ppid); + if (!parent) { + if (gDebugLevel >= DEBUG_ERRORS) { + fprintf(stderr, "OpenProcess failed\n"); + } + return; + } + WaitForSingleObject(parent, INFINITE); + CloseHandle(parent); +#else + while (getppid() == ppid) { + sleep(1); + } +#endif + if (gDebugLevel >= DEBUG_ERRORS) { + fprintf(stderr, "Parent process crashed\n"); + } + exit(1); + }).detach(); + + while (true) { + PRNetAddr clientAddr; + PRFileDesc* clientSocket = + PR_Accept(serverSocket.get(), &clientAddr, PR_INTERVAL_NO_TIMEOUT); + HandleConnection(clientSocket, modelSocket); + } + + return 0; +} + +} // namespace test +} // namespace mozilla diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h new file mode 100644 index 0000000000..3927b3e541 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/lib/TLSServer.h @@ -0,0 +1,93 @@ +/* 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/. */ + +#ifndef TLSServer_h +#define TLSServer_h + +// This is a standalone server for testing SSL features of Gecko. +// The client is expected to connect and initiate an SSL handshake (with SNI +// to indicate which "server" to connect to). If all is good, the client then +// sends one encrypted byte and receives that same byte back. +// This server also has the ability to "call back" another process waiting on +// it. That is, when the server is all set up and ready to receive connections, +// it will connect to a specified port and issue a simple HTTP request. + +#include + +#include "ScopedNSSTypes.h" +#include "mozilla/Casting.h" +#include "prio.h" +#include "secerr.h" +#include "ssl.h" + +namespace mozilla { + +MOZ_TYPE_SPECIFIC_UNIQUE_PTR_TEMPLATE(UniquePRDir, PRDir, PR_CloseDir); + +} // namespace mozilla + +namespace mozilla { +namespace test { + +typedef SECStatus (*ServerConfigFunc)(PRFileDesc* fd); + +enum DebugLevel { DEBUG_ERRORS = 1, DEBUG_WARNINGS = 2, DEBUG_VERBOSE = 3 }; + +extern DebugLevel gDebugLevel; + +void PrintPRError(const char* aPrefix); + +// The default certificate is trusted for localhost and *.example.com +extern const char DEFAULT_CERT_NICKNAME[]; + +// ConfigSecureServerWithNamedCert sets up the hostname name provided. If the +// extraData parameter is presented, extraData->certChain will be automatically +// filled in using database information. +// Pass DEFAULT_CERT_NICKNAME as certName unless you need a specific +// certificate. +SECStatus ConfigSecureServerWithNamedCert( + PRFileDesc* fd, const char* certName, + /*optional*/ UniqueCERTCertificate* cert, + /*optional*/ SSLKEAType* kea, + /*optional*/ SSLExtraServerCertData* extraData); + +SECStatus InitializeNSS(const char* nssCertDBDir); + +// StartServer initializes NSS, sockets, the SNI callback, and a default +// certificate. configFunc (optional) is a pointer to an implementation- +// defined configuration function, which is called on the model socket +// prior to handling any connections. +int StartServer(int argc, char* argv[], SSLSNISocketConfig sniSocketConfig, + void* sniSocketConfigArg, + ServerConfigFunc configFunc = nullptr); + +template +inline const Host* GetHostForSNI(const SECItem* aSrvNameArr, + uint32_t aSrvNameArrSize, const Host* hosts) { + for (uint32_t i = 0; i < aSrvNameArrSize; i++) { + for (const Host* host = hosts; host->mHostName; ++host) { + SECItem hostName; + hostName.data = BitwiseCast(host->mHostName); + hostName.len = strlen(host->mHostName); + if (SECITEM_ItemsAreEqual(&hostName, &aSrvNameArr[i])) { + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "found pre-defined host '%s'\n", host->mHostName); + } + return host; + } + } + } + + if (gDebugLevel >= DEBUG_VERBOSE) { + fprintf(stderr, "could not find host info from SNI\n"); + } + + PR_SetError(SEC_ERROR_INVALID_ARGS, 0); + return nullptr; +} + +} // namespace test +} // namespace mozilla + +#endif // TLSServer_h diff --git a/security/manager/ssl/tests/unit/tlsserver/lib/moz.build b/security/manager/ssl/tests/unit/tlsserver/lib/moz.build new file mode 100644 index 0000000000..1fd92d724d --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/lib/moz.build @@ -0,0 +1,16 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +UNIFIED_SOURCES += [ + "OCSPCommon.cpp", + "TLSServer.cpp", +] + +USE_LIBS += [ + "mozpkix-testlib", +] + +Library("tlsserver") diff --git a/security/manager/ssl/tests/unit/tlsserver/moz.build b/security/manager/ssl/tests/unit/tlsserver/moz.build new file mode 100644 index 0000000000..1488352914 --- /dev/null +++ b/security/manager/ssl/tests/unit/tlsserver/moz.build @@ -0,0 +1,8 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# 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/. + +# lib must be first, because cmd depends on its output +DIRS += ["lib", "cmd"] diff --git a/security/manager/ssl/tests/unit/xpcshell-smartcards.ini b/security/manager/ssl/tests/unit/xpcshell-smartcards.ini new file mode 100644 index 0000000000..df3cfa1c87 --- /dev/null +++ b/security/manager/ssl/tests/unit/xpcshell-smartcards.ini @@ -0,0 +1,15 @@ +[DEFAULT] +head = head_psm.js +tail = +tags = psm +skip-if = toolkit == 'android' +support-files = + +[test_osclientcerts_module.js] +skip-if = (os != 'win' && os != 'mac') || processor == 'aarch64' +[test_pkcs11_module.js] +[test_pkcs11_moduleDB.js] +[test_pkcs11_safe_mode.js] +[test_pkcs11_slot.js] +[test_pkcs11_token.js] +[test_pkcs11_tokenDB.js] diff --git a/security/manager/ssl/tests/unit/xpcshell.ini b/security/manager/ssl/tests/unit/xpcshell.ini new file mode 100644 index 0000000000..e80615104a --- /dev/null +++ b/security/manager/ssl/tests/unit/xpcshell.ini @@ -0,0 +1,237 @@ +[DEFAULT] +head = head_psm.js +tags = psm +firefox-appdir = browser +support-files = + bad_certs/** + ocsp_certs/** + test_baseline_requirements/** + test_broken_fips/** + test_cert_eku/** + test_cert_embedded_null/** + test_cert_isBuiltInRoot_reload/** + test_cert_keyUsage/** + test_cert_overrides_read_only/** + test_cert_sha1/** + test_cert_signatures/** + test_cert_storage_direct/** + test_cert_storage_preexisting/** + test_cert_storage_preexisting_crlite/** + test_cert_trust/** + test_cert_utf8/** + test_cert_version/** + test_certDB_import/** + test_content_signing/** + test_crlite_filters/** + test_ct/** + test_delegated_credentials/** + test_encrypted_client_hello/** + test_ev_certs/** + test_intermediate_basic_usage_constraints/** + test_intermediate_preloads/** + test_keysize/** + test_keysize_ev/** + test_missing_intermediate/** + test_name_constraints/** + test_ocsp_url/** + test_onecrl/** + test_sanctions/** + test_sdr_preexisting/** + test_sdr_preexisting_with_password/** + test_self_signed_certs/** + test_signed_apps/** + test_startcom_wosign/** + test_validity/** + tlsserver/** + +[test_add_preexisting_cert.js] +[test_baseline_requirements_subject_common_name.js] +[test_blocklist_onecrl.js] +# Skip signature tests for Thunderbird (Bug 1341983). +skip-if = appname == "thunderbird" +tags = remote-settings blocklist psm +[test_blocklist_pinning.js] +tags = remote-settings blocklist psm +[test_broken_fips.js] +# FIPS has never been a thing on Android, so the workaround doesn't +# exist on that platform. +# FIPS still works on Linux, so this test doesn't make any sense there. +# FIPS still works on Windows, but running the test to ensure that it does not +# break with a non-ASCII profile path. +skip-if = toolkit == 'android' || os == 'linux' +[test_cert_storage.js] +tags = addons psm blocklist +[test_cert_storage_broken_db.js] +[test_cert_storage_direct.js] +[test_cert_storage_preexisting.js] +[test_cert_storage_preexisting_crlite.js] +# This test cannot succeed on 32-bit platforms. See bugs 1546361 and 1548956. +skip-if = bits != 64 +[test_cert_storage_prefs.js] +[test_cert_chains.js] +run-sequentially = hardcoded ports +[test_cert_dbKey.js] +[test_cert_eku.js] +[test_cert_embedded_null.js] +[test_cert_expiration_canary.js] +run-if = nightly_build +[test_cert_keyUsage.js] +[test_cert_isBuiltInRoot.js] +[test_cert_isBuiltInRoot_reload.js] +[test_cert_overrides.js] +run-sequentially = hardcoded ports +[test_cert_overrides_read_only.js] +run-sequentially = hardcoded ports +[test_cert_override_bits_mismatches.js] +run-sequentially = hardcoded ports +[test_cert_sha1.js] +[test_cert_signatures.js] +[test_cert_trust.js] +[test_cert_version.js] +[test_cert_utf8.js] +[test_certDB_export_pkcs12.js] +[test_certDB_export_pkcs12_with_master_password.js] +[test_certDB_import.js] +# nsCertificateDialogs not available in geckoview, bug 1554276 +skip-if = toolkit == 'android' && processor == 'x86_64' +[test_certDB_import_pkcs12.js] +[test_certDB_import_with_master_password.js] +# nsCertificateDialogs not available in geckoview, bug 1554276 +skip-if = toolkit == 'android' && processor == 'x86_64' +[test_constructX509FromBase64.js] +[test_content_signing.js] +[test_crlite_filters.js] +tags = remote-settings psm +[test_ct.js] +# Requires hard-coded debug-only data +skip-if = !debug +run-sequentially = hardcoded ports +[test_db_format_pref_new.js] +# Android always has and always will use the new format, so +# this test doesn't apply. +skip-if = toolkit == 'android' +[test_delegated_credentials.js] +run-sequentially = hardcoded ports +[test_encrypted_client_hello.js] +run-sequentially = hardcoded ports +[test_encrypted_client_hello_client_only.js] +run-sequentially = hardcoded ports +[test_der.js] +[test_enterprise_roots.js] +# This feature is implemented for Windows and OS X. However, we don't currently +# have a way to test it on OS X. +skip-if = os != 'win' +[test_ev_certs.js] +tags = blocklist psm +run-sequentially = hardcoded ports +[test_forget_about_site_security_headers.js] +run-sequentially = hardcoded ports +[test_hash_algorithms.js] +[test_hash_algorithms_wrap.js] +# bug 1124289 - run_test_in_child violates the sandbox on android +skip-if = toolkit == 'android' +[test_hmac.js] +[test_intermediate_basic_usage_constraints.js] +[test_intermediate_preloads.js] +run-sequentially = hardcoded ports +tags = blocklist psm remote-settings +# Bug 1520297 - do something to handle tighter resource constraints on Android +skip-if = toolkit == 'android' +[test_imminent_distrust.js] +run-sequentially = hardcoded ports +[test_allow_all_cert_errors.js] +run-sequentially = hardcoded ports +[test_keysize.js] +[test_keysize_ev.js] +run-sequentially = hardcoded ports +[test_local_cert.js] +[test_logoutAndTeardown.js] +skip-if = socketprocess_networking +run-sequentially = hardcoded ports +[test_missing_intermediate.js] +run-sequentially = hardcoded ports +[test_name_constraints.js] +[test_nonascii_path.js] +[test_nsCertType.js] +run-sequentially = hardcoded ports +[test_nsIX509Cert_utf8.js] +[test_nsIX509CertValidity.js] +[test_nss_shutdown.js] +[test_ocsp_caching.js] +run-sequentially = hardcoded ports +[test_ocsp_enabled_pref.js] +run-sequentially = hardcoded ports +[test_ocsp_must_staple.js] +run-sequentially = hardcoded ports +[test_ocsp_private_caching.js] +run-sequentially = hardcoded ports +[test_ocsp_no_hsts_upgrade.js] +run-sequentially = hardcoded ports +[test_ocsp_required.js] +run-sequentially = hardcoded ports +[test_ocsp_stapling.js] +run-sequentially = hardcoded ports +[test_ocsp_stapling_expired.js] +run-sequentially = hardcoded ports +[test_ocsp_stapling_with_intermediate.js] +run-sequentially = hardcoded ports +[test_ocsp_timeout.js] +run-sequentially = hardcoded ports +[test_ocsp_url.js] +run-sequentially = hardcoded ports +[test_oskeystore.js] +[test_osreauthenticator.js] +# Reauthentication has been implemented on Windows and MacOS, so running this +# test results in the OS popping up a dialog, which means we can't run it in +# automation. +skip-if = os == 'win' || os == 'mac' +[test_password_prompt.js] +[test_pinning.js] +run-sequentially = hardcoded ports +[test_sdr.js] +[test_sdr_preexisting.js] +# Not relevant to Android. See the comment in the test. +skip-if = toolkit == 'android' +[test_sdr_preexisting_with_password.js] +# Not relevant to Android. See the comment in the test. +skip-if = toolkit == 'android' +[test_self_signed_certs.js] +[test_session_resumption.js] +skip-if = ccov && webrender && os == "win" # Bug 1585916 +run-sequentially = hardcoded ports +[test_signed_apps.js] +[test_ssl_status.js] +run-sequentially = hardcoded ports +[test_sss_enumerate.js] +run-sequentially = hardcoded ports +[test_sss_eviction.js] +[test_sss_originAttributes.js] +run-sequentially = hardcoded ports +[test_sss_readstate.js] +[test_sss_readstate_child.js] +support-files = sss_readstate_child_worker.js +# bug 1124289 - run_test_in_child violates the sandbox on android +skip-if = toolkit == 'android' +[test_sss_readstate_empty.js] +[test_sss_readstate_garbage.js] +[test_sss_readstate_huge.js] +[test_sss_resetState.js] +run-sequentially = hardcoded ports +[test_sss_savestate.js] +[test_sss_sanitizeOnShutdown.js] +firefox-appdir = browser +# Sanitization works differently on Android - this doesn't apply. +# browser/modules/Sanitizer.jsm used by the test isn't available in Thunderbird. +skip-if = toolkit == 'android' || appname == 'thunderbird' +[test_startcom_wosign.js] +[test_sts_fqdn.js] +[test_sts_ipv4_ipv6.js] +[test_sts_parser.js] +[test_sts_preload_dynamic.js] +[test_sts_preloadlist_perwindowpb.js] +[test_sts_preloadlist_selfdestruct.js] +[test_sanctions_symantec_apple_google.js] +run-sequentially = hardcoded ports +[test_validity.js] +run-sequentially = hardcoded ports +[test_x509.js] -- cgit v1.2.3