static ExitCode HandleWolfsslSetup()

in AzureEventGrid/mqtt_connection.c [313:415]


static ExitCode HandleWolfsslSetup(void)
{
    int ret;
    // Check whether the connection succeeded.
    int error;
    socklen_t errSize = sizeof(error);
    int r = getsockopt(sockFd, SOL_SOCKET, SO_ERROR, &error, &errSize);
    if (!(r == 0 && error == 0)) {
        Log_Debug("ERROR: Socket connection failed\n");
        return ExitCode_HandleWolfSslSetup_Failed;
    }

    // Connection was made successfully, so allocate wolfSSL session and context.
    r = wolfSSL_Init();
    if (r != WOLFSSL_SUCCESS) {
        Log_Debug("ERROR: wolfSSL_init failed\n");
        return ExitCode_HandleWolfSslSetup_Init;
    }
    wolfSslInitialized = true;

    WOLFSSL_METHOD *wolfSslMethod = wolfTLSv1_3_client_method();
    if (wolfSslMethod == NULL) {
        Log_Debug("ERROR: failed to create WOLFSSL METHOD\n");
        return ExitCode_HandleWolfSslSetup_Method;
    }

    wolfSslCtx = wolfSSL_CTX_new(wolfSslMethod);
    if (wolfSslCtx == NULL) {
        Log_Debug("ERROR: failed to create WOLFSSL_CTX\n");
        return ExitCode_HandleWolfSslSetup_Context;
    }

    if (deviceCertPath == NULL) {
        Log_Debug("HandleWolfsslSetup: Device cert path is null.\n");
        return ExitCode_HandleWolfSslSetup_DeviceCertPath;
    }

    // Use device certificate for authentication
    if ((ret = wolfSSL_CTX_use_certificate_file(wolfSslCtx, deviceCertPath,
                                                WOLFSSL_FILETYPE_PEM)) != WOLFSSL_SUCCESS) {
        Log_Debug("ERROR: failed to use device certificate\n");
        return ExitCode_HandleWolfSslSetup_CertPath;
    }

    // Specify the root certificate which is used to validate the Azure Event Grid.
    char *certPathAbs =
        Storage_GetAbsolutePathInImagePackage(mqttClientContext->ca_cert);
    if (certPathAbs == NULL) {
        Log_Debug("ERROR: failed to get path to CA certificate\n");
        return ExitCode_HandleWolfSslSetup_CertPath;
    }

    if ((ret = wolfSSL_CTX_load_verify_locations(wolfSslCtx, certPathAbs, NULL)) != WOLFSSL_SUCCESS) {
        Log_Debug("ERROR: failed to load ca certificate\n");
        free(certPathAbs);
        certPathAbs = NULL;
        return ExitCode_HandleWolfSslSetup_VerifyLocations;
    }
    free(certPathAbs);
    certPathAbs = NULL;
    
    // Use Server Name Identification (SNI) as Azure Event Grid uses SNI. 
    ret = wolfSSL_CTX_UseSNI(wolfSslCtx, WOLFSSL_SNI_HOST_NAME, mqttClientContext->hostname,
                             (short unsigned int)strlen(mqttClientContext->hostname));

        if (ret != WOLFSSL_SUCCESS)
    {
        // sni usage failed
        Log_Debug("SNI usage failed\n");
        return ExitCode_HandleWolfSslSetup_UseSni;
    }

    wolfSslSession = wolfSSL_new(wolfSslCtx);
    if (wolfSslSession == NULL) {
        Log_Debug("ERROR: Failed to open new WOlfSsl session\n");
        return ExitCode_HandleWolfSslSetup_Session;
    }

    // Check domain name of peer certificate.
    r = wolfSSL_check_domain_name(wolfSslSession, mqttClientContext->hostname);
    if (r != WOLFSSL_SUCCESS) {
        Log_Debug("ERROR: wolfSSL_check_domain_name %d\n", r);
        return ExitCode_HandleWolfSslSetup_CheckDomainName;
    }

    // Associate socket with wolfSSL session.
    r = wolfSSL_set_fd(wolfSslSession, sockFd);
    if (r != WOLFSSL_SUCCESS) {
        Log_Debug("ERROR: wolfSSL_set_fd %d\n", r);
        return ExitCode_HandleWolfSslSetup_SetFd;
    }

    // Perform TLS handshake.
    // Asynchronous handshakes require repeated calls to wolfSSL_connect, so jump to the
    // handler to avoid repeating code.
    ret = HandleTlsHandshake();
    if (ret != ExitCode_Success) {
        return ret;
    }

    return ExitCode_Success;

}