diff options
Diffstat (limited to 'security/nss/lib/crmf/cmmfresp.c')
-rw-r--r-- | security/nss/lib/crmf/cmmfresp.c | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/security/nss/lib/crmf/cmmfresp.c b/security/nss/lib/crmf/cmmfresp.c new file mode 100644 index 000000000..c4b59b8e9 --- /dev/null +++ b/security/nss/lib/crmf/cmmfresp.c @@ -0,0 +1,280 @@ +/* -*- 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); +} |