PRBool CERT_MatchNickname(char *name1, char *name2) { char *nickname1= NULL; char *nickname2 = NULL; char *token1; char *token2; /* first deal with the straight comparison */ if (PORT_Strcmp(name1, name2) == 0) { return PR_TRUE; } /* we need to handle the case where one name has an explicit token and the other * doesn't */ token1 = PORT_Strchr(name1,':'); token2 = PORT_Strchr(name2,':'); if ((token1 && token2) || (!token1 && !token2)) { /* either both token names are specified or neither are, not match */ return PR_FALSE; } if (token1) { nickname1=token1; nickname2=name2; } else { nickname1=token2; nickname2=name1; } nickname1++; if (PORT_Strcmp(nickname1,nickname2) != 0) { return PR_FALSE; } /* Bug 1192443 - compare the other token with the internal slot here */ return PR_TRUE; }
static SECStatus nss_load_crl(const char* crlfilename) { PRFileDesc *infile; PRFileInfo info; SECItem filedata = { 0, NULL, 0 }; SECItem crlDER = { 0, NULL, 0 }; char *body; infile = PR_Open(crlfilename, PR_RDONLY, 0); if(!infile) return SECFailure; if(PR_SUCCESS != PR_GetOpenFileInfo(infile, &info)) goto fail; if(!SECITEM_AllocItem(NULL, &filedata, info.size + /* zero ended */ 1)) goto fail; if(info.size != PR_Read(infile, filedata.data, info.size)) goto fail; /* place a trailing zero right after the visible data */ body = (char*)filedata.data; body[--filedata.len] = '\0'; body = strstr(body, "-----BEGIN"); if(body) { /* assume ASCII */ char *trailer; char *begin = PORT_Strchr(body, '\n'); if(!begin) begin = PORT_Strchr(body, '\r'); if(!begin) goto fail; trailer = strstr(++begin, "-----END"); if(!trailer) goto fail; /* retrieve DER from ASCII */ *trailer = '\0'; if(ATOB_ConvertAsciiToItem(&crlDER, begin)) goto fail; SECITEM_FreeItem(&filedata, PR_FALSE); } else /* assume DER */ crlDER = filedata; PR_Close(infile); return nss_cache_crl(&crlDER); fail: PR_Close(infile); SECITEM_FreeItem(&filedata, PR_FALSE); return SECFailure; }
SECStatus SECU_ReadDERFromFile(SECItem *der, PRFileDesc *inFile, PRBool ascii) { SECStatus rv; if (ascii) { /* First convert ascii to binary */ SECItem filedata; char *asc, *body; /* Read in ascii data */ rv = SECU_FileToItem(&filedata, inFile); asc = (char *)filedata.data; if (!asc) { fprintf(stderr, "unable to read data from input file\n"); return SECFailure; } /* check for headers and trailers and remove them */ if ((body = strstr(asc, "-----BEGIN")) != NULL) { char *trailer = NULL; asc = body; body = PORT_Strchr(body, '\n'); if (!body) body = PORT_Strchr(asc, '\r'); /* maybe this is a MAC file */ if (body) trailer = strstr(++body, "-----END"); if (trailer != NULL) { *trailer = '\0'; } else { fprintf(stderr, "input has header but no trailer\n"); PORT_Free(filedata.data); return SECFailure; } } else { body = asc; } /* Convert to binary */ rv = ATOB_ConvertAsciiToItem(der, body); if (rv) { fprintf(stderr, "error converting ascii to binary (%d)\n", PORT_GetError()); PORT_Free(filedata.data); return SECFailure; } PORT_Free(filedata.data); } else { /* Read in binary der */ rv = SECU_FileToItem(der, inFile); if (rv) { fprintf(stderr, "error converting der (%d)\n", PORT_GetError()); return SECFailure; } } return SECSuccess; }
UtlBoolean SmimeBody::convertPemToDer(UtlString& pemData, UtlString& derData) { UtlBoolean conversionSucceeded = FALSE; derData.remove(0); #ifdef ENABLE_NSS_SMIME // Code from NSS secutil.c char* body = NULL; char* pemDataPtr = (char*) pemData.data(); /* check for headers and trailers and remove them */ if ((body = strstr(pemDataPtr, "-----BEGIN")) != NULL) { char *trailer = NULL; pemData = strdup(body); body = PORT_Strchr(body, '\n'); if (!body) body = PORT_Strchr(pemDataPtr, '\r'); /* maybe this is a MAC file */ if (body) trailer = strstr(++body, "-----END"); if (trailer != NULL) { *trailer = '\0'; } else { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "input has header but no trailer\n"); } } else { body = pemDataPtr; } /* Convert to binary */ SECItem derItem; derItem.data = NULL; derItem.len = 0; if(ATOB_ConvertAsciiToItem(&derItem, body)) { Os::Logger::instance().log(FAC_SIP, PRI_ERR, "error converting PEM base64 data to binary"); } else { derData.append(((char*)derItem.data), derItem.len); conversionSucceeded = TRUE; } #else Os::Logger::instance().log(FAC_SIP, PRI_ERR, "SmimeBody::convertPemToDer implemented with NSS and OpenSSL disabled"); #endif return(conversionSucceeded); }
/* Modified from NSS source */ SECStatus SECU_ReadDER(SECItem *der, std::string data) { SECStatus rv; /* First convert ascii to binary */ //SECItem filedata; char *asc, *body; /* Read in ascii data */ asc = const_cast<char*>(data.data()); if (!asc) { fprintf(stderr, "unable to read data from input file\n"); return SECFailure; } /* check for headers and trailers and remove them */ if ((body = strstr(asc, "-----BEGIN")) != NULL) { char *trailer = NULL; asc = body; body = PORT_Strchr(body, '\n'); if (!body) body = PORT_Strchr(asc, '\r'); /* maybe this is a MAC file */ if (body) trailer = strstr(++body, "-----END"); if (trailer != NULL) { *trailer = '\0'; } else { fprintf(stderr, "input has header but no trailer\n"); return SECFailure; } } else { body = asc; } /* Convert to binary */ rv = ATOB_ConvertAsciiToItem(der, body); if (rv) { return SECFailure; } return SECSuccess; }
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; }
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; }
/* * 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 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); } }
/* * Add a module to the Data base */ static SECStatus nssutil_AddSecmodDBEntry(const char *appName, const char *filename, const char *dbname, char *module, PRBool rw) { os_stat_type stat_existing; os_open_permissions_type file_mode; FILE *fd = NULL; char *block = NULL; PRBool libFound = PR_FALSE; if (dbname == NULL) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } /* can't write to a read only module */ if (!rw) { PORT_SetError(SEC_ERROR_READ_ONLY); return SECFailure; } /* remove the previous version if it exists */ (void) nssutil_DeleteSecmodDBEntry(appName, filename, dbname, module, rw); /* get the permissions of the existing file, or use the default */ if (!os_stat(dbname, &stat_existing)) { file_mode = stat_existing.st_mode; } else { file_mode = os_open_permissions_default; } fd = lfopen(dbname, lfopen_append, file_mode); if (fd == NULL) { return SECFailure; } module = NSSUTIL_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 = nssutil_DupCat(block, module); break; } block = nssutil_DupnCat(block, module, keyEnd-module+1); if (block == NULL) { goto loser; } value = NSSUTIL_ArgFetchValue(&keyEnd[1], &count); if (value) { block = nssutil_DupCat(block, NSSUTIL_ArgStrip(value)); PORT_Free(value); } if (block == NULL) { goto loser; } block = nssutil_DupnCat(block, "\n", 1); module = keyEnd + 1 + count; module = NSSUTIL_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; }
/* * Add a module to the Data base */ static SECStatus nssutil_AddSecmodDB(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) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return SECFailure; } /* can't write to a read only module */ if (!rw) { PORT_SetError(SEC_ERROR_READ_ONLY); return SECFailure; } /* remove the previous version if it exists */ (void) nssutil_DeleteSecmodDB(appName, filename, dbname, module, rw); fd = lfopen(dbname, "a+", O_CREAT|O_RDWR|O_APPEND); if (fd == NULL) { return SECFailure; } module = NSSUTIL_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 = nssutil_DupCat(block, module); break; } block = nssutil_DupnCat(block, module, keyEnd-module+1); if (block == NULL) { goto loser; } value = NSSUTIL_ArgFetchValue(&keyEnd[1], &count); if (value) { block = nssutil_DupCat(block, NSSUTIL_ArgStrip(value)); PORT_Free(value); } if (block == NULL) { goto loser; } block = nssutil_DupnCat(block, "\n", 1); module = keyEnd + 1 + count; module = NSSUTIL_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 CERTCertificate * common_FindCertByNicknameOrEmailAddrForUsage(CERTCertDBHandle *handle, const char *name, PRBool anyUsage, SECCertUsage lookingForUsage) { NSSCryptoContext *cc; NSSCertificate *c, *ct; CERTCertificate *cert = NULL; NSSUsage usage; CERTCertList *certlist; if (NULL == name) { PORT_SetError(SEC_ERROR_INVALID_ARGS); return NULL; } usage.anyUsage = anyUsage; if (!anyUsage) { usage.nss3lookingForCA = PR_FALSE; usage.nss3usage = lookingForUsage; } 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); } } if (anyUsage) { cert = PK11_FindCertFromNickname(name, NULL); } else { if (ct) { /* Does ct really have the required usage? */ nssDecodedCert *dc; dc = nssCertificate_GetDecoding(ct); if (!dc->matchUsage(dc, &usage)) { CERT_DestroyCertificate(STAN_GetCERTCertificateOrRelease(ct)); ct = NULL; } } certlist = PK11_FindCertsFromNickname(name, NULL); if (certlist) { SECStatus rv = CERT_FilterCertListByUsage(certlist, lookingForUsage, PR_FALSE); if (SECSuccess == rv && !CERT_LIST_END(CERT_LIST_HEAD(certlist), certlist)) { cert = CERT_DupCertificate(CERT_LIST_HEAD(certlist)->cert); } CERT_DestroyCertList(certlist); } } 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; }
static int nss_load_crl(const char* crlfilename, PRBool ascii) { PRFileDesc *infile; PRStatus prstat; PRFileInfo info; PRInt32 nb; int rv; SECItem crlDER; CERTSignedCrl *crl=NULL; PK11SlotInfo *slot=NULL; infile = PR_Open(crlfilename,PR_RDONLY,0); if (!infile) { return 0; } crlDER.data = NULL; prstat = PR_GetOpenFileInfo(infile,&info); if (prstat!=PR_SUCCESS) return 0; if (ascii) { SECItem filedata; char *asc,*body; filedata.data = NULL; if (!SECITEM_AllocItem(NULL,&filedata,info.size)) return 0; nb = PR_Read(infile,filedata.data,info.size); if (nb!=info.size) return 0; asc = (char*)filedata.data; if (!asc) return 0; body=strstr(asc,"-----BEGIN"); if (body != NULL) { char *trailer=NULL; asc = body; body = PORT_Strchr(asc,'\n'); if (!body) body = PORT_Strchr(asc,'\r'); if (body) trailer = strstr(++body,"-----END"); if (trailer!=NULL) *trailer='\0'; else return 0; } else { body = asc; } rv = ATOB_ConvertAsciiToItem(&crlDER,body); PORT_Free(filedata.data); if (rv) return 0; } else { if (!SECITEM_AllocItem(NULL,&crlDER,info.size)) return 0; nb = PR_Read(infile,crlDER.data,info.size); if (nb!=info.size) return 0; } slot = PK11_GetInternalKeySlot(); crl = PK11_ImportCRL(slot,&crlDER, NULL,SEC_CRL_TYPE, NULL,CRL_IMPORT_DEFAULT_OPTIONS, NULL,(CRL_DECODE_DEFAULT_OPTIONS| CRL_DECODE_DONT_COPY_DER)); if (slot) PK11_FreeSlot(slot); if (!crl) return 0; SEC_DestroyCrl(crl); return 1; }
/* * read an old style ascii or binary certificate chain */ SECStatus CERT_DecodeCertPackage(char *certbuf, int certlen, CERTImportCertificateFunc f, void *arg) { unsigned char *cp; unsigned char *bincert = NULL; char * ascCert = NULL; SECStatus rv; if ( certbuf == NULL ) { return(SECFailure); } cp = (unsigned char *)certbuf; /* is a DER encoded certificate of some type? */ if ( ( *cp & 0x1f ) == SEC_ASN1_SEQUENCE ) { SECItem certitem; SECItem *pcertitem = &certitem; int seqLen, seqLenLen; cp++; if ( *cp & 0x80) { /* Multibyte length */ seqLenLen = cp[0] & 0x7f; switch (seqLenLen) { case 4: seqLen = ((unsigned long)cp[1]<<24) | ((unsigned long)cp[2]<<16) | (cp[3]<<8) | cp[4]; break; case 3: seqLen = ((unsigned long)cp[1]<<16) | (cp[2]<<8) | cp[3]; break; case 2: seqLen = (cp[1]<<8) | cp[2]; break; case 1: seqLen = cp[1]; break; default: /* indefinite length */ seqLen = 0; } cp += ( seqLenLen + 1 ); } else { seqLenLen = 0; seqLen = *cp; cp++; } /* check entire length if definite length */ if ( seqLen || seqLenLen ) { if ( certlen != ( seqLen + seqLenLen + 2 ) ) { if (certlen > ( seqLen + seqLenLen + 2 )) PORT_SetError(SEC_ERROR_EXTRA_INPUT); else PORT_SetError(SEC_ERROR_INPUT_LEN); goto notder; } } /* check the type string */ /* netscape wrapped DER cert */ if ( ( cp[0] == SEC_ASN1_OCTET_STRING ) && ( cp[1] == CERTIFICATE_TYPE_LEN ) && ( PORT_Strcmp((char *)&cp[2], CERTIFICATE_TYPE_STRING) ) ) { cp += ( CERTIFICATE_TYPE_LEN + 2 ); /* it had better be a certificate by now!! */ certitem.data = cp; certitem.len = certlen - ( cp - (unsigned char *)certbuf ); rv = (* f)(arg, &pcertitem, 1); return(rv); } else if ( cp[0] == SEC_ASN1_OBJECT_ID ) { SECOidData *oiddata; SECItem oiditem; /* XXX - assume DER encoding of OID len!! */ oiditem.len = cp[1]; oiditem.data = (unsigned char *)&cp[2]; oiddata = SECOID_FindOID(&oiditem); if ( oiddata == NULL ) { return(SECFailure); } certitem.data = (unsigned char*)certbuf; certitem.len = certlen; switch ( oiddata->offset ) { case SEC_OID_PKCS7_SIGNED_DATA: return(SEC_ReadPKCS7Certs(&certitem, f, arg)); break; case SEC_OID_NS_TYPE_CERT_SEQUENCE: return(SEC_ReadCertSequence(&certitem, f, arg)); break; default: break; } } else { /* it had better be a certificate by now!! */ certitem.data = (unsigned char*)certbuf; certitem.len = certlen; rv = (* f)(arg, &pcertitem, 1); return(rv); } } /* now look for a netscape base64 ascii encoded cert */ notder: { unsigned char *certbegin = NULL; unsigned char *certend = NULL; char *pc; int cl; /* Convert the ASCII data into a nul-terminated string */ ascCert = (char *)PORT_Alloc(certlen + 1); if (!ascCert) { rv = SECFailure; goto loser; } PORT_Memcpy(ascCert, certbuf, certlen); ascCert[certlen] = '\0'; pc = PORT_Strchr(ascCert, '\n'); /* find an EOL */ if (!pc) { /* maybe this is a MAC file */ pc = ascCert; while (*pc && NULL != (pc = PORT_Strchr(pc, '\r'))) { *pc++ = '\n'; } } cp = (unsigned char *)ascCert; cl = certlen; /* find the beginning marker */ while ( cl > NS_CERT_HEADER_LEN ) { if ( !PORT_Strncasecmp((char *)cp, NS_CERT_HEADER, NS_CERT_HEADER_LEN) ) { cl -= NS_CERT_HEADER_LEN; cp += NS_CERT_HEADER_LEN; certbegin = cp; break; } /* skip to next eol */ do { cp++; cl--; } while ( ( *cp != '\n') && cl ); /* skip all blank lines */ while ( ( *cp == '\n') && cl ) { cp++; cl--; } } if ( certbegin ) { /* find the ending marker */ while ( cl > NS_CERT_TRAILER_LEN ) { if ( !PORT_Strncasecmp((char *)cp, NS_CERT_TRAILER, NS_CERT_TRAILER_LEN) ) { certend = (unsigned char *)cp; break; } /* skip to next eol */ do { cp++; cl--; } while ( ( *cp != '\n') && cl ); /* skip all blank lines */ while ( ( *cp == '\n') && cl ) { cp++; cl--; } } } if ( certbegin && certend ) { unsigned int binLen; *certend = 0; /* convert to binary */ bincert = ATOB_AsciiToData(certbegin, &binLen); if (!bincert) { rv = SECFailure; goto loser; } /* now recurse to decode the binary */ rv = CERT_DecodeCertPackage((char *)bincert, binLen, f, arg); } else { rv = SECFailure; } } loser: if ( bincert ) { PORT_Free(bincert); } if ( ascCert ) { PORT_Free(ascCert); } return(rv); }