1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/crmf/respcmn.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,406 @@ 1.4 +/* -*- Mode: C; tab-width: 8 -*-*/ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "cmmf.h" 1.10 +#include "cmmfi.h" 1.11 +#include "secitem.h" 1.12 +#include "secder.h" 1.13 + 1.14 +SECStatus 1.15 +cmmf_DestroyPKIStatusInfo (CMMFPKIStatusInfo *info, PRBool freeit) 1.16 +{ 1.17 + if (info->status.data != NULL) { 1.18 + PORT_Free(info->status.data); 1.19 + info->status.data = NULL; 1.20 + } 1.21 + if (info->statusString.data != NULL) { 1.22 + PORT_Free(info->statusString.data); 1.23 + info->statusString.data = NULL; 1.24 + } 1.25 + if (info->failInfo.data != NULL) { 1.26 + PORT_Free(info->failInfo.data); 1.27 + info->failInfo.data = NULL; 1.28 + } 1.29 + if (freeit) { 1.30 + PORT_Free(info); 1.31 + } 1.32 + return SECSuccess; 1.33 +} 1.34 + 1.35 +SECStatus 1.36 +CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp) 1.37 +{ 1.38 + PORT_Assert(inCertResp != NULL); 1.39 + if (inCertResp != NULL) { 1.40 + if (inCertResp->certReqId.data != NULL) { 1.41 + PORT_Free(inCertResp->certReqId.data); 1.42 + } 1.43 + cmmf_DestroyPKIStatusInfo(&inCertResp->status, PR_FALSE); 1.44 + if (inCertResp->certifiedKeyPair != NULL) { 1.45 + CMMF_DestroyCertifiedKeyPair(inCertResp->certifiedKeyPair); 1.46 + } 1.47 + PORT_Free(inCertResp); 1.48 + } 1.49 + return SECSuccess; 1.50 +} 1.51 + 1.52 +SECStatus 1.53 +CMMF_DestroyCertRepContent(CMMFCertRepContent *inCertRepContent) 1.54 +{ 1.55 + PORT_Assert(inCertRepContent != NULL); 1.56 + if (inCertRepContent != NULL) { 1.57 + CMMFCertResponse **pResponse = inCertRepContent->response; 1.58 + if (pResponse != NULL) { 1.59 + for (; *pResponse != NULL; pResponse++) { 1.60 + CMMFCertifiedKeyPair *certKeyPair = (*pResponse)->certifiedKeyPair; 1.61 + /* XXX Why not call CMMF_DestroyCertifiedKeyPair or 1.62 + ** XXX cmmf_DestroyCertOrEncCert ? 1.63 + */ 1.64 + if (certKeyPair != NULL && 1.65 + certKeyPair->certOrEncCert.choice == cmmfCertificate && 1.66 + certKeyPair->certOrEncCert.cert.certificate != NULL) { 1.67 + CERT_DestroyCertificate 1.68 + (certKeyPair->certOrEncCert.cert.certificate); 1.69 + certKeyPair->certOrEncCert.cert.certificate = NULL; 1.70 + } 1.71 + } 1.72 + } 1.73 + if (inCertRepContent->caPubs) { 1.74 + CERTCertificate **caPubs = inCertRepContent->caPubs; 1.75 + for (; *caPubs; ++caPubs) { 1.76 + CERT_DestroyCertificate(*caPubs); 1.77 + *caPubs = NULL; 1.78 + } 1.79 + } 1.80 + if (inCertRepContent->poolp != NULL) { 1.81 + PORT_FreeArena(inCertRepContent->poolp, PR_TRUE); 1.82 + } 1.83 + } 1.84 + return SECSuccess; 1.85 +} 1.86 + 1.87 +SECStatus 1.88 +CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont) 1.89 +{ 1.90 + PORT_Assert(inDecKeyCont != NULL); 1.91 + if (inDecKeyCont != NULL && inDecKeyCont->poolp) { 1.92 + PORT_FreeArena(inDecKeyCont->poolp, PR_FALSE); 1.93 + } 1.94 + return SECSuccess; 1.95 +} 1.96 + 1.97 +SECStatus 1.98 +crmf_create_prtime(SECItem *src, PRTime **dest) 1.99 +{ 1.100 + *dest = PORT_ZNew(PRTime); 1.101 + return DER_DecodeTimeChoice(*dest, src); 1.102 +} 1.103 + 1.104 +CRMFCertExtension* 1.105 +crmf_copy_cert_extension(PLArenaPool *poolp, CRMFCertExtension *inExtension) 1.106 +{ 1.107 + PRBool isCritical; 1.108 + SECOidTag id; 1.109 + SECItem *data; 1.110 + CRMFCertExtension *newExt; 1.111 + 1.112 + PORT_Assert(inExtension != NULL); 1.113 + if (inExtension == NULL) { 1.114 + return NULL; 1.115 + } 1.116 + id = CRMF_CertExtensionGetOidTag(inExtension); 1.117 + isCritical = CRMF_CertExtensionGetIsCritical(inExtension); 1.118 + data = CRMF_CertExtensionGetValue(inExtension); 1.119 + newExt = crmf_create_cert_extension(poolp, id, 1.120 + isCritical, 1.121 + data); 1.122 + SECITEM_FreeItem(data, PR_TRUE); 1.123 + return newExt; 1.124 +} 1.125 + 1.126 +static SECItem* 1.127 +cmmf_encode_certificate(CERTCertificate *inCert) 1.128 +{ 1.129 + return SEC_ASN1EncodeItem(NULL, NULL, inCert, 1.130 + SEC_ASN1_GET(SEC_SignedCertificateTemplate)); 1.131 +} 1.132 + 1.133 +CERTCertList* 1.134 +cmmf_MakeCertList(CERTCertificate **inCerts) 1.135 +{ 1.136 + CERTCertList *certList; 1.137 + CERTCertificate *currCert; 1.138 + SECItem *derCert, *freeCert = NULL; 1.139 + SECStatus rv; 1.140 + int i; 1.141 + 1.142 + certList = CERT_NewCertList(); 1.143 + if (certList == NULL) { 1.144 + return NULL; 1.145 + } 1.146 + for (i=0; inCerts[i] != NULL; i++) { 1.147 + derCert = &inCerts[i]->derCert; 1.148 + if (derCert->data == NULL) { 1.149 + derCert = freeCert = cmmf_encode_certificate(inCerts[i]); 1.150 + } 1.151 + currCert=CERT_NewTempCertificate(CERT_GetDefaultCertDB(), 1.152 + derCert, NULL, PR_FALSE, PR_TRUE); 1.153 + if (freeCert != NULL) { 1.154 + SECITEM_FreeItem(freeCert, PR_TRUE); 1.155 + freeCert = NULL; 1.156 + } 1.157 + if (currCert == NULL) { 1.158 + goto loser; 1.159 + } 1.160 + rv = CERT_AddCertToListTail(certList, currCert); 1.161 + if (rv != SECSuccess) { 1.162 + goto loser; 1.163 + } 1.164 + } 1.165 + return certList; 1.166 + loser: 1.167 + CERT_DestroyCertList(certList); 1.168 + return NULL; 1.169 +} 1.170 + 1.171 +CMMFPKIStatus 1.172 +cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus) 1.173 +{ 1.174 + long derVal; 1.175 + 1.176 + derVal = DER_GetInteger(&inStatus->status); 1.177 + if (derVal == -1 || derVal < cmmfGranted || derVal >= cmmfNumPKIStatus) { 1.178 + return cmmfNoPKIStatus; 1.179 + } 1.180 + return (CMMFPKIStatus)derVal; 1.181 +} 1.182 + 1.183 +int 1.184 +CMMF_CertRepContentGetNumResponses(CMMFCertRepContent *inCertRepContent) 1.185 +{ 1.186 + int numResponses = 0; 1.187 + PORT_Assert (inCertRepContent != NULL); 1.188 + if (inCertRepContent != NULL && inCertRepContent->response != NULL) { 1.189 + while (inCertRepContent->response[numResponses] != NULL) { 1.190 + numResponses++; 1.191 + } 1.192 + } 1.193 + return numResponses; 1.194 +} 1.195 + 1.196 + 1.197 +SECStatus 1.198 +cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit) 1.199 +{ 1.200 + switch (certOrEncCert->choice) { 1.201 + case cmmfCertificate: 1.202 + CERT_DestroyCertificate(certOrEncCert->cert.certificate); 1.203 + certOrEncCert->cert.certificate = NULL; 1.204 + break; 1.205 + case cmmfEncryptedCert: 1.206 + crmf_destroy_encrypted_value(certOrEncCert->cert.encryptedCert, 1.207 + PR_TRUE); 1.208 + certOrEncCert->cert.encryptedCert = NULL; 1.209 + break; 1.210 + default: 1.211 + break; 1.212 + } 1.213 + if (freeit) { 1.214 + PORT_Free(certOrEncCert); 1.215 + } 1.216 + return SECSuccess; 1.217 +} 1.218 + 1.219 +SECStatus 1.220 +cmmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src) 1.221 +{ 1.222 + SECStatus rv; 1.223 + 1.224 + if (src->data != NULL) { 1.225 + rv = SECITEM_CopyItem(poolp, dest, src); 1.226 + } else { 1.227 + dest->data = NULL; 1.228 + dest->len = 0; 1.229 + rv = SECSuccess; 1.230 + } 1.231 + return rv; 1.232 +} 1.233 + 1.234 +SECStatus 1.235 +CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair) 1.236 +{ 1.237 + PORT_Assert(inCertKeyPair != NULL); 1.238 + if (inCertKeyPair != NULL) { 1.239 + cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE); 1.240 + if (inCertKeyPair->privateKey) { 1.241 + crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE); 1.242 + } 1.243 + if (inCertKeyPair->derPublicationInfo.data) { 1.244 + PORT_Free(inCertKeyPair->derPublicationInfo.data); 1.245 + } 1.246 + PORT_Free(inCertKeyPair); 1.247 + } 1.248 + return SECSuccess; 1.249 +} 1.250 + 1.251 +SECStatus 1.252 +cmmf_CopyCertResponse(PLArenaPool *poolp, 1.253 + CMMFCertResponse *dest, 1.254 + CMMFCertResponse *src) 1.255 +{ 1.256 + SECStatus rv; 1.257 + 1.258 + if (src->certReqId.data != NULL) { 1.259 + rv = SECITEM_CopyItem(poolp, &dest->certReqId, &src->certReqId); 1.260 + if (rv != SECSuccess) { 1.261 + return rv; 1.262 + } 1.263 + } 1.264 + rv = cmmf_CopyPKIStatusInfo(poolp, &dest->status, &src->status); 1.265 + if (rv != SECSuccess) { 1.266 + return rv; 1.267 + } 1.268 + if (src->certifiedKeyPair != NULL) { 1.269 + CMMFCertifiedKeyPair *destKeyPair; 1.270 + 1.271 + destKeyPair = (poolp == NULL) ? PORT_ZNew(CMMFCertifiedKeyPair) : 1.272 + PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair); 1.273 + if (!destKeyPair) { 1.274 + return SECFailure; 1.275 + } 1.276 + rv = cmmf_CopyCertifiedKeyPair(poolp, destKeyPair, 1.277 + src->certifiedKeyPair); 1.278 + if (rv != SECSuccess) { 1.279 + if (!poolp) { 1.280 + CMMF_DestroyCertifiedKeyPair(destKeyPair); 1.281 + } 1.282 + return rv; 1.283 + } 1.284 + dest->certifiedKeyPair = destKeyPair; 1.285 + } 1.286 + return SECSuccess; 1.287 +} 1.288 + 1.289 +static SECStatus 1.290 +cmmf_CopyCertOrEncCert(PLArenaPool *poolp, CMMFCertOrEncCert *dest, 1.291 + CMMFCertOrEncCert *src) 1.292 +{ 1.293 + SECStatus rv = SECSuccess; 1.294 + CRMFEncryptedValue *encVal; 1.295 + 1.296 + dest->choice = src->choice; 1.297 + rv = cmmf_copy_secitem(poolp, &dest->derValue, &src->derValue); 1.298 + switch (src->choice) { 1.299 + case cmmfCertificate: 1.300 + dest->cert.certificate = CERT_DupCertificate(src->cert.certificate); 1.301 + break; 1.302 + case cmmfEncryptedCert: 1.303 + encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : 1.304 + PORT_ArenaZNew(poolp, CRMFEncryptedValue); 1.305 + if (encVal == NULL) { 1.306 + return SECFailure; 1.307 + } 1.308 + rv = crmf_copy_encryptedvalue(poolp, src->cert.encryptedCert, encVal); 1.309 + if (rv != SECSuccess) { 1.310 + if (!poolp) { 1.311 + crmf_destroy_encrypted_value(encVal, PR_TRUE); 1.312 + } 1.313 + return rv; 1.314 + } 1.315 + dest->cert.encryptedCert = encVal; 1.316 + break; 1.317 + default: 1.318 + rv = SECFailure; 1.319 + } 1.320 + return rv; 1.321 +} 1.322 + 1.323 +SECStatus 1.324 +cmmf_CopyCertifiedKeyPair(PLArenaPool *poolp, CMMFCertifiedKeyPair *dest, 1.325 + CMMFCertifiedKeyPair *src) 1.326 +{ 1.327 + SECStatus rv; 1.328 + 1.329 + rv = cmmf_CopyCertOrEncCert(poolp, &dest->certOrEncCert, 1.330 + &src->certOrEncCert); 1.331 + if (rv != SECSuccess) { 1.332 + return rv; 1.333 + } 1.334 + 1.335 + if (src->privateKey != NULL) { 1.336 + CRMFEncryptedValue *encVal; 1.337 + 1.338 + encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : 1.339 + PORT_ArenaZNew(poolp, CRMFEncryptedValue); 1.340 + if (encVal == NULL) { 1.341 + return SECFailure; 1.342 + } 1.343 + rv = crmf_copy_encryptedvalue(poolp, src->privateKey, 1.344 + encVal); 1.345 + if (rv != SECSuccess) { 1.346 + if (!poolp) { 1.347 + crmf_destroy_encrypted_value(encVal, PR_TRUE); 1.348 + } 1.349 + return rv; 1.350 + } 1.351 + dest->privateKey = encVal; 1.352 + } 1.353 + rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo, 1.354 + &src->derPublicationInfo); 1.355 + return rv; 1.356 +} 1.357 + 1.358 +SECStatus 1.359 +cmmf_CopyPKIStatusInfo(PLArenaPool *poolp, CMMFPKIStatusInfo *dest, 1.360 + CMMFPKIStatusInfo *src) 1.361 +{ 1.362 + SECStatus rv; 1.363 + 1.364 + rv = cmmf_copy_secitem (poolp, &dest->status, &src->status); 1.365 + if (rv != SECSuccess) { 1.366 + return rv; 1.367 + } 1.368 + rv = cmmf_copy_secitem (poolp, &dest->statusString, &src->statusString); 1.369 + if (rv != SECSuccess) { 1.370 + return rv; 1.371 + } 1.372 + rv = cmmf_copy_secitem (poolp, &dest->failInfo, &src->failInfo); 1.373 + return rv; 1.374 +} 1.375 + 1.376 +CERTCertificate* 1.377 +cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert, 1.378 + CERTCertDBHandle *certdb) 1.379 +{ 1.380 + if (certOrEncCert->choice != cmmfCertificate || 1.381 + certOrEncCert->cert.certificate == NULL) { 1.382 + return NULL; 1.383 + } 1.384 + return CERT_NewTempCertificate(certdb, 1.385 + &certOrEncCert->cert.certificate->derCert, 1.386 + NULL, PR_FALSE, PR_TRUE); 1.387 +} 1.388 + 1.389 +SECStatus 1.390 +cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo, 1.391 + PLArenaPool *poolp, 1.392 + CMMFPKIStatus inStatus) 1.393 +{ 1.394 + SECItem *dummy; 1.395 + 1.396 + if (inStatus <cmmfGranted || inStatus >= cmmfNumPKIStatus) { 1.397 + return SECFailure; 1.398 + } 1.399 + 1.400 + dummy = SEC_ASN1EncodeInteger(poolp, &statusInfo->status, inStatus); 1.401 + PORT_Assert(dummy == &statusInfo->status); 1.402 + if (dummy != &statusInfo->status) { 1.403 + SECITEM_FreeItem(dummy, PR_TRUE); 1.404 + return SECFailure; 1.405 + } 1.406 + return SECSuccess; 1.407 +} 1.408 + 1.409 +