/********************* Arena code follows ***************************** * ArenaPools are like heaps. The memory in them consists of large blocks, * called arenas, which are allocated from the/a system heap. Inside an * ArenaPool, the arenas are organized as if they were in a stack. Newly * allocated arenas are "pushed" on that stack. When you attempt to * allocate memory from an ArenaPool, the code first looks to see if there * is enough unused space in the top arena on the stack to satisfy your * request, and if so, your request is satisfied from that arena. * Otherwise, a new arena is allocated (or taken from NSPR's list of freed * arenas) and pushed on to the stack. The new arena is always big enough * to satisfy the request, and is also at least a minimum size that is * established at the time that the ArenaPool is created. * * The ArenaMark function returns the address of a marker in the arena at * the top of the arena stack. It is the address of the place in the arena * on the top of the arena stack from which the next block of memory will * be allocated. Each ArenaPool has its own separate stack, and hence * marks are only relevant to the ArenaPool from which they are gotten. * Marks may be nested. That is, a thread can get a mark, and then get * another mark. * * It is intended that all the marks in an ArenaPool may only be owned by a * single thread. In DEBUG builds, this is enforced. In non-DEBUG builds, * it is not. In DEBUG builds, when a thread gets a mark from an * ArenaPool, no other thread may acquire a mark in that ArenaPool while * that mark exists, that is, until that mark is unmarked or released. * Therefore, it is important that every mark be unmarked or released when * the creating thread has no further need for exclusive ownership of the * right to manage the ArenaPool. * * The ArenaUnmark function discards the ArenaMark at the address given, * and all marks nested inside that mark (that is, acquired from that same * ArenaPool while that mark existed). It is an error for a thread other * than the mark's creator to try to unmark it. When a thread has unmarked * all its marks from an ArenaPool, then another thread is able to set * marks in that ArenaPool. ArenaUnmark does not deallocate (or "pop") any * memory allocated from the ArenaPool since the mark was created. * * ArenaRelease "pops" the stack back to the mark, deallocating all the * memory allocated from the arenas in the ArenaPool since that mark was * created, and removing any arenas from the ArenaPool that have no * remaining active allocations when that is done. It implicitly releases * any marks nested inside the mark being explicitly released. It is the * only operation, other than destroying the arenapool, that potentially * reduces the number of arenas on the stack. Otherwise, the stack grows * until the arenapool is destroyed, at which point all the arenas are * freed or returned to a "free arena list", depending on their sizes. */ PLArenaPool * PORT_NewArena(unsigned long chunksize) { PORTArenaPool *pool; if (chunksize > MAX_SIZE) { PORT_SetError(SEC_ERROR_NO_MEMORY); return NULL; } pool = PORT_ZNew(PORTArenaPool); if (!pool) { return NULL; } pool->magic = ARENAPOOL_MAGIC; pool->lock = PZ_NewLock(nssILockArena); if (!pool->lock) { PORT_Free(pool); return NULL; } PL_InitArenaPool(&pool->arena, "security", chunksize, sizeof(double)); return (&pool->arena); }
/* * c a l c u l a t e _ M D 5 _ r a n g e * * Calculate the MD5 digest on a range of bytes in * the specified fopen'd file. Returns base64. * */ static int calculate_MD5_range (FILE *fp, long r1, long r2, JAR_Digest *dig) { int num; int range; unsigned char *buf; SECStatus rv; range = r2 - r1; /* position to the beginning of range */ fseek (fp, r1, SEEK_SET); buf = (unsigned char *) PORT_ZAlloc (range); if (buf == NULL) out_of_memory(); if ((num = fread (buf, 1, range, fp)) != range) { PR_fprintf(errorFD, "%s: expected %d bytes, got %d\n", PROGRAM_NAME, range, num); errorCount++; exit (ERRX); } rv = PK11_HashBuf(SEC_OID_MD5, dig->md5, buf, range); if (rv == SECSuccess) { rv =PK11_HashBuf(SEC_OID_SHA1, dig->sha1, buf, range); } if (rv != SECSuccess) { PR_fprintf(errorFD, "%s: can't generate digest context\n", PROGRAM_NAME); errorCount++; exit (ERRX); } PORT_Free (buf); return 0; }
static SECStatus crmf_destroy_encrypted_key(CRMFEncryptedKey *inEncrKey, PRBool freeit) { PORT_Assert(inEncrKey != NULL); if (inEncrKey != NULL) { switch (inEncrKey->encKeyChoice){ case crmfEncryptedValueChoice: crmf_destroy_encrypted_value(&inEncrKey->value.encryptedValue, PR_FALSE); break; case crmfEnvelopedDataChoice: SEC_PKCS7DestroyContentInfo(inEncrKey->value.envelopedData); break; default: break; } if (freeit) { PORT_Free(inEncrKey); } } return SECSuccess; }
SECItem* SSL_GetNegotiatedHostInfo(PRFileDesc *fd) { SECItem *sniName = NULL; sslSocket *ss; char *name = NULL; ss = ssl_FindSocket(fd); if (!ss) { SSL_DBG(("%d: SSL[%d]: bad socket in SSL_GetNegotiatedHostInfo", SSL_GETPID(), fd)); return NULL; } if (ss->sec.isServer) { if (ss->version > SSL_LIBRARY_VERSION_3_0 && ss->ssl3.initialized) { /* TLS */ SECItem *crsName; ssl_GetSpecReadLock(ss); /*********************************/ crsName = &ss->ssl3.crSpec->srvVirtName; if (crsName->data) { sniName = SECITEM_DupItem(crsName); } ssl_ReleaseSpecReadLock(ss); /*----------------------------*/ } return sniName; } name = SSL_RevealURL(fd); if (name) { sniName = PORT_ZNew(SECItem); if (!sniName) { PORT_Free(name); return NULL; } sniName->data = (void*)name; sniName->len = PORT_Strlen(name); } return sniName; }
CERTCrlDistributionPoints * CERT_FindCRLDistributionPoints(CERTCertificate *cert) { SECItem encodedExtenValue; SECStatus rv; CERTCrlDistributionPoints *dps; encodedExtenValue.data = NULL; encodedExtenValue.len = 0; rv = cert_FindExtension(cert->extensions, SEC_OID_X509_CRL_DIST_POINTS, &encodedExtenValue); if (rv != SECSuccess) { return (NULL); } dps = CERT_DecodeCRLDistributionPoints(cert->arena, &encodedExtenValue); PORT_Free(encodedExtenValue.data); return dps; }
SECStatus secu_StdinToItem(SECItem *dst) { unsigned char buf[1000]; PRInt32 numBytes; PRBool notDone = PR_TRUE; dst->len = 0; dst->data = NULL; while (notDone) { numBytes = PR_Read(PR_STDIN, buf, sizeof(buf)); if (numBytes < 0) { return SECFailure; } if (numBytes == 0) break; if (dst->data) { unsigned char *p = dst->data; dst->data = (unsigned char *)PORT_Realloc(p, dst->len + numBytes); if (!dst->data) { PORT_Free(p); } } else { dst->data = (unsigned char *)PORT_Alloc(numBytes); } if (!dst->data) { return SECFailure; } PORT_Memcpy(dst->data + dst->len, buf, numBytes); dst->len += numBytes; } return SECSuccess; }
static CK_RV lg_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly, NSSLOWCERTCertDBHandle **certdbPtr) { NSSLOWCERTCertDBHandle *certdb = NULL; CK_RV crv = CKR_NETSCAPE_CERTDB_FAILED; SECStatus rv; char * name = NULL; char * appName = NULL; if (prefix == NULL) { prefix = ""; } configdir = lg_EvaluateConfigDir(configdir, &appName); name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix); if (name == NULL) goto loser; certdb = (NSSLOWCERTCertDBHandle*)PORT_ZAlloc(sizeof(NSSLOWCERTCertDBHandle)); if (certdb == NULL) goto loser; certdb->ref = 1; /* fix when we get the DB in */ rv = nsslowcert_OpenCertDB(certdb, readOnly, appName, prefix, lg_certdb_name_cb, (void *)name, PR_FALSE); if (rv == SECSuccess) { crv = CKR_OK; *certdbPtr = certdb; certdb = NULL; } loser: if (certdb) PR_Free(certdb); if (name) PR_smprintf_free(name); if (appName) PORT_Free(appName); return crv; }
/* string decryptString (in string crypt); */ NS_IMETHODIMP nsSecretDecoderRing:: DecryptString(const char *crypt, char **_retval) { nsNSSShutDownPreventionLock locker; nsresult rv = NS_OK; char *r = 0; unsigned char *decoded = 0; PRInt32 decodedLen; unsigned char *decrypted = 0; PRInt32 decryptedLen; if (crypt == nsnull || _retval == nsnull) { rv = NS_ERROR_INVALID_POINTER; goto loser; } rv = decode(crypt, &decoded, &decodedLen); if (rv != NS_OK) goto loser; rv = Decrypt(decoded, decodedLen, &decrypted, &decryptedLen); if (rv != NS_OK) goto loser; // Convert to NUL-terminated string r = (char *)nsMemory::Alloc(decryptedLen+1); if (!r) { rv = NS_ERROR_OUT_OF_MEMORY; goto loser; } memcpy(r, decrypted, decryptedLen); r[decryptedLen] = 0; *_retval = r; r = 0; loser: if (decrypted) PORT_Free(decrypted); if (decoded) PR_DELETE(decoded); return rv; }
CERTAuthKeyID * CERT_FindAuthKeyIDExten (PLArenaPool *arena, CERTCertificate *cert) { SECItem encodedExtenValue; SECStatus rv; CERTAuthKeyID *ret; encodedExtenValue.data = NULL; encodedExtenValue.len = 0; rv = cert_FindExtension(cert->extensions, SEC_OID_X509_AUTH_KEY_ID, &encodedExtenValue); if ( rv != SECSuccess ) { return (NULL); } ret = CERT_DecodeAuthKeyID (arena, &encodedExtenValue); PORT_Free(encodedExtenValue.data); encodedExtenValue.data = NULL; return(ret); }
/* string encryptString (in string text); */ NS_IMETHODIMP nsSecretDecoderRing:: EncryptString(const char *text, char **_retval) { nsNSSShutDownPreventionLock locker; nsresult rv = NS_OK; unsigned char *encrypted = 0; PRInt32 eLen; if (text == nsnull || _retval == nsnull) { rv = NS_ERROR_INVALID_POINTER; goto loser; } rv = Encrypt((unsigned char *)text, PL_strlen(text), &encrypted, &eLen); if (rv != NS_OK) { goto loser; } rv = encode(encrypted, eLen, _retval); loser: if (encrypted) PORT_Free(encrypted); return rv; }
static nsresult GetCertFingerprintByOidTag(CERTCertificate* nsscert, SECOidTag aOidTag, nsCString &fp) { unsigned int hash_len = HASH_ResultLenByOidTag(aOidTag); nsStringBuffer* fingerprint = nsStringBuffer::Alloc(hash_len); if (!fingerprint) return NS_ERROR_OUT_OF_MEMORY; PK11_HashBuf(aOidTag, (unsigned char*)fingerprint->Data(), nsscert->derCert.data, nsscert->derCert.len); SECItem fpItem; fpItem.data = (unsigned char*)fingerprint->Data(); fpItem.len = hash_len; char *tmpstr = CERT_Hexify(&fpItem, 1); fp.Assign(tmpstr); PORT_Free(tmpstr); fingerprint->Release(); return NS_OK; }
static char *sftk_getOldSecmodName(const char *dbname,const char *filename) { char *file = NULL; char *dirPath = PORT_Strdup(dbname); char *sep; sep = PORT_Strrchr(dirPath,*PATH_SEPARATOR); #ifdef _WIN32 if (!sep) { /* pkcs11i.h defines PATH_SEPARATOR as "/" for all platforms. */ sep = PORT_Strrchr(dirPath,'\\'); } #endif if (sep) { *sep = 0; file = PR_smprintf("%s"PATH_SEPARATOR"%s", dirPath, filename); } else { file = PR_smprintf("%s", filename); } PORT_Free(dirPath); return file; }
NS_IMETHODIMP nsNSSCertificate::GetMd5Fingerprint(nsAString &_md5Fingerprint) { nsNSSShutDownPreventionLock locker; if (isAlreadyShutDown()) return NS_ERROR_NOT_AVAILABLE; _md5Fingerprint.Truncate(); unsigned char fingerprint[20]; SECItem fpItem; memset(fingerprint, 0, sizeof fingerprint); PK11_HashBuf(SEC_OID_MD5, fingerprint, mCert->derCert.data, mCert->derCert.len); fpItem.data = fingerprint; fpItem.len = MD5_LENGTH; char *fpStr = CERT_Hexify(&fpItem, 1); if (fpStr) { _md5Fingerprint = NS_ConvertASCIItoUTF16(fpStr); PORT_Free(fpStr); return NS_OK; } return NS_ERROR_FAILURE; }
SecAsn1Item * SECITEM_ArenaDupItem(PRArenaPool *arena, const SecAsn1Item *from) { SecAsn1Item *to; if ( from == NULL ) { return(NULL); } if ( arena != NULL ) { to = (SecAsn1Item *)PORT_ArenaAlloc(arena, sizeof(SecAsn1Item)); } else { to = (SecAsn1Item *)PORT_Alloc(sizeof(SecAsn1Item)); } if ( to == NULL ) { return(NULL); } if ( arena != NULL ) { to->Data = (unsigned char *)PORT_ArenaAlloc(arena, from->Length); } else { to->Data = (unsigned char *)PORT_Alloc(from->Length); } if ( to->Data == NULL ) { PORT_Free(to); return(NULL); } to->Length = from->Length; // to->type = from->type; if ( to->Length ) { PORT_Memcpy(to->Data, from->Data, to->Length); } return(to); }
nsresult nsClientAuthRememberService::RememberDecision(const nsACString & aHostName, CERTCertificate *aServerCert, CERTCertificate *aClientCert) { // aClientCert == NULL means: remember that user does not want to use a cert NS_ENSURE_ARG_POINTER(aServerCert); if (aHostName.IsEmpty()) return NS_ERROR_INVALID_ARG; nsCAutoString fpStr; nsresult rv = GetCertFingerprintByOidTag(aServerCert, SEC_OID_SHA256, fpStr); if (NS_FAILED(rv)) return rv; { nsAutoMonitor lock(monitor); if (aClientCert) { nsNSSCertificate pipCert(aClientCert); char *dbkey = NULL; rv = pipCert.GetDbKey(&dbkey); if (NS_SUCCEEDED(rv) && dbkey) { AddEntryToList(aHostName, fpStr, nsDependentCString(dbkey)); } if (dbkey) { PORT_Free(dbkey); } } else { nsCString empty; AddEntryToList(aHostName, fpStr, empty); } } return NS_OK; }
CERTCertificate * CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, const char *name) { NSSCryptoContext *cc; NSSCertificate *c, *ct; CERTCertificate *cert; NSSUsage usage; if (NULL == name) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } usage.anyUsage = PR_TRUE; cc = STAN_GetDefaultCryptoContext(); ct = NSSCryptoContext_FindBestCertificateByNickname(cc, name, NULL, &usage, NULL); if (!ct && PORT_Strchr(name, '@') != NULL) { char* lowercaseName = CERT_FixupEmailAddr(name); if (lowercaseName) { ct = NSSCryptoContext_FindBestCertificateByEmail(cc, lowercaseName, NULL, &usage, NULL); PORT_Free(lowercaseName); } } cert = PK11_FindCertFromNickname(name, NULL); if (cert) { c = get_best_temp_or_perm(ct, STAN_GetNSSCertificate(cert)); CERT_DestroyCertificate(cert); if (ct) { CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct)); } } else { c = ct; } return c ? STAN_GetCERTCertificateOrRelease(c) : NULL; }
SECStatus CERT_FindBasicConstraintExten(CERTCertificate *cert, CERTBasicConstraints *value) { SECItem encodedExtenValue; SECStatus rv; encodedExtenValue.data = NULL; encodedExtenValue.len = 0; rv = cert_FindExtension(cert->extensions, SEC_OID_X509_BASIC_CONSTRAINTS, &encodedExtenValue); if ( rv != SECSuccess ) { return (rv); } rv = CERT_DecodeBasicConstraintValue (value, &encodedExtenValue); /* free the raw extension data */ PORT_Free(encodedExtenValue.data); encodedExtenValue.data = NULL; return(rv); }
SECItem * SECITEM_ArenaDupItem(PLArenaPool *arena, const SECItem *from) { SECItem *to; if ( from == NULL ) { return(NULL); } if ( arena != NULL ) { to = (SECItem *)PORT_ArenaAlloc(arena, sizeof(SECItem)); } else { to = (SECItem *)PORT_Alloc(sizeof(SECItem)); } if ( to == NULL ) { return(NULL); } if ( arena != NULL ) { to->data = (unsigned char *)PORT_ArenaAlloc(arena, from->len); } else { to->data = (unsigned char *)PORT_Alloc(from->len); } if ( to->data == NULL ) { PORT_Free(to); return(NULL); } to->len = from->len; to->type = from->type; if ( to->len ) { PORT_Memcpy(to->data, from->data, to->len); } return(to); }
SECStatus AddCertificateFromFile(const char* basePath, const char* filename) { char buf[16384] = { 0 }; SECStatus rv = ReadFileToBuffer(basePath, filename, buf); if (rv != SECSuccess) { return rv; } SECItem certDER; rv = CERT_DecodeCertPackage(buf, strlen(buf), DecodeCertCallback, &certDER); if (rv != SECSuccess) { PrintPRError("CERT_DecodeCertPackage failed"); return rv; } ScopedCERTCertificate cert(CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &certDER, nullptr, false, true)); PORT_Free(certDER.data); if (!cert) { PrintPRError("CERT_NewTempCertificate failed"); return SECFailure; } ScopedPK11SlotInfo slot(PK11_GetInternalKeySlot()); if (!slot) { PrintPRError("PK11_GetInternalKeySlot failed"); return SECFailure; } // The nickname is the filename without '.pem'. std::string nickname(filename, strlen(filename) - 4); rv = PK11_ImportCert(slot, cert, CK_INVALID_HANDLE, nickname.c_str(), false); if (rv != SECSuccess) { PrintPRError("PK11_ImportCert failed"); return rv; } return SECSuccess; }
/* * FUNCTION: pkix_pl_LdapCertStore_DestroyAVAList * DESCRIPTION: * * This function frees the space allocated for the components of the * equalFilters that make up the andFilter pointed to by "filter". * * PARAMETERS: * "requestParams" * The address of the andFilter whose components are to be freed. Must be * non-NULL. * "plContext" * Platform-specific context pointer * THREAD SAFETY: * Thread Safe (see Thread Safety Definitions in Programmer's Guide) * RETURNS: * Returns NULL if the function succeeds. * Returns a CertStore Error if the function fails in a non-fatal way. * Returns a Fatal Error if the function fails in an unrecoverable way. */ static PKIX_Error * pkix_pl_LdapCertStore_DestroyAVAList( LDAPNameComponent **nameComponents, void *plContext) { LDAPNameComponent **currentNC = NULL; unsigned char *component = NULL; PKIX_ENTER(CERTSTORE, "pkix_pl_LdapCertStore_DestroyAVAList"); PKIX_NULLCHECK_ONE(nameComponents); /* Set currentNC to point to first AVA pointer */ currentNC = nameComponents; while ((*currentNC) != NULL) { component = (*currentNC)->attrValue; if (component != NULL) { PORT_Free(component); } currentNC++; } PKIX_RETURN(CERTSTORE); }
static void AppendErrorTextMismatch(const nsString &host, nsIX509Cert* ix509, nsINSSComponent *component, bool wantsHtml, nsString &returnedMessage) { const char16_t *params[1]; nsresult rv; ScopedCERTCertificate nssCert(ix509->GetCert()); if (!nssCert) { // We are unable to extract the valid names, say "not valid for name". params[0] = host.get(); nsString formattedString; rv = component->PIPBundleFormatStringFromName("certErrorMismatch", params, 1, formattedString); if (NS_SUCCEEDED(rv)) { returnedMessage.Append(formattedString); returnedMessage.Append('\n'); } return; } nsString allNames; uint32_t nameCount = 0; bool useSAN = false; if (nssCert) useSAN = GetSubjectAltNames(nssCert.get(), component, allNames, nameCount); if (!useSAN) { char *certName = CERT_GetCommonName(&nssCert->subject); if (certName) { nsDependentCSubstring commonName(certName, strlen(certName)); if (IsUTF8(commonName)) { // Bug 1024781 // We should actually check that the common name is a valid dns name or // ip address and not any string value before adding it to the display // list. ++nameCount; allNames.Assign(NS_ConvertUTF8toUTF16(commonName)); } PORT_Free(certName); } } if (nameCount > 1) { nsString message; rv = component->GetPIPNSSBundleString("certErrorMismatchMultiple", message); if (NS_SUCCEEDED(rv)) { returnedMessage.Append(message); returnedMessage.AppendLiteral("\n "); returnedMessage.Append(allNames); returnedMessage.AppendLiteral(" \n"); } } else if (nameCount == 1) { const char16_t *params[1]; params[0] = allNames.get(); const char *stringID; if (wantsHtml) stringID = "certErrorMismatchSingle2"; else stringID = "certErrorMismatchSinglePlain"; nsString formattedString; rv = component->PIPBundleFormatStringFromName(stringID, params, 1, formattedString); if (NS_SUCCEEDED(rv)) { returnedMessage.Append(formattedString); returnedMessage.Append('\n'); } } else { // nameCount == 0 nsString message; nsresult rv = component->GetPIPNSSBundleString("certErrorMismatchNoNames", message); if (NS_SUCCEEDED(rv)) { returnedMessage.Append(message); returnedMessage.Append('\n'); } } }
char * SECU_FilePasswd(PK11SlotInfo *slot, PRBool retry, void *arg) { char* phrases, *phrase; PRFileDesc *fd; int32_t nb; char *pwFile = arg; int i; const long maxPwdFileSize = 4096; char* tokenName = NULL; int tokenLen = 0; if (!pwFile) return 0; if (retry) { return 0; /* no good retrying - the files contents will be the same */ } phrases = PORT_ZAlloc(maxPwdFileSize); if (!phrases) { return 0; /* out of memory */ } fd = PR_Open(pwFile, PR_RDONLY, 0); if (!fd) { fprintf(stderr, "No password file \"%s\" exists.\n", pwFile); PORT_Free(phrases); return NULL; } nb = PR_Read(fd, phrases, maxPwdFileSize); PR_Close(fd); if (nb == 0) { fprintf(stderr,"password file contains no data\n"); PORT_Free(phrases); return NULL; } if (slot) { tokenName = PK11_GetTokenName(slot); if (tokenName) { tokenLen = PORT_Strlen(tokenName); } } i = 0; do { int startphrase = i; int phraseLen; /* handle the Windows EOL case */ while (phrases[i] != '\r' && phrases[i] != '\n' && i < nb) i++; /* terminate passphrase */ phrases[i++] = '\0'; /* clean up any EOL before the start of the next passphrase */ while ( (i<nb) && (phrases[i] == '\r' || phrases[i] == '\n')) { phrases[i++] = '\0'; } /* now analyze the current passphrase */ phrase = &phrases[startphrase]; if (!tokenName) break; if (PORT_Strncmp(phrase, tokenName, tokenLen)) continue; phraseLen = PORT_Strlen(phrase); if (phraseLen < (tokenLen+1)) continue; if (phrase[tokenLen] != ':') continue; phrase = &phrase[tokenLen+1]; break; } while (i<nb); phrase = PORT_Strdup((char*)phrase); PORT_Free(phrases); return phrase; }
int main(int argc, char **argv) { int rv, ascii; char *progName; FILE *outFile; PRFileDesc *inFile; SECItem der, data; char *typeTag; PLOptState *optstate; progName = strrchr(argv[0], '/'); progName = progName ? progName+1 : argv[0]; ascii = 0; inFile = 0; outFile = 0; typeTag = 0; optstate = PL_CreateOptState(argc, argv, "at:i:o:"); while ( PL_GetNextOpt(optstate) == PL_OPT_OK ) { switch (optstate->option) { case '?': Usage(progName); break; case 'a': ascii = 1; break; case 'i': inFile = PR_Open(optstate->value, PR_RDONLY, 0); if (!inFile) { fprintf(stderr, "%s: unable to open \"%s\" for reading\n", progName, optstate->value); return -1; } break; case 'o': outFile = fopen(optstate->value, "w"); if (!outFile) { fprintf(stderr, "%s: unable to open \"%s\" for writing\n", progName, optstate->value); return -1; } break; case 't': typeTag = strdup(optstate->value); break; } } PL_DestroyOptState(optstate); if (!typeTag) Usage(progName); if (!inFile) inFile = PR_STDIN; if (!outFile) outFile = stdout; PR_Init(PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1); rv = NSS_NoDB_Init(NULL); if (rv != SECSuccess) { fprintf(stderr, "%s: NSS_NoDB_Init failed (%s)\n", progName, SECU_Strerror(PORT_GetError())); exit(1); } SECU_RegisterDynamicOids(); rv = SECU_ReadDERFromFile(&der, inFile, ascii, PR_FALSE); if (rv != SECSuccess) { fprintf(stderr, "%s: SECU_ReadDERFromFile failed\n", progName); exit(1); } /* Data is untyped, using the specified type */ data.data = der.data; data.len = der.len; /* Pretty print it */ if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE) == 0) { rv = SECU_PrintSignedData(outFile, &data, "Certificate", 0, SECU_PrintCertificate); } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_ID) == 0) { PRBool saveWrapeState = SECU_GetWrapEnabled(); SECU_EnableWrap(PR_FALSE); rv = SECU_PrintSignedContent(outFile, &data, 0, 0, SECU_PrintDumpDerIssuerAndSerial); SECU_EnableWrap(saveWrapeState); } else if (PORT_Strcmp(typeTag, SEC_CT_CERTIFICATE_REQUEST) == 0) { rv = SECU_PrintSignedData(outFile, &data, "Certificate Request", 0, SECU_PrintCertificateRequest); } else if (PORT_Strcmp (typeTag, SEC_CT_CRL) == 0) { rv = SECU_PrintSignedData (outFile, &data, "CRL", 0, SECU_PrintCrl); #ifdef HAVE_EPV_TEMPLATE } else if (PORT_Strcmp(typeTag, SEC_CT_PRIVATE_KEY) == 0) { rv = SECU_PrintPrivateKey(outFile, &data, "Private Key", 0); #endif } else if (PORT_Strcmp(typeTag, SEC_CT_PUBLIC_KEY) == 0) { rv = SECU_PrintSubjectPublicKeyInfo(outFile, &data, "Public Key", 0); } else if (PORT_Strcmp(typeTag, SEC_CT_PKCS7) == 0) { rv = SECU_PrintPKCS7ContentInfo(outFile, &data, "PKCS #7 Content Info", 0); } else if (PORT_Strcmp(typeTag, SEC_CT_NAME) == 0) { rv = SECU_PrintDERName(outFile, &data, "Name", 0); } else { fprintf(stderr, "%s: don't know how to print out '%s' files\n", progName, typeTag); SECU_PrintAny(outFile, &data, "File contains", 0); return -1; } if (inFile != PR_STDIN) PR_Close(inFile); PORT_Free(der.data); if (rv) { fprintf(stderr, "%s: problem converting data (%s)\n", progName, SECU_Strerror(PORT_GetError())); } if (NSS_Shutdown() != SECSuccess) { fprintf(stderr, "%s: NSS_Shutdown failed (%s)\n", progName, SECU_Strerror(PORT_GetError())); rv = SECFailure; } PR_Cleanup(); return rv; }
/* * Add a module to the Data base */ SECStatus sftkdb_AddSecmodDB(SDBType dbType, const char *appName, const char *filename, const char *dbname, char *module, PRBool rw) { FILE *fd = NULL; char *block = NULL; PRBool libFound = PR_FALSE; if (dbname == NULL) { return SECFailure; } if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { return sftkdbCall_AddSecmodDB(appName, filename, dbname, module, rw); } /* can't write to a read only module */ if (!rw) { return SECFailure; } /* remove the previous version if it exists */ (void) sftkdb_DeleteSecmodDB(dbType, appName, filename, dbname, module, rw); #ifdef WINCE fd = fopen(dbname, "a+"); #else fd = lfopen(dbname, "a+", O_CREAT|O_RDWR|O_APPEND); #endif if (fd == NULL) { return SECFailure; } module = sftk_argStrip(module); while (*module) { int count; char *keyEnd = PORT_Strchr(module,'='); char *value; if (PORT_Strncmp(module, "library=", 8) == 0) { libFound=PR_TRUE; } if (keyEnd == NULL) { block = sftkdb_DupCat(block, module); break; } block = sftkdb_DupnCat(block, module, keyEnd-module+1); if (block == NULL) { goto loser; } value = sftk_argFetchValue(&keyEnd[1], &count); if (value) { block = sftkdb_DupCat(block, sftk_argStrip(value)); PORT_Free(value); } if (block == NULL) { goto loser; } block = sftkdb_DupnCat(block, "\n", 1); module = keyEnd + 1 + count; module = sftk_argStrip(module); } if (block) { if (!libFound) { fprintf(fd,"library=\n"); } fwrite(block, PORT_Strlen(block), 1, fd); fprintf(fd,"\n"); PORT_Free(block); block = NULL; } fclose(fd); return SECSuccess; loser: PORT_Free(block); fclose(fd); return SECFailure; }
static void ListCRLNames (CERTCertDBHandle *certHandle, int crlType, PRBool deletecrls) { CERTCrlHeadNode *crlList = NULL; CERTCrlNode *crlNode = NULL; CERTName *name = NULL; PLArenaPool *arena = NULL; SECStatus rv; do { arena = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE); if (arena == NULL) { fprintf(stderr, "%s: fail to allocate memory\n", progName); break; } name = PORT_ArenaZAlloc (arena, sizeof(*name)); if (name == NULL) { fprintf(stderr, "%s: fail to allocate memory\n", progName); break; } name->arena = arena; rv = SEC_LookupCrls (certHandle, &crlList, crlType); if (rv != SECSuccess) { fprintf(stderr, "%s: fail to look up CRLs (%s)\n", progName, SECU_Strerror(PORT_GetError())); break; } /* just in case */ if (!crlList) break; crlNode = crlList->first; fprintf (stdout, "\n"); fprintf (stdout, "\n%-40s %-5s\n\n", "CRL names", "CRL Type"); while (crlNode) { char* asciiname = NULL; CERTCertificate *cert = NULL; if (crlNode->crl && &crlNode->crl->crl.derName) { cert = CERT_FindCertByName(certHandle, &crlNode->crl->crl.derName); if (!cert) { SECU_PrintError(progName, "could not find signing " "certificate in database"); } } if (cert) { char* certName = NULL; if (cert->nickname && PORT_Strlen(cert->nickname) > 0) { certName = cert->nickname; } else if (cert->emailAddr && PORT_Strlen(cert->emailAddr) > 0) { certName = cert->emailAddr; } if (certName) { asciiname = PORT_Strdup(certName); } CERT_DestroyCertificate(cert); } if (!asciiname) { name = &crlNode->crl->crl.name; if (!name){ SECU_PrintError(progName, "fail to get the CRL " "issuer name"); continue; } asciiname = CERT_NameToAscii(name); } fprintf (stdout, "%-40s %-5s\n", asciiname, "CRL"); if (asciiname) { PORT_Free(asciiname); } if ( PR_TRUE == deletecrls) { CERTSignedCrl* acrl = NULL; SECItem* issuer = &crlNode->crl->crl.derName; acrl = SEC_FindCrlByName(certHandle, issuer, crlType); if (acrl) { SEC_DeletePermCRL(acrl); SEC_DestroyCrl(acrl); } } crlNode = crlNode->next; } } while (0); if (crlList) PORT_FreeArena (crlList->arena, PR_FALSE); PORT_FreeArena (arena, PR_FALSE); }
/* * Delete a module from the Data Base */ SECStatus sftkdb_DeleteSecmodDB(SDBType dbType, const char *appName, const char *filename, const char *dbname, char *args, PRBool rw) { /* SHDB_FIXME implement */ FILE *fd = NULL; FILE *fd2 = NULL; char line[MAX_LINE_LENGTH]; char *dbname2 = NULL; char *block = NULL; char *name = NULL; char *lib = NULL; int name_len, lib_len; PRBool skip = PR_FALSE; PRBool found = PR_FALSE; if (dbname == NULL) { return SECFailure; } if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { return sftkdbCall_DeleteSecmodDB(appName, filename, dbname, args, rw); } if (!rw) { return SECFailure; } dbname2 = strdup(dbname); if (dbname2 == NULL) goto loser; dbname2[strlen(dbname)-1]++; /* do we really want to use streams here */ fd = fopen(dbname, "r"); if (fd == NULL) goto loser; #ifdef WINCE fd2 = fopen(dbname2, "w+"); #else fd2 = lfopen(dbname2, "w+", O_CREAT|O_RDWR|O_TRUNC); #endif if (fd2 == NULL) goto loser; name = sftk_argGetParamValue("name",args); if (name) { name_len = PORT_Strlen(name); } lib = sftk_argGetParamValue("library",args); if (lib) { lib_len = PORT_Strlen(lib); } /* * the following loop takes line separated config files and collapses * the lines to a single string, escaping and quoting as necessary. */ /* loop state variables */ block = NULL; skip = PR_FALSE; while (fgets(line, sizeof(line), fd) != NULL) { /* If we are processing a block (we haven't hit a blank line yet */ if (*line != '\n') { /* skip means we are in the middle of a block we are deleting */ if (skip) { continue; } /* if we haven't found the block yet, check to see if this block * matches our requirements */ if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) && (PORT_Strncmp(line+5,name,name_len) == 0)) || (lib && (PORT_Strncasecmp(line,"library=",8) == 0) && (PORT_Strncmp(line+8,lib,lib_len) == 0)))) { /* yup, we don't need to save any more data, */ PORT_Free(block); block=NULL; /* we don't need to collect more of this block */ skip = PR_TRUE; /* we don't need to continue searching for the block */ found =PR_TRUE; continue; } /* not our match, continue to collect data in this block */ block = sftkdb_DupCat(block,line); continue; } /* we've collected a block of data that wasn't the module we were * looking for, write it out */ if (block) { fwrite(block, PORT_Strlen(block), 1, fd2); PORT_Free(block); block = NULL; } /* If we didn't just delete the this block, keep the blank line */ if (!skip) { fputs(line,fd2); } /* we are definately not in a deleted block anymore */ skip = PR_FALSE; } fclose(fd); fclose(fd2); if (found) { /* rename dbname2 to dbname */ PR_Delete(dbname); PR_Rename(dbname2,dbname); } else { PR_Delete(dbname2); } PORT_Free(dbname2); PORT_Free(lib); PORT_Free(name); PORT_Free(block); return SECSuccess; loser: if (fd != NULL) { fclose(fd); } if (fd2 != NULL) { fclose(fd2); } if (dbname2) { PR_Delete(dbname2); PORT_Free(dbname2); } PORT_Free(lib); PORT_Free(name); return SECFailure; }
SECStatus SGN_End(SGNContext *cx, SECItem *result) { unsigned char digest[HASH_LENGTH_MAX]; unsigned part1; int signatureLen; SECStatus rv; SECItem digder, sigitem; PLArenaPool *arena = 0; SECKEYPrivateKey *privKey = cx->key; SGNDigestInfo *di = 0; result->data = 0; digder.data = 0; /* Finish up digest function */ if (cx->hashcx == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } (*cx->hashobj->end)(cx->hashcx, digest, &part1, sizeof(digest)); if (privKey->keyType == rsaKey) { arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( !arena ) { rv = SECFailure; goto loser; } /* Construct digest info */ di = SGN_CreateDigestInfo(cx->hashalg, digest, part1); if (!di) { rv = SECFailure; goto loser; } /* Der encode the digest as a DigestInfo */ rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di); if (rv != SECSuccess) { goto loser; } } else { digder.data = digest; digder.len = part1; } /* ** Encrypt signature after constructing appropriate PKCS#1 signature ** block */ signatureLen = PK11_SignatureLen(privKey); if (signatureLen <= 0) { PORT_SetError(SEC_ERROR_INVALID_KEY); rv = SECFailure; goto loser; } sigitem.len = signatureLen; sigitem.data = (unsigned char*) PORT_Alloc(signatureLen); if (sigitem.data == NULL) { rv = SECFailure; goto loser; } rv = PK11_Sign(privKey, &sigitem, &digder); if (rv != SECSuccess) { PORT_Free(sigitem.data); sigitem.data = NULL; goto loser; } if ((cx->signalg == SEC_OID_ANSIX9_DSA_SIGNATURE) || (cx->signalg == SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { /* DSAU_EncodeDerSigWithLen works for DSA and ECDSA */ rv = DSAU_EncodeDerSigWithLen(result, &sigitem, sigitem.len); PORT_Free(sigitem.data); if (rv != SECSuccess) goto loser; } else { result->len = sigitem.len; result->data = sigitem.data; } loser: SGN_DestroyDigestInfo(di); if (arena != NULL) { PORT_FreeArena(arena, PR_FALSE); } return rv; }
/* * Create a DER-encoded OCSP request (for the certificate whose nickname is * "cert_name"), then get and dump a corresponding response. The responder * location is either specified explicitly (as "responder_url") or found * via the AuthorityInfoAccess URL in the cert. */ static SECStatus dump_response (FILE *out_file, CERTCertDBHandle *handle, CERTCertificate *cert, const char *responder_url) { CERTCertList *certs = NULL; CERTCertificate *myCert = NULL; char *loc = NULL; PRTime now = PR_Now(); SECItem *response = NULL; SECStatus rv = SECFailure; PRBool includeServiceLocator; if (handle == NULL || cert == NULL) return rv; myCert = CERT_DupCertificate(cert); if (myCert == NULL) goto loser; if (responder_url != NULL) { loc = (char *) responder_url; includeServiceLocator = PR_TRUE; } else { loc = CERT_GetOCSPAuthorityInfoAccessLocation (cert); if (loc == NULL) goto loser; includeServiceLocator = PR_FALSE; } /* * We need to create a list of one. */ certs = CERT_NewCertList(); if (certs == NULL) goto loser; if (CERT_AddCertToListTail (certs, myCert) != SECSuccess) goto loser; /* * Now that cert is included in the list, we need to be careful * that we do not try to destroy it twice. This will prevent that. */ myCert = NULL; response = CERT_GetEncodedOCSPResponse (NULL, certs, loc, now, includeServiceLocator, NULL, NULL, NULL); if (response == NULL) goto loser; MAKE_FILE_BINARY(out_file); if (fwrite (response->data, response->len, 1, out_file) != 1) goto loser; rv = SECSuccess; loser: if (response != NULL) SECITEM_FreeItem (response, PR_TRUE); if (certs != NULL) CERT_DestroyCertList (certs); if (myCert != NULL) CERT_DestroyCertificate(myCert); if (loc != NULL && loc != responder_url) PORT_Free (loc); return rv; }
SECStatus SGN_Digest(SECKEYPrivateKey *privKey, SECOidTag algtag, SECItem *result, SECItem *digest) { int modulusLen; SECStatus rv; SECItem digder; PLArenaPool *arena = 0; SGNDigestInfo *di = 0; result->data = 0; if (privKey->keyType == rsaKey) { arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE); if ( !arena ) { rv = SECFailure; goto loser; } /* Construct digest info */ di = SGN_CreateDigestInfo(algtag, digest->data, digest->len); if (!di) { rv = SECFailure; goto loser; } /* Der encode the digest as a DigestInfo */ rv = DER_Encode(arena, &digder, SGNDigestInfoTemplate, di); if (rv != SECSuccess) { goto loser; } } else { digder.data = digest->data; digder.len = digest->len; } /* ** Encrypt signature after constructing appropriate PKCS#1 signature ** block */ modulusLen = PK11_SignatureLen(privKey); if (modulusLen <= 0) { PORT_SetError(SEC_ERROR_INVALID_KEY); rv = SECFailure; goto loser; } result->len = modulusLen; result->data = (unsigned char*) PORT_Alloc(modulusLen); result->type = siBuffer; if (result->data == NULL) { rv = SECFailure; goto loser; } rv = PK11_Sign(privKey, result, &digder); if (rv != SECSuccess) { PORT_Free(result->data); result->data = NULL; } loser: SGN_DestroyDigestInfo(di); if (arena != NULL) { PORT_FreeArena(arena, PR_FALSE); } return rv; }
SECStatus SEC_DerSignData(PLArenaPool *arena, SECItem *result, const unsigned char *buf, int len, SECKEYPrivateKey *pk, SECOidTag algID) { SECItem it; CERTSignedData sd; SECStatus rv; it.data = 0; /* XXX We should probably have some asserts here to make sure the key type * and algID match */ if (algID == SEC_OID_UNKNOWN) { switch(pk->keyType) { case rsaKey: algID = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; break; case dsaKey: /* get Signature length (= q_len*2) and work from there */ switch (PK11_SignatureLen(pk)) { case 448: algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST; break; case 512: algID = SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST; break; default: algID = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break; } break; case ecKey: algID = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST; break; default: PORT_SetError(SEC_ERROR_INVALID_KEY); return SECFailure; } } /* Sign input buffer */ rv = SEC_SignData(&it, buf, len, pk, algID); if (rv) goto loser; /* Fill out SignedData object */ PORT_Memset(&sd, 0, sizeof(sd)); sd.data.data = (unsigned char*) buf; sd.data.len = len; sd.signature.data = it.data; sd.signature.len = it.len << 3; /* convert to bit string */ rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, algID, 0); if (rv) goto loser; /* DER encode the signed data object */ rv = DER_Encode(arena, result, CERTSignedDataTemplate, &sd); /* FALL THROUGH */ loser: PORT_Free(it.data); return rv; }