NSS_IMPLEMENT PRBool nssUTF8_Equal(const NSSUTF8 *a, const NSSUTF8 *b, PRStatus *statusOpt) { PRUint32 la, lb; #ifdef NSSDEBUG if (((const NSSUTF8 *)NULL == a) || ((const NSSUTF8 *)NULL == b)) { nss_SetError(NSS_ERROR_INVALID_POINTER); if ((PRStatus *)NULL != statusOpt) { *statusOpt = PR_FAILURE; } return PR_FALSE; } #endif /* NSSDEBUG */ la = nssUTF8_Size(a, statusOpt); if (0 == la) { return PR_FALSE; } lb = nssUTF8_Size(b, statusOpt); if (0 == lb) { return PR_FALSE; } if (la != lb) { return PR_FALSE; } return nsslibc_memequal(a, b, la, statusOpt); }
char * STAN_GetCERTCertificateNameForInstance ( PLArenaPool *arenaOpt, NSSCertificate *c, nssCryptokiInstance *instance ) { NSSCryptoContext *context = c->object.cryptoContext; PRStatus nssrv; int nicklen, tokenlen, len; NSSUTF8 *tokenName = NULL; NSSUTF8 *stanNick = NULL; char *nickname = NULL; char *nick; if (instance) { stanNick = instance->label; } else if (context) { stanNick = c->object.tempName; } if (stanNick) { /* fill other fields needed by NSS3 functions using CERTCertificate */ if (instance && (!PK11_IsInternalKeySlot(instance->token->pk11slot) || PORT_Strchr(stanNick, ':') != NULL) ) { tokenName = nssToken_GetName(instance->token); tokenlen = nssUTF8_Size(tokenName, &nssrv); } else { /* don't use token name for internal slot; 3.3 didn't */ tokenlen = 0; } nicklen = nssUTF8_Size(stanNick, &nssrv); len = tokenlen + nicklen; if (arenaOpt) { nickname = PORT_ArenaAlloc(arenaOpt, len); } else { nickname = PORT_Alloc(len); } nick = nickname; if (tokenName) { memcpy(nick, tokenName, tokenlen-1); nick += tokenlen-1; *nick++ = ':'; } memcpy(nick, stanNick, nicklen-1); nickname[len-1] = '\0'; } return nickname; }
NSS_IMPLEMENT CK_VERSION nss_dbm_db_get_format_version ( nss_dbm_db_t *db ) { CK_VERSION rv; DBT k, v; int dbrv; char buffer[64]; rv.major = rv.minor = 0; k.data = PREFIX_METADATA "FormatVersion"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); (void)memset(&v, 0, sizeof(v)); /* Locked region */ { if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) { return rv; } dbrv = db->db->get(db->db, &k, &v, 0); if( dbrv == 0 ) { CK_ULONG major = 0, minor = 0; (void)PR_sscanf(v.data, "%ld.%ld", &major, &minor); rv.major = major; rv.minor = minor; } else if( dbrv > 0 ) { (void)PR_snprintf(buffer, sizeof(buffer), "%ld.%ld", nss_dbm_db_format_version.major, nss_dbm_db_format_version.minor); v.data = buffer; v.size = nssUTF8_Size((NSSUTF8 *)v.data, (PRStatus *)NULL); dbrv = db->db->put(db->db, &k, &v, 0); (void)db->db->sync(db->db, 0); rv = nss_dbm_db_format_version; } else { /* No error return.. */ ; } (void)NSSCKFWMutex_Unlock(db->crustylock); } return rv; }
NSS_IMPLEMENT PRStatus nssUTF8_CopyIntoFixedBuffer(NSSUTF8 *string, char *buffer, PRUint32 bufferSize, char pad) { PRUint32 stringSize = 0; #ifdef NSSDEBUG if ((char *)NULL == buffer) { nss_SetError(NSS_ERROR_INVALID_POINTER); return PR_FALSE; } if (0 == bufferSize) { nss_SetError(NSS_ERROR_INVALID_ARGUMENT); return PR_FALSE; } if ((pad & 0x80) != 0x00) { nss_SetError(NSS_ERROR_INVALID_ARGUMENT); return PR_FALSE; } #endif /* NSSDEBUG */ if ((NSSUTF8 *)NULL == string) { string = (NSSUTF8 *)""; } stringSize = nssUTF8_Size(string, (PRStatus *)NULL); stringSize--; /* don't count the trailing null */ if (stringSize > bufferSize) { PRUint32 bs = bufferSize; (void)nsslibc_memcpy(buffer, string, bufferSize); if ((((buffer[bs - 1] & 0x80) == 0x00)) || ((bs > 1) && ((buffer[bs - 2] & 0xE0) == 0xC0)) || ((bs > 2) && ((buffer[bs - 3] & 0xF0) == 0xE0)) || ((bs > 3) && ((buffer[bs - 4] & 0xF8) == 0xF0)) || ((bs > 4) && ((buffer[bs - 5] & 0xFC) == 0xF8)) || ((bs > 5) && ((buffer[bs - 6] & 0xFE) == 0xFC))) { /* It fit exactly */ return PR_SUCCESS; } /* Too long. We have to trim the last character */ for (/*bs*/; bs != 0; bs--) { if ((buffer[bs - 1] & 0xC0) != 0x80) { buffer[bs - 1] = pad; break; } else { buffer[bs - 1] = pad; } } } else { (void)nsslibc_memset(buffer, pad, bufferSize); (void)nsslibc_memcpy(buffer, string, stringSize); } return PR_SUCCESS; }
NSS_IMPLEMENT CK_RV nss_dbm_db_set_label ( nss_dbm_db_t *db, NSSUTF8 *label ) { CK_RV rv; DBT k, v; int dbrv; k.data = PREFIX_METADATA "Label"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); v.data = label; v.size = nssUTF8_Size((NSSUTF8 *)v.data, (PRStatus *)NULL); /* Locked region */ { rv = NSSCKFWMutex_Lock(db->crustylock); if( CKR_OK != rv ) { return rv; } dbrv = db->db->put(db->db, &k, &v, 0); if( 0 != dbrv ) { rv = CKR_DEVICE_ERROR; } dbrv = db->db->sync(db->db, 0); if( 0 != dbrv ) { rv = CKR_DEVICE_ERROR; } (void)NSSCKFWMutex_Unlock(db->crustylock); } return rv; }
NSS_IMPLEMENT NSSUTF8 * nss_dbm_db_get_label ( nss_dbm_db_t *db, NSSArena *arena, CK_RV *pError ) { NSSUTF8 *rv = (NSSUTF8 *)NULL; DBT k, v; int dbrv; k.data = PREFIX_METADATA "Label"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); /* Locked region */ { if( CKR_OK != NSSCKFWMutex_Lock(db->crustylock) ) { return rv; } dbrv = db->db->get(db->db, &k, &v, 0); if( 0 == dbrv ) { rv = nssUTF8_Duplicate((NSSUTF8 *)v.data, arena); if( (NSSUTF8 *)NULL == rv ) { *pError = CKR_HOST_MEMORY; } } else if( dbrv > 0 ) { /* Just return null */ ; } else { *pError = CKR_DEVICE_ERROR; ; } (void)NSSCKFWMutex_Unlock(db->crustylock); } return rv; }
static void fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced) { CERTCertTrust* trust = NULL; NSSTrust *nssTrust; NSSCryptoContext *context = c->object.cryptoContext; nssCryptokiInstance *instance; NSSUTF8 *stanNick = NULL; /* We are holding the base class object's lock on entry of this function * This lock protects writes to fields of the CERTCertificate . * It is also needed by some functions to compute values such as trust. */ instance = get_cert_instance(c); if (instance) { stanNick = instance->label; } else if (context) { stanNick = c->object.tempName; } /* fill other fields needed by NSS3 functions using CERTCertificate */ if ((!cc->nickname && stanNick) || forced) { PRStatus nssrv; int nicklen, tokenlen, len; NSSUTF8 *tokenName = NULL; char *nick; if (instance && (!PK11_IsInternalKeySlot(instance->token->pk11slot) || (stanNick && PORT_Strchr(stanNick, ':') != NULL))) { tokenName = nssToken_GetName(instance->token); tokenlen = nssUTF8_Size(tokenName, &nssrv); } else { /* don't use token name for internal slot; 3.3 didn't */ tokenlen = 0; } if (stanNick) { nicklen = nssUTF8_Size(stanNick, &nssrv); len = tokenlen + nicklen; nick = PORT_ArenaAlloc(cc->arena, len); if (tokenName) { memcpy(nick, tokenName, tokenlen-1); nick[tokenlen-1] = ':'; memcpy(nick+tokenlen, stanNick, nicklen-1); } else { memcpy(nick, stanNick, nicklen-1); } nick[len-1] = '\0'; cc->nickname = nick; } else { cc->nickname = NULL; } } if (context) { /* trust */ nssTrust = nssCryptoContext_FindTrustForCertificate(context, c); if (!nssTrust) { /* chicken and egg issue: * * c->issuer and c->serial are empty at this point, but * nssTrustDomain_FindTrustForCertificate use them to look up * up the trust object, so we point them to cc->derIssuer and * cc->serialNumber. * * Our caller will fill these in with proper arena copies when we * return. */ c->issuer.data = cc->derIssuer.data; c->issuer.size = cc->derIssuer.len; c->serial.data = cc->serialNumber.data; c->serial.size = cc->serialNumber.len; nssTrust = nssTrustDomain_FindTrustForCertificate(context->td, c); } if (nssTrust) { trust = cert_trust_from_stan_trust(nssTrust, cc->arena); if (trust) { /* we should destroy cc->trust before replacing it, but it's allocated in cc->arena, so memory growth will occur on each refresh */ CERT_LockCertTrust(cc); cc->trust = trust; CERT_UnlockCertTrust(cc); } nssTrust_Destroy(nssTrust); } } else if (instance) { /* slot */ if (cc->slot != instance->token->pk11slot) { if (cc->slot) { PK11_FreeSlot(cc->slot); } cc->slot = PK11_ReferenceSlot(instance->token->pk11slot); } cc->ownSlot = PR_TRUE; /* pkcs11ID */ cc->pkcs11ID = instance->handle; /* trust */ trust = nssTrust_GetCERTCertTrustForCert(c, cc); if (trust) { /* we should destroy cc->trust before replacing it, but it's allocated in cc->arena, so memory growth will occur on each refresh */ CERT_LockCertTrust(cc); cc->trust = trust; CERT_UnlockCertTrust(cc); } nssCryptokiObject_Destroy(instance); } /* database handle is now the trust domain */ cc->dbhandle = c->object.trustDomain; /* subjectList ? */ /* istemp and isperm are supported in NSS 3.4 */ cc->istemp = PR_FALSE; /* CERT_NewTemp will override this */ cc->isperm = PR_TRUE; /* by default */ /* pointer back */ cc->nssCertificate = c; if (trust) { /* force the cert type to be recomputed to include trust info */ PRUint32 nsCertType = cert_ComputeCertType(cc); /* Assert that it is safe to cast &cc->nsCertType to "PRInt32 *" */ PORT_Assert(sizeof(cc->nsCertType) == sizeof(PRInt32)); PR_ATOMIC_SET((PRInt32 *)&cc->nsCertType, nsCertType); } }
NSS_IMPLEMENT NSSItem * nssUTF8_GetEncoding(NSSArena *arenaOpt, NSSItem *rvOpt, nssStringType type, NSSUTF8 *string) { NSSItem *rv = (NSSItem *)NULL; PRStatus status = PR_SUCCESS; #ifdef NSSDEBUG if ((NSSArena *)NULL != arenaOpt) { if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) { return (NSSItem *)NULL; } } if ((NSSUTF8 *)NULL == string) { nss_SetError(NSS_ERROR_INVALID_POINTER); return (NSSItem *)NULL; } #endif /* NSSDEBUG */ switch (type) { case nssStringType_DirectoryString: nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; case nssStringType_TeletexString: nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; case nssStringType_PrintableString: nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; case nssStringType_UniversalString: nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; case nssStringType_BMPString: nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; case nssStringType_UTF8String: { NSSUTF8 *dup = nssUTF8_Duplicate(string, arenaOpt); if ((NSSUTF8 *)NULL == dup) { return (NSSItem *)NULL; } if ((NSSItem *)NULL == rvOpt) { rv = nss_ZNEW(arenaOpt, NSSItem); if ((NSSItem *)NULL == rv) { (void)nss_ZFreeIf(dup); return (NSSItem *)NULL; } } else { rv = rvOpt; } rv->data = dup; dup = (NSSUTF8 *)NULL; rv->size = nssUTF8_Size(rv->data, &status); if ((0 == rv->size) && (PR_SUCCESS != status)) { if ((NSSItem *)NULL == rvOpt) { (void)nss_ZFreeIf(rv); } return (NSSItem *)NULL; } } break; case nssStringType_PHGString: nss_SetError(NSS_ERROR_INTERNAL_ERROR); /* unimplemented */ break; default: nss_SetError(NSS_ERROR_UNSUPPORTED_TYPE); break; } return rv; }
static CK_ULONG nss_dbm_db_new_handle ( nss_dbm_db_t *db, DBT *dbt, /* pre-allocated */ CK_RV *pError ) { CK_ULONG rv; DBT k, v; CK_ULONG align = 0, id, myid; struct handle *hp; if( sizeof(struct handle) != dbt->size ) { return EINVAL; } /* Locked region */ { *pError = NSSCKFWMutex_Lock(db->crustylock); if( CKR_OK != *pError ) { return EINVAL; } k.data = PREFIX_METADATA "LastID"; k.size = nssUTF8_Size((NSSUTF8 *)k.data, (PRStatus *)NULL); (void)memset(&v, 0, sizeof(v)); rv = db->db->get(db->db, &k, &v, 0); if( 0 == rv ) { (void)memcpy(&align, v.data, sizeof(CK_ULONG)); id = ntohl(align); } else if( rv > 0 ) { id = 0; } else { goto done; } myid = id; id++; align = htonl(id); v.data = &align; v.size = sizeof(CK_ULONG); rv = db->db->put(db->db, &k, &v, 0); if( 0 != rv ) { goto done; } rv = db->db->sync(db->db, 0); if( 0 != rv ) { goto done; } done: (void)NSSCKFWMutex_Unlock(db->crustylock); } if( 0 != rv ) { return rv; } hp = (struct handle *)dbt->data; (void)memcpy(&hp->prefix[0], PREFIX_OBJECT, 4); hp->id = myid; return 0; }