in src/utils/eis_utils/src/eis_utils.c [435:704]
EISUtilityResult RequestConnectionStringFromEISWithExpiry(
const time_t expirySecsSinceEpoch, uint32_t timeoutMS, ADUC_ConnectionInfo* provisioningInfo)
{
EISUtilityResult result = { EISErr_Failed, EISService_Utils };
if (provisioningInfo == NULL)
{
result.err = EISErr_InvalidArg;
return result;
}
if (expirySecsSinceEpoch <= time(NULL) || timeoutMS == 0)
{
result.err = EISErr_InvalidArg;
return result;
}
memset(provisioningInfo, 0, sizeof(*provisioningInfo));
bool success = false;
char* connectionStr = NULL;
char* keyHandlePtr = NULL;
ADUC_ConnType connType = ADUC_ConnType_NotSet;
ADUC_AuthType authType = ADUC_AuthType_NotSet;
char* resourceUri = NULL;
char* sharedSignatureStr = NULL;
char* identityResponseStr = NULL;
JSON_Value* identityResponseJson = NULL;
char* certResponseStr = NULL;
JSON_Value* certResponseJson = NULL;
char* certString = NULL;
EISErr identityResult = RequestIdentitiesFromEIS(timeoutMS, &identityResponseStr);
if (identityResult != EISErr_Ok)
{
result.service = EISService_IdentityService;
result.err = identityResult;
goto done;
}
identityResponseJson = json_parse_string(identityResponseStr);
if (identityResponseJson == NULL)
{
result.err = EISErr_InvalidJsonRespErr;
result.service = EISService_IdentityService;
goto done;
}
const JSON_Object* identityResponseJsonObj = json_value_get_object(identityResponseJson);
if (identityResponseJsonObj == NULL)
{
goto done;
}
const JSON_Object* specJson =
json_value_get_object(json_object_get_value(identityResponseJsonObj, EIS_IDENTITY_RESP_SPEC_FIELD));
if (specJson == NULL)
{
result.err = EISErr_InvalidJsonRespErr;
result.service = EISService_IdentityService;
goto done;
}
const char* hubName = json_object_get_string(specJson, EIS_IDENTITY_RESP_HUBNAME_FIELD);
if (hubName == NULL)
{
result.err = EISErr_InvalidJsonRespErr;
result.service = EISService_IdentityService;
goto done;
}
const char* deviceId = json_object_get_string(specJson, EIS_IDENTITY_RESP_DEVICEID_FIELD);
if (deviceId == NULL)
{
result.err = EISErr_InvalidJsonRespErr;
result.service = EISService_IdentityService;
goto done;
}
connType = ADUC_ConnType_Device;
const char* moduleId = json_object_get_string(specJson, EIS_IDENTITY_RESP_MODULEID_FIELD);
if (moduleId != NULL)
{
connType = ADUC_ConnType_Module;
}
// Build request for the signature
if (connType == ADUC_ConnType_Device)
{
resourceUri = ADUC_StringFormat("%s/devices/%s", hubName, deviceId);
}
else if (connType == ADUC_ConnType_Module)
{
resourceUri = ADUC_StringFormat("%s/devices/%s/modules/%s", hubName, deviceId, moduleId);
}
else
{
goto done;
}
if (resourceUri == NULL)
{
goto done;
}
const char* gatewayHostName = json_object_get_string(specJson, EIS_IDENTITY_RESP_GATEWAYHOSTNAME_FIELD);
const JSON_Object* authJson = json_value_get_object(json_object_get_value(specJson, EIS_IDENTITY_RESP_AUTH_FIELD));
if (authJson == NULL)
{
result.err = EISErr_InvalidJsonRespErr;
result.service = EISService_IdentityService;
goto done;
}
const char* authTypeStr = json_object_get_string(authJson, EIS_IDENTITY_RESP_AUTH_TYPE_FIELD);
if (authTypeStr == NULL)
{
result.err = EISErr_InvalidJsonRespErr;
result.service = EISService_IdentityService;
goto done;
}
const char* keyHandle = json_object_get_string(authJson, EIS_IDENTITY_RESP_AUTH_KEYHANDLE_FIELD);
if (keyHandle == NULL)
{
result.err = EISErr_InvalidJsonRespErr;
result.service = EISService_KeyService;
goto done;
}
if (strcmp(authTypeStr, "sas") == 0)
{
authType = ADUC_AuthType_SASToken;
result =
BuildSharedAccessSignature(resourceUri, keyHandle, expirySecsSinceEpoch, timeoutMS, &sharedSignatureStr);
if (result.err != EISErr_Ok)
{
goto done;
}
result.err = BuildSasTokenConnectionString(
hubName, deviceId, moduleId, connType, sharedSignatureStr, gatewayHostName, &connectionStr);
if (result.err != EISErr_Ok)
{
goto done;
}
}
else if (strcmp(authTypeStr, "x509") == 0)
{
authType = ADUC_AuthType_SASCert;
if (mallocAndStrcpy_s(&keyHandlePtr, keyHandle) != 0)
{
result.err = EISErr_ContentAllocErr;
goto done;
}
const char* certId = json_object_get_string(authJson, EIS_IDENTITY_RESP_AUTH_CERTID_FIELD);
if (certId == NULL)
{
result.err = EISErr_InvalidJsonRespErr;
result.service = EISService_IdentityService;
goto done;
}
EISErr certResult = RequestCertificateFromEIS(certId, timeoutMS, &certResponseStr);
if (certResult != EISErr_Ok)
{
result.err = certResult;
result.service = EISService_CertService;
goto done;
}
certResponseJson = json_parse_string(certResponseStr);
if (certResponseJson == NULL)
{
result.err = EISErr_InvalidJsonRespErr;
result.service = EISService_CertService;
goto done;
}
const JSON_Object* certResponseJsonObj = json_value_get_object(certResponseJson);
const char* certificateStr = json_object_get_string(certResponseJsonObj, EIS_CERT_RESP_PEM);
if (certificateStr == NULL)
{
result.err = EISErr_InvalidJsonRespErr;
result.service = EISService_CertService;
goto done;
}
if (mallocAndStrcpy_s(&certString, certificateStr) != 0)
{
result.err = EISErr_ContentAllocErr;
goto done;
}
result.err =
BuildSasCertConnectionString(hubName, deviceId, moduleId, connType, gatewayHostName, &connectionStr);
if (result.err != EISErr_Ok)
{
goto done;
}
}
else
{
// Authentication type not supported
result.err = EISErr_RecvInvalidValueErr;
result.service = EISService_IdentityService;
goto done;
}
success = true;
result.err = EISErr_Ok;
done:
json_value_free(identityResponseJson);
free(resourceUri);
free(sharedSignatureStr);
free(identityResponseStr);
provisioningInfo->connectionString = connectionStr;
provisioningInfo->certificateString = certString;
provisioningInfo->opensslPrivateKey = keyHandlePtr;
provisioningInfo->connType = connType;
provisioningInfo->authType = authType;
if (provisioningInfo->authType == ADUC_AuthType_SASCert && provisioningInfo->certificateString != NULL)
{
if (mallocAndStrcpy_s(&provisioningInfo->opensslEngine, EIS_OPENSSL_KEY_ENGINE_ID) != 0)
{
success = false;
}
}
if (!success)
{
ADUC_ConnectionInfo_DeAlloc(provisioningInfo);
}
return result;
}