security/nss/lib/pki/certificate.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 2 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 4
michael@0 5 #ifndef NSSPKI_H
michael@0 6 #include "nsspki.h"
michael@0 7 #endif /* NSSPKI_H */
michael@0 8
michael@0 9 #ifndef PKIT_H
michael@0 10 #include "pkit.h"
michael@0 11 #endif /* PKIT_H */
michael@0 12
michael@0 13 #ifndef PKIM_H
michael@0 14 #include "pkim.h"
michael@0 15 #endif /* PKIM_H */
michael@0 16
michael@0 17 #ifndef DEV_H
michael@0 18 #include "dev.h"
michael@0 19 #endif /* DEV_H */
michael@0 20
michael@0 21 #include "pkistore.h"
michael@0 22
michael@0 23 #include "pki3hack.h"
michael@0 24 #include "pk11func.h"
michael@0 25 #include "hasht.h"
michael@0 26
michael@0 27 #ifndef BASE_H
michael@0 28 #include "base.h"
michael@0 29 #endif /* BASE_H */
michael@0 30
michael@0 31 extern const NSSError NSS_ERROR_NOT_FOUND;
michael@0 32
michael@0 33 /* Creates a certificate from a base object */
michael@0 34 NSS_IMPLEMENT NSSCertificate *
michael@0 35 nssCertificate_Create (
michael@0 36 nssPKIObject *object
michael@0 37 )
michael@0 38 {
michael@0 39 PRStatus status;
michael@0 40 NSSCertificate *rvCert;
michael@0 41 nssArenaMark * mark;
michael@0 42 NSSArena *arena = object->arena;
michael@0 43 PR_ASSERT(object->instances != NULL && object->numInstances > 0);
michael@0 44 PR_ASSERT(object->lockType == nssPKIMonitor);
michael@0 45 mark = nssArena_Mark(arena);
michael@0 46 rvCert = nss_ZNEW(arena, NSSCertificate);
michael@0 47 if (!rvCert) {
michael@0 48 return (NSSCertificate *)NULL;
michael@0 49 }
michael@0 50 rvCert->object = *object;
michael@0 51 /* XXX should choose instance based on some criteria */
michael@0 52 status = nssCryptokiCertificate_GetAttributes(object->instances[0],
michael@0 53 NULL, /* XXX sessionOpt */
michael@0 54 arena,
michael@0 55 &rvCert->type,
michael@0 56 &rvCert->id,
michael@0 57 &rvCert->encoding,
michael@0 58 &rvCert->issuer,
michael@0 59 &rvCert->serial,
michael@0 60 &rvCert->subject);
michael@0 61 if (status != PR_SUCCESS ||
michael@0 62 !rvCert->encoding.data ||
michael@0 63 !rvCert->encoding.size ||
michael@0 64 !rvCert->issuer.data ||
michael@0 65 !rvCert->issuer.size ||
michael@0 66 !rvCert->serial.data ||
michael@0 67 !rvCert->serial.size) {
michael@0 68 if (mark)
michael@0 69 nssArena_Release(arena, mark);
michael@0 70 return (NSSCertificate *)NULL;
michael@0 71 }
michael@0 72 if (mark)
michael@0 73 nssArena_Unmark(arena, mark);
michael@0 74 return rvCert;
michael@0 75 }
michael@0 76
michael@0 77 NSS_IMPLEMENT NSSCertificate *
michael@0 78 nssCertificate_AddRef (
michael@0 79 NSSCertificate *c
michael@0 80 )
michael@0 81 {
michael@0 82 if (c) {
michael@0 83 nssPKIObject_AddRef(&c->object);
michael@0 84 }
michael@0 85 return c;
michael@0 86 }
michael@0 87
michael@0 88 NSS_IMPLEMENT PRStatus
michael@0 89 nssCertificate_Destroy (
michael@0 90 NSSCertificate *c
michael@0 91 )
michael@0 92 {
michael@0 93 nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
michael@0 94 nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
michael@0 95
michael@0 96 if (c) {
michael@0 97 PRUint32 i;
michael@0 98 nssDecodedCert *dc = c->decoding;
michael@0 99 NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
michael@0 100 NSSCryptoContext *cc = c->object.cryptoContext;
michael@0 101
michael@0 102 PR_ASSERT(c->object.refCount > 0);
michael@0 103
michael@0 104 /* --- LOCK storage --- */
michael@0 105 if (cc) {
michael@0 106 nssCertificateStore_Lock(cc->certStore, &lockTrace);
michael@0 107 } else {
michael@0 108 nssTrustDomain_LockCertCache(td);
michael@0 109 }
michael@0 110 if (PR_ATOMIC_DECREMENT(&c->object.refCount) == 0) {
michael@0 111 /* --- remove cert and UNLOCK storage --- */
michael@0 112 if (cc) {
michael@0 113 nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
michael@0 114 nssCertificateStore_Unlock(cc->certStore, &lockTrace,
michael@0 115 &unlockTrace);
michael@0 116 } else {
michael@0 117 nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
michael@0 118 nssTrustDomain_UnlockCertCache(td);
michael@0 119 }
michael@0 120 /* free cert data */
michael@0 121 for (i=0; i<c->object.numInstances; i++) {
michael@0 122 nssCryptokiObject_Destroy(c->object.instances[i]);
michael@0 123 }
michael@0 124 nssPKIObject_DestroyLock(&c->object);
michael@0 125 nssArena_Destroy(c->object.arena);
michael@0 126 nssDecodedCert_Destroy(dc);
michael@0 127 } else {
michael@0 128 /* --- UNLOCK storage --- */
michael@0 129 if (cc) {
michael@0 130 nssCertificateStore_Unlock(cc->certStore,
michael@0 131 &lockTrace,
michael@0 132 &unlockTrace);
michael@0 133 } else {
michael@0 134 nssTrustDomain_UnlockCertCache(td);
michael@0 135 }
michael@0 136 }
michael@0 137 }
michael@0 138 return PR_SUCCESS;
michael@0 139 }
michael@0 140
michael@0 141 NSS_IMPLEMENT PRStatus
michael@0 142 NSSCertificate_Destroy (
michael@0 143 NSSCertificate *c
michael@0 144 )
michael@0 145 {
michael@0 146 return nssCertificate_Destroy(c);
michael@0 147 }
michael@0 148
michael@0 149 NSS_IMPLEMENT NSSDER *
michael@0 150 nssCertificate_GetEncoding (
michael@0 151 NSSCertificate *c
michael@0 152 )
michael@0 153 {
michael@0 154 if (c->encoding.size > 0 && c->encoding.data) {
michael@0 155 return &c->encoding;
michael@0 156 } else {
michael@0 157 return (NSSDER *)NULL;
michael@0 158 }
michael@0 159 }
michael@0 160
michael@0 161 NSS_IMPLEMENT NSSDER *
michael@0 162 nssCertificate_GetIssuer (
michael@0 163 NSSCertificate *c
michael@0 164 )
michael@0 165 {
michael@0 166 if (c->issuer.size > 0 && c->issuer.data) {
michael@0 167 return &c->issuer;
michael@0 168 } else {
michael@0 169 return (NSSDER *)NULL;
michael@0 170 }
michael@0 171 }
michael@0 172
michael@0 173 NSS_IMPLEMENT NSSDER *
michael@0 174 nssCertificate_GetSerialNumber (
michael@0 175 NSSCertificate *c
michael@0 176 )
michael@0 177 {
michael@0 178 if (c->serial.size > 0 && c->serial.data) {
michael@0 179 return &c->serial;
michael@0 180 } else {
michael@0 181 return (NSSDER *)NULL;
michael@0 182 }
michael@0 183 }
michael@0 184
michael@0 185 NSS_IMPLEMENT NSSDER *
michael@0 186 nssCertificate_GetSubject (
michael@0 187 NSSCertificate *c
michael@0 188 )
michael@0 189 {
michael@0 190 if (c->subject.size > 0 && c->subject.data) {
michael@0 191 return &c->subject;
michael@0 192 } else {
michael@0 193 return (NSSDER *)NULL;
michael@0 194 }
michael@0 195 }
michael@0 196
michael@0 197 /* Returns a copy, Caller must free using nss_ZFreeIf */
michael@0 198 NSS_IMPLEMENT NSSUTF8 *
michael@0 199 nssCertificate_GetNickname (
michael@0 200 NSSCertificate *c,
michael@0 201 NSSToken *tokenOpt
michael@0 202 )
michael@0 203 {
michael@0 204 return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
michael@0 205 }
michael@0 206
michael@0 207 NSS_IMPLEMENT NSSASCII7 *
michael@0 208 nssCertificate_GetEmailAddress (
michael@0 209 NSSCertificate *c
michael@0 210 )
michael@0 211 {
michael@0 212 return c->email;
michael@0 213 }
michael@0 214
michael@0 215 NSS_IMPLEMENT PRStatus
michael@0 216 NSSCertificate_DeleteStoredObject (
michael@0 217 NSSCertificate *c,
michael@0 218 NSSCallback *uhh
michael@0 219 )
michael@0 220 {
michael@0 221 return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE);
michael@0 222 }
michael@0 223
michael@0 224 NSS_IMPLEMENT PRStatus
michael@0 225 NSSCertificate_Validate (
michael@0 226 NSSCertificate *c,
michael@0 227 NSSTime *timeOpt, /* NULL for "now" */
michael@0 228 NSSUsage *usage,
michael@0 229 NSSPolicies *policiesOpt /* NULL for none */
michael@0 230 )
michael@0 231 {
michael@0 232 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 233 return PR_FAILURE;
michael@0 234 }
michael@0 235
michael@0 236 NSS_IMPLEMENT void ** /* void *[] */
michael@0 237 NSSCertificate_ValidateCompletely (
michael@0 238 NSSCertificate *c,
michael@0 239 NSSTime *timeOpt, /* NULL for "now" */
michael@0 240 NSSUsage *usage,
michael@0 241 NSSPolicies *policiesOpt, /* NULL for none */
michael@0 242 void **rvOpt, /* NULL for allocate */
michael@0 243 PRUint32 rvLimit, /* zero for no limit */
michael@0 244 NSSArena *arenaOpt /* NULL for heap */
michael@0 245 )
michael@0 246 {
michael@0 247 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 248 return NULL;
michael@0 249 }
michael@0 250
michael@0 251 NSS_IMPLEMENT PRStatus
michael@0 252 NSSCertificate_ValidateAndDiscoverUsagesAndPolicies (
michael@0 253 NSSCertificate *c,
michael@0 254 NSSTime **notBeforeOutOpt,
michael@0 255 NSSTime **notAfterOutOpt,
michael@0 256 void *allowedUsages,
michael@0 257 void *disallowedUsages,
michael@0 258 void *allowedPolicies,
michael@0 259 void *disallowedPolicies,
michael@0 260 /* more args.. work on this fgmr */
michael@0 261 NSSArena *arenaOpt
michael@0 262 )
michael@0 263 {
michael@0 264 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 265 return PR_FAILURE;
michael@0 266 }
michael@0 267
michael@0 268 NSS_IMPLEMENT NSSDER *
michael@0 269 NSSCertificate_Encode (
michael@0 270 NSSCertificate *c,
michael@0 271 NSSDER *rvOpt,
michael@0 272 NSSArena *arenaOpt
michael@0 273 )
michael@0 274 {
michael@0 275 /* Item, DER, BER are all typedefs now... */
michael@0 276 return nssItem_Duplicate((NSSItem *)&c->encoding, arenaOpt, rvOpt);
michael@0 277 }
michael@0 278
michael@0 279 NSS_IMPLEMENT nssDecodedCert *
michael@0 280 nssCertificate_GetDecoding (
michael@0 281 NSSCertificate *c
michael@0 282 )
michael@0 283 {
michael@0 284 nssDecodedCert* deco = NULL;
michael@0 285 if (c->type == NSSCertificateType_PKIX) {
michael@0 286 (void)STAN_GetCERTCertificate(c);
michael@0 287 }
michael@0 288 nssPKIObject_Lock(&c->object);
michael@0 289 if (!c->decoding) {
michael@0 290 deco = nssDecodedCert_Create(NULL, &c->encoding, c->type);
michael@0 291 PORT_Assert(!c->decoding);
michael@0 292 c->decoding = deco;
michael@0 293 } else {
michael@0 294 deco = c->decoding;
michael@0 295 }
michael@0 296 nssPKIObject_Unlock(&c->object);
michael@0 297 return deco;
michael@0 298 }
michael@0 299
michael@0 300 static NSSCertificate **
michael@0 301 filter_subject_certs_for_id (
michael@0 302 NSSCertificate **subjectCerts,
michael@0 303 void *id
michael@0 304 )
michael@0 305 {
michael@0 306 NSSCertificate **si;
michael@0 307 nssDecodedCert *dcp;
michael@0 308 int nextOpenSlot = 0;
michael@0 309 int i;
michael@0 310 nssCertIDMatch matchLevel = nssCertIDMatch_Unknown;
michael@0 311 nssCertIDMatch match;
michael@0 312
michael@0 313 /* walk the subject certs */
michael@0 314 for (si = subjectCerts; *si; si++) {
michael@0 315 dcp = nssCertificate_GetDecoding(*si);
michael@0 316 if (!dcp) {
michael@0 317 NSSCertificate_Destroy(*si);
michael@0 318 continue;
michael@0 319 }
michael@0 320 match = dcp->matchIdentifier(dcp, id);
michael@0 321 switch (match) {
michael@0 322 case nssCertIDMatch_Yes:
michael@0 323 if (matchLevel == nssCertIDMatch_Unknown) {
michael@0 324 /* we have non-definitive matches, forget them */
michael@0 325 for (i = 0; i < nextOpenSlot; i++) {
michael@0 326 NSSCertificate_Destroy(subjectCerts[i]);
michael@0 327 subjectCerts[i] = NULL;
michael@0 328 }
michael@0 329 nextOpenSlot = 0;
michael@0 330 /* only keep definitive matches from now on */
michael@0 331 matchLevel = nssCertIDMatch_Yes;
michael@0 332 }
michael@0 333 /* keep the cert */
michael@0 334 subjectCerts[nextOpenSlot++] = *si;
michael@0 335 break;
michael@0 336 case nssCertIDMatch_Unknown:
michael@0 337 if (matchLevel == nssCertIDMatch_Unknown) {
michael@0 338 /* only have non-definitive matches so far, keep it */
michael@0 339 subjectCerts[nextOpenSlot++] = *si;
michael@0 340 break;
michael@0 341 }
michael@0 342 /* else fall through, we have a definitive match already */
michael@0 343 case nssCertIDMatch_No:
michael@0 344 default:
michael@0 345 NSSCertificate_Destroy(*si);
michael@0 346 *si = NULL;
michael@0 347 }
michael@0 348 }
michael@0 349 subjectCerts[nextOpenSlot] = NULL;
michael@0 350 return subjectCerts;
michael@0 351 }
michael@0 352
michael@0 353 static NSSCertificate **
michael@0 354 filter_certs_for_valid_issuers (
michael@0 355 NSSCertificate **certs
michael@0 356 )
michael@0 357 {
michael@0 358 NSSCertificate **cp;
michael@0 359 nssDecodedCert *dcp;
michael@0 360 int nextOpenSlot = 0;
michael@0 361
michael@0 362 for (cp = certs; *cp; cp++) {
michael@0 363 dcp = nssCertificate_GetDecoding(*cp);
michael@0 364 if (dcp && dcp->isValidIssuer(dcp)) {
michael@0 365 certs[nextOpenSlot++] = *cp;
michael@0 366 } else {
michael@0 367 NSSCertificate_Destroy(*cp);
michael@0 368 }
michael@0 369 }
michael@0 370 certs[nextOpenSlot] = NULL;
michael@0 371 return certs;
michael@0 372 }
michael@0 373
michael@0 374 static NSSCertificate *
michael@0 375 find_cert_issuer (
michael@0 376 NSSCertificate *c,
michael@0 377 NSSTime *timeOpt,
michael@0 378 NSSUsage *usage,
michael@0 379 NSSPolicies *policiesOpt,
michael@0 380 NSSTrustDomain *td,
michael@0 381 NSSCryptoContext *cc
michael@0 382 )
michael@0 383 {
michael@0 384 NSSArena *arena;
michael@0 385 NSSCertificate **certs = NULL;
michael@0 386 NSSCertificate **ccIssuers = NULL;
michael@0 387 NSSCertificate **tdIssuers = NULL;
michael@0 388 NSSCertificate *issuer = NULL;
michael@0 389
michael@0 390 if (!cc)
michael@0 391 cc = c->object.cryptoContext;
michael@0 392 if (!td)
michael@0 393 td = NSSCertificate_GetTrustDomain(c);
michael@0 394 arena = nssArena_Create();
michael@0 395 if (!arena) {
michael@0 396 return (NSSCertificate *)NULL;
michael@0 397 }
michael@0 398 if (cc) {
michael@0 399 ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
michael@0 400 &c->issuer,
michael@0 401 NULL,
michael@0 402 0,
michael@0 403 arena);
michael@0 404 }
michael@0 405 if (td)
michael@0 406 tdIssuers = nssTrustDomain_FindCertificatesBySubject(td,
michael@0 407 &c->issuer,
michael@0 408 NULL,
michael@0 409 0,
michael@0 410 arena);
michael@0 411 certs = nssCertificateArray_Join(ccIssuers, tdIssuers);
michael@0 412 if (certs) {
michael@0 413 nssDecodedCert *dc = NULL;
michael@0 414 void *issuerID = NULL;
michael@0 415 dc = nssCertificate_GetDecoding(c);
michael@0 416 if (dc) {
michael@0 417 issuerID = dc->getIssuerIdentifier(dc);
michael@0 418 }
michael@0 419 /* XXX review based on CERT_FindCertIssuer
michael@0 420 * this function is not using the authCertIssuer field as a fallback
michael@0 421 * if authority key id does not exist
michael@0 422 */
michael@0 423 if (issuerID) {
michael@0 424 certs = filter_subject_certs_for_id(certs, issuerID);
michael@0 425 }
michael@0 426 certs = filter_certs_for_valid_issuers(certs);
michael@0 427 issuer = nssCertificateArray_FindBestCertificate(certs,
michael@0 428 timeOpt,
michael@0 429 usage,
michael@0 430 policiesOpt);
michael@0 431 nssCertificateArray_Destroy(certs);
michael@0 432 }
michael@0 433 nssArena_Destroy(arena);
michael@0 434 return issuer;
michael@0 435 }
michael@0 436
michael@0 437 /* This function returns the built chain, as far as it gets,
michael@0 438 ** even if/when it fails to find an issuer, and returns PR_FAILURE
michael@0 439 */
michael@0 440 NSS_IMPLEMENT NSSCertificate **
michael@0 441 nssCertificate_BuildChain (
michael@0 442 NSSCertificate *c,
michael@0 443 NSSTime *timeOpt,
michael@0 444 NSSUsage *usage,
michael@0 445 NSSPolicies *policiesOpt,
michael@0 446 NSSCertificate **rvOpt,
michael@0 447 PRUint32 rvLimit,
michael@0 448 NSSArena *arenaOpt,
michael@0 449 PRStatus *statusOpt,
michael@0 450 NSSTrustDomain *td,
michael@0 451 NSSCryptoContext *cc
michael@0 452 )
michael@0 453 {
michael@0 454 NSSCertificate **rvChain = NULL;
michael@0 455 NSSUsage issuerUsage = *usage;
michael@0 456 nssPKIObjectCollection *collection = NULL;
michael@0 457 PRUint32 rvCount = 0;
michael@0 458 PRStatus st;
michael@0 459 PRStatus ret = PR_SUCCESS;
michael@0 460
michael@0 461 if (!c || !cc ||
michael@0 462 (!td && (td = NSSCertificate_GetTrustDomain(c)) == NULL)) {
michael@0 463 goto loser;
michael@0 464 }
michael@0 465 /* bump the usage up to CA level */
michael@0 466 issuerUsage.nss3lookingForCA = PR_TRUE;
michael@0 467 collection = nssCertificateCollection_Create(td, NULL);
michael@0 468 if (!collection)
michael@0 469 goto loser;
michael@0 470 st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
michael@0 471 if (st != PR_SUCCESS)
michael@0 472 goto loser;
michael@0 473 for (rvCount = 1; (!rvLimit || rvCount < rvLimit); ++rvCount) {
michael@0 474 CERTCertificate *cCert = STAN_GetCERTCertificate(c);
michael@0 475 if (cCert->isRoot) {
michael@0 476 /* not including the issuer of the self-signed cert, which is,
michael@0 477 * of course, itself
michael@0 478 */
michael@0 479 break;
michael@0 480 }
michael@0 481 c = find_cert_issuer(c, timeOpt, &issuerUsage, policiesOpt, td, cc);
michael@0 482 if (!c) {
michael@0 483 ret = PR_FAILURE;
michael@0 484 break;
michael@0 485 }
michael@0 486 st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
michael@0 487 nssCertificate_Destroy(c); /* collection has it */
michael@0 488 if (st != PR_SUCCESS)
michael@0 489 goto loser;
michael@0 490 }
michael@0 491 rvChain = nssPKIObjectCollection_GetCertificates(collection,
michael@0 492 rvOpt,
michael@0 493 rvLimit,
michael@0 494 arenaOpt);
michael@0 495 if (rvChain) {
michael@0 496 nssPKIObjectCollection_Destroy(collection);
michael@0 497 if (statusOpt)
michael@0 498 *statusOpt = ret;
michael@0 499 if (ret != PR_SUCCESS)
michael@0 500 nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
michael@0 501 return rvChain;
michael@0 502 }
michael@0 503
michael@0 504 loser:
michael@0 505 if (collection)
michael@0 506 nssPKIObjectCollection_Destroy(collection);
michael@0 507 if (statusOpt)
michael@0 508 *statusOpt = PR_FAILURE;
michael@0 509 nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
michael@0 510 return rvChain;
michael@0 511 }
michael@0 512
michael@0 513 NSS_IMPLEMENT NSSCertificate **
michael@0 514 NSSCertificate_BuildChain (
michael@0 515 NSSCertificate *c,
michael@0 516 NSSTime *timeOpt,
michael@0 517 NSSUsage *usage,
michael@0 518 NSSPolicies *policiesOpt,
michael@0 519 NSSCertificate **rvOpt,
michael@0 520 PRUint32 rvLimit, /* zero for no limit */
michael@0 521 NSSArena *arenaOpt,
michael@0 522 PRStatus *statusOpt,
michael@0 523 NSSTrustDomain *td,
michael@0 524 NSSCryptoContext *cc
michael@0 525 )
michael@0 526 {
michael@0 527 return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt,
michael@0 528 rvOpt, rvLimit, arenaOpt, statusOpt,
michael@0 529 td, cc);
michael@0 530 }
michael@0 531
michael@0 532 NSS_IMPLEMENT NSSCryptoContext *
michael@0 533 nssCertificate_GetCryptoContext (
michael@0 534 NSSCertificate *c
michael@0 535 )
michael@0 536 {
michael@0 537 return c->object.cryptoContext;
michael@0 538 }
michael@0 539
michael@0 540 NSS_IMPLEMENT NSSTrustDomain *
michael@0 541 nssCertificate_GetTrustDomain (
michael@0 542 NSSCertificate *c
michael@0 543 )
michael@0 544 {
michael@0 545 return c->object.trustDomain;
michael@0 546 }
michael@0 547
michael@0 548 NSS_IMPLEMENT NSSTrustDomain *
michael@0 549 NSSCertificate_GetTrustDomain (
michael@0 550 NSSCertificate *c
michael@0 551 )
michael@0 552 {
michael@0 553 return nssCertificate_GetTrustDomain(c);
michael@0 554 }
michael@0 555
michael@0 556 NSS_IMPLEMENT NSSToken *
michael@0 557 NSSCertificate_GetToken (
michael@0 558 NSSCertificate *c,
michael@0 559 PRStatus *statusOpt
michael@0 560 )
michael@0 561 {
michael@0 562 return (NSSToken *)NULL;
michael@0 563 }
michael@0 564
michael@0 565 NSS_IMPLEMENT NSSSlot *
michael@0 566 NSSCertificate_GetSlot (
michael@0 567 NSSCertificate *c,
michael@0 568 PRStatus *statusOpt
michael@0 569 )
michael@0 570 {
michael@0 571 return (NSSSlot *)NULL;
michael@0 572 }
michael@0 573
michael@0 574 NSS_IMPLEMENT NSSModule *
michael@0 575 NSSCertificate_GetModule (
michael@0 576 NSSCertificate *c,
michael@0 577 PRStatus *statusOpt
michael@0 578 )
michael@0 579 {
michael@0 580 return (NSSModule *)NULL;
michael@0 581 }
michael@0 582
michael@0 583 NSS_IMPLEMENT NSSItem *
michael@0 584 NSSCertificate_Encrypt (
michael@0 585 NSSCertificate *c,
michael@0 586 NSSAlgorithmAndParameters *apOpt,
michael@0 587 NSSItem *data,
michael@0 588 NSSTime *timeOpt,
michael@0 589 NSSUsage *usage,
michael@0 590 NSSPolicies *policiesOpt,
michael@0 591 NSSCallback *uhh,
michael@0 592 NSSItem *rvOpt,
michael@0 593 NSSArena *arenaOpt
michael@0 594 )
michael@0 595 {
michael@0 596 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 597 return NULL;
michael@0 598 }
michael@0 599
michael@0 600 NSS_IMPLEMENT PRStatus
michael@0 601 NSSCertificate_Verify (
michael@0 602 NSSCertificate *c,
michael@0 603 NSSAlgorithmAndParameters *apOpt,
michael@0 604 NSSItem *data,
michael@0 605 NSSItem *signature,
michael@0 606 NSSTime *timeOpt,
michael@0 607 NSSUsage *usage,
michael@0 608 NSSPolicies *policiesOpt,
michael@0 609 NSSCallback *uhh
michael@0 610 )
michael@0 611 {
michael@0 612 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 613 return PR_FAILURE;
michael@0 614 }
michael@0 615
michael@0 616 NSS_IMPLEMENT NSSItem *
michael@0 617 NSSCertificate_VerifyRecover (
michael@0 618 NSSCertificate *c,
michael@0 619 NSSAlgorithmAndParameters *apOpt,
michael@0 620 NSSItem *signature,
michael@0 621 NSSTime *timeOpt,
michael@0 622 NSSUsage *usage,
michael@0 623 NSSPolicies *policiesOpt,
michael@0 624 NSSCallback *uhh,
michael@0 625 NSSItem *rvOpt,
michael@0 626 NSSArena *arenaOpt
michael@0 627 )
michael@0 628 {
michael@0 629 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 630 return NULL;
michael@0 631 }
michael@0 632
michael@0 633 NSS_IMPLEMENT NSSItem *
michael@0 634 NSSCertificate_WrapSymmetricKey (
michael@0 635 NSSCertificate *c,
michael@0 636 NSSAlgorithmAndParameters *apOpt,
michael@0 637 NSSSymmetricKey *keyToWrap,
michael@0 638 NSSTime *timeOpt,
michael@0 639 NSSUsage *usage,
michael@0 640 NSSPolicies *policiesOpt,
michael@0 641 NSSCallback *uhh,
michael@0 642 NSSItem *rvOpt,
michael@0 643 NSSArena *arenaOpt
michael@0 644 )
michael@0 645 {
michael@0 646 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 647 return NULL;
michael@0 648 }
michael@0 649
michael@0 650 NSS_IMPLEMENT NSSCryptoContext *
michael@0 651 NSSCertificate_CreateCryptoContext (
michael@0 652 NSSCertificate *c,
michael@0 653 NSSAlgorithmAndParameters *apOpt,
michael@0 654 NSSTime *timeOpt,
michael@0 655 NSSUsage *usage,
michael@0 656 NSSPolicies *policiesOpt,
michael@0 657 NSSCallback *uhh
michael@0 658 )
michael@0 659 {
michael@0 660 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 661 return NULL;
michael@0 662 }
michael@0 663
michael@0 664 NSS_IMPLEMENT NSSPublicKey *
michael@0 665 NSSCertificate_GetPublicKey (
michael@0 666 NSSCertificate *c
michael@0 667 )
michael@0 668 {
michael@0 669 #if 0
michael@0 670 CK_ATTRIBUTE pubktemplate[] = {
michael@0 671 { CKA_CLASS, NULL, 0 },
michael@0 672 { CKA_ID, NULL, 0 },
michael@0 673 { CKA_SUBJECT, NULL, 0 }
michael@0 674 };
michael@0 675 PRStatus nssrv;
michael@0 676 CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
michael@0 677 NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
michael@0 678 if (c->id.size > 0) {
michael@0 679 /* CKA_ID */
michael@0 680 NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]);
michael@0 681 } else {
michael@0 682 /* failure, yes? */
michael@0 683 return (NSSPublicKey *)NULL;
michael@0 684 }
michael@0 685 if (c->subject.size > 0) {
michael@0 686 /* CKA_SUBJECT */
michael@0 687 NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]);
michael@0 688 } else {
michael@0 689 /* failure, yes? */
michael@0 690 return (NSSPublicKey *)NULL;
michael@0 691 }
michael@0 692 /* Try the cert's token first */
michael@0 693 if (c->token) {
michael@0 694 nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
michael@0 695 }
michael@0 696 #endif
michael@0 697 /* Try all other key tokens */
michael@0 698 return (NSSPublicKey *)NULL;
michael@0 699 }
michael@0 700
michael@0 701 NSS_IMPLEMENT NSSPrivateKey *
michael@0 702 NSSCertificate_FindPrivateKey (
michael@0 703 NSSCertificate *c,
michael@0 704 NSSCallback *uhh
michael@0 705 )
michael@0 706 {
michael@0 707 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 708 return NULL;
michael@0 709 }
michael@0 710
michael@0 711 NSS_IMPLEMENT PRBool
michael@0 712 NSSCertificate_IsPrivateKeyAvailable (
michael@0 713 NSSCertificate *c,
michael@0 714 NSSCallback *uhh,
michael@0 715 PRStatus *statusOpt
michael@0 716 )
michael@0 717 {
michael@0 718 PRBool isUser = PR_FALSE;
michael@0 719 nssCryptokiObject **ip;
michael@0 720 nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
michael@0 721 if (!instances) {
michael@0 722 return PR_FALSE;
michael@0 723 }
michael@0 724 for (ip = instances; *ip; ip++) {
michael@0 725 nssCryptokiObject *instance = *ip;
michael@0 726 if (nssToken_IsPrivateKeyAvailable(instance->token, c, instance)) {
michael@0 727 isUser = PR_TRUE;
michael@0 728 }
michael@0 729 }
michael@0 730 nssCryptokiObjectArray_Destroy(instances);
michael@0 731 return isUser;
michael@0 732 }
michael@0 733
michael@0 734 /* sort the subject cert list from newest to oldest */
michael@0 735 PRIntn
michael@0 736 nssCertificate_SubjectListSort (
michael@0 737 void *v1,
michael@0 738 void *v2
michael@0 739 )
michael@0 740 {
michael@0 741 NSSCertificate *c1 = (NSSCertificate *)v1;
michael@0 742 NSSCertificate *c2 = (NSSCertificate *)v2;
michael@0 743 nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
michael@0 744 nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
michael@0 745 if (!dc1) {
michael@0 746 return dc2 ? 1 : 0;
michael@0 747 } else if (!dc2) {
michael@0 748 return -1;
michael@0 749 } else {
michael@0 750 return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
michael@0 751 }
michael@0 752 }
michael@0 753
michael@0 754 NSS_IMPLEMENT PRBool
michael@0 755 NSSUserCertificate_IsStillPresent (
michael@0 756 NSSUserCertificate *uc,
michael@0 757 PRStatus *statusOpt
michael@0 758 )
michael@0 759 {
michael@0 760 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 761 return PR_FALSE;
michael@0 762 }
michael@0 763
michael@0 764 NSS_IMPLEMENT NSSItem *
michael@0 765 NSSUserCertificate_Decrypt (
michael@0 766 NSSUserCertificate *uc,
michael@0 767 NSSAlgorithmAndParameters *apOpt,
michael@0 768 NSSItem *data,
michael@0 769 NSSTime *timeOpt,
michael@0 770 NSSUsage *usage,
michael@0 771 NSSPolicies *policiesOpt,
michael@0 772 NSSCallback *uhh,
michael@0 773 NSSItem *rvOpt,
michael@0 774 NSSArena *arenaOpt
michael@0 775 )
michael@0 776 {
michael@0 777 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 778 return NULL;
michael@0 779 }
michael@0 780
michael@0 781 NSS_IMPLEMENT NSSItem *
michael@0 782 NSSUserCertificate_Sign (
michael@0 783 NSSUserCertificate *uc,
michael@0 784 NSSAlgorithmAndParameters *apOpt,
michael@0 785 NSSItem *data,
michael@0 786 NSSTime *timeOpt,
michael@0 787 NSSUsage *usage,
michael@0 788 NSSPolicies *policiesOpt,
michael@0 789 NSSCallback *uhh,
michael@0 790 NSSItem *rvOpt,
michael@0 791 NSSArena *arenaOpt
michael@0 792 )
michael@0 793 {
michael@0 794 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 795 return NULL;
michael@0 796 }
michael@0 797
michael@0 798 NSS_IMPLEMENT NSSItem *
michael@0 799 NSSUserCertificate_SignRecover (
michael@0 800 NSSUserCertificate *uc,
michael@0 801 NSSAlgorithmAndParameters *apOpt,
michael@0 802 NSSItem *data,
michael@0 803 NSSTime *timeOpt,
michael@0 804 NSSUsage *usage,
michael@0 805 NSSPolicies *policiesOpt,
michael@0 806 NSSCallback *uhh,
michael@0 807 NSSItem *rvOpt,
michael@0 808 NSSArena *arenaOpt
michael@0 809 )
michael@0 810 {
michael@0 811 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 812 return NULL;
michael@0 813 }
michael@0 814
michael@0 815 NSS_IMPLEMENT NSSSymmetricKey *
michael@0 816 NSSUserCertificate_UnwrapSymmetricKey (
michael@0 817 NSSUserCertificate *uc,
michael@0 818 NSSAlgorithmAndParameters *apOpt,
michael@0 819 NSSItem *wrappedKey,
michael@0 820 NSSTime *timeOpt,
michael@0 821 NSSUsage *usage,
michael@0 822 NSSPolicies *policiesOpt,
michael@0 823 NSSCallback *uhh,
michael@0 824 NSSItem *rvOpt,
michael@0 825 NSSArena *arenaOpt
michael@0 826 )
michael@0 827 {
michael@0 828 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 829 return NULL;
michael@0 830 }
michael@0 831
michael@0 832 NSS_IMPLEMENT NSSSymmetricKey *
michael@0 833 NSSUserCertificate_DeriveSymmetricKey (
michael@0 834 NSSUserCertificate *uc, /* provides private key */
michael@0 835 NSSCertificate *c, /* provides public key */
michael@0 836 NSSAlgorithmAndParameters *apOpt,
michael@0 837 NSSOID *target,
michael@0 838 PRUint32 keySizeOpt, /* zero for best allowed */
michael@0 839 NSSOperations operations,
michael@0 840 NSSCallback *uhh
michael@0 841 )
michael@0 842 {
michael@0 843 nss_SetError(NSS_ERROR_NOT_FOUND);
michael@0 844 return NULL;
michael@0 845 }
michael@0 846
michael@0 847 NSS_IMPLEMENT nssSMIMEProfile *
michael@0 848 nssSMIMEProfile_Create (
michael@0 849 NSSCertificate *cert,
michael@0 850 NSSItem *profileTime,
michael@0 851 NSSItem *profileData
michael@0 852 )
michael@0 853 {
michael@0 854 NSSArena *arena;
michael@0 855 nssSMIMEProfile *rvProfile;
michael@0 856 nssPKIObject *object;
michael@0 857 NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert);
michael@0 858 NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
michael@0 859 arena = nssArena_Create();
michael@0 860 if (!arena) {
michael@0 861 return NULL;
michael@0 862 }
michael@0 863 object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock);
michael@0 864 if (!object) {
michael@0 865 goto loser;
michael@0 866 }
michael@0 867 rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
michael@0 868 if (!rvProfile) {
michael@0 869 goto loser;
michael@0 870 }
michael@0 871 rvProfile->object = *object;
michael@0 872 rvProfile->certificate = cert;
michael@0 873 rvProfile->email = nssUTF8_Duplicate(cert->email, arena);
michael@0 874 rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL);
michael@0 875 if (profileTime) {
michael@0 876 rvProfile->profileTime = nssItem_Duplicate(profileTime, arena, NULL);
michael@0 877 }
michael@0 878 if (profileData) {
michael@0 879 rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL);
michael@0 880 }
michael@0 881 return rvProfile;
michael@0 882 loser:
michael@0 883 if (object) nssPKIObject_Destroy(object);
michael@0 884 else if (arena) nssArena_Destroy(arena);
michael@0 885 return (nssSMIMEProfile *)NULL;
michael@0 886 }
michael@0 887
michael@0 888 /* execute a callback function on all members of a cert list */
michael@0 889 NSS_EXTERN PRStatus
michael@0 890 nssCertificateList_DoCallback (
michael@0 891 nssList *certList,
michael@0 892 PRStatus (* callback)(NSSCertificate *c, void *arg),
michael@0 893 void *arg
michael@0 894 )
michael@0 895 {
michael@0 896 nssListIterator *certs;
michael@0 897 NSSCertificate *cert;
michael@0 898 PRStatus nssrv;
michael@0 899 certs = nssList_CreateIterator(certList);
michael@0 900 if (!certs) {
michael@0 901 return PR_FAILURE;
michael@0 902 }
michael@0 903 for (cert = (NSSCertificate *)nssListIterator_Start(certs);
michael@0 904 cert != (NSSCertificate *)NULL;
michael@0 905 cert = (NSSCertificate *)nssListIterator_Next(certs))
michael@0 906 {
michael@0 907 nssrv = (*callback)(cert, arg);
michael@0 908 }
michael@0 909 nssListIterator_Finish(certs);
michael@0 910 nssListIterator_Destroy(certs);
michael@0 911 return PR_SUCCESS;
michael@0 912 }
michael@0 913
michael@0 914 static PRStatus add_ref_callback(NSSCertificate *c, void *a)
michael@0 915 {
michael@0 916 nssCertificate_AddRef(c);
michael@0 917 return PR_SUCCESS;
michael@0 918 }
michael@0 919
michael@0 920 NSS_IMPLEMENT void
michael@0 921 nssCertificateList_AddReferences (
michael@0 922 nssList *certList
michael@0 923 )
michael@0 924 {
michael@0 925 (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL);
michael@0 926 }
michael@0 927
michael@0 928
michael@0 929 /*
michael@0 930 * Is this trust record safe to apply to all certs of the same issuer/SN
michael@0 931 * independent of the cert matching the hash. This is only true is the trust
michael@0 932 * is unknown or distrusted. In general this feature is only useful to
michael@0 933 * explicitly distrusting certs. It is not safe to use to trust certs, so
michael@0 934 * only allow unknown and untrusted trust types.
michael@0 935 */
michael@0 936 PRBool
michael@0 937 nssTrust_IsSafeToIgnoreCertHash(nssTrustLevel serverAuth,
michael@0 938 nssTrustLevel clientAuth, nssTrustLevel codeSigning,
michael@0 939 nssTrustLevel email, PRBool stepup)
michael@0 940 {
michael@0 941 /* step up is a trust type, if it's on, we must have a hash for the cert */
michael@0 942 if (stepup) {
michael@0 943 return PR_FALSE;
michael@0 944 }
michael@0 945 if ((serverAuth != nssTrustLevel_Unknown) &&
michael@0 946 (serverAuth != nssTrustLevel_NotTrusted)) {
michael@0 947 return PR_FALSE;
michael@0 948 }
michael@0 949 if ((clientAuth != nssTrustLevel_Unknown) &&
michael@0 950 (clientAuth != nssTrustLevel_NotTrusted)) {
michael@0 951 return PR_FALSE;
michael@0 952 }
michael@0 953 if ((codeSigning != nssTrustLevel_Unknown) &&
michael@0 954 (codeSigning != nssTrustLevel_NotTrusted)) {
michael@0 955 return PR_FALSE;
michael@0 956 }
michael@0 957 if ((email != nssTrustLevel_Unknown) &&
michael@0 958 (email != nssTrustLevel_NotTrusted)) {
michael@0 959 return PR_FALSE;
michael@0 960 }
michael@0 961 /* record only has Unknown and Untrusted entries, ok to accept without a
michael@0 962 * hash */
michael@0 963 return PR_TRUE;
michael@0 964 }
michael@0 965
michael@0 966 NSS_IMPLEMENT NSSTrust *
michael@0 967 nssTrust_Create (
michael@0 968 nssPKIObject *object,
michael@0 969 NSSItem *certData
michael@0 970 )
michael@0 971 {
michael@0 972 PRStatus status;
michael@0 973 PRUint32 i;
michael@0 974 PRUint32 lastTrustOrder, myTrustOrder;
michael@0 975 unsigned char sha1_hashcmp[SHA1_LENGTH];
michael@0 976 unsigned char sha1_hashin[SHA1_LENGTH];
michael@0 977 NSSItem sha1_hash;
michael@0 978 NSSTrust *rvt;
michael@0 979 nssCryptokiObject *instance;
michael@0 980 nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection;
michael@0 981 SECStatus rv; /* Should be stan flavor */
michael@0 982 PRBool stepUp;
michael@0 983
michael@0 984 lastTrustOrder = 1<<16; /* just make it big */
michael@0 985 PR_ASSERT(object->instances != NULL && object->numInstances > 0);
michael@0 986 rvt = nss_ZNEW(object->arena, NSSTrust);
michael@0 987 if (!rvt) {
michael@0 988 return (NSSTrust *)NULL;
michael@0 989 }
michael@0 990 rvt->object = *object;
michael@0 991
michael@0 992 /* should be stan flavor of Hashbuf */
michael@0 993 rv = PK11_HashBuf(SEC_OID_SHA1,sha1_hashcmp,certData->data,certData->size);
michael@0 994 if (rv != SECSuccess) {
michael@0 995 return (NSSTrust *)NULL;
michael@0 996 }
michael@0 997 sha1_hash.data = sha1_hashin;
michael@0 998 sha1_hash.size = sizeof (sha1_hashin);
michael@0 999 /* trust has to peek into the base object members */
michael@0 1000 nssPKIObject_Lock(object);
michael@0 1001 for (i=0; i<object->numInstances; i++) {
michael@0 1002 instance = object->instances[i];
michael@0 1003 myTrustOrder = nssToken_GetTrustOrder(instance->token);
michael@0 1004 status = nssCryptokiTrust_GetAttributes(instance, NULL,
michael@0 1005 &sha1_hash,
michael@0 1006 &serverAuth,
michael@0 1007 &clientAuth,
michael@0 1008 &codeSigning,
michael@0 1009 &emailProtection,
michael@0 1010 &stepUp);
michael@0 1011 if (status != PR_SUCCESS) {
michael@0 1012 nssPKIObject_Unlock(object);
michael@0 1013 return (NSSTrust *)NULL;
michael@0 1014 }
michael@0 1015 /* if no hash is specified, then trust applies to all certs with
michael@0 1016 * this issuer/SN. NOTE: This is only true for entries that
michael@0 1017 * have distrust and unknown record */
michael@0 1018 if (!(
michael@0 1019 /* we continue if there is no hash, and the trust type is
michael@0 1020 * safe to accept without a hash ... or ... */
michael@0 1021 ((sha1_hash.size == 0) &&
michael@0 1022 nssTrust_IsSafeToIgnoreCertHash(serverAuth,clientAuth,
michael@0 1023 codeSigning, emailProtection,stepUp))
michael@0 1024 ||
michael@0 1025 /* we have a hash of the correct size, and it matches */
michael@0 1026 ((sha1_hash.size == SHA1_LENGTH) && (PORT_Memcmp(sha1_hashin,
michael@0 1027 sha1_hashcmp,SHA1_LENGTH) == 0)) )) {
michael@0 1028 nssPKIObject_Unlock(object);
michael@0 1029 return (NSSTrust *)NULL;
michael@0 1030 }
michael@0 1031 if (rvt->serverAuth == nssTrustLevel_Unknown ||
michael@0 1032 myTrustOrder < lastTrustOrder)
michael@0 1033 {
michael@0 1034 rvt->serverAuth = serverAuth;
michael@0 1035 }
michael@0 1036 if (rvt->clientAuth == nssTrustLevel_Unknown ||
michael@0 1037 myTrustOrder < lastTrustOrder)
michael@0 1038 {
michael@0 1039 rvt->clientAuth = clientAuth;
michael@0 1040 }
michael@0 1041 if (rvt->emailProtection == nssTrustLevel_Unknown ||
michael@0 1042 myTrustOrder < lastTrustOrder)
michael@0 1043 {
michael@0 1044 rvt->emailProtection = emailProtection;
michael@0 1045 }
michael@0 1046 if (rvt->codeSigning == nssTrustLevel_Unknown ||
michael@0 1047 myTrustOrder < lastTrustOrder)
michael@0 1048 {
michael@0 1049 rvt->codeSigning = codeSigning;
michael@0 1050 }
michael@0 1051 rvt->stepUpApproved = stepUp;
michael@0 1052 lastTrustOrder = myTrustOrder;
michael@0 1053 }
michael@0 1054 nssPKIObject_Unlock(object);
michael@0 1055 return rvt;
michael@0 1056 }
michael@0 1057
michael@0 1058 NSS_IMPLEMENT NSSTrust *
michael@0 1059 nssTrust_AddRef (
michael@0 1060 NSSTrust *trust
michael@0 1061 )
michael@0 1062 {
michael@0 1063 if (trust) {
michael@0 1064 nssPKIObject_AddRef(&trust->object);
michael@0 1065 }
michael@0 1066 return trust;
michael@0 1067 }
michael@0 1068
michael@0 1069 NSS_IMPLEMENT PRStatus
michael@0 1070 nssTrust_Destroy (
michael@0 1071 NSSTrust *trust
michael@0 1072 )
michael@0 1073 {
michael@0 1074 if (trust) {
michael@0 1075 (void)nssPKIObject_Destroy(&trust->object);
michael@0 1076 }
michael@0 1077 return PR_SUCCESS;
michael@0 1078 }
michael@0 1079
michael@0 1080 NSS_IMPLEMENT nssSMIMEProfile *
michael@0 1081 nssSMIMEProfile_AddRef (
michael@0 1082 nssSMIMEProfile *profile
michael@0 1083 )
michael@0 1084 {
michael@0 1085 if (profile) {
michael@0 1086 nssPKIObject_AddRef(&profile->object);
michael@0 1087 }
michael@0 1088 return profile;
michael@0 1089 }
michael@0 1090
michael@0 1091 NSS_IMPLEMENT PRStatus
michael@0 1092 nssSMIMEProfile_Destroy (
michael@0 1093 nssSMIMEProfile *profile
michael@0 1094 )
michael@0 1095 {
michael@0 1096 if (profile) {
michael@0 1097 (void)nssPKIObject_Destroy(&profile->object);
michael@0 1098 }
michael@0 1099 return PR_SUCCESS;
michael@0 1100 }
michael@0 1101
michael@0 1102 NSS_IMPLEMENT NSSCRL *
michael@0 1103 nssCRL_Create (
michael@0 1104 nssPKIObject *object
michael@0 1105 )
michael@0 1106 {
michael@0 1107 PRStatus status;
michael@0 1108 NSSCRL *rvCRL;
michael@0 1109 NSSArena *arena = object->arena;
michael@0 1110 PR_ASSERT(object->instances != NULL && object->numInstances > 0);
michael@0 1111 rvCRL = nss_ZNEW(arena, NSSCRL);
michael@0 1112 if (!rvCRL) {
michael@0 1113 return (NSSCRL *)NULL;
michael@0 1114 }
michael@0 1115 rvCRL->object = *object;
michael@0 1116 /* XXX should choose instance based on some criteria */
michael@0 1117 status = nssCryptokiCRL_GetAttributes(object->instances[0],
michael@0 1118 NULL, /* XXX sessionOpt */
michael@0 1119 arena,
michael@0 1120 &rvCRL->encoding,
michael@0 1121 NULL, /* subject */
michael@0 1122 NULL, /* class */
michael@0 1123 &rvCRL->url,
michael@0 1124 &rvCRL->isKRL);
michael@0 1125 if (status != PR_SUCCESS) {
michael@0 1126 return (NSSCRL *)NULL;
michael@0 1127 }
michael@0 1128 return rvCRL;
michael@0 1129 }
michael@0 1130
michael@0 1131 NSS_IMPLEMENT NSSCRL *
michael@0 1132 nssCRL_AddRef (
michael@0 1133 NSSCRL *crl
michael@0 1134 )
michael@0 1135 {
michael@0 1136 if (crl) {
michael@0 1137 nssPKIObject_AddRef(&crl->object);
michael@0 1138 }
michael@0 1139 return crl;
michael@0 1140 }
michael@0 1141
michael@0 1142 NSS_IMPLEMENT PRStatus
michael@0 1143 nssCRL_Destroy (
michael@0 1144 NSSCRL *crl
michael@0 1145 )
michael@0 1146 {
michael@0 1147 if (crl) {
michael@0 1148 (void)nssPKIObject_Destroy(&crl->object);
michael@0 1149 }
michael@0 1150 return PR_SUCCESS;
michael@0 1151 }
michael@0 1152
michael@0 1153 NSS_IMPLEMENT PRStatus
michael@0 1154 nssCRL_DeleteStoredObject (
michael@0 1155 NSSCRL *crl,
michael@0 1156 NSSCallback *uhh
michael@0 1157 )
michael@0 1158 {
michael@0 1159 return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
michael@0 1160 }
michael@0 1161
michael@0 1162 NSS_IMPLEMENT NSSDER *
michael@0 1163 nssCRL_GetEncoding (
michael@0 1164 NSSCRL *crl
michael@0 1165 )
michael@0 1166 {
michael@0 1167 if (crl && crl->encoding.data != NULL && crl->encoding.size > 0) {
michael@0 1168 return &crl->encoding;
michael@0 1169 } else {
michael@0 1170 return (NSSDER *)NULL;
michael@0 1171 }
michael@0 1172 }

mercurial