Exemple #1
0
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;
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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);
}
Exemple #5
0
/* 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;
}
Exemple #6
0
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;
}
Exemple #8
0
/*
 * 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;
}
Exemple #9
0
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);
    }
}
Exemple #10
0
/*
 * 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;
}
Exemple #11
0
/*
 * 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;
}
Exemple #12
0
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;
}
Exemple #13
0
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;
}
Exemple #14
0
/*
 * 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);
}