in archive/cyclonessl/tlsio_cyclonessl.c [123:251]
static CONCRETE_IO_HANDLE tlsio_cyclonessl_create(void* io_create_parameters)
{
TLS_IO_INSTANCE* result;
/* Codes_SRS_TLSIO_CYCLONESSL_01_002: [ If io_create_parameters is NULL, tlsio_cyclonessl_create shall fail and return NULL. ]*/
if (io_create_parameters == NULL)
{
result = NULL;
LogError("NULL tls_io_config.");
}
else
{
/* Codes_SRS_TLSIO_CYCLONESSL_01_003: [ io_create_parameters shall be used as a TLSIO_CONFIG\*. ]*/
TLSIO_CONFIG* tls_io_config = io_create_parameters;
/* Codes_SRS_TLSIO_CYCLONESSL_01_004: [ If the hostname member is NULL, then tlsio_cyclonessl_create shall fail and return NULL. ]*/
if (tls_io_config->hostname == NULL)
{
result = NULL;
LogError("NULL hostname in the TLS IO configuration.");
}
else
{
result = malloc(sizeof(TLS_IO_INSTANCE));
if (result == NULL)
{
/* Codes_SRS_TLSIO_CYCLONESSL_01_076: [ If allocating memory for the TLS IO instance fails then tlsio_cyclonessl_create shall fail and return NULL. ]*/
LogError("Failed allocating TLSIO instance.");
}
else
{
uint8_t seed[32];
size_t i;
/* Codes_SRS_TLSIO_CYCLONESSL_01_005: [ tlsio_cyclonessl_create shall copy the hostname and port values for later use when the open of the underlying socket is needed. ]*/
/* Codes_SRS_TLSIO_CYCLONESSL_01_006: [ hostname shall be copied by calling mallocAndStrcpy_s. ]*/
if (mallocAndStrcpy_s(&result->hostname, tls_io_config->hostname) != 0)
{
/* Codes_SRS_TLSIO_CYCLONESSL_01_007: [ If mallocAndStrcpy_s fails then tlsio_cyclonessl_create shall fail and return NULL. ]*/
/* Codes_SRS_TLSIO_CYCLONESSL_01_018: [ When tlsio_cyclonessl_create fails, all allocated resources up to that point shall be freed. ]*/
LogError("Failed to copy the hostname.");
free(result);
result = NULL;
}
else
{
result->port = tls_io_config->port;
result->certificate = NULL;
result->on_bytes_received = NULL;
result->on_bytes_received_context = NULL;
result->on_io_error = NULL;
result->on_io_error_context = NULL;
result->tlsio_state = TLSIO_STATE_NOT_OPEN;
result->socket = (TlsSocket)NULL;
/* seed should be initialized with some random seed ... */
for (i = 0; i < 32; i++)
{
seed[i] = rand() * 255 / RAND_MAX;
}
/* Codes_SRS_TLSIO_CYCLONESSL_01_008: [ tlsio_cyclonessl_create shall initialize the yarrow context by calling yarrowInit. ]*/
if (yarrowInit(&result->yarrowContext) != NO_ERROR)
{
/* Codes_SRS_TLSIO_CYCLONESSL_01_009: [ If yarrowInit fails then tlsio_cyclonessl_create shall return NULL. ]*/
/* Codes_SRS_TLSIO_CYCLONESSL_01_018: [ When tlsio_cyclonessl_create fails, all allocated resources up to that point shall be freed. ]*/
LogError("yarrowInit failed");
free(result->hostname);
free(result);
result = NULL;
}
/* Codes_SRS_TLSIO_CYCLONESSL_01_010: [ The yarrow context shall be seeded with 32 bytes of randomly chosen data by calling yarrowSeed. ]*/
else if (yarrowSeed(&result->yarrowContext, seed, sizeof(seed)) != NO_ERROR)
{
/* Codes_SRS_TLSIO_CYCLONESSL_01_011: [ If yarrowSeed fails then tlsio_cyclonessl_create shall return NULL. ]*/
/* Codes_SRS_TLSIO_CYCLONESSL_01_018: [ When tlsio_cyclonessl_create fails, all allocated resources up to that point shall be freed. ]*/
LogError("yarrowInit seed failed");
yarrowRelease(&result->yarrowContext);
free(result->hostname);
free(result);
result = NULL;
}
else
{
/* Codes_SRS_TLSIO_CYCLONESSL_01_012: [ tlsio_cyclonessl_create shall create a TLS context by calling tlsInit. ]*/
result->tlsContext = tlsInit();
if (result->tlsContext == NULL)
{
/* Codes_SRS_TLSIO_CYCLONESSL_01_013: [ If tlsInit fails then tlsio_cyclonessl_create shall return NULL. ]*/
/* Codes_SRS_TLSIO_CYCLONESSL_01_018: [ When tlsio_cyclonessl_create fails, all allocated resources up to that point shall be freed. ]*/
tlsFree(result->tlsContext);
yarrowRelease(&result->yarrowContext);
free(result->hostname);
free(result);
LogError("Creating the TLS context failed");
result = NULL;
}
/* Codes_SRS_TLSIO_CYCLONESSL_01_014: [ The TLS context shall be setup to operate as a client by calling tlsSetConnectionEnd with TLS_CONNECTION_END_CLIENT. ]*/
else if (tlsSetConnectionEnd(result->tlsContext, TLS_CONNECTION_END_CLIENT))
{
/* Codes_SRS_TLSIO_CYCLONESSL_01_015: [ If tlsSetConnectionEnd fails then tlsio_cyclonessl_create shall return NULL. ]*/
/* Codes_SRS_TLSIO_CYCLONESSL_01_018: [ When tlsio_cyclonessl_create fails, all allocated resources up to that point shall be freed. ]*/
tlsFree(result->tlsContext);
yarrowRelease(&result->yarrowContext);
free(result->hostname);
free(result);
LogError("tlsSetConnectionEnd failed");
result = NULL;
}
/* Codes_SRS_TLSIO_CYCLONESSL_01_016: [ The pseudo random number generator to be used shall be set by calling tlsSetPrng with the yarrow instance as argument. ]*/
else if (tlsSetPrng(result->tlsContext, YARROW_PRNG_ALGO, &result->yarrowContext) != NO_ERROR)
{
/* Codes_SRS_TLSIO_CYCLONESSL_01_017: [ If tlsSetPrng fails then tlsio_cyclonessl_create shall return NULL. ]*/
/* Codes_SRS_TLSIO_CYCLONESSL_01_018: [ When tlsio_cyclonessl_create fails, all allocated resources up to that point shall be freed. ]*/
tlsFree(result->tlsContext);
yarrowRelease(&result->yarrowContext);
free(result->hostname);
free(result);
LogError("tlsSetPrng failed");
result = NULL;
}
}
}
}
}
}
return result;
}