1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/crmf/crmfpop.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,600 @@ 1.4 +/* -*- Mode: C; tab-width: 8 -*-*/ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 + 1.10 +#include "crmf.h" 1.11 +#include "crmfi.h" 1.12 +#include "secasn1.h" 1.13 +#include "keyhi.h" 1.14 +#include "cryptohi.h" 1.15 + 1.16 +#define CRMF_DEFAULT_ALLOC_SIZE 1024 1.17 + 1.18 +SECStatus 1.19 +crmf_init_encoder_callback_arg (struct crmfEncoderArg *encoderArg, 1.20 + SECItem *derDest) 1.21 +{ 1.22 + derDest->data = PORT_ZNewArray(unsigned char, CRMF_DEFAULT_ALLOC_SIZE); 1.23 + if (derDest->data == NULL) { 1.24 + return SECFailure; 1.25 + } 1.26 + derDest->len = 0; 1.27 + encoderArg->allocatedLen = CRMF_DEFAULT_ALLOC_SIZE; 1.28 + encoderArg->buffer = derDest; 1.29 + return SECSuccess; 1.30 + 1.31 +} 1.32 + 1.33 +/* Caller should release or unmark the pool, instead of doing it here. 1.34 +** But there are NO callers of this function at present... 1.35 +*/ 1.36 +SECStatus 1.37 +CRMF_CertReqMsgSetRAVerifiedPOP(CRMFCertReqMsg *inCertReqMsg) 1.38 +{ 1.39 + SECItem *dummy; 1.40 + CRMFProofOfPossession *pop; 1.41 + PLArenaPool *poolp; 1.42 + void *mark; 1.43 + 1.44 + PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL); 1.45 + poolp = inCertReqMsg->poolp; 1.46 + mark = PORT_ArenaMark(poolp); 1.47 + if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice) { 1.48 + return SECFailure; 1.49 + } 1.50 + pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); 1.51 + if (pop == NULL) { 1.52 + goto loser; 1.53 + } 1.54 + pop->popUsed = crmfRAVerified; 1.55 + pop->popChoice.raVerified.data = NULL; 1.56 + pop->popChoice.raVerified.len = 0; 1.57 + inCertReqMsg->pop = pop; 1.58 + dummy = SEC_ASN1EncodeItem(poolp, &(inCertReqMsg->derPOP), 1.59 + &(pop->popChoice.raVerified), 1.60 + CRMFRAVerifiedTemplate); 1.61 + return SECSuccess; 1.62 + loser: 1.63 + PORT_ArenaRelease(poolp, mark); 1.64 + return SECFailure; 1.65 +} 1.66 + 1.67 +static SECOidTag 1.68 +crmf_get_key_sign_tag(SECKEYPublicKey *inPubKey) 1.69 +{ 1.70 + /* maintain backward compatibility with older 1.71 + * implementations */ 1.72 + if (inPubKey->keyType == rsaKey) { 1.73 + return SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; 1.74 + } 1.75 + return SEC_GetSignatureAlgorithmOidTag(inPubKey->keyType, SEC_OID_UNKNOWN); 1.76 +} 1.77 + 1.78 +static SECAlgorithmID* 1.79 +crmf_create_poposignkey_algid(PLArenaPool *poolp, 1.80 + SECKEYPublicKey *inPubKey) 1.81 +{ 1.82 + SECAlgorithmID *algID; 1.83 + SECOidTag tag; 1.84 + SECStatus rv; 1.85 + void *mark; 1.86 + 1.87 + mark = PORT_ArenaMark(poolp); 1.88 + algID = PORT_ArenaZNew(poolp, SECAlgorithmID); 1.89 + if (algID == NULL) { 1.90 + goto loser; 1.91 + } 1.92 + tag = crmf_get_key_sign_tag(inPubKey); 1.93 + if (tag == SEC_OID_UNKNOWN) { 1.94 + goto loser; 1.95 + } 1.96 + rv = SECOID_SetAlgorithmID(poolp, algID, tag, NULL); 1.97 + if (rv != SECSuccess) { 1.98 + goto loser; 1.99 + } 1.100 + PORT_ArenaUnmark(poolp, mark); 1.101 + return algID; 1.102 + loser: 1.103 + PORT_ArenaRelease(poolp, mark); 1.104 + return NULL; 1.105 +} 1.106 + 1.107 +static CRMFPOPOSigningKeyInput* 1.108 +crmf_create_poposigningkeyinput(PLArenaPool *poolp, CERTCertificate *inCert, 1.109 + CRMFMACPasswordCallback fn, void *arg) 1.110 +{ 1.111 + /* PSM isn't going to do this, so we'll fail here for now.*/ 1.112 + return NULL; 1.113 +} 1.114 + 1.115 +void 1.116 +crmf_generic_encoder_callback(void *arg, const char* buf, unsigned long len, 1.117 + int depth, SEC_ASN1EncodingPart data_kind) 1.118 +{ 1.119 + struct crmfEncoderArg *encoderArg = (struct crmfEncoderArg*)arg; 1.120 + unsigned char *cursor; 1.121 + 1.122 + if (encoderArg->buffer->len + len > encoderArg->allocatedLen) { 1.123 + int newSize = encoderArg->buffer->len+CRMF_DEFAULT_ALLOC_SIZE; 1.124 + void *dummy = PORT_Realloc(encoderArg->buffer->data, newSize); 1.125 + if (dummy == NULL) { 1.126 + /* I really want to return an error code here */ 1.127 + PORT_Assert(0); 1.128 + return; 1.129 + } 1.130 + encoderArg->buffer->data = dummy; 1.131 + encoderArg->allocatedLen = newSize; 1.132 + } 1.133 + cursor = &(encoderArg->buffer->data[encoderArg->buffer->len]); 1.134 + PORT_Memcpy (cursor, buf, len); 1.135 + encoderArg->buffer->len += len; 1.136 +} 1.137 + 1.138 +static SECStatus 1.139 +crmf_encode_certreq(CRMFCertRequest *inCertReq, SECItem *derDest) 1.140 +{ 1.141 + struct crmfEncoderArg encoderArg; 1.142 + SECStatus rv; 1.143 + 1.144 + rv = crmf_init_encoder_callback_arg (&encoderArg, derDest); 1.145 + if (rv != SECSuccess) { 1.146 + return SECFailure; 1.147 + } 1.148 + return SEC_ASN1Encode(inCertReq, CRMFCertRequestTemplate, 1.149 + crmf_generic_encoder_callback, &encoderArg); 1.150 +} 1.151 + 1.152 +static SECStatus 1.153 +crmf_sign_certreq(PLArenaPool *poolp, 1.154 + CRMFPOPOSigningKey *crmfSignKey, 1.155 + CRMFCertRequest *certReq, 1.156 + SECKEYPrivateKey *inKey, 1.157 + SECAlgorithmID *inAlgId) 1.158 +{ 1.159 + SECItem derCertReq = { siBuffer, NULL, 0 }; 1.160 + SECItem certReqSig = { siBuffer, NULL, 0 }; 1.161 + SECStatus rv = SECSuccess; 1.162 + 1.163 + rv = crmf_encode_certreq(certReq, &derCertReq); 1.164 + if (rv != SECSuccess) { 1.165 + goto loser; 1.166 + } 1.167 + rv = SEC_SignData(&certReqSig, derCertReq.data, derCertReq.len, 1.168 + inKey,SECOID_GetAlgorithmTag(inAlgId)); 1.169 + if (rv != SECSuccess) { 1.170 + goto loser; 1.171 + } 1.172 + 1.173 + /* Now make it a part of the POPOSigningKey */ 1.174 + rv = SECITEM_CopyItem(poolp, &(crmfSignKey->signature), &certReqSig); 1.175 + /* Convert this length to number of bits */ 1.176 + crmfSignKey->signature.len <<= 3; 1.177 + 1.178 + loser: 1.179 + if (derCertReq.data != NULL) { 1.180 + PORT_Free(derCertReq.data); 1.181 + } 1.182 + if (certReqSig.data != NULL) { 1.183 + PORT_Free(certReqSig.data); 1.184 + } 1.185 + return rv; 1.186 +} 1.187 + 1.188 +static SECStatus 1.189 +crmf_create_poposignkey(PLArenaPool *poolp, 1.190 + CRMFCertReqMsg *inCertReqMsg, 1.191 + CRMFPOPOSigningKeyInput *signKeyInput, 1.192 + SECKEYPrivateKey *inPrivKey, 1.193 + SECAlgorithmID *inAlgID, 1.194 + CRMFPOPOSigningKey *signKey) 1.195 +{ 1.196 + CRMFCertRequest *certReq; 1.197 + void *mark; 1.198 + PRBool useSignKeyInput; 1.199 + SECStatus rv; 1.200 + 1.201 + PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL); 1.202 + mark = PORT_ArenaMark(poolp); 1.203 + if (signKey == NULL) { 1.204 + goto loser; 1.205 + } 1.206 + certReq = inCertReqMsg->certReq; 1.207 + useSignKeyInput = !(CRMF_DoesRequestHaveField(certReq,crmfSubject) && 1.208 + CRMF_DoesRequestHaveField(certReq,crmfPublicKey)); 1.209 + 1.210 + if (useSignKeyInput) { 1.211 + goto loser; 1.212 + } else { 1.213 + rv = crmf_sign_certreq(poolp, signKey, certReq,inPrivKey, inAlgID); 1.214 + if (rv != SECSuccess) { 1.215 + goto loser; 1.216 + } 1.217 + } 1.218 + PORT_ArenaUnmark(poolp,mark); 1.219 + return SECSuccess; 1.220 + loser: 1.221 + PORT_ArenaRelease(poolp,mark); 1.222 + return SECFailure; 1.223 +} 1.224 + 1.225 +SECStatus 1.226 +CRMF_CertReqMsgSetSignaturePOP(CRMFCertReqMsg *inCertReqMsg, 1.227 + SECKEYPrivateKey *inPrivKey, 1.228 + SECKEYPublicKey *inPubKey, 1.229 + CERTCertificate *inCertForInput, 1.230 + CRMFMACPasswordCallback fn, 1.231 + void *arg) 1.232 +{ 1.233 + SECAlgorithmID *algID; 1.234 + PLArenaPool *poolp; 1.235 + SECItem derTemp = {siBuffer, NULL, 0}; 1.236 + void *mark; 1.237 + SECStatus rv; 1.238 + CRMFPOPOSigningKeyInput *signKeyInput = NULL; 1.239 + CRMFCertRequest *certReq; 1.240 + CRMFProofOfPossession *pop; 1.241 + struct crmfEncoderArg encoderArg; 1.242 + 1.243 + PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->certReq != NULL && 1.244 + inCertReqMsg->pop == NULL); 1.245 + certReq = inCertReqMsg->certReq; 1.246 + if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice || 1.247 + !CRMF_DoesRequestHaveField(certReq, crmfPublicKey)) { 1.248 + return SECFailure; 1.249 + } 1.250 + poolp = inCertReqMsg->poolp; 1.251 + mark = PORT_ArenaMark(poolp); 1.252 + algID = crmf_create_poposignkey_algid(poolp, inPubKey); 1.253 + 1.254 + if(!CRMF_DoesRequestHaveField(certReq,crmfSubject)) { 1.255 + signKeyInput = crmf_create_poposigningkeyinput(poolp, inCertForInput, 1.256 + fn, arg); 1.257 + if (signKeyInput == NULL) { 1.258 + goto loser; 1.259 + } 1.260 + } 1.261 + 1.262 + pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); 1.263 + if (pop == NULL) { 1.264 + goto loser; 1.265 + } 1.266 + 1.267 + rv = crmf_create_poposignkey(poolp, inCertReqMsg, 1.268 + signKeyInput, inPrivKey, algID, 1.269 + &(pop->popChoice.signature)); 1.270 + if (rv != SECSuccess) { 1.271 + goto loser; 1.272 + } 1.273 + 1.274 + pop->popUsed = crmfSignature; 1.275 + pop->popChoice.signature.algorithmIdentifier = algID; 1.276 + inCertReqMsg->pop = pop; 1.277 + 1.278 + rv = crmf_init_encoder_callback_arg (&encoderArg, &derTemp); 1.279 + if (rv != SECSuccess) { 1.280 + goto loser; 1.281 + } 1.282 + rv = SEC_ASN1Encode(&pop->popChoice.signature, 1.283 + CRMFPOPOSigningKeyTemplate, 1.284 + crmf_generic_encoder_callback, &encoderArg); 1.285 + if (rv != SECSuccess) { 1.286 + goto loser; 1.287 + } 1.288 + rv = SECITEM_CopyItem(poolp, &(inCertReqMsg->derPOP), &derTemp); 1.289 + if (rv != SECSuccess) { 1.290 + goto loser; 1.291 + } 1.292 + PORT_Free (derTemp.data); 1.293 + PORT_ArenaUnmark(poolp,mark); 1.294 + return SECSuccess; 1.295 + 1.296 + loser: 1.297 + PORT_ArenaRelease(poolp,mark); 1.298 + if (derTemp.data != NULL) { 1.299 + PORT_Free(derTemp.data); 1.300 + } 1.301 + return SECFailure; 1.302 +} 1.303 + 1.304 +static const SEC_ASN1Template* 1.305 +crmf_get_popoprivkey_subtemplate(CRMFPOPOPrivKey *inPrivKey) 1.306 +{ 1.307 + const SEC_ASN1Template *retTemplate = NULL; 1.308 + 1.309 + switch (inPrivKey->messageChoice) { 1.310 + case crmfThisMessage: 1.311 + retTemplate = CRMFThisMessageTemplate; 1.312 + break; 1.313 + case crmfSubsequentMessage: 1.314 + retTemplate = CRMFSubsequentMessageTemplate; 1.315 + break; 1.316 + case crmfDHMAC: 1.317 + retTemplate = CRMFDHMACTemplate; 1.318 + break; 1.319 + default: 1.320 + retTemplate = NULL; 1.321 + } 1.322 + return retTemplate; 1.323 +} 1.324 + 1.325 +static SECStatus 1.326 +crmf_encode_popoprivkey(PLArenaPool *poolp, 1.327 + CRMFCertReqMsg *inCertReqMsg, 1.328 + CRMFPOPOPrivKey *popoPrivKey, 1.329 + const SEC_ASN1Template *privKeyTemplate) 1.330 +{ 1.331 + struct crmfEncoderArg encoderArg; 1.332 + SECItem derTemp = { siBuffer, NULL, 0 }; 1.333 + SECStatus rv; 1.334 + void *mark; 1.335 + const SEC_ASN1Template *subDerTemplate; 1.336 + 1.337 + mark = PORT_ArenaMark(poolp); 1.338 + rv = crmf_init_encoder_callback_arg(&encoderArg, &derTemp); 1.339 + if (rv != SECSuccess) { 1.340 + goto loser; 1.341 + } 1.342 + subDerTemplate = crmf_get_popoprivkey_subtemplate(popoPrivKey); 1.343 + /* We've got a union, so a pointer to one item is a pointer to 1.344 + * all the items in the union. 1.345 + */ 1.346 + rv = SEC_ASN1Encode(&popoPrivKey->message.thisMessage, 1.347 + subDerTemplate, 1.348 + crmf_generic_encoder_callback, &encoderArg); 1.349 + if (rv != SECSuccess) { 1.350 + goto loser; 1.351 + } 1.352 + if (encoderArg.allocatedLen > derTemp.len+2) { 1.353 + void *dummy = PORT_Realloc(derTemp.data, derTemp.len+2); 1.354 + if (dummy == NULL) { 1.355 + goto loser; 1.356 + } 1.357 + derTemp.data = dummy; 1.358 + } 1.359 + PORT_Memmove(&derTemp.data[2], &derTemp.data[0], derTemp.len); 1.360 + /* I couldn't figure out how to get the ASN1 encoder to implicitly 1.361 + * tag an implicitly tagged der blob. So I'm putting in the outter- 1.362 + * most tag myself. -javi 1.363 + */ 1.364 + derTemp.data[0] = (unsigned char)privKeyTemplate->kind; 1.365 + derTemp.data[1] = (unsigned char)derTemp.len; 1.366 + derTemp.len += 2; 1.367 + rv = SECITEM_CopyItem(poolp, &inCertReqMsg->derPOP, &derTemp); 1.368 + if (rv != SECSuccess) { 1.369 + goto loser; 1.370 + } 1.371 + PORT_Free(derTemp.data); 1.372 + PORT_ArenaUnmark(poolp, mark); 1.373 + return SECSuccess; 1.374 + loser: 1.375 + PORT_ArenaRelease(poolp, mark); 1.376 + if (derTemp.data) { 1.377 + PORT_Free(derTemp.data); 1.378 + } 1.379 + return SECFailure; 1.380 +} 1.381 + 1.382 +static const SEC_ASN1Template* 1.383 +crmf_get_template_for_privkey(CRMFPOPChoice inChoice) 1.384 +{ 1.385 + switch (inChoice) { 1.386 + case crmfKeyAgreement: 1.387 + return CRMFPOPOKeyAgreementTemplate; 1.388 + case crmfKeyEncipherment: 1.389 + return CRMFPOPOKeyEnciphermentTemplate; 1.390 + default: 1.391 + break; 1.392 + } 1.393 + return NULL; 1.394 +} 1.395 + 1.396 +static SECStatus 1.397 +crmf_add_privkey_thismessage(CRMFCertReqMsg *inCertReqMsg, SECItem *encPrivKey, 1.398 + CRMFPOPChoice inChoice) 1.399 +{ 1.400 + PLArenaPool *poolp; 1.401 + void *mark; 1.402 + CRMFPOPOPrivKey *popoPrivKey; 1.403 + CRMFProofOfPossession *pop; 1.404 + SECStatus rv; 1.405 + 1.406 + PORT_Assert(inCertReqMsg != NULL && encPrivKey != NULL); 1.407 + poolp = inCertReqMsg->poolp; 1.408 + mark = PORT_ArenaMark(poolp); 1.409 + pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); 1.410 + if (pop == NULL) { 1.411 + goto loser; 1.412 + } 1.413 + pop->popUsed = inChoice; 1.414 + /* popChoice is a union, so getting a pointer to one 1.415 + * field gives me a pointer to the other fields as 1.416 + * well. This in essence points to both 1.417 + * pop->popChoice.keyEncipherment and 1.418 + * pop->popChoice.keyAgreement 1.419 + */ 1.420 + popoPrivKey = &pop->popChoice.keyEncipherment; 1.421 + 1.422 + rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.thisMessage), 1.423 + encPrivKey); 1.424 + if (rv != SECSuccess) { 1.425 + goto loser; 1.426 + } 1.427 + popoPrivKey->message.thisMessage.len <<= 3; 1.428 + popoPrivKey->messageChoice = crmfThisMessage; 1.429 + inCertReqMsg->pop = pop; 1.430 + rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey, 1.431 + crmf_get_template_for_privkey(inChoice)); 1.432 + if (rv != SECSuccess) { 1.433 + goto loser; 1.434 + } 1.435 + PORT_ArenaUnmark(poolp, mark); 1.436 + return SECSuccess; 1.437 + 1.438 + loser: 1.439 + PORT_ArenaRelease(poolp, mark); 1.440 + return SECFailure; 1.441 +} 1.442 + 1.443 +static SECStatus 1.444 +crmf_add_privkey_dhmac(CRMFCertReqMsg *inCertReqMsg, SECItem *dhmac, 1.445 + CRMFPOPChoice inChoice) 1.446 +{ 1.447 + PLArenaPool *poolp; 1.448 + void *mark; 1.449 + CRMFPOPOPrivKey *popoPrivKey; 1.450 + CRMFProofOfPossession *pop; 1.451 + SECStatus rv; 1.452 + 1.453 + PORT_Assert(inCertReqMsg != NULL && dhmac != NULL); 1.454 + poolp = inCertReqMsg->poolp; 1.455 + mark = PORT_ArenaMark(poolp); 1.456 + pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); 1.457 + if (pop == NULL) { 1.458 + goto loser; 1.459 + } 1.460 + pop->popUsed = inChoice; 1.461 + popoPrivKey = &pop->popChoice.keyAgreement; 1.462 + 1.463 + rv = SECITEM_CopyItem(poolp, &(popoPrivKey->message.dhMAC), 1.464 + dhmac); 1.465 + if (rv != SECSuccess) { 1.466 + goto loser; 1.467 + } 1.468 + popoPrivKey->message.dhMAC.len <<= 3; 1.469 + popoPrivKey->messageChoice = crmfDHMAC; 1.470 + inCertReqMsg->pop = pop; 1.471 + rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey, 1.472 + crmf_get_template_for_privkey(inChoice)); 1.473 + if (rv != SECSuccess) { 1.474 + goto loser; 1.475 + } 1.476 + PORT_ArenaUnmark(poolp, mark); 1.477 + return SECSuccess; 1.478 + 1.479 + loser: 1.480 + PORT_ArenaRelease(poolp, mark); 1.481 + return SECFailure; 1.482 +} 1.483 + 1.484 +static SECStatus 1.485 +crmf_add_privkey_subseqmessage(CRMFCertReqMsg *inCertReqMsg, 1.486 + CRMFSubseqMessOptions subsequentMessage, 1.487 + CRMFPOPChoice inChoice) 1.488 +{ 1.489 + void *mark; 1.490 + PLArenaPool *poolp; 1.491 + CRMFProofOfPossession *pop; 1.492 + CRMFPOPOPrivKey *popoPrivKey; 1.493 + SECStatus rv; 1.494 + const SEC_ASN1Template *privKeyTemplate; 1.495 + 1.496 + if (subsequentMessage == crmfNoSubseqMess) { 1.497 + return SECFailure; 1.498 + } 1.499 + poolp = inCertReqMsg->poolp; 1.500 + mark = PORT_ArenaMark(poolp); 1.501 + pop = PORT_ArenaZNew(poolp, CRMFProofOfPossession); 1.502 + if (pop == NULL) { 1.503 + goto loser; 1.504 + } 1.505 + 1.506 + pop->popUsed = inChoice; 1.507 + /* 1.508 + * We have a union, so a pointer to one member of the union 1.509 + * is also a member to another member of that same union. 1.510 + */ 1.511 + popoPrivKey = &pop->popChoice.keyEncipherment; 1.512 + 1.513 + switch (subsequentMessage) { 1.514 + case crmfEncrCert: 1.515 + rv = crmf_encode_integer(poolp, 1.516 + &(popoPrivKey->message.subsequentMessage), 1.517 + 0); 1.518 + break; 1.519 + case crmfChallengeResp: 1.520 + rv = crmf_encode_integer(poolp, 1.521 + &(popoPrivKey->message.subsequentMessage), 1.522 + 1); 1.523 + break; 1.524 + default: 1.525 + goto loser; 1.526 + } 1.527 + if (rv != SECSuccess) { 1.528 + goto loser; 1.529 + } 1.530 + popoPrivKey->messageChoice = crmfSubsequentMessage; 1.531 + privKeyTemplate = crmf_get_template_for_privkey(inChoice); 1.532 + inCertReqMsg->pop = pop; 1.533 + rv = crmf_encode_popoprivkey(poolp, inCertReqMsg, popoPrivKey, 1.534 + privKeyTemplate); 1.535 + 1.536 + if (rv != SECSuccess) { 1.537 + goto loser; 1.538 + } 1.539 + PORT_ArenaUnmark(poolp, mark); 1.540 + return SECSuccess; 1.541 + loser: 1.542 + PORT_ArenaRelease(poolp, mark); 1.543 + return SECFailure; 1.544 +} 1.545 + 1.546 +SECStatus 1.547 +CRMF_CertReqMsgSetKeyEnciphermentPOP(CRMFCertReqMsg *inCertReqMsg, 1.548 + CRMFPOPOPrivKeyChoice inKeyChoice, 1.549 + CRMFSubseqMessOptions subseqMess, 1.550 + SECItem *encPrivKey) 1.551 +{ 1.552 + SECStatus rv; 1.553 + 1.554 + PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL); 1.555 + if (CRMF_CertReqMsgGetPOPType(inCertReqMsg) != crmfNoPOPChoice) { 1.556 + return SECFailure; 1.557 + } 1.558 + switch (inKeyChoice) { 1.559 + case crmfThisMessage: 1.560 + rv = crmf_add_privkey_thismessage(inCertReqMsg, encPrivKey, 1.561 + crmfKeyEncipherment); 1.562 + break; 1.563 + case crmfSubsequentMessage: 1.564 + rv = crmf_add_privkey_subseqmessage(inCertReqMsg, subseqMess, 1.565 + crmfKeyEncipherment); 1.566 + break; 1.567 + case crmfDHMAC: 1.568 + default: 1.569 + rv = SECFailure; 1.570 + } 1.571 + return rv; 1.572 +} 1.573 + 1.574 +SECStatus 1.575 +CRMF_CertReqMsgSetKeyAgreementPOP (CRMFCertReqMsg *inCertReqMsg, 1.576 + CRMFPOPOPrivKeyChoice inKeyChoice, 1.577 + CRMFSubseqMessOptions subseqMess, 1.578 + SECItem *encPrivKey) 1.579 +{ 1.580 + SECStatus rv; 1.581 + 1.582 + PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->pop == NULL); 1.583 + switch (inKeyChoice) { 1.584 + case crmfThisMessage: 1.585 + rv = crmf_add_privkey_thismessage(inCertReqMsg, encPrivKey, 1.586 + crmfKeyAgreement); 1.587 + break; 1.588 + case crmfSubsequentMessage: 1.589 + rv = crmf_add_privkey_subseqmessage(inCertReqMsg, subseqMess, 1.590 + crmfKeyAgreement); 1.591 + break; 1.592 + case crmfDHMAC: 1.593 + /* In this case encPrivKey should be the calculated dhMac 1.594 + * as specified in RFC 2511 */ 1.595 + rv = crmf_add_privkey_dhmac(inCertReqMsg, encPrivKey, 1.596 + crmfKeyAgreement); 1.597 + break; 1.598 + default: 1.599 + rv = SECFailure; 1.600 + } 1.601 + return rv; 1.602 +} 1.603 +