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;
}