security/nss/lib/pki/certificate.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/lib/pki/certificate.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1172 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +#ifndef NSSPKI_H
     1.9 +#include "nsspki.h"
    1.10 +#endif /* NSSPKI_H */
    1.11 +
    1.12 +#ifndef PKIT_H
    1.13 +#include "pkit.h"
    1.14 +#endif /* PKIT_H */
    1.15 +
    1.16 +#ifndef PKIM_H
    1.17 +#include "pkim.h"
    1.18 +#endif /* PKIM_H */
    1.19 +
    1.20 +#ifndef DEV_H
    1.21 +#include "dev.h"
    1.22 +#endif /* DEV_H */
    1.23 +
    1.24 +#include "pkistore.h"
    1.25 +
    1.26 +#include "pki3hack.h"
    1.27 +#include "pk11func.h"
    1.28 +#include "hasht.h"
    1.29 +
    1.30 +#ifndef BASE_H
    1.31 +#include "base.h"
    1.32 +#endif /* BASE_H */
    1.33 +
    1.34 +extern const NSSError NSS_ERROR_NOT_FOUND;
    1.35 +
    1.36 +/* Creates a certificate from a base object */
    1.37 +NSS_IMPLEMENT NSSCertificate *
    1.38 +nssCertificate_Create (
    1.39 +  nssPKIObject *object
    1.40 +)
    1.41 +{
    1.42 +    PRStatus status;
    1.43 +    NSSCertificate *rvCert;
    1.44 +    nssArenaMark * mark;
    1.45 +    NSSArena *arena = object->arena;
    1.46 +    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
    1.47 +    PR_ASSERT(object->lockType == nssPKIMonitor);
    1.48 +    mark = nssArena_Mark(arena);
    1.49 +    rvCert = nss_ZNEW(arena, NSSCertificate);
    1.50 +    if (!rvCert) {
    1.51 +	return (NSSCertificate *)NULL;
    1.52 +    }
    1.53 +    rvCert->object = *object;
    1.54 +    /* XXX should choose instance based on some criteria */
    1.55 +    status = nssCryptokiCertificate_GetAttributes(object->instances[0],
    1.56 +                                                  NULL,  /* XXX sessionOpt */
    1.57 +                                                  arena,
    1.58 +                                                  &rvCert->type,
    1.59 +                                                  &rvCert->id,
    1.60 +                                                  &rvCert->encoding,
    1.61 +                                                  &rvCert->issuer,
    1.62 +                                                  &rvCert->serial,
    1.63 +                                                  &rvCert->subject);
    1.64 +    if (status != PR_SUCCESS ||
    1.65 +	!rvCert->encoding.data ||
    1.66 +	!rvCert->encoding.size ||
    1.67 +	!rvCert->issuer.data ||
    1.68 +	!rvCert->issuer.size ||
    1.69 +	!rvCert->serial.data ||
    1.70 +	!rvCert->serial.size) {
    1.71 +	if (mark)
    1.72 +	    nssArena_Release(arena, mark);
    1.73 +	return (NSSCertificate *)NULL;
    1.74 +    }
    1.75 +    if (mark)
    1.76 +	nssArena_Unmark(arena, mark);
    1.77 +    return rvCert;
    1.78 +}
    1.79 +
    1.80 +NSS_IMPLEMENT NSSCertificate *
    1.81 +nssCertificate_AddRef (
    1.82 +  NSSCertificate *c
    1.83 +)
    1.84 +{
    1.85 +    if (c) {
    1.86 +	nssPKIObject_AddRef(&c->object);
    1.87 +    }
    1.88 +    return c;
    1.89 +}
    1.90 +
    1.91 +NSS_IMPLEMENT PRStatus
    1.92 +nssCertificate_Destroy (
    1.93 +  NSSCertificate *c
    1.94 +)
    1.95 +{
    1.96 +    nssCertificateStoreTrace lockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
    1.97 +    nssCertificateStoreTrace unlockTrace = {NULL, NULL, PR_FALSE, PR_FALSE};
    1.98 +
    1.99 +    if (c) {
   1.100 +	PRUint32 i;
   1.101 +	nssDecodedCert *dc = c->decoding;
   1.102 +	NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
   1.103 +	NSSCryptoContext *cc = c->object.cryptoContext;
   1.104 +
   1.105 +	PR_ASSERT(c->object.refCount > 0);
   1.106 +
   1.107 +	/* --- LOCK storage --- */
   1.108 +	if (cc) {
   1.109 +	    nssCertificateStore_Lock(cc->certStore, &lockTrace);
   1.110 +	} else {
   1.111 +	    nssTrustDomain_LockCertCache(td);
   1.112 +	}
   1.113 +	if (PR_ATOMIC_DECREMENT(&c->object.refCount) == 0) {
   1.114 +	    /* --- remove cert and UNLOCK storage --- */
   1.115 +	    if (cc) {
   1.116 +		nssCertificateStore_RemoveCertLOCKED(cc->certStore, c);
   1.117 +		nssCertificateStore_Unlock(cc->certStore, &lockTrace,
   1.118 +                                           &unlockTrace);
   1.119 +	    } else {
   1.120 +		nssTrustDomain_RemoveCertFromCacheLOCKED(td, c);
   1.121 +		nssTrustDomain_UnlockCertCache(td);
   1.122 +	    }
   1.123 +	    /* free cert data */
   1.124 +	    for (i=0; i<c->object.numInstances; i++) {
   1.125 +		nssCryptokiObject_Destroy(c->object.instances[i]);
   1.126 +	    }
   1.127 +	    nssPKIObject_DestroyLock(&c->object);
   1.128 +	    nssArena_Destroy(c->object.arena);
   1.129 +	    nssDecodedCert_Destroy(dc);
   1.130 +	} else {
   1.131 +	    /* --- UNLOCK storage --- */
   1.132 +	    if (cc) {
   1.133 +		nssCertificateStore_Unlock(cc->certStore,
   1.134 +					   &lockTrace,
   1.135 +					   &unlockTrace);
   1.136 +	    } else {
   1.137 +		nssTrustDomain_UnlockCertCache(td);
   1.138 +	    }
   1.139 +	}
   1.140 +    }
   1.141 +    return PR_SUCCESS;
   1.142 +}
   1.143 +
   1.144 +NSS_IMPLEMENT PRStatus
   1.145 +NSSCertificate_Destroy (
   1.146 +  NSSCertificate *c
   1.147 +)
   1.148 +{
   1.149 +    return nssCertificate_Destroy(c);
   1.150 +}
   1.151 +
   1.152 +NSS_IMPLEMENT NSSDER *
   1.153 +nssCertificate_GetEncoding (
   1.154 +  NSSCertificate *c
   1.155 +)
   1.156 +{
   1.157 +    if (c->encoding.size > 0 && c->encoding.data) {
   1.158 +	return &c->encoding;
   1.159 +    } else {
   1.160 +	return (NSSDER *)NULL;
   1.161 +    }
   1.162 +}
   1.163 +
   1.164 +NSS_IMPLEMENT NSSDER *
   1.165 +nssCertificate_GetIssuer (
   1.166 +  NSSCertificate *c
   1.167 +)
   1.168 +{
   1.169 +    if (c->issuer.size > 0 && c->issuer.data) {
   1.170 +	return &c->issuer;
   1.171 +    } else {
   1.172 +	return (NSSDER *)NULL;
   1.173 +    }
   1.174 +}
   1.175 +
   1.176 +NSS_IMPLEMENT NSSDER *
   1.177 +nssCertificate_GetSerialNumber (
   1.178 +  NSSCertificate *c
   1.179 +)
   1.180 +{
   1.181 +    if (c->serial.size > 0 && c->serial.data) {
   1.182 +	return &c->serial;
   1.183 +    } else {
   1.184 +	return (NSSDER *)NULL;
   1.185 +    }
   1.186 +}
   1.187 +
   1.188 +NSS_IMPLEMENT NSSDER *
   1.189 +nssCertificate_GetSubject (
   1.190 +  NSSCertificate *c
   1.191 +)
   1.192 +{
   1.193 +    if (c->subject.size > 0 && c->subject.data) {
   1.194 +	return &c->subject;
   1.195 +    } else {
   1.196 +	return (NSSDER *)NULL;
   1.197 +    }
   1.198 +}
   1.199 +
   1.200 +/* Returns a copy, Caller must free using nss_ZFreeIf */
   1.201 +NSS_IMPLEMENT NSSUTF8 *
   1.202 +nssCertificate_GetNickname (
   1.203 +  NSSCertificate *c,
   1.204 +  NSSToken *tokenOpt
   1.205 +)
   1.206 +{
   1.207 +    return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt);
   1.208 +}
   1.209 +
   1.210 +NSS_IMPLEMENT NSSASCII7 *
   1.211 +nssCertificate_GetEmailAddress (
   1.212 +  NSSCertificate *c
   1.213 +)
   1.214 +{
   1.215 +    return c->email;
   1.216 +}
   1.217 +
   1.218 +NSS_IMPLEMENT PRStatus
   1.219 +NSSCertificate_DeleteStoredObject (
   1.220 +  NSSCertificate *c,
   1.221 +  NSSCallback *uhh
   1.222 +)
   1.223 +{
   1.224 +    return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE);
   1.225 +}
   1.226 +
   1.227 +NSS_IMPLEMENT PRStatus
   1.228 +NSSCertificate_Validate (
   1.229 +  NSSCertificate *c,
   1.230 +  NSSTime *timeOpt, /* NULL for "now" */
   1.231 +  NSSUsage *usage,
   1.232 +  NSSPolicies *policiesOpt /* NULL for none */
   1.233 +)
   1.234 +{
   1.235 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.236 +    return PR_FAILURE;
   1.237 +}
   1.238 +
   1.239 +NSS_IMPLEMENT void ** /* void *[] */
   1.240 +NSSCertificate_ValidateCompletely (
   1.241 +  NSSCertificate *c,
   1.242 +  NSSTime *timeOpt, /* NULL for "now" */
   1.243 +  NSSUsage *usage,
   1.244 +  NSSPolicies *policiesOpt, /* NULL for none */
   1.245 +  void **rvOpt, /* NULL for allocate */
   1.246 +  PRUint32 rvLimit, /* zero for no limit */
   1.247 +  NSSArena *arenaOpt /* NULL for heap */
   1.248 +)
   1.249 +{
   1.250 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.251 +    return NULL;
   1.252 +}
   1.253 +
   1.254 +NSS_IMPLEMENT PRStatus
   1.255 +NSSCertificate_ValidateAndDiscoverUsagesAndPolicies (
   1.256 +  NSSCertificate *c,
   1.257 +  NSSTime **notBeforeOutOpt,
   1.258 +  NSSTime **notAfterOutOpt,
   1.259 +  void *allowedUsages,
   1.260 +  void *disallowedUsages,
   1.261 +  void *allowedPolicies,
   1.262 +  void *disallowedPolicies,
   1.263 +  /* more args.. work on this fgmr */
   1.264 +  NSSArena *arenaOpt
   1.265 +)
   1.266 +{
   1.267 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.268 +    return PR_FAILURE;
   1.269 +}
   1.270 +
   1.271 +NSS_IMPLEMENT NSSDER *
   1.272 +NSSCertificate_Encode (
   1.273 +  NSSCertificate *c,
   1.274 +  NSSDER *rvOpt,
   1.275 +  NSSArena *arenaOpt
   1.276 +)
   1.277 +{
   1.278 +    /* Item, DER, BER are all typedefs now... */
   1.279 +    return nssItem_Duplicate((NSSItem *)&c->encoding, arenaOpt, rvOpt);
   1.280 +}
   1.281 +
   1.282 +NSS_IMPLEMENT nssDecodedCert *
   1.283 +nssCertificate_GetDecoding (
   1.284 +  NSSCertificate *c
   1.285 +)
   1.286 +{
   1.287 +    nssDecodedCert* deco = NULL;
   1.288 +    if (c->type == NSSCertificateType_PKIX) {
   1.289 +        (void)STAN_GetCERTCertificate(c);
   1.290 +    }
   1.291 +    nssPKIObject_Lock(&c->object);
   1.292 +    if (!c->decoding) {
   1.293 +	deco = nssDecodedCert_Create(NULL, &c->encoding, c->type);
   1.294 +    	PORT_Assert(!c->decoding); 
   1.295 +        c->decoding = deco;
   1.296 +    } else {
   1.297 +        deco = c->decoding;
   1.298 +    }
   1.299 +    nssPKIObject_Unlock(&c->object);
   1.300 +    return deco;
   1.301 +}
   1.302 +
   1.303 +static NSSCertificate **
   1.304 +filter_subject_certs_for_id (
   1.305 +  NSSCertificate **subjectCerts, 
   1.306 +  void *id
   1.307 +)
   1.308 +{
   1.309 +    NSSCertificate **si;
   1.310 +    nssDecodedCert *dcp;
   1.311 +    int nextOpenSlot = 0;
   1.312 +    int i;
   1.313 +    nssCertIDMatch matchLevel = nssCertIDMatch_Unknown;
   1.314 +    nssCertIDMatch match;
   1.315 +
   1.316 +    /* walk the subject certs */
   1.317 +    for (si = subjectCerts; *si; si++) {
   1.318 +	dcp = nssCertificate_GetDecoding(*si);
   1.319 +	if (!dcp) {
   1.320 +	    NSSCertificate_Destroy(*si);
   1.321 +	    continue;
   1.322 +	}
   1.323 +	match = dcp->matchIdentifier(dcp, id);
   1.324 +	switch (match) {
   1.325 +	case nssCertIDMatch_Yes:
   1.326 +	    if (matchLevel == nssCertIDMatch_Unknown) {
   1.327 +		/* we have non-definitive matches, forget them */
   1.328 +		for (i = 0; i < nextOpenSlot; i++) {
   1.329 +		    NSSCertificate_Destroy(subjectCerts[i]);
   1.330 +		    subjectCerts[i] = NULL;
   1.331 +		}
   1.332 +		nextOpenSlot = 0;
   1.333 +		/* only keep definitive matches from now on */
   1.334 +		matchLevel = nssCertIDMatch_Yes;
   1.335 +	    }
   1.336 +	    /* keep the cert */
   1.337 +	    subjectCerts[nextOpenSlot++] = *si;
   1.338 +	    break;
   1.339 +	case nssCertIDMatch_Unknown:
   1.340 +	    if (matchLevel == nssCertIDMatch_Unknown) {
   1.341 +		/* only have non-definitive matches so far, keep it */
   1.342 +		subjectCerts[nextOpenSlot++] = *si;
   1.343 +		break;
   1.344 +	    }
   1.345 +	    /* else fall through, we have a definitive match already */
   1.346 +	case nssCertIDMatch_No:
   1.347 +	default:
   1.348 +	    NSSCertificate_Destroy(*si);
   1.349 +	    *si = NULL;
   1.350 +	}
   1.351 +    }
   1.352 +    subjectCerts[nextOpenSlot] = NULL;
   1.353 +    return subjectCerts;
   1.354 +}
   1.355 +
   1.356 +static NSSCertificate **
   1.357 +filter_certs_for_valid_issuers (
   1.358 +  NSSCertificate **certs
   1.359 +)
   1.360 +{
   1.361 +    NSSCertificate **cp;
   1.362 +    nssDecodedCert *dcp;
   1.363 +    int nextOpenSlot = 0;
   1.364 +
   1.365 +    for (cp = certs; *cp; cp++) {
   1.366 +	dcp = nssCertificate_GetDecoding(*cp);
   1.367 +	if (dcp && dcp->isValidIssuer(dcp)) {
   1.368 +	    certs[nextOpenSlot++] = *cp;
   1.369 +	} else {
   1.370 +	    NSSCertificate_Destroy(*cp);
   1.371 +	}
   1.372 +    }
   1.373 +    certs[nextOpenSlot] = NULL;
   1.374 +    return certs;
   1.375 +}
   1.376 +
   1.377 +static NSSCertificate *
   1.378 +find_cert_issuer (
   1.379 +  NSSCertificate *c,
   1.380 +  NSSTime *timeOpt,
   1.381 +  NSSUsage *usage,
   1.382 +  NSSPolicies *policiesOpt,
   1.383 +  NSSTrustDomain *td,
   1.384 +  NSSCryptoContext *cc
   1.385 +)
   1.386 +{
   1.387 +    NSSArena *arena;
   1.388 +    NSSCertificate **certs = NULL;
   1.389 +    NSSCertificate **ccIssuers = NULL;
   1.390 +    NSSCertificate **tdIssuers = NULL;
   1.391 +    NSSCertificate *issuer = NULL;
   1.392 +
   1.393 +    if (!cc)
   1.394 +	cc = c->object.cryptoContext;
   1.395 +    if (!td)
   1.396 +	td = NSSCertificate_GetTrustDomain(c);
   1.397 +    arena = nssArena_Create();
   1.398 +    if (!arena) {
   1.399 +	return (NSSCertificate *)NULL;
   1.400 +    }
   1.401 +    if (cc) {
   1.402 +	ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc,
   1.403 +	                                                       &c->issuer,
   1.404 +	                                                       NULL,
   1.405 +	                                                       0,
   1.406 +	                                                       arena);
   1.407 +    }
   1.408 +    if (td)
   1.409 +	tdIssuers = nssTrustDomain_FindCertificatesBySubject(td,
   1.410 +                                                         &c->issuer,
   1.411 +                                                         NULL,
   1.412 +                                                         0,
   1.413 +                                                         arena);
   1.414 +    certs = nssCertificateArray_Join(ccIssuers, tdIssuers);
   1.415 +    if (certs) {
   1.416 +	nssDecodedCert *dc = NULL;
   1.417 +	void *issuerID = NULL;
   1.418 +	dc = nssCertificate_GetDecoding(c);
   1.419 +	if (dc) {
   1.420 +	    issuerID = dc->getIssuerIdentifier(dc);
   1.421 +	}
   1.422 +	/* XXX review based on CERT_FindCertIssuer
   1.423 +	 * this function is not using the authCertIssuer field as a fallback
   1.424 +	 * if authority key id does not exist
   1.425 +	 */
   1.426 +	if (issuerID) {
   1.427 +	    certs = filter_subject_certs_for_id(certs, issuerID);
   1.428 +	}
   1.429 +	certs = filter_certs_for_valid_issuers(certs);
   1.430 +	issuer = nssCertificateArray_FindBestCertificate(certs,
   1.431 +	                                                 timeOpt,
   1.432 +	                                                 usage,
   1.433 +	                                                 policiesOpt);
   1.434 +	nssCertificateArray_Destroy(certs);
   1.435 +    }
   1.436 +    nssArena_Destroy(arena);
   1.437 +    return issuer;
   1.438 +}
   1.439 +
   1.440 +/* This function returns the built chain, as far as it gets,
   1.441 +** even if/when it fails to find an issuer, and returns PR_FAILURE
   1.442 +*/
   1.443 +NSS_IMPLEMENT NSSCertificate **
   1.444 +nssCertificate_BuildChain (
   1.445 +  NSSCertificate *c,
   1.446 +  NSSTime *timeOpt,
   1.447 +  NSSUsage *usage,
   1.448 +  NSSPolicies *policiesOpt,
   1.449 +  NSSCertificate **rvOpt,
   1.450 +  PRUint32 rvLimit,
   1.451 +  NSSArena *arenaOpt,
   1.452 +  PRStatus *statusOpt,
   1.453 +  NSSTrustDomain *td,
   1.454 +  NSSCryptoContext *cc 
   1.455 +)
   1.456 +{
   1.457 +    NSSCertificate **rvChain = NULL;
   1.458 +    NSSUsage issuerUsage = *usage;
   1.459 +    nssPKIObjectCollection *collection = NULL;
   1.460 +    PRUint32  rvCount = 0;
   1.461 +    PRStatus  st;
   1.462 +    PRStatus  ret = PR_SUCCESS;
   1.463 +
   1.464 +    if (!c || !cc ||
   1.465 +        (!td && (td = NSSCertificate_GetTrustDomain(c)) == NULL)) {
   1.466 +	goto loser;
   1.467 +    }
   1.468 +    /* bump the usage up to CA level */
   1.469 +    issuerUsage.nss3lookingForCA = PR_TRUE;
   1.470 +    collection = nssCertificateCollection_Create(td, NULL);
   1.471 +    if (!collection)
   1.472 +	goto loser;
   1.473 +    st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
   1.474 +    if (st != PR_SUCCESS)
   1.475 +    	goto loser;
   1.476 +    for (rvCount = 1; (!rvLimit || rvCount < rvLimit); ++rvCount) {
   1.477 +	CERTCertificate *cCert = STAN_GetCERTCertificate(c);
   1.478 +	if (cCert->isRoot) {
   1.479 +	    /* not including the issuer of the self-signed cert, which is,
   1.480 +	     * of course, itself
   1.481 +	     */
   1.482 +	    break;
   1.483 +	}
   1.484 +	c = find_cert_issuer(c, timeOpt, &issuerUsage, policiesOpt, td, cc);
   1.485 +	if (!c) {
   1.486 +	    ret = PR_FAILURE;
   1.487 +	    break;
   1.488 +	}
   1.489 +	st = nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c);
   1.490 +	nssCertificate_Destroy(c); /* collection has it */
   1.491 +	if (st != PR_SUCCESS)
   1.492 +	    goto loser;
   1.493 +    }
   1.494 +    rvChain = nssPKIObjectCollection_GetCertificates(collection, 
   1.495 +                                                     rvOpt, 
   1.496 +                                                     rvLimit, 
   1.497 +                                                     arenaOpt);
   1.498 +    if (rvChain) {
   1.499 +	nssPKIObjectCollection_Destroy(collection);
   1.500 +	if (statusOpt) 
   1.501 +	    *statusOpt = ret;
   1.502 +	if (ret != PR_SUCCESS)
   1.503 +	    nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
   1.504 +	return rvChain;
   1.505 +    }
   1.506 +
   1.507 +loser:
   1.508 +    if (collection)
   1.509 +	nssPKIObjectCollection_Destroy(collection);
   1.510 +    if (statusOpt) 
   1.511 +	*statusOpt = PR_FAILURE;
   1.512 +    nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND);
   1.513 +    return rvChain;
   1.514 +}
   1.515 +
   1.516 +NSS_IMPLEMENT NSSCertificate **
   1.517 +NSSCertificate_BuildChain (
   1.518 +  NSSCertificate *c,
   1.519 +  NSSTime *timeOpt,
   1.520 +  NSSUsage *usage,
   1.521 +  NSSPolicies *policiesOpt,
   1.522 +  NSSCertificate **rvOpt,
   1.523 +  PRUint32 rvLimit, /* zero for no limit */
   1.524 +  NSSArena *arenaOpt,
   1.525 +  PRStatus *statusOpt,
   1.526 +  NSSTrustDomain *td,
   1.527 +  NSSCryptoContext *cc 
   1.528 +)
   1.529 +{
   1.530 +    return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt,
   1.531 +                                     rvOpt, rvLimit, arenaOpt, statusOpt,
   1.532 +				     td, cc);
   1.533 +}
   1.534 +
   1.535 +NSS_IMPLEMENT NSSCryptoContext *
   1.536 +nssCertificate_GetCryptoContext (
   1.537 +  NSSCertificate *c
   1.538 +)
   1.539 +{
   1.540 +    return c->object.cryptoContext;
   1.541 +}
   1.542 +
   1.543 +NSS_IMPLEMENT NSSTrustDomain *
   1.544 +nssCertificate_GetTrustDomain (
   1.545 +  NSSCertificate *c
   1.546 +)
   1.547 +{
   1.548 +    return c->object.trustDomain;
   1.549 +}
   1.550 +
   1.551 +NSS_IMPLEMENT NSSTrustDomain *
   1.552 +NSSCertificate_GetTrustDomain (
   1.553 +  NSSCertificate *c
   1.554 +)
   1.555 +{
   1.556 +    return nssCertificate_GetTrustDomain(c);
   1.557 +}
   1.558 +
   1.559 +NSS_IMPLEMENT NSSToken *
   1.560 +NSSCertificate_GetToken (
   1.561 +  NSSCertificate *c,
   1.562 +  PRStatus *statusOpt
   1.563 +)
   1.564 +{
   1.565 +    return (NSSToken *)NULL;
   1.566 +}
   1.567 +
   1.568 +NSS_IMPLEMENT NSSSlot *
   1.569 +NSSCertificate_GetSlot (
   1.570 +  NSSCertificate *c,
   1.571 +  PRStatus *statusOpt
   1.572 +)
   1.573 +{
   1.574 +    return (NSSSlot *)NULL;
   1.575 +}
   1.576 +
   1.577 +NSS_IMPLEMENT NSSModule *
   1.578 +NSSCertificate_GetModule (
   1.579 +  NSSCertificate *c,
   1.580 +  PRStatus *statusOpt
   1.581 +)
   1.582 +{
   1.583 +    return (NSSModule *)NULL;
   1.584 +}
   1.585 +
   1.586 +NSS_IMPLEMENT NSSItem *
   1.587 +NSSCertificate_Encrypt (
   1.588 +  NSSCertificate *c,
   1.589 +  NSSAlgorithmAndParameters *apOpt,
   1.590 +  NSSItem *data,
   1.591 +  NSSTime *timeOpt,
   1.592 +  NSSUsage *usage,
   1.593 +  NSSPolicies *policiesOpt,
   1.594 +  NSSCallback *uhh,
   1.595 +  NSSItem *rvOpt,
   1.596 +  NSSArena *arenaOpt
   1.597 +)
   1.598 +{
   1.599 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.600 +    return NULL;
   1.601 +}
   1.602 +
   1.603 +NSS_IMPLEMENT PRStatus
   1.604 +NSSCertificate_Verify (
   1.605 +  NSSCertificate *c,
   1.606 +  NSSAlgorithmAndParameters *apOpt,
   1.607 +  NSSItem *data,
   1.608 +  NSSItem *signature,
   1.609 +  NSSTime *timeOpt,
   1.610 +  NSSUsage *usage,
   1.611 +  NSSPolicies *policiesOpt,
   1.612 +  NSSCallback *uhh
   1.613 +)
   1.614 +{
   1.615 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.616 +    return PR_FAILURE;
   1.617 +}
   1.618 +
   1.619 +NSS_IMPLEMENT NSSItem *
   1.620 +NSSCertificate_VerifyRecover (
   1.621 +  NSSCertificate *c,
   1.622 +  NSSAlgorithmAndParameters *apOpt,
   1.623 +  NSSItem *signature,
   1.624 +  NSSTime *timeOpt,
   1.625 +  NSSUsage *usage,
   1.626 +  NSSPolicies *policiesOpt,
   1.627 +  NSSCallback *uhh,
   1.628 +  NSSItem *rvOpt,
   1.629 +  NSSArena *arenaOpt
   1.630 +)
   1.631 +{
   1.632 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.633 +    return NULL;
   1.634 +}
   1.635 +
   1.636 +NSS_IMPLEMENT NSSItem *
   1.637 +NSSCertificate_WrapSymmetricKey (
   1.638 +  NSSCertificate *c,
   1.639 +  NSSAlgorithmAndParameters *apOpt,
   1.640 +  NSSSymmetricKey *keyToWrap,
   1.641 +  NSSTime *timeOpt,
   1.642 +  NSSUsage *usage,
   1.643 +  NSSPolicies *policiesOpt,
   1.644 +  NSSCallback *uhh,
   1.645 +  NSSItem *rvOpt,
   1.646 +  NSSArena *arenaOpt
   1.647 +)
   1.648 +{
   1.649 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.650 +    return NULL;
   1.651 +}
   1.652 +
   1.653 +NSS_IMPLEMENT NSSCryptoContext *
   1.654 +NSSCertificate_CreateCryptoContext (
   1.655 +  NSSCertificate *c,
   1.656 +  NSSAlgorithmAndParameters *apOpt,
   1.657 +  NSSTime *timeOpt,
   1.658 +  NSSUsage *usage,
   1.659 +  NSSPolicies *policiesOpt,
   1.660 +  NSSCallback *uhh  
   1.661 +)
   1.662 +{
   1.663 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.664 +    return NULL;
   1.665 +}
   1.666 +
   1.667 +NSS_IMPLEMENT NSSPublicKey *
   1.668 +NSSCertificate_GetPublicKey (
   1.669 +  NSSCertificate *c
   1.670 +)
   1.671 +{
   1.672 +#if 0
   1.673 +    CK_ATTRIBUTE pubktemplate[] = {
   1.674 +	{ CKA_CLASS,   NULL, 0 },
   1.675 +	{ CKA_ID,      NULL, 0 },
   1.676 +	{ CKA_SUBJECT, NULL, 0 }
   1.677 +    };
   1.678 +    PRStatus nssrv;
   1.679 +    CK_ULONG count = sizeof(pubktemplate) / sizeof(pubktemplate[0]);
   1.680 +    NSS_CK_SET_ATTRIBUTE_ITEM(pubktemplate, 0, &g_ck_class_pubkey);
   1.681 +    if (c->id.size > 0) {
   1.682 +	/* CKA_ID */
   1.683 +	NSS_CK_ITEM_TO_ATTRIBUTE(&c->id, &pubktemplate[1]);
   1.684 +    } else {
   1.685 +	/* failure, yes? */
   1.686 +	return (NSSPublicKey *)NULL;
   1.687 +    }
   1.688 +    if (c->subject.size > 0) {
   1.689 +	/* CKA_SUBJECT */
   1.690 +	NSS_CK_ITEM_TO_ATTRIBUTE(&c->subject, &pubktemplate[2]);
   1.691 +    } else {
   1.692 +	/* failure, yes? */
   1.693 +	return (NSSPublicKey *)NULL;
   1.694 +    }
   1.695 +    /* Try the cert's token first */
   1.696 +    if (c->token) {
   1.697 +	nssrv = nssToken_FindObjectByTemplate(c->token, pubktemplate, count);
   1.698 +    }
   1.699 +#endif
   1.700 +    /* Try all other key tokens */
   1.701 +    return (NSSPublicKey *)NULL;
   1.702 +}
   1.703 +
   1.704 +NSS_IMPLEMENT NSSPrivateKey *
   1.705 +NSSCertificate_FindPrivateKey (
   1.706 +  NSSCertificate *c,
   1.707 +  NSSCallback *uhh
   1.708 +)
   1.709 +{
   1.710 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.711 +    return NULL;
   1.712 +}
   1.713 +
   1.714 +NSS_IMPLEMENT PRBool
   1.715 +NSSCertificate_IsPrivateKeyAvailable (
   1.716 +  NSSCertificate *c,
   1.717 +  NSSCallback *uhh,
   1.718 +  PRStatus *statusOpt
   1.719 +)
   1.720 +{
   1.721 +    PRBool isUser = PR_FALSE;
   1.722 +    nssCryptokiObject **ip;
   1.723 +    nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object);
   1.724 +    if (!instances) {
   1.725 +	return PR_FALSE;
   1.726 +    }
   1.727 +    for (ip = instances; *ip; ip++) {
   1.728 +	nssCryptokiObject *instance = *ip;
   1.729 +	if (nssToken_IsPrivateKeyAvailable(instance->token, c, instance)) {
   1.730 +	    isUser = PR_TRUE;
   1.731 +	}
   1.732 +    }
   1.733 +    nssCryptokiObjectArray_Destroy(instances);
   1.734 +    return isUser;
   1.735 +}
   1.736 +
   1.737 +/* sort the subject cert list from newest to oldest */
   1.738 +PRIntn
   1.739 +nssCertificate_SubjectListSort (
   1.740 +  void *v1,
   1.741 +  void *v2
   1.742 +)
   1.743 +{
   1.744 +    NSSCertificate *c1 = (NSSCertificate *)v1;
   1.745 +    NSSCertificate *c2 = (NSSCertificate *)v2;
   1.746 +    nssDecodedCert *dc1 = nssCertificate_GetDecoding(c1);
   1.747 +    nssDecodedCert *dc2 = nssCertificate_GetDecoding(c2);
   1.748 +    if (!dc1) {
   1.749 +	return dc2 ? 1 : 0;
   1.750 +    } else if (!dc2) {
   1.751 +	return -1;
   1.752 +    } else {
   1.753 +	return dc1->isNewerThan(dc1, dc2) ? -1 : 1;
   1.754 +    }
   1.755 +}
   1.756 +
   1.757 +NSS_IMPLEMENT PRBool
   1.758 +NSSUserCertificate_IsStillPresent (
   1.759 +  NSSUserCertificate *uc,
   1.760 +  PRStatus *statusOpt
   1.761 +)
   1.762 +{
   1.763 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.764 +    return PR_FALSE;
   1.765 +}
   1.766 +
   1.767 +NSS_IMPLEMENT NSSItem *
   1.768 +NSSUserCertificate_Decrypt (
   1.769 +  NSSUserCertificate *uc,
   1.770 +  NSSAlgorithmAndParameters *apOpt,
   1.771 +  NSSItem *data,
   1.772 +  NSSTime *timeOpt,
   1.773 +  NSSUsage *usage,
   1.774 +  NSSPolicies *policiesOpt,
   1.775 +  NSSCallback *uhh,
   1.776 +  NSSItem *rvOpt,
   1.777 +  NSSArena *arenaOpt
   1.778 +)
   1.779 +{
   1.780 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.781 +    return NULL;
   1.782 +}
   1.783 +
   1.784 +NSS_IMPLEMENT NSSItem *
   1.785 +NSSUserCertificate_Sign (
   1.786 +  NSSUserCertificate *uc,
   1.787 +  NSSAlgorithmAndParameters *apOpt,
   1.788 +  NSSItem *data,
   1.789 +  NSSTime *timeOpt,
   1.790 +  NSSUsage *usage,
   1.791 +  NSSPolicies *policiesOpt,
   1.792 +  NSSCallback *uhh,
   1.793 +  NSSItem *rvOpt,
   1.794 +  NSSArena *arenaOpt
   1.795 +)
   1.796 +{
   1.797 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.798 +    return NULL;
   1.799 +}
   1.800 +
   1.801 +NSS_IMPLEMENT NSSItem *
   1.802 +NSSUserCertificate_SignRecover (
   1.803 +  NSSUserCertificate *uc,
   1.804 +  NSSAlgorithmAndParameters *apOpt,
   1.805 +  NSSItem *data,
   1.806 +  NSSTime *timeOpt,
   1.807 +  NSSUsage *usage,
   1.808 +  NSSPolicies *policiesOpt,
   1.809 +  NSSCallback *uhh,
   1.810 +  NSSItem *rvOpt,
   1.811 +  NSSArena *arenaOpt
   1.812 +)
   1.813 +{
   1.814 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.815 +    return NULL;
   1.816 +}
   1.817 +
   1.818 +NSS_IMPLEMENT NSSSymmetricKey *
   1.819 +NSSUserCertificate_UnwrapSymmetricKey (
   1.820 +  NSSUserCertificate *uc,
   1.821 +  NSSAlgorithmAndParameters *apOpt,
   1.822 +  NSSItem *wrappedKey,
   1.823 +  NSSTime *timeOpt,
   1.824 +  NSSUsage *usage,
   1.825 +  NSSPolicies *policiesOpt,
   1.826 +  NSSCallback *uhh,
   1.827 +  NSSItem *rvOpt,
   1.828 +  NSSArena *arenaOpt
   1.829 +)
   1.830 +{
   1.831 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.832 +    return NULL;
   1.833 +}
   1.834 +
   1.835 +NSS_IMPLEMENT NSSSymmetricKey *
   1.836 +NSSUserCertificate_DeriveSymmetricKey (
   1.837 +  NSSUserCertificate *uc, /* provides private key */
   1.838 +  NSSCertificate *c, /* provides public key */
   1.839 +  NSSAlgorithmAndParameters *apOpt,
   1.840 +  NSSOID *target,
   1.841 +  PRUint32 keySizeOpt, /* zero for best allowed */
   1.842 +  NSSOperations operations,
   1.843 +  NSSCallback *uhh
   1.844 +)
   1.845 +{
   1.846 +    nss_SetError(NSS_ERROR_NOT_FOUND);
   1.847 +    return NULL;
   1.848 +}
   1.849 +
   1.850 +NSS_IMPLEMENT nssSMIMEProfile *
   1.851 +nssSMIMEProfile_Create (
   1.852 +  NSSCertificate *cert,
   1.853 +  NSSItem *profileTime,
   1.854 +  NSSItem *profileData
   1.855 +)
   1.856 +{
   1.857 +    NSSArena *arena;
   1.858 +    nssSMIMEProfile *rvProfile;
   1.859 +    nssPKIObject *object;
   1.860 +    NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert);
   1.861 +    NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert);
   1.862 +    arena = nssArena_Create();
   1.863 +    if (!arena) {
   1.864 +	return NULL;
   1.865 +    }
   1.866 +    object = nssPKIObject_Create(arena, NULL, td, cc, nssPKILock);
   1.867 +    if (!object) {
   1.868 +	goto loser;
   1.869 +    }
   1.870 +    rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
   1.871 +    if (!rvProfile) {
   1.872 +	goto loser;
   1.873 +    }
   1.874 +    rvProfile->object = *object;
   1.875 +    rvProfile->certificate = cert;
   1.876 +    rvProfile->email = nssUTF8_Duplicate(cert->email, arena);
   1.877 +    rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL);
   1.878 +    if (profileTime) {
   1.879 +	rvProfile->profileTime = nssItem_Duplicate(profileTime, arena, NULL);
   1.880 +    }
   1.881 +    if (profileData) {
   1.882 +	rvProfile->profileData = nssItem_Duplicate(profileData, arena, NULL);
   1.883 +    }
   1.884 +    return rvProfile;
   1.885 +loser:
   1.886 +    if (object) nssPKIObject_Destroy(object);
   1.887 +    else if (arena)  nssArena_Destroy(arena);
   1.888 +    return (nssSMIMEProfile *)NULL;
   1.889 +}
   1.890 +
   1.891 +/* execute a callback function on all members of a cert list */
   1.892 +NSS_EXTERN PRStatus
   1.893 +nssCertificateList_DoCallback (
   1.894 +  nssList *certList, 
   1.895 +  PRStatus (* callback)(NSSCertificate *c, void *arg),
   1.896 +  void *arg
   1.897 +)
   1.898 +{
   1.899 +    nssListIterator *certs;
   1.900 +    NSSCertificate *cert;
   1.901 +    PRStatus nssrv;
   1.902 +    certs = nssList_CreateIterator(certList);
   1.903 +    if (!certs) {
   1.904 +        return PR_FAILURE;
   1.905 +    }
   1.906 +    for (cert  = (NSSCertificate *)nssListIterator_Start(certs);
   1.907 +         cert != (NSSCertificate *)NULL;
   1.908 +         cert  = (NSSCertificate *)nssListIterator_Next(certs))
   1.909 +    {
   1.910 +	nssrv = (*callback)(cert, arg);
   1.911 +    }
   1.912 +    nssListIterator_Finish(certs);
   1.913 +    nssListIterator_Destroy(certs);
   1.914 +    return PR_SUCCESS;
   1.915 +}
   1.916 +
   1.917 +static PRStatus add_ref_callback(NSSCertificate *c, void *a)
   1.918 +{
   1.919 +    nssCertificate_AddRef(c);
   1.920 +    return PR_SUCCESS;
   1.921 +}
   1.922 +
   1.923 +NSS_IMPLEMENT void
   1.924 +nssCertificateList_AddReferences (
   1.925 +  nssList *certList
   1.926 +)
   1.927 +{
   1.928 +    (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL);
   1.929 +}
   1.930 +
   1.931 +
   1.932 +/*
   1.933 + * Is this trust record safe to apply to all certs of the same issuer/SN 
   1.934 + * independent of the cert matching the hash. This is only true is the trust 
   1.935 + * is unknown or distrusted. In general this feature is only useful to 
   1.936 + * explicitly distrusting certs. It is not safe to use to trust certs, so 
   1.937 + * only allow unknown and untrusted trust types.
   1.938 + */
   1.939 +PRBool
   1.940 +nssTrust_IsSafeToIgnoreCertHash(nssTrustLevel serverAuth, 
   1.941 +		nssTrustLevel clientAuth, nssTrustLevel codeSigning, 
   1.942 +		nssTrustLevel email, PRBool stepup)
   1.943 +{
   1.944 +    /* step up is a trust type, if it's on, we must have a hash for the cert */
   1.945 +    if (stepup) {
   1.946 +	return PR_FALSE;
   1.947 +    }
   1.948 +    if ((serverAuth != nssTrustLevel_Unknown) && 
   1.949 +	(serverAuth != nssTrustLevel_NotTrusted)) {
   1.950 +	return PR_FALSE;
   1.951 +    }
   1.952 +    if ((clientAuth != nssTrustLevel_Unknown) && 
   1.953 +	(clientAuth != nssTrustLevel_NotTrusted)) {
   1.954 +	return PR_FALSE;
   1.955 +    }
   1.956 +    if ((codeSigning != nssTrustLevel_Unknown) && 
   1.957 +	(codeSigning != nssTrustLevel_NotTrusted)) {
   1.958 +	return PR_FALSE;
   1.959 +    }
   1.960 +    if ((email != nssTrustLevel_Unknown) && 
   1.961 +	(email != nssTrustLevel_NotTrusted)) {
   1.962 +	return PR_FALSE;
   1.963 +    }
   1.964 +    /* record only has Unknown and Untrusted entries, ok to accept without a 
   1.965 +     * hash */
   1.966 +    return PR_TRUE;
   1.967 +}
   1.968 +
   1.969 +NSS_IMPLEMENT NSSTrust *
   1.970 +nssTrust_Create (
   1.971 +  nssPKIObject *object,
   1.972 +  NSSItem *certData
   1.973 +)
   1.974 +{
   1.975 +    PRStatus status;
   1.976 +    PRUint32 i;
   1.977 +    PRUint32 lastTrustOrder, myTrustOrder;
   1.978 +    unsigned char sha1_hashcmp[SHA1_LENGTH];
   1.979 +    unsigned char sha1_hashin[SHA1_LENGTH];
   1.980 +    NSSItem sha1_hash;
   1.981 +    NSSTrust *rvt;
   1.982 +    nssCryptokiObject *instance;
   1.983 +    nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection;
   1.984 +    SECStatus rv; /* Should be stan flavor */
   1.985 +    PRBool stepUp;
   1.986 +
   1.987 +    lastTrustOrder = 1<<16; /* just make it big */
   1.988 +    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
   1.989 +    rvt = nss_ZNEW(object->arena, NSSTrust);
   1.990 +    if (!rvt) {
   1.991 +	return (NSSTrust *)NULL;
   1.992 +    }
   1.993 +    rvt->object = *object;
   1.994 +
   1.995 +    /* should be stan flavor of Hashbuf */
   1.996 +    rv = PK11_HashBuf(SEC_OID_SHA1,sha1_hashcmp,certData->data,certData->size);
   1.997 +    if (rv != SECSuccess) {
   1.998 +	return (NSSTrust *)NULL;
   1.999 +    }
  1.1000 +    sha1_hash.data = sha1_hashin;
  1.1001 +    sha1_hash.size = sizeof (sha1_hashin);
  1.1002 +    /* trust has to peek into the base object members */
  1.1003 +    nssPKIObject_Lock(object);
  1.1004 +    for (i=0; i<object->numInstances; i++) {
  1.1005 +	instance = object->instances[i];
  1.1006 +	myTrustOrder = nssToken_GetTrustOrder(instance->token);
  1.1007 +	status = nssCryptokiTrust_GetAttributes(instance, NULL,
  1.1008 +						&sha1_hash,
  1.1009 +	                                        &serverAuth,
  1.1010 +	                                        &clientAuth,
  1.1011 +	                                        &codeSigning,
  1.1012 +	                                        &emailProtection,
  1.1013 +	                                        &stepUp);
  1.1014 +	if (status != PR_SUCCESS) {
  1.1015 +	    nssPKIObject_Unlock(object);
  1.1016 +	    return (NSSTrust *)NULL;
  1.1017 +	}
  1.1018 +	/* if no hash is specified, then trust applies to all certs with
  1.1019 +	 * this issuer/SN. NOTE: This is only true for entries that
  1.1020 +	 * have distrust and unknown record */
  1.1021 +	if (!(
  1.1022 +            /* we continue if there is no hash, and the trust type is
  1.1023 +	     * safe to accept without a hash ... or ... */
  1.1024 +	     ((sha1_hash.size == 0)  && 
  1.1025 +		nssTrust_IsSafeToIgnoreCertHash(serverAuth,clientAuth,
  1.1026 +		codeSigning, emailProtection,stepUp)) 
  1.1027 +	   ||
  1.1028 +            /* we have a hash of the correct size, and it matches */
  1.1029 +            ((sha1_hash.size == SHA1_LENGTH) && (PORT_Memcmp(sha1_hashin,
  1.1030 +	        sha1_hashcmp,SHA1_LENGTH) == 0))   )) {
  1.1031 +	    nssPKIObject_Unlock(object);
  1.1032 +	    return (NSSTrust *)NULL;
  1.1033 +	}
  1.1034 +	if (rvt->serverAuth == nssTrustLevel_Unknown ||
  1.1035 +	    myTrustOrder < lastTrustOrder) 
  1.1036 +	{
  1.1037 +	    rvt->serverAuth = serverAuth;
  1.1038 +	}
  1.1039 +	if (rvt->clientAuth == nssTrustLevel_Unknown ||
  1.1040 +	    myTrustOrder < lastTrustOrder) 
  1.1041 +	{
  1.1042 +	    rvt->clientAuth = clientAuth;
  1.1043 +	}
  1.1044 +	if (rvt->emailProtection == nssTrustLevel_Unknown ||
  1.1045 +	    myTrustOrder < lastTrustOrder) 
  1.1046 +	{
  1.1047 +	    rvt->emailProtection = emailProtection;
  1.1048 +	}
  1.1049 +	if (rvt->codeSigning == nssTrustLevel_Unknown ||
  1.1050 +	    myTrustOrder < lastTrustOrder) 
  1.1051 +	{
  1.1052 +	    rvt->codeSigning = codeSigning;
  1.1053 +	}
  1.1054 +	rvt->stepUpApproved = stepUp;
  1.1055 +	lastTrustOrder = myTrustOrder;
  1.1056 +    }
  1.1057 +    nssPKIObject_Unlock(object);
  1.1058 +    return rvt;
  1.1059 +}
  1.1060 +
  1.1061 +NSS_IMPLEMENT NSSTrust *
  1.1062 +nssTrust_AddRef (
  1.1063 +  NSSTrust *trust
  1.1064 +)
  1.1065 +{
  1.1066 +    if (trust) {
  1.1067 +	nssPKIObject_AddRef(&trust->object);
  1.1068 +    }
  1.1069 +    return trust;
  1.1070 +}
  1.1071 +
  1.1072 +NSS_IMPLEMENT PRStatus
  1.1073 +nssTrust_Destroy (
  1.1074 +  NSSTrust *trust
  1.1075 +)
  1.1076 +{
  1.1077 +    if (trust) {
  1.1078 +	(void)nssPKIObject_Destroy(&trust->object);
  1.1079 +    }
  1.1080 +    return PR_SUCCESS;
  1.1081 +}
  1.1082 +
  1.1083 +NSS_IMPLEMENT nssSMIMEProfile *
  1.1084 +nssSMIMEProfile_AddRef (
  1.1085 +  nssSMIMEProfile *profile
  1.1086 +)
  1.1087 +{
  1.1088 +    if (profile) {
  1.1089 +	nssPKIObject_AddRef(&profile->object);
  1.1090 +    }
  1.1091 +    return profile;
  1.1092 +}
  1.1093 +
  1.1094 +NSS_IMPLEMENT PRStatus
  1.1095 +nssSMIMEProfile_Destroy (
  1.1096 +  nssSMIMEProfile *profile
  1.1097 +)
  1.1098 +{
  1.1099 +    if (profile) {
  1.1100 +	(void)nssPKIObject_Destroy(&profile->object);
  1.1101 +    }
  1.1102 +    return PR_SUCCESS;
  1.1103 +}
  1.1104 +
  1.1105 +NSS_IMPLEMENT NSSCRL *
  1.1106 +nssCRL_Create (
  1.1107 +  nssPKIObject *object
  1.1108 +)
  1.1109 +{
  1.1110 +    PRStatus status;
  1.1111 +    NSSCRL *rvCRL;
  1.1112 +    NSSArena *arena = object->arena;
  1.1113 +    PR_ASSERT(object->instances != NULL && object->numInstances > 0);
  1.1114 +    rvCRL = nss_ZNEW(arena, NSSCRL);
  1.1115 +    if (!rvCRL) {
  1.1116 +	return (NSSCRL *)NULL;
  1.1117 +    }
  1.1118 +    rvCRL->object = *object;
  1.1119 +    /* XXX should choose instance based on some criteria */
  1.1120 +    status = nssCryptokiCRL_GetAttributes(object->instances[0],
  1.1121 +                                          NULL,  /* XXX sessionOpt */
  1.1122 +                                          arena,
  1.1123 +                                          &rvCRL->encoding,
  1.1124 +                                          NULL, /* subject */
  1.1125 +                                          NULL, /* class */
  1.1126 +                                          &rvCRL->url,
  1.1127 +                                          &rvCRL->isKRL);
  1.1128 +    if (status != PR_SUCCESS) {
  1.1129 +	return (NSSCRL *)NULL;
  1.1130 +    }
  1.1131 +    return rvCRL;
  1.1132 +}
  1.1133 +
  1.1134 +NSS_IMPLEMENT NSSCRL *
  1.1135 +nssCRL_AddRef (
  1.1136 +  NSSCRL *crl
  1.1137 +)
  1.1138 +{
  1.1139 +    if (crl) {
  1.1140 +	nssPKIObject_AddRef(&crl->object);
  1.1141 +    }
  1.1142 +    return crl;
  1.1143 +}
  1.1144 +
  1.1145 +NSS_IMPLEMENT PRStatus
  1.1146 +nssCRL_Destroy (
  1.1147 +  NSSCRL *crl
  1.1148 +)
  1.1149 +{
  1.1150 +    if (crl) {
  1.1151 +	(void)nssPKIObject_Destroy(&crl->object);
  1.1152 +    }
  1.1153 +    return PR_SUCCESS;
  1.1154 +}
  1.1155 +
  1.1156 +NSS_IMPLEMENT PRStatus
  1.1157 +nssCRL_DeleteStoredObject (
  1.1158 +  NSSCRL *crl,
  1.1159 +  NSSCallback *uhh
  1.1160 +)
  1.1161 +{
  1.1162 +    return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
  1.1163 +}
  1.1164 +
  1.1165 +NSS_IMPLEMENT NSSDER *
  1.1166 +nssCRL_GetEncoding (
  1.1167 +  NSSCRL *crl
  1.1168 +)
  1.1169 +{
  1.1170 +    if (crl && crl->encoding.data != NULL && crl->encoding.size > 0) {
  1.1171 +	return &crl->encoding;
  1.1172 +    } else {
  1.1173 +	return (NSSDER *)NULL;
  1.1174 +    }
  1.1175 +}

mercurial