crmfpop.c

来自「支持SSL v2/v3, TLS, PKCS #5, PKCS #7, PKCS」· C语言 代码 · 共 605 行 · 第 1/2 页

C
605
字号
	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, &derDest);    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), &derDest);    PORT_Free (derDest.data);    if (rv != SECSuccess) {        goto loser;    }    PORT_ArenaUnmark(poolp,mark);    return SECSuccess; loser:    PORT_ArenaRelease(poolp,mark);    if (derDest.data != NULL) {        PORT_Free(derDest.data);    }    return SECFailure;}static const SEC_ASN1Template*crmf_get_popoprivkey_subtemplate(CRMFPOPOPrivKey *inPrivKey) {    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;}static SECStatuscrmf_encode_popoprivkey(PRArenaPool            *poolp, 			CRMFCertReqMsg         *inCertReqMsg,			CRMFPOPOPrivKey        *popoPrivKey,			const SEC_ASN1Template *privKeyTemplate){    struct crmfEncoderArg   encoderArg;    SECItem                 derDest;     SECStatus               rv;    void                   *mark;    const SEC_ASN1Template *subDerTemplate;    mark = PORT_ArenaMark(poolp);    rv = crmf_init_encoder_callback_arg(&encoderArg, &derDest);    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 > derDest.len+2) {        void *dummy = PORT_Realloc(derDest.data, derDest.len+2);	if (dummy == NULL) {	    goto loser;	}	derDest.data = dummy;    }    PORT_Memmove(&derDest.data[2], &derDest.data[0], derDest.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     */    derDest.data[0] = (unsigned char)privKeyTemplate->kind;    derDest.data[1] = (unsigned char)derDest.len;    derDest.len += 2;    rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derDest);    if (rv != SECSuccess) {        goto loser;    }    PORT_Free(derDest.data);    PORT_ArenaUnmark(poolp, mark);    return SECSuccess; loser:    PORT_ArenaRelease(poolp, mark);    if (derDest.data) {        PORT_Free(derDest.data);    }    return SECFailure;}static const SEC_ASN1Template*crmf_get_template_for_privkey(CRMFPOPChoice inChoice) {    switch (inChoice) {    case crmfKeyAgreement:        return CRMFPOPOKeyAgreementTemplate;    case crmfKeyEncipherment:        return CRMFPOPOKeyEnciphermentTemplate;    default:        break;    }    return NULL;}static SECStatuscrmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey,			     CRMFPOPChoice inChoice){    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;}static SECStatuscrmf_add_privkey_subseqmessage(CRMFCertReqMsg        *inCertReqMsg,			       CRMFSubseqMessOptions  subsequentMessage,			       CRMFPOPChoice          inChoice){    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;}SECStatus CRMF_CertReqMsgSetKeyEnciphermentPOP(CRMFCertReqMsg        *inCertReqMsg,				     CRMFPOPOPrivKeyChoice  inKeyChoice,				     CRMFSubseqMessOptions  subseqMess,				     SECItem               *encPrivKey){    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_CertReqMsgSetKeyAgreementPOP (CRMFCertReqMsg        *inCertReqMsg,				   CRMFPOPOPrivKeyChoice  inKeyChoice,				   CRMFSubseqMessOptions  subseqMess,				   SECItem               *encPrivKey){    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);    case crmfDHMAC:        /* This case should be added in the future. */    default:        rv = SECFailure;    }    return rv;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?