pocoproject / poco

The POCO C++ Libraries are powerful cross-platform C++ libraries for building network- and internet-based applications that run on desktop, server, mobile, IoT, and embedded systems.
https://pocoproject.org
Other
8.48k stars 2.18k forks source link

Getting SSLException : Unacceptable certificate from abc.example.com: application verification failure #4736

Open gokulkrishna-k opened 1 month ago

gokulkrishna-k commented 1 month ago

when establishing a WebSocket connection to our server this exception occurs. Unacceptable certificate from abc.example.com: application verification failure The exception is captured by const Poco::Net::SSLException &e , kindly refer the code below

initialize() will be called before connect()

void WSSyncSocket::initialize() {
    std::string hostName = getServerHostName();
    int hostPort = getServerPort();

    lpHttpRequest = std::shared_ptr<HTTPRequest>(new HTTPRequest(
        Poco::Net::HTTPRequest::HTTP_GET, "/" + serverEndpointUrl, HTTPMessage::HTTP_1_1));

    Poco::Net::initializeSSL();
    _isSSLInitialized = true;

    ptrMyInvalidCertificateHandler = new Poco::Net::MyInvalidCertificateHandler(
        false, _isSystemMode, (WsLogger) ? WsLogger : nullptr);

    ptrHandler = ptrMyInvalidCertificateHandler;

    lpWssContext = (new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE, "", "", "",
                                           Poco::Net::Context::VERIFY_RELAXED, 9, true));
    lpWssContext->requireMinimumProtocol(Poco::Net::Context::PROTO_TLSV1_2);
    lpWssContext->setInvalidCertificateHandler(ptrMyInvalidCertificateHandler);

    if (!ptrHandler)
        Poco::Net::SSLManager::instance().initializeClient(0, ptrHandler, lpWssContext);

    lpClientSession = std::shared_ptr<HTTPClientSession>(
        (HTTPClientSession *)new HTTPSClientSession(hostName, hostPort, lpWssContext));
}

bool WSSyncSocket::connect() {
    bool connectResult = false;

    try {
        if ((lpHttpRequest != NULL) && (lpClientSession != NULL)) {
            if (WsLogger)
                WsLogger->log(CSLoggerUtils::CSLogger::LOG_INFO,
                              "Creating a websocket connection object");

            lpWebSocket = std::shared_ptr<WebSocket>(
                new WebSocket(*(lpClientSession.get()), *(lpHttpRequest.get()), (httpResponse)));

            if (lpWebSocket != NULL) {
                initSocketConfigurations();

                if (WsLogger)
                    WsLogger->log(CSLoggerUtils::CSLogger::LOG_INFO,
                                  "WebSocket Connection Successful");

                connectResult = true;
            } else {
                if (WsLogger)
                    WsLogger->log(CSLoggerUtils::CSLogger::LOG_INFO, "WebSocket Connection failed");
            }
        } else {
            if (WsLogger)
                WsLogger->log(CSLoggerUtils::CSLogger::LOG_ERROR,
                              "HTTPRequest and ClientSession parameters not initialized");
            setLastError(SOCKUTIL_ERROR_SOCKET_NOT_INITIALIZED);
        }
    } catch (WebSocketException &wsExcep) {
        if (WsLogger)
            WsLogger->log(CSLoggerUtils::CSLogger::LOG_ERROR, "Code : %d, WebSocketException - %s",
                          wsExcep.code(), wsExcep.message());
        setLastError(wsExcep.code(), (char *)wsExcep.what());
    } catch (const Poco::Net::SSLException &e) {
        std::string errorMessage = std::string((char *)e.what());

        if (WsLogger) {
            WsLogger->log(CSLoggerUtils::CSLogger::LOG_ERROR,
                          "SSLException Code : %d, Message : %s", e.code(), e.message());
        }

        setLastError(e.code(), (char *)errorMessage.c_str());
    } catch (std::exception &excep) {
        if (WsLogger)
            WsLogger->log(CSLoggerUtils::CSLogger::LOG_ERROR, "Exception - %s",
                          std::string(excep.what()));
        connectResult = false;
        setLastError(SOCKUTIL_STD_EXCEPTION, (char *)excep.what());
    } catch (...) {
        if (WsLogger) WsLogger->log(CSLoggerUtils::CSLogger::LOG_ERROR, "Exception - UNKNOWN");
        connectResult = false;
        setLastError(SOCKUTIL_STD_EXCEPTION, ("UNKNOWN_EXCEPTION"));
    }

    return connectResult;
}

I observed that this exception only occurs when the SSL cert received from the server contains different CN instead of the server endpoint I'm connecting to (in case Self Signed firewall certificates).

I printed the certificate , here is the sample as i cannot share the original certificate

Certificate Validation Success, Certificate Details: Subject: CN=*.xyz.com, Issued Name: C=GB,ST=Greater Manchester,L=Salford,O=Sectigo Limited,CN=Sectigo RSA Domain Validation Secure Server CA, Common Name: *.xyz.com, Serial Number: 90F3****DEE, Expires on: 2025-05-02 05:29:59, Signature Algorithm: sha256WithRSAEncryption

xyz.com is not the server I'm trying to connect to.

1414 - this is similar to my issue but in my case I'm using WebSocket with HTTPClientSession

Thanks in advance for any suggestions.

micheleselea commented 1 month ago

try using Poco::Net::Context::VERIFY_NONE because if you use VERIFY_RELAXED you need to create the Poco::Net::Context giving the correct caLocation file. For example you can use a .pem file from mozilla firefox you can find it online