123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317 |
- /* -*- 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 implement the functions related to key recovery in
- * CMMF
- */
- #include "cmmf.h"
- #include "cmmfi.h"
- #include "secitem.h"
- #include "keyhi.h"
- CMMFKeyRecRepContent *
- CMMF_CreateKeyRecRepContent(void)
- {
- PLArenaPool *poolp;
- CMMFKeyRecRepContent *keyRecContent;
- poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
- if (poolp == NULL) {
- return NULL;
- }
- keyRecContent = PORT_ArenaZNew(poolp, CMMFKeyRecRepContent);
- if (keyRecContent == NULL) {
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
- }
- keyRecContent->poolp = poolp;
- return keyRecContent;
- }
- SECStatus
- CMMF_DestroyKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep)
- {
- PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep != NULL && inKeyRecRep->poolp != NULL) {
- int i;
- if (!inKeyRecRep->isDecoded && inKeyRecRep->newSigCert != NULL) {
- CERT_DestroyCertificate(inKeyRecRep->newSigCert);
- }
- if (inKeyRecRep->caCerts != NULL) {
- for (i = 0; inKeyRecRep->caCerts[i] != NULL; i++) {
- CERT_DestroyCertificate(inKeyRecRep->caCerts[i]);
- }
- }
- if (inKeyRecRep->keyPairHist != NULL) {
- for (i = 0; inKeyRecRep->keyPairHist[i] != NULL; i++) {
- if (inKeyRecRep->keyPairHist[i]->certOrEncCert.choice ==
- cmmfCertificate) {
- CERT_DestroyCertificate(inKeyRecRep->keyPairHist[i]->certOrEncCert.cert.certificate);
- }
- }
- }
- PORT_FreeArena(inKeyRecRep->poolp, PR_TRUE);
- }
- return SECSuccess;
- }
- SECStatus
- CMMF_KeyRecRepContentSetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep,
- CMMFPKIStatus inPKIStatus)
- {
- PORT_Assert(inKeyRecRep != NULL && inPKIStatus >= cmmfGranted &&
- inPKIStatus < cmmfNumPKIStatus);
- if (inKeyRecRep == NULL) {
- return SECFailure;
- }
- return cmmf_PKIStatusInfoSetStatus(&inKeyRecRep->status,
- inKeyRecRep->poolp,
- inPKIStatus);
- }
- SECStatus
- CMMF_KeyRecRepContentSetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertificate *inNewSignCert)
- {
- PORT_Assert(inKeyRecRep != NULL && inNewSignCert != NULL);
- if (inKeyRecRep == NULL || inNewSignCert == NULL) {
- return SECFailure;
- }
- if (!inKeyRecRep->isDecoded && inKeyRecRep->newSigCert) {
- CERT_DestroyCertificate(inKeyRecRep->newSigCert);
- }
- inKeyRecRep->isDecoded = PR_FALSE;
- inKeyRecRep->newSigCert = CERT_DupCertificate(inNewSignCert);
- return (inKeyRecRep->newSigCert == NULL) ? SECFailure : SECSuccess;
- }
- SECStatus
- CMMF_KeyRecRepContentSetCACerts(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertList *inCACerts)
- {
- SECStatus rv;
- void *mark;
- PORT_Assert(inKeyRecRep != NULL && inCACerts != NULL);
- if (inKeyRecRep == NULL || inCACerts == NULL) {
- return SECFailure;
- }
- mark = PORT_ArenaMark(inKeyRecRep->poolp);
- rv = cmmf_ExtractCertsFromList(inCACerts, inKeyRecRep->poolp,
- &inKeyRecRep->caCerts);
- if (rv != SECSuccess) {
- PORT_ArenaRelease(inKeyRecRep->poolp, mark);
- } else {
- PORT_ArenaUnmark(inKeyRecRep->poolp, mark);
- }
- return rv;
- }
- SECStatus
- CMMF_KeyRecRepContentSetCertifiedKeyPair(CMMFKeyRecRepContent *inKeyRecRep,
- CERTCertificate *inCert,
- SECKEYPrivateKey *inPrivKey,
- SECKEYPublicKey *inPubKey)
- {
- CMMFCertifiedKeyPair *keyPair;
- CRMFEncryptedValue *dummy;
- PLArenaPool *poolp;
- void *mark;
- SECStatus rv;
- PORT_Assert(inKeyRecRep != NULL &&
- inCert != NULL &&
- inPrivKey != NULL &&
- inPubKey != NULL);
- if (inKeyRecRep == NULL ||
- inCert == NULL ||
- inPrivKey == NULL ||
- inPubKey == NULL) {
- return SECFailure;
- }
- poolp = inKeyRecRep->poolp;
- mark = PORT_ArenaMark(poolp);
- if (inKeyRecRep->keyPairHist == NULL) {
- inKeyRecRep->keyPairHist = PORT_ArenaNewArray(poolp,
- CMMFCertifiedKeyPair *,
- (CMMF_MAX_KEY_PAIRS + 1));
- if (inKeyRecRep->keyPairHist == NULL) {
- goto loser;
- }
- inKeyRecRep->allocKeyPairs = CMMF_MAX_KEY_PAIRS;
- inKeyRecRep->numKeyPairs = 0;
- }
- if (inKeyRecRep->allocKeyPairs == inKeyRecRep->numKeyPairs) {
- goto loser;
- }
- keyPair = PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair);
- if (keyPair == NULL) {
- goto loser;
- }
- rv = cmmf_CertOrEncCertSetCertificate(&keyPair->certOrEncCert,
- poolp, inCert);
- if (rv != SECSuccess) {
- goto loser;
- }
- keyPair->privateKey = PORT_ArenaZNew(poolp, CRMFEncryptedValue);
- if (keyPair->privateKey == NULL) {
- goto loser;
- }
- dummy = crmf_create_encrypted_value_wrapped_privkey(inPrivKey, inPubKey,
- keyPair->privateKey);
- PORT_Assert(dummy == keyPair->privateKey);
- if (dummy != keyPair->privateKey) {
- crmf_destroy_encrypted_value(dummy, PR_TRUE);
- goto loser;
- }
- inKeyRecRep->keyPairHist[inKeyRecRep->numKeyPairs] = keyPair;
- inKeyRecRep->numKeyPairs++;
- inKeyRecRep->keyPairHist[inKeyRecRep->numKeyPairs] = NULL;
- PORT_ArenaUnmark(poolp, mark);
- return SECSuccess;
- loser:
- PORT_ArenaRelease(poolp, mark);
- return SECFailure;
- }
- CMMFPKIStatus
- CMMF_KeyRecRepContentGetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep)
- {
- PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep == NULL) {
- return cmmfNoPKIStatus;
- }
- return cmmf_PKIStatusInfoGetStatus(&inKeyRecRep->status);
- }
- CERTCertificate *
- CMMF_KeyRecRepContentGetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep)
- {
- PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep == NULL ||
- inKeyRecRep->newSigCert == NULL) {
- return NULL;
- }
- /* newSigCert may not be a real certificate, it may be a hand decoded
- * cert structure. This code makes sure we hand off a real, fully formed
- * CERTCertificate to the caller. TODO: This should move into the decode
- * portion so that we never wind up with a half formed CERTCertificate
- * here. In this case the call would be to CERT_DupCertificate.
- */
- return CERT_NewTempCertificate(CERT_GetDefaultCertDB(),
- &inKeyRecRep->newSigCert->signatureWrap.data,
- NULL, PR_FALSE, PR_TRUE);
- }
- CERTCertList *
- CMMF_KeyRecRepContentGetCACerts(CMMFKeyRecRepContent *inKeyRecRep)
- {
- PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep == NULL || inKeyRecRep->caCerts == NULL) {
- return NULL;
- }
- return cmmf_MakeCertList(inKeyRecRep->caCerts);
- }
- int
- CMMF_KeyRecRepContentGetNumKeyPairs(CMMFKeyRecRepContent *inKeyRecRep)
- {
- PORT_Assert(inKeyRecRep != NULL);
- return (inKeyRecRep == NULL) ? 0 : inKeyRecRep->numKeyPairs;
- }
- PRBool
- cmmf_KeyRecRepContentIsValidIndex(CMMFKeyRecRepContent *inKeyRecRep,
- int inIndex)
- {
- int numKeyPairs = CMMF_KeyRecRepContentGetNumKeyPairs(inKeyRecRep);
- return (PRBool)(inIndex >= 0 && inIndex < numKeyPairs);
- }
- CMMFCertifiedKeyPair *
- CMMF_KeyRecRepContentGetCertKeyAtIndex(CMMFKeyRecRepContent *inKeyRecRep,
- int inIndex)
- {
- CMMFCertifiedKeyPair *newKeyPair;
- SECStatus rv;
- PORT_Assert(inKeyRecRep != NULL &&
- cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex));
- if (inKeyRecRep == NULL ||
- !cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex)) {
- return NULL;
- }
- newKeyPair = PORT_ZNew(CMMFCertifiedKeyPair);
- if (newKeyPair == NULL) {
- return NULL;
- }
- rv = cmmf_CopyCertifiedKeyPair(NULL, newKeyPair,
- inKeyRecRep->keyPairHist[inIndex]);
- if (rv != SECSuccess) {
- CMMF_DestroyCertifiedKeyPair(newKeyPair);
- newKeyPair = NULL;
- }
- return newKeyPair;
- }
- SECStatus
- CMMF_CertifiedKeyPairUnwrapPrivKey(CMMFCertifiedKeyPair *inKeyPair,
- SECKEYPrivateKey *inPrivKey,
- SECItem *inNickName,
- PK11SlotInfo *inSlot,
- CERTCertDBHandle *inCertdb,
- SECKEYPrivateKey **destPrivKey,
- void *wincx)
- {
- CERTCertificate *cert;
- SECItem keyUsageValue = { siBuffer, NULL, 0 };
- unsigned char keyUsage = 0x0;
- SECKEYPublicKey *pubKey;
- SECStatus rv;
- PORT_Assert(inKeyPair != NULL &&
- inPrivKey != NULL && inCertdb != NULL);
- if (inKeyPair == NULL ||
- inPrivKey == NULL ||
- inKeyPair->privateKey == NULL ||
- inCertdb == NULL) {
- return SECFailure;
- }
- cert = CMMF_CertifiedKeyPairGetCertificate(inKeyPair, inCertdb);
- CERT_FindKeyUsageExtension(cert, &keyUsageValue);
- if (keyUsageValue.data != NULL) {
- keyUsage = keyUsageValue.data[3];
- PORT_Free(keyUsageValue.data);
- }
- pubKey = CERT_ExtractPublicKey(cert);
- rv = crmf_encrypted_value_unwrap_priv_key(NULL, inKeyPair->privateKey,
- inPrivKey, pubKey,
- inNickName, inSlot, keyUsage,
- destPrivKey, wincx);
- SECKEY_DestroyPublicKey(pubKey);
- CERT_DestroyCertificate(cert);
- return rv;
- }
- PRBool
- CMMF_KeyRecRepContentHasCACerts(CMMFKeyRecRepContent *inKeyRecRep)
- {
- PORT_Assert(inKeyRecRep != NULL);
- if (inKeyRecRep == NULL) {
- return PR_FALSE;
- }
- return (PRBool)(inKeyRecRep->caCerts != NULL &&
- inKeyRecRep->caCerts[0] != NULL);
- }
|