📄 writesign.c
字号:
break;
/* Extract the issuerName and serialNum from the signingCert.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltDecodeX509CertCreate (
libCtx, signerInfo->cert.data, signerInfo->cert.len, &x509Cert);
if (status != 0)
break;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
if (Asn1Encoded_set (
newObj->issuerSerial->issuerName, x509Cert->innerCert->issuer->base.data,
(unsigned int)(x509Cert->innerCert->issuer->base.length)) != 1)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (ASN1_STRING_set (
newObj->issuerSerial->serialNumber,
x509Cert->innerCert->serialNum->data,
(unsigned int)(x509Cert->innerCert->serialNum->length)) != 1)
break;
/* We don't have the authenticated attributes or the signature yet,
* but we can put some placeholders there.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = BuildAuthAttributes (
p7Obj, VT_PKCS7_DATA, digestBuf, digestLen, &(signCtx->signingTime),
(unsigned char *)0, 0, &authAttrsLen);
if (status == 0)
status = VT_ERROR_GENERAL;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
authAttrs = (unsigned char *)Z2Malloc (authAttrsLen, 0);
if (authAttrs == (unsigned char *)0)
break;
/* Because authenticated attributes is OPTIONAL, the OpenSSL ASN.1
* engine did not create the Asn1Encoded object.
*/
VOLT_SET_FNCT_LINE (fnctLine)
newObj->authAttributes = Asn1Encoded_new ();
if (newObj->authAttributes == (Asn1Encoded *)0)
break;
VOLT_SET_FNCT_LINE (fnctLine)
if (Asn1Encoded_set (
newObj->authAttributes, authAttrs, authAttrsLen) != 1)
break;
/* Build the signer object, use signatureLen as a temp
* variable to pass in the format.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
signatureLen = VT_DSA_SIGNATURE_DER_ENCODED;
status = VtCreateAlgorithmObject (
(VtLibCtx)libCtx, VtAlgorithmImplDSASign, (Pointer)&signatureLen,
&(signerInfo->signObj));
if (status != 0)
break;
/* If there's a surrender ctx, get it to pass along to signers.
*/
if (surrCtx != (VoltSurrenderCtx *)0)
{
/* Set the signing 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;
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSetAlgorithmParam (
signerInfo->signObj, VtAlgorithmParamSurrenderCallback,
(Pointer)&surrenderCtx);
if (status != 0)
break;
}
VOLT_SET_FNCT_LINE (fnctLine)
status = VtSign (
signerInfo->signObj, signerInfo->priKeyRef, random,
digestCtx->algorithm, (unsigned char *)signCtx, signCtx->digestSize,
(unsigned char *)0, 0, &signatureLen);
if (status == 0)
status = VT_ERROR_GENERAL;
if (status != VT_ERROR_BUFFER_TOO_SMALL)
break;
/* Allocate the signature buffer.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
signerInfo->signature = (unsigned char *)Z2Realloc (
signerInfo->signature, signatureLen);
if (signerInfo->signature == (unsigned char *)0)
break;
signerInfo->sigBufSize = signatureLen;
VOLT_SET_FNCT_LINE (fnctLine)
if (ASN1_OCTET_STRING_set (
newObj->signature, signerInfo->signature, (int)signatureLen) != 1)
break;
/* Encode with a NULL output buffer to get the length.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_INPUT;
signerInfo->signerInfoLen = i2d_Asn1SignerInfo (
newObj, (unsigned char **)0);
if (signerInfo->signerInfoLen == 0)
break;
signerInfo->asn1SignerInfo = newObj;
status = 0;
} while (0);
if (x509Cert != (Asn1X509Cert *)0)
Asn1X509Cert_free (x509Cert);
if (authAttrs != (unsigned char *)0)
Z2Free (authAttrs);
/* If success, we're done.
*/
if (status == 0)
return (0);
/* If error, destroy what we created.
*/
if (newObj != (Asn1SignerInfo *)0)
Asn1SignerInfo_free (newObj);
VOLT_LOG_ERROR_INFO (
0, p7Obj, status, 0, errorType,
(char *)0, "BuildSignerInfoCreate", fnctLine, (char *)0)
return (status);
}
#define VOLT_CONTENT_TYPE_ATTR_LEN \
VoltP9AtContentTypeOidBytesLen+VoltP7DataOidBytesLen+8
static int BuildAuthAttributes (
VoltPkcs7Object *p7Obj,
unsigned int contentType,
unsigned char *contentDigest,
unsigned int contentDigestLen,
VtTime *theTime,
unsigned char *authAttrs,
unsigned int bufferSize,
unsigned int *authAttrsLen
)
{
int status;
unsigned int contentAttrLen, timeAttrLen, digestAttrLen;
unsigned int encodingLen, lengthLen;
VoltLibCtx *libCtx = (VoltLibCtx *)(p7Obj->voltObject.libraryCtx);
unsigned char *temp;
unsigned char contentTypeAttr[VOLT_CONTENT_TYPE_ATTR_LEN] =
{
0x30, VoltP9AtContentTypeOidBytesLen + VoltP7DataOidBytesLen + 6,
0x06, VoltP9AtContentTypeOidBytesLen,
VoltP9AtContentTypeOidBytes,
0x31, VoltP7DataOidBytesLen + 2, 0x06, VoltP7DataOidBytesLen,
VoltP7DataOidBytes
};
unsigned char signTimeOid[VoltP9AtSignTimeOidBytesLen] =
{ VoltP9AtSignTimeOidBytes };
unsigned char digestAttrOid[VoltP9AtDigestOidBytesLen] =
{ VoltP9AtDigestOidBytes };
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
/* We're going to build
*
* 31 len
* 30 len -- contentType attribute
* 30 len -- signingTime attribute
* 30 len -- digest attribute
*
* First, figure out how long each of the attributes will be. The
* contentType attribute is a fixed size, the signingTime attribute
* is one of two sizes depending on whether we use UTCTime or
* GeneralizedTime, and the digest attribute size depends on the
* incoming digest len.
*/
contentAttrLen = VOLT_CONTENT_TYPE_ATTR_LEN;
timeAttrLen = VoltP9AtSignTimeOidBytesLen + VOLT_UTC_LEN + 8;
if (theTime->year >= 2050)
timeAttrLen += (VOLT_GEN_LEN - VOLT_UTC_LEN);
/* Assume the digestLen is not > 0x70 (112 bytes = 896 bits). If
* the toolkit ever supports such a digest (at the time of the
* first release, the largest possible digest it might support is
* 512 bits: SHA-512), this code will have to change.
* If there is a digest > 0x70, the SEQUENCE len will be more than
* 0x7f and will need a 2-byte length.
* The length is 2 bytes for the 30 len, 11 bytes for the
* 06 09 <pkcs-9-at-messageDigset>, 4 bytes for the
* 31 len 04 len in front of the digest, plus the digestLen bytes
*/
digestAttrLen = VoltP9AtDigestOidBytesLen + contentDigestLen + 8;
encodingLen = contentAttrLen + timeAttrLen + digestAttrLen;
/* Determine the lengthLen of the outer SET OF.
*/
lengthLen = VoltDetermineDerLengthLen ((UInt32)encodingLen, (UInt32)0);
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_BUFFER_TOO_SMALL;
*authAttrsLen = 1 + lengthLen + encodingLen;
if (bufferSize < *authAttrsLen)
break;
/* Write out the encoding.
* First, the outer SET OF (IMPLICIT).
*/
temp = authAttrs;
temp += VoltWriteDerTagAndLen (temp, 0xa0, (UInt32)encodingLen, (UInt32)0);
Z2Memcpy (temp, contentTypeAttr, sizeof (contentTypeAttr));
temp += (sizeof (contentTypeAttr) - 1);
/* The contentTypeAttr buffer contains the OID for P7 Data. If the
* contentType flag passed in is not Data, change it.
*/
*temp = (unsigned char)contentType;
temp++;
/* Write the signingTime attribute. Lengths are different depending
* on the year.
*/
temp += VoltWriteDerTagAndLen (
temp, 0x30, (UInt32)(timeAttrLen - 2), (UInt32)0);
temp += VoltWriteDerTagAndLen (
temp, 0x06, (UInt32)VoltP9AtSignTimeOidBytesLen, (UInt32)0);
Z2Memcpy (temp, signTimeOid, VoltP9AtSignTimeOidBytesLen);
temp += VoltP9AtSignTimeOidBytesLen;
if (theTime->year < 2050)
{
temp += VoltWriteDerTagAndLen (
temp, 0x31, (UInt32)(VOLT_UTC_LEN + 2), (UInt32)0);
temp += VoltWriteDerTagAndLen (
temp, 0x17, (UInt32)VOLT_UTC_LEN, (UInt32)0);
temp += VoltConvertVtTimeToUTC (theTime, temp);
}
else
{
temp += VoltWriteDerTagAndLen (
temp, 0x31, (UInt32)(VOLT_GEN_LEN + 2), (UInt32)0);
temp += VoltWriteDerTagAndLen (
temp, 0x18, (UInt32)VOLT_GEN_LEN, (UInt32)0);
temp += VoltConvertVtTimeToGen (theTime, temp);
}
/* Write out the digest attribute.
*/
temp += VoltWriteDerTagAndLen (
temp, 0x30, (UInt32)(digestAttrLen - 2), (UInt32)0);
temp += VoltWriteDerTagAndLen (
temp, 0x06, (UInt32)VoltP9AtDigestOidBytesLen, (UInt32)0);
Z2Memcpy (temp, digestAttrOid, VoltP9AtDigestOidBytesLen);
temp += VoltP9AtDigestOidBytesLen;
temp += VoltWriteDerTagAndLen (
temp, 0x31, (UInt32)(contentDigestLen + 2), (UInt32)0);
temp += VoltWriteDerTagAndLen (
temp, 0x04, (UInt32)contentDigestLen, (UInt32)0);
Z2Memcpy (temp, contentDigest, contentDigestLen);
status = 0;
} while (0);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, p7Obj, status, 0, VT_ERROR_TYPE_PRIMARY,
(char *)0, "BuildAuthAttributes", fnctLine, (char *)0)
return (status);
}
static void FixDsaSignature (
VoltLibCtx *libCtx,
unsigned char *signature,
unsigned int sigBufSize,
unsigned int *signatureLen
)
{
unsigned char *rVal, *sVal;
unsigned int rLen, sLen, offset;
unsigned char tempBuf[48] =
{
0x30, 0x2e, 0x02, 0x15, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x02, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
/* The rLen will be the 4th byte (index 3) always.
* rVal will always begin on the 5th byte (index 4).
*/
rLen = signature[3];
rVal = signature + 4;
/* Now move rLen bytes from rVal to find sLen and sVal.
*/
sLen = signature[rLen + 5];
sVal = signature + rLen + 6;
/* Build a signature with appropriate lengths and leading 00 octets.
*/
offset = 4;
offset += (21 - rLen);
Z2Memcpy (tempBuf + offset, rVal, rLen);
offset = 27;
offset += (21 - sLen);
Z2Memcpy (tempBuf + offset, sVal, sLen);
Z2Memcpy (signature, tempBuf, 48);
*signatureLen = 48;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -