📄 writesign.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 "derhelp.h"
#include "oidlist.h"
#include "vcert.h"
#include "digest.h"
#include "vtime.h"
#include "surrender.h"
#include "errorctx.h"
/* Set up the OpenSSL ASN.1 templates.
*/
ASN1_SEQUENCE (Asn1P9Attribute) =
{
ASN1_SIMPLE (Asn1P9Attribute, attrType, Asn1ObjectId),
ASN1_SET_OF (Asn1P9Attribute, attrValues, Asn1Encoded)
} ASN1_SEQUENCE_END (Asn1P9Attribute);
IMPLEMENT_ASN1_FUNCTIONS (Asn1P9Attribute)
ASN1_SEQUENCE (Asn1IssuerSerial) =
{
ASN1_SIMPLE (Asn1IssuerSerial, issuerName, Asn1Encoded),
ASN1_SIMPLE (Asn1IssuerSerial, serialNumber, ASN1_INTEGER)
} ASN1_SEQUENCE_END (Asn1IssuerSerial);
IMPLEMENT_ASN1_FUNCTIONS (Asn1IssuerSerial)
ASN1_SEQUENCE (Asn1SignerInfo) =
{
ASN1_SIMPLE (Asn1SignerInfo, version, ASN1_INTEGER),
ASN1_SIMPLE (Asn1SignerInfo, issuerSerial, Asn1IssuerSerial),
ASN1_SIMPLE (Asn1SignerInfo, digestAlg, Asn1Encoded),
ASN1_OPT (Asn1SignerInfo, authAttributes, Asn1Encoded),
ASN1_SIMPLE (Asn1SignerInfo, signatureAlg, Asn1Encoded),
ASN1_SIMPLE (Asn1SignerInfo, signature, ASN1_OCTET_STRING),
ASN1_IMP_SET_OF_OPT (Asn1SignerInfo, unauthAttributes, Asn1P9Attribute, 1),
} ASN1_SEQUENCE_END (Asn1SignerInfo);
IMPLEMENT_ASN1_FUNCTIONS (Asn1SignerInfo)
/* Create an Asn1SignerInfo object, then set it with the information
* found in the signerInfo struct.
* <p>The caller passes in a VoltP7SignerInfo struct containing key and
* cert defining the signer. The struct also contains the field where
* the function will place the created Asn1 object.
* <p>The struct also contains a filed for the length of the
* signerInfo. This is the length of the encoded SignerInfo. This length
* will be an upper bound, the actual length may be shorter.
*
* @param p7Obj The object containing the signCtx and other info.
* @param surrCtx If not NULL a surrender ctx to pass on to subordinate
* objects.
* @param random A random object, if needed.
* @param signerInfo The struct containing the key and cert, also the
* place where the created Asn1 object and length will be deposited.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV BuildSignerInfoCreate VOLT_PROTO_LIST ((
VoltPkcs7Object *p7Obj,
VoltSurrenderCtx *surrCtx,
VtRandomObject random,
unsigned char *digestBuf,
unsigned int digestLen,
VoltP7SignerInfo *signerInfo
));
/* Build the AuthenticatedAttributes for a SignedData message.
* <p>Actually, this builds only the following three attributes:
* pkcs-9-at-contentType, pkcs-9-at-messageDigest, and
* pkcs-9-at-signingTime.
* <p>If using AuthenticatedAttributes in a P7 SignedData message, the
* contentType and messageDigest are required.
* <p>The input flag contentType must be one of the following.
* <code>
* <pre>
* VT_PKCS7_DATA
* VT_PKCS7_SIGNED_DATA
* VT_PKCS7_ENVELOPED_DATA
* VT_PKCS7_SIGN_ENV_DATA
* VT_PKCS7_DIGESTED_DATA
* VT_PKCS7_ENCRYPTED_DATA
* </pre>
* </code>
* <p>This routine will create the DER encoding of the Attributes:
* <code>
* <pre>
* Attributes ::= SET OF {
* Attribute }
*
* Attribute ::= SEQUENCE {
* type OID,
* values SET OF ANY }
* </pre>
* </code>
* <p>For SignedData, the Attributes are Implicit, so the function will
* make sure the appropriate tag is used.
* <p>This routine will fill the provided buffer. If no buffer is given
* or if the buffer is too small, the function will return
* VT_ERROR_BUFFER_TOO_SMALL and set the authAttrsLen to the needed
* size.
*
* @param p7Obj The object containing info needed, such as signCtx and
* libCtx.
* @param contentType A flag indicating what contentType is being
* signed (Data, SignedData, EnvelopedData, etc.).
* @param contentDigest The digest of the content, this is what will be
* the value of the messageDigest attribute.
* @param contentDigestLen The length, in bytes, of the contentDigest.
* @param theTime The time to use for signingTime.
* @param authAttrs The buffer the function will fill with the
* attributes.
* @param bufferSize The size, in bytes of the output buffer.
* @param authAttrsLen The address where this function will deposit the
* length, in bytes, of the encoding of the attributes.
* @return an int, 0 if the function completed successfully or a
* non-zero error code.
*/
static int VOLT_CALLING_CONV BuildAuthAttributes VOLT_PROTO_LIST ((
VoltPkcs7Object *p7Obj,
unsigned int contentType,
unsigned char *contentDigest,
unsigned int contentDigestLen,
VtTime *theTime,
unsigned char *authAttrs,
unsigned int bufferSize,
unsigned int *authAttrsLen
));
/* Fix the signature so that the signatureLen is the same as
* sigBufSize. Do this by prepending 00 bytes in the appropriate
* places.
* <p>This particular function operates on DSA signatures only. In the
* future, we'll have to be able to fix any signature. This function
* also expects r and s to be 20 bytes. In other words, the signature
* was created using DSA with a subprime of 160 bits.
* <p>This function expects the signature to be in the buffer and that the
* buffer is sigBufSize bytes big. It will go to the address given by
* signatureLen to find the actual signatureLen, and it will set that
* value to the new signatureLen.
*
* @param libCtx
* @param signature
* @param sigBufSize
* @param signatureLen
* @return none
*/
static void VOLT_CALLING_CONV FixDsaSignature VOLT_PROTO_LIST ((
VoltLibCtx *libCtx,
unsigned char *signature,
unsigned int sigBufSize,
unsigned int *signatureLen
));
int VoltP7SignWriteInit (
VtPkcs7Object pkcs7Obj,
VtPolicyCtx policyCtx,
VtStorageCtx storageCtx,
VtTransportCtx transportCtx,
VtRandomObject random
)
{
int status;
unsigned int index;
VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
VoltPkcs7WriteSignCtx *signCtx = (VoltPkcs7WriteSignCtx *)(obj->localCtx);
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
VoltP7SignerInfo *currentSignerInfo;
VtCertObject nextCert = (VtCertObject)0;
VtItem *getCertData = (VtItem *)0;
VtKeyObject *obtainKey;
VtCertObject *obtainCert;
VoltSurrenderCtx *surrCtx = (VoltSurrenderCtx *)0;
VOLT_DECLARE_ERROR_TYPE (errorType)
VOLT_DECLARE_FNCT_LINE (fnctLine)
do
{
if ( ((obj->voltObject.objectType & VOLT_OBJECT_TYPE_SURRENDER) != 0) &&
(obj->voltObject.surrenderCtx != (Pointer)0) )
surrCtx = (VoltSurrenderCtx *)(obj->voltObject.surrenderCtx);
/* The state must be VOLT_P7_STATE_SIGN_WRITE_SET, if not, we're
* not allowed to call WriteInit.
*/
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_SET)
break;
/* This implementation does not work without signers.
*/
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_INVALID_P7_OBJ;
if (signCtx->signerInfosCount == 0)
break;
/* Get the signing time.
*/
VtGetTime ((VtLibCtx)libCtx, &(signCtx->signingTime));
/* For each of the signers, get the private key and cert. This
* implementation of P7 requires a cert for each signer.
*/
status = 0;
for (index = 0; index < signCtx->signerInfosCount; ++index)
{
currentSignerInfo = &(signCtx->signerInfos[index]);
if ( (currentSignerInfo->priKeyRef == (VtKeyObject)0) &&
(currentSignerInfo->priKey != (VtKeyObject)0) )
currentSignerInfo->priKeyRef = currentSignerInfo->priKey;
/* Check to see if we already have a key and cert.
*/
obtainKey = (VtKeyObject *)0;
obtainCert = (VtCertObject *)0;
if (currentSignerInfo->priKeyRef == (VtKeyObject)0)
obtainKey = &(currentSignerInfo->priKey);
if (currentSignerInfo->cert.data == (unsigned char *)0)
obtainCert = &nextCert;
/* If there's no DSA private key and/or cert, get them. If we
* already have them, no need. We don't need the IBE private key.
*/
if ( (obtainKey != (VtKeyObject *)0) ||
(obtainCert != (VtCertObject *)0) )
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VoltP7GetKeysAndCert (
surrCtx, currentSignerInfo->signerId, random, policyCtx, storageCtx,
transportCtx, obtainCert, (VtKeyObject *)0, obtainKey);
if (status != 0)
break;
}
/* Get the cert data.
*/
if (obtainCert != (VtCertObject *)0)
{
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = VtGetCertParam (
nextCert, VtCertParamX509DerData, (Pointer *)&getCertData);
if (status != 0)
break;
/* Copy the cert data.
*/
VOLT_SET_ERROR_TYPE (errorType, VT_ERROR_TYPE_PRIMARY)
VOLT_SET_FNCT_LINE (fnctLine)
status = VT_ERROR_MEMORY;
if (currentSignerInfo->cert.data != (unsigned char *)0)
Z2Free (currentSignerInfo->cert.data);
currentSignerInfo->cert.data = Z2Malloc (getCertData->len, 0);
if (currentSignerInfo->cert.data == (unsigned char *)0)
break;
Z2Memcpy (
currentSignerInfo->cert.data, getCertData->data, getCertData->len);
currentSignerInfo->cert.len = getCertData->len;
status = 0;
}
if (obtainKey != (VtKeyObject *)0)
currentSignerInfo->priKeyRef = currentSignerInfo->priKey;
/* We only needed this object to get the data. Destroy it so
* the next iteration will have a NULL.
*/
VtDestroyCertObject (&nextCert);
/* Now that we have the key and cert, build the Asn1SignerInfo
* object.
*/
VOLT_SET_ERROR_TYPE (errorType, 0)
VOLT_SET_FNCT_LINE (fnctLine)
status = BuildSignerInfoCreate (
obj, surrCtx, random, signCtx->digest, signCtx->digestSize,
currentSignerInfo);
if (status != 0)
break;
signCtx->totalSignerInfoLen += currentSignerInfo->signerInfoLen;
signCtx->totalCertLen += currentSignerInfo->cert.len;
}
/* Count up the extra certs.
*/
for (index = 0; index < signCtx->extraCertsCount; ++index)
signCtx->totalCertLen += signCtx->extraCerts[index].len;
} while (0);
if (status == 0)
obj->state = VOLT_P7_STATE_SIGN_WRITE_INIT;
VtDestroyCertObject (&nextCert);
VOLT_LOG_ERROR_INFO_COMPARE (
status, 0, pkcs7Obj, status, 0, errorType,
(char *)0, "VoltP7SignWriteInit", fnctLine, (char *)0)
return (status);
}
int VoltP7SignWriteUpdate (
VtPkcs7Object pkcs7Obj,
VtRandomObject random,
unsigned char *inputData,
unsigned int inputDataLen,
unsigned char *message,
unsigned int bufferSize,
unsigned int *messageLen
)
{
int status;
unsigned int offset;
#if VT_64_BIT_LENGTH == 64
VtUInt64 outputLen, contentLen, contentInfoLen, signedDataLen;
VtUInt64 explicitLen, totalLen;
#else
unsigned int outputLen, contentLen, contentInfoLen, signedDataLen;
unsigned int explicitLen, totalLen;
#endif
VoltPkcs7Object *obj = (VoltPkcs7Object *)pkcs7Obj;
VoltPkcs7WriteSignCtx *signCtx = (VoltPkcs7WriteSignCtx *)(obj->localCtx);
VoltLibCtx *libCtx = (VoltLibCtx *)(obj->voltObject.libraryCtx);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -