Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
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 | } |