📄 p7getkeys.c
字号:
/* Copyright 2003-2006, Voltage Security, all rights reserved.
*/
#include "vibe.h"
#include "environment.h"
#include "base.h"
#include "libctx.h"
#include "p7obj.h"
#include "idobj.h"
#include "certobj.h"
#include "errorctx.h"
/* Make sure the private key and the public key in the cert match.
* <p>This function will get the public key data out of the objects.
* The private key must be a type that allows returning the public key
* data. A hardware key, or a key that does not hold the public key
* data, for example, might not allow this.
*/
static int VOLT_CALLING_CONV CheckDSASigningKeys VOLT_PROTO_LIST ((
VtLibCtx libraryCtx,
VtKeyObject priKey,
VtCertObject cert
));
int VoltP7GetKeysAndCert (
VoltSurrenderCtx *surrCtx,
VtIdentityObject identity,
VtRandomObject random,
VtPolicyCtx policyCtx,
VtStorageCtx storageCtx,
VtTransportCtx transportCtx,
VtCertObject *signingCert,
VtKeyObject *ibePriKey,
VtKeyObject *dsaPriKey
)
{
int status;
unsigned int encodingLen;
VoltIdentityObject *obj = (VoltIdentityObject *)identity;
VtLibCtx libraryCtx = obj->voltObject.libraryCtx;
VtMpIntCtx mpCtx = (VtMpIntCtx)0;
VtMpIntCtx getMpCtx = (VtMpIntCtx)0;
VtCertRequestObject certReq = (VtCertRequestObject)0;
VtCertObject newCert = (VtCertObject)0;
VtKeyObject newIbePri = (VtKeyObject)0;
VtKeyObject newDsaPub = (VtKeyObject)0;
VtKeyObject newDsaPri = (VtKeyObject)0;
VtParameterObject dsaParams = (VtParameterObject)0;
VtSurrenderCallback surrenderCtx;
VtSurrenderCallback *surrenderToUse = (VtSurrenderCallback *)0;
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Make sure the ID is encoded. If no output buffer is given, the
* function will encode it internally only. We're expecting
* BUFFER_TOO_SMALL error.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtEncodeIdentity (
identity, VT_ENCODE_IBCS_2_V_DISTRICT | VT_ENCODE_FOR_SIGNING,
policyCtx, storageCtx, transportCtx,
(unsigned char *)0, 0, &encodingLen);
if (status == 0)
status = VT_ERROR_GENERAL;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
/* We'll need an mpCtx.
*/
getMpCtx = (VtMpIntCtx)(obj->mpCtx);
if (getMpCtx == (VtMpIntCtx)0)
{
getMpCtx = (VtMpIntCtx)VoltGetLibCtxInfo (
libraryCtx, VOLT_LIB_CTX_INFO_TYPE_MP_CTX);
if (getMpCtx == (VtMpIntCtx)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateMpIntCtx (
libraryCtx, VtMpIntImplOpenSSL, (Pointer)0, &mpCtx);
if (status != 0)
break;
getMpCtx = mpCtx;
}
}
/* If there's a surrender ctx, use it.
*/
if (surrCtx != (VoltSurrenderCtx *)0)
{
/* Set the key object with the surrender ctx, but don't copy the
* appData, just copy a reference, so we're still using the P7
* object's appData.
*/
surrenderCtx.Surrender = surrCtx->Surrender;
surrenderCtx.appData = surrCtx->appData;
surrenderCtx.AppDataCopy = (VtSurrenderAppDataCopy)0;
surrenderCtx.AppDataFree = (VtSurrenderAppDataFree)0;
surrenderToUse = &surrenderCtx;
}
/* Create "empty" objects into which we'll place the data from
* storage (if the data is in storage).
*/
if (ibePriKey != (VtKeyObject *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
libraryCtx, VtKeyImplMpCtx, (Pointer)getMpCtx, &newIbePri);
if (status != 0)
break;
}
if (dsaPriKey != (VtKeyObject *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
libraryCtx, VtKeyImplMpCtx, (Pointer)getMpCtx, &newDsaPri);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateCertObject (
libraryCtx, VtCertImplMpCtx, (Pointer)getMpCtx, &newCert);
if (status != 0)
break;
}
/* Try to get the keys and cert from storage. Because we're passing
* the STORAGE_ONLY flag, this function will look only in storage.
* If the return is 0, we found the values, we're done. If the
* return is ENTRY_NOT_FOUND, the values were not in storage, we'll
* generate and download new values.
* Any other return is an error we want to pass along.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtObtainPrivateKeysAndCert (
identity, random, VT_OBTAIN_KEYS_FLAG_STORAGE_ONLY, policyCtx,
storageCtx, (VtTransportCtx)0, newDsaPri, newCert, newIbePri);
if (status == 0)
{
/* If we have a key pair, make sure they match.
*/
if (newDsaPri != (VtKeyObject)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = CheckDSASigningKeys (libraryCtx, newDsaPri, newCert);
if (status == VT_ERROR_UNMATCHED_KEY_PAIR)
status = VT_ERROR_ENTRY_NOT_FOUND;
}
}
if (status != VT_ERROR_ENTRY_NOT_FOUND)
break;
if (ibePriKey != (VtKeyObject *)0)
{
VtDestroyKeyObject (&newIbePri);
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
libraryCtx, VtKeyImplMpCtx, (Pointer)getMpCtx, &newIbePri);
if (status != 0)
break;
}
if (dsaPriKey != (VtKeyObject *)0)
{
VtDestroyKeyObject (&newDsaPri);
VtDestroyCertObject (&newCert);
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
libraryCtx, VtKeyImplMpCtx, (Pointer)getMpCtx, &newDsaPri);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateCertObject (
libraryCtx, VtCertImplMpCtx, (Pointer)getMpCtx, &newCert);
if (status != 0)
break;
/* This function will build a DSA parameter object either from the
* district's params or from a default set. We don't care which,
* so we'll ignore the returned flag. Just use encodingLen for the
* return flag.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltGetDsaParamsCreate (
identity, (VtDistrictObject)0, getMpCtx, &encodingLen, &dsaParams);
if (status != 0)
break;
/* If there's a surrender ctx, use it.
*/
if (surrCtx != (VoltSurrenderCtx *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetKeyParam (
newDsaPri, VtKeyParamSurrenderCallback, (Pointer)surrenderToUse);
if (status != 0)
break;
}
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
libraryCtx, VtKeyImplMpCtx, (Pointer)getMpCtx, &newDsaPub);
if (status != 0)
break;
/* Now that we have params, generate a key pair.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGenerateKeyPair (
VtKeyPairGenDSA, (Pointer)dsaParams, random, newDsaPub, newDsaPri);
if (status != 0)
break;
/* We need a cert request to send to the key server.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateCertRequestObject (
libraryCtx, VtCertRequestImplMpCtx, (Pointer)getMpCtx,
&certReq);
if (status != 0)
break;
/* If there's a surrender ctx, use it.
*/
if (surrCtx != (VoltSurrenderCtx *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetCertRequestParam (
certReq, VtCertRequestParamSurrenderCallback, (Pointer)surrenderToUse);
if (status != 0)
break;
}
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGenerateCertRequest (
identity, newDsaPub, newDsaPri, VtCertRequestTypeP10DSA,
(Pointer)random, certReq);
if (status != 0)
break;
}
/* Get the private key and signing cert.
* This call will store the private IBE key and the cert, but not
* the private DSA key.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDownloadIBEPrivateKeyAndCert (
identity, policyCtx, storageCtx, transportCtx,
certReq, newCert, newIbePri);
if (status != 0)
break;
if (storageCtx == (VtStorageCtx)0)
break;
if (dsaPriKey != (VtKeyObject *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtStoreEntry (
libraryCtx, VT_ENTRY_TYPE_SIGNING_PRI_KEY,
(Pointer)identity, (Pointer)newDsaPri, storageCtx);
if (status != 0)
break;
}
if (signingCert != (VtCertObject *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtStoreEntry (
libraryCtx, VT_ENTRY_TYPE_CERTIFICATE, (Pointer)identity,
(Pointer)newCert, storageCtx);
if (status != 0)
break;
}
if (ibePriKey != (VtKeyObject *)0)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VtStoreEntry (
libraryCtx, VT_ENTRY_TYPE_IBE_PRI_KEY, (Pointer)identity,
(Pointer)newIbePri, storageCtx);
}
} while (0);
VtDestroyParameterObject (&dsaParams);
VtDestroyKeyObject (&newDsaPub);
VtDestroyCertRequestObject (&certReq);
VtDestroyMpIntCtx (&mpCtx);
/* If status is 0, we've got our values, return them. Well, return
* the values the caller wanted, destroy the others.
*/
if (status == 0)
{
if (signingCert != (VtCertObject *)0)
*signingCert = newCert;
else
VtDestroyCertObject (&newCert);
if (ibePriKey != (VtKeyObject *)0)
*ibePriKey = newIbePri;
else
VtDestroyKeyObject (&newIbePri);
if (dsaPriKey != (VtKeyObject *)0)
*dsaPriKey = newDsaPri;
else
VtDestroyKeyObject (&newDsaPri);
return (0);
}
/* If there was an error, we need to destroy these objects.
*/
VtDestroyKeyObject (&newIbePri);
VtDestroyKeyObject (&newDsaPri);
VtDestroyCertObject (&newCert);
VOLT_LOG_ERROR_INFO (
0, identity, status, 0, 0,
(char *)0, "VoltP7GetKeysAndCert", fnctLine, (char *)0)
return (status);
}
int VoltGetSignerInfoCount (
VoltPkcs7Object *obj,
unsigned int *signerInfoCount
)
{
int status;
VoltPkcs7ReadSignCtx *readCtx;
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* If the object is "Read Signed" and done, return the count from a
* VoltPkcs7ReadSignCtx localCtx.
*/
if (obj->state == VOLT_P7_STATE_SIGN_READ_FINAL)
{
readCtx = (VoltPkcs7ReadSignCtx *)(obj->localCtx);
*signerInfoCount = readCtx->signerInfosCount;
return (0);
}
/* The object is not "Read Signed" and done, maybe it's "Read Signed"
* and just not done.
*/
*signerInfoCount = 0;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_P7_OBJ;
if (obj->contentType == VOLT_PKCS7_SIGNED_DATA_READ)
{
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
}
VOLT_LOG_ERROR_INFO (
0, obj, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "VoltGetSignerInfoCount", fnctLine, (char *)0)
return (status);
}
static int CheckDSASigningKeys (
VtLibCtx libraryCtx,
VtKeyObject priKey,
VtCertObject cert
)
{
int status;
VtDSAPubKeyInfo *getInfoFromPri, *getInfoFromPub;
VtKeyObject pubKey = (VtKeyObject)0;
VoltCertObject *obj = (VoltCertObject *)cert;
VoltMpIntCtx *mpCtx = obj->mpCtx;
VoltLibCtx *libCtx = (VoltLibCtx *)libraryCtx;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* Build a public key from the cert.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
libraryCtx, VtKeyImplMpCtx, (Pointer)mpCtx, &pubKey);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetKeyParam (
pubKey, VtKeyParamX509CertObject, (Pointer)cert);
if (status != 0)
break;
/* Now get the public key data out of each key object.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetKeyParam (
pubKey, VtKeyParamDSAPublic, (Pointer *)&getInfoFromPub);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetKeyParam (
priKey, VtKeyParamDSAPublic, (Pointer *)&getInfoFromPri);
if (status != 0)
break;
/* Compare the pubValY.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_UNMATCHED_KEY_PAIR;
if (getInfoFromPri->pubValY.len != getInfoFromPub->pubValY.len)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (Z2Memcmp (
getInfoFromPri->pubValY.data, getInfoFromPub->pubValY.data,
getInfoFromPri->pubValY.len) != 0)
break;
/* If we reach this far, the public vlues are the same, we can
* safely assume the keys are the same.
*/
status = 0;
} while (0);
VtDestroyKeyObject (&pubKey);
VOLT_LOG_ERROR_INFO_COMPARE (
status, libraryCtx, 0, status, 0, errorType,
(char *)0, "CheckDSASigningKeys", fnctLine, (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -