📄 defaulttransprov.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "transport.h"
#include "deftrans.h"
#include "vsdistrict.h"
#include "idobj.h"
#include "distobj.h"
#include "certobj.h"
#include "vstorage.h"
#include "defaultstore.h"
#include "derhelp.h"
#include "oidlist.h"
#include "ibe.h"
#include "ibekeyber.h"
#include "surrender.h"
#include "errorctx.h"
/* Implements VCtxDestroy.
*/
void VOLT_CALLING_CONV AsyncInfoDestroy VOLT_PROTO_LIST ((
Pointer obj,
Pointer ctx
));
int VoltDefaultDownloadParameters (
VtTransportCtx transportCtx,
VtDistrictObject district,
UInt32 *authFlag
)
{
int status;
unsigned int paramsTextLen;
VoltTransportCtx *ctx = (VoltTransportCtx *)transportCtx;
VoltDefaultTransCtx *localCtx = (VoltDefaultTransCtx *)(ctx->localCtx);
VoltDistrictObject *obj = (VoltDistrictObject *)district;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
mIcDistrictObject *icDist = (mIcDistrictObject *)0;
char *domainName = (char *)0;
char *districtName = (char *)0;
VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*authFlag = 0;
do
{
/* This transport function performs network access. Check the no net
* access bit in the libCtx->flags field to make sure the caller
* allows it.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_DISTRICT;
if ((libCtx->flags & VOLT_LIB_CTX_NO_NETWORK_ACCESS) != 0)
break;
/* If there's a surrender ctx, call the Surrender function. For
* downloading params, we'll call once before and once after. No
* more.
*/
if ( ((ctx->voltObject.objectType & VOLT_OBJECT_TYPE_SURRENDER) != 0) &&
(ctx->voltObject.surrenderCtx != (Pointer)0) )
{
surrCtx = (VoltSurrenderCtx *)(ctx->voltObject.surrenderCtx);
surrCtx->surrenderInfo.callingFlag =
VT_SURRENDER_FNCT_DIST_PARAM_DOWNLOAD;
surrCtx->surrenderInfo.callCount = 2;
surrCtx->surrenderInfo.callNumber = 1;
VOLT_SET_FNCT_LINE (fnctLine)
status = surrCtx->Surrender (
surrCtx->libraryCtx, surrCtx->appData, &(surrCtx->surrenderInfo));
if (status != 0)
break;
}
/* Get the district and domain names out of the district object.
*/
domainName = obj->unqualDistrictName.data;
districtName = obj->qualDistrictName.data;
/* Call the icDistrict code to download params.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = mIcDistrictCreateObject (
ctx->voltObject.libraryCtx, localCtx->DoHttp, localCtx->uiHandle,
localCtx->trustStore, ctx->timeout, &icDist);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mIcDistrictRetrieveParams (
domainName, districtName, icDist, obj->mpCtx, libCtx);
if (status != 0)
break;
/* Convert them to distObj format.
*/
paramsTextLen = Z2Strlen (icDist->paramsText);
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltSetDistFromIcParams (
icDist->paramsText, paramsTextLen, icDist->icParams, obj->mpCtx, obj);
if (status != 0)
break;
/* This provider used channel authentication.
*/
*authFlag = VOLT_PARAMS_CHANNEL_AUTH | VOLT_PARAMS_AUTHENTICATED;
if (surrCtx != (VoltSurrenderCtx *)0)
{
surrCtx->surrenderInfo.callingFlag =
VT_SURRENDER_FNCT_DIST_PARAM_DOWNLOAD;
surrCtx->surrenderInfo.callCount = 2;
surrCtx->surrenderInfo.callNumber = 2;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = surrCtx->Surrender (
surrCtx->libraryCtx, surrCtx->appData, &(surrCtx->surrenderInfo));
if (status != 0)
break;
}
} while (0);
if (icDist != (mIcDistrictObject *)0)
mIcDistrictDestroyObject (&icDist);
VOLT_LOG_ERROR_COMPARE (
status, (VtLibCtx)libCtx, status, errorType, fnctLine,
"VoltDefaultDownloadParameters", (char *)0)
return (status);
}
int VoltDefaultDownloadKeyAndCert (
VtTransportCtx transportCtx,
VtIdentityObject identity,
VtPolicyCtx policyCtx,
VtStorageCtx storageCtx,
VtCertRequestObject certRequest,
VtCertObject signingCert,
VtKeyObject ibePriKey,
Pointer appSpecificData
)
{
int status, keyFlag, certFlag;
unsigned int districtNameLen;
unsigned int tokenCount, asyncContinueFlag;
VoltTransportCtx *transCtx = (VoltTransportCtx *)transportCtx;
VoltDefaultTransCtx *localCtx = (VoltDefaultTransCtx *)(transCtx->localCtx);
VoltIdentityObject *obj = (VoltIdentityObject *)identity;
VoltCertRequestObject *certReq = (VoltCertRequestObject *)certRequest;
VoltKeyObject *priKey = (VoltKeyObject *)ibePriKey;
VoltCertObject *certObj = (VoltCertObject *)signingCert;
VoltStorageCtx *prov = (VoltStorageCtx *)storageCtx;
VoltDefaultStorageCtx *localStorage = (VoltDefaultStorageCtx *)0;
VoltDistrictObject *distObj;
VoltLibCtx *libCtx = (VoltLibCtx *)(transCtx->voltObject.libraryCtx);
VtArbitraryStorageObject arbitObj = (VtArbitraryStorageObject)0;
VoltAsyncSaveInfo *asyncInfo = (VoltAsyncSaveInfo *)0;
unsigned char *temp;
Asn1P10Request *asnCertReq = (Asn1P10Request *)0;
mIcServerObject *icServer = (mIcServerObject *)0;
char *component = "TKCOM/2.3.0.0";
unsigned char *policyServer = (unsigned char *)0;
VtAuthTokenList *tokenList = (VtAuthTokenList *)0;
VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
VoltRequestInfoData reqInfoData;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
Z2Memset (&reqInfoData, 0, sizeof (reqInfoData));
if (prov != (VoltStorageCtx *)0)
localStorage = (VoltDefaultStorageCtx *)(prov->localStorageCtx);
do
{
/* This transport function performs network access. Check the no net
* access bit in the libCtx->flags field to make sure the caller
* allows it.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNKNOWN_DISTRICT;
if ((libCtx->flags & VOLT_LIB_CTX_NO_NETWORK_ACCESS) != 0)
break;
/* If keyFlag and/or certFlag is 0, it means the function should not
* try to obtain that value. Set a flag to 1 if the function should
* get the value.
*/
keyFlag = 0;
certFlag = 0;
if (ibePriKey != (VtKeyObject)0)
keyFlag = 1;
if (signingCert != (VtCertObject)0)
certFlag = 1;
/* If both keyFlag and certFlag are 0, the caller wants no key or
* cert. That's not how this provider operates.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_PROVIDER_USE;
if ((keyFlag + certFlag) == 0)
break;
/* If we have a cert object make sure we have the Cert request too.
* The opposite is not true though. We can pass a cert request but
* pass a null cert object if we just want to ignore the
* cert received in the response.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_PROVIDER_USE;
if ( (certReq == (VoltCertRequestObject *)0) &&
(certObj != (VoltCertObject *)0) )
break;
/* One of the keys may already contain data (it was in storage, the
* other was not). So clear the private key data or the pub key cert.
* We want to make sure the key and cert match, so we'll want to keep
* whatever is downloaded from the server.
*/
if (ibePriKey != (VtKeyObject)0)
{
if (priKey->keyData != (Pointer)0)
{
if (priKey->KeyDataDestroy != (VCtxDestroy)0)
{
priKey->KeyDataDestroy ((Pointer)priKey, priKey->keyData);
priKey->keyData = (Pointer)0;
priKey->KeyDataDestroy = (VCtxDestroy)0;
priKey->keyType = 0;
}
}
}
if (signingCert != (VtCertObject)0)
{
VtDestroyKeyObject (&(certObj->pubKey));
if (certObj->certificate.data != (unsigned char *)0)
{
libCtx = (VoltLibCtx *)(certObj->voltObject.libraryCtx);
Z2Free (certObj->certificate.data);
certObj->certificate.data = (unsigned char *)0;
certObj->certificate.len = 0;
libCtx = (VoltLibCtx *)(transCtx->voltObject.libraryCtx);
}
}
if ( ((transCtx->voltObject.objectType & VOLT_OBJECT_TYPE_SURRENDER) != 0) &&
(transCtx->voltObject.surrenderCtx != (Pointer)0) )
{
surrCtx = (VoltSurrenderCtx *)(transCtx->voltObject.surrenderCtx);
surrCtx->surrenderInfo.callingFlag = VT_SURRENDER_FNCT_IBE_KEY_DOWNLOAD;
surrCtx->surrenderInfo.callCount = 2;
surrCtx->surrenderInfo.callNumber = 1;
VOLT_SET_FNCT_LINE (fnctLine)
status = surrCtx->Surrender (
surrCtx->libraryCtx, surrCtx->appData, &(surrCtx->surrenderInfo));
if (status != 0)
break;
}
/* Get the district parameters from the encoded identity.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDetermineDistrict (
identity, policyCtx, storageCtx, transportCtx,
(unsigned char *)0, 0, &districtNameLen);
if (status == 0)
status = VT_ERROR_INVALID_INPUT;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtObtainIBEParams (
obj->district, policyCtx, storageCtx, transportCtx);
if (status != 0)
break;
/* Set up the reqInfoData in case we need it.
*/
reqInfoData.encodedId = obj->encoding.data;
reqInfoData.encodedIdLen = obj->encoding.len;
reqInfoData.certRequestDER = (unsigned char *)0;
reqInfoData.certRequestDERLen = 0;
reqInfoData.ibeKeyRequest = 0;
if (keyFlag != 0)
reqInfoData.ibeKeyRequest = 1;
if (certFlag != 0)
{
reqInfoData.certRequestDER = certReq->certRequest.data;
reqInfoData.certRequestDERLen = certReq->certRequest.len;
}
if (prov != (VoltStorageCtx *)0)
{
reqInfoData.storageType = prov->storageTypeFlag;
reqInfoData.storageLocation = (unsigned char *)0;
if (prov->storageTypeFlag < 4)
{
if (localStorage->pathName != (char *)0)
reqInfoData.storageLocation =
(unsigned char *)(localStorage->pathName);
}
}
/* Build the object we will use to store and/or delete the request
* info.
*/
if (localCtx->ArbitraryStorageImpl != (VtArbitraryStorageImpl *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltCreateArbitraryStorageObject (
libCtx, VtArbitraryStorageImplRequestInfo, (Pointer)0,
&arbitObj);
if (status != 0)
break;
}
/* Get the state for this identity's download. If we have no
* asyncInfo, this is the first call to DownloadKey, the state is
* START. If there is asyncInfo, the state will be there.
*/
if (obj->asyncDownloadInfo == (Pointer)0)
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltSetTransportAsync (
transportCtx, identity, arbitObj, &reqInfoData, 0,
localCtx->asyncFlag, (mIcServerObject *)0);
if (status != 0)
break;
}
asyncInfo = (VoltAsyncSaveInfo *)(obj->asyncDownloadInfo);
} while (0);
if (status != 0)
{
VOLT_LOG_ERROR (
(VtLibCtx)libCtx, status, errorType, fnctLine,
"VoltDefaultDownloadKeyAndCert", (char *)0)
return (status);
}
switch (asyncInfo->state)
{
default:
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
break;
case VOLT_ASYNC_STATE_RESTART:
case VOLT_ASYNC_STATE_SETUP:
/* Get the policy server extension out of the district.
*/
distObj = (VoltDistrictObject *)obj->district;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetDistrictParam (
(VtDistrictObject)distObj, VtDistrictParamPolicyServer,
(Pointer *)&policyServer);
if (status != 0)
break;
/* Create the icServer object.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mIcServerCreateObject (
(VtLibCtx)libCtx, localCtx->DoHttp, localCtx->uiHandle,
localCtx->trustStore, transCtx->timeout, &icServer);
if (status != 0)
break;
/* We need the cert request in AsnP10Request form.
*/
if (certFlag != 0)
{
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
asnCertReq = Asn1P10Request_new ();
if (asnCertReq == (Asn1P10Request *)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_ENCODING;
temp = certReq->certRequest.data;
d2i_Asn1P10Request (&asnCertReq, &temp, certReq->certRequest.len);
if (asnCertReq == (Asn1P10Request *)0)
break;
}
/* Get any new authTokens.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
if (storageCtx != (VtStorageCtx) 0 &&
asyncInfo->tokenListObj->tokenCount == 0)
{
status = prov->RetrieveNewAuthTokens (
storageCtx, obj->district, asyncInfo->tokenListObj, &tokenCount);
if (status != 0)
break;
}
/* Fill in the fields of the serverRequestData.
*/
icServer->uiHandle = localCtx->uiHandle;
icServer->asyncFlag = localCtx->asyncFlag;
/* The server is the policy server.
*/
icServer->serverRequestData.server = policyServer;
icServer->serverRequestData.components = component;
/* Pass along any authTokens.
*/
if (asyncInfo->tokenListObj->tokenCount != 0)
{
icServer->serverRequestData.authTokens =
asyncInfo->tokenListObj->tokenList;
icServer->serverRequestData.authTokensCount =
asyncInfo->tokenListObj->tokenCount;
}
icServer->serverRequestData.id = obj->encoding.data;
icServer->serverRequestData.idLen = obj->encoding.len;
icServer->serverRequestData.request = asnCertReq;
/* This call downloads the info. If it succeeds, we have what
* we're looking for, break out of this switch.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mIcServerRequest (icServer, obj, transCtx);
if (status == 0)
break;
/* If we get an ASYNC operation and the previous state was
* VOLT_ASYNC_STATE_RESTART. We just want to continue instead
* of going thru the async operations again because they already
* have been started in previous calls.
*/
if (asyncInfo->state == VOLT_ASYNC_STATE_RESTART)
{
status = VT_ERROR_DOWNLOAD_PENDING;
asyncInfo->state = VOLT_ASYNC_STATE_CONTINUE;
break;
}
/* If we didn't break, the return from mIcServerRequest was not 0,
* meaning it was either ASYNC or error. Call SetTransportAsync to
* sort it out. If the return from that call is 0, we're supposed
* to launch the async operation.
*/
case VOLT_ASYNC_STATE_WAIT:
/* A previous call found ASYNC or ASYNC and PREVIOUS. It
* returned. The caller decided to run anyway. To get things
* moving, call SetTransport with previousStatus as PREVIOUS.
*/
if (status == 0)
status = VT_ERROR_DOWNLOAD_PREVIOUS;
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltSetTransportAsync (
transportCtx, identity, arbitObj, &reqInfoData, status,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -