mirror of
https://github.com/rn10950/RetroZilla.git
synced 2024-11-11 10:20:19 +01:00
44b7f056d9
bug1001332, 56b691c003ad, bug1086145, bug1054069, bug1155922, bug991783, bug1125025, bug1162521, bug1162644, bug1132941, bug1164364, bug1166205, bug1166163, bug1166515, bug1138554, bug1167046, bug1167043, bug1169451, bug1172128, bug1170322, bug102794, bug1128184, bug557830, bug1174648, bug1180244, bug1177784, bug1173413, bug1169174, bug1084669, bug951455, bug1183395, bug1177430, bug1183827, bug1160139, bug1154106, bug1142209, bug1185033, bug1193467, bug1182667(with sha512 changes backed out, which breaks VC6 compilation), bug1158489, bug337796
600 lines
17 KiB
C
600 lines
17 KiB
C
/* -*- Mode: C; tab-width: 8 -*-*/
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
#include "crmf.h"
|
|
#include "crmfi.h"
|
|
#include "secasn1.h"
|
|
#include "keyhi.h"
|
|
#include "cryptohi.h"
|
|
|
|
#define CRMF_DEFAULT_ALLOC_SIZE 1024U
|
|
|
|
SECStatus
|
|
crmf_init_encoder_callback_arg (struct crmfEncoderArg *encoderArg,
|
|
SECItem *derDest)
|
|
{
|
|
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;
|
|
|
|
}
|
|
|
|
/* Caller should release or unmark the pool, instead of doing it here.
|
|
** But there are NO callers of this function at present...
|
|
*/
|
|
SECStatus
|
|
CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg)
|
|
{
|
|
CRMFProofOfPossession *pop;
|
|
PLArenaPool *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;
|
|
(void)SEC_ASN1EncodeItem(poolp, &(inCertReqMsg->derPOP),
|
|
&(pop->popChoice.raVerified),
|
|
CRMFRAVerifiedTemplate);
|
|
return SECSuccess;
|
|
loser:
|
|
PORT_ArenaRelease(poolp, mark);
|
|
return SECFailure;
|
|
}
|
|
|
|
static SECOidTag
|
|
crmf_get_key_sign_tag(SECKEYPublicKey *inPubKey)
|
|
{
|
|
/* 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);
|
|
}
|
|
|
|
static SECAlgorithmID*
|
|
crmf_create_poposignkey_algid(PLArenaPool *poolp,
|
|
SECKEYPublicKey *inPubKey)
|
|
{
|
|
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;
|
|
}
|
|
|
|
static CRMFPOPOSigningKeyInput*
|
|
crmf_create_poposigningkeyinput(PLArenaPool *poolp, CERTCertificate *inCert,
|
|
CRMFMACPasswordCallback fn, void *arg)
|
|
{
|
|
/* PSM isn't going to do this, so we'll fail here for now.*/
|
|
return NULL;
|
|
}
|
|
|
|
void
|
|
crmf_generic_encoder_callback(void *arg, const char* buf, unsigned long len,
|
|
int depth, SEC_ASN1EncodingPart data_kind)
|
|
{
|
|
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;
|
|
}
|
|
|
|
static SECStatus
|
|
crmf_encode_certreq(CRMFCertRequest *inCertReq, SECItem *derDest)
|
|
{
|
|
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);
|
|
}
|
|
|
|
static SECStatus
|
|
crmf_sign_certreq(PLArenaPool *poolp,
|
|
CRMFPOPOSigningKey *crmfSignKey,
|
|
CRMFCertRequest *certReq,
|
|
SECKEYPrivateKey *inKey,
|
|
SECAlgorithmID *inAlgId)
|
|
{
|
|
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;
|
|
}
|
|
|
|
static SECStatus
|
|
crmf_create_poposignkey(PLArenaPool *poolp,
|
|
CRMFCertReqMsg *inCertReqMsg,
|
|
CRMFPOPOSigningKeyInput *signKeyInput,
|
|
SECKEYPrivateKey *inPrivKey,
|
|
SECAlgorithmID *inAlgID,
|
|
CRMFPOPOSigningKey *signKey)
|
|
{
|
|
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;
|
|
}
|
|
|
|
SECStatus
|
|
CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg,
|
|
SECKEYPrivateKey *inPrivKey,
|
|
SECKEYPublicKey *inPubKey,
|
|
CERTCertificate *inCertForInput,
|
|
CRMFMACPasswordCallback fn,
|
|
void *arg)
|
|
{
|
|
SECAlgorithmID *algID;
|
|
PLArenaPool *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 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 SECStatus
|
|
crmf_encode_popoprivkey(PLArenaPool *poolp,
|
|
CRMFCertReqMsg *inCertReqMsg,
|
|
CRMFPOPOPrivKey *popoPrivKey,
|
|
const SEC_ASN1Template *privKeyTemplate)
|
|
{
|
|
struct crmfEncoderArg encoderArg;
|
|
SECItem derTemp = { siBuffer, NULL, 0 };
|
|
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;
|
|
}
|
|
|
|
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 SECStatus
|
|
crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey,
|
|
CRMFPOPChoice inChoice)
|
|
{
|
|
PLArenaPool *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 SECStatus
|
|
crmf_add_privkey_dhmac(CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac,
|
|
CRMFPOPChoice inChoice)
|
|
{
|
|
PLArenaPool *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;
|
|
}
|
|
|
|
static SECStatus
|
|
crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg,
|
|
CRMFSubseqMessOptions subsequentMessage,
|
|
CRMFPOPChoice inChoice)
|
|
{
|
|
void *mark;
|
|
PLArenaPool *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);
|
|
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;
|
|
}
|
|
|