Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions
crmfpop.c File Reference
#include "crmf.h"
#include "crmfi.h"
#include "secasn1.h"
#include "keyhi.h"
#include "cryptohi.h"

Go to the source code of this file.

Defines

#define CRMF_DEFAULT_ALLOC_SIZE   1024

Functions

SECStatus crmf_init_encoder_callback_arg (struct crmfEncoderArg *encoderArg, SECItem *derDest)
SECStatus CRMF_CertReqMsgSetRAVerifiedPOP (CRMFCertReqMsg *inCertReqMsg)
SECOidTag crmf_get_key_sign_tag (SECKEYPublicKey *inPubKey)
SECAlgorithmID * crmf_create_poposignkey_algid (PRArenaPool *poolp, SECKEYPublicKey *inPubKey)
static CRMFPOPOSigningKeyInput * crmf_create_poposigningkeyinput (PRArenaPool *poolp, CERTCertificate *inCert, CRMFMACPasswordCallback fn, void *arg)
void crmf_generic_encoder_callback (void *arg, const char *buf, unsigned long len, int depth, SEC_ASN1EncodingPart data_kind)
static SECStatus crmf_encode_certreq (CRMFCertRequest *inCertReq, SECItem *derDest)
static SECStatus crmf_sign_certreq (PRArenaPool *poolp, CRMFPOPOSigningKey *crmfSignKey, CRMFCertRequest *certReq, SECKEYPrivateKey *inKey, SECAlgorithmID *inAlgId)
static SECStatus crmf_create_poposignkey (PRArenaPool *poolp, CRMFCertReqMsg *inCertReqMsg, CRMFPOPOSigningKeyInput *signKeyInput, SECKEYPrivateKey *inPrivKey, SECAlgorithmID *inAlgID, CRMFPOPOSigningKey *signKey)
SECStatus CRMF_CertReqMsgSetSignaturePOP (CRMFCertReqMsg *inCertReqMsg, SECKEYPrivateKey *inPrivKey, SECKEYPublicKey *inPubKey, CERTCertificate *inCertForInput, CRMFMACPasswordCallback fn, void *arg)
static const SEC_ASN1Templatecrmf_get_popoprivkey_subtemplate (CRMFPOPOPrivKey *inPrivKey)
static SECStatus crmf_encode_popoprivkey (PRArenaPool *poolp, CRMFCertReqMsg *inCertReqMsg, CRMFPOPOPrivKey *popoPrivKey, const SEC_ASN1Template *privKeyTemplate)
static const SEC_ASN1Templatecrmf_get_template_for_privkey (CRMFPOPChoice inChoice)
static SECStatus crmf_add_privkey_thismessage (CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey, CRMFPOPChoice inChoice)
static SECStatus crmf_add_privkey_dhmac (CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac, CRMFPOPChoice inChoice)
static SECStatus crmf_add_privkey_subseqmessage (CRMFCertReqMsg *inCertReqMsg, CRMFSubseqMessOptions subsequentMessage, CRMFPOPChoice inChoice)
SECStatus CRMF_CertReqMsgSetKeyEnciphermentPOP (CRMFCertReqMsg *inCertReqMsg, CRMFPOPOPrivKeyChoice inKeyChoice, CRMFSubseqMessOptions subseqMess, SECItem *encPrivKey)
SECStatus CRMF_CertReqMsgSetKeyAgreementPOP (CRMFCertReqMsg *inCertReqMsg, CRMFPOPOPrivKeyChoice inKeyChoice, CRMFSubseqMessOptions subseqMess, SECItem *encPrivKey)

Define Documentation

Definition at line 45 of file crmfpop.c.


Function Documentation

static SECStatus crmf_add_privkey_dhmac ( CRMFCertReqMsg *  inCertReqMsg,
SECItem *  dhmac,
CRMFPOPChoice  inChoice 
) [static]

Definition at line 473 of file crmfpop.c.

{
    PRArenaPool           *poolp;
    void                  *mark;
    CRMFPOPOPrivKey       *popoPrivKey;
    CRMFProofOfPossession *pop;
    SECStatus              rv;

    PORT_Assert(inCertReqMsg != NULL && dhmac != NULL);
    poolp = inCertReqMsg->poolp;
    mark = PORT_ArenaMark(poolp);
    pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
    if (pop == NULL) {
        goto loser;
    }
    pop->popUsed = inChoice;
    popoPrivKey = &pop->popChoice.keyAgreement;

    rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.dhMAC),
                          dhmac);
    if (rv != SECSuccess) {
        goto loser;
    }
    popoPrivKey->message.dhMAC.len <<= 3;
    popoPrivKey->messageChoice = crmfDHMAC;
    inCertReqMsg->pop = pop;
    rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey,
                                 crmf_get_template_for_privkey(inChoice));
    if (rv != SECSuccess) {
        goto loser;
    }
    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;
    
 loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus crmf_add_privkey_subseqmessage ( CRMFCertReqMsg *  inCertReqMsg,
CRMFSubseqMessOptions  subsequentMessage,
CRMFPOPChoice  inChoice 
) [static]

Definition at line 514 of file crmfpop.c.

{
    void                  *mark;
    PRArenaPool           *poolp;
    CRMFProofOfPossession *pop;
    CRMFPOPOPrivKey       *popoPrivKey;
    SECStatus              rv;
    const SEC_ASN1Template *privKeyTemplate;

    if (subsequentMessage == crmfNoSubseqMess) {
        return SECFailure;
    }
    poolp = inCertReqMsg->poolp;
    mark = PORT_ArenaMark(poolp);
    pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
    if (pop == NULL) {
        goto loser;
    }

    pop->popUsed = inChoice;
    /* 
     * We have a union, so a pointer to one member of the union
     * is also a member to another member of that same union.
     */
    popoPrivKey = &pop->popChoice.keyEncipherment;

    switch (subsequentMessage) {
    case crmfEncrCert:
        rv = crmf_encode_integer(poolp, 
                             &(popoPrivKey->message.subsequentMessage),
                             0);
       break;
    case crmfChallengeResp:
        rv = crmf_encode_integer(poolp,
                             &(popoPrivKey->message.subsequentMessage),
                             1);
       break;
    default:
        goto loser;
    }
    if (rv != SECSuccess) {
        goto loser;
    }
    popoPrivKey->messageChoice = crmfSubsequentMessage;
    privKeyTemplate = crmf_get_template_for_privkey(inChoice);
    inCertReqMsg->pop = pop;
    rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey,
                             privKeyTemplate);

    if (rv != SECSuccess) {
        goto loser;
    }
    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;
 loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus crmf_add_privkey_thismessage ( CRMFCertReqMsg *  inCertReqMsg,
SECItem *  encPrivKey,
CRMFPOPChoice  inChoice 
) [static]

Definition at line 426 of file crmfpop.c.

{
    PRArenaPool           *poolp;
    void                  *mark;
    CRMFPOPOPrivKey       *popoPrivKey;
    CRMFProofOfPossession *pop;
    SECStatus              rv;

    PORT_Assert(inCertReqMsg != NULL && encPrivKey != NULL);
    poolp = inCertReqMsg->poolp;
    mark = PORT_ArenaMark(poolp);
    pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
    if (pop == NULL) {
        goto loser;
    }
    pop->popUsed = inChoice;
    /* popChoice is a union, so getting a pointer to one
     * field gives me a pointer to the other fields as
     * well.  This in essence points to both 
     * pop->popChoice.keyEncipherment and
     * pop->popChoice.keyAgreement
     */
    popoPrivKey = &pop->popChoice.keyEncipherment;

    rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.thisMessage),
                       encPrivKey);
    if (rv != SECSuccess) {
        goto loser;
    }
    popoPrivKey->message.thisMessage.len <<= 3;
    popoPrivKey->messageChoice = crmfThisMessage;
    inCertReqMsg->pop = pop;
    rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey,
                             crmf_get_template_for_privkey(inChoice));
    if (rv != SECSuccess) {
        goto loser;
    }
    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;
    
 loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CRMF_CertReqMsgSetKeyAgreementPOP ( CRMFCertReqMsg *  inCertReqMsg,
CRMFPOPOPrivKeyChoice  inKeyChoice,
CRMFSubseqMessOptions  subseqMess,
SECItem *  encPrivKey 
)

Definition at line 604 of file crmfpop.c.

{
    SECStatus rv;

    PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL);
    switch (inKeyChoice) {    
    case crmfThisMessage:
        rv = crmf_add_privkey_thismessage(inCertReqMsg, encPrivKey,
                                     crmfKeyAgreement);
       break;
    case crmfSubsequentMessage:
        rv = crmf_add_privkey_subseqmessage(inCertReqMsg, subseqMess, 
                                       crmfKeyAgreement);
       break;
    case crmfDHMAC:
        /* In this case encPrivKey should be the calculated dhMac
         * as specified in RFC 2511 */
        rv = crmf_add_privkey_dhmac(inCertReqMsg, encPrivKey,
                                    crmfKeyAgreement);
        break;
    default:
        rv = SECFailure;
    }
    return rv;
}
SECStatus CRMF_CertReqMsgSetKeyEnciphermentPOP ( CRMFCertReqMsg *  inCertReqMsg,
CRMFPOPOPrivKeyChoice  inKeyChoice,
CRMFSubseqMessOptions  subseqMess,
SECItem *  encPrivKey 
)

Definition at line 576 of file crmfpop.c.

{
    SECStatus rv;

    PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL);
    if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice) {
        return SECFailure;
    }
    switch (inKeyChoice) {    
    case crmfThisMessage:
        rv = crmf_add_privkey_thismessage(inCertReqMsg, encPrivKey,
                                     crmfKeyEncipherment);
       break;
    case crmfSubsequentMessage:
        rv = crmf_add_privkey_subseqmessage(inCertReqMsg, subseqMess, 
                                       crmfKeyEncipherment);
        break;
    case crmfDHMAC:
    default:
        rv = SECFailure;
    }
    return rv;
}
SECStatus CRMF_CertReqMsgSetRAVerifiedPOP ( CRMFCertReqMsg *  inCertReqMsg)

Definition at line 66 of file crmfpop.c.

{
    SECItem               *dummy;
    CRMFProofOfPossession *pop;
    PRArenaPool           *poolp;
    void                  *mark;

    PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL);
    poolp = inCertReqMsg->poolp;
    mark = PORT_ArenaMark(poolp);
    if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice) {
        return SECFailure;
    }
    pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
    if (pop == NULL) {
        goto loser;
    }
    pop->popUsed = crmfRAVerified;
    pop->popChoice.raVerified.data = NULL;
    pop->popChoice.raVerified.len  = 0;
    inCertReqMsg->pop = pop;
    dummy = SEC_ASN1EncodeItem(poolp, &(inCertReqMsg->derPOP),
                            &(pop->popChoice.raVerified),
                            CRMFRAVerifiedTemplate);
    return SECSuccess;
 loser:
    PORT_ArenaRelease(poolp, mark);
    return SECFailure;
}
SECStatus CRMF_CertReqMsgSetSignaturePOP ( CRMFCertReqMsg *  inCertReqMsg,
SECKEYPrivateKey *  inPrivKey,
SECKEYPublicKey *  inPubKey,
CERTCertificate *  inCertForInput,
CRMFMACPasswordCallback  fn,
void arg 
)

Definition at line 255 of file crmfpop.c.

{
    SECAlgorithmID  *algID;
    PRArenaPool     *poolp;
    SECItem          derTemp = {siBuffer, NULL, 0};
    void            *mark;
    SECStatus        rv;
    CRMFPOPOSigningKeyInput *signKeyInput = NULL;
    CRMFCertRequest         *certReq;
    CRMFProofOfPossession   *pop;
    struct crmfEncoderArg    encoderArg;

    PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL &&
              inCertReqMsg->pop == NULL);
    certReq = inCertReqMsg->certReq;
    if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice || 
       !CRMF_DoesRequestHaveField(certReq, crmfPublicKey)) {
        return SECFailure;
    } 
    poolp = inCertReqMsg->poolp;
    mark = PORT_ArenaMark(poolp);
    algID = crmf_create_poposignkey_algid(poolp, inPubKey);

    if(!CRMF_DoesRequestHaveField(certReq,crmfSubject)) {
        signKeyInput = crmf_create_poposigningkeyinput(poolp, inCertForInput,
                                                 fn, arg);
       if (signKeyInput == NULL) {
           goto loser;
       }
    }

    pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession);
    if (pop == NULL) {
        goto loser;
    }
    
    rv = crmf_create_poposignkey(poolp, inCertReqMsg, 
                             signKeyInput, inPrivKey, algID,
                             &(pop->popChoice.signature));
    if (rv != SECSuccess) {
        goto loser;
    }

    pop->popUsed = crmfSignature;
    pop->popChoice.signature.algorithmIdentifier = algID;
    inCertReqMsg->pop = pop;
  
    rv = crmf_init_encoder_callback_arg (&encoderArg, &derTemp);
    if (rv != SECSuccess) {
        goto loser;
    }
    rv = SEC_ASN1Encode(&pop->popChoice.signature, 
                     CRMFPOPOSigningKeyTemplate,
                     crmf_generic_encoder_callback, &encoderArg);
    if (rv != SECSuccess) {
        goto loser;
    }
    rv = SECITEM_CopyItem(poolp, &(inCertReqMsg->derPOP), &derTemp);
    if (rv != SECSuccess) {
        goto loser;
    }
    PORT_Free (derTemp.data);
    PORT_ArenaUnmark(poolp,mark);
    return SECSuccess;

 loser:
    PORT_ArenaRelease(poolp,mark);
    if (derTemp.data != NULL) {
        PORT_Free(derTemp.data);
    }
    return SECFailure;
}
static CRMFPOPOSigningKeyInput* crmf_create_poposigningkeyinput ( PRArenaPool poolp,
CERTCertificate *  inCert,
CRMFMACPasswordCallback  fn,
void arg 
) [static]

Definition at line 137 of file crmfpop.c.

{
  /* PSM isn't going to do this, so we'll fail here for now.*/
     return NULL;
}

Here is the caller graph for this function:

static SECStatus crmf_create_poposignkey ( PRArenaPool poolp,
CRMFCertReqMsg *  inCertReqMsg,
CRMFPOPOSigningKeyInput *  signKeyInput,
SECKEYPrivateKey *  inPrivKey,
SECAlgorithmID *  inAlgID,
CRMFPOPOSigningKey *  signKey 
) [static]

Definition at line 218 of file crmfpop.c.

{
    CRMFCertRequest    *certReq;
    void               *mark;
    PRBool              useSignKeyInput;
    SECStatus           rv;
    
    PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL);
    mark = PORT_ArenaMark(poolp);
    if (signKey == NULL) {
        goto loser;
    }
    certReq = inCertReqMsg->certReq;
    useSignKeyInput = !(CRMF_DoesRequestHaveField(certReq,crmfSubject)  &&
                     CRMF_DoesRequestHaveField(certReq,crmfPublicKey));

    if (useSignKeyInput) {
        goto loser; 
    } else {
        rv = crmf_sign_certreq(poolp, signKey, certReq,inPrivKey, inAlgID);
       if (rv != SECSuccess) {
           goto loser;
       }
    }
    PORT_ArenaUnmark(poolp,mark);
    return SECSuccess;
 loser:
    PORT_ArenaRelease(poolp,mark);
    return SECFailure;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECAlgorithmID* crmf_create_poposignkey_algid ( PRArenaPool poolp,
SECKEYPublicKey *  inPubKey 
)

Definition at line 108 of file crmfpop.c.

{
    SECAlgorithmID *algID;
    SECOidTag       tag;
    SECStatus       rv;
    void           *mark;

    mark = PORT_ArenaMark(poolp);
    algID = PORT_ArenaZNew(poolp, SECAlgorithmID);
    if (algID == NULL) {
        goto loser;
    }
    tag = crmf_get_key_sign_tag(inPubKey);
    if (tag == SEC_OID_UNKNOWN) {
        goto loser;
    }
    rv = SECOID_SetAlgorithmID(poolp, algID, tag, NULL);
    if (rv != SECSuccess) {
        goto loser;
    }
    PORT_ArenaUnmark(poolp, mark);
    return algID;
 loser:
    PORT_ArenaRelease(poolp, mark);
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus crmf_encode_certreq ( CRMFCertRequest *  inCertReq,
SECItem *  derDest 
) [static]

Definition at line 168 of file crmfpop.c.

{
    struct crmfEncoderArg encoderArg;
    SECStatus             rv;
  
    rv = crmf_init_encoder_callback_arg (&encoderArg, derDest);
    if (rv != SECSuccess) {
        return SECFailure;
    }
    return SEC_ASN1Encode(inCertReq, CRMFCertRequestTemplate, 
                       crmf_generic_encoder_callback, &encoderArg);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus crmf_encode_popoprivkey ( PRArenaPool poolp,
CRMFCertReqMsg *  inCertReqMsg,
CRMFPOPOPrivKey *  popoPrivKey,
const SEC_ASN1Template privKeyTemplate 
) [static]

Definition at line 355 of file crmfpop.c.

{
    struct crmfEncoderArg   encoderArg;
    SECItem                 derTemp; 
    SECStatus               rv;
    void                   *mark;
    const SEC_ASN1Template *subDerTemplate;

    mark = PORT_ArenaMark(poolp);
    rv = crmf_init_encoder_callback_arg(&encoderArg, &derTemp);
    if (rv != SECSuccess) {
        goto loser;
    }
    subDerTemplate = crmf_get_popoprivkey_subtemplate(popoPrivKey);
    /* We've got a union, so a pointer to one item is a pointer to 
     * all the items in the union.
     */
    rv = SEC_ASN1Encode(&popoPrivKey->message.thisMessage, 
                     subDerTemplate,
                     crmf_generic_encoder_callback, &encoderArg);
    if (rv != SECSuccess) {
        goto loser;
    }
    if (encoderArg.allocatedLen > derTemp.len+2) {
        void *dummy = PORT_Realloc(derTemp.data, derTemp.len+2);
       if (dummy == NULL) {
           goto loser;
       }
       derTemp.data = dummy;
    }
    PORT_Memmove(&derTemp.data[2], &derTemp.data[0], derTemp.len);
    /* I couldn't figure out how to get the ASN1 encoder to implicitly
     * tag an implicitly tagged der blob.  So I'm putting in the outter-
     * most tag myself. -javi
     */
    derTemp.data[0] = (unsigned char)privKeyTemplate->kind;
    derTemp.data[1] = (unsigned char)derTemp.len;
    derTemp.len += 2;
    rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derTemp);
    if (rv != SECSuccess) {
        goto loser;
    }
    PORT_Free(derTemp.data);
    PORT_ArenaUnmark(poolp, mark);
    return SECSuccess;
 loser:
    PORT_ArenaRelease(poolp, mark);
    if (derTemp.data) {
        PORT_Free(derTemp.data);
    }
    return SECFailure;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void crmf_generic_encoder_callback ( void arg,
const char *  buf,
unsigned long  len,
int  depth,
SEC_ASN1EncodingPart  data_kind 
)

Definition at line 145 of file crmfpop.c.

{
    struct crmfEncoderArg *encoderArg = (struct crmfEncoderArg*)arg;
    unsigned char *cursor;
    
   if (encoderArg->buffer->len + len > encoderArg->allocatedLen) {
        int newSize = encoderArg->buffer->len+CRMF_DEFAULT_ALLOC_SIZE;
        void *dummy = PORT_Realloc(encoderArg->buffer->data, newSize);
       if (dummy == NULL) {
           /* I really want to return an error code here */
           PORT_Assert(0);
           return;
       }
       encoderArg->buffer->data = dummy;
       encoderArg->allocatedLen = newSize;
    }
    cursor = &(encoderArg->buffer->data[encoderArg->buffer->len]);
    PORT_Memcpy (cursor, buf, len);
    encoderArg->buffer->len += len;    
}
SECOidTag crmf_get_key_sign_tag ( SECKEYPublicKey *  inPubKey)

Definition at line 97 of file crmfpop.c.

{
    /* maintain backward compatibility with older
     * implementations */
    if (inPubKey->keyType == rsaKey) {
        return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
    }
    return SEC_GetSignatureAlgorithmOidTag(inPubKey->keyType, SEC_OID_UNKNOWN);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static const SEC_ASN1Template* crmf_get_popoprivkey_subtemplate ( CRMFPOPOPrivKey *  inPrivKey) [static]

Definition at line 334 of file crmfpop.c.

{
    const SEC_ASN1Template *retTemplate = NULL;

    switch (inPrivKey->messageChoice) {
    case crmfThisMessage:
        retTemplate = CRMFThisMessageTemplate;
       break;
    case crmfSubsequentMessage:
        retTemplate = CRMFSubsequentMessageTemplate;
       break;
    case crmfDHMAC:
        retTemplate = CRMFDHMACTemplate;
       break;
    default:
        retTemplate = NULL;
    }
    return retTemplate;
}

Here is the caller graph for this function:

Definition at line 412 of file crmfpop.c.

{
    switch (inChoice) {
    case crmfKeyAgreement:
        return CRMFPOPOKeyAgreementTemplate;
    case crmfKeyEncipherment:
        return CRMFPOPOKeyEnciphermentTemplate;
    default:
        break;
    }
    return NULL;
}

Here is the caller graph for this function:

SECStatus crmf_init_encoder_callback_arg ( struct crmfEncoderArg encoderArg,
SECItem *  derDest 
)

Definition at line 48 of file crmfpop.c.

{
    derDest->data = PORT_ZNewArray(unsigned char, CRMF_DEFAULT_ALLOC_SIZE);
    if (derDest->data == NULL) {
        return SECFailure;
    }
    derDest->len = 0;
    encoderArg->allocatedLen = CRMF_DEFAULT_ALLOC_SIZE;
    encoderArg->buffer = derDest;
    return SECSuccess;

}
static SECStatus crmf_sign_certreq ( PRArenaPool poolp,
CRMFPOPOSigningKey *  crmfSignKey,
CRMFCertRequest *  certReq,
SECKEYPrivateKey *  inKey,
SECAlgorithmID *  inAlgId 
) [static]

Definition at line 182 of file crmfpop.c.

{
    SECItem                      derCertReq = { siBuffer, NULL, 0 };
    SECItem                      certReqSig = { siBuffer, NULL, 0 };
    SECStatus                    rv = SECSuccess;

    rv = crmf_encode_certreq(certReq, &derCertReq);
    if (rv != SECSuccess) {
       goto loser;
    }
    rv = SEC_SignData(&certReqSig, derCertReq.data, derCertReq.len,
                    inKey,SECOID_GetAlgorithmTag(inAlgId));
    if (rv != SECSuccess) {
        goto loser;
    }
 
    /* Now make it a part of the POPOSigningKey */
    rv = SECITEM_CopyItem(poolp, &(crmfSignKey->signature), &certReqSig);
    /* Convert this length to number of bits */
    crmfSignKey->signature.len <<= 3; 
   
 loser:
    if (derCertReq.data != NULL) {
        PORT_Free(derCertReq.data);
    }
    if (certReqSig.data != NULL) {
        PORT_Free(certReqSig.data);
    }
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function: