security/nss/lib/crmf/respcmn.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C; tab-width: 8 -*-*/
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "cmmf.h"
michael@0 7 #include "cmmfi.h"
michael@0 8 #include "secitem.h"
michael@0 9 #include "secder.h"
michael@0 10
michael@0 11 SECStatus
michael@0 12 cmmf_DestroyPKIStatusInfo (CMMFPKIStatusInfo *info, PRBool freeit)
michael@0 13 {
michael@0 14 if (info->status.data != NULL) {
michael@0 15 PORT_Free(info->status.data);
michael@0 16 info->status.data = NULL;
michael@0 17 }
michael@0 18 if (info->statusString.data != NULL) {
michael@0 19 PORT_Free(info->statusString.data);
michael@0 20 info->statusString.data = NULL;
michael@0 21 }
michael@0 22 if (info->failInfo.data != NULL) {
michael@0 23 PORT_Free(info->failInfo.data);
michael@0 24 info->failInfo.data = NULL;
michael@0 25 }
michael@0 26 if (freeit) {
michael@0 27 PORT_Free(info);
michael@0 28 }
michael@0 29 return SECSuccess;
michael@0 30 }
michael@0 31
michael@0 32 SECStatus
michael@0 33 CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp)
michael@0 34 {
michael@0 35 PORT_Assert(inCertResp != NULL);
michael@0 36 if (inCertResp != NULL) {
michael@0 37 if (inCertResp->certReqId.data != NULL) {
michael@0 38 PORT_Free(inCertResp->certReqId.data);
michael@0 39 }
michael@0 40 cmmf_DestroyPKIStatusInfo(&inCertResp->status, PR_FALSE);
michael@0 41 if (inCertResp->certifiedKeyPair != NULL) {
michael@0 42 CMMF_DestroyCertifiedKeyPair(inCertResp->certifiedKeyPair);
michael@0 43 }
michael@0 44 PORT_Free(inCertResp);
michael@0 45 }
michael@0 46 return SECSuccess;
michael@0 47 }
michael@0 48
michael@0 49 SECStatus
michael@0 50 CMMF_DestroyCertRepContent(CMMFCertRepContent *inCertRepContent)
michael@0 51 {
michael@0 52 PORT_Assert(inCertRepContent != NULL);
michael@0 53 if (inCertRepContent != NULL) {
michael@0 54 CMMFCertResponse **pResponse = inCertRepContent->response;
michael@0 55 if (pResponse != NULL) {
michael@0 56 for (; *pResponse != NULL; pResponse++) {
michael@0 57 CMMFCertifiedKeyPair *certKeyPair = (*pResponse)->certifiedKeyPair;
michael@0 58 /* XXX Why not call CMMF_DestroyCertifiedKeyPair or
michael@0 59 ** XXX cmmf_DestroyCertOrEncCert ?
michael@0 60 */
michael@0 61 if (certKeyPair != NULL &&
michael@0 62 certKeyPair->certOrEncCert.choice == cmmfCertificate &&
michael@0 63 certKeyPair->certOrEncCert.cert.certificate != NULL) {
michael@0 64 CERT_DestroyCertificate
michael@0 65 (certKeyPair->certOrEncCert.cert.certificate);
michael@0 66 certKeyPair->certOrEncCert.cert.certificate = NULL;
michael@0 67 }
michael@0 68 }
michael@0 69 }
michael@0 70 if (inCertRepContent->caPubs) {
michael@0 71 CERTCertificate **caPubs = inCertRepContent->caPubs;
michael@0 72 for (; *caPubs; ++caPubs) {
michael@0 73 CERT_DestroyCertificate(*caPubs);
michael@0 74 *caPubs = NULL;
michael@0 75 }
michael@0 76 }
michael@0 77 if (inCertRepContent->poolp != NULL) {
michael@0 78 PORT_FreeArena(inCertRepContent->poolp, PR_TRUE);
michael@0 79 }
michael@0 80 }
michael@0 81 return SECSuccess;
michael@0 82 }
michael@0 83
michael@0 84 SECStatus
michael@0 85 CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont)
michael@0 86 {
michael@0 87 PORT_Assert(inDecKeyCont != NULL);
michael@0 88 if (inDecKeyCont != NULL && inDecKeyCont->poolp) {
michael@0 89 PORT_FreeArena(inDecKeyCont->poolp, PR_FALSE);
michael@0 90 }
michael@0 91 return SECSuccess;
michael@0 92 }
michael@0 93
michael@0 94 SECStatus
michael@0 95 crmf_create_prtime(SECItem *src, PRTime **dest)
michael@0 96 {
michael@0 97 *dest = PORT_ZNew(PRTime);
michael@0 98 return DER_DecodeTimeChoice(*dest, src);
michael@0 99 }
michael@0 100
michael@0 101 CRMFCertExtension*
michael@0 102 crmf_copy_cert_extension(PLArenaPool *poolp, CRMFCertExtension *inExtension)
michael@0 103 {
michael@0 104 PRBool isCritical;
michael@0 105 SECOidTag id;
michael@0 106 SECItem *data;
michael@0 107 CRMFCertExtension *newExt;
michael@0 108
michael@0 109 PORT_Assert(inExtension != NULL);
michael@0 110 if (inExtension == NULL) {
michael@0 111 return NULL;
michael@0 112 }
michael@0 113 id = CRMF_CertExtensionGetOidTag(inExtension);
michael@0 114 isCritical = CRMF_CertExtensionGetIsCritical(inExtension);
michael@0 115 data = CRMF_CertExtensionGetValue(inExtension);
michael@0 116 newExt = crmf_create_cert_extension(poolp, id,
michael@0 117 isCritical,
michael@0 118 data);
michael@0 119 SECITEM_FreeItem(data, PR_TRUE);
michael@0 120 return newExt;
michael@0 121 }
michael@0 122
michael@0 123 static SECItem*
michael@0 124 cmmf_encode_certificate(CERTCertificate *inCert)
michael@0 125 {
michael@0 126 return SEC_ASN1EncodeItem(NULL, NULL, inCert,
michael@0 127 SEC_ASN1_GET(SEC_SignedCertificateTemplate));
michael@0 128 }
michael@0 129
michael@0 130 CERTCertList*
michael@0 131 cmmf_MakeCertList(CERTCertificate **inCerts)
michael@0 132 {
michael@0 133 CERTCertList *certList;
michael@0 134 CERTCertificate *currCert;
michael@0 135 SECItem *derCert, *freeCert = NULL;
michael@0 136 SECStatus rv;
michael@0 137 int i;
michael@0 138
michael@0 139 certList = CERT_NewCertList();
michael@0 140 if (certList == NULL) {
michael@0 141 return NULL;
michael@0 142 }
michael@0 143 for (i=0; inCerts[i] != NULL; i++) {
michael@0 144 derCert = &inCerts[i]->derCert;
michael@0 145 if (derCert->data == NULL) {
michael@0 146 derCert = freeCert = cmmf_encode_certificate(inCerts[i]);
michael@0 147 }
michael@0 148 currCert=CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
michael@0 149 derCert, NULL, PR_FALSE, PR_TRUE);
michael@0 150 if (freeCert != NULL) {
michael@0 151 SECITEM_FreeItem(freeCert, PR_TRUE);
michael@0 152 freeCert = NULL;
michael@0 153 }
michael@0 154 if (currCert == NULL) {
michael@0 155 goto loser;
michael@0 156 }
michael@0 157 rv = CERT_AddCertToListTail(certList, currCert);
michael@0 158 if (rv != SECSuccess) {
michael@0 159 goto loser;
michael@0 160 }
michael@0 161 }
michael@0 162 return certList;
michael@0 163 loser:
michael@0 164 CERT_DestroyCertList(certList);
michael@0 165 return NULL;
michael@0 166 }
michael@0 167
michael@0 168 CMMFPKIStatus
michael@0 169 cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus)
michael@0 170 {
michael@0 171 long derVal;
michael@0 172
michael@0 173 derVal = DER_GetInteger(&inStatus->status);
michael@0 174 if (derVal == -1 || derVal < cmmfGranted || derVal >= cmmfNumPKIStatus) {
michael@0 175 return cmmfNoPKIStatus;
michael@0 176 }
michael@0 177 return (CMMFPKIStatus)derVal;
michael@0 178 }
michael@0 179
michael@0 180 int
michael@0 181 CMMF_CertRepContentGetNumResponses(CMMFCertRepContent *inCertRepContent)
michael@0 182 {
michael@0 183 int numResponses = 0;
michael@0 184 PORT_Assert (inCertRepContent != NULL);
michael@0 185 if (inCertRepContent != NULL && inCertRepContent->response != NULL) {
michael@0 186 while (inCertRepContent->response[numResponses] != NULL) {
michael@0 187 numResponses++;
michael@0 188 }
michael@0 189 }
michael@0 190 return numResponses;
michael@0 191 }
michael@0 192
michael@0 193
michael@0 194 SECStatus
michael@0 195 cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit)
michael@0 196 {
michael@0 197 switch (certOrEncCert->choice) {
michael@0 198 case cmmfCertificate:
michael@0 199 CERT_DestroyCertificate(certOrEncCert->cert.certificate);
michael@0 200 certOrEncCert->cert.certificate = NULL;
michael@0 201 break;
michael@0 202 case cmmfEncryptedCert:
michael@0 203 crmf_destroy_encrypted_value(certOrEncCert->cert.encryptedCert,
michael@0 204 PR_TRUE);
michael@0 205 certOrEncCert->cert.encryptedCert = NULL;
michael@0 206 break;
michael@0 207 default:
michael@0 208 break;
michael@0 209 }
michael@0 210 if (freeit) {
michael@0 211 PORT_Free(certOrEncCert);
michael@0 212 }
michael@0 213 return SECSuccess;
michael@0 214 }
michael@0 215
michael@0 216 SECStatus
michael@0 217 cmmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src)
michael@0 218 {
michael@0 219 SECStatus rv;
michael@0 220
michael@0 221 if (src->data != NULL) {
michael@0 222 rv = SECITEM_CopyItem(poolp, dest, src);
michael@0 223 } else {
michael@0 224 dest->data = NULL;
michael@0 225 dest->len = 0;
michael@0 226 rv = SECSuccess;
michael@0 227 }
michael@0 228 return rv;
michael@0 229 }
michael@0 230
michael@0 231 SECStatus
michael@0 232 CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair)
michael@0 233 {
michael@0 234 PORT_Assert(inCertKeyPair != NULL);
michael@0 235 if (inCertKeyPair != NULL) {
michael@0 236 cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE);
michael@0 237 if (inCertKeyPair->privateKey) {
michael@0 238 crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE);
michael@0 239 }
michael@0 240 if (inCertKeyPair->derPublicationInfo.data) {
michael@0 241 PORT_Free(inCertKeyPair->derPublicationInfo.data);
michael@0 242 }
michael@0 243 PORT_Free(inCertKeyPair);
michael@0 244 }
michael@0 245 return SECSuccess;
michael@0 246 }
michael@0 247
michael@0 248 SECStatus
michael@0 249 cmmf_CopyCertResponse(PLArenaPool *poolp,
michael@0 250 CMMFCertResponse *dest,
michael@0 251 CMMFCertResponse *src)
michael@0 252 {
michael@0 253 SECStatus rv;
michael@0 254
michael@0 255 if (src->certReqId.data != NULL) {
michael@0 256 rv = SECITEM_CopyItem(poolp, &dest->certReqId, &src->certReqId);
michael@0 257 if (rv != SECSuccess) {
michael@0 258 return rv;
michael@0 259 }
michael@0 260 }
michael@0 261 rv = cmmf_CopyPKIStatusInfo(poolp, &dest->status, &src->status);
michael@0 262 if (rv != SECSuccess) {
michael@0 263 return rv;
michael@0 264 }
michael@0 265 if (src->certifiedKeyPair != NULL) {
michael@0 266 CMMFCertifiedKeyPair *destKeyPair;
michael@0 267
michael@0 268 destKeyPair = (poolp == NULL) ? PORT_ZNew(CMMFCertifiedKeyPair) :
michael@0 269 PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair);
michael@0 270 if (!destKeyPair) {
michael@0 271 return SECFailure;
michael@0 272 }
michael@0 273 rv = cmmf_CopyCertifiedKeyPair(poolp, destKeyPair,
michael@0 274 src->certifiedKeyPair);
michael@0 275 if (rv != SECSuccess) {
michael@0 276 if (!poolp) {
michael@0 277 CMMF_DestroyCertifiedKeyPair(destKeyPair);
michael@0 278 }
michael@0 279 return rv;
michael@0 280 }
michael@0 281 dest->certifiedKeyPair = destKeyPair;
michael@0 282 }
michael@0 283 return SECSuccess;
michael@0 284 }
michael@0 285
michael@0 286 static SECStatus
michael@0 287 cmmf_CopyCertOrEncCert(PLArenaPool *poolp, CMMFCertOrEncCert *dest,
michael@0 288 CMMFCertOrEncCert *src)
michael@0 289 {
michael@0 290 SECStatus rv = SECSuccess;
michael@0 291 CRMFEncryptedValue *encVal;
michael@0 292
michael@0 293 dest->choice = src->choice;
michael@0 294 rv = cmmf_copy_secitem(poolp, &dest->derValue, &src->derValue);
michael@0 295 switch (src->choice) {
michael@0 296 case cmmfCertificate:
michael@0 297 dest->cert.certificate = CERT_DupCertificate(src->cert.certificate);
michael@0 298 break;
michael@0 299 case cmmfEncryptedCert:
michael@0 300 encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) :
michael@0 301 PORT_ArenaZNew(poolp, CRMFEncryptedValue);
michael@0 302 if (encVal == NULL) {
michael@0 303 return SECFailure;
michael@0 304 }
michael@0 305 rv = crmf_copy_encryptedvalue(poolp, src->cert.encryptedCert, encVal);
michael@0 306 if (rv != SECSuccess) {
michael@0 307 if (!poolp) {
michael@0 308 crmf_destroy_encrypted_value(encVal, PR_TRUE);
michael@0 309 }
michael@0 310 return rv;
michael@0 311 }
michael@0 312 dest->cert.encryptedCert = encVal;
michael@0 313 break;
michael@0 314 default:
michael@0 315 rv = SECFailure;
michael@0 316 }
michael@0 317 return rv;
michael@0 318 }
michael@0 319
michael@0 320 SECStatus
michael@0 321 cmmf_CopyCertifiedKeyPair(PLArenaPool *poolp, CMMFCertifiedKeyPair *dest,
michael@0 322 CMMFCertifiedKeyPair *src)
michael@0 323 {
michael@0 324 SECStatus rv;
michael@0 325
michael@0 326 rv = cmmf_CopyCertOrEncCert(poolp, &dest->certOrEncCert,
michael@0 327 &src->certOrEncCert);
michael@0 328 if (rv != SECSuccess) {
michael@0 329 return rv;
michael@0 330 }
michael@0 331
michael@0 332 if (src->privateKey != NULL) {
michael@0 333 CRMFEncryptedValue *encVal;
michael@0 334
michael@0 335 encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) :
michael@0 336 PORT_ArenaZNew(poolp, CRMFEncryptedValue);
michael@0 337 if (encVal == NULL) {
michael@0 338 return SECFailure;
michael@0 339 }
michael@0 340 rv = crmf_copy_encryptedvalue(poolp, src->privateKey,
michael@0 341 encVal);
michael@0 342 if (rv != SECSuccess) {
michael@0 343 if (!poolp) {
michael@0 344 crmf_destroy_encrypted_value(encVal, PR_TRUE);
michael@0 345 }
michael@0 346 return rv;
michael@0 347 }
michael@0 348 dest->privateKey = encVal;
michael@0 349 }
michael@0 350 rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo,
michael@0 351 &src->derPublicationInfo);
michael@0 352 return rv;
michael@0 353 }
michael@0 354
michael@0 355 SECStatus
michael@0 356 cmmf_CopyPKIStatusInfo(PLArenaPool *poolp, CMMFPKIStatusInfo *dest,
michael@0 357 CMMFPKIStatusInfo *src)
michael@0 358 {
michael@0 359 SECStatus rv;
michael@0 360
michael@0 361 rv = cmmf_copy_secitem (poolp, &dest->status, &src->status);
michael@0 362 if (rv != SECSuccess) {
michael@0 363 return rv;
michael@0 364 }
michael@0 365 rv = cmmf_copy_secitem (poolp, &dest->statusString, &src->statusString);
michael@0 366 if (rv != SECSuccess) {
michael@0 367 return rv;
michael@0 368 }
michael@0 369 rv = cmmf_copy_secitem (poolp, &dest->failInfo, &src->failInfo);
michael@0 370 return rv;
michael@0 371 }
michael@0 372
michael@0 373 CERTCertificate*
michael@0 374 cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert,
michael@0 375 CERTCertDBHandle *certdb)
michael@0 376 {
michael@0 377 if (certOrEncCert->choice != cmmfCertificate ||
michael@0 378 certOrEncCert->cert.certificate == NULL) {
michael@0 379 return NULL;
michael@0 380 }
michael@0 381 return CERT_NewTempCertificate(certdb,
michael@0 382 &certOrEncCert->cert.certificate->derCert,
michael@0 383 NULL, PR_FALSE, PR_TRUE);
michael@0 384 }
michael@0 385
michael@0 386 SECStatus
michael@0 387 cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo,
michael@0 388 PLArenaPool *poolp,
michael@0 389 CMMFPKIStatus inStatus)
michael@0 390 {
michael@0 391 SECItem *dummy;
michael@0 392
michael@0 393 if (inStatus <cmmfGranted || inStatus >= cmmfNumPKIStatus) {
michael@0 394 return SECFailure;
michael@0 395 }
michael@0 396
michael@0 397 dummy = SEC_ASN1EncodeInteger(poolp, &statusInfo->status, inStatus);
michael@0 398 PORT_Assert(dummy == &statusInfo->status);
michael@0 399 if (dummy != &statusInfo->status) {
michael@0 400 SECITEM_FreeItem(dummy, PR_TRUE);
michael@0 401 return SECFailure;
michael@0 402 }
michael@0 403 return SECSuccess;
michael@0 404 }
michael@0 405
michael@0 406

mercurial