📄 writesign.c
字号:
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, pkcs7Obj, status, 0, errorType,
(char *)0, "VoltP7SignWriteUpdate", fnctLine, (char *)0)
return (status);
}
int VoltP7SignWriteFinal (
VtPkcs7Object pkcs7Obj,
VtRandomObject random,
unsigned char *inputData,
unsigned int inputDataLen,
unsigned char *message,
unsigned int bufferSize,
unsigned int *messageLen
)
{
int status;
unsigned int index, bufSize;
unsigned int signatureLen, lastMessageLen, digestLen, totalLen;
VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
VoltPkcs7WriteSignCtx *signCtx = (VoltPkcs7WriteSignCtx *)(obj->localCtx);
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)
(((VoltAlgorithmObject *)(signCtx->digester))->classCtx);
unsigned char *buffer, *temp;
unsigned char *digest = (unsigned char *)0;
Asn1SignerInfo *nextSignerInfo;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* If no dataLen is set, the inputDataLen is that value.
*/
#if VT_64_BIT_LENGTH == 64
if (obj->dataLen64 == 0)
obj->dataLen64 = (VtUInt64)inputDataLen;
#else
if (obj->dataLen == 0)
obj->dataLen = inputDataLen;
#endif
/* The state must be INIT or UPDATE.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_CALL_ORDER;
if ( (obj->state != VOLT_P7_STATE_SIGN_WRITE_INIT) &&
(obj->state != VOLT_P7_STATE_SIGN_WRITE_UPDATE) )
break;
/* Make sure the total len of input equals the "predicted" len.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
#if VT_64_BIT_LENGTH == 64
if (((VtUInt64)inputDataLen + obj->inputLen64) != obj->dataLen64)
#else
if ((inputDataLen + obj->inputLen) != obj->dataLen)
#endif
break;
/* How much space is needed for the last chunk of data?
* If there's no input data, the outputLen might be 0, which is
* fine. So if the return is 0, reset status to BUFFER_TOO_SMALL
* just to make it easier to break out on a different error.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltP7SignWriteUpdate (
pkcs7Obj, random, (unsigned char *)0, inputDataLen,
(unsigned char *)0, 0, &lastMessageLen);
if (status == 0)
status = VT_ERROR_BUFFER_TOO_SMALL;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
/* We now know how long each of the components will be, determine
* the total length.
* last of the message
* A0 len
* <certs>
* --no CRL's for this implementation--
* 31 len
* <SignerInfo's>
*/
totalLen = VoltDetermineDerLengthLen (
(UInt32)(signCtx->totalCertLen), (UInt32)0);
totalLen += 1 + signCtx->totalCertLen;
totalLen += VoltDetermineDerLengthLen (
(UInt32)(signCtx->totalSignerInfoLen), (UInt32)0);
totalLen += 1 + signCtx->totalSignerInfoLen;
totalLen += lastMessageLen;
/* Make sure totalLen is < 2^32.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT_LENGTH;
if (totalLen < lastMessageLen)
break;
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_BUFFER_TOO_SMALL;
*messageLen = totalLen;
if (bufferSize < totalLen)
break;
/* If the caller passed NULL input with non-zero inputLen, they
* just wanted the length, don't process.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if ( (inputData == (unsigned char *)0) && (inputDataLen != 0) )
break;
/* The buffer is big enough, place data into the output.
*/
totalLen = 0;
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltP7SignWriteUpdate (
pkcs7Obj, random, inputData, inputDataLen,
message, bufferSize, &lastMessageLen);
if (status != 0)
break;
bufferSize -= lastMessageLen;
totalLen += lastMessageLen;
/* Call DigestFinal to get the digest of the data.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestFinal (
signCtx->digester, (unsigned char *)0, 0,
signCtx->digest, signCtx->digestSize, &digestLen);
if (status != 0)
break;
/* Place the certs. IMPLICIT SET OF.
*/
totalLen += VoltWriteDerTagAndLen (
message + totalLen, 0xA0, (UInt32)(signCtx->totalCertLen), (UInt32)0);
for (index = 0; index < signCtx->signerInfosCount; ++index)
{
Z2Memcpy (
message + totalLen, signCtx->signerInfos[index].cert.data,
signCtx->signerInfos[index].cert.len);
totalLen += signCtx->signerInfos[index].cert.len;
}
for (index = 0; index < signCtx->extraCertsCount; ++index)
{
Z2Memcpy (
message + totalLen, signCtx->extraCerts[index].data,
signCtx->extraCerts[index].len);
totalLen += signCtx->extraCerts[index].len;
}
/* Next is SingerInfos, that's a SET OF.
*/
totalLen += VoltWriteDerTagAndLen (
message + totalLen, 0x31,
(UInt32)(signCtx->totalSignerInfoLen), (UInt32)0);
/* We need a buffer to hold the digest of auth attrs.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
digest = (unsigned char *)Z2Malloc (signCtx->digestSize, 0);
if (digest == (unsigned char *)0)
break;
/* For each of the signer's, place the correct digest into the
* authAttributes, then create the signature of the authAttributes.
*/
for (index = 0; index < signCtx->signerInfosCount; ++index)
{
nextSignerInfo = signCtx->signerInfos[index].asn1SignerInfo;
/* We set the Asn1Encoded inside the asn1SignerInfo object with a
* placeholder. We'll fill the buffer inside the object with the
* actual data now.
*/
buffer = nextSignerInfo->authAttributes->base.data;
bufSize = (unsigned int)(nextSignerInfo->authAttributes->base.length);
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = BuildAuthAttributes (
obj, VT_PKCS7_DATA, signCtx->digest, signCtx->digestSize,
&(signCtx->signingTime), buffer, bufSize, &bufSize);
if (status != 0)
break;
/* Digest the auth attrs for the signature.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestInit (signCtx->digester);
if (status != 0)
break;
/* P7 says to sign the auth attrs as SET OF. However, we built
* the authAttrs as IMPLICIT. So for the digesting, change the A0
* to 31. Then when the digesting is done, change it back.
*/
buffer[0] = 0x31;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtDigestFinal (
signCtx->digester, buffer, bufSize,
digest, signCtx->digestSize, &digestLen);
if (status != 0)
break;
buffer[0] = 0xA0;
/* Create a signature for that data.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSign (
signCtx->signerInfos[index].signObj,
signCtx->signerInfos[index].priKeyRef,
random, digestCtx->algorithm, digest, digestLen,
signCtx->signerInfos[index].signature,
signCtx->signerInfos[index].sigBufSize, &signatureLen);
if (status != 0)
break;
/* If the signature is smaller than the sigBufSize, fix it
* (prepend 00 bytes in appropriate places) to make it work.
*/
if (signatureLen != signCtx->signerInfos[index].sigBufSize)
FixDsaSignature (
libCtx, signCtx->signerInfos[index].signature,
signCtx->signerInfos[index].sigBufSize, &signatureLen);
/* Place the signature into the SignerInfo.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
if (ASN1_OCTET_STRING_set (
nextSignerInfo->signature,
signCtx->signerInfos[index].signature, (int)signatureLen) != 1)
break;
/* Encode the SignerInfo into the message buffer.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
temp = message + totalLen;
signCtx->signerInfos[index].signerInfoLen = i2d_Asn1SignerInfo (
signCtx->signerInfos[index].asn1SignerInfo, &temp);
if (temp == (unsigned char *)0)
break;
totalLen += signCtx->signerInfos[index].signerInfoLen;
status = 0;
}
if (status != 0)
break;
} while (0);
if (digest != (unsigned char *)0)
Z2Free (digest);
if (status == 0)
obj->state = VOLT_P7_STATE_SIGN_WRITE_FINAL;
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, pkcs7Obj, status, 0, errorType,
(char *)0, "VoltP7SignWriteFinal", fnctLine, (char *)0)
return (status);
}
static int BuildSignerInfoCreate (
VoltPkcs7Object *p7Obj,
VoltSurrenderCtx *surrCtx,
VtRandomObject random,
unsigned char *digestBuf,
unsigned int digestLen,
VoltP7SignerInfo *signerInfo
)
{
int status;
unsigned int authAttrsLen, signatureLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(p7Obj->voltObject.libraryCtx);
VoltPkcs7WriteSignCtx *signCtx = (VoltPkcs7WriteSignCtx *)(p7Obj->localCtx);
VoltDigestClassCtx *digestCtx = (VoltDigestClassCtx *)
(((VoltAlgorithmObject *)(signCtx->digester))->classCtx);
Asn1SignerInfo *newObj = (Asn1SignerInfo *)0;
Asn1X509Cert *x509Cert = (Asn1X509Cert *)0;
unsigned char *authAttrs = (unsigned char *)0;
VtSurrenderCallback surrenderCtx;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
/* If there's already an object in the struct, do nothing.
*/
if (signerInfo->asn1SignerInfo != (Asn1SignerInfo *)0)
return (0);
do
{
/* Create the object.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
newObj = Asn1SignerInfo_new ();
if (newObj == (Asn1SignerInfo *)0)
break;
/* Set the fields.
*/
VOLT_SET_FNCT_LINE (fnctLine)
if (ASN1_INTEGER_set (newObj->version, 0) != 1)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (Asn1Encoded_set (
newObj->digestAlg, signCtx->digestAlgId.data,
signCtx->digestAlgId.len) != 1)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (Asn1Encoded_set (
newObj->signatureAlg, signCtx->sigAlgId.data,
signCtx->sigAlgId.len) != 1)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -