security/nss/lib/crmf/cmmfrec.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C; tab-width: 8 -*-*/
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 /*
     7  * This file will implement the functions related to key recovery in 
     8  * CMMF
     9  */
    11 #include "cmmf.h"
    12 #include "cmmfi.h"
    13 #include "secitem.h"
    14 #include "keyhi.h"
    16 CMMFKeyRecRepContent*
    17 CMMF_CreateKeyRecRepContent(void)
    18 {
    19     PLArenaPool          *poolp;
    20     CMMFKeyRecRepContent *keyRecContent;
    22     poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
    23     if (poolp == NULL) {
    24         return NULL;
    25     }
    26     keyRecContent = PORT_ArenaZNew(poolp, CMMFKeyRecRepContent);
    27     if (keyRecContent == NULL) {
    28         PORT_FreeArena(poolp, PR_FALSE);
    29 	return NULL;
    30     }
    31     keyRecContent->poolp = poolp;
    32     return keyRecContent;
    33 }
    35 SECStatus
    36 CMMF_DestroyKeyRecRepContent(CMMFKeyRecRepContent *inKeyRecRep)
    37 {
    38     PORT_Assert(inKeyRecRep != NULL);
    39     if (inKeyRecRep != NULL && inKeyRecRep->poolp != NULL) {
    40 	int i;
    42 	if (!inKeyRecRep->isDecoded && inKeyRecRep->newSigCert != NULL) {
    43 	    CERT_DestroyCertificate(inKeyRecRep->newSigCert);
    44 	}
    45 	if (inKeyRecRep->caCerts != NULL) {
    46 	    for (i=0; inKeyRecRep->caCerts[i] != NULL; i++) {
    47 		CERT_DestroyCertificate(inKeyRecRep->caCerts[i]);
    48 	    }
    49 	}
    50 	if (inKeyRecRep->keyPairHist != NULL) {
    51 	    for (i=0; inKeyRecRep->keyPairHist[i] != NULL; i++) {
    52 	        if (inKeyRecRep->keyPairHist[i]->certOrEncCert.choice ==
    53 			cmmfCertificate) {
    54 		    CERT_DestroyCertificate(inKeyRecRep->keyPairHist[i]->
    55 					       certOrEncCert.cert.certificate);
    56 		}
    57 	    }
    58 	}
    59         PORT_FreeArena(inKeyRecRep->poolp, PR_TRUE);
    60     }
    61     return SECSuccess;
    62 }
    64 SECStatus
    65 CMMF_KeyRecRepContentSetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep,
    66 					    CMMFPKIStatus         inPKIStatus)
    67 {
    68     PORT_Assert(inKeyRecRep != NULL && inPKIStatus >= cmmfGranted &&
    69 		inPKIStatus < cmmfNumPKIStatus);
    70     if (inKeyRecRep == NULL) {
    71         return SECFailure;
    72     }
    74     return cmmf_PKIStatusInfoSetStatus(&inKeyRecRep->status, 
    75 				       inKeyRecRep->poolp,
    76 				       inPKIStatus);
    77 }
    79 SECStatus
    80 CMMF_KeyRecRepContentSetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep,
    81 				    CERTCertificate      *inNewSignCert)
    82 {
    83     PORT_Assert (inKeyRecRep != NULL && inNewSignCert != NULL);
    84     if (inKeyRecRep == NULL || inNewSignCert == NULL) {
    85         return SECFailure;
    86     }
    87     if (!inKeyRecRep->isDecoded && inKeyRecRep->newSigCert) {
    88 	CERT_DestroyCertificate(inKeyRecRep->newSigCert);
    89     }
    90     inKeyRecRep->isDecoded = PR_FALSE;
    91     inKeyRecRep->newSigCert = CERT_DupCertificate(inNewSignCert);
    92     return (inKeyRecRep->newSigCert == NULL) ? SECFailure : SECSuccess;    
    93 }
    95 SECStatus
    96 CMMF_KeyRecRepContentSetCACerts(CMMFKeyRecRepContent *inKeyRecRep,
    97 				CERTCertList         *inCACerts)
    98 {
    99     SECStatus rv;
   100     void *mark;
   102     PORT_Assert (inKeyRecRep != NULL && inCACerts != NULL);
   103     if (inKeyRecRep == NULL || inCACerts == NULL) {
   104         return SECFailure;
   105     }
   106     mark = PORT_ArenaMark(inKeyRecRep->poolp);
   107     rv = cmmf_ExtractCertsFromList(inCACerts, inKeyRecRep->poolp,
   108 				   &inKeyRecRep->caCerts);
   109     if (rv != SECSuccess) {
   110         PORT_ArenaRelease(inKeyRecRep->poolp, mark);
   111     } else {
   112         PORT_ArenaUnmark(inKeyRecRep->poolp, mark);
   113     }
   114     return rv;
   115 }
   117 SECStatus
   118 CMMF_KeyRecRepContentSetCertifiedKeyPair(CMMFKeyRecRepContent *inKeyRecRep,
   119 					 CERTCertificate      *inCert,
   120 					 SECKEYPrivateKey     *inPrivKey,
   121 					 SECKEYPublicKey      *inPubKey)
   122 {
   123     CMMFCertifiedKeyPair *keyPair;
   124     CRMFEncryptedValue   *dummy;
   125     PLArenaPool          *poolp;
   126     void                 *mark;
   127     SECStatus             rv;
   129     PORT_Assert (inKeyRecRep != NULL &&
   130 		 inCert      != NULL &&
   131 		 inPrivKey   != NULL &&
   132 		 inPubKey    != NULL);
   133     if (inKeyRecRep == NULL ||
   134 	inCert      == NULL ||
   135 	inPrivKey   == NULL ||
   136 	inPubKey    == NULL) {
   137         return SECFailure;
   138     }
   139     poolp = inKeyRecRep->poolp;
   140     mark = PORT_ArenaMark(poolp);
   141     if (inKeyRecRep->keyPairHist == NULL) {
   142         inKeyRecRep->keyPairHist = PORT_ArenaNewArray(poolp, 
   143 						      CMMFCertifiedKeyPair*,
   144 						      (CMMF_MAX_KEY_PAIRS+1));
   145 	if (inKeyRecRep->keyPairHist == NULL) {
   146 	    goto loser;
   147 	}
   148 	inKeyRecRep->allocKeyPairs = CMMF_MAX_KEY_PAIRS;
   149 	inKeyRecRep->numKeyPairs   = 0;
   150     }
   152     if (inKeyRecRep->allocKeyPairs == inKeyRecRep->numKeyPairs) {
   153         goto loser;
   154     }
   156     keyPair = PORT_ArenaZNew(poolp, CMMFCertifiedKeyPair);
   157     if (keyPair == NULL) {
   158         goto loser;
   159     }
   160     rv = cmmf_CertOrEncCertSetCertificate(&keyPair->certOrEncCert,
   161 					  poolp, inCert);
   162     if (rv != SECSuccess) {
   163         goto loser;
   164     }
   165     keyPair->privateKey = PORT_ArenaZNew(poolp, CRMFEncryptedValue);
   166     if (keyPair->privateKey == NULL) {
   167         goto loser;
   168     }
   169     dummy = crmf_create_encrypted_value_wrapped_privkey(inPrivKey, inPubKey, 
   170 							keyPair->privateKey);
   171     PORT_Assert(dummy == keyPair->privateKey);
   172     if (dummy != keyPair->privateKey) {
   173         crmf_destroy_encrypted_value(dummy, PR_TRUE);
   174 	goto loser;
   175     }
   176     inKeyRecRep->keyPairHist[inKeyRecRep->numKeyPairs] = keyPair;
   177     inKeyRecRep->numKeyPairs++;
   178     inKeyRecRep->keyPairHist[inKeyRecRep->numKeyPairs] = NULL;
   179     PORT_ArenaUnmark(poolp, mark);
   180     return SECSuccess;
   182  loser:
   183     PORT_ArenaRelease(poolp, mark);
   184     return SECFailure;
   185 }
   187 CMMFPKIStatus
   188 CMMF_KeyRecRepContentGetPKIStatusInfoStatus(CMMFKeyRecRepContent *inKeyRecRep)
   189 {
   190     PORT_Assert(inKeyRecRep != NULL);
   191     if (inKeyRecRep == NULL) {
   192         return cmmfNoPKIStatus;
   193     }
   194     return cmmf_PKIStatusInfoGetStatus(&inKeyRecRep->status);
   195 }
   197 CERTCertificate*
   198 CMMF_KeyRecRepContentGetNewSignCert(CMMFKeyRecRepContent *inKeyRecRep)
   199 {
   200     PORT_Assert(inKeyRecRep != NULL);
   201     if (inKeyRecRep             == NULL ||
   202 	inKeyRecRep->newSigCert == NULL) {
   203         return NULL;
   204     }
   205     /* newSigCert may not be a real certificate, it may be a hand decoded
   206      * cert structure. This code makes sure we hand off a real, fully formed
   207      * CERTCertificate to the caller. TODO: This should move into the decode
   208      * portion so that we never wind up with a half formed CERTCertificate
   209      * here. In this case the call would be to CERT_DupCertificate.
   210      */
   211     return CERT_NewTempCertificate(CERT_GetDefaultCertDB(), 
   212 			          &inKeyRecRep->newSigCert->signatureWrap.data,
   213 				   NULL, PR_FALSE, PR_TRUE);
   214 }
   216 CERTCertList*
   217 CMMF_KeyRecRepContentGetCACerts(CMMFKeyRecRepContent *inKeyRecRep)
   218 {
   219     PORT_Assert(inKeyRecRep != NULL);
   220     if (inKeyRecRep == NULL || inKeyRecRep->caCerts == NULL) {
   221         return NULL;
   222     }
   223     return cmmf_MakeCertList(inKeyRecRep->caCerts);
   224 }
   226 int 
   227 CMMF_KeyRecRepContentGetNumKeyPairs(CMMFKeyRecRepContent *inKeyRecRep)
   228 {
   229     PORT_Assert(inKeyRecRep != NULL);
   230     return (inKeyRecRep == NULL) ? 0 : inKeyRecRep->numKeyPairs;
   231 }
   233 PRBool
   234 cmmf_KeyRecRepContentIsValidIndex(CMMFKeyRecRepContent *inKeyRecRep,
   235 				  int                   inIndex)
   236 {
   237     int numKeyPairs = CMMF_KeyRecRepContentGetNumKeyPairs(inKeyRecRep);
   239     return (PRBool)(inIndex >= 0 && inIndex < numKeyPairs);
   240 }
   242 CMMFCertifiedKeyPair*
   243 CMMF_KeyRecRepContentGetCertKeyAtIndex(CMMFKeyRecRepContent *inKeyRecRep,
   244 				       int                   inIndex)
   245 {
   246     CMMFCertifiedKeyPair *newKeyPair;
   247     SECStatus             rv;
   249     PORT_Assert(inKeyRecRep != NULL &&
   250 		cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex));
   251     if (inKeyRecRep == NULL ||
   252 	!cmmf_KeyRecRepContentIsValidIndex(inKeyRecRep, inIndex)) {
   253         return NULL;
   254     }
   255     newKeyPair = PORT_ZNew(CMMFCertifiedKeyPair);
   256     if (newKeyPair == NULL) {
   257         return NULL;
   258     }
   259     rv = cmmf_CopyCertifiedKeyPair(NULL, newKeyPair, 
   260 				   inKeyRecRep->keyPairHist[inIndex]);
   261     if (rv != SECSuccess) {
   262         CMMF_DestroyCertifiedKeyPair(newKeyPair);
   263 	newKeyPair = NULL;
   264     }
   265     return newKeyPair;
   266 }
   268 SECStatus 
   269 CMMF_CertifiedKeyPairUnwrapPrivKey(CMMFCertifiedKeyPair *inKeyPair,
   270 				   SECKEYPrivateKey     *inPrivKey,
   271 				   SECItem              *inNickName,
   272 				   PK11SlotInfo         *inSlot,
   273 				   CERTCertDBHandle     *inCertdb,
   274 				   SECKEYPrivateKey    **destPrivKey,
   275 				   void                 *wincx)
   276 {
   277     CERTCertificate *cert;
   278     SECItem keyUsageValue = {siBuffer, NULL, 0};
   279     unsigned char keyUsage = 0x0;
   280     SECKEYPublicKey *pubKey;
   281     SECStatus rv;
   283     PORT_Assert(inKeyPair != NULL &&
   284 		inPrivKey != NULL && inCertdb != NULL);
   285     if (inKeyPair             == NULL ||
   286 	inPrivKey             == NULL ||
   287 	inKeyPair->privateKey == NULL ||
   288 	inCertdb              == NULL) {
   289         return SECFailure;
   290     }
   292     cert = CMMF_CertifiedKeyPairGetCertificate(inKeyPair, inCertdb);
   293     CERT_FindKeyUsageExtension(cert, &keyUsageValue);
   294     if (keyUsageValue.data != NULL) {
   295         keyUsage = keyUsageValue.data[3];
   296 	PORT_Free(keyUsageValue.data);
   297     }
   298     pubKey = CERT_ExtractPublicKey(cert);
   299     rv = crmf_encrypted_value_unwrap_priv_key(NULL, inKeyPair->privateKey,
   300 					      inPrivKey, pubKey, 
   301 					      inNickName, inSlot, keyUsage, 
   302 					      destPrivKey, wincx);
   303     SECKEY_DestroyPublicKey(pubKey);
   304     CERT_DestroyCertificate(cert);
   305     return rv;
   306 }
   309 PRBool 
   310 CMMF_KeyRecRepContentHasCACerts(CMMFKeyRecRepContent *inKeyRecRep)
   311 {
   312     PORT_Assert(inKeyRecRep != NULL);
   313     if (inKeyRecRep == NULL) {
   314         return PR_FALSE;
   315     }
   316     return (PRBool)(inKeyRecRep->caCerts    != NULL && 
   317 		    inKeyRecRep->caCerts[0] != NULL);
   318 }

mercurial