void verify(vmime::shared_ptr <vmime::security::cert::certificateChain> chain, const vmime::string& hostname) { try { setX509TrustedCerts(m_trustedCerts); defaultCertificateVerifier::verify(chain, hostname); } catch (vmime::exceptions::certificate_verification_exception&) { // Obtain subject's certificate vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0); std::cout << std::endl; std::cout << "Server sent a '" << cert->getType() << "'" << " certificate." << std::endl; std::cout << "Do you want to accept this certificate? (Y/n) "; std::cout.flush(); std::string answer; std::getline(std::cin, answer); if (answer.length() != 0 && (answer[0] == 'Y' || answer[0] == 'y')) { // Accept it, and remember user's choice for later if (cert->getType() == "X.509") { m_trustedCerts.push_back(vmime::dynamicCast <vmime::security::cert::X509Certificate>(cert)); setX509TrustedCerts(m_trustedCerts); defaultCertificateVerifier::verify(chain, hostname); } return; } throw vmime::exceptions::certificate_verification_exception ("User did not accept the certificate."); } }
void SimpleCertificateVerifier::verify(vmime::shared_ptr <vmime::security::cert::certificateChain> chain, const vmime::string& hostname) { try { setX509TrustedCerts(m_trustedCerts); defaultCertificateVerifier::verify(chain, hostname); } catch (vmime::security::cert::certificateException&) { // Obtain subject's certificate vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0); // Accept it, and remember user's choice for later if (cert->getType() == "X.509") { m_trustedCerts.push_back(vmime::dynamicCast <vmime::security::cert::X509Certificate>(cert)); setX509TrustedCerts(m_trustedCerts); defaultCertificateVerifier::verify(chain, hostname); } } }
void CertificateVerifier::verify (vmime::shared_ptr<vmime::security::cert::certificateChain> chain, const vmime::string& host) { namespace vsc = vmime::security::cert; QList<QSslCertificate> qtChain; for (size_t i = 0; i < chain->getCount (); ++i) { const auto& item = chain->getAt (i); const auto& subcerts = ToSslCerts (item); if (subcerts.size () != 1) { qWarning () << Q_FUNC_INFO << "unexpected certificates count for certificate type" << item->getType ().c_str () << ", got" << subcerts.size () << "certificates"; throw vsc::unsupportedCertificateTypeException { "unexpected certificates counts" }; } qtChain << subcerts.at (0); } const auto& errs = QSslCertificate::verify (qtChain, QString::fromStdString (host)); if (errs.isEmpty ()) return; qWarning () << Q_FUNC_INFO << errs; for (const auto& error : errs) switch (error.error ()) { case QSslError::CertificateExpired: throw vsc::certificateExpiredException {}; case QSslError::CertificateNotYetValid: throw vsc::certificateNotYetValidException {}; case QSslError::HostNameMismatch: throw vsc::serverIdentityException {}; case QSslError::UnableToDecryptCertificateSignature: case QSslError::InvalidNotAfterField: case QSslError::InvalidNotBeforeField: case QSslError::CertificateSignatureFailed: case QSslError::PathLengthExceeded: case QSslError::UnspecifiedError: throw vsc::unsupportedCertificateTypeException { "incorrect format" }; case QSslError::UnableToGetIssuerCertificate: case QSslError::UnableToGetLocalIssuerCertificate: case QSslError::UnableToDecodeIssuerPublicKey: case QSslError::UnableToVerifyFirstCertificate: case QSslError::SubjectIssuerMismatch: case QSslError::AuthorityIssuerSerialNumberMismatch: throw vsc::certificateIssuerVerificationException {}; case QSslError::SelfSignedCertificate: case QSslError::SelfSignedCertificateInChain: case QSslError::CertificateRevoked: case QSslError::InvalidCaCertificate: case QSslError::InvalidPurpose: case QSslError::CertificateUntrusted: case QSslError::CertificateRejected: case QSslError::NoPeerCertificate: case QSslError::CertificateBlacklisted: throw vsc::certificateNotTrustedException {}; case QSslError::NoError: case QSslError::NoSslSupport: break; } throw vsc::certificateException { "other certificate error" }; }