michael@0: /* -*- Mode: C; tab-width: 8 -*-*/ 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: #include "cmmf.h" michael@0: #include "cmmfi.h" michael@0: #include "secitem.h" michael@0: #include "secder.h" michael@0: michael@0: SECStatus michael@0: cmmf_DestroyPKIStatusInfo (CMMFPKIStatusInfo *info, PRBool freeit) michael@0: { michael@0: if (info->status.data != NULL) { michael@0: PORT_Free(info->status.data); michael@0: info->status.data = NULL; michael@0: } michael@0: if (info->statusString.data != NULL) { michael@0: PORT_Free(info->statusString.data); michael@0: info->statusString.data = NULL; michael@0: } michael@0: if (info->failInfo.data != NULL) { michael@0: PORT_Free(info->failInfo.data); michael@0: info->failInfo.data = NULL; michael@0: } michael@0: if (freeit) { michael@0: PORT_Free(info); michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: CMMF_DestroyCertResponse(CMMFCertResponse *inCertResp) michael@0: { michael@0: PORT_Assert(inCertResp != NULL); michael@0: if (inCertResp != NULL) { michael@0: if (inCertResp->certReqId.data != NULL) { michael@0: PORT_Free(inCertResp->certReqId.data); michael@0: } michael@0: cmmf_DestroyPKIStatusInfo(&inCertResp->status, PR_FALSE); michael@0: if (inCertResp->certifiedKeyPair != NULL) { michael@0: CMMF_DestroyCertifiedKeyPair(inCertResp->certifiedKeyPair); michael@0: } michael@0: PORT_Free(inCertResp); michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: CMMF_DestroyCertRepContent(CMMFCertRepContent *inCertRepContent) michael@0: { michael@0: PORT_Assert(inCertRepContent != NULL); michael@0: if (inCertRepContent != NULL) { michael@0: CMMFCertResponse **pResponse = inCertRepContent->response; michael@0: if (pResponse != NULL) { michael@0: for (; *pResponse != NULL; pResponse++) { michael@0: CMMFCertifiedKeyPair *certKeyPair = (*pResponse)->certifiedKeyPair; michael@0: /* XXX Why not call CMMF_DestroyCertifiedKeyPair or michael@0: ** XXX cmmf_DestroyCertOrEncCert ? michael@0: */ michael@0: if (certKeyPair != NULL && michael@0: certKeyPair->certOrEncCert.choice == cmmfCertificate && michael@0: certKeyPair->certOrEncCert.cert.certificate != NULL) { michael@0: CERT_DestroyCertificate michael@0: (certKeyPair->certOrEncCert.cert.certificate); michael@0: certKeyPair->certOrEncCert.cert.certificate = NULL; michael@0: } michael@0: } michael@0: } michael@0: if (inCertRepContent->caPubs) { michael@0: CERTCertificate **caPubs = inCertRepContent->caPubs; michael@0: for (; *caPubs; ++caPubs) { michael@0: CERT_DestroyCertificate(*caPubs); michael@0: *caPubs = NULL; michael@0: } michael@0: } michael@0: if (inCertRepContent->poolp != NULL) { michael@0: PORT_FreeArena(inCertRepContent->poolp, PR_TRUE); michael@0: } michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: CMMF_DestroyPOPODecKeyChallContent(CMMFPOPODecKeyChallContent *inDecKeyCont) michael@0: { michael@0: PORT_Assert(inDecKeyCont != NULL); michael@0: if (inDecKeyCont != NULL && inDecKeyCont->poolp) { michael@0: PORT_FreeArena(inDecKeyCont->poolp, PR_FALSE); michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: crmf_create_prtime(SECItem *src, PRTime **dest) michael@0: { michael@0: *dest = PORT_ZNew(PRTime); michael@0: return DER_DecodeTimeChoice(*dest, src); michael@0: } michael@0: michael@0: CRMFCertExtension* michael@0: crmf_copy_cert_extension(PLArenaPool *poolp, CRMFCertExtension *inExtension) michael@0: { michael@0: PRBool isCritical; michael@0: SECOidTag id; michael@0: SECItem *data; michael@0: CRMFCertExtension *newExt; michael@0: michael@0: PORT_Assert(inExtension != NULL); michael@0: if (inExtension == NULL) { michael@0: return NULL; michael@0: } michael@0: id = CRMF_CertExtensionGetOidTag(inExtension); michael@0: isCritical = CRMF_CertExtensionGetIsCritical(inExtension); michael@0: data = CRMF_CertExtensionGetValue(inExtension); michael@0: newExt = crmf_create_cert_extension(poolp, id, michael@0: isCritical, michael@0: data); michael@0: SECITEM_FreeItem(data, PR_TRUE); michael@0: return newExt; michael@0: } michael@0: michael@0: static SECItem* michael@0: cmmf_encode_certificate(CERTCertificate *inCert) michael@0: { michael@0: return SEC_ASN1EncodeItem(NULL, NULL, inCert, michael@0: SEC_ASN1_GET(SEC_SignedCertificateTemplate)); michael@0: } michael@0: michael@0: CERTCertList* michael@0: cmmf_MakeCertList(CERTCertificate **inCerts) michael@0: { michael@0: CERTCertList *certList; michael@0: CERTCertificate *currCert; michael@0: SECItem *derCert, *freeCert = NULL; michael@0: SECStatus rv; michael@0: int i; michael@0: michael@0: certList = CERT_NewCertList(); michael@0: if (certList == NULL) { michael@0: return NULL; michael@0: } michael@0: for (i=0; inCerts[i] != NULL; i++) { michael@0: derCert = &inCerts[i]->derCert; michael@0: if (derCert->data == NULL) { michael@0: derCert = freeCert = cmmf_encode_certificate(inCerts[i]); michael@0: } michael@0: currCert=CERT_NewTempCertificate(CERT_GetDefaultCertDB(), michael@0: derCert, NULL, PR_FALSE, PR_TRUE); michael@0: if (freeCert != NULL) { michael@0: SECITEM_FreeItem(freeCert, PR_TRUE); michael@0: freeCert = NULL; michael@0: } michael@0: if (currCert == NULL) { michael@0: goto loser; michael@0: } michael@0: rv = CERT_AddCertToListTail(certList, currCert); michael@0: if (rv != SECSuccess) { michael@0: goto loser; michael@0: } michael@0: } michael@0: return certList; michael@0: loser: michael@0: CERT_DestroyCertList(certList); michael@0: return NULL; michael@0: } michael@0: michael@0: CMMFPKIStatus michael@0: cmmf_PKIStatusInfoGetStatus(CMMFPKIStatusInfo *inStatus) michael@0: { michael@0: long derVal; michael@0: michael@0: derVal = DER_GetInteger(&inStatus->status); michael@0: if (derVal == -1 || derVal < cmmfGranted || derVal >= cmmfNumPKIStatus) { michael@0: return cmmfNoPKIStatus; michael@0: } michael@0: return (CMMFPKIStatus)derVal; michael@0: } michael@0: michael@0: int michael@0: CMMF_CertRepContentGetNumResponses(CMMFCertRepContent *inCertRepContent) michael@0: { michael@0: int numResponses = 0; michael@0: PORT_Assert (inCertRepContent != NULL); michael@0: if (inCertRepContent != NULL && inCertRepContent->response != NULL) { michael@0: while (inCertRepContent->response[numResponses] != NULL) { michael@0: numResponses++; michael@0: } michael@0: } michael@0: return numResponses; michael@0: } michael@0: michael@0: michael@0: SECStatus michael@0: cmmf_DestroyCertOrEncCert(CMMFCertOrEncCert *certOrEncCert, PRBool freeit) michael@0: { michael@0: switch (certOrEncCert->choice) { michael@0: case cmmfCertificate: michael@0: CERT_DestroyCertificate(certOrEncCert->cert.certificate); michael@0: certOrEncCert->cert.certificate = NULL; michael@0: break; michael@0: case cmmfEncryptedCert: michael@0: crmf_destroy_encrypted_value(certOrEncCert->cert.encryptedCert, michael@0: PR_TRUE); michael@0: certOrEncCert->cert.encryptedCert = NULL; michael@0: break; michael@0: default: michael@0: break; michael@0: } michael@0: if (freeit) { michael@0: PORT_Free(certOrEncCert); michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: cmmf_copy_secitem (PLArenaPool *poolp, SECItem *dest, SECItem *src) michael@0: { michael@0: SECStatus rv; michael@0: michael@0: if (src->data != NULL) { michael@0: rv = SECITEM_CopyItem(poolp, dest, src); michael@0: } else { michael@0: dest->data = NULL; michael@0: dest->len = 0; michael@0: rv = SECSuccess; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: CMMF_DestroyCertifiedKeyPair(CMMFCertifiedKeyPair *inCertKeyPair) michael@0: { michael@0: PORT_Assert(inCertKeyPair != NULL); michael@0: if (inCertKeyPair != NULL) { michael@0: cmmf_DestroyCertOrEncCert(&inCertKeyPair->certOrEncCert, PR_FALSE); michael@0: if (inCertKeyPair->privateKey) { michael@0: crmf_destroy_encrypted_value(inCertKeyPair->privateKey, PR_TRUE); michael@0: } michael@0: if (inCertKeyPair->derPublicationInfo.data) { michael@0: PORT_Free(inCertKeyPair->derPublicationInfo.data); michael@0: } michael@0: PORT_Free(inCertKeyPair); michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: SECStatus michael@0: cmmf_CopyCertResponse(PLArenaPool *poolp, michael@0: CMMFCertResponse *dest, michael@0: CMMFCertResponse *src) michael@0: { michael@0: SECStatus rv; michael@0: michael@0: if (src->certReqId.data != NULL) { michael@0: rv = SECITEM_CopyItem(poolp, &dest->certReqId, &src->certReqId); michael@0: if (rv != SECSuccess) { michael@0: return rv; michael@0: } michael@0: } michael@0: rv = cmmf_CopyPKIStatusInfo(poolp, &dest->status, &src->status); michael@0: if (rv != SECSuccess) { michael@0: return rv; michael@0: } michael@0: if (src->certifiedKeyPair != NULL) { michael@0: CMMFCertifiedKeyPair *destKeyPair; michael@0: michael@0: destKeyPair = (poolp == NULL) ? PORT_ZNew(CMMFCertifiedKeyPair) : michael@0: PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair); michael@0: if (!destKeyPair) { michael@0: return SECFailure; michael@0: } michael@0: rv = cmmf_CopyCertifiedKeyPair(poolp, destKeyPair, michael@0: src->certifiedKeyPair); michael@0: if (rv != SECSuccess) { michael@0: if (!poolp) { michael@0: CMMF_DestroyCertifiedKeyPair(destKeyPair); michael@0: } michael@0: return rv; michael@0: } michael@0: dest->certifiedKeyPair = destKeyPair; michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: static SECStatus michael@0: cmmf_CopyCertOrEncCert(PLArenaPool *poolp, CMMFCertOrEncCert *dest, michael@0: CMMFCertOrEncCert *src) michael@0: { michael@0: SECStatus rv = SECSuccess; michael@0: CRMFEncryptedValue *encVal; michael@0: michael@0: dest->choice = src->choice; michael@0: rv = cmmf_copy_secitem(poolp, &dest->derValue, &src->derValue); michael@0: switch (src->choice) { michael@0: case cmmfCertificate: michael@0: dest->cert.certificate = CERT_DupCertificate(src->cert.certificate); michael@0: break; michael@0: case cmmfEncryptedCert: michael@0: encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : michael@0: PORT_ArenaZNew(poolp, CRMFEncryptedValue); michael@0: if (encVal == NULL) { michael@0: return SECFailure; michael@0: } michael@0: rv = crmf_copy_encryptedvalue(poolp, src->cert.encryptedCert, encVal); michael@0: if (rv != SECSuccess) { michael@0: if (!poolp) { michael@0: crmf_destroy_encrypted_value(encVal, PR_TRUE); michael@0: } michael@0: return rv; michael@0: } michael@0: dest->cert.encryptedCert = encVal; michael@0: break; michael@0: default: michael@0: rv = SECFailure; michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: cmmf_CopyCertifiedKeyPair(PLArenaPool *poolp, CMMFCertifiedKeyPair *dest, michael@0: CMMFCertifiedKeyPair *src) michael@0: { michael@0: SECStatus rv; michael@0: michael@0: rv = cmmf_CopyCertOrEncCert(poolp, &dest->certOrEncCert, michael@0: &src->certOrEncCert); michael@0: if (rv != SECSuccess) { michael@0: return rv; michael@0: } michael@0: michael@0: if (src->privateKey != NULL) { michael@0: CRMFEncryptedValue *encVal; michael@0: michael@0: encVal = (poolp == NULL) ? PORT_ZNew(CRMFEncryptedValue) : michael@0: PORT_ArenaZNew(poolp, CRMFEncryptedValue); michael@0: if (encVal == NULL) { michael@0: return SECFailure; michael@0: } michael@0: rv = crmf_copy_encryptedvalue(poolp, src->privateKey, michael@0: encVal); michael@0: if (rv != SECSuccess) { michael@0: if (!poolp) { michael@0: crmf_destroy_encrypted_value(encVal, PR_TRUE); michael@0: } michael@0: return rv; michael@0: } michael@0: dest->privateKey = encVal; michael@0: } michael@0: rv = cmmf_copy_secitem(poolp, &dest->derPublicationInfo, michael@0: &src->derPublicationInfo); michael@0: return rv; michael@0: } michael@0: michael@0: SECStatus michael@0: cmmf_CopyPKIStatusInfo(PLArenaPool *poolp, CMMFPKIStatusInfo *dest, michael@0: CMMFPKIStatusInfo *src) michael@0: { michael@0: SECStatus rv; michael@0: michael@0: rv = cmmf_copy_secitem (poolp, &dest->status, &src->status); michael@0: if (rv != SECSuccess) { michael@0: return rv; michael@0: } michael@0: rv = cmmf_copy_secitem (poolp, &dest->statusString, &src->statusString); michael@0: if (rv != SECSuccess) { michael@0: return rv; michael@0: } michael@0: rv = cmmf_copy_secitem (poolp, &dest->failInfo, &src->failInfo); michael@0: return rv; michael@0: } michael@0: michael@0: CERTCertificate* michael@0: cmmf_CertOrEncCertGetCertificate(CMMFCertOrEncCert *certOrEncCert, michael@0: CERTCertDBHandle *certdb) michael@0: { michael@0: if (certOrEncCert->choice != cmmfCertificate || michael@0: certOrEncCert->cert.certificate == NULL) { michael@0: return NULL; michael@0: } michael@0: return CERT_NewTempCertificate(certdb, michael@0: &certOrEncCert->cert.certificate->derCert, michael@0: NULL, PR_FALSE, PR_TRUE); michael@0: } michael@0: michael@0: SECStatus michael@0: cmmf_PKIStatusInfoSetStatus(CMMFPKIStatusInfo *statusInfo, michael@0: PLArenaPool *poolp, michael@0: CMMFPKIStatus inStatus) michael@0: { michael@0: SECItem *dummy; michael@0: michael@0: if (inStatus = cmmfNumPKIStatus) { michael@0: return SECFailure; michael@0: } michael@0: michael@0: dummy = SEC_ASN1EncodeInteger(poolp, &statusInfo->status, inStatus); michael@0: PORT_Assert(dummy == &statusInfo->status); michael@0: if (dummy != &statusInfo->status) { michael@0: SECITEM_FreeItem(dummy, PR_TRUE); michael@0: return SECFailure; michael@0: } michael@0: return SECSuccess; michael@0: } michael@0: michael@0: