/* -*- Mode: C; tab-width: 8 -*-*/ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * This file will contain all routines dealing with creating a * CMMFCertRepContent structure through Create/Set functions. */ #include "cmmf.h" #include "cmmfi.h" #include "crmf.h" #include "crmfi.h" #include "secitem.h" #include "secder.h" CMMFCertRepContent * CMMF_CreateCertRepContent(void) { CMMFCertRepContent *retCertRep; PLArenaPool *poolp; poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); if (poolp == NULL) { goto loser; } retCertRep = PORT_ArenaZNew(poolp, CMMFCertRepContent); if (retCertRep == NULL) { goto loser; } retCertRep->poolp = poolp; return retCertRep; loser: if (poolp != NULL) { PORT_FreeArena(poolp, PR_FALSE); } return NULL; } SECStatus cmmf_CertOrEncCertSetCertificate(CMMFCertOrEncCert *certOrEncCert, PLArenaPool *poolp, CERTCertificate *inCert) { SECItem *derDest = NULL; SECStatus rv = SECFailure; if (inCert->derCert.data == NULL) { derDest = SEC_ASN1EncodeItem(NULL, NULL, inCert, CMMFCertOrEncCertCertificateTemplate); if (derDest == NULL) { goto loser; } } else { derDest = SECITEM_DupItem(&inCert->derCert); if (derDest == NULL) { goto loser; } } PORT_Assert(certOrEncCert->cert.certificate == NULL); certOrEncCert->cert.certificate = CERT_DupCertificate(inCert); certOrEncCert->choice = cmmfCertificate; if (poolp != NULL) { rv = SECITEM_CopyItem(poolp, &certOrEncCert->derValue, derDest); if (rv != SECSuccess) { goto loser; } } else { certOrEncCert->derValue = *derDest; } PORT_Free(derDest); return SECSuccess; loser: if (derDest != NULL) { SECITEM_FreeItem(derDest, PR_TRUE); } return rv; } SECStatus cmmf_ExtractCertsFromList(CERTCertList *inCertList, PLArenaPool *poolp, CERTCertificate ***certArray) { CERTCertificate **arrayLocalCopy; CERTCertListNode *node; int numNodes = 0, i; for (node = CERT_LIST_HEAD(inCertList); !CERT_LIST_END(node, inCertList); node = CERT_LIST_NEXT(node)) { numNodes++; } arrayLocalCopy = *certArray = (poolp == NULL) ? PORT_NewArray(CERTCertificate *, (numNodes + 1)) : PORT_ArenaNewArray(poolp, CERTCertificate *, (numNodes + 1)); if (arrayLocalCopy == NULL) { return SECFailure; } for (node = CERT_LIST_HEAD(inCertList), i = 0; !CERT_LIST_END(node, inCertList); node = CERT_LIST_NEXT(node), i++) { arrayLocalCopy[i] = CERT_DupCertificate(node->cert); if (arrayLocalCopy[i] == NULL) { int j; for (j = 0; j < i; j++) { CERT_DestroyCertificate(arrayLocalCopy[j]); } if (poolp == NULL) { PORT_Free(arrayLocalCopy); } *certArray = NULL; return SECFailure; } } arrayLocalCopy[numNodes] = NULL; return SECSuccess; } SECStatus CMMF_CertRepContentSetCertResponses(CMMFCertRepContent *inCertRepContent, CMMFCertResponse **inCertResponses, int inNumResponses) { PLArenaPool *poolp; CMMFCertResponse **respArr, *newResp; void *mark; SECStatus rv; int i; PORT_Assert(inCertRepContent != NULL && inCertResponses != NULL && inNumResponses > 0); if (inCertRepContent == NULL || inCertResponses == NULL || inCertRepContent->response != NULL) { return SECFailure; } poolp = inCertRepContent->poolp; mark = PORT_ArenaMark(poolp); respArr = inCertRepContent->response = PORT_ArenaZNewArray(poolp, CMMFCertResponse *, (inNumResponses + 1)); if (respArr == NULL) { goto loser; } for (i = 0; i < inNumResponses; i++) { newResp = PORT_ArenaZNew(poolp, CMMFCertResponse); if (newResp == NULL) { goto loser; } rv = cmmf_CopyCertResponse(poolp, newResp, inCertResponses[i]); if (rv != SECSuccess) { goto loser; } respArr[i] = newResp; } respArr[inNumResponses] = NULL; PORT_ArenaUnmark(poolp, mark); return SECSuccess; loser: PORT_ArenaRelease(poolp, mark); return SECFailure; } CMMFCertResponse * CMMF_CreateCertResponse(long inCertReqId) { SECItem *dummy; CMMFCertResponse *newResp; newResp = PORT_ZNew(CMMFCertResponse); if (newResp == NULL) { goto loser; } dummy = SEC_ASN1EncodeInteger(NULL, &newResp->certReqId, inCertReqId); if (dummy != &newResp->certReqId) { goto loser; } return newResp; loser: if (newResp != NULL) { CMMF_DestroyCertResponse(newResp); } return NULL; } SECStatus CMMF_CertResponseSetPKIStatusInfoStatus(CMMFCertResponse *inCertResp, CMMFPKIStatus inPKIStatus) { PORT_Assert(inCertResp != NULL && inPKIStatus >= cmmfGranted && inPKIStatus < cmmfNumPKIStatus); if (inCertResp == NULL) { return SECFailure; } return cmmf_PKIStatusInfoSetStatus(&inCertResp->status, NULL, inPKIStatus); } SECStatus CMMF_CertResponseSetCertificate(CMMFCertResponse *inCertResp, CERTCertificate *inCertificate) { CMMFCertifiedKeyPair *keyPair = NULL; SECStatus rv = SECFailure; PORT_Assert(inCertResp != NULL && inCertificate != NULL); if (inCertResp == NULL || inCertificate == NULL) { return SECFailure; } if (inCertResp->certifiedKeyPair == NULL) { keyPair = inCertResp->certifiedKeyPair = PORT_ZNew(CMMFCertifiedKeyPair); } else { keyPair = inCertResp->certifiedKeyPair; } if (keyPair == NULL) { goto loser; } rv = cmmf_CertOrEncCertSetCertificate(&keyPair->certOrEncCert, NULL, inCertificate); if (rv != SECSuccess) { goto loser; } return SECSuccess; loser: if (keyPair) { if (keyPair->certOrEncCert.derValue.data) { PORT_Free(keyPair->certOrEncCert.derValue.data); } PORT_Free(keyPair); } return rv; } SECStatus CMMF_CertRepContentSetCAPubs(CMMFCertRepContent *inCertRepContent, CERTCertList *inCAPubs) { PLArenaPool *poolp; void *mark; SECStatus rv; PORT_Assert(inCertRepContent != NULL && inCAPubs != NULL && inCertRepContent->caPubs == NULL); if (inCertRepContent == NULL || inCAPubs == NULL || inCertRepContent == NULL) { return SECFailure; } poolp = inCertRepContent->poolp; mark = PORT_ArenaMark(poolp); rv = cmmf_ExtractCertsFromList(inCAPubs, poolp, &inCertRepContent->caPubs); if (rv != SECSuccess) { PORT_ArenaRelease(poolp, mark); } else { PORT_ArenaUnmark(poolp, mark); } return rv; } CERTCertificate * CMMF_CertifiedKeyPairGetCertificate(CMMFCertifiedKeyPair *inCertKeyPair, CERTCertDBHandle *inCertdb) { PORT_Assert(inCertKeyPair != NULL); if (inCertKeyPair == NULL) { return NULL; } return cmmf_CertOrEncCertGetCertificate(&inCertKeyPair->certOrEncCert, inCertdb); }