📄 rsax931impl.c
字号:
/* Get the data into the signature buffer. If the actual length is
* shorter than the required len, prepend 00 bytes.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->MpIntToOctetString (
result, &sign, signature, blockSize, sigLen);
if (status != 0)
break;
if (*sigLen == blockSize)
break;
Z2Memmove (signature + (blockSize - *sigLen), signature, *sigLen);
Z2Memset (signature, 0, blockSize - *sigLen);
*sigLen = blockSize;
} while (0);
if (base != (VoltMpInt *)0)
mpCtx->DestroyMpInt (&base);
if (result != (VoltMpInt *)0)
mpCtx->DestroyMpInt (&result);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, 0,
(char *)0, "X931RSASignData", fnctLine, (char *)0)
return (status);
}
int X931RSAVerifyData (
VoltAlgorithmObject *obj,
VoltKeyObject *key,
VtRandomObject random,
unsigned char *dataToVerify,
unsigned int dataToVerifyLen,
unsigned char *signature,
unsigned int sigLen,
unsigned int *verifyResult
)
{
int status;
unsigned int modLen, resultLen, sign;
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltSignClassCtx *signCtx = (VoltSignClassCtx *)(obj->classCtx);
VoltRsaSignCtx *rsaCtx = (VoltRsaSignCtx *)(signCtx->localSignCtx);
unsigned char *buffer = (unsigned char *)0;
VoltRsaPublicKey *getKeyData;
VtRSAPubKeyInfo *getKeyInfo;
VoltMpIntCtx *mpCtx;
VoltMpInt *base = (VoltMpInt *)0;
VoltMpInt *result = (VoltMpInt *)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
*verifyResult = 0;
do
{
/* Make sure the key is an RSA public key. Also, this implementation
* needs the key as data.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_KEY_OBJ;
if ((key->keyType & VOLT_KEY_TYPE_MASK_ASYM_ALG) != VOLT_KEY_ALG_RSA)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if ((key->keyType & VOLT_KEY_TYPE_PUBLIC) == 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (key->mpCtx == (VoltMpIntCtx *)0)
break;
mpCtx = key->mpCtx;
/* Can we get the key data out of the object?
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetKeyParam (
(VtKeyObject)key, VtKeyParamRSAPublicVerify, (Pointer *)&getKeyInfo);
if (status == VT_ERROR_GET_INFO_UNAVAILABLE)
status = VT_ERROR_INVALID_KEY_OBJ;
if (status != 0)
break;
VtDestroyKeyObject (&(rsaCtx->tempKey));
rsaCtx->priKeyData = (VoltRsaPrivateKey *)0;
rsaCtx->pubKeyData = (VoltRsaPublicKey *)0;
/* Create a key object we know will possess the key data the way
* we want it.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtCreateKeyObject (
obj->voltObject.libraryCtx, VtKeyImplMpCtx, (Pointer)(key->mpCtx),
&(rsaCtx->tempKey));
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetKeyParam (
rsaCtx->tempKey, VtKeyParamRSAPublicVerify, (Pointer)getKeyInfo);
if (status != 0)
break;
key = (VoltKeyObject *)(rsaCtx->tempKey);
getKeyData = (VoltRsaPublicKey *)(key->keyData);
/* How big will the signature be? It depends on the key size.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->GetBitLength (getKeyData->modulus, &modLen);
if (status != 0)
break;
modLen = (modLen + 7) / 8;
/* The signature must be the same length as the modulus.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (sigLen != modLen)
break;
/* Perform the ModExp that is RSA.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->CreateMpInt ((Pointer)mpCtx, &base);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->OctetStringToMpInt (0, signature, sigLen, base);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->CreateMpInt ((Pointer)mpCtx, &result);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->ModExp (
base, getKeyData->pubExpo, getKeyData->modulus, result);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->GetBitLength (result, &resultLen);
if (status != 0)
break;
resultLen = (resultLen + 7) / 8;
/* If the resultLen is > modLen, something went wrong, the
* signature does not verify. We already have the verifyResult set
* to 0 (does not verify).
*/
if (resultLen > modLen)
break;
/* Allocate a buffer to hold the result as a byte array.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
buffer = (unsigned char *)Z2Malloc (modLen, VOLT_MEMORY_SENSITIVE);
if (buffer == (unsigned char *)0)
break;
/* Get the result as a buffer the same size as the modulus, which
* may involve prepending some 00 bytes.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->MpIntToOctetString (
result, &sign, buffer + (modLen - resultLen), resultLen, &resultLen);
if (status != 0)
break;
Z2Memset (buffer, 0, modLen - resultLen);
/* The last byte should be 0xCC, check to see if the last 4 bits
* are indeed 12.
*/
if ((buffer[modLen - 1] & 0x0f) != 0x0c)
{
/* The last 4 bits are not 1100, that means the signer computed
* mod - result. So find mod - result.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->Subtract (getKeyData->modulus, result, base);
if (status != 0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->GetBitLength (base, &resultLen);
if (status != 0)
break;
resultLen = (resultLen + 7) / 8;
/* If the resultLen is > modLen, something went wrong, the
* signature does not verify. We already have the verifyResult
* set 0 (does not verify).
*/
if (resultLen > modLen)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = mpCtx->MpIntToOctetString (
base, &sign, buffer + (modLen - resultLen), resultLen, &resultLen);
if (status != 0)
break;
Z2Memset (buffer, 0, modLen - resultLen);
/* The last byte should be 0xCC, check to see if the last 4 bits
* are indeed 12. If not, the signature does not verify.
*/
if ((buffer[modLen - 1] & 0x0f) != 0x0c)
break;
}
/* If we need to Unpad, call the Unpad function in the signCtx.
*/
if (signCtx->Unpad != (VUnpad)0)
{
/* If the error is INVALID_PAD, just say that the signature did
* not verify (return 0).
* If it was some other error, return the error.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = signCtx->Unpad (
obj, signCtx->padCtx, buffer, modLen, &resultLen);
if (status != 0)
{
/* If the error is something other than INVALID_PAD, return
* that error.
*/
if (status != VT_ERROR_INVALID_PAD)
break;
/* The error is INVALID_PAD. This implementation says the
* signature does not verify. The call was successful, so set
* status to 0, but the sig does not verify (verifyResult was
* initially set to "no").
*/
status = 0;
break;
}
}
/* At this point we need to compare the dataToVerify with the
* unpadded buffer.
*/
if (resultLen != dataToVerifyLen)
break;
if (Z2Memcmp (buffer, dataToVerify, resultLen) != 0)
break;
/* If we reach this point in the code, the signature verifies and
* status is set to 0. Change the verifyResult to verify and we're
* done.
*/
*verifyResult = 1;
} while (0);
if (buffer != (unsigned char *)0)
Z2Free (buffer);
if (base != (VoltMpInt *)0)
mpCtx->DestroyMpInt (&base);
if (result != (VoltMpInt *)0)
mpCtx->DestroyMpInt (&result);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, obj, status, 0, errorType,
(char *)0, "X931RSAVerifyData", fnctLine, (char *)0)
return (status);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -