1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/crmf/crmfcont.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1158 @@ 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 +#include "crmf.h" 1.10 +#include "crmfi.h" 1.11 +#include "pk11func.h" 1.12 +#include "keyhi.h" 1.13 +#include "secoid.h" 1.14 + 1.15 +static SECStatus 1.16 +crmf_modify_control_array (CRMFCertRequest *inCertReq, int count) 1.17 +{ 1.18 + if (count > 0) { 1.19 + void *dummy = PORT_Realloc(inCertReq->controls, 1.20 + sizeof(CRMFControl*)*(count+2)); 1.21 + if (dummy == NULL) { 1.22 + return SECFailure; 1.23 + } 1.24 + inCertReq->controls = dummy; 1.25 + } else { 1.26 + inCertReq->controls = PORT_ZNewArray(CRMFControl*, 2); 1.27 + } 1.28 + return (inCertReq->controls == NULL) ? SECFailure : SECSuccess ; 1.29 +} 1.30 + 1.31 +static SECStatus 1.32 +crmf_add_new_control(CRMFCertRequest *inCertReq,SECOidTag inTag, 1.33 + CRMFControl **destControl) 1.34 +{ 1.35 + SECOidData *oidData; 1.36 + SECStatus rv; 1.37 + PLArenaPool *poolp; 1.38 + int numControls = 0; 1.39 + CRMFControl *newControl; 1.40 + CRMFControl **controls; 1.41 + void *mark; 1.42 + 1.43 + poolp = inCertReq->poolp; 1.44 + if (poolp == NULL) { 1.45 + return SECFailure; 1.46 + } 1.47 + mark = PORT_ArenaMark(poolp); 1.48 + if (inCertReq->controls != NULL) { 1.49 + while (inCertReq->controls[numControls] != NULL) 1.50 + numControls++; 1.51 + } 1.52 + rv = crmf_modify_control_array(inCertReq, numControls); 1.53 + if (rv != SECSuccess) { 1.54 + goto loser; 1.55 + } 1.56 + controls = inCertReq->controls; 1.57 + oidData = SECOID_FindOIDByTag(inTag); 1.58 + newControl = *destControl = PORT_ArenaZNew(poolp,CRMFControl); 1.59 + if (newControl == NULL) { 1.60 + goto loser; 1.61 + } 1.62 + rv = SECITEM_CopyItem(poolp, &newControl->derTag, &oidData->oid); 1.63 + if (rv != SECSuccess) { 1.64 + goto loser; 1.65 + } 1.66 + newControl->tag = inTag; 1.67 + controls[numControls] = newControl; 1.68 + controls[numControls+1] = NULL; 1.69 + PORT_ArenaUnmark(poolp, mark); 1.70 + return SECSuccess; 1.71 + 1.72 + loser: 1.73 + PORT_ArenaRelease(poolp, mark); 1.74 + *destControl = NULL; 1.75 + return SECFailure; 1.76 + 1.77 +} 1.78 + 1.79 +static SECStatus 1.80 +crmf_add_secitem_control(CRMFCertRequest *inCertReq, SECItem *value, 1.81 + SECOidTag inTag) 1.82 +{ 1.83 + SECStatus rv; 1.84 + CRMFControl *newControl; 1.85 + void *mark; 1.86 + 1.87 + rv = crmf_add_new_control(inCertReq, inTag, &newControl); 1.88 + if (rv != SECSuccess) { 1.89 + return rv; 1.90 + } 1.91 + mark = PORT_ArenaMark(inCertReq->poolp); 1.92 + rv = SECITEM_CopyItem(inCertReq->poolp, &newControl->derValue, value); 1.93 + if (rv != SECSuccess) { 1.94 + PORT_ArenaRelease(inCertReq->poolp, mark); 1.95 + return rv; 1.96 + } 1.97 + PORT_ArenaUnmark(inCertReq->poolp, mark); 1.98 + return SECSuccess; 1.99 +} 1.100 + 1.101 +SECStatus 1.102 +CRMF_CertRequestSetRegTokenControl(CRMFCertRequest *inCertReq, SECItem *value) 1.103 +{ 1.104 + return crmf_add_secitem_control(inCertReq, value, 1.105 + SEC_OID_PKIX_REGCTRL_REGTOKEN); 1.106 +} 1.107 + 1.108 +SECStatus 1.109 +CRMF_CertRequestSetAuthenticatorControl (CRMFCertRequest *inCertReq, 1.110 + SECItem *value) 1.111 +{ 1.112 + return crmf_add_secitem_control(inCertReq, value, 1.113 + SEC_OID_PKIX_REGCTRL_AUTHENTICATOR); 1.114 +} 1.115 + 1.116 +SECStatus 1.117 +crmf_destroy_encrypted_value(CRMFEncryptedValue *inEncrValue, PRBool freeit) 1.118 +{ 1.119 + if (inEncrValue != NULL) { 1.120 + if (inEncrValue->intendedAlg) { 1.121 + SECOID_DestroyAlgorithmID(inEncrValue->intendedAlg, PR_TRUE); 1.122 + inEncrValue->intendedAlg = NULL; 1.123 + } 1.124 + if (inEncrValue->symmAlg) { 1.125 + SECOID_DestroyAlgorithmID(inEncrValue->symmAlg, PR_TRUE); 1.126 + inEncrValue->symmAlg = NULL; 1.127 + } 1.128 + if (inEncrValue->encSymmKey.data) { 1.129 + PORT_Free(inEncrValue->encSymmKey.data); 1.130 + inEncrValue->encSymmKey.data = NULL; 1.131 + } 1.132 + if (inEncrValue->keyAlg) { 1.133 + SECOID_DestroyAlgorithmID(inEncrValue->keyAlg, PR_TRUE); 1.134 + inEncrValue->keyAlg = NULL; 1.135 + } 1.136 + if (inEncrValue->valueHint.data) { 1.137 + PORT_Free(inEncrValue->valueHint.data); 1.138 + inEncrValue->valueHint.data = NULL; 1.139 + } 1.140 + if (inEncrValue->encValue.data) { 1.141 + PORT_Free(inEncrValue->encValue.data); 1.142 + inEncrValue->encValue.data = NULL; 1.143 + } 1.144 + if (freeit) { 1.145 + PORT_Free(inEncrValue); 1.146 + } 1.147 + } 1.148 + return SECSuccess; 1.149 +} 1.150 + 1.151 +SECStatus 1.152 +CRMF_DestroyEncryptedValue(CRMFEncryptedValue *inEncrValue) 1.153 +{ 1.154 + return crmf_destroy_encrypted_value(inEncrValue, PR_TRUE); 1.155 +} 1.156 + 1.157 +SECStatus 1.158 +crmf_copy_encryptedvalue_secalg(PLArenaPool *poolp, 1.159 + SECAlgorithmID *srcAlgId, 1.160 + SECAlgorithmID **destAlgId) 1.161 +{ 1.162 + SECAlgorithmID *newAlgId; 1.163 + SECStatus rv; 1.164 + 1.165 + newAlgId = (poolp != NULL) ? PORT_ArenaZNew(poolp, SECAlgorithmID) : 1.166 + PORT_ZNew(SECAlgorithmID); 1.167 + if (newAlgId == NULL) { 1.168 + return SECFailure; 1.169 + } 1.170 + 1.171 + rv = SECOID_CopyAlgorithmID(poolp, newAlgId, srcAlgId); 1.172 + if (rv != SECSuccess) { 1.173 + if (!poolp) { 1.174 + SECOID_DestroyAlgorithmID(newAlgId, PR_TRUE); 1.175 + } 1.176 + return rv; 1.177 + } 1.178 + *destAlgId = newAlgId; 1.179 + 1.180 + return rv; 1.181 +} 1.182 + 1.183 +SECStatus 1.184 +crmf_copy_encryptedvalue(PLArenaPool *poolp, 1.185 + CRMFEncryptedValue *srcValue, 1.186 + CRMFEncryptedValue *destValue) 1.187 +{ 1.188 + SECStatus rv; 1.189 + 1.190 + if (srcValue->intendedAlg != NULL) { 1.191 + rv = crmf_copy_encryptedvalue_secalg(poolp, 1.192 + srcValue->intendedAlg, 1.193 + &destValue->intendedAlg); 1.194 + if (rv != SECSuccess) { 1.195 + goto loser; 1.196 + } 1.197 + } 1.198 + if (srcValue->symmAlg != NULL) { 1.199 + rv = crmf_copy_encryptedvalue_secalg(poolp, 1.200 + srcValue->symmAlg, 1.201 + &destValue->symmAlg); 1.202 + if (rv != SECSuccess) { 1.203 + goto loser; 1.204 + } 1.205 + } 1.206 + if (srcValue->encSymmKey.data != NULL) { 1.207 + rv = crmf_make_bitstring_copy(poolp, 1.208 + &destValue->encSymmKey, 1.209 + &srcValue->encSymmKey); 1.210 + if (rv != SECSuccess) { 1.211 + goto loser; 1.212 + } 1.213 + } 1.214 + if (srcValue->keyAlg != NULL) { 1.215 + rv = crmf_copy_encryptedvalue_secalg(poolp, 1.216 + srcValue->keyAlg, 1.217 + &destValue->keyAlg); 1.218 + if (rv != SECSuccess) { 1.219 + goto loser; 1.220 + } 1.221 + } 1.222 + if (srcValue->valueHint.data != NULL) { 1.223 + rv = SECITEM_CopyItem(poolp, 1.224 + &destValue->valueHint, 1.225 + &srcValue->valueHint); 1.226 + if (rv != SECSuccess) { 1.227 + goto loser; 1.228 + } 1.229 + } 1.230 + if (srcValue->encValue.data != NULL) { 1.231 + rv = crmf_make_bitstring_copy(poolp, 1.232 + &destValue->encValue, 1.233 + &srcValue->encValue); 1.234 + if (rv != SECSuccess) { 1.235 + goto loser; 1.236 + } 1.237 + } 1.238 + return SECSuccess; 1.239 + loser: 1.240 + if (poolp == NULL && destValue != NULL) { 1.241 + crmf_destroy_encrypted_value(destValue, PR_FALSE); 1.242 + } 1.243 + return SECFailure; 1.244 +} 1.245 + 1.246 +SECStatus 1.247 +crmf_copy_encryptedkey(PLArenaPool *poolp, 1.248 + CRMFEncryptedKey *srcEncrKey, 1.249 + CRMFEncryptedKey *destEncrKey) 1.250 +{ 1.251 + SECStatus rv; 1.252 + void *mark = NULL; 1.253 + 1.254 + if (poolp != NULL) { 1.255 + mark = PORT_ArenaMark(poolp); 1.256 + } 1.257 + 1.258 + switch (srcEncrKey->encKeyChoice) { 1.259 + case crmfEncryptedValueChoice: 1.260 + rv = crmf_copy_encryptedvalue(poolp, 1.261 + &srcEncrKey->value.encryptedValue, 1.262 + &destEncrKey->value.encryptedValue); 1.263 + break; 1.264 + case crmfEnvelopedDataChoice: 1.265 + destEncrKey->value.envelopedData = 1.266 + SEC_PKCS7CopyContentInfo(srcEncrKey->value.envelopedData); 1.267 + rv = (destEncrKey->value.envelopedData != NULL) ? SECSuccess: 1.268 + SECFailure; 1.269 + break; 1.270 + default: 1.271 + rv = SECFailure; 1.272 + } 1.273 + if (rv != SECSuccess) { 1.274 + goto loser; 1.275 + } 1.276 + destEncrKey->encKeyChoice = srcEncrKey->encKeyChoice; 1.277 + if (mark) { 1.278 + PORT_ArenaUnmark(poolp, mark); 1.279 + } 1.280 + return SECSuccess; 1.281 + 1.282 + loser: 1.283 + if (mark) { 1.284 + PORT_ArenaRelease(poolp, mark); 1.285 + } 1.286 + return SECFailure; 1.287 +} 1.288 + 1.289 +static CRMFPKIArchiveOptions* 1.290 +crmf_create_encr_pivkey_option(CRMFEncryptedKey *inEncryptedKey) 1.291 +{ 1.292 + CRMFPKIArchiveOptions *newArchOpt; 1.293 + SECStatus rv; 1.294 + 1.295 + newArchOpt = PORT_ZNew(CRMFPKIArchiveOptions); 1.296 + if (newArchOpt == NULL) { 1.297 + goto loser; 1.298 + } 1.299 + 1.300 + rv = crmf_copy_encryptedkey(NULL, inEncryptedKey, 1.301 + &newArchOpt->option.encryptedKey); 1.302 + 1.303 + if (rv != SECSuccess) { 1.304 + goto loser; 1.305 + } 1.306 + newArchOpt->archOption = crmfEncryptedPrivateKey; 1.307 + return newArchOpt; 1.308 + loser: 1.309 + if (newArchOpt != NULL) { 1.310 + CRMF_DestroyPKIArchiveOptions(newArchOpt); 1.311 + } 1.312 + return NULL; 1.313 +} 1.314 + 1.315 +static CRMFPKIArchiveOptions* 1.316 +crmf_create_keygen_param_option(SECItem *inKeyGenParams) 1.317 +{ 1.318 + CRMFPKIArchiveOptions *newArchOptions; 1.319 + SECStatus rv; 1.320 + 1.321 + newArchOptions = PORT_ZNew(CRMFPKIArchiveOptions); 1.322 + if (newArchOptions == NULL) { 1.323 + goto loser; 1.324 + } 1.325 + newArchOptions->archOption = crmfKeyGenParameters; 1.326 + rv = SECITEM_CopyItem(NULL, &newArchOptions->option.keyGenParameters, 1.327 + inKeyGenParams); 1.328 + if (rv != SECSuccess) { 1.329 + goto loser; 1.330 + } 1.331 + return newArchOptions; 1.332 + loser: 1.333 + if (newArchOptions != NULL) { 1.334 + CRMF_DestroyPKIArchiveOptions(newArchOptions); 1.335 + } 1.336 + return NULL; 1.337 +} 1.338 + 1.339 +static CRMFPKIArchiveOptions* 1.340 +crmf_create_arch_rem_gen_privkey(PRBool archiveRemGenPrivKey) 1.341 +{ 1.342 + unsigned char value; 1.343 + SECItem *dummy; 1.344 + CRMFPKIArchiveOptions *newArchOptions; 1.345 + 1.346 + value = (archiveRemGenPrivKey) ? hexTrue : hexFalse; 1.347 + newArchOptions = PORT_ZNew(CRMFPKIArchiveOptions); 1.348 + if (newArchOptions == NULL) { 1.349 + goto loser; 1.350 + } 1.351 + dummy = SEC_ASN1EncodeItem(NULL, 1.352 + &newArchOptions->option.archiveRemGenPrivKey, 1.353 + &value, SEC_ASN1_GET(SEC_BooleanTemplate)); 1.354 + PORT_Assert (dummy == &newArchOptions->option.archiveRemGenPrivKey); 1.355 + if (dummy != &newArchOptions->option.archiveRemGenPrivKey) { 1.356 + SECITEM_FreeItem (dummy, PR_TRUE); 1.357 + goto loser; 1.358 + } 1.359 + newArchOptions->archOption = crmfArchiveRemGenPrivKey; 1.360 + return newArchOptions; 1.361 + loser: 1.362 + if (newArchOptions != NULL) { 1.363 + CRMF_DestroyPKIArchiveOptions(newArchOptions); 1.364 + } 1.365 + return NULL; 1.366 +} 1.367 + 1.368 +CRMFPKIArchiveOptions* 1.369 +CRMF_CreatePKIArchiveOptions(CRMFPKIArchiveOptionsType inType, void *data) 1.370 +{ 1.371 + CRMFPKIArchiveOptions* retOptions; 1.372 + 1.373 + PORT_Assert(data != NULL); 1.374 + if (data == NULL) { 1.375 + return NULL; 1.376 + } 1.377 + switch(inType) { 1.378 + case crmfEncryptedPrivateKey: 1.379 + retOptions = crmf_create_encr_pivkey_option((CRMFEncryptedKey*)data); 1.380 + break; 1.381 + case crmfKeyGenParameters: 1.382 + retOptions = crmf_create_keygen_param_option((SECItem*)data); 1.383 + break; 1.384 + case crmfArchiveRemGenPrivKey: 1.385 + retOptions = crmf_create_arch_rem_gen_privkey(*(PRBool*)data); 1.386 + break; 1.387 + default: 1.388 + retOptions = NULL; 1.389 + } 1.390 + return retOptions; 1.391 +} 1.392 + 1.393 +static SECStatus 1.394 +crmf_destroy_encrypted_key(CRMFEncryptedKey *inEncrKey, PRBool freeit) 1.395 +{ 1.396 + PORT_Assert(inEncrKey != NULL); 1.397 + if (inEncrKey != NULL) { 1.398 + switch (inEncrKey->encKeyChoice){ 1.399 + case crmfEncryptedValueChoice: 1.400 + crmf_destroy_encrypted_value(&inEncrKey->value.encryptedValue, 1.401 + PR_FALSE); 1.402 + break; 1.403 + case crmfEnvelopedDataChoice: 1.404 + SEC_PKCS7DestroyContentInfo(inEncrKey->value.envelopedData); 1.405 + break; 1.406 + default: 1.407 + break; 1.408 + } 1.409 + if (freeit) { 1.410 + PORT_Free(inEncrKey); 1.411 + } 1.412 + } 1.413 + return SECSuccess; 1.414 +} 1.415 + 1.416 +SECStatus 1.417 +crmf_destroy_pkiarchiveoptions(CRMFPKIArchiveOptions *inArchOptions, 1.418 + PRBool freeit) 1.419 +{ 1.420 + PORT_Assert(inArchOptions != NULL); 1.421 + if (inArchOptions != NULL) { 1.422 + switch (inArchOptions->archOption) { 1.423 + case crmfEncryptedPrivateKey: 1.424 + crmf_destroy_encrypted_key(&inArchOptions->option.encryptedKey, 1.425 + PR_FALSE); 1.426 + break; 1.427 + case crmfKeyGenParameters: 1.428 + case crmfArchiveRemGenPrivKey: 1.429 + /* This is a union, so having a pointer to one is like 1.430 + * having a pointer to both. 1.431 + */ 1.432 + SECITEM_FreeItem(&inArchOptions->option.keyGenParameters, 1.433 + PR_FALSE); 1.434 + break; 1.435 + case crmfNoArchiveOptions: 1.436 + break; 1.437 + } 1.438 + if (freeit) { 1.439 + PORT_Free(inArchOptions); 1.440 + } 1.441 + } 1.442 + return SECSuccess; 1.443 +} 1.444 + 1.445 +SECStatus 1.446 +CRMF_DestroyPKIArchiveOptions(CRMFPKIArchiveOptions *inArchOptions) 1.447 +{ 1.448 + return crmf_destroy_pkiarchiveoptions(inArchOptions, PR_TRUE); 1.449 +} 1.450 + 1.451 +static CK_MECHANISM_TYPE 1.452 +crmf_get_non_pad_mechanism(CK_MECHANISM_TYPE type) 1.453 +{ 1.454 + switch (type) { 1.455 + case CKM_DES3_CBC_PAD: 1.456 + return CKM_DES3_CBC; 1.457 + case CKM_CAST5_CBC_PAD: 1.458 + return CKM_CAST5_CBC; 1.459 + case CKM_DES_CBC_PAD: 1.460 + return CKM_DES_CBC; 1.461 + case CKM_IDEA_CBC_PAD: 1.462 + return CKM_IDEA_CBC; 1.463 + case CKM_CAST3_CBC_PAD: 1.464 + return CKM_CAST3_CBC; 1.465 + case CKM_CAST_CBC_PAD: 1.466 + return CKM_CAST_CBC; 1.467 + case CKM_RC5_CBC_PAD: 1.468 + return CKM_RC5_CBC; 1.469 + case CKM_RC2_CBC_PAD: 1.470 + return CKM_RC2_CBC; 1.471 + case CKM_CDMF_CBC_PAD: 1.472 + return CKM_CDMF_CBC; 1.473 + } 1.474 + return type; 1.475 +} 1.476 + 1.477 +static CK_MECHANISM_TYPE 1.478 +crmf_get_pad_mech_from_tag(SECOidTag oidTag) 1.479 +{ 1.480 + CK_MECHANISM_TYPE mechType; 1.481 + SECOidData *oidData; 1.482 + 1.483 + oidData = SECOID_FindOIDByTag(oidTag); 1.484 + mechType = (CK_MECHANISM_TYPE)oidData->mechanism; 1.485 + return PK11_GetPadMechanism(mechType); 1.486 +} 1.487 + 1.488 +static CK_MECHANISM_TYPE 1.489 +crmf_get_best_privkey_wrap_mechanism(PK11SlotInfo *slot) 1.490 +{ 1.491 + CK_MECHANISM_TYPE privKeyPadMechs[] = { CKM_DES3_CBC_PAD, 1.492 + CKM_CAST5_CBC_PAD, 1.493 + CKM_DES_CBC_PAD, 1.494 + CKM_IDEA_CBC_PAD, 1.495 + CKM_CAST3_CBC_PAD, 1.496 + CKM_CAST_CBC_PAD, 1.497 + CKM_RC5_CBC_PAD, 1.498 + CKM_RC2_CBC_PAD, 1.499 + CKM_CDMF_CBC_PAD }; 1.500 + int mechCount = sizeof(privKeyPadMechs)/sizeof(privKeyPadMechs[0]); 1.501 + int i; 1.502 + 1.503 + for (i=0; i < mechCount; i++) { 1.504 + if (PK11_DoesMechanism(slot, privKeyPadMechs[i])) { 1.505 + return privKeyPadMechs[i]; 1.506 + } 1.507 + } 1.508 + return CKM_INVALID_MECHANISM; 1.509 +} 1.510 + 1.511 +CK_MECHANISM_TYPE 1.512 +CRMF_GetBestWrapPadMechanism(PK11SlotInfo *slot) 1.513 +{ 1.514 + return crmf_get_best_privkey_wrap_mechanism(slot); 1.515 +} 1.516 + 1.517 +static SECItem* 1.518 +crmf_get_iv(CK_MECHANISM_TYPE mechType) 1.519 +{ 1.520 + int iv_size = PK11_GetIVLength(mechType); 1.521 + SECItem *iv; 1.522 + SECStatus rv; 1.523 + 1.524 + iv = PORT_ZNew(SECItem); 1.525 + if (iv == NULL) { 1.526 + return NULL; 1.527 + } 1.528 + if (iv_size == 0) { 1.529 + iv->data = NULL; 1.530 + iv->len = 0; 1.531 + return iv; 1.532 + } 1.533 + iv->data = PORT_NewArray(unsigned char, iv_size); 1.534 + if (iv->data == NULL) { 1.535 + iv->len = 0; 1.536 + return iv; 1.537 + } 1.538 + iv->len = iv_size; 1.539 + rv = PK11_GenerateRandom(iv->data, iv->len); 1.540 + if (rv != SECSuccess) { 1.541 + PORT_Free(iv->data); 1.542 + iv->data = NULL; 1.543 + iv->len = 0; 1.544 + } 1.545 + return iv; 1.546 +} 1.547 + 1.548 +SECItem* 1.549 +CRMF_GetIVFromMechanism(CK_MECHANISM_TYPE mechType) 1.550 +{ 1.551 + return crmf_get_iv(mechType); 1.552 +} 1.553 + 1.554 +CK_MECHANISM_TYPE 1.555 +crmf_get_mechanism_from_public_key(SECKEYPublicKey *inPubKey) 1.556 +{ 1.557 + CERTSubjectPublicKeyInfo *spki = NULL; 1.558 + SECOidTag tag; 1.559 + 1.560 + 1.561 + spki = SECKEY_CreateSubjectPublicKeyInfo(inPubKey); 1.562 + if (spki == NULL) { 1.563 + return CKM_INVALID_MECHANISM; 1.564 + } 1.565 + tag = SECOID_FindOIDTag(&spki->algorithm.algorithm); 1.566 + SECKEY_DestroySubjectPublicKeyInfo(spki); 1.567 + spki = NULL; 1.568 + return PK11_AlgtagToMechanism(tag); 1.569 +} 1.570 + 1.571 +SECItem* 1.572 +crmf_get_public_value(SECKEYPublicKey *pubKey, SECItem *dest) 1.573 +{ 1.574 + SECItem *src; 1.575 + 1.576 + switch(pubKey->keyType) { 1.577 + case dsaKey: 1.578 + src = &pubKey->u.dsa.publicValue; 1.579 + break; 1.580 + case rsaKey: 1.581 + src = &pubKey->u.rsa.modulus; 1.582 + break; 1.583 + case dhKey: 1.584 + src = &pubKey->u.dh.publicValue; 1.585 + break; 1.586 + default: 1.587 + src = NULL; 1.588 + break; 1.589 + } 1.590 + if (!src) { 1.591 + PORT_SetError(SEC_ERROR_INVALID_ARGS); 1.592 + return NULL; 1.593 + } 1.594 + 1.595 + if (dest != NULL) { 1.596 + SECStatus rv = SECITEM_CopyItem(NULL, dest, src); 1.597 + if (rv != SECSuccess) { 1.598 + dest = NULL; 1.599 + } 1.600 + } else { 1.601 + dest = SECITEM_ArenaDupItem(NULL, src); 1.602 + } 1.603 + return dest; 1.604 +} 1.605 + 1.606 +static SECItem* 1.607 +crmf_decode_params(SECItem *inParams) 1.608 +{ 1.609 + SECItem *params; 1.610 + SECStatus rv = SECFailure; 1.611 + PLArenaPool *poolp; 1.612 + 1.613 + poolp = PORT_NewArena(CRMF_DEFAULT_ARENA_SIZE); 1.614 + if (poolp == NULL) { 1.615 + return NULL; 1.616 + } 1.617 + 1.618 + params = PORT_ArenaZNew(poolp, SECItem); 1.619 + if (params) { 1.620 + rv = SEC_ASN1DecodeItem(poolp, params, 1.621 + SEC_ASN1_GET(SEC_OctetStringTemplate), 1.622 + inParams); 1.623 + } 1.624 + params = (rv == SECSuccess) ? SECITEM_ArenaDupItem(NULL, params) : NULL; 1.625 + PORT_FreeArena(poolp, PR_FALSE); 1.626 + return params; 1.627 +} 1.628 + 1.629 +static int 1.630 +crmf_get_key_size_from_mech(CK_MECHANISM_TYPE mechType) 1.631 +{ 1.632 + CK_MECHANISM_TYPE keyGen = PK11_GetKeyGen(mechType); 1.633 + 1.634 + switch (keyGen) { 1.635 + case CKM_CDMF_KEY_GEN: 1.636 + case CKM_DES_KEY_GEN: 1.637 + return 8; 1.638 + case CKM_DES2_KEY_GEN: 1.639 + return 16; 1.640 + case CKM_DES3_KEY_GEN: 1.641 + return 24; 1.642 + } 1.643 + return 0; 1.644 +} 1.645 + 1.646 +SECStatus 1.647 +crmf_encrypted_value_unwrap_priv_key(PLArenaPool *poolp, 1.648 + CRMFEncryptedValue *encValue, 1.649 + SECKEYPrivateKey *privKey, 1.650 + SECKEYPublicKey *newPubKey, 1.651 + SECItem *nickname, 1.652 + PK11SlotInfo *slot, 1.653 + unsigned char keyUsage, 1.654 + SECKEYPrivateKey **unWrappedKey, 1.655 + void *wincx) 1.656 +{ 1.657 + PK11SymKey *wrappingKey = NULL; 1.658 + CK_MECHANISM_TYPE wrapMechType; 1.659 + SECOidTag oidTag; 1.660 + SECItem *params = NULL, *publicValue = NULL; 1.661 + int keySize, origLen; 1.662 + CK_KEY_TYPE keyType; 1.663 + CK_ATTRIBUTE_TYPE *usage = NULL; 1.664 + CK_ATTRIBUTE_TYPE rsaUsage[] = { 1.665 + CKA_UNWRAP, CKA_DECRYPT, CKA_SIGN, CKA_SIGN_RECOVER }; 1.666 + CK_ATTRIBUTE_TYPE dsaUsage[] = { CKA_SIGN }; 1.667 + CK_ATTRIBUTE_TYPE dhUsage[] = { CKA_DERIVE }; 1.668 + int usageCount = 0; 1.669 + 1.670 + oidTag = SECOID_GetAlgorithmTag(encValue->symmAlg); 1.671 + wrapMechType = crmf_get_pad_mech_from_tag(oidTag); 1.672 + keySize = crmf_get_key_size_from_mech(wrapMechType); 1.673 + wrappingKey = PK11_PubUnwrapSymKey(privKey, &encValue->encSymmKey, 1.674 + wrapMechType, CKA_UNWRAP, keySize); 1.675 + if (wrappingKey == NULL) { 1.676 + goto loser; 1.677 + }/* Make the length a byte length instead of bit length*/ 1.678 + params = (encValue->symmAlg != NULL) ? 1.679 + crmf_decode_params(&encValue->symmAlg->parameters) : NULL; 1.680 + origLen = encValue->encValue.len; 1.681 + encValue->encValue.len = CRMF_BITS_TO_BYTES(origLen); 1.682 + publicValue = crmf_get_public_value(newPubKey, NULL); 1.683 + switch(newPubKey->keyType) { 1.684 + default: 1.685 + case rsaKey: 1.686 + keyType = CKK_RSA; 1.687 + switch (keyUsage & (KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE)) { 1.688 + case KU_KEY_ENCIPHERMENT: 1.689 + usage = rsaUsage; 1.690 + usageCount = 2; 1.691 + break; 1.692 + case KU_DIGITAL_SIGNATURE: 1.693 + usage = &rsaUsage[2]; 1.694 + usageCount = 2; 1.695 + break; 1.696 + case KU_KEY_ENCIPHERMENT|KU_DIGITAL_SIGNATURE: 1.697 + case 0: /* default to everything */ 1.698 + usage = rsaUsage; 1.699 + usageCount = 4; 1.700 + break; 1.701 + } 1.702 + break; 1.703 + case dhKey: 1.704 + keyType = CKK_DH; 1.705 + usage = dhUsage; 1.706 + usageCount = sizeof(dhUsage)/sizeof(dhUsage[0]); 1.707 + break; 1.708 + case dsaKey: 1.709 + keyType = CKK_DSA; 1.710 + usage = dsaUsage; 1.711 + usageCount = sizeof(dsaUsage)/sizeof(dsaUsage[0]); 1.712 + break; 1.713 + } 1.714 + PORT_Assert(usage != NULL); 1.715 + PORT_Assert(usageCount != 0); 1.716 + *unWrappedKey = PK11_UnwrapPrivKey(slot, wrappingKey, wrapMechType, params, 1.717 + &encValue->encValue, nickname, 1.718 + publicValue, PR_TRUE,PR_TRUE, 1.719 + keyType, usage, usageCount, wincx); 1.720 + encValue->encValue.len = origLen; 1.721 + if (*unWrappedKey == NULL) { 1.722 + goto loser; 1.723 + } 1.724 + SECITEM_FreeItem (publicValue, PR_TRUE); 1.725 + if (params!= NULL) { 1.726 + SECITEM_FreeItem(params, PR_TRUE); 1.727 + } 1.728 + PK11_FreeSymKey(wrappingKey); 1.729 + return SECSuccess; 1.730 + loser: 1.731 + *unWrappedKey = NULL; 1.732 + return SECFailure; 1.733 +} 1.734 + 1.735 +CRMFEncryptedValue * 1.736 +crmf_create_encrypted_value_wrapped_privkey(SECKEYPrivateKey *inPrivKey, 1.737 + SECKEYPublicKey *inCAKey, 1.738 + CRMFEncryptedValue *destValue) 1.739 +{ 1.740 + SECItem wrappedPrivKey, wrappedSymKey; 1.741 + SECItem encodedParam, *dummy; 1.742 + SECStatus rv; 1.743 + CK_MECHANISM_TYPE pubMechType, symKeyType; 1.744 + unsigned char *wrappedSymKeyBits; 1.745 + unsigned char *wrappedPrivKeyBits; 1.746 + SECItem *iv = NULL; 1.747 + SECOidTag tag; 1.748 + PK11SymKey *symKey; 1.749 + PK11SlotInfo *slot; 1.750 + SECAlgorithmID *symmAlg; 1.751 + CRMFEncryptedValue *myEncrValue = NULL; 1.752 + 1.753 + encodedParam.data = NULL; 1.754 + wrappedSymKeyBits = PORT_NewArray(unsigned char, MAX_WRAPPED_KEY_LEN); 1.755 + wrappedPrivKeyBits = PORT_NewArray(unsigned char, MAX_WRAPPED_KEY_LEN); 1.756 + if (wrappedSymKeyBits == NULL || wrappedPrivKeyBits == NULL) { 1.757 + goto loser; 1.758 + } 1.759 + if (destValue == NULL) { 1.760 + myEncrValue = destValue = PORT_ZNew(CRMFEncryptedValue); 1.761 + if (destValue == NULL) { 1.762 + goto loser; 1.763 + } 1.764 + } 1.765 + 1.766 + pubMechType = crmf_get_mechanism_from_public_key(inCAKey); 1.767 + if (pubMechType == CKM_INVALID_MECHANISM) { 1.768 + /* XXX I should probably do something here for non-RSA 1.769 + * keys that are in certs. (ie DSA) 1.770 + * XXX or at least SET AN ERROR CODE. 1.771 + */ 1.772 + goto loser; 1.773 + } 1.774 + slot = inPrivKey->pkcs11Slot; 1.775 + PORT_Assert(slot != NULL); 1.776 + symKeyType = crmf_get_best_privkey_wrap_mechanism(slot); 1.777 + symKey = PK11_KeyGen(slot, symKeyType, NULL, 0, NULL); 1.778 + if (symKey == NULL) { 1.779 + goto loser; 1.780 + } 1.781 + 1.782 + wrappedSymKey.data = wrappedSymKeyBits; 1.783 + wrappedSymKey.len = MAX_WRAPPED_KEY_LEN; 1.784 + rv = PK11_PubWrapSymKey(pubMechType, inCAKey, symKey, &wrappedSymKey); 1.785 + if (rv != SECSuccess) { 1.786 + goto loser; 1.787 + } 1.788 + /* Make the length of the result a Bit String length. */ 1.789 + wrappedSymKey.len <<= 3; 1.790 + 1.791 + wrappedPrivKey.data = wrappedPrivKeyBits; 1.792 + wrappedPrivKey.len = MAX_WRAPPED_KEY_LEN; 1.793 + iv = crmf_get_iv(symKeyType); 1.794 + rv = PK11_WrapPrivKey(slot, symKey, inPrivKey, symKeyType, iv, 1.795 + &wrappedPrivKey, NULL); 1.796 + PK11_FreeSymKey(symKey); 1.797 + if (rv != SECSuccess) { 1.798 + goto loser; 1.799 + } 1.800 + /* Make the length of the result a Bit String length. */ 1.801 + wrappedPrivKey.len <<= 3; 1.802 + rv = crmf_make_bitstring_copy(NULL, 1.803 + &destValue->encValue, 1.804 + &wrappedPrivKey); 1.805 + if (rv != SECSuccess) { 1.806 + goto loser; 1.807 + } 1.808 + 1.809 + rv = crmf_make_bitstring_copy(NULL, 1.810 + &destValue->encSymmKey, 1.811 + &wrappedSymKey); 1.812 + if (rv != SECSuccess) { 1.813 + goto loser; 1.814 + } 1.815 + destValue->symmAlg = symmAlg = PORT_ZNew(SECAlgorithmID); 1.816 + if (symmAlg == NULL) { 1.817 + goto loser; 1.818 + } 1.819 + 1.820 + dummy = SEC_ASN1EncodeItem(NULL, &encodedParam, iv, 1.821 + SEC_ASN1_GET(SEC_OctetStringTemplate)); 1.822 + if (dummy != &encodedParam) { 1.823 + SECITEM_FreeItem(dummy, PR_TRUE); 1.824 + goto loser; 1.825 + } 1.826 + 1.827 + symKeyType = crmf_get_non_pad_mechanism(symKeyType); 1.828 + tag = PK11_MechanismToAlgtag(symKeyType); 1.829 + rv = SECOID_SetAlgorithmID(NULL, symmAlg, tag, &encodedParam); 1.830 + if (rv != SECSuccess) { 1.831 + goto loser; 1.832 + } 1.833 + SECITEM_FreeItem(&encodedParam, PR_FALSE); 1.834 + PORT_Free(wrappedPrivKeyBits); 1.835 + PORT_Free(wrappedSymKeyBits); 1.836 + SECITEM_FreeItem(iv, PR_TRUE); 1.837 + return destValue; 1.838 + loser: 1.839 + if (iv != NULL) { 1.840 + SECITEM_FreeItem(iv, PR_TRUE); 1.841 + } 1.842 + if (myEncrValue != NULL) { 1.843 + crmf_destroy_encrypted_value(myEncrValue, PR_TRUE); 1.844 + } 1.845 + if (wrappedSymKeyBits != NULL) { 1.846 + PORT_Free(wrappedSymKeyBits); 1.847 + } 1.848 + if (wrappedPrivKeyBits != NULL) { 1.849 + PORT_Free(wrappedPrivKeyBits); 1.850 + } 1.851 + if (encodedParam.data != NULL) { 1.852 + SECITEM_FreeItem(&encodedParam, PR_FALSE); 1.853 + } 1.854 + return NULL; 1.855 +} 1.856 + 1.857 +CRMFEncryptedKey* 1.858 +CRMF_CreateEncryptedKeyWithEncryptedValue (SECKEYPrivateKey *inPrivKey, 1.859 + CERTCertificate *inCACert) 1.860 +{ 1.861 + SECKEYPublicKey *caPubKey = NULL; 1.862 + CRMFEncryptedKey *encKey = NULL; 1.863 + CRMFEncryptedValue *dummy; 1.864 + 1.865 + PORT_Assert(inPrivKey != NULL && inCACert != NULL); 1.866 + if (inPrivKey == NULL || inCACert == NULL) { 1.867 + return NULL; 1.868 + } 1.869 + 1.870 + caPubKey = CERT_ExtractPublicKey(inCACert); 1.871 + if (caPubKey == NULL) { 1.872 + goto loser; 1.873 + } 1.874 + 1.875 + encKey = PORT_ZNew(CRMFEncryptedKey); 1.876 + if (encKey == NULL) { 1.877 + goto loser; 1.878 + } 1.879 + dummy = crmf_create_encrypted_value_wrapped_privkey(inPrivKey, 1.880 + caPubKey, 1.881 + &encKey->value.encryptedValue); 1.882 + PORT_Assert(dummy == &encKey->value.encryptedValue); 1.883 + /* We won't add the der value here, but rather when it 1.884 + * becomes part of a certificate request. 1.885 + */ 1.886 + SECKEY_DestroyPublicKey(caPubKey); 1.887 + encKey->encKeyChoice = crmfEncryptedValueChoice; 1.888 + return encKey; 1.889 + loser: 1.890 + if (encKey != NULL) { 1.891 + CRMF_DestroyEncryptedKey(encKey); 1.892 + } 1.893 + if (caPubKey != NULL) { 1.894 + SECKEY_DestroyPublicKey(caPubKey); 1.895 + } 1.896 + return NULL; 1.897 +} 1.898 + 1.899 +SECStatus 1.900 +CRMF_DestroyEncryptedKey(CRMFEncryptedKey *inEncrKey) 1.901 +{ 1.902 + return crmf_destroy_encrypted_key(inEncrKey, PR_TRUE); 1.903 +} 1.904 + 1.905 +SECStatus 1.906 +crmf_copy_pkiarchiveoptions(PLArenaPool *poolp, 1.907 + CRMFPKIArchiveOptions *destOpt, 1.908 + CRMFPKIArchiveOptions *srcOpt) 1.909 +{ 1.910 + SECStatus rv; 1.911 + destOpt->archOption = srcOpt->archOption; 1.912 + switch (srcOpt->archOption) { 1.913 + case crmfEncryptedPrivateKey: 1.914 + rv = crmf_copy_encryptedkey(poolp, 1.915 + &srcOpt->option.encryptedKey, 1.916 + &destOpt->option.encryptedKey); 1.917 + break; 1.918 + case crmfKeyGenParameters: 1.919 + case crmfArchiveRemGenPrivKey: 1.920 + /* We've got a union, so having a pointer to one is just 1.921 + * like having a pointer to the other one. 1.922 + */ 1.923 + rv = SECITEM_CopyItem(poolp, 1.924 + &destOpt->option.keyGenParameters, 1.925 + &srcOpt->option.keyGenParameters); 1.926 + break; 1.927 + default: 1.928 + rv = SECFailure; 1.929 + } 1.930 + return rv; 1.931 +} 1.932 + 1.933 +static SECStatus 1.934 +crmf_check_and_adjust_archoption(CRMFControl *inControl) 1.935 +{ 1.936 + CRMFPKIArchiveOptions *options; 1.937 + 1.938 + options = &inControl->value.archiveOptions; 1.939 + if (options->archOption == crmfNoArchiveOptions) { 1.940 + /* It hasn't been set, so figure it out from the 1.941 + * der. 1.942 + */ 1.943 + switch (inControl->derValue.data[0] & 0x0f) { 1.944 + case 0: 1.945 + options->archOption = crmfEncryptedPrivateKey; 1.946 + break; 1.947 + case 1: 1.948 + options->archOption = crmfKeyGenParameters; 1.949 + break; 1.950 + case 2: 1.951 + options->archOption = crmfArchiveRemGenPrivKey; 1.952 + break; 1.953 + default: 1.954 + /* We've got bad DER. Return an error. */ 1.955 + return SECFailure; 1.956 + } 1.957 + } 1.958 + return SECSuccess; 1.959 +} 1.960 + 1.961 +static const SEC_ASN1Template * 1.962 +crmf_get_pkiarchive_subtemplate(CRMFControl *inControl) 1.963 +{ 1.964 + const SEC_ASN1Template *retTemplate; 1.965 + SECStatus rv; 1.966 + /* 1.967 + * We could be in the process of decoding, in which case the 1.968 + * archOption field will not be set. Let's check it and set 1.969 + * it accordingly. 1.970 + */ 1.971 + 1.972 + rv = crmf_check_and_adjust_archoption(inControl); 1.973 + if (rv != SECSuccess) { 1.974 + return NULL; 1.975 + } 1.976 + 1.977 + switch (inControl->value.archiveOptions.archOption) { 1.978 + case crmfEncryptedPrivateKey: 1.979 + retTemplate = CRMFEncryptedKeyWithEncryptedValueTemplate; 1.980 + inControl->value.archiveOptions.option.encryptedKey.encKeyChoice = 1.981 + crmfEncryptedValueChoice; 1.982 + break; 1.983 + default: 1.984 + retTemplate = NULL; 1.985 + } 1.986 + return retTemplate; 1.987 +} 1.988 + 1.989 +const SEC_ASN1Template* 1.990 +crmf_get_pkiarchiveoptions_subtemplate(CRMFControl *inControl) 1.991 +{ 1.992 + const SEC_ASN1Template *retTemplate; 1.993 + 1.994 + switch (inControl->tag) { 1.995 + case SEC_OID_PKIX_REGCTRL_REGTOKEN: 1.996 + case SEC_OID_PKIX_REGCTRL_AUTHENTICATOR: 1.997 + retTemplate = SEC_ASN1_GET(SEC_UTF8StringTemplate); 1.998 + break; 1.999 + case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS: 1.1000 + retTemplate = crmf_get_pkiarchive_subtemplate(inControl); 1.1001 + break; 1.1002 + case SEC_OID_PKIX_REGCTRL_PKIPUBINFO: 1.1003 + case SEC_OID_PKIX_REGCTRL_OLD_CERT_ID: 1.1004 + case SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY: 1.1005 + /* We don't support these controls, so we fail for now.*/ 1.1006 + retTemplate = NULL; 1.1007 + break; 1.1008 + default: 1.1009 + retTemplate = NULL; 1.1010 + } 1.1011 + return retTemplate; 1.1012 +} 1.1013 + 1.1014 +static SECStatus 1.1015 +crmf_encode_pkiarchiveoptions(PLArenaPool *poolp, CRMFControl *inControl) 1.1016 +{ 1.1017 + const SEC_ASN1Template *asn1Template; 1.1018 + 1.1019 + asn1Template = crmf_get_pkiarchiveoptions_subtemplate(inControl); 1.1020 + /* We've got a union, so passing a pointer to one element of the 1.1021 + * union, is the same as passing a pointer to any of the other 1.1022 + * members of the union. 1.1023 + */ 1.1024 + SEC_ASN1EncodeItem(poolp, &inControl->derValue, 1.1025 + &inControl->value.archiveOptions, asn1Template); 1.1026 + 1.1027 + if (inControl->derValue.data == NULL) { 1.1028 + goto loser; 1.1029 + } 1.1030 + return SECSuccess; 1.1031 + loser: 1.1032 + return SECFailure; 1.1033 +} 1.1034 + 1.1035 +SECStatus 1.1036 +CRMF_CertRequestSetPKIArchiveOptions(CRMFCertRequest *inCertReq, 1.1037 + CRMFPKIArchiveOptions *inOptions) 1.1038 +{ 1.1039 + CRMFControl *newControl; 1.1040 + PLArenaPool *poolp; 1.1041 + SECStatus rv; 1.1042 + void *mark; 1.1043 + 1.1044 + PORT_Assert(inCertReq != NULL && inOptions != NULL); 1.1045 + if (inCertReq == NULL || inOptions == NULL) { 1.1046 + return SECFailure; 1.1047 + } 1.1048 + poolp = inCertReq->poolp; 1.1049 + mark = PORT_ArenaMark(poolp); 1.1050 + rv = crmf_add_new_control(inCertReq, 1.1051 + SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS, 1.1052 + &newControl); 1.1053 + if (rv != SECSuccess) { 1.1054 + goto loser; 1.1055 + } 1.1056 + 1.1057 + rv = crmf_copy_pkiarchiveoptions(poolp, 1.1058 + &newControl->value.archiveOptions, 1.1059 + inOptions); 1.1060 + if (rv != SECSuccess) { 1.1061 + goto loser; 1.1062 + } 1.1063 + 1.1064 + rv = crmf_encode_pkiarchiveoptions(poolp, newControl); 1.1065 + if (rv != SECSuccess) { 1.1066 + goto loser; 1.1067 + } 1.1068 + PORT_ArenaUnmark(poolp, mark); 1.1069 + return SECSuccess; 1.1070 + loser: 1.1071 + PORT_ArenaRelease(poolp, mark); 1.1072 + return SECFailure; 1.1073 +} 1.1074 + 1.1075 +static SECStatus 1.1076 +crmf_destroy_control(CRMFControl *inControl, PRBool freeit) 1.1077 +{ 1.1078 + PORT_Assert(inControl != NULL); 1.1079 + if (inControl != NULL) { 1.1080 + SECITEM_FreeItem(&inControl->derTag, PR_FALSE); 1.1081 + SECITEM_FreeItem(&inControl->derValue, PR_FALSE); 1.1082 + /* None of the other tags require special processing at 1.1083 + * the moment when freeing because they are not supported, 1.1084 + * but if/when they are, add the necessary routines here. 1.1085 + * If all controls are supported, then every member of the 1.1086 + * union inControl->value will have a case that deals with 1.1087 + * it in the following switch statement. 1.1088 + */ 1.1089 + switch (inControl->tag) { 1.1090 + case SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS: 1.1091 + crmf_destroy_pkiarchiveoptions(&inControl->value.archiveOptions, 1.1092 + PR_FALSE); 1.1093 + break; 1.1094 + default: 1.1095 + /* Put this here to get rid of all those annoying warnings.*/ 1.1096 + break; 1.1097 + } 1.1098 + if (freeit) { 1.1099 + PORT_Free(inControl); 1.1100 + } 1.1101 + } 1.1102 + return SECSuccess; 1.1103 +} 1.1104 + 1.1105 +SECStatus 1.1106 +CRMF_DestroyControl(CRMFControl *inControl) 1.1107 +{ 1.1108 + return crmf_destroy_control(inControl, PR_TRUE); 1.1109 +} 1.1110 + 1.1111 +static SECOidTag 1.1112 +crmf_controltype_to_tag(CRMFControlType inControlType) 1.1113 +{ 1.1114 + SECOidTag retVal; 1.1115 + 1.1116 + switch(inControlType) { 1.1117 + case crmfRegTokenControl: 1.1118 + retVal = SEC_OID_PKIX_REGCTRL_REGTOKEN; 1.1119 + break; 1.1120 + case crmfAuthenticatorControl: 1.1121 + retVal = SEC_OID_PKIX_REGCTRL_AUTHENTICATOR; 1.1122 + break; 1.1123 + case crmfPKIPublicationInfoControl: 1.1124 + retVal = SEC_OID_PKIX_REGCTRL_PKIPUBINFO; 1.1125 + break; 1.1126 + case crmfPKIArchiveOptionsControl: 1.1127 + retVal = SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS; 1.1128 + break; 1.1129 + case crmfOldCertIDControl: 1.1130 + retVal = SEC_OID_PKIX_REGCTRL_OLD_CERT_ID; 1.1131 + break; 1.1132 + case crmfProtocolEncrKeyControl: 1.1133 + retVal = SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY; 1.1134 + break; 1.1135 + default: 1.1136 + retVal = SEC_OID_UNKNOWN; 1.1137 + break; 1.1138 + } 1.1139 + return retVal; 1.1140 +} 1.1141 + 1.1142 +PRBool 1.1143 +CRMF_CertRequestIsControlPresent(CRMFCertRequest *inCertReq, 1.1144 + CRMFControlType inControlType) 1.1145 +{ 1.1146 + SECOidTag controlTag; 1.1147 + int i; 1.1148 + 1.1149 + PORT_Assert(inCertReq != NULL); 1.1150 + if (inCertReq == NULL || inCertReq->controls == NULL) { 1.1151 + return PR_FALSE; 1.1152 + } 1.1153 + controlTag = crmf_controltype_to_tag(inControlType); 1.1154 + for (i=0; inCertReq->controls[i] != NULL; i++) { 1.1155 + if (inCertReq->controls[i]->tag == controlTag) { 1.1156 + return PR_TRUE; 1.1157 + } 1.1158 + } 1.1159 + return PR_FALSE; 1.1160 +} 1.1161 +