security/nss/lib/smime/cmsdigdata.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 /*
michael@0 6 * CMS digestedData methods.
michael@0 7 */
michael@0 8
michael@0 9 #include "cmslocal.h"
michael@0 10
michael@0 11 #include "secitem.h"
michael@0 12 #include "secasn1.h"
michael@0 13 #include "secoid.h"
michael@0 14 #include "secerr.h"
michael@0 15
michael@0 16 /*
michael@0 17 * NSS_CMSDigestedData_Create - create a digestedData object (presumably for encoding)
michael@0 18 *
michael@0 19 * version will be set by NSS_CMSDigestedData_Encode_BeforeStart
michael@0 20 * digestAlg is passed as parameter
michael@0 21 * contentInfo must be filled by the user
michael@0 22 * digest will be calculated while encoding
michael@0 23 */
michael@0 24 NSSCMSDigestedData *
michael@0 25 NSS_CMSDigestedData_Create(NSSCMSMessage *cmsg, SECAlgorithmID *digestalg)
michael@0 26 {
michael@0 27 void *mark;
michael@0 28 NSSCMSDigestedData *digd;
michael@0 29 PLArenaPool *poolp;
michael@0 30
michael@0 31 poolp = cmsg->poolp;
michael@0 32
michael@0 33 mark = PORT_ArenaMark(poolp);
michael@0 34
michael@0 35 digd = (NSSCMSDigestedData *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSDigestedData));
michael@0 36 if (digd == NULL)
michael@0 37 goto loser;
michael@0 38
michael@0 39 digd->cmsg = cmsg;
michael@0 40
michael@0 41 if (SECOID_CopyAlgorithmID (poolp, &(digd->digestAlg), digestalg) != SECSuccess)
michael@0 42 goto loser;
michael@0 43
michael@0 44 PORT_ArenaUnmark(poolp, mark);
michael@0 45 return digd;
michael@0 46
michael@0 47 loser:
michael@0 48 PORT_ArenaRelease(poolp, mark);
michael@0 49 return NULL;
michael@0 50 }
michael@0 51
michael@0 52 /*
michael@0 53 * NSS_CMSDigestedData_Destroy - destroy a digestedData object
michael@0 54 */
michael@0 55 void
michael@0 56 NSS_CMSDigestedData_Destroy(NSSCMSDigestedData *digd)
michael@0 57 {
michael@0 58 /* everything's in a pool, so don't worry about the storage */
michael@0 59 NSS_CMSContentInfo_Destroy(&(digd->contentInfo));
michael@0 60 return;
michael@0 61 }
michael@0 62
michael@0 63 /*
michael@0 64 * NSS_CMSDigestedData_GetContentInfo - return pointer to digestedData object's contentInfo
michael@0 65 */
michael@0 66 NSSCMSContentInfo *
michael@0 67 NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData *digd)
michael@0 68 {
michael@0 69 return &(digd->contentInfo);
michael@0 70 }
michael@0 71
michael@0 72 /*
michael@0 73 * NSS_CMSDigestedData_Encode_BeforeStart - do all the necessary things to a DigestedData
michael@0 74 * before encoding begins.
michael@0 75 *
michael@0 76 * In particular:
michael@0 77 * - set the right version number. The contentInfo's content type must be set up already.
michael@0 78 */
michael@0 79 SECStatus
michael@0 80 NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd)
michael@0 81 {
michael@0 82 unsigned long version;
michael@0 83 SECItem *dummy;
michael@0 84
michael@0 85 version = NSS_CMS_DIGESTED_DATA_VERSION_DATA;
michael@0 86 if (!NSS_CMSType_IsData(NSS_CMSContentInfo_GetContentTypeTag(
michael@0 87 &(digd->contentInfo))))
michael@0 88 version = NSS_CMS_DIGESTED_DATA_VERSION_ENCAP;
michael@0 89
michael@0 90 dummy = SEC_ASN1EncodeInteger(digd->cmsg->poolp, &(digd->version), version);
michael@0 91 return (dummy == NULL) ? SECFailure : SECSuccess;
michael@0 92 }
michael@0 93
michael@0 94 /*
michael@0 95 * NSS_CMSDigestedData_Encode_BeforeData - do all the necessary things to a DigestedData
michael@0 96 * before the encapsulated data is passed through the encoder.
michael@0 97 *
michael@0 98 * In detail:
michael@0 99 * - set up the digests if necessary
michael@0 100 */
michael@0 101 SECStatus
michael@0 102 NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd)
michael@0 103 {
michael@0 104 SECStatus rv =NSS_CMSContentInfo_Private_Init(&digd->contentInfo);
michael@0 105 if (rv != SECSuccess) {
michael@0 106 return SECFailure;
michael@0 107 }
michael@0 108
michael@0 109 /* set up the digests */
michael@0 110 if (digd->digestAlg.algorithm.len != 0 && digd->digest.len == 0) {
michael@0 111 /* if digest is already there, do nothing */
michael@0 112 digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg));
michael@0 113 if (digd->contentInfo.privateInfo->digcx == NULL)
michael@0 114 return SECFailure;
michael@0 115 }
michael@0 116 return SECSuccess;
michael@0 117 }
michael@0 118
michael@0 119 /*
michael@0 120 * NSS_CMSDigestedData_Encode_AfterData - do all the necessary things to a DigestedData
michael@0 121 * after all the encapsulated data was passed through the encoder.
michael@0 122 *
michael@0 123 * In detail:
michael@0 124 * - finish the digests
michael@0 125 */
michael@0 126 SECStatus
michael@0 127 NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData *digd)
michael@0 128 {
michael@0 129 SECStatus rv = SECSuccess;
michael@0 130 /* did we have digest calculation going on? */
michael@0 131 if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) {
michael@0 132 rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx,
michael@0 133 digd->cmsg->poolp,
michael@0 134 &(digd->digest));
michael@0 135 /* error has been set by NSS_CMSDigestContext_FinishSingle */
michael@0 136 digd->contentInfo.privateInfo->digcx = NULL;
michael@0 137 }
michael@0 138
michael@0 139 return rv;
michael@0 140 }
michael@0 141
michael@0 142 /*
michael@0 143 * NSS_CMSDigestedData_Decode_BeforeData - do all the necessary things to a DigestedData
michael@0 144 * before the encapsulated data is passed through the encoder.
michael@0 145 *
michael@0 146 * In detail:
michael@0 147 * - set up the digests if necessary
michael@0 148 */
michael@0 149 SECStatus
michael@0 150 NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd)
michael@0 151 {
michael@0 152 SECStatus rv;
michael@0 153
michael@0 154 /* is there a digest algorithm yet? */
michael@0 155 if (digd->digestAlg.algorithm.len == 0)
michael@0 156 return SECFailure;
michael@0 157
michael@0 158 rv = NSS_CMSContentInfo_Private_Init(&digd->contentInfo);
michael@0 159 if (rv != SECSuccess) {
michael@0 160 return SECFailure;
michael@0 161 }
michael@0 162
michael@0 163 digd->contentInfo.privateInfo->digcx = NSS_CMSDigestContext_StartSingle(&(digd->digestAlg));
michael@0 164 if (digd->contentInfo.privateInfo->digcx == NULL)
michael@0 165 return SECFailure;
michael@0 166
michael@0 167 return SECSuccess;
michael@0 168 }
michael@0 169
michael@0 170 /*
michael@0 171 * NSS_CMSDigestedData_Decode_AfterData - do all the necessary things to a DigestedData
michael@0 172 * after all the encapsulated data was passed through the encoder.
michael@0 173 *
michael@0 174 * In detail:
michael@0 175 * - finish the digests
michael@0 176 */
michael@0 177 SECStatus
michael@0 178 NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData *digd)
michael@0 179 {
michael@0 180 SECStatus rv = SECSuccess;
michael@0 181 /* did we have digest calculation going on? */
michael@0 182 if (digd->contentInfo.privateInfo && digd->contentInfo.privateInfo->digcx) {
michael@0 183 rv = NSS_CMSDigestContext_FinishSingle(digd->contentInfo.privateInfo->digcx,
michael@0 184 digd->cmsg->poolp,
michael@0 185 &(digd->cdigest));
michael@0 186 /* error has been set by NSS_CMSDigestContext_FinishSingle */
michael@0 187 digd->contentInfo.privateInfo->digcx = NULL;
michael@0 188 }
michael@0 189
michael@0 190 return rv;
michael@0 191 }
michael@0 192
michael@0 193 /*
michael@0 194 * NSS_CMSDigestedData_Decode_AfterEnd - finalize a digestedData.
michael@0 195 *
michael@0 196 * In detail:
michael@0 197 * - check the digests for equality
michael@0 198 */
michael@0 199 SECStatus
michael@0 200 NSS_CMSDigestedData_Decode_AfterEnd(NSSCMSDigestedData *digd)
michael@0 201 {
michael@0 202 /* did we have digest calculation going on? */
michael@0 203 if (digd->cdigest.len != 0) {
michael@0 204 /* XXX comparision btw digest & cdigest */
michael@0 205 /* XXX set status */
michael@0 206 /* TODO!!!! */
michael@0 207 }
michael@0 208
michael@0 209 return SECSuccess;
michael@0 210 }

mercurial