michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: /* michael@0: * CMS digestedData methods. michael@0: */ michael@0: michael@0: #include "cmslocal.h" michael@0: michael@0: #include "secitem.h" michael@0: #include "secasn1.h" michael@0: #include "secoid.h" michael@0: #include "secerr.h" michael@0: michael@0: /* michael@0: * NSS_CMSDigestedData_Create - create a digestedData object (presumably for encoding) michael@0: * michael@0: * version will be set by NSS_CMSDigestedData_Encode_BeforeStart michael@0: * digestAlg is passed as parameter michael@0: * contentInfo must be filled by the user michael@0: * digest will be calculated while encoding michael@0: */ michael@0: NSSCMSDigestedData * michael@0: NSS_CMSDigestedData_Create(NSSCMSMessage *cmsg, SECAlgorithmID *digestalg) michael@0: { michael@0: void *mark; michael@0: NSSCMSDigestedData *digd; michael@0: PLArenaPool *poolp; michael@0: michael@0: poolp = cmsg->poolp; michael@0: michael@0: mark = PORT_ArenaMark(poolp); michael@0: michael@0: digd = (NSSCMSDigestedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSDigestedData)); michael@0: if (digd == NULL) michael@0: goto loser; michael@0: michael@0: digd->cmsg = cmsg; michael@0: michael@0: if (SECOID_CopyAlgorithmID (poolp, &(digd->digestAlg), digestalg) != SECSuccess) michael@0: goto loser; michael@0: michael@0: PORT_ArenaUnmark(poolp, mark); michael@0: return digd; michael@0: michael@0: loser: michael@0: PORT_ArenaRelease(poolp, mark); michael@0: return NULL; michael@0: } michael@0: michael@0: /* michael@0: * NSS_CMSDigestedData_Destroy - destroy a digestedData object michael@0: */ michael@0: void michael@0: NSS_CMSDigestedData_Destroy(NSSCMSDigestedData *digd) michael@0: { michael@0: /* everything's in a pool, so don't worry about the storage */ michael@0: NSS_CMSContentInfo_Destroy(&(digd->contentInfo)); michael@0: return; michael@0: } michael@0: michael@0: /* michael@0: * NSS_CMSDigestedData_GetContentInfo - return pointer to digestedData object's contentInfo michael@0: */ michael@0: NSSCMSContentInfo * michael@0: NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData *digd) michael@0: { michael@0: return &(digd->contentInfo); michael@0: } michael@0: michael@0: /* michael@0: * NSS_CMSDigestedData_Encode_BeforeStart - do all the necessary things to a DigestedData michael@0: * before encoding begins. michael@0: * michael@0: * In particular: michael@0: * - set the right version number. The contentInfo's content type must be set up already. michael@0: */ michael@0: SECStatus michael@0: NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd) michael@0: { michael@0: unsigned long version; michael@0: SECItem *dummy; michael@0: michael@0: version = NSS_CMS_DIGESTED_DATA_VERSION_DATA; michael@0: if (!NSS_CMSType_IsData(NSS_CMSContentInfo_GetContentTypeTag( michael@0: &(digd->contentInfo)))) michael@0: version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP; michael@0: michael@0: dummy = SEC_ASN1EncodeInteger(digd->cmsg->poolp, &(digd->version), version); michael@0: return (dummy == NULL) ? SECFailure : SECSuccess; michael@0: } michael@0: michael@0: /* michael@0: * NSS_CMSDigestedData_Encode_BeforeData - do all the necessary things to a DigestedData michael@0: * before the encapsulated data is passed through the encoder. michael@0: * michael@0: * In detail: michael@0: * - set up the digests if necessary michael@0: */ michael@0: SECStatus michael@0: NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd) michael@0: { michael@0: SECStatus rv =NSS_CMSContentInfo_Private_Init(&digd->contentInfo); michael@0: if (rv != SECSuccess) { michael@0: return SECFailure; michael@0: } michael@0: michael@0: /* set up the digests */ michael@0: if (digd->digestAlg.algorithm.len != 0 && digd->digest.len == 0) { michael@0: /* if digest is already there, do nothing */ michael@0: digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); michael@0: if (digd->contentInfo.privateInfo->digcx == NULL) michael@0: return SECFailure; michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: /* michael@0: * NSS_CMSDigestedData_Encode_AfterData - do all the necessary things to a DigestedData michael@0: * after all the encapsulated data was passed through the encoder. michael@0: * michael@0: * In detail: michael@0: * - finish the digests michael@0: */ michael@0: SECStatus michael@0: NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData *digd) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: /* did we have digest calculation going on? */ michael@0: if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) { michael@0: rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx, michael@0: digd->cmsg->poolp, michael@0: &(digd->digest)); michael@0: /* error has been set by NSS_CMSDigestContext_FinishSingle */ michael@0: digd->contentInfo.privateInfo->digcx = NULL; michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: /* michael@0: * NSS_CMSDigestedData_Decode_BeforeData - do all the necessary things to a DigestedData michael@0: * before the encapsulated data is passed through the encoder. michael@0: * michael@0: * In detail: michael@0: * - set up the digests if necessary michael@0: */ michael@0: SECStatus michael@0: NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd) michael@0: { michael@0: SECStatus rv; michael@0: michael@0: /* is there a digest algorithm yet? */ michael@0: if (digd->digestAlg.algorithm.len == 0) michael@0: return SECFailure; michael@0: michael@0: rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo); michael@0: if (rv != SECSuccess) { michael@0: return SECFailure; michael@0: } michael@0: michael@0: digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg)); michael@0: if (digd->contentInfo.privateInfo->digcx == NULL) michael@0: return SECFailure; michael@0: michael@0: return SECSuccess; michael@0: } michael@0: michael@0: /* michael@0: * NSS_CMSDigestedData_Decode_AfterData - do all the necessary things to a DigestedData michael@0: * after all the encapsulated data was passed through the encoder. michael@0: * michael@0: * In detail: michael@0: * - finish the digests michael@0: */ michael@0: SECStatus michael@0: NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData *digd) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: /* did we have digest calculation going on? */ michael@0: if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) { michael@0: rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx, michael@0: digd->cmsg->poolp, michael@0: &(digd->cdigest)); michael@0: /* error has been set by NSS_CMSDigestContext_FinishSingle */ michael@0: digd->contentInfo.privateInfo->digcx = NULL; michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: /* michael@0: * NSS_CMSDigestedData_Decode_AfterEnd - finalize a digestedData. michael@0: * michael@0: * In detail: michael@0: * - check the digests for equality michael@0: */ michael@0: SECStatus michael@0: NSS_CMSDigestedData_Decode_AfterEnd(NSSCMSDigestedData *digd) michael@0: { michael@0: /* did we have digest calculation going on? */ michael@0: if (digd->cdigest.len != 0) { michael@0: /* XXX comparision btw digest & cdigest */ michael@0: /* XXX set status */ michael@0: /* TODO!!!! */ michael@0: } michael@0: michael@0: return SECSuccess; michael@0: }