Back to index

lightning-sunbird  0.9+nobinonly
servget.c
Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 8 -*-*/
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape security libraries.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1994-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 
00039 #include "cmmf.h"
00040 #include "cmmfi.h"
00041 #include "secitem.h"
00042 #include "keyhi.h"
00043 #include "secder.h"
00044 
00045 CRMFEncryptedKeyChoice
00046 CRMF_EncryptedKeyGetChoice(CRMFEncryptedKey *inEncrKey)
00047 {
00048     PORT_Assert(inEncrKey != NULL);
00049     if (inEncrKey == NULL) {
00050         return crmfNoEncryptedKeyChoice;
00051     }
00052     return inEncrKey->encKeyChoice;
00053 }
00054 
00055 CRMFEncryptedValue*
00056 CRMF_EncryptedKeyGetEncryptedValue(CRMFEncryptedKey *inEncrKey)
00057 {
00058     CRMFEncryptedValue *newEncrValue = NULL;
00059     SECStatus           rv;
00060 
00061     PORT_Assert(inEncrKey != NULL);
00062     if (inEncrKey == NULL ||
00063        CRMF_EncryptedKeyGetChoice(inEncrKey) != crmfEncryptedValueChoice) {
00064         goto loser;
00065     }
00066     newEncrValue = PORT_ZNew(CRMFEncryptedValue);
00067     if (newEncrValue == NULL) {
00068         goto loser;
00069     }
00070     rv = crmf_copy_encryptedvalue(NULL, &inEncrKey->value.encryptedValue,
00071                               newEncrValue);
00072     if (rv != SECSuccess) {
00073         goto loser;
00074     }
00075     return newEncrValue;
00076  loser:
00077     if (newEncrValue != NULL) {
00078         CRMF_DestroyEncryptedValue(newEncrValue);
00079     }
00080     return NULL;
00081 }
00082 
00083 static SECItem*
00084 crmf_get_encvalue_bitstring(SECItem *srcItem)
00085 {
00086     SECItem   *newItem = NULL;
00087     SECStatus rv;
00088     
00089     if (srcItem->data == NULL) {
00090         return NULL;
00091     }
00092     newItem = PORT_ZNew(SECItem);
00093     if (newItem == NULL) {
00094         goto loser;
00095     }
00096     rv = crmf_make_bitstring_copy(NULL, newItem, srcItem);
00097     if (rv != SECSuccess) {
00098         goto loser;
00099     }
00100     return newItem;
00101  loser:
00102     if (newItem != NULL) {
00103         SECITEM_FreeItem(newItem, PR_TRUE);
00104     }
00105     return NULL;
00106 }
00107 
00108 SECItem*
00109 CRMF_EncryptedValueGetEncSymmKey(CRMFEncryptedValue *inEncValue)
00110 {
00111     if (inEncValue == NULL) {
00112         return NULL;
00113     }
00114     return crmf_get_encvalue_bitstring(&inEncValue->encSymmKey);
00115 }
00116 
00117 SECItem*
00118 CRMF_EncryptedValueGetEncValue(CRMFEncryptedValue *inEncrValue)
00119 {
00120     if (inEncrValue == NULL || inEncrValue->encValue.data == NULL) {
00121         return NULL;
00122     }
00123     return crmf_get_encvalue_bitstring(&inEncrValue->encValue);
00124 }
00125 
00126 static SECAlgorithmID*
00127 crmf_get_encvalue_algid(SECAlgorithmID *srcAlg)
00128 {
00129     SECStatus       rv;
00130     SECAlgorithmID *newAlgID;
00131     
00132     if (srcAlg == NULL) {
00133         return NULL;
00134     }
00135     rv = crmf_copy_encryptedvalue_secalg(NULL, srcAlg, &newAlgID);
00136     if (rv != SECSuccess) {
00137         return NULL;
00138     }
00139     return newAlgID;
00140 }
00141 
00142 SECAlgorithmID*
00143 CRMF_EncryptedValueGetIntendedAlg(CRMFEncryptedValue *inEncValue)
00144 {
00145     if (inEncValue == NULL) {
00146         return NULL;
00147     }
00148     return crmf_get_encvalue_algid(inEncValue->intendedAlg);
00149 }
00150 
00151 SECAlgorithmID*
00152 CRMF_EncryptedValueGetKeyAlg(CRMFEncryptedValue *inEncValue)
00153 {
00154     if (inEncValue == NULL) {
00155         return NULL;
00156     }
00157     return crmf_get_encvalue_algid(inEncValue->keyAlg);
00158 }
00159 
00160 SECAlgorithmID*
00161 CRMF_EncryptedValueGetSymmAlg(CRMFEncryptedValue *inEncValue)
00162 {
00163     if (inEncValue == NULL) {
00164         return NULL;
00165     }
00166     return crmf_get_encvalue_algid(inEncValue->symmAlg);
00167 }
00168 
00169 SECItem*
00170 CRMF_EncryptedValueGetValueHint(CRMFEncryptedValue *inEncValue)
00171 {
00172     if (inEncValue == NULL || inEncValue->valueHint.data == NULL) {
00173         return NULL;
00174     }
00175     return SECITEM_DupItem(&inEncValue->valueHint);
00176 }
00177 
00178 SECStatus
00179 CRMF_PKIArchiveOptionsGetArchiveRemGenPrivKey(CRMFPKIArchiveOptions *inOpt, 
00180                                          PRBool                *destVal)
00181 {
00182     if (inOpt == NULL || destVal == NULL ||
00183        CRMF_PKIArchiveOptionsGetOptionType(inOpt) != crmfArchiveRemGenPrivKey){
00184         return SECFailure;
00185     }
00186     *destVal = (inOpt->option.archiveRemGenPrivKey.data[0] == hexFalse) 
00187                                                                  ? PR_FALSE:
00188                                                                    PR_TRUE;
00189     return SECSuccess;
00190 }
00191                           
00192 CRMFEncryptedKey*
00193 CRMF_PKIArchiveOptionsGetEncryptedPrivKey(CRMFPKIArchiveOptions *inOpts)
00194 {
00195     CRMFEncryptedKey *newEncrKey = NULL;
00196     SECStatus         rv;
00197 
00198     PORT_Assert(inOpts != NULL);
00199     if (inOpts == NULL ||
00200        CRMF_PKIArchiveOptionsGetOptionType(inOpts) != crmfEncryptedPrivateKey){
00201         return NULL;
00202     }
00203     newEncrKey = PORT_ZNew(CRMFEncryptedKey);
00204     if (newEncrKey == NULL) {
00205         goto loser;
00206     }
00207     rv = crmf_copy_encryptedkey(NULL, &inOpts->option.encryptedKey,
00208                             newEncrKey);
00209     if (rv != SECSuccess) {
00210         goto loser;
00211     }
00212     return newEncrKey;
00213  loser:
00214     if (newEncrKey != NULL) {
00215         CRMF_DestroyEncryptedKey(newEncrKey);
00216     }
00217     return NULL;
00218 }
00219 
00220 SECItem*
00221 CRMF_PKIArchiveOptionsGetKeyGenParameters(CRMFPKIArchiveOptions *inOptions)
00222 {
00223     if (inOptions == NULL ||
00224        CRMF_PKIArchiveOptionsGetOptionType(inOptions) != crmfKeyGenParameters ||
00225        inOptions->option.keyGenParameters.data == NULL) {
00226         return NULL;
00227     }
00228     return SECITEM_DupItem(&inOptions->option.keyGenParameters);
00229 }
00230 
00231 CRMFPKIArchiveOptionsType
00232 CRMF_PKIArchiveOptionsGetOptionType(CRMFPKIArchiveOptions *inOptions)
00233 {
00234     PORT_Assert (inOptions != NULL);
00235     if (inOptions == NULL) {
00236         return crmfNoArchiveOptions;
00237     }
00238     return inOptions->archOption;
00239 }
00240 
00241 static SECStatus
00242 crmf_extract_long_from_item(SECItem *intItem, long *destLong)
00243 {
00244     *destLong = DER_GetInteger(intItem);
00245     return (*destLong == -1) ? SECFailure : SECSuccess;
00246 }
00247 
00248 SECStatus
00249 CRMF_POPOPrivGetKeySubseqMess(CRMFPOPOPrivKey       *inKey,
00250                            CRMFSubseqMessOptions *destOpt)
00251 {
00252     long      value;
00253     SECStatus rv;
00254 
00255     PORT_Assert(inKey != NULL);
00256     if (inKey == NULL ||
00257        inKey->messageChoice != crmfSubsequentMessage) {
00258         return SECFailure;
00259     }
00260     rv = crmf_extract_long_from_item(&inKey->message.subsequentMessage,&value);
00261     if (rv != SECSuccess) {
00262         return SECFailure;
00263     }
00264     switch (value) {
00265     case 0:
00266         *destOpt = crmfEncrCert;
00267        break;
00268     case 1:
00269         *destOpt = crmfChallengeResp;
00270        break;
00271     default:
00272         rv = SECFailure;
00273     }
00274     if (rv != SECSuccess) {
00275         return rv;
00276     }
00277     return SECSuccess;
00278 }
00279 
00280 CRMFPOPOPrivKeyChoice
00281 CRMF_POPOPrivKeyGetChoice(CRMFPOPOPrivKey *inPrivKey)
00282 {
00283     PORT_Assert(inPrivKey != NULL);
00284     if (inPrivKey != NULL) {
00285         return inPrivKey->messageChoice;
00286     }
00287     return crmfNoMessage;
00288 }
00289 
00290 SECStatus
00291 CRMF_POPOPrivKeyGetDHMAC(CRMFPOPOPrivKey *inKey, SECItem *destMAC)
00292 {
00293     PORT_Assert(inKey != NULL);
00294     if (inKey == NULL || inKey->message.dhMAC.data == NULL) {
00295         return SECFailure;
00296     }
00297     return crmf_make_bitstring_copy(NULL, destMAC, &inKey->message.dhMAC);
00298 }
00299 
00300 SECStatus
00301 CRMF_POPOPrivKeyGetThisMessage(CRMFPOPOPrivKey  *inKey,
00302                             SECItem          *destString)
00303 {
00304     PORT_Assert(inKey != NULL);
00305     if (inKey == NULL           ||
00306        inKey->messageChoice != crmfThisMessage) {
00307         return SECFailure;
00308     }
00309 
00310     return crmf_make_bitstring_copy(NULL, destString, 
00311                                 &inKey->message.thisMessage);
00312 }
00313 
00314 SECAlgorithmID*
00315 CRMF_POPOSigningKeyGetAlgID(CRMFPOPOSigningKey *inSignKey)
00316 {
00317     SECAlgorithmID *newAlgId = NULL;
00318     SECStatus       rv;
00319 
00320     PORT_Assert(inSignKey != NULL);
00321     if (inSignKey == NULL) {
00322         return NULL;
00323     }
00324     newAlgId = PORT_ZNew(SECAlgorithmID);
00325     if (newAlgId == NULL) {
00326         goto loser;
00327     }
00328     rv = SECOID_CopyAlgorithmID(NULL, newAlgId, 
00329                             inSignKey->algorithmIdentifier);
00330     if (rv != SECSuccess) {
00331         goto loser;
00332     }
00333     return newAlgId;
00334 
00335  loser:
00336     if (newAlgId != NULL) {
00337         SECOID_DestroyAlgorithmID(newAlgId, PR_TRUE);
00338     }
00339     return NULL;
00340 }
00341 
00342 SECItem*
00343 CRMF_POPOSigningKeyGetInput(CRMFPOPOSigningKey *inSignKey)
00344 {
00345     PORT_Assert(inSignKey != NULL);
00346     if (inSignKey == NULL || inSignKey->derInput.data == NULL) {
00347         return NULL;
00348     }
00349     return SECITEM_DupItem(&inSignKey->derInput);
00350 }
00351 
00352 SECItem*
00353 CRMF_POPOSigningKeyGetSignature(CRMFPOPOSigningKey *inSignKey)
00354 {
00355     SECItem   *newSig = NULL;
00356     SECStatus  rv;
00357 
00358     PORT_Assert(inSignKey != NULL);
00359     if (inSignKey == NULL) {
00360         return NULL;
00361     }
00362     newSig = PORT_ZNew(SECItem);
00363     if (newSig == NULL) {
00364         goto loser;
00365     }
00366     rv = crmf_make_bitstring_copy(NULL, newSig, &inSignKey->signature);
00367     if (rv != SECSuccess) {
00368         goto loser;
00369     }
00370     return newSig;
00371  loser:
00372     if (newSig != NULL) {
00373         SECITEM_FreeItem(newSig, PR_TRUE);
00374     }
00375     return NULL;
00376 }
00377 
00378 static SECStatus 
00379 crmf_copy_poposigningkey(PRArenaPool        *poolp, 
00380                       CRMFPOPOSigningKey *inPopoSignKey,
00381                       CRMFPOPOSigningKey *destPopoSignKey)
00382 {
00383     SECStatus rv;
00384 
00385     /* We don't support use of the POPOSigningKeyInput, so we'll only 
00386      * store away the DER encoding.
00387      */
00388     if (inPopoSignKey->derInput.data != NULL) {
00389         rv = SECITEM_CopyItem(poolp, &destPopoSignKey->derInput, 
00390                            &inPopoSignKey->derInput);
00391     }
00392     destPopoSignKey->algorithmIdentifier = (poolp == NULL) ? 
00393                                          PORT_ZNew(SECAlgorithmID) :
00394                                          PORT_ArenaZNew(poolp, SECAlgorithmID);
00395 
00396     if (destPopoSignKey->algorithmIdentifier == NULL) {
00397         goto loser;
00398     }
00399     rv = SECOID_CopyAlgorithmID(poolp, destPopoSignKey->algorithmIdentifier,
00400                             inPopoSignKey->algorithmIdentifier);
00401     if (rv != SECSuccess) {
00402         goto loser;
00403     }
00404     
00405     rv = crmf_make_bitstring_copy(poolp, &destPopoSignKey->signature, 
00406                               &inPopoSignKey->signature);
00407     if (rv != SECSuccess) {
00408         goto loser;
00409     }
00410     return SECSuccess;
00411  loser:
00412     if (poolp == NULL) {
00413         CRMF_DestroyPOPOSigningKey(destPopoSignKey);
00414     }
00415     return SECFailure;
00416 }
00417 
00418 static SECStatus
00419 crmf_copy_popoprivkey(PRArenaPool     *poolp,
00420                     CRMFPOPOPrivKey *srcPrivKey,
00421                     CRMFPOPOPrivKey *destPrivKey)
00422 {
00423     SECStatus        rv;
00424 
00425     destPrivKey->messageChoice = srcPrivKey->messageChoice;
00426     switch (destPrivKey->messageChoice) {
00427     case crmfThisMessage:
00428     case crmfDHMAC:
00429         /* I've got a union, so taking the address of one, will also give
00430         * me a pointer to the other (eg, message.dhMAC)
00431         */
00432         rv = crmf_make_bitstring_copy(poolp, &destPrivKey->message.thisMessage,
00433                                   &srcPrivKey->message.thisMessage);
00434        break;
00435     case crmfSubsequentMessage:
00436         rv = SECITEM_CopyItem(poolp, &destPrivKey->message.subsequentMessage,
00437                            &srcPrivKey->message.subsequentMessage);
00438        break;
00439     default:
00440         rv = SECFailure;
00441     }
00442 
00443     if (rv != SECSuccess && poolp == NULL) {
00444         CRMF_DestroyPOPOPrivKey(destPrivKey);
00445     }
00446     return rv;
00447 }
00448 
00449 static CRMFProofOfPossession*
00450 crmf_copy_pop(PRArenaPool *poolp, CRMFProofOfPossession *srcPOP)
00451 {
00452     CRMFProofOfPossession *newPOP;
00453     SECStatus              rv;
00454 
00455     /* 
00456      * Proof Of Possession structures are always part of the Request
00457      * message, so there will always be an arena for allocating memory.
00458      */
00459     if (poolp == NULL) {
00460         return NULL;
00461     }
00462     newPOP = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
00463     if (newPOP == NULL) {
00464         return NULL;
00465     }
00466     switch (srcPOP->popUsed) {
00467     case crmfRAVerified:
00468         newPOP->popChoice.raVerified.data = NULL;
00469        newPOP->popChoice.raVerified.len  = 0;
00470        break;
00471     case crmfSignature:
00472         rv = crmf_copy_poposigningkey(poolp, &srcPOP->popChoice.signature,
00473                                   &newPOP->popChoice.signature);
00474        if (rv != SECSuccess) {
00475            goto loser;
00476        }
00477        break;
00478     case crmfKeyEncipherment:
00479     case crmfKeyAgreement:
00480         /* We've got a union, so a pointer to one, is a pointer to the
00481         * other one.
00482         */
00483         rv = crmf_copy_popoprivkey(poolp, &srcPOP->popChoice.keyEncipherment,
00484                                &newPOP->popChoice.keyEncipherment);
00485        if (rv != SECSuccess) {
00486            goto loser;
00487        }
00488        break;
00489     default:
00490         goto loser;
00491     }
00492     newPOP->popUsed = srcPOP->popUsed;
00493     return newPOP;
00494 
00495  loser:
00496     return NULL;
00497 }
00498 
00499 static CRMFCertReqMsg*
00500 crmf_copy_cert_req_msg(CRMFCertReqMsg *srcReqMsg)
00501 {
00502     CRMFCertReqMsg *newReqMsg;
00503     PRArenaPool    *poolp;
00504 
00505     poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
00506     if (poolp == NULL) {
00507         return NULL;
00508     }
00509     newReqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg);
00510     if (newReqMsg == NULL) {
00511         goto loser;
00512     }
00513 
00514     newReqMsg->poolp = poolp;
00515     newReqMsg->certReq = crmf_copy_cert_request(poolp, srcReqMsg->certReq);
00516     if (newReqMsg->certReq == NULL) {
00517         goto loser;
00518     }
00519     newReqMsg->pop = crmf_copy_pop(poolp, srcReqMsg->pop);
00520     if (newReqMsg->pop == NULL) {
00521         goto loser;
00522     }
00523     /* None of my set/get routines operate on the regInfo field, so
00524      * for now, that won't get copied over.
00525      */
00526     return newReqMsg;
00527 
00528  loser:
00529     if (newReqMsg != NULL) {
00530         CRMF_DestroyCertReqMsg(newReqMsg);
00531     }
00532     return NULL;
00533 }
00534 
00535 CRMFCertReqMsg*
00536 CRMF_CertReqMessagesGetCertReqMsgAtIndex(CRMFCertReqMessages *inReqMsgs,
00537                                     int                  index)
00538 {
00539     int numMsgs;
00540 
00541     PORT_Assert(inReqMsgs != NULL && index >= 0);
00542     if (inReqMsgs == NULL) {
00543         return NULL;
00544     }
00545     numMsgs = CRMF_CertReqMessagesGetNumMessages(inReqMsgs);
00546     if (index < 0 || index >= numMsgs) {
00547         return NULL;
00548     }
00549     return crmf_copy_cert_req_msg(inReqMsgs->messages[index]);
00550 }
00551 
00552 int
00553 CRMF_CertReqMessagesGetNumMessages(CRMFCertReqMessages *inCertReqMsgs)
00554 {
00555     int numMessages = 0;
00556 
00557     PORT_Assert(inCertReqMsgs != NULL);
00558     if (inCertReqMsgs == NULL) {
00559         return 0;
00560     }
00561     while (inCertReqMsgs->messages[numMessages] != NULL) {
00562         numMessages++;
00563     }
00564     return numMessages;
00565 }
00566 
00567 CRMFCertRequest*
00568 CRMF_CertReqMsgGetCertRequest(CRMFCertReqMsg *inCertReqMsg)
00569 {
00570     PRArenaPool     *poolp      = NULL;
00571     CRMFCertRequest *newCertReq = NULL;
00572 
00573     PORT_Assert(inCertReqMsg != NULL);
00574 
00575     poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
00576     if (poolp == NULL) {
00577         goto loser;
00578     }
00579     newCertReq = crmf_copy_cert_request(poolp, inCertReqMsg->certReq);
00580     if (newCertReq == NULL) {
00581         goto loser;
00582     }
00583     newCertReq->poolp = poolp;
00584     return newCertReq;
00585  loser:
00586     if (poolp != NULL) {
00587         PORT_FreeArena(poolp, PR_FALSE);
00588     }
00589     return NULL;
00590 }
00591 
00592 SECStatus
00593 CRMF_CertReqMsgGetID(CRMFCertReqMsg *inCertReqMsg, long *destID)
00594 {
00595     PORT_Assert(inCertReqMsg != NULL && destID != NULL);
00596     if (inCertReqMsg == NULL || inCertReqMsg->certReq == NULL) {
00597         return SECFailure;
00598     }
00599     return crmf_extract_long_from_item(&inCertReqMsg->certReq->certReqId, 
00600                                    destID);
00601 }
00602 
00603 SECStatus
00604 CRMF_CertReqMsgGetPOPKeyAgreement(CRMFCertReqMsg   *inCertReqMsg,
00605                               CRMFPOPOPrivKey **destKey)
00606 {
00607     PORT_Assert(inCertReqMsg != NULL && destKey != NULL);
00608     if (inCertReqMsg == NULL || destKey == NULL ||
00609        CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyAgreement) {
00610         return SECFailure;
00611     }
00612     *destKey = PORT_ZNew(CRMFPOPOPrivKey);
00613     if (*destKey == NULL) {
00614         return SECFailure;
00615     }
00616     return crmf_copy_popoprivkey(NULL,
00617                              &inCertReqMsg->pop->popChoice.keyAgreement,
00618                              *destKey);
00619 }
00620 
00621 SECStatus
00622 CRMF_CertReqMsgGetPOPKeyEncipherment(CRMFCertReqMsg   *inCertReqMsg,
00623                                  CRMFPOPOPrivKey **destKey)
00624 {
00625     PORT_Assert(inCertReqMsg != NULL && destKey != NULL);
00626     if (inCertReqMsg == NULL || destKey == NULL ||
00627        CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfKeyEncipherment) {
00628         return SECFailure;
00629     }
00630     *destKey = PORT_ZNew(CRMFPOPOPrivKey);
00631     if (destKey == NULL) {
00632        return SECFailure;
00633     }
00634     return crmf_copy_popoprivkey(NULL,
00635                              &inCertReqMsg->pop->popChoice.keyEncipherment,
00636                              *destKey);
00637 }
00638 
00639 SECStatus
00640 CRMF_CertReqMsgGetPOPOSigningKey(CRMFCertReqMsg      *inCertReqMsg,
00641                              CRMFPOPOSigningKey **destKey)
00642 {
00643     CRMFProofOfPossession *pop;
00644     PORT_Assert(inCertReqMsg != NULL);
00645     if (inCertReqMsg  == NULL) {
00646         return SECFailure;
00647     }
00648     pop = inCertReqMsg->pop;;
00649     if (pop->popUsed != crmfSignature) {
00650         return SECFailure;
00651     }
00652     *destKey = PORT_ZNew(CRMFPOPOSigningKey);
00653     if (*destKey == NULL) {
00654         return SECFailure;
00655     }
00656     return crmf_copy_poposigningkey(NULL,&pop->popChoice.signature, *destKey);
00657 }
00658 
00659 static SECStatus
00660 crmf_copy_name(CERTName *destName, CERTName *srcName)
00661 {
00662   PRArenaPool *poolp = NULL;
00663   SECStatus rv;
00664 
00665   if (destName->arena != NULL) {
00666     poolp = destName->arena;
00667   } else {
00668     poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE);
00669   }
00670   if (poolp == NULL) {
00671     return SECFailure;
00672   }
00673   /* Need to do this so that CERT_CopyName doesn't free out
00674    * the arena from underneath us.
00675    */
00676   destName->arena = NULL;
00677   rv = CERT_CopyName(poolp, destName, srcName); 
00678   destName->arena = poolp;
00679   return rv;
00680 }
00681 
00682 SECStatus
00683 CRMF_CertRequestGetCertTemplateIssuer(CRMFCertRequest *inCertReq,
00684                                   CERTName        *destIssuer)
00685 {
00686     PORT_Assert(inCertReq != NULL);
00687     if (inCertReq == NULL) {
00688         return SECFailure;
00689     }
00690     if (CRMF_DoesRequestHaveField(inCertReq, crmfIssuer)) {
00691         return crmf_copy_name(destIssuer, 
00692                            inCertReq->certTemplate.issuer);
00693     }
00694     return SECFailure;
00695 }
00696 
00697 SECStatus 
00698 CRMF_CertRequestGetCertTemplateIssuerUID(CRMFCertRequest *inCertReq,
00699                                     SECItem         *destIssuerUID)
00700 {
00701     PORT_Assert(inCertReq != NULL);
00702     if (inCertReq == NULL) {
00703         return SECFailure;
00704     }
00705     if (CRMF_DoesRequestHaveField(inCertReq, crmfIssuerUID)) {
00706         return crmf_make_bitstring_copy(NULL, destIssuerUID,
00707                                    &inCertReq->certTemplate.issuerUID);
00708     }
00709     return SECFailure;
00710 }
00711 
00712 SECStatus
00713 CRMF_CertRequestGetCertTemplatePublicKey(CRMFCertRequest          *inCertReq,
00714                                    CERTSubjectPublicKeyInfo *destPublicKey)
00715 {
00716     PORT_Assert (inCertReq != NULL);
00717     if (inCertReq == NULL) {
00718         return SECFailure;
00719     }
00720     if (CRMF_DoesRequestHaveField(inCertReq, crmfPublicKey)) {
00721         return SECKEY_CopySubjectPublicKeyInfo(NULL, destPublicKey,
00722                                    inCertReq->certTemplate.publicKey);
00723     }
00724     return SECFailure;
00725 }
00726 
00727 SECStatus
00728 CRMF_CertRequestGetCertTemplateSerialNumber(CRMFCertRequest *inCertReq,
00729                                        long            *serialNumber)
00730 {
00731     PORT_Assert(inCertReq != NULL);
00732     if (inCertReq == NULL) {
00733         return SECFailure;
00734     }
00735     if (CRMF_DoesRequestHaveField(inCertReq, crmfSerialNumber)) {
00736         return 
00737          crmf_extract_long_from_item(&inCertReq->certTemplate.serialNumber,
00738                                   serialNumber);
00739     }
00740     return SECFailure;
00741 }
00742 
00743 SECStatus
00744 CRMF_CertRequestGetCertTemplateSigningAlg(CRMFCertRequest *inCertReq,
00745                                      SECAlgorithmID  *destAlg)
00746 {
00747     PORT_Assert(inCertReq != NULL);
00748     if (inCertReq == NULL) {
00749         return SECFailure;
00750     }
00751     if (CRMF_DoesRequestHaveField(inCertReq, crmfSigningAlg)) {
00752         return SECOID_CopyAlgorithmID(NULL, destAlg, 
00753                                   inCertReq->certTemplate.signingAlg);
00754     }
00755     return SECFailure;
00756 }
00757 
00758 SECStatus 
00759 CRMF_CertRequestGetCertTemplateSubject(CRMFCertRequest *inCertReq,
00760                                    CERTName        *destSubject)
00761 {
00762   PORT_Assert(inCertReq != NULL);
00763   if (inCertReq == NULL) {
00764       return SECFailure;
00765   }
00766   if (CRMF_DoesRequestHaveField(inCertReq, crmfSubject)) {
00767       return crmf_copy_name(destSubject, inCertReq->certTemplate.subject);
00768   }
00769   return SECFailure;
00770 }
00771 
00772 SECStatus
00773 CRMF_CertRequestGetCertTemplateSubjectUID(CRMFCertRequest *inCertReq,
00774                                      SECItem         *destSubjectUID)
00775 {
00776     PORT_Assert(inCertReq != NULL);
00777     if (inCertReq == NULL) {
00778         return SECFailure;
00779     }
00780     if (CRMF_DoesRequestHaveField(inCertReq, crmfSubjectUID)) {
00781         return crmf_make_bitstring_copy(NULL, destSubjectUID, 
00782                                    &inCertReq->certTemplate.subjectUID);
00783     }
00784     return SECFailure;
00785 }
00786 
00787 SECStatus 
00788 CRMF_CertRequestGetCertTemplateVersion(CRMFCertRequest *inCertReq, 
00789                                    long            *version)
00790 {
00791     PORT_Assert (inCertReq != NULL);
00792     if (inCertReq == NULL) {
00793         return SECFailure;
00794     }
00795     if (CRMF_DoesRequestHaveField(inCertReq, crmfVersion)) {
00796         return crmf_extract_long_from_item(&inCertReq->certTemplate.version,
00797                                       version);
00798     } 
00799     return SECFailure;
00800 }
00801 
00802 static SECStatus
00803 crmf_copy_validity(CRMFGetValidity      *destValidity,
00804                  CRMFOptionalValidity *src)
00805 {
00806     SECStatus rv;
00807     
00808     destValidity->notBefore = destValidity->notAfter = NULL;
00809     if (src->notBefore.data != NULL) {
00810         rv = crmf_create_prtime(&src->notBefore, 
00811                             &destValidity->notBefore);
00812        if (rv != SECSuccess) {
00813            return rv;
00814        }
00815     }
00816     if (src->notAfter.data != NULL) {
00817         rv = crmf_create_prtime(&src->notAfter,
00818                             &destValidity->notAfter);
00819        if (rv != SECSuccess) {
00820            return rv;
00821        }
00822     }
00823     return SECSuccess;
00824 }
00825 
00826 SECStatus 
00827 CRMF_CertRequestGetCertTemplateValidity(CRMFCertRequest *inCertReq,
00828                                    CRMFGetValidity *destValidity)
00829 {
00830     PORT_Assert(inCertReq != NULL);
00831     if (inCertReq == NULL) {
00832         return SECFailure;
00833     }
00834     if (CRMF_DoesRequestHaveField(inCertReq, crmfValidity)) {
00835         return crmf_copy_validity(destValidity, 
00836                               inCertReq->certTemplate.validity);
00837     }
00838     return SECFailure;
00839 }
00840 
00841 CRMFControl*
00842 CRMF_CertRequestGetControlAtIndex(CRMFCertRequest *inCertReq, int index)
00843 {
00844     CRMFControl *newControl, *srcControl;
00845     int          numControls;
00846     SECStatus    rv;
00847 
00848     PORT_Assert(inCertReq != NULL);
00849     if (inCertReq == NULL) {
00850         return NULL;
00851     }
00852     numControls = CRMF_CertRequestGetNumControls(inCertReq);
00853     if (index >= numControls || index < 0) {
00854         return NULL;
00855     }
00856     newControl = PORT_ZNew(CRMFControl);
00857     if (newControl == NULL) {
00858         return NULL;
00859     }
00860     srcControl = inCertReq->controls[index];
00861     newControl->tag = srcControl->tag;
00862     rv = SECITEM_CopyItem (NULL, &newControl->derTag, &srcControl->derTag);
00863     if (rv != SECSuccess) {
00864         goto loser;
00865     }
00866 
00867     rv = SECITEM_CopyItem(NULL, &newControl->derValue, 
00868                        &srcControl->derValue);
00869     if (rv != SECSuccess) {
00870         goto loser;
00871     }
00872     /* Copy over the PKIArchiveOptions stuff */
00873     switch (srcControl->tag) {
00874     case SEC_OID_PKIX_REGCTRL_REGTOKEN:
00875     case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
00876         /* No further processing necessary for these types. */
00877         rv = SECSuccess;
00878        break;
00879     case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
00880     case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
00881     case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
00882         /* These aren't supported yet, so no post-processing will
00883         * be done at this time.  But we don't want to fail in case
00884         * we read in DER that has one of these options.
00885         */
00886         rv = SECSuccess;
00887        break;
00888     case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
00889         rv = crmf_copy_pkiarchiveoptions(NULL, 
00890                                     &newControl->value.archiveOptions,
00891                                     &srcControl->value.archiveOptions);
00892        break;
00893     default:
00894         rv = SECFailure;
00895     }
00896     if (rv != SECSuccess) {
00897         goto loser;
00898     }
00899     return newControl;
00900  loser:
00901     if (newControl != NULL) {
00902         CRMF_DestroyControl(newControl);
00903     }
00904     return NULL;
00905 }
00906 
00907 static SECItem*
00908 crmf_copy_control_value(CRMFControl *inControl)
00909 {
00910     return SECITEM_DupItem(&inControl->derValue);
00911 }
00912 
00913 SECItem*
00914 CRMF_ControlGetAuthenticatorControlValue(CRMFControl *inControl)
00915 {
00916     PORT_Assert (inControl!= NULL);
00917     if (inControl == NULL ||
00918        CRMF_ControlGetControlType(inControl) != crmfAuthenticatorControl) {
00919         return NULL;
00920     }
00921     return crmf_copy_control_value(inControl);
00922 }
00923 
00924 CRMFControlType
00925 CRMF_ControlGetControlType(CRMFControl *inControl)
00926 {
00927     CRMFControlType retType;
00928 
00929     PORT_Assert(inControl != NULL);
00930     switch (inControl->tag) {
00931     case SEC_OID_PKIX_REGCTRL_REGTOKEN:
00932         retType = crmfRegTokenControl;
00933        break;
00934     case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR:
00935         retType = crmfAuthenticatorControl;
00936        break;
00937     case SEC_OID_PKIX_REGCTRL_PKIPUBINFO:
00938         retType = crmfPKIPublicationInfoControl;
00939        break;
00940     case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS:
00941         retType = crmfPKIArchiveOptionsControl;
00942        break;
00943     case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID:
00944         retType = crmfOldCertIDControl;
00945        break;
00946     case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY:
00947         retType = crmfProtocolEncrKeyControl;
00948        break;
00949     default:
00950         retType = crmfNoControl;
00951     }
00952     return retType;
00953 }
00954 
00955 CRMFPKIArchiveOptions*
00956 CRMF_ControlGetPKIArchiveOptions(CRMFControl *inControl)
00957 {
00958     CRMFPKIArchiveOptions *newOpt = NULL;
00959     SECStatus rv;
00960 
00961     PORT_Assert(inControl != NULL);
00962     if (inControl == NULL ||
00963        CRMF_ControlGetControlType(inControl) != crmfPKIArchiveOptionsControl){
00964         goto loser;
00965     }
00966     newOpt = PORT_ZNew(CRMFPKIArchiveOptions);
00967     if (newOpt == NULL) {
00968         goto loser;
00969     }
00970     rv = crmf_copy_pkiarchiveoptions(NULL, newOpt, 
00971                                  &inControl->value.archiveOptions);
00972     if (rv != SECSuccess) {
00973         goto loser;
00974     }
00975 
00976  loser:
00977     if (newOpt != NULL) {
00978         CRMF_DestroyPKIArchiveOptions(newOpt);
00979     }
00980     return NULL;
00981 }
00982 
00983 SECItem*
00984 CRMF_ControlGetRegTokenControlValue(CRMFControl *inControl)
00985 {
00986     PORT_Assert(inControl != NULL);
00987     if (inControl == NULL ||
00988        CRMF_ControlGetControlType(inControl) != crmfRegTokenControl) {
00989         return NULL;
00990     }
00991     return crmf_copy_control_value(inControl);;
00992 }
00993 
00994 CRMFCertExtension*
00995 CRMF_CertRequestGetExtensionAtIndex(CRMFCertRequest *inCertReq,
00996                                 int              index)
00997 {
00998     int numExtensions;
00999 
01000     PORT_Assert(inCertReq != NULL);
01001     numExtensions = CRMF_CertRequestGetNumberOfExtensions(inCertReq);
01002     if (index >= numExtensions || index < 0) {
01003         return NULL;
01004     }
01005     return 
01006       crmf_copy_cert_extension(NULL, 
01007                             inCertReq->certTemplate.extensions[index]);
01008 }
01009