示例#1
0
int
sm_SignMessage (
	unsigned char   **signedMessage,	/* OUT */
	size_t		*signedMessageLen,	/* OUT */
	unsigned char	*tbs,			/* IN data to sign */
	size_t		tbsLen,			/* IN length of `tbs' */
	int		nested,			/* IN */
	const char	*contentType,		/* IN type of `tbs' */
	const char	*digestAlgorithm,	/* IN */
	const unsigned char	*digestParam,	/* IN */
	size_t		digestParamSize,	/* IN */
	const char	*signatureAlgorithm,	/* IN */
	const unsigned char	*sigParam,	/* IN */
	size_t		sigParamSize,		/* IN */
	PKICertificate	*signerCertificate,	/* IN */
	PKIAttributes	*signedAttributes,	/* IN (optional) */
	List		*includeCerts,		/* IN (optional) */
	HashCallback	*hashCallback,		/* IN */
	void		*hashCallbackData,	/* IN (optional) */
	SignCallback	*signCallback,		/* IN */
	void		*signCallbackData,	/* IN (optional) */
	PKICONTEXT	*ctx)			/* IN */
{
    PKIContentInfo	contentInfo;
    PKISignedData	*signedData;
    PKISignerInfo	*signerInfo;
    PKIOBJECT_ID	*digestOID;
    PKIOBJECT_ID	*contentOID;
    PKIOBJECT_ID	*signatureOID;
    PKIOBJECT_ID	*contentTypeOID;
    PKIOBJECT_ID	*signedDataOID;
    PKIANY		asnBlock;
    PKIANY		digestValue;

    int			err = 0;
    int			i;
    size_t		msgLen;
    unsigned char	*msg;
    int			result;
    unsigned char	*pcontent;
    size_t		pcontentlen;

    signedData = PKINewSignedData (ctx);

    /* CMS states that the version is 1 if no attribute certificates are
       present and the underlying content type is id-data */
    PKIPutIntVal (ctx, &signedData->version, (!strcmp (contentType, SM_OID_CONTENT_DATA)) ? 1 : 3);

    signedData->digestAlgorithms.n = 1;
    signedData->digestAlgorithms.elt[0] = PKINewDigestAlgorithmIdentifier (ctx);

    digestOID = sm_StringToOID (digestAlgorithm, ctx);

    PKIPutOctVal (ctx, &signedData->digestAlgorithms.elt[0]->algorithm, digestOID->val, digestOID->len);
    if (digestParamSize)
    {
	signedData->digestAlgorithms.elt[0]->parameters = PKINewANY (ctx);
	PKIPutOctVal (ctx, signedData->digestAlgorithms.elt[0]->parameters, digestParam, digestParamSize);
    }

    contentOID = sm_StringToOID (contentType, ctx);
    PKIPutOctVal (ctx, &signedData->contentInfo.contentType, contentOID->val, contentOID->len);

    /* add the data that is being signed */
    signedData->contentInfo.content = PKINewANY (ctx);

    /* if we have type Data, it must be encoded as OCTET STRING */
    if (strcmp (contentType, SM_OID_CONTENT_DATA) == 0)
    {
        PKIOCTET_STRING    *content;

        content = PKINewOCTET_STRING (ctx);
        PKIPutOctVal (ctx, content, tbs, tbsLen);
        signedData->contentInfo.content->len = PKISizeofOCTET_STRING (ctx, content, 1);
        signedData->contentInfo.content->val = PKIAlloc (ctx->memMgr, signedData->contentInfo.content->len);
        PKIPackOCTET_STRING (ctx, signedData->contentInfo.content->val, signedData->contentInfo.content->len, content, &err);
        PKIFreeOCTET_STRING (ctx, content);
        if (err)
            return PKCS7_ERROR_UNKNOWN;
        pcontent = tbs;
        pcontentlen = tbsLen;
    }
    else
    {
        PKIPutOctVal (ctx, signedData->contentInfo.content, tbs, tbsLen);
        /* when signing, the type and length octets are not included in the hash */
        pcontent = tbs + 1;
        pcontent += PKIGetLength (pcontent, &pcontentlen);
    }

    signedData->signerInfos.n = 1;
    signerInfo = signedData->signerInfos.elt[0] = PKINewSignerInfo (ctx);

    PKIPutIntVal (ctx, &signerInfo->version, 1); /* version 1 */

    sm_CopyIssuerAndSerialNumber (&signerInfo->issuerAndSerialNumber, signerCertificate, ctx);

    PKIPutOctVal (ctx, &signerInfo->digestAlgorithm.algorithm, digestOID->val, digestOID->len);
    PKIFreeOBJECT_ID (ctx, digestOID);
    if (digestParamSize)
    {
	signerInfo->digestAlgorithm.parameters = PKINewANY (ctx);
	PKIPutOctVal (ctx, signerInfo->digestAlgorithm.parameters, digestParam, digestParamSize);
    }

    if (signedAttributes || (strcmp (contentType, SM_OID_CONTENT_DATA)))
    {
	contentTypeOID = sm_StringToOID (SM_OID_CONTENT_TYPE, ctx);

	signerInfo->authenticatedAttributes = PKINewAttributes (ctx);

	/* add the id-contentType attribute */
	memset (&asnBlock, 0, sizeof (asnBlock));
	asnBlock.len = PKISizeofOBJECT_ID (ctx, contentOID, 1);
	asnBlock.val = PKIAlloc (ctx->memMgr, asnBlock.len);
	PKIPackOBJECT_ID (ctx, asnBlock.val, asnBlock.len, contentOID, &err);
	sm_AddSimpleAttribute (signerInfo->authenticatedAttributes, contentTypeOID, &asnBlock, ctx);
	PKIFree (ctx->memMgr, asnBlock.val);
	PKIFreeOBJECT_ID (ctx, contentTypeOID);

	/* add the id-messageDigest attribute */
	result = hashCallback (&digestValue, digestAlgorithm, pcontent, pcontentlen, hashCallbackData, ctx);
	if (result != PKCS7_OK)
	    return (result);

	memset (&asnBlock, 0, sizeof (asnBlock));
	err = 0;
	asnBlock.len = PKISizeofOCTET_STRING (ctx, &digestValue, 1);
	asnBlock.val = PKIAlloc (ctx->memMgr, asnBlock.len);
	PKIPackOCTET_STRING (ctx, asnBlock.val, asnBlock.len, &digestValue, &err);
	contentTypeOID = sm_StringToOID (SM_OID_MESSAGE_DIGEST, ctx);
	sm_AddSimpleAttribute (signerInfo->authenticatedAttributes, contentTypeOID, &asnBlock, ctx);
	PKIFreeOBJECT_ID (ctx, contentTypeOID);
	PKIFree (ctx->memMgr, asnBlock.val);
	PKIFree (ctx->memMgr, digestValue.val);

	/* add the user specified attributes */
	if (signedAttributes)
	{
	    for (i = 0; i < signedAttributes->n; i++)
	    {
		signerInfo->authenticatedAttributes->elt[signerInfo->authenticatedAttributes->n++] = sm_CopyAttribute (signedAttributes->elt[i], ctx);
	    }
	}

	/* if auth attributes are present, we sign the DER of it.  the body
	   of the message is protected by the fact that the hash value is
	   included as an attribute */
	msgLen = PKISizeofAttributes (ctx, signerInfo->authenticatedAttributes, 1);
	msg = PKIAlloc (ctx->memMgr, msgLen);
	PKIPackAttributes (ctx, msg, msgLen, signerInfo->authenticatedAttributes, &err);
	if (err)
	    return PKCS7_ERROR_ATTRIBUTES;
    }
    else
    {
	/* otherwise sign the data itself */
	msgLen = pcontentlen;
	msg = PKIAlloc (ctx->memMgr, msgLen);
	memcpy (msg, pcontent, pcontentlen);
    }

    PKIFreeOBJECT_ID (ctx, contentOID);

    result = signCallback (
	    &signerInfo->encryptedDigest,
	    digestAlgorithm,
	    signatureAlgorithm,
	    signerCertificate,
	    msg,
	    msgLen,
	    signCallbackData,
	    ctx);
    PKIFree (ctx->memMgr, msg);
    if (result != PKCS7_OK)
        return (result);

    signatureOID = sm_StringToOID (signatureAlgorithm, ctx);
    PKIPutOctVal (ctx,
	    &signerInfo->digestEncryptionAlgorithm.algorithm,
	    signatureOID->val, signatureOID->len);
    PKIFreeOBJECT_ID (ctx, signatureOID);

    if (sigParamSize)
    {
	signerInfo->digestEncryptionAlgorithm.parameters = PKINewANY (ctx);
	PKIPutOctVal (ctx, signerInfo->digestEncryptionAlgorithm.parameters, sigParam, sigParamSize);
    }

    if (includeCerts)
    {
	List *pCert;
	int certCount = 0;
	
	signedData->certificates = PKINewExtendedCertificatesAndCertificates(ctx);
	for (pCert = includeCerts; pCert; pCert = pCert->next, certCount++)
	{
	    unsigned char *certData;
	    size_t certLen;
	    PKICertificate *tCert = (PKICertificate *) pCert->data;
	    int asnError = 0;
	    
	    certLen = PKISizeofCertificate (ctx, tCert, 1);
	    certData = PKIAlloc (ctx->memMgr, certLen);
	    PKIPackCertificate (ctx, certData, certLen, tCert, &asnError);
	    if (asnError)
	    {
		PKIFree (ctx->memMgr, certData);
		continue;
	    }
	    signedData->certificates->elt[certCount] = PKIAlloc (ctx->memMgr,
		    sizeof (PKIExtendedCertificateOrCertificate));
	    signedData->certificates->elt[certCount]->CHOICE_field_type = PKIID_Certificate;
	    PKIUnpackCertificate (ctx, (PKICertificate **) &signedData->certificates->elt[certCount]->data,
		    certData,
		    certLen,
		    &asnError);
	    PKIFree (ctx->memMgr, certData);
	}
	signedData->certificates->n = certCount;
    }

    if (nested)
    {
	/* when doing nested protection, the ContentInfo header will be
	   present in the upper level SignedData or EnvelopedData, so just
	   return the SignedData object directly */

	*signedMessageLen = PKISizeofSignedData (ctx, signedData, 1);
	*signedMessage = PKIAlloc (ctx->memMgr, *signedMessageLen);
	PKIPackSignedData (ctx, *signedMessage, *signedMessageLen, signedData, &err);
    }
    else
    {
	signedDataOID = sm_StringToOID (SM_OID_CONTENT_SIGNED_DATA, ctx);

	memset (&contentInfo, 0, sizeof (contentInfo));
	PKIPutOctVal (ctx, &contentInfo.contentType, signedDataOID->val, signedDataOID->len);
	PKIFreeOCTET_STRING (ctx, signedDataOID);

	contentInfo.content = PKINewANY (ctx);
	contentInfo.content->len = PKISizeofSignedData (ctx, signedData, 1);
	contentInfo.content->val = PKIAlloc (ctx->memMgr, contentInfo.content->len);
	PKIPackSignedData (ctx, contentInfo.content->val, contentInfo.content->len, signedData, &err);

	/* pack up the final version of the message */
	*signedMessageLen = PKISizeofContentInfo (ctx, &contentInfo, 1);
	*signedMessage = PKIAlloc (ctx->memMgr, *signedMessageLen);
	PKIPackContentInfo (ctx, *signedMessage, *signedMessageLen, &contentInfo, &err);

	PKIDropInPlaceContentInfo (ctx, &contentInfo);
    }

    PKIFreeSignedData (ctx, signedData);

    return 0;
}
示例#2
0
void CGHostGenie :: EventBNETHashRequest( const EventBNETHashRequestData &data )
{
	if( hashCallback != NULL )
		hashCallback( callbackObject, data );
}