| OLD | NEW |
| (Empty) |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 4 | |
| 5 #include "prtime.h" | |
| 6 | |
| 7 #include "cert.h" | |
| 8 #include "certi.h" | |
| 9 #include "certdb.h" | |
| 10 #include "secitem.h" | |
| 11 #include "secder.h" | |
| 12 | |
| 13 /* Call to PK11_FreeSlot below */ | |
| 14 | |
| 15 #include "secasn1.h" | |
| 16 #include "secerr.h" | |
| 17 #include "nssilock.h" | |
| 18 #include "prmon.h" | |
| 19 #include "base64.h" | |
| 20 #include "sechash.h" | |
| 21 #include "plhash.h" | |
| 22 #include "pk11func.h" /* sigh */ | |
| 23 | |
| 24 #include "nsspki.h" | |
| 25 #include "pki.h" | |
| 26 #include "pkim.h" | |
| 27 #include "pki3hack.h" | |
| 28 #include "ckhelper.h" | |
| 29 #include "base.h" | |
| 30 #include "pkistore.h" | |
| 31 #include "dev3hack.h" | |
| 32 #include "dev.h" | |
| 33 | |
| 34 PRBool | |
| 35 SEC_CertNicknameConflict(const char *nickname, const SECItem *derSubject, | |
| 36 CERTCertDBHandle *handle) | |
| 37 { | |
| 38 CERTCertificate *cert; | |
| 39 PRBool conflict = PR_FALSE; | |
| 40 | |
| 41 cert = CERT_FindCertByNickname(handle, nickname); | |
| 42 | |
| 43 if (!cert) { | |
| 44 return conflict; | |
| 45 } | |
| 46 | |
| 47 conflict = !SECITEM_ItemsAreEqual(derSubject, &cert->derSubject); | |
| 48 CERT_DestroyCertificate(cert); | |
| 49 return conflict; | |
| 50 } | |
| 51 | |
| 52 SECStatus | |
| 53 SEC_DeletePermCertificate(CERTCertificate *cert) | |
| 54 { | |
| 55 PRStatus nssrv; | |
| 56 NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); | |
| 57 NSSCertificate *c = STAN_GetNSSCertificate(cert); | |
| 58 CERTCertTrust *certTrust; | |
| 59 | |
| 60 if (c == NULL) { | |
| 61 /* error code is set */ | |
| 62 return SECFailure; | |
| 63 } | |
| 64 | |
| 65 certTrust = nssTrust_GetCERTCertTrustForCert(c, cert); | |
| 66 if (certTrust) { | |
| 67 NSSTrust *nssTrust = nssTrustDomain_FindTrustForCertificate(td, c); | |
| 68 if (nssTrust) { | |
| 69 nssrv = STAN_DeleteCertTrustMatchingSlot(c); | |
| 70 if (nssrv != PR_SUCCESS) { | |
| 71 CERT_MapStanError(); | |
| 72 } | |
| 73 /* This call always returns PR_SUCCESS! */ | |
| 74 (void)nssTrust_Destroy(nssTrust); | |
| 75 } | |
| 76 } | |
| 77 | |
| 78 /* get rid of the token instances */ | |
| 79 nssrv = NSSCertificate_DeleteStoredObject(c, NULL); | |
| 80 | |
| 81 /* get rid of the cache entry */ | |
| 82 nssTrustDomain_LockCertCache(td); | |
| 83 nssTrustDomain_RemoveCertFromCacheLOCKED(td, c); | |
| 84 nssTrustDomain_UnlockCertCache(td); | |
| 85 | |
| 86 return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; | |
| 87 } | |
| 88 | |
| 89 SECStatus | |
| 90 CERT_GetCertTrust(const CERTCertificate *cert, CERTCertTrust *trust) | |
| 91 { | |
| 92 SECStatus rv; | |
| 93 CERT_LockCertTrust(cert); | |
| 94 if (cert->trust == NULL) { | |
| 95 rv = SECFailure; | |
| 96 } else { | |
| 97 *trust = *cert->trust; | |
| 98 rv = SECSuccess; | |
| 99 } | |
| 100 CERT_UnlockCertTrust(cert); | |
| 101 return (rv); | |
| 102 } | |
| 103 | |
| 104 extern const NSSError NSS_ERROR_NO_ERROR; | |
| 105 extern const NSSError NSS_ERROR_INTERNAL_ERROR; | |
| 106 extern const NSSError NSS_ERROR_NO_MEMORY; | |
| 107 extern const NSSError NSS_ERROR_INVALID_POINTER; | |
| 108 extern const NSSError NSS_ERROR_INVALID_ARENA; | |
| 109 extern const NSSError NSS_ERROR_INVALID_ARENA_MARK; | |
| 110 extern const NSSError NSS_ERROR_DUPLICATE_POINTER; | |
| 111 extern const NSSError NSS_ERROR_POINTER_NOT_REGISTERED; | |
| 112 extern const NSSError NSS_ERROR_TRACKER_NOT_EMPTY; | |
| 113 extern const NSSError NSS_ERROR_TRACKER_NOT_INITIALIZED; | |
| 114 extern const NSSError NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD; | |
| 115 extern const NSSError NSS_ERROR_VALUE_TOO_LARGE; | |
| 116 extern const NSSError NSS_ERROR_UNSUPPORTED_TYPE; | |
| 117 extern const NSSError NSS_ERROR_BUFFER_TOO_SHORT; | |
| 118 extern const NSSError NSS_ERROR_INVALID_ATOB_CONTEXT; | |
| 119 extern const NSSError NSS_ERROR_INVALID_BASE64; | |
| 120 extern const NSSError NSS_ERROR_INVALID_BTOA_CONTEXT; | |
| 121 extern const NSSError NSS_ERROR_INVALID_ITEM; | |
| 122 extern const NSSError NSS_ERROR_INVALID_STRING; | |
| 123 extern const NSSError NSS_ERROR_INVALID_ASN1ENCODER; | |
| 124 extern const NSSError NSS_ERROR_INVALID_ASN1DECODER; | |
| 125 extern const NSSError NSS_ERROR_INVALID_BER; | |
| 126 extern const NSSError NSS_ERROR_INVALID_ATAV; | |
| 127 extern const NSSError NSS_ERROR_INVALID_ARGUMENT; | |
| 128 extern const NSSError NSS_ERROR_INVALID_UTF8; | |
| 129 extern const NSSError NSS_ERROR_INVALID_NSSOID; | |
| 130 extern const NSSError NSS_ERROR_UNKNOWN_ATTRIBUTE; | |
| 131 extern const NSSError NSS_ERROR_NOT_FOUND; | |
| 132 extern const NSSError NSS_ERROR_INVALID_PASSWORD; | |
| 133 extern const NSSError NSS_ERROR_USER_CANCELED; | |
| 134 extern const NSSError NSS_ERROR_MAXIMUM_FOUND; | |
| 135 extern const NSSError NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND; | |
| 136 extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE; | |
| 137 extern const NSSError NSS_ERROR_HASH_COLLISION; | |
| 138 extern const NSSError NSS_ERROR_DEVICE_ERROR; | |
| 139 extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; | |
| 140 extern const NSSError NSS_ERROR_BUSY; | |
| 141 extern const NSSError NSS_ERROR_ALREADY_INITIALIZED; | |
| 142 extern const NSSError NSS_ERROR_PKCS11; | |
| 143 | |
| 144 /* Look at the stan error stack and map it to NSS 3 errors */ | |
| 145 #define STAN_MAP_ERROR(x, y) \ | |
| 146 else if (error == (x)) { secError = y; } | |
| 147 | |
| 148 /* | |
| 149 * map Stan errors into NSS errors | |
| 150 * This function examines the stan error stack and automatically sets | |
| 151 * PORT_SetError(); to the appropriate SEC_ERROR value. | |
| 152 */ | |
| 153 void | |
| 154 CERT_MapStanError() | |
| 155 { | |
| 156 PRInt32 *errorStack; | |
| 157 NSSError error, prevError; | |
| 158 int secError; | |
| 159 int i; | |
| 160 | |
| 161 error = 0; | |
| 162 | |
| 163 errorStack = NSS_GetErrorStack(); | |
| 164 if (errorStack == 0) { | |
| 165 PORT_SetError(0); | |
| 166 return; | |
| 167 } | |
| 168 error = prevError = CKR_GENERAL_ERROR; | |
| 169 /* get the 'top 2' error codes from the stack */ | |
| 170 for (i = 0; errorStack[i]; i++) { | |
| 171 prevError = error; | |
| 172 error = errorStack[i]; | |
| 173 } | |
| 174 if (error == NSS_ERROR_PKCS11) { | |
| 175 /* map it */ | |
| 176 secError = PK11_MapError(prevError); | |
| 177 } | |
| 178 STAN_MAP_ERROR(NSS_ERROR_NO_ERROR, 0) | |
| 179 STAN_MAP_ERROR(NSS_ERROR_NO_MEMORY, SEC_ERROR_NO_MEMORY) | |
| 180 STAN_MAP_ERROR(NSS_ERROR_INVALID_BASE64, SEC_ERROR_BAD_DATA) | |
| 181 STAN_MAP_ERROR(NSS_ERROR_INVALID_BER, SEC_ERROR_BAD_DER) | |
| 182 STAN_MAP_ERROR(NSS_ERROR_INVALID_ATAV, SEC_ERROR_INVALID_AVA) | |
| 183 STAN_MAP_ERROR(NSS_ERROR_INVALID_PASSWORD, SEC_ERROR_BAD_PASSWORD) | |
| 184 STAN_MAP_ERROR(NSS_ERROR_BUSY, SEC_ERROR_BUSY) | |
| 185 STAN_MAP_ERROR(NSS_ERROR_DEVICE_ERROR, SEC_ERROR_IO) | |
| 186 STAN_MAP_ERROR(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND, | |
| 187 SEC_ERROR_UNKNOWN_ISSUER) | |
| 188 STAN_MAP_ERROR(NSS_ERROR_INVALID_CERTIFICATE, SEC_ERROR_CERT_NOT_VALID) | |
| 189 STAN_MAP_ERROR(NSS_ERROR_INVALID_UTF8, SEC_ERROR_BAD_DATA) | |
| 190 STAN_MAP_ERROR(NSS_ERROR_INVALID_NSSOID, SEC_ERROR_BAD_DATA) | |
| 191 | |
| 192 /* these are library failure for lack of a better error code */ | |
| 193 STAN_MAP_ERROR(NSS_ERROR_NOT_FOUND, SEC_ERROR_LIBRARY_FAILURE) | |
| 194 STAN_MAP_ERROR(NSS_ERROR_CERTIFICATE_IN_CACHE, SEC_ERROR_LIBRARY_FAILURE) | |
| 195 STAN_MAP_ERROR(NSS_ERROR_MAXIMUM_FOUND, SEC_ERROR_LIBRARY_FAILURE) | |
| 196 STAN_MAP_ERROR(NSS_ERROR_USER_CANCELED, SEC_ERROR_LIBRARY_FAILURE) | |
| 197 STAN_MAP_ERROR(NSS_ERROR_TRACKER_NOT_INITIALIZED, SEC_ERROR_LIBRARY_FAILURE) | |
| 198 STAN_MAP_ERROR(NSS_ERROR_ALREADY_INITIALIZED, SEC_ERROR_LIBRARY_FAILURE) | |
| 199 STAN_MAP_ERROR(NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD, | |
| 200 SEC_ERROR_LIBRARY_FAILURE) | |
| 201 STAN_MAP_ERROR(NSS_ERROR_HASH_COLLISION, SEC_ERROR_LIBRARY_FAILURE) | |
| 202 | |
| 203 STAN_MAP_ERROR(NSS_ERROR_INTERNAL_ERROR, SEC_ERROR_LIBRARY_FAILURE) | |
| 204 | |
| 205 /* these are all invalid arguments */ | |
| 206 STAN_MAP_ERROR(NSS_ERROR_INVALID_ARGUMENT, SEC_ERROR_INVALID_ARGS) | |
| 207 STAN_MAP_ERROR(NSS_ERROR_INVALID_POINTER, SEC_ERROR_INVALID_ARGS) | |
| 208 STAN_MAP_ERROR(NSS_ERROR_INVALID_ARENA, SEC_ERROR_INVALID_ARGS) | |
| 209 STAN_MAP_ERROR(NSS_ERROR_INVALID_ARENA_MARK, SEC_ERROR_INVALID_ARGS) | |
| 210 STAN_MAP_ERROR(NSS_ERROR_DUPLICATE_POINTER, SEC_ERROR_INVALID_ARGS) | |
| 211 STAN_MAP_ERROR(NSS_ERROR_POINTER_NOT_REGISTERED, SEC_ERROR_INVALID_ARGS) | |
| 212 STAN_MAP_ERROR(NSS_ERROR_TRACKER_NOT_EMPTY, SEC_ERROR_INVALID_ARGS) | |
| 213 STAN_MAP_ERROR(NSS_ERROR_VALUE_TOO_LARGE, SEC_ERROR_INVALID_ARGS) | |
| 214 STAN_MAP_ERROR(NSS_ERROR_UNSUPPORTED_TYPE, SEC_ERROR_INVALID_ARGS) | |
| 215 STAN_MAP_ERROR(NSS_ERROR_BUFFER_TOO_SHORT, SEC_ERROR_INVALID_ARGS) | |
| 216 STAN_MAP_ERROR(NSS_ERROR_INVALID_ATOB_CONTEXT, SEC_ERROR_INVALID_ARGS) | |
| 217 STAN_MAP_ERROR(NSS_ERROR_INVALID_BTOA_CONTEXT, SEC_ERROR_INVALID_ARGS) | |
| 218 STAN_MAP_ERROR(NSS_ERROR_INVALID_ITEM, SEC_ERROR_INVALID_ARGS) | |
| 219 STAN_MAP_ERROR(NSS_ERROR_INVALID_STRING, SEC_ERROR_INVALID_ARGS) | |
| 220 STAN_MAP_ERROR(NSS_ERROR_INVALID_ASN1ENCODER, SEC_ERROR_INVALID_ARGS) | |
| 221 STAN_MAP_ERROR(NSS_ERROR_INVALID_ASN1DECODER, SEC_ERROR_INVALID_ARGS) | |
| 222 STAN_MAP_ERROR(NSS_ERROR_UNKNOWN_ATTRIBUTE, SEC_ERROR_INVALID_ARGS) | |
| 223 else { secError = SEC_ERROR_LIBRARY_FAILURE; } | |
| 224 PORT_SetError(secError); | |
| 225 } | |
| 226 | |
| 227 SECStatus | |
| 228 CERT_ChangeCertTrust(CERTCertDBHandle *handle, CERTCertificate *cert, | |
| 229 CERTCertTrust *trust) | |
| 230 { | |
| 231 SECStatus rv = SECSuccess; | |
| 232 PRStatus ret; | |
| 233 | |
| 234 ret = STAN_ChangeCertTrust(cert, trust); | |
| 235 if (ret != PR_SUCCESS) { | |
| 236 rv = SECFailure; | |
| 237 CERT_MapStanError(); | |
| 238 } | |
| 239 return rv; | |
| 240 } | |
| 241 | |
| 242 extern const NSSError NSS_ERROR_INVALID_CERTIFICATE; | |
| 243 | |
| 244 SECStatus | |
| 245 __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, | |
| 246 CERTCertTrust *trust) | |
| 247 { | |
| 248 NSSUTF8 *stanNick; | |
| 249 PK11SlotInfo *slot; | |
| 250 NSSToken *internal; | |
| 251 NSSCryptoContext *context; | |
| 252 nssCryptokiObject *permInstance; | |
| 253 NSSCertificate *c = STAN_GetNSSCertificate(cert); | |
| 254 nssCertificateStoreTrace lockTrace = { NULL, NULL, PR_FALSE, PR_FALSE }; | |
| 255 nssCertificateStoreTrace unlockTrace = { NULL, NULL, PR_FALSE, PR_FALSE }; | |
| 256 SECStatus rv; | |
| 257 PRStatus ret; | |
| 258 | |
| 259 if (c == NULL) { | |
| 260 CERT_MapStanError(); | |
| 261 return SECFailure; | |
| 262 } | |
| 263 | |
| 264 context = c->object.cryptoContext; | |
| 265 if (!context) { | |
| 266 PORT_SetError(SEC_ERROR_ADDING_CERT); | |
| 267 return SECFailure; /* wasn't a temp cert */ | |
| 268 } | |
| 269 stanNick = nssCertificate_GetNickname(c, NULL); | |
| 270 if (stanNick && nickname && strcmp(nickname, stanNick) != 0) { | |
| 271 /* different: take the new nickname */ | |
| 272 cert->nickname = NULL; | |
| 273 nss_ZFreeIf(stanNick); | |
| 274 stanNick = NULL; | |
| 275 } | |
| 276 if (!stanNick && nickname) { | |
| 277 /* Either there was no nickname yet, or we have a new nickname */ | |
| 278 stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, NULL); | |
| 279 } /* else: old stanNick is identical to new nickname */ | |
| 280 /* Delete the temp instance */ | |
| 281 nssCertificateStore_Lock(context->certStore, &lockTrace); | |
| 282 nssCertificateStore_RemoveCertLOCKED(context->certStore, c); | |
| 283 nssCertificateStore_Unlock(context->certStore, &lockTrace, &unlockTrace); | |
| 284 c->object.cryptoContext = NULL; | |
| 285 /* Import the perm instance onto the internal token */ | |
| 286 slot = PK11_GetInternalKeySlot(); | |
| 287 internal = PK11Slot_GetNSSToken(slot); | |
| 288 permInstance = nssToken_ImportCertificate( | |
| 289 internal, NULL, NSSCertificateType_PKIX, &c->id, stanNick, &c->encoding, | |
| 290 &c->issuer, &c->subject, &c->serial, cert->emailAddr, PR_TRUE); | |
| 291 nss_ZFreeIf(stanNick); | |
| 292 stanNick = NULL; | |
| 293 PK11_FreeSlot(slot); | |
| 294 if (!permInstance) { | |
| 295 if (NSS_GetError() == NSS_ERROR_INVALID_CERTIFICATE) { | |
| 296 PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); | |
| 297 } | |
| 298 return SECFailure; | |
| 299 } | |
| 300 nssPKIObject_AddInstance(&c->object, permInstance); | |
| 301 nssTrustDomain_AddCertsToCache(STAN_GetDefaultTrustDomain(), &c, 1); | |
| 302 /* reset the CERTCertificate fields */ | |
| 303 cert->nssCertificate = NULL; | |
| 304 cert = STAN_GetCERTCertificateOrRelease(c); /* should return same pointer */ | |
| 305 if (!cert) { | |
| 306 CERT_MapStanError(); | |
| 307 return SECFailure; | |
| 308 } | |
| 309 cert->istemp = PR_FALSE; | |
| 310 cert->isperm = PR_TRUE; | |
| 311 if (!trust) { | |
| 312 return SECSuccess; | |
| 313 } | |
| 314 ret = STAN_ChangeCertTrust(cert, trust); | |
| 315 rv = SECSuccess; | |
| 316 if (ret != PR_SUCCESS) { | |
| 317 rv = SECFailure; | |
| 318 CERT_MapStanError(); | |
| 319 } | |
| 320 return rv; | |
| 321 } | |
| 322 | |
| 323 SECStatus | |
| 324 CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, | |
| 325 CERTCertTrust *trust) | |
| 326 { | |
| 327 return __CERT_AddTempCertToPerm(cert, nickname, trust); | |
| 328 } | |
| 329 | |
| 330 CERTCertificate * | |
| 331 CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, | |
| 332 char *nickname, PRBool isperm, PRBool copyDER) | |
| 333 { | |
| 334 NSSCertificate *c; | |
| 335 CERTCertificate *cc; | |
| 336 NSSCertificate *tempCert = NULL; | |
| 337 nssPKIObject *pkio; | |
| 338 NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext(); | |
| 339 NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain(); | |
| 340 if (!isperm) { | |
| 341 NSSDER encoding; | |
| 342 NSSITEM_FROM_SECITEM(&encoding, derCert); | |
| 343 /* First, see if it is already a temp cert */ | |
| 344 c = NSSCryptoContext_FindCertificateByEncodedCertificate(gCC, | |
| 345 &encoding); | |
| 346 if (!c) { | |
| 347 /* Then, see if it is already a perm cert */ | |
| 348 c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle, | |
| 349 &encoding); | |
| 350 } | |
| 351 if (c) { | |
| 352 /* actually, that search ends up going by issuer/serial, | |
| 353 * so it is still possible to return a cert with the same | |
| 354 * issuer/serial but a different encoding, and we're | |
| 355 * going to reject that | |
| 356 */ | |
| 357 if (!nssItem_Equal(&c->encoding, &encoding, NULL)) { | |
| 358 nssCertificate_Destroy(c); | |
| 359 PORT_SetError(SEC_ERROR_REUSED_ISSUER_AND_SERIAL); | |
| 360 cc = NULL; | |
| 361 } else { | |
| 362 cc = STAN_GetCERTCertificateOrRelease(c); | |
| 363 if (cc == NULL) { | |
| 364 CERT_MapStanError(); | |
| 365 } | |
| 366 } | |
| 367 return cc; | |
| 368 } | |
| 369 } | |
| 370 pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC, nssPKIMonitor); | |
| 371 if (!pkio) { | |
| 372 CERT_MapStanError(); | |
| 373 return NULL; | |
| 374 } | |
| 375 c = nss_ZNEW(pkio->arena, NSSCertificate); | |
| 376 if (!c) { | |
| 377 CERT_MapStanError(); | |
| 378 nssPKIObject_Destroy(pkio); | |
| 379 return NULL; | |
| 380 } | |
| 381 c->object = *pkio; | |
| 382 if (copyDER) { | |
| 383 nssItem_Create(c->object.arena, &c->encoding, derCert->len, | |
| 384 derCert->data); | |
| 385 } else { | |
| 386 NSSITEM_FROM_SECITEM(&c->encoding, derCert); | |
| 387 } | |
| 388 /* Forces a decoding of the cert in order to obtain the parts used | |
| 389 * below | |
| 390 */ | |
| 391 /* 'c' is not adopted here, if we fail loser frees what has been | |
| 392 * allocated so far for 'c' */ | |
| 393 cc = STAN_GetCERTCertificate(c); | |
| 394 if (!cc) { | |
| 395 CERT_MapStanError(); | |
| 396 goto loser; | |
| 397 } | |
| 398 nssItem_Create(c->object.arena, &c->issuer, cc->derIssuer.len, | |
| 399 cc->derIssuer.data); | |
| 400 nssItem_Create(c->object.arena, &c->subject, cc->derSubject.len, | |
| 401 cc->derSubject.data); | |
| 402 if (PR_TRUE) { | |
| 403 /* CERTCertificate stores serial numbers decoded. I need the DER | |
| 404 * here. sigh. | |
| 405 */ | |
| 406 SECItem derSerial = { 0 }; | |
| 407 CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial); | |
| 408 if (!derSerial.data) | |
| 409 goto loser; | |
| 410 nssItem_Create(c->object.arena, &c->serial, derSerial.len, | |
| 411 derSerial.data); | |
| 412 PORT_Free(derSerial.data); | |
| 413 } | |
| 414 if (nickname) { | |
| 415 c->object.tempName = | |
| 416 nssUTF8_Create(c->object.arena, nssStringType_UTF8String, | |
| 417 (NSSUTF8 *)nickname, PORT_Strlen(nickname)); | |
| 418 } | |
| 419 if (cc->emailAddr && cc->emailAddr[0]) { | |
| 420 c->email = nssUTF8_Create( | |
| 421 c->object.arena, nssStringType_PrintableString, | |
| 422 (NSSUTF8 *)cc->emailAddr, PORT_Strlen(cc->emailAddr)); | |
| 423 } | |
| 424 | |
| 425 tempCert = NSSCryptoContext_FindOrImportCertificate(gCC, c); | |
| 426 if (!tempCert) { | |
| 427 CERT_MapStanError(); | |
| 428 goto loser; | |
| 429 } | |
| 430 /* destroy our copy */ | |
| 431 NSSCertificate_Destroy(c); | |
| 432 /* and use the stored entry */ | |
| 433 c = tempCert; | |
| 434 cc = STAN_GetCERTCertificateOrRelease(c); | |
| 435 if (!cc) { | |
| 436 /* STAN_GetCERTCertificateOrRelease destroys c on failure. */ | |
| 437 CERT_MapStanError(); | |
| 438 return NULL; | |
| 439 } | |
| 440 | |
| 441 cc->istemp = PR_TRUE; | |
| 442 cc->isperm = PR_FALSE; | |
| 443 return cc; | |
| 444 loser: | |
| 445 /* Perhaps this should be nssCertificate_Destroy(c) */ | |
| 446 nssPKIObject_Destroy(&c->object); | |
| 447 return NULL; | |
| 448 } | |
| 449 | |
| 450 /* This symbol is exported for backward compatibility. */ | |
| 451 CERTCertificate * | |
| 452 __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, | |
| 453 char *nickname, PRBool isperm, PRBool copyDER) | |
| 454 { | |
| 455 return CERT_NewTempCertificate(handle, derCert, nickname, isperm, copyDER); | |
| 456 } | |
| 457 | |
| 458 /* maybe all the wincx's should be some const for internal token login? */ | |
| 459 CERTCertificate * | |
| 460 CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, | |
| 461 CERTIssuerAndSN *issuerAndSN) | |
| 462 { | |
| 463 PK11SlotInfo *slot; | |
| 464 CERTCertificate *cert; | |
| 465 | |
| 466 cert = PK11_FindCertByIssuerAndSN(&slot, issuerAndSN, NULL); | |
| 467 if (cert && slot) { | |
| 468 PK11_FreeSlot(slot); | |
| 469 } | |
| 470 | |
| 471 return cert; | |
| 472 } | |
| 473 | |
| 474 static NSSCertificate * | |
| 475 get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp) | |
| 476 { | |
| 477 NSSUsage usage; | |
| 478 NSSCertificate *arr[3]; | |
| 479 if (!ct) { | |
| 480 return nssCertificate_AddRef(cp); | |
| 481 } else if (!cp) { | |
| 482 return nssCertificate_AddRef(ct); | |
| 483 } | |
| 484 arr[0] = ct; | |
| 485 arr[1] = cp; | |
| 486 arr[2] = NULL; | |
| 487 usage.anyUsage = PR_TRUE; | |
| 488 return nssCertificateArray_FindBestCertificate(arr, NULL, &usage, NULL); | |
| 489 } | |
| 490 | |
| 491 CERTCertificate * | |
| 492 CERT_FindCertByName(CERTCertDBHandle *handle, SECItem *name) | |
| 493 { | |
| 494 NSSCertificate *cp, *ct, *c; | |
| 495 NSSDER subject; | |
| 496 NSSUsage usage; | |
| 497 NSSCryptoContext *cc; | |
| 498 NSSITEM_FROM_SECITEM(&subject, name); | |
| 499 usage.anyUsage = PR_TRUE; | |
| 500 cc = STAN_GetDefaultCryptoContext(); | |
| 501 ct = NSSCryptoContext_FindBestCertificateBySubject(cc, &subject, NULL, | |
| 502 &usage, NULL); | |
| 503 cp = NSSTrustDomain_FindBestCertificateBySubject(handle, &subject, NULL, | |
| 504 &usage, NULL); | |
| 505 c = get_best_temp_or_perm(ct, cp); | |
| 506 if (ct) { | |
| 507 CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct)); | |
| 508 } | |
| 509 if (cp) { | |
| 510 CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(cp)); | |
| 511 } | |
| 512 return c ? STAN_GetCERTCertificateOrRelease(c) : NULL; | |
| 513 } | |
| 514 | |
| 515 CERTCertificate * | |
| 516 CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID) | |
| 517 { | |
| 518 CERTCertList *list; | |
| 519 CERTCertificate *cert = NULL; | |
| 520 CERTCertListNode *node, *head; | |
| 521 | |
| 522 list = CERT_CreateSubjectCertList(NULL, handle, name, 0, PR_FALSE); | |
| 523 if (list == NULL) | |
| 524 return NULL; | |
| 525 | |
| 526 node = head = CERT_LIST_HEAD(list); | |
| 527 if (head) { | |
| 528 do { | |
| 529 if (node->cert && | |
| 530 SECITEM_ItemsAreEqual(&node->cert->subjectKeyID, keyID)) { | |
| 531 cert = CERT_DupCertificate(node->cert); | |
| 532 goto done; | |
| 533 } | |
| 534 node = CERT_LIST_NEXT(node); | |
| 535 } while (node && head != node); | |
| 536 } | |
| 537 PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER); | |
| 538 done: | |
| 539 if (list) { | |
| 540 CERT_DestroyCertList(list); | |
| 541 } | |
| 542 return cert; | |
| 543 } | |
| 544 | |
| 545 CERTCertificate * | |
| 546 CERT_FindCertByNickname(CERTCertDBHandle *handle, const char *nickname) | |
| 547 { | |
| 548 NSSCryptoContext *cc; | |
| 549 NSSCertificate *c, *ct; | |
| 550 CERTCertificate *cert; | |
| 551 NSSUsage usage; | |
| 552 usage.anyUsage = PR_TRUE; | |
| 553 cc = STAN_GetDefaultCryptoContext(); | |
| 554 ct = NSSCryptoContext_FindBestCertificateByNickname(cc, nickname, NULL, | |
| 555 &usage, NULL); | |
| 556 cert = PK11_FindCertFromNickname(nickname, NULL); | |
| 557 c = NULL; | |
| 558 if (cert) { | |
| 559 c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert)); | |
| 560 CERT_DestroyCertificate(cert); | |
| 561 if (ct) { | |
| 562 CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct)); | |
| 563 } | |
| 564 } else { | |
| 565 c = ct; | |
| 566 } | |
| 567 return c ? STAN_GetCERTCertificateOrRelease(c) : NULL; | |
| 568 } | |
| 569 | |
| 570 CERTCertificate * | |
| 571 CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert) | |
| 572 { | |
| 573 NSSCryptoContext *cc; | |
| 574 NSSCertificate *c; | |
| 575 NSSDER encoding; | |
| 576 NSSITEM_FROM_SECITEM(&encoding, derCert); | |
| 577 cc = STAN_GetDefaultCryptoContext(); | |
| 578 c = NSSCryptoContext_FindCertificateByEncodedCertificate(cc, &encoding); | |
| 579 if (!c) { | |
| 580 c = NSSTrustDomain_FindCertificateByEncodedCertificate(handle, | |
| 581 &encoding); | |
| 582 if (!c) | |
| 583 return NULL; | |
| 584 } | |
| 585 return STAN_GetCERTCertificateOrRelease(c); | |
| 586 } | |
| 587 | |
| 588 static CERTCertificate * | |
| 589 common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, | |
| 590 const char *name, PRBool anyUsage, | |
| 591 SECCertUsage lookingForUsage) | |
| 592 { | |
| 593 NSSCryptoContext *cc; | |
| 594 NSSCertificate *c, *ct; | |
| 595 CERTCertificate *cert = NULL; | |
| 596 NSSUsage usage; | |
| 597 CERTCertList *certlist; | |
| 598 | |
| 599 if (NULL == name) { | |
| 600 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
| 601 return NULL; | |
| 602 } | |
| 603 | |
| 604 usage.anyUsage = anyUsage; | |
| 605 | |
| 606 if (!anyUsage) { | |
| 607 usage.nss3lookingForCA = PR_FALSE; | |
| 608 usage.nss3usage = lookingForUsage; | |
| 609 } | |
| 610 | |
| 611 cc = STAN_GetDefaultCryptoContext(); | |
| 612 ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, NULL, &usage, | |
| 613 NULL); | |
| 614 if (!ct && PORT_Strchr(name, '@') != NULL) { | |
| 615 char *lowercaseName = CERT_FixupEmailAddr(name); | |
| 616 if (lowercaseName) { | |
| 617 ct = NSSCryptoContext_FindBestCertificateByEmail( | |
| 618 cc, lowercaseName, NULL, &usage, NULL); | |
| 619 PORT_Free(lowercaseName); | |
| 620 } | |
| 621 } | |
| 622 | |
| 623 if (anyUsage) { | |
| 624 cert = PK11_FindCertFromNickname(name, NULL); | |
| 625 } else { | |
| 626 if (ct) { | |
| 627 /* Does ct really have the required usage? */ | |
| 628 nssDecodedCert *dc; | |
| 629 dc = nssCertificate_GetDecoding(ct); | |
| 630 if (!dc->matchUsage(dc, &usage)) { | |
| 631 CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct)); | |
| 632 ct = NULL; | |
| 633 } | |
| 634 } | |
| 635 | |
| 636 certlist = PK11_FindCertsFromNickname(name, NULL); | |
| 637 if (certlist) { | |
| 638 SECStatus rv = | |
| 639 CERT_FilterCertListByUsage(certlist, lookingForUsage, PR_FALSE); | |
| 640 if (SECSuccess == rv && | |
| 641 !CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist)) { | |
| 642 cert = CERT_DupCertificate(CERT_LIST_HEAD(certlist)->cert); | |
| 643 } | |
| 644 CERT_DestroyCertList(certlist); | |
| 645 } | |
| 646 } | |
| 647 | |
| 648 if (cert) { | |
| 649 c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert)); | |
| 650 CERT_DestroyCertificate(cert); | |
| 651 if (ct) { | |
| 652 CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct)); | |
| 653 } | |
| 654 } else { | |
| 655 c = ct; | |
| 656 } | |
| 657 return c ? STAN_GetCERTCertificateOrRelease(c) : NULL; | |
| 658 } | |
| 659 | |
| 660 CERTCertificate * | |
| 661 CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name) | |
| 662 { | |
| 663 return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_TRUE, | |
| 664 0); | |
| 665 } | |
| 666 | |
| 667 CERTCertificate * | |
| 668 CERT_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, | |
| 669 const char *name, | |
| 670 SECCertUsage lookingForUsage) | |
| 671 { | |
| 672 return common_FindCertByNicknameOrEmailAddrForUsage(handle, name, PR_FALSE, | |
| 673 lookingForUsage); | |
| 674 } | |
| 675 | |
| 676 static void | |
| 677 add_to_subject_list(CERTCertList *certList, CERTCertificate *cert, | |
| 678 PRBool validOnly, PRTime sorttime) | |
| 679 { | |
| 680 SECStatus secrv; | |
| 681 if (!validOnly || | |
| 682 CERT_CheckCertValidTimes(cert, sorttime, PR_FALSE) == | |
| 683 secCertTimeValid) { | |
| 684 secrv = CERT_AddCertToListSorted(certList, cert, CERT_SortCBValidity, | |
| 685 (void *)&sorttime); | |
| 686 if (secrv != SECSuccess) { | |
| 687 CERT_DestroyCertificate(cert); | |
| 688 } | |
| 689 } else { | |
| 690 CERT_DestroyCertificate(cert); | |
| 691 } | |
| 692 } | |
| 693 | |
| 694 CERTCertList * | |
| 695 CERT_CreateSubjectCertList(CERTCertList *certList, CERTCertDBHandle *handle, | |
| 696 const SECItem *name, PRTime sorttime, | |
| 697 PRBool validOnly) | |
| 698 { | |
| 699 NSSCryptoContext *cc; | |
| 700 NSSCertificate **tSubjectCerts, **pSubjectCerts; | |
| 701 NSSCertificate **ci; | |
| 702 CERTCertificate *cert; | |
| 703 NSSDER subject; | |
| 704 PRBool myList = PR_FALSE; | |
| 705 cc = STAN_GetDefaultCryptoContext(); | |
| 706 NSSITEM_FROM_SECITEM(&subject, name); | |
| 707 /* Collect both temp and perm certs for the subject */ | |
| 708 tSubjectCerts = | |
| 709 NSSCryptoContext_FindCertificatesBySubject(cc, &subject, NULL, 0, NULL); | |
| 710 pSubjectCerts = NSSTrustDomain_FindCertificatesBySubject(handle, &subject, | |
| 711 NULL, 0, NULL); | |
| 712 if (!tSubjectCerts && !pSubjectCerts) { | |
| 713 return NULL; | |
| 714 } | |
| 715 if (certList == NULL) { | |
| 716 certList = CERT_NewCertList(); | |
| 717 myList = PR_TRUE; | |
| 718 if (!certList) | |
| 719 goto loser; | |
| 720 } | |
| 721 /* Iterate over the matching temp certs. Add them to the list */ | |
| 722 ci = tSubjectCerts; | |
| 723 while (ci && *ci) { | |
| 724 cert = STAN_GetCERTCertificateOrRelease(*ci); | |
| 725 /* *ci may be invalid at this point, don't reference it again */ | |
| 726 if (cert) { | |
| 727 /* NOTE: add_to_subject_list adopts the incoming cert. */ | |
| 728 add_to_subject_list(certList, cert, validOnly, sorttime); | |
| 729 } | |
| 730 ci++; | |
| 731 } | |
| 732 /* Iterate over the matching perm certs. Add them to the list */ | |
| 733 ci = pSubjectCerts; | |
| 734 while (ci && *ci) { | |
| 735 cert = STAN_GetCERTCertificateOrRelease(*ci); | |
| 736 /* *ci may be invalid at this point, don't reference it again */ | |
| 737 if (cert) { | |
| 738 /* NOTE: add_to_subject_list adopts the incoming cert. */ | |
| 739 add_to_subject_list(certList, cert, validOnly, sorttime); | |
| 740 } | |
| 741 ci++; | |
| 742 } | |
| 743 /* all the references have been adopted or freed at this point, just | |
| 744 * free the arrays now */ | |
| 745 nss_ZFreeIf(tSubjectCerts); | |
| 746 nss_ZFreeIf(pSubjectCerts); | |
| 747 return certList; | |
| 748 loser: | |
| 749 /* need to free the references in tSubjectCerts and pSubjectCerts! */ | |
| 750 nssCertificateArray_Destroy(tSubjectCerts); | |
| 751 nssCertificateArray_Destroy(pSubjectCerts); | |
| 752 if (myList && certList != NULL) { | |
| 753 CERT_DestroyCertList(certList); | |
| 754 } | |
| 755 return NULL; | |
| 756 } | |
| 757 | |
| 758 void | |
| 759 CERT_DestroyCertificate(CERTCertificate *cert) | |
| 760 { | |
| 761 if (cert) { | |
| 762 /* don't use STAN_GetNSSCertificate because we don't want to | |
| 763 * go to the trouble of translating the CERTCertificate into | |
| 764 * an NSSCertificate just to destroy it. If it hasn't been done | |
| 765 * yet, don't do it at all. | |
| 766 */ | |
| 767 NSSCertificate *tmp = cert->nssCertificate; | |
| 768 if (tmp) { | |
| 769 /* delete the NSSCertificate */ | |
| 770 NSSCertificate_Destroy(tmp); | |
| 771 } else if (cert->arena) { | |
| 772 PORT_FreeArena(cert->arena, PR_FALSE); | |
| 773 } | |
| 774 } | |
| 775 return; | |
| 776 } | |
| 777 | |
| 778 int | |
| 779 CERT_GetDBContentVersion(CERTCertDBHandle *handle) | |
| 780 { | |
| 781 /* should read the DB content version from the pkcs #11 device */ | |
| 782 return 0; | |
| 783 } | |
| 784 | |
| 785 SECStatus | |
| 786 certdb_SaveSingleProfile(CERTCertificate *cert, const char *emailAddr, | |
| 787 SECItem *emailProfile, SECItem *profileTime) | |
| 788 { | |
| 789 PRTime oldtime; | |
| 790 PRTime newtime; | |
| 791 SECStatus rv = SECFailure; | |
| 792 PRBool saveit; | |
| 793 SECItem oldprof, oldproftime; | |
| 794 SECItem *oldProfile = NULL; | |
| 795 SECItem *oldProfileTime = NULL; | |
| 796 PK11SlotInfo *slot = NULL; | |
| 797 NSSCertificate *c; | |
| 798 NSSCryptoContext *cc; | |
| 799 nssSMIMEProfile *stanProfile = NULL; | |
| 800 PRBool freeOldProfile = PR_FALSE; | |
| 801 | |
| 802 c = STAN_GetNSSCertificate(cert); | |
| 803 if (!c) | |
| 804 return SECFailure; | |
| 805 cc = c->object.cryptoContext; | |
| 806 if (cc != NULL) { | |
| 807 stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c); | |
| 808 if (stanProfile) { | |
| 809 PORT_Assert(stanProfile->profileData); | |
| 810 SECITEM_FROM_NSSITEM(&oldprof, stanProfile->profileData); | |
| 811 oldProfile = &oldprof; | |
| 812 SECITEM_FROM_NSSITEM(&oldproftime, stanProfile->profileTime); | |
| 813 oldProfileTime = &oldproftime; | |
| 814 } | |
| 815 } else { | |
| 816 oldProfile = PK11_FindSMimeProfile(&slot, (char *)emailAddr, | |
| 817 &cert->derSubject, &oldProfileTime); | |
| 818 freeOldProfile = PR_TRUE; | |
| 819 } | |
| 820 | |
| 821 saveit = PR_FALSE; | |
| 822 | |
| 823 /* both profileTime and emailProfile have to exist or not exist */ | |
| 824 if (emailProfile == NULL) { | |
| 825 profileTime = NULL; | |
| 826 } else if (profileTime == NULL) { | |
| 827 emailProfile = NULL; | |
| 828 } | |
| 829 | |
| 830 if (oldProfileTime == NULL) { | |
| 831 saveit = PR_TRUE; | |
| 832 } else { | |
| 833 /* there was already a profile for this email addr */ | |
| 834 if (profileTime) { | |
| 835 /* we have an old and new profile - save whichever is more recent*/ | |
| 836 if (oldProfileTime->len == 0) { | |
| 837 /* always replace if old entry doesn't have a time */ | |
| 838 oldtime = LL_MININT; | |
| 839 } else { | |
| 840 rv = DER_UTCTimeToTime(&oldtime, oldProfileTime); | |
| 841 if (rv != SECSuccess) { | |
| 842 goto loser; | |
| 843 } | |
| 844 } | |
| 845 | |
| 846 rv = DER_UTCTimeToTime(&newtime, profileTime); | |
| 847 if (rv != SECSuccess) { | |
| 848 goto loser; | |
| 849 } | |
| 850 | |
| 851 if (LL_CMP(newtime, >, oldtime)) { | |
| 852 /* this is a newer profile, save it and cert */ | |
| 853 saveit = PR_TRUE; | |
| 854 } | |
| 855 } else { | |
| 856 saveit = PR_TRUE; | |
| 857 } | |
| 858 } | |
| 859 | |
| 860 if (saveit) { | |
| 861 if (cc) { | |
| 862 if (stanProfile) { | |
| 863 /* stanProfile is already stored in the crypto context, | |
| 864 * overwrite the data | |
| 865 */ | |
| 866 NSSArena *arena = stanProfile->object.arena; | |
| 867 stanProfile->profileTime = nssItem_Create( | |
| 868 arena, NULL, profileTime->len, profileTime->data); | |
| 869 stanProfile->profileData = nssItem_Create( | |
| 870 arena, NULL, emailProfile->len, emailProfile->data); | |
| 871 } else if (profileTime && emailProfile) { | |
| 872 PRStatus nssrv; | |
| 873 NSSItem profTime, profData; | |
| 874 NSSITEM_FROM_SECITEM(&profTime, profileTime); | |
| 875 NSSITEM_FROM_SECITEM(&profData, emailProfile); | |
| 876 stanProfile = nssSMIMEProfile_Create(c, &profTime, &profData); | |
| 877 if (!stanProfile) | |
| 878 goto loser; | |
| 879 nssrv = nssCryptoContext_ImportSMIMEProfile(cc, stanProfile); | |
| 880 rv = (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; | |
| 881 } | |
| 882 } else { | |
| 883 rv = PK11_SaveSMimeProfile(slot, (char *)emailAddr, | |
| 884 &cert->derSubject, emailProfile, | |
| 885 profileTime); | |
| 886 } | |
| 887 } else { | |
| 888 rv = SECSuccess; | |
| 889 } | |
| 890 | |
| 891 loser: | |
| 892 if (oldProfile && freeOldProfile) { | |
| 893 SECITEM_FreeItem(oldProfile, PR_TRUE); | |
| 894 } | |
| 895 if (oldProfileTime && freeOldProfile) { | |
| 896 SECITEM_FreeItem(oldProfileTime, PR_TRUE); | |
| 897 } | |
| 898 if (stanProfile) { | |
| 899 nssSMIMEProfile_Destroy(stanProfile); | |
| 900 } | |
| 901 if (slot) { | |
| 902 PK11_FreeSlot(slot); | |
| 903 } | |
| 904 | |
| 905 return (rv); | |
| 906 } | |
| 907 | |
| 908 /* | |
| 909 * | |
| 910 * Manage S/MIME profiles | |
| 911 * | |
| 912 */ | |
| 913 | |
| 914 SECStatus | |
| 915 CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile, | |
| 916 SECItem *profileTime) | |
| 917 { | |
| 918 const char *emailAddr; | |
| 919 SECStatus rv; | |
| 920 | |
| 921 if (!cert) { | |
| 922 return SECFailure; | |
| 923 } | |
| 924 | |
| 925 if (cert->slot && !PK11_IsInternal(cert->slot)) { | |
| 926 /* this cert comes from an external source, we need to add it | |
| 927 to the cert db before creating an S/MIME profile */ | |
| 928 PK11SlotInfo *internalslot = PK11_GetInternalKeySlot(); | |
| 929 if (!internalslot) { | |
| 930 return SECFailure; | |
| 931 } | |
| 932 rv = PK11_ImportCert(internalslot, cert, CK_INVALID_HANDLE, NULL, | |
| 933 PR_FALSE); | |
| 934 | |
| 935 PK11_FreeSlot(internalslot); | |
| 936 if (rv != SECSuccess) { | |
| 937 return SECFailure; | |
| 938 } | |
| 939 } | |
| 940 | |
| 941 if (cert->slot && cert->isperm && CERT_IsUserCert(cert) && | |
| 942 (!emailProfile || !emailProfile->len)) { | |
| 943 /* Don't clobber emailProfile for user certs. */ | |
| 944 return SECSuccess; | |
| 945 } | |
| 946 | |
| 947 for (emailAddr = CERT_GetFirstEmailAddress(cert); emailAddr != NULL; | |
| 948 emailAddr = CERT_GetNextEmailAddress(cert, emailAddr)) { | |
| 949 rv = certdb_SaveSingleProfile(cert, emailAddr, emailProfile, | |
| 950 profileTime); | |
| 951 if (rv != SECSuccess) { | |
| 952 return SECFailure; | |
| 953 } | |
| 954 } | |
| 955 return SECSuccess; | |
| 956 } | |
| 957 | |
| 958 SECItem * | |
| 959 CERT_FindSMimeProfile(CERTCertificate *cert) | |
| 960 { | |
| 961 PK11SlotInfo *slot = NULL; | |
| 962 NSSCertificate *c; | |
| 963 NSSCryptoContext *cc; | |
| 964 SECItem *rvItem = NULL; | |
| 965 | |
| 966 if (!cert || !cert->emailAddr || !cert->emailAddr[0]) { | |
| 967 PORT_SetError(SEC_ERROR_INVALID_ARGS); | |
| 968 return NULL; | |
| 969 } | |
| 970 c = STAN_GetNSSCertificate(cert); | |
| 971 if (!c) | |
| 972 return NULL; | |
| 973 cc = c->object.cryptoContext; | |
| 974 if (cc != NULL) { | |
| 975 nssSMIMEProfile *stanProfile; | |
| 976 stanProfile = nssCryptoContext_FindSMIMEProfileForCertificate(cc, c); | |
| 977 if (stanProfile) { | |
| 978 rvItem = | |
| 979 SECITEM_AllocItem(NULL, NULL, stanProfile->profileData->size); | |
| 980 if (rvItem) { | |
| 981 rvItem->data = stanProfile->profileData->data; | |
| 982 } | |
| 983 nssSMIMEProfile_Destroy(stanProfile); | |
| 984 } | |
| 985 return rvItem; | |
| 986 } | |
| 987 rvItem = | |
| 988 PK11_FindSMimeProfile(&slot, cert->emailAddr, &cert->derSubject, NULL); | |
| 989 if (slot) { | |
| 990 PK11_FreeSlot(slot); | |
| 991 } | |
| 992 return rvItem; | |
| 993 } | |
| 994 | |
| 995 /* | |
| 996 * deprecated functions that are now just stubs. | |
| 997 */ | |
| 998 /* | |
| 999 * Close the database | |
| 1000 */ | |
| 1001 void | |
| 1002 __CERT_ClosePermCertDB(CERTCertDBHandle *handle) | |
| 1003 { | |
| 1004 PORT_Assert("CERT_ClosePermCertDB is Deprecated" == NULL); | |
| 1005 return; | |
| 1006 } | |
| 1007 | |
| 1008 SECStatus | |
| 1009 CERT_OpenCertDBFilename(CERTCertDBHandle *handle, char *certdbname, | |
| 1010 PRBool readOnly) | |
| 1011 { | |
| 1012 PORT_Assert("CERT_OpenCertDBFilename is Deprecated" == NULL); | |
| 1013 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
| 1014 return SECFailure; | |
| 1015 } | |
| 1016 | |
| 1017 SECItem * | |
| 1018 SECKEY_HashPassword(char *pw, SECItem *salt) | |
| 1019 { | |
| 1020 PORT_Assert("SECKEY_HashPassword is Deprecated" == NULL); | |
| 1021 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
| 1022 return NULL; | |
| 1023 } | |
| 1024 | |
| 1025 SECStatus | |
| 1026 __CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle, | |
| 1027 SECItem *derSubject, void *cb, void *cbarg) | |
| 1028 { | |
| 1029 PORT_Assert("CERT_TraversePermCertsForSubject is Deprecated" == NULL); | |
| 1030 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
| 1031 return SECFailure; | |
| 1032 } | |
| 1033 | |
| 1034 SECStatus | |
| 1035 __CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname, | |
| 1036 void *cb, void *cbarg) | |
| 1037 { | |
| 1038 PORT_Assert("CERT_TraversePermCertsForNickname is Deprecated" == NULL); | |
| 1039 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | |
| 1040 return SECFailure; | |
| 1041 } | |
| OLD | NEW |