Support for nsICertPrincipal. We do the certificate verification of certificates passed by JavaSoft

This commit is contained in:
raman%netscape.com 1998-10-14 02:52:40 +00:00
parent 1164f2ffcd
commit 5f82c88ba4
4 changed files with 177 additions and 33 deletions

View File

@ -76,6 +76,11 @@ public:
PRBool isSecurePrincipal(void);
/* The following method is used by Javasoft JVM to verify their
* code signing certificates against our security DB files
*/
PRBool isTrustedCertChainPrincipal(void);
PRBool isFileCodeBase(void);
PRBool isCert(void);
@ -96,21 +101,22 @@ private:
/* Private Field Accessors */
nsPrincipalType itsType;
void * itsZig;
char * itsKey;
void* itsZig;
char* itsKey;
PRUint32 itsKeyLen;
nsVector* itsCertArray;
PRInt32 itsHashCode;
char * itsCompanyName;
char * itsCertAuth;
char * itsSerialNo;
char * itsExpDate;
char * itsAsciiFingerPrint;
char * itsNickname;
char * itsString;
char* itsCompanyName;
char* itsCertAuth;
char* itsSerialNo;
char* itsExpDate;
char* itsAsciiFingerPrint;
char* itsNickname;
char* itsString;
/* Private Methods */
void init(nsPrincipalType type, void * key, PRUint32 key_len);

View File

@ -42,7 +42,7 @@ nsCCertPrincipal::IsTrusted(char* scope, PRBool *pbIsTrusted)
*pbIsTrusted = PR_FALSE;
return NS_ERROR_ILLEGAL_VALUE;
}
*pbIsTrusted = m_pNSPrincipal->isSecurePrincipal();
*pbIsTrusted = m_pNSPrincipal->isTrustedCertChainPrincipal();
return NS_OK;
}
@ -183,7 +183,7 @@ nsCCertPrincipal::nsCCertPrincipal(const unsigned char **certChain,
PRUint32 noOfCerts,
nsresult *result)
{
m_pNSPrincipal = new nsPrincipal(nsPrincipalType_Cert, certChain,
m_pNSPrincipal = new nsPrincipal(nsPrincipalType_CertChain, certChain,
certChainLengths, noOfCerts);
if(m_pNSPrincipal == NULL)
{

View File

@ -39,10 +39,17 @@ NS_IMPL_QUERY_INTERFACE(nsCCodeSourcePrincipal, kICodeSourcePrincipalIID);
NS_METHOD
nsCCodeSourcePrincipal::IsTrusted(char* scope, PRBool *pbIsTrusted)
{
if(m_pNSICertPrincipal == NULL)
if(m_pNSICertPrincipal == NULL)
{
*pbIsTrusted = PR_FALSE;
return NS_ERROR_ILLEGAL_VALUE;
if(m_pNSICodebasePrincipal == NULL)
{
*pbIsTrusted = PR_FALSE;
return NS_ERROR_ILLEGAL_VALUE;
}
else
{
return m_pNSICodebasePrincipal->IsTrusted(scope, pbIsTrusted);
}
}
return m_pNSICertPrincipal->IsTrusted(scope, pbIsTrusted);
}

View File

@ -16,6 +16,12 @@
* Reserved.
*/
/* TODO:
*
* + Remove all XXX's.
*
*/
#include "nsPrincipal.h"
#include "nsPrivilegeManager.h"
@ -23,6 +29,12 @@
#include "xp_mem.h"
#include "prmem.h"
#include "zig.h"
#include "secnav.h"
#ifndef NO_SECURITY
#include "navhook.h"
#include "jarutil.h"
#endif /* NO_SECURITY */
/* XXX: Hack to determine the system principal */
@ -34,6 +46,11 @@ PR_BEGIN_EXTERN_C
#include "fe_proto.h"
#include "nsLoadZig.h"
static void destroyCertificates(nsVector* certArray);
static nsVector* getTempCertificates(const unsigned char **certChain,
PRUint32 *certChainLengths,
PRUint32 noOfCerts);
/* XXX: Create an error object with all arguments except errorText, instead pass error enum,
This will be a method on caps consumer interface. */
PR_PUBLIC_API(int)
@ -135,6 +152,70 @@ PR_END_EXTERN_C
/* XXX: end of hack to determine the system principal */
static void destroyCertificates(nsVector* certArray)
{
if (certArray == NULL)
return;
for (PRUint32 i = certArray->GetSize(); i-- > 0; ) {
CERTCertificate *cert = (CERTCertificate *)certArray->Get(i);
if (cert != NULL) {
CERT_DestroyCertificate(cert);
certArray->Set(i, NULL);
}
}
delete certArray;
}
static nsVector* getTempCertificates(const unsigned char **certChain,
PRUint32 *certChainLengths,
PRUint32 noOfCerts)
{
#ifdef NO_SECURITY
return NULL;
#else
CERTCertificate *cert;
CERTCertDBHandle *handle = CERT_GetDefaultCertDB();
SECStatus rv;
nsVector* certArray = new nsVector();
certArray->SetSize(noOfCerts, 1);
if (certArray == NULL) {
return NULL;
}
for (PRUint32 i = noOfCerts; i-- > 0; ) {
SECItem derCert;
derCert.data = (unsigned char *)certChain[i];
derCert.len = certChainLengths[i];
cert = CERT_NewTempCertificate(handle, &derCert, NULL,
PR_FALSE, PR_TRUE);
if (cert != NULL) {
certArray->Set(i, (void*)cert);
} else {
// unable to add cert to the temp database
certArray->Set(i, NULL);
}
}
cert = (CERTCertificate *)certArray->Get(0);
rv = CERT_VerifyCert(handle, cert, PR_TRUE,
certUsageObjectSigner,
PR_FALSE, NULL, NULL);
if (rv != SECSuccess) {
// Free the certificates and mark this principal as not trusted.
destroyCertificates(certArray);
return NULL;
}
return certArray;
#endif /* NO_SECURITY */
}
//
// PUBLIC METHODS
//
@ -163,15 +244,9 @@ nsPrincipal::nsPrincipal(nsPrincipalType type,
{
/* We will store the signers certificate as the key */
init(type, (void*)certChain[0], certChainLengths[0]);
for (PRUint32 i = noOfCerts; i < noOfCerts; i--) {
void* cert = (void*)certChain[i];
PRUint32 cert_len = certChainLengths[i];
/*
SOB_ImportCert(cert, cert_len);
SOB_ValidateCert(cert, cert_len);
SOB_GetCertAttributes(cert, cert_len);
*/
}
itsCertArray = getTempCertificates(certChain,
certChainLengths,
noOfCerts);
}
nsPrincipal::~nsPrincipal(void)
@ -200,13 +275,31 @@ nsPrincipal::~nsPrincipal(void)
if (itsNickname) {
delete []itsNickname;
}
if (itsCertArray) {
destroyCertificates(itsCertArray);
}
}
PRBool nsPrincipal::equals(nsPrincipal *prin)
{
if (prin == this)
return PR_TRUE;
/* Deal with CertChain principal specially */
if ((itsType == nsPrincipalType_CertChain) ||
(prin->itsType == nsPrincipalType_CertChain)) {
/* Because we have full certificate for the CertChain
* we will compare different attributes of the principal
* and if all the attributes match, then we return TRUE
*/
if ((XP_STRCMP(getSerialNo(), prin->getSerialNo()) == 0) &&
(XP_STRCMP(getSecAuth(), prin->getSecAuth()) == 0) &&
(XP_STRCMP(getExpDate(), prin->getExpDate()) == 0) &&
(XP_STRCMP(getFingerPrint(), prin->getFingerPrint()) == 0))
return PR_TRUE;
}
if ((itsType != prin->itsType) ||
(itsKeyLen != prin->itsKeyLen))
return PR_FALSE;
@ -235,6 +328,7 @@ char * nsPrincipal::getVendor(void)
}
// XXX copyied from ns/lib/libjar/zig.h
// RAMAN: Why??
#ifndef ZIG_C_COMPANY
#define ZIG_C_COMPANY 1
#endif
@ -319,12 +413,8 @@ char * nsPrincipal::getNickname(void)
return "Classes for whom we don't the principal";
}
if (nsPrincipalType_CertChain == itsType) {
/* XXX: We should get the first certificate's nickname */
return "Javasoft's principal";
}
if (nsPrincipalType_CertKey != itsType)
if ((nsPrincipalType_CertKey != itsType) ||
(nsPrincipalType_CertChain != itsType))
return itsKey;
if (itsNickname == NULL)
@ -399,6 +489,16 @@ PRBool nsPrincipal::isSecurePrincipal(void)
return PR_FALSE;
}
PRBool nsPrincipal::isTrustedCertChainPrincipal(void)
{
/* We destroy the cert array if cert chain didn't verify */
if ((itsType != nsPrincipalType_CertChain) ||
(itsCertArray == NULL))
return PR_FALSE;
return PR_TRUE;
}
/*
* This method is introduced to check the whether a given url base
* is a file based or any other type. Returns TRUE if the key is a
@ -565,6 +665,7 @@ void nsPrincipal::init(nsPrincipalType type, void * key, PRUint32 key_len)
itsKeyLen = key_len;
itsHashCode = computeHashCode();
itsZig = NULL;
itsCertArray = NULL;
itsString = NULL;
itsCompanyName = NULL;
itsCertAuth = NULL;
@ -606,7 +707,9 @@ PRInt32 nsPrincipal::computeHashCode(void)
char * nsPrincipal::saveCert(void)
{
int result;
/* XXX: Implement CertChain principal */
if (itsType == nsPrincipalType_CertChain) {
return NULL;
}
if ((!itsZig) || (!itsKey)) {
return NULL;
}
@ -632,8 +735,36 @@ nsPrincipal::getCertAttribute(int attrib)
}
if (itsType == nsPrincipalType_CertChain) {
/* XXX: Implement CertChain Principal */
return "Javasoft's cert chain principal";
char *attributeStr;
CERTCertificate *cert = (CERTCertificate *)itsCertArray->Get(0);
switch (attrib) {
#ifndef NO_SECURITY
case ZIG_C_COMPANY:
attributeStr = SECNAV_GetJarCertInfo(cert, snjSubjectName);
break;
case ZIG_C_CA:
attributeStr = SECNAV_GetJarCertInfo(cert, snjIssuerName);
break;
case ZIG_C_SERIAL:
attributeStr = SECNAV_GetJarCertInfo(cert, snjSerialNumber);
break;
case ZIG_C_EXPIRES:
attributeStr = SECNAV_GetJarCertInfo(cert, snjExpirationDate);
break;
case ZIG_C_NICKNAME:
attributeStr = SECNAV_GetJarCertInfo(cert, snjNickname);
break;
case ZIG_C_FP:
attributeStr = SECNAV_GetJarCertInfo(cert, snjFingerprint);
break;
#endif /* NO_SECURITY */
default:
return NULL;
}
attrStr = new char[strlen(attributeStr)+1];
XP_STRCPY(attrStr, attributeStr);
PR_FREEIF(attributeStr);
return attrStr;
}
if (SOB_cert_attribute(attrib, zig,