cmmfrec.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:10k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /* -*- Mode: C; tab-width: 8 -*-*/
  2. /*
  3.  * The contents of this file are subject to the Mozilla Public
  4.  * License Version 1.1 (the "License"); you may not use this file
  5.  * except in compliance with the License. You may obtain a copy of
  6.  * the License at http://www.mozilla.org/MPL/
  7.  * 
  8.  * Software distributed under the License is distributed on an "AS
  9.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  10.  * implied. See the License for the specific language governing
  11.  * rights and limitations under the License.
  12.  * 
  13.  * The Original Code is the Netscape security libraries.
  14.  * 
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation.  Portions created by Netscape are 
  17.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  18.  * Rights Reserved.
  19.  * 
  20.  * Contributor(s):
  21.  * 
  22.  * Alternatively, the contents of this file may be used under the
  23.  * terms of the GNU General Public License Version 2 or later (the
  24.  * "GPL"), in which case the provisions of the GPL are applicable 
  25.  * instead of those above.  If you wish to allow use of your 
  26.  * version of this file only under the terms of the GPL and not to
  27.  * allow others to use your version of this file under the MPL,
  28.  * indicate your decision by deleting the provisions above and
  29.  * replace them with the notice and other provisions required by
  30.  * the GPL.  If you do not delete the provisions above, a recipient
  31.  * may use your version of this file under either the MPL or the
  32.  * GPL.
  33.  */
  34. /*
  35.  * This file will implement the functions related to key recovery in 
  36.  * CMMF
  37.  */
  38. #include "cmmf.h"
  39. #include "cmmfi.h"
  40. #include "secitem.h"
  41. #include "keyhi.h"
  42. CMMFKeyRecRepContent*
  43. CMMF_CreateKeyRecRepContent(void)
  44. {
  45.     PRArenaPool          *poolp;
  46.     CMMFKeyRecRepContent *keyRecContent;
  47.     poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
  48.     if (poolp == NULL) {
  49.         return NULL;
  50.     }
  51.     keyRecContent = PORT_ArenaZNew(poolp, CMMFKeyRecRepContent);
  52.     if (keyRecContent == NULL) {
  53.         PORT_FreeArena(poolp, PR_FALSE);
  54. return NULL;
  55.     }
  56.     keyRecContent->poolp = poolp;
  57.     return keyRecContent;
  58. }
  59. SECStatus
  60. CMMF_DestroyKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep)
  61. {
  62.     PORT_Assert(inKeyRecRep != NULL);
  63.     if (inKeyRecRep != NULL && inKeyRecRep->poolp != NULL) {
  64.         if (!inKeyRecRep->isDecoded) {
  65.     int i;
  66.     CERT_DestroyCertificate(inKeyRecRep->newSigCert);
  67.     if (inKeyRecRep->caCerts != NULL) {
  68.         for (i=0; inKeyRecRep->caCerts[i] != NULL; i++) {
  69.     CERT_DestroyCertificate(inKeyRecRep->caCerts[i]);
  70. }
  71.     }
  72.     if (inKeyRecRep->keyPairHist != NULL) {
  73.         for (i=0; inKeyRecRep->keyPairHist[i] != NULL; i++) {
  74.     if (inKeyRecRep->keyPairHist[i]->certOrEncCert.choice ==
  75. cmmfCertificate) {
  76.         CERT_DestroyCertificate(inKeyRecRep->keyPairHist[i]->
  77.        certOrEncCert.cert.certificate);
  78.     }
  79. }
  80.     }
  81. }
  82.         PORT_FreeArena(inKeyRecRep->poolp, PR_TRUE);
  83.     }
  84.     return SECSuccess;
  85. }
  86. SECStatus
  87. CMMF_KeyRecRepContentSetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep,
  88.     CMMFPKIStatus         inPKIStatus)
  89. {
  90.     PORT_Assert(inKeyRecRep != NULL && inPKIStatus >= cmmfGranted &&
  91. inPKIStatus < cmmfNumPKIStatus);
  92.     if (inKeyRecRep == NULL) {
  93.         return SECFailure;
  94.     }
  95.     
  96.     return cmmf_PKIStatusInfoSetStatus(&inKeyRecRep->status, 
  97.        inKeyRecRep->poolp,
  98.        inPKIStatus);
  99. }
  100. SECStatus
  101. CMMF_KeyRecRepContentSetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep,
  102.     CERTCertificate      *inNewSignCert)
  103. {
  104.     PORT_Assert (inKeyRecRep != NULL && inNewSignCert != NULL);
  105.     if (inKeyRecRep == NULL || inNewSignCert == NULL) {
  106.         return SECFailure;
  107.     }
  108.     inKeyRecRep->newSigCert = CERT_DupCertificate(inNewSignCert);
  109.     return (inKeyRecRep->newSigCert == NULL) ? SECFailure : SECSuccess;    
  110. }
  111. SECStatus
  112. CMMF_KeyRecRepContentSetCACerts(CMMFKeyRecRepContent *inKeyRecRep,
  113. CERTCertList         *inCACerts)
  114. {
  115.     SECStatus rv;
  116.     void *mark;
  117.     PORT_Assert (inKeyRecRep != NULL && inCACerts != NULL);
  118.     if (inKeyRecRep == NULL || inCACerts == NULL) {
  119.         return SECFailure;
  120.     }
  121.     mark = PORT_ArenaMark(inKeyRecRep->poolp);
  122.     rv = cmmf_ExtractCertsFromList(inCACerts, inKeyRecRep->poolp,
  123.    &inKeyRecRep->caCerts);
  124.     if (rv != SECSuccess) {
  125.         PORT_ArenaRelease(inKeyRecRep->poolp, mark);
  126.     } else {
  127.         PORT_ArenaUnmark(inKeyRecRep->poolp, mark);
  128.     }
  129.     return rv;
  130. }
  131. SECStatus
  132. CMMF_KeyRecRepContentSetCertifiedKeyPair(CMMFKeyRecRepContent *inKeyRecRep,
  133.  CERTCertificate      *inCert,
  134.  SECKEYPrivateKey     *inPrivKey,
  135.  SECKEYPublicKey      *inPubKey)
  136. {
  137.     CMMFCertifiedKeyPair *keyPair;
  138.     CRMFEncryptedValue   *dummy;
  139.     PRArenaPool          *poolp;
  140.     void                 *mark;
  141.     SECStatus             rv;
  142.     PORT_Assert (inKeyRecRep != NULL &&
  143.  inCert      != NULL &&
  144.  inPrivKey   != NULL &&
  145.  inPubKey    != NULL);
  146.     if (inKeyRecRep == NULL ||
  147. inCert      == NULL ||
  148. inPrivKey   == NULL ||
  149. inPubKey    == NULL) {
  150.         return SECFailure;
  151.     }
  152.     poolp = inKeyRecRep->poolp;
  153.     mark = PORT_ArenaMark(poolp);
  154.     if (inKeyRecRep->keyPairHist == NULL) {
  155.         inKeyRecRep->keyPairHist = PORT_ArenaNewArray(poolp, 
  156.       CMMFCertifiedKeyPair*,
  157.       (CMMF_MAX_KEY_PAIRS+1));
  158. if (inKeyRecRep->keyPairHist == NULL) {
  159.     goto loser;
  160. }
  161. inKeyRecRep->allocKeyPairs = CMMF_MAX_KEY_PAIRS;
  162. inKeyRecRep->numKeyPairs   = 0;
  163.     }
  164.     if (inKeyRecRep->allocKeyPairs == inKeyRecRep->numKeyPairs) {
  165.         goto loser;
  166.     }
  167.     
  168.     keyPair = PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair);
  169.     if (keyPair == NULL) {
  170.         goto loser;
  171.     }
  172.     rv = cmmf_CertOrEncCertSetCertificate(&keyPair->certOrEncCert,
  173.   poolp, inCert);
  174.     if (rv != SECSuccess) {
  175.         goto loser;
  176.     }
  177.     keyPair->privateKey = PORT_ArenaZNew(poolp, CRMFEncryptedValue);
  178.     if (keyPair->privateKey == NULL) {
  179.         goto loser;
  180.     }
  181.     dummy = crmf_create_encrypted_value_wrapped_privkey(inPrivKey, inPubKey, 
  182. keyPair->privateKey);
  183.     PORT_Assert(dummy = keyPair->privateKey);
  184.     if (dummy != keyPair->privateKey) {
  185.         crmf_destroy_encrypted_value(dummy, PR_TRUE);
  186. goto loser;
  187.     }
  188.     inKeyRecRep->keyPairHist[inKeyRecRep->numKeyPairs] = keyPair;
  189.     inKeyRecRep->numKeyPairs++;
  190.     inKeyRecRep->keyPairHist[inKeyRecRep->numKeyPairs] = NULL;
  191.     PORT_ArenaUnmark(poolp, mark);
  192.     return SECSuccess;
  193.  loser:
  194.     PORT_ArenaRelease(poolp, mark);
  195.     return SECFailure;
  196. }
  197. CMMFPKIStatus
  198. CMMF_KeyRecRepContentGetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep)
  199. {
  200.     PORT_Assert(inKeyRecRep != NULL);
  201.     if (inKeyRecRep == NULL) {
  202.         return cmmfNoPKIStatus;
  203.     }
  204.     return cmmf_PKIStatusInfoGetStatus(&inKeyRecRep->status);
  205. }
  206. CERTCertificate*
  207. CMMF_KeyRecRepContentGetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep)
  208. {
  209.     PORT_Assert(inKeyRecRep != NULL);
  210.     if (inKeyRecRep             == NULL ||
  211. inKeyRecRep->newSigCert == NULL) {
  212.         return NULL;
  213.     }
  214.     return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), 
  215.           &inKeyRecRep->newSigCert->signatureWrap.data,
  216.    NULL, PR_FALSE, PR_TRUE);
  217. }
  218. CERTCertList*
  219. CMMF_KeyRecRepContentGetCACerts(CMMFKeyRecRepContent *inKeyRecRep)
  220. {
  221.     PORT_Assert(inKeyRecRep != NULL);
  222.     if (inKeyRecRep == NULL || inKeyRecRep->caCerts == NULL) {
  223.         return NULL;
  224.     }
  225.     return cmmf_MakeCertList(inKeyRecRep->caCerts);
  226. }
  227. int 
  228. CMMF_KeyRecRepContentGetNumKeyPairs(CMMFKeyRecRepContent *inKeyRecRep)
  229. {
  230.     PORT_Assert(inKeyRecRep != NULL);
  231.     return (inKeyRecRep == NULL) ? 0 : inKeyRecRep->numKeyPairs;
  232. }
  233. PRBool
  234. cmmf_KeyRecRepContentIsValidIndex(CMMFKeyRecRepContent *inKeyRecRep,
  235.   int                   inIndex)
  236. {
  237.     int numKeyPairs = CMMF_KeyRecRepContentGetNumKeyPairs(inKeyRecRep);
  238.     
  239.     return (PRBool)(inIndex >= 0 && inIndex < numKeyPairs);
  240. }
  241. CMMFCertifiedKeyPair*
  242. CMMF_KeyRecRepContentGetCertKeyAtIndex(CMMFKeyRecRepContent *inKeyRecRep,
  243.        int                   inIndex)
  244. {
  245.     CMMFCertifiedKeyPair *newKeyPair;
  246.     SECStatus             rv;
  247.     PORT_Assert(inKeyRecRep != NULL &&
  248. cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex));
  249.     if (inKeyRecRep == NULL ||
  250. !cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex)) {
  251.         return NULL;
  252.     }
  253.     newKeyPair = PORT_ZNew(CMMFCertifiedKeyPair);
  254.     if (newKeyPair == NULL) {
  255.         return NULL;
  256.     }
  257.     rv = cmmf_CopyCertifiedKeyPair(NULL, newKeyPair, 
  258.    inKeyRecRep->keyPairHist[inIndex]);
  259.     if (rv != SECSuccess) {
  260.         CMMF_DestroyCertifiedKeyPair(newKeyPair);
  261. newKeyPair = NULL;
  262.     }
  263.     return newKeyPair;
  264. }
  265. SECStatus 
  266. CMMF_CertifiedKeyPairUnwrapPrivKey(CMMFCertifiedKeyPair *inKeyPair,
  267.    SECKEYPrivateKey     *inPrivKey,
  268.    SECItem              *inNickName,
  269.    PK11SlotInfo         *inSlot,
  270.    CERTCertDBHandle     *inCertdb,
  271.    SECKEYPrivateKey    **destPrivKey,
  272.    void                 *wincx)
  273. {
  274.     CERTCertificate *cert;
  275.     SECItem keyUsageValue = {siBuffer, NULL, 0};
  276.     unsigned char keyUsage = 0x0;
  277.     SECKEYPublicKey *pubKey;
  278.     SECStatus rv;
  279.     PORT_Assert(inKeyPair != NULL &&
  280. inPrivKey != NULL && inCertdb != NULL);
  281.     if (inKeyPair             == NULL ||
  282. inPrivKey             == NULL ||
  283. inKeyPair->privateKey == NULL ||
  284. inCertdb              == NULL) {
  285.         return SECFailure;
  286.     }
  287.     
  288.     cert = CMMF_CertifiedKeyPairGetCertificate(inKeyPair, inCertdb);
  289.     CERT_FindKeyUsageExtension(cert, &keyUsageValue);
  290.     if (keyUsageValue.data != NULL) {
  291.         keyUsage = keyUsageValue.data[3];
  292. PORT_Free(keyUsageValue.data);
  293.     }
  294.     pubKey = CERT_ExtractPublicKey(cert);
  295.     rv = crmf_encrypted_value_unwrap_priv_key(NULL, inKeyPair->privateKey,
  296.       inPrivKey, pubKey, 
  297.       inNickName, inSlot, keyUsage, 
  298.       destPrivKey, wincx);
  299.     SECKEY_DestroyPublicKey(pubKey);
  300.     CERT_DestroyCertificate(cert);
  301.     return rv;
  302. }
  303. PRBool 
  304. CMMF_KeyRecRepContentHasCACerts(CMMFKeyRecRepContent *inKeyRecRep)
  305. {
  306.     PORT_Assert(inKeyRecRep != NULL);
  307.     if (inKeyRecRep == NULL) {
  308.         return PR_FALSE;
  309.     }
  310.     return (PRBool)(inKeyRecRep->caCerts    != NULL && 
  311.     inKeyRecRep->caCerts[0] != NULL);
  312. }