netscape-revival
security/lib/nav/policy.c
/*
* Security Policy Enforcement for crypto code
*
* Copyright © 1995 Netscape Communications Corporation, all rights reserved.
*
* $Id: policy.c,v 1.4.2.6 1997/05/24 00:23:40 jwz Exp $
*/
#include "xp.h"
#include "secport.h"
#include "secnav.h"
#include "sslproto.h"
#include "cert.h" /* for CertCertificate */
#include "prefapi.h"
#include "zig.h"
#include "xpgetstr.h"
#include "gui.h" /* for XP_AppCodeName */
#include "fe_proto.h" /* for FE_Alert() */
#include "proto.h" /* for XP_FindSomeContext() */
#ifdef AKBAR
extern char *XP_AppLanguage;
extern char * XP_PlatformFileToURL (const char *name);
#endif /* AKBAR */
#define NOT_FOR_RELEASE_TO_THE_PUBLIC 0
#define PR_MAYBE ((PRBool)SSL_RESTRICTED)
#define ACQUIRE_WRITE_LOCK
#define RELEASE_WRITE_LOCK
#define ACQUIRE_READ_LOCK
#define RELEASE_READ_LOCK
/* pointers to global string indexes */
/* there oughtta be a better way than this... */
extern int XP_SMIME_DES_CBC;
extern int XP_SMIME_DES_EDE3;
extern int XP_SMIME_RC2_CBC_128;
extern int XP_SMIME_RC2_CBC_40;
extern int XP_SMIME_RC2_CBC_64;
#ifdef DOING_RC5PAD
extern int XP_SMIME_RC5PAD_64_16_128;
extern int XP_SMIME_RC5PAD_64_16_40;
extern int XP_SMIME_RC5PAD_64_16_64;
#endif
extern int XP_SSL2_DES_192_EDE3;
extern int XP_SSL2_DES_64;
extern int XP_SSL2_RC2_128;
extern int XP_SSL2_RC2_40;
extern int XP_SSL2_RC4_128;
extern int XP_SSL2_RC4_40;
extern int XP_SSL3_RSA_RC4_128_MD5;
extern int XP_SSL3_RSA_3DES_SHA;
extern int XP_SSL3_RSA_DES_SHA;
extern int XP_SSL3_RSA_RC4_40_MD5;
extern int XP_SSL3_RSA_RC2_40_MD5;
extern int XP_SSL3_RSA_NULL_MD5;
#ifdef FORTEZZA
extern int XP_SSL3_FORTEZZA_SHA;
extern int XP_SSL3_FORTEZZA_RC4_SHA;
extern int XP_SSL3_FORTEZZA_NULL_SHA;
#endif
extern int XP_CONFIG_NO_POLICY_STRINGS;
#ifndef PORT_Atol
#define PORT_Atol atol
#endif
typedef enum {
undefinedType = 0, /* make 0 invalid */
boolType,
longType,
stringType,
numValueTypes /* this many valueTypes */
} valueType;
typedef struct _algdesc {
char * policyDesc; /* name to identify this in policy module */
char * sectionName; /* section of the policy file */
char * prefName; /* associated preference name */
int * descNum; /* string ID, for looking up in pref UI */
PRBool allowed; /* does the policy module allow this */
PRBool preferred; /* is this alg preference enabled ? */
char * stringValue; /* value for string type items */
valueType type; /* what type of value is this item */
long longValue; /* value for "long" type items */
long protocolID; /* protocol specific identifier */
} policyAlgorithmDesc;
/*
* Well-defined indices for certain entries in table below
*/
#define ALGNDX_SW_VERSION 0
#define ALGNDX_COUNTRIES 1
#define ALGNDX_EXCLUDED 2
#define ALGNDX_KEYGEN_BITS 3
/* Global Policy Version pointer (yuck).
* Application can override default value before calling SECNAV_PolicyInit().
*/
const char * XP_PolicyVersion = "P2"; /* "P2" means second "official" policy */
static PRBool policyFileIsOK;
/*
* This is the policy table of possible algorithms for Dogbert
* Keep it sorted in decreasing ordfer of preference, within family.
*/
policyAlgorithmDesc algTable[] = {
/*
* General items
*/
{ /* which version of mozilla is the file intended for */
"Software-Version", "General",
NULL, 0,
PR_FALSE, PR_FALSE, NULL, stringType, 0L,
-1L
},
{
"Countries", "General",
NULL, 0,
PR_FALSE, PR_FALSE, NULL, stringType, 0L,
-1L
},
{
"Excluded-Countries", "General",
NULL, 0,
PR_FALSE, PR_FALSE, NULL, stringType, 0L,
-1L
},
{
"MAX-GEN-KEY-BITS", "KEYGEN",
"security.keygen.maxbits", 0,
PR_FALSE, PR_FALSE, NULL, longType, 512L,
-1L
},
/*
* PKCS12 algorithms and key lengths, in order of decreasing preference.
*/
{
"PKCS12-DES-EDE3", "PKCS12",
NULL, 0,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
PKCS12_DES_EDE3_168
},
{
"PKCS12-DES-56", "PKCS12",
NULL, 0,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
PKCS12_DES_56
},
{
"PKCS12-RC2-128", "PKCS12",
NULL, 0,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
PKCS12_RC2_CBC_128
},
{
"PKCS12-RC4-128", "PKCS12",
NULL, 0,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
PKCS12_RC4_128
},
{
"PKCS12-RC2-40", "PKCS12",
NULL, 0,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
PKCS12_RC2_CBC_40
},
{
"PKCS12-RC4-40", "PKCS12",
NULL, 0,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
PKCS12_RC4_40
},
/*
* SSL 2 algorithms
* in order of decreasing preference
*/
{
"SSL2-RC4-128-WITH-MD5", CIPHER_FAMILY_SSL2,
"security.ssl2.rc4_128", &XP_SSL2_RC4_128,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_EN_RC4_128_WITH_MD5
},
{
"SSL2-RC2-128-CBC-WITH-MD5", CIPHER_FAMILY_SSL2,
"security.ssl2.rc2_128", &XP_SSL2_RC2_128,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_EN_RC2_128_CBC_WITH_MD5
},
{
"SSL2-DES-168-EDE3-CBC-WITH-MD5", CIPHER_FAMILY_SSL2,
"security.ssl2.des_ede3_192", &XP_SSL2_DES_192_EDE3,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_EN_DES_192_EDE3_CBC_WITH_MD5
},
{
"SSL2-DES-56-CBC-WITH-MD5", CIPHER_FAMILY_SSL2,
"security.ssl2.des_64", &XP_SSL2_DES_64,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_EN_DES_64_CBC_WITH_MD5
},
{
"SSL2-RC4-128-EXPORT40-WITH-MD5", CIPHER_FAMILY_SSL2,
"security.ssl2.rc4_40", &XP_SSL2_RC4_40,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_EN_RC4_128_EXPORT40_WITH_MD5
},
{
"SSL2-RC2-128-CBC-EXPORT40-WITH-MD5", CIPHER_FAMILY_SSL2,
"security.ssl2.rc2_40", &XP_SSL2_RC2_40,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_EN_RC2_128_CBC_EXPORT40_WITH_MD5
},
/*
* SSL 3 algorithms
* in order of decreasing preference
*/
#ifdef FORTEZZA
{
"SSL3-FORTEZZA-DMS-WITH-FORTEZZA-CBC-SHA", CIPHER_FAMILY_SSL3,
"security.ssl3.fortezza_fortezza_sha", &XP_SSL3_FORTEZZA_SHA,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA
},
{
"SSL3-FORTEZZA-DMS-WITH-RC4-128-SHA", CIPHER_FAMILY_SSL3,
"security.ssl3.fortezza_rc4_sha", &XP_SSL3_FORTEZZA_RC4_SHA,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_FORTEZZA_DMS_WITH_RC4_128_SHA
},
#endif
{
"SSL3-RSA-WITH-RC4-128-MD5", CIPHER_FAMILY_SSL3,
"security.ssl3.rsa_rc4_128_md5", &XP_SSL3_RSA_RC4_128_MD5,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_RSA_WITH_RC4_128_MD5
},
{
"SSL3-RSA-WITH-3DES-EDE-CBC-SHA", CIPHER_FAMILY_SSL3,
"security.ssl3.rsa_des_ede3_sha", &XP_SSL3_RSA_3DES_SHA,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_RSA_WITH_3DES_EDE_CBC_SHA
},
{
"SSL3-RSA-WITH-DES-CBC-SHA", CIPHER_FAMILY_SSL3,
"security.ssl3.rsa_des_sha", &XP_SSL3_RSA_DES_SHA,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_RSA_WITH_DES_CBC_SHA
},
{
"SSL3-RSA-WITH-RC4-40-MD5", CIPHER_FAMILY_SSL3,
"security.ssl3.rsa_rc4_40_md5", &XP_SSL3_RSA_RC4_40_MD5,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_RSA_EXPORT_WITH_RC4_40_MD5
},
{
"SSL3-RSA-WITH-RC2-CBC-40-MD5", CIPHER_FAMILY_SSL3,
"security.ssl3.rsa_rc2_40_md5", &XP_SSL3_RSA_RC2_40_MD5,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SSL_RSA_EXPORT_WITH_RC2_CBC_40_MD5
},
#ifdef FORTEZZA
{
"SSL3-FORTEZZA-DMS-WITH-NULL-SHA", CIPHER_FAMILY_SSL3,
"security.ssl3.fortezza_null_sha", &XP_SSL3_FORTEZZA_NULL_SHA,
PR_TRUE, PR_FALSE, NULL, boolType, 0L,
SSL_FORTEZZA_DMS_WITH_NULL_SHA
},
#endif
{
"SSL3-RSA-WITH-NULL-MD5", CIPHER_FAMILY_SSL3,
"security.ssl3.rsa_null_md5", &XP_SSL3_RSA_NULL_MD5,
PR_TRUE, PR_FALSE, NULL, boolType, 0L,
SSL_RSA_WITH_NULL_MD5
},
/*
* SMIME bulk-cipher suites
* in order of decreasing preference
*/
{
"SMIME-DES-EDE3", CIPHER_FAMILY_SMIME,
"security.smime.des_ede3", &XP_SMIME_DES_EDE3,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SMIME_DES_EDE3_168
},
{
"SMIME-RC2-CBC-128", CIPHER_FAMILY_SMIME,
"security.smime.rc2_128", &XP_SMIME_RC2_CBC_128,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SMIME_RC2_CBC_128
},
#ifdef DOING_RC5PAD
{
"SMIME-RC5PAD-64-16-128", CIPHER_FAMILY_SMIME,
"security.smime.rc5.b64r16k128", &XP_SMIME_RC5PAD_64_16_128,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SMIME_RC5PAD_64_16_128
},
#endif
{
"SMIME-DES-CBC", CIPHER_FAMILY_SMIME,
"security.smime.des", &XP_SMIME_DES_CBC,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SMIME_DES_CBC_56
},
{
"SMIME-RC2-CBC-64", CIPHER_FAMILY_SMIME,
"security.smime.rc2_64", &XP_SMIME_RC2_CBC_64,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SMIME_RC2_CBC_64
},
#ifdef DOING_RC5PAD
{
"SMIME-RC5PAD-64-16-64", CIPHER_FAMILY_SMIME,
"security.smime.rc5.b64r16k64", &XP_SMIME_RC5PAD_64_16_64,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SMIME_RC5PAD_64_16_64
},
#endif
{
"SMIME-RC2-CBC-40", CIPHER_FAMILY_SMIME,
"security.smime.rc2_40", &XP_SMIME_RC2_CBC_40,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SMIME_RC2_CBC_40
}
#ifdef DOING_RC5PAD
,{
"SMIME-RC5PAD-64-16-40", CIPHER_FAMILY_SMIME,
"security.smime.rc5.b64r16k40", &XP_SMIME_RC5PAD_64_16_40,
PR_FALSE, PR_FALSE, NULL, boolType, 0L,
SMIME_RC5PAD_64_16_40
}
#endif
};
static const int tableSize = sizeof(algTable) / sizeof(policyAlgorithmDesc);
static unsigned char policyCaCertDERPubKey[] = {
0x30, 0x81, 0x9f, 0x30, 0x0d, 0x06, 0x09, 0x2a,
0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
0x05, 0x00, 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81,
0x89, 0x02, 0x81, 0x81, 0x00, 0xbc, 0x27, 0xb9,
0x4c, 0x56, 0x70, 0xec, 0xe7, 0xe9, 0x4d, 0x4d,
0x8a, 0x86, 0x9f, 0xf0, 0xa8, 0x3f, 0x12, 0xdb,
0x95, 0x1a, 0x20, 0x4e, 0xed, 0xcb, 0x14, 0x00,
0xe6, 0x45, 0xb1, 0xc1, 0x34, 0xee, 0x98, 0x38,
0xe2, 0xb3, 0x8a, 0xa5, 0x49, 0xa8, 0xf5, 0x86,
0x86, 0x72, 0xc6, 0x72, 0xbb, 0x18, 0xdd, 0x5d,
0xaa, 0xbc, 0x21, 0x6c, 0x9d, 0x82, 0xdd, 0xec,
0xfe, 0x21, 0xac, 0x3d, 0xa1, 0xf5, 0x99, 0xe7,
0x3a, 0x9d, 0xfd, 0x94, 0xd4, 0xb7, 0xb4, 0xc7,
0xbb, 0x5c, 0x38, 0xeb, 0xaa, 0x08, 0xda, 0x7b,
0x1d, 0xfd, 0xfe, 0x51, 0xcb, 0x20, 0x3c, 0xcf,
0x89, 0x1c, 0x9e, 0x2f, 0x6d, 0x22, 0x16, 0x5b,
0x53, 0xda, 0x65, 0xee, 0x19, 0x37, 0xf6, 0x73,
0xe4, 0x6a, 0x7a, 0x46, 0x12, 0x29, 0xbb, 0xd7,
0x2f, 0x57, 0xd3, 0x6d, 0x05, 0x2e, 0x22, 0xfe,
0xbc, 0x42, 0xb0, 0x34, 0x7f, 0x02, 0x03, 0x01,
0x00, 0x01
};
/* read in preferences associated with policy items */
void
SECNAV_PrefsRefresh(void)
{
policyAlgorithmDesc *desc = algTable;
int i;
ACQUIRE_WRITE_LOCK
/* read prefs for each boolean item in the table */
for ( i = tableSize; i > 0; i-- ) {
if ( desc->type == boolType && desc->allowed && desc->prefName ) {
int err;
XP_Bool prefval;
err = PREF_GetBoolPref(desc->prefName, &prefval);
PORT_Assert(0 <= err);
if (0 <= err)
desc->preferred = ( prefval ? PR_TRUE : PR_FALSE );
}
++desc;
}
RELEASE_WRITE_LOCK
}
/* Update preferences in local table, and in pref software table.
* Caller should also call PREF_SavePrefFile() after updating the prefs.
*/
void
SECNAV_PrefBoolUpdate(long protocolID, PRBool prefval)
{
policyAlgorithmDesc *desc = algTable;
int i;
int err = 0;
ACQUIRE_WRITE_LOCK
/* read prefs for each boolean item in the table */
for ( i = tableSize; i > 0; i-- ) {
if ( desc->protocolID == protocolID && desc->type == boolType ) {
err = PREF_SetBoolPref(desc->prefName, prefval);
PORT_Assert(0 <= err);
if (0 <= err)
desc->preferred = ( prefval ? PR_TRUE : PR_FALSE );
break;
}
++desc;
}
RELEASE_WRITE_LOCK
PORT_Assert(i > 0);
}
static void
parseMetaInfo( policyAlgorithmDesc *desc, char * value)
{
if (!value)
return;
switch ( desc->type ) {
case stringType:
/* if an old string exists, free it */
if ( desc->stringValue ) {
PORT_Free(desc->stringValue);
desc->stringValue = NULL;
}
/* copy the string value */
desc->stringValue = PORT_Strdup(value);
break;
case boolType:
if ('t' == *value || 'y' == *value) /* true, yes */
desc->allowed = PR_TRUE;
else if ('m' == *value || 'c' == *value) /* conditional, maybe */
desc->allowed = PR_MAYBE;
else /* if ('f' == *value || 'n' == *value) */ /* false, no */
desc->allowed = PR_FALSE;
break;
case longType:
desc->longValue = PORT_Atol(value);
break;
}
}
static void
processMetaInfo(ZIG * zig, policyAlgorithmDesc *desc)
{
unsigned long infoLen; /* pointless, since info is always a string */
void * info;
int result;
info = NULL;
result = SOB_get_metainfo(zig, NULL, desc->policyDesc, &info, &infoLen);
if (0 <= result) {
parseMetaInfo(desc, (char *)info);
}
if (info)
PORT_Free(info);
}
static PRBool
isPolicyCert( CERTCertificate * cert )
{
PRBool ret;
if (cert->derPublicKey.len != sizeof policyCaCertDERPubKey)
return PR_FALSE;
ret = (PRBool)(0 == memcmp( cert->derPublicKey.data, policyCaCertDERPubKey,
sizeof policyCaCertDERPubKey));
return ret;
}
/* copy up to "destLen"-1 "numeric characters" from src to dest,
* where "numeric characters" are 0-9 and "."
* If strspn() existed in NSPR, or on all platforms, I wouldn't need this...
*/
static void
numStrNCpy(char * dest, const char * src, int destLen)
{
static const char numChrs[] = { "0123456789." };
static char isNumeric[256];
const char * cp;
for (cp = numChrs; *cp != 0; ++cp)
isNumeric[(unsigned char)(*cp)] = 1;
while (--destLen > 0 ) {
char cc = *src++;
if (!isNumeric[(unsigned char)cc])
break;
*dest++ = cc;
}
*dest = 0;
}
/* returns true if policy file is wrong version for this user.
* returns false if policy file is OK for this user.
*/
static PRBool
wrongVersion( ZIG * zig )
{
char * stringValue;
const char *langString;
int slen;
char cmpString[100];
char verString[100];
static const char format[] = { "%s/%s%s [%s] " };
static const char en[] = { "en" };
/* if XP_AppLanguage does not contain a valid language string, use "en" */
langString = (XP_AppLanguage == NULL || *XP_AppLanguage == 0) ? en :
XP_AppLanguage;
/* get the "numeric" portion of the app version string into our buffer */
numStrNCpy(verString, XP_AppVersion, sizeof verString);
/* avoid buffer overflows */
slen = PORT_Strlen(XP_AppCodeName) +
PORT_Strlen(verString) +
PORT_Strlen(XP_PolicyVersion)+
PORT_Strlen(langString) + 6;
PORT_Assert( slen <= sizeof cmpString);
if (slen > sizeof cmpString)
return PR_TRUE; /* failed */
/* construct our local version string for comparison */
sprintf(cmpString, format, XP_AppCodeName, verString,
XP_PolicyVersion, langString);
/* now get the software version string from the policy file */
processMetaInfo( zig, &algTable[ALGNDX_SW_VERSION] );
stringValue = algTable[ALGNDX_SW_VERSION].stringValue;
if (!stringValue) /* MUST be present */
return PR_TRUE;
slen = PORT_Strlen(stringValue);
if (!slen)
return PR_TRUE; /* MUST NOT be empty */
/* they must match for as much of the string as is present in the file */
if (0 == PORT_Strncmp(stringValue, cmpString, slen))
return PR_FALSE; /* passed with flying colors */
return PR_TRUE; /* failed */
}
static void
readPolicyFile(char *filename)
{
ZIG * zig;
int err;
int i;
PRBool valid = PR_FALSE;
SOBITEM *item;
zig = SOB_new();
if (!zig) {
/* set some error ?? XXX */
return;
}
err = SOB_pass_archive( ZIG_F_GUESS, filename, "", zig);
if (err < 0)
goto fail; /* file doesn't exist */
if (zig->valid < 0)
goto fail; /* or fails signature test */
/* Verify that it is signed by netscape ! */
SOB_find(zig, "", ZIG_WALK);
while (SOB_find_next(zig, &item) >= 0) {
FINGERZIG * fing;
fing = (FINGERZIG *) item->data;
if (!fing || !fing->cert)
break; /* bogus cert chain, stop here */
valid = isPolicyCert( fing->cert );
if (valid)
break; /* found it, stop here */
}
if (!valid)
goto fail;
/* Validate the version number field before processing the rest. */
if (wrongVersion(zig))
goto fail;
/* parse name-value pairs that we care about */
for (i = 1; i < tableSize; ++i) {
processMetaInfo( zig, algTable + i);
}
policyFileIsOK = PR_TRUE;
fail:
(void)SOB_destroy(&zig);
}
/*
* Read in policy bits.
*/
void
SECNAV_PolicyInit(void)
{
policyAlgorithmDesc *desc = algTable;
char * name;
char* nativeName = WH_FileName("", xpCryptoPolicy);
char* urlName = XP_PlatformFileToURL(nativeName);
name = XP_STRDUP(urlName + XP_STRLEN("file://"));
if (urlName) XP_FREE(urlName);
if (nativeName) XP_FREE(nativeName);
ACQUIRE_WRITE_LOCK
if (name) {
readPolicyFile(name);
PORT_Free(name);
}
RELEASE_WRITE_LOCK
if (! policyFileIsOK) {
MWContext * context;
char * tmpMsg;
char * msg;
context = XP_FindSomeContext();
tmpMsg = XP_GetString(XP_CONFIG_NO_POLICY_STRINGS);
if (tmpMsg != NULL) {
msg = PORT_Strdup(tmpMsg);
if (msg != NULL) {
FE_Alert(context, msg);
PORT_Free(msg);
}
}
}
}
struct SECNAVPolicyFindStr {
int nextAlgDescIndex;
long protocolID[1]; /* actual count may be larger */
};
/*
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* Query functions
*/
SECNAVPolicyFind *
SECNAV_FindInit(const char * cipherFamily,
PRBool policyFilter, /* include iff allowed by policy */
PRBool preferenceFilter) /* include iff preference chosen */
{
SECNAVPolicyFind * snpf;
int famLen = PORT_Strlen(cipherFamily);
snpf = (SECNAVPolicyFind *)malloc(
(sizeof snpf) + tableSize * (sizeof snpf->protocolID[0]) );
if (snpf) {
int ndx;
int count = -1;
ACQUIRE_READ_LOCK
for (ndx = tableSize; --ndx >= 0; ) {
if (!PORT_Strncmp(algTable[ndx].sectionName, cipherFamily, famLen)) {
if (policyFilter && ! algTable[ndx].allowed)
continue;
if (preferenceFilter && ! algTable[ndx].preferred)
continue;
snpf->protocolID[++count] = algTable[ndx].protocolID;
}
}
snpf->nextAlgDescIndex = count;
RELEASE_READ_LOCK
}
return snpf;
}
long
SECNAV_FindNext(SECNAVPolicyFind * snpf)
{
if (!snpf || 0 > snpf->nextAlgDescIndex)
return -1L;
return snpf->protocolID[snpf->nextAlgDescIndex--];
}
void
SECNAV_FindEnd(SECNAVPolicyFind * snpf)
{
PORT_Free(snpf);
}
PRBool
SECNAV_AlgPreferred(long protocolID)
{
policyAlgorithmDesc *desc = algTable;
int count = tableSize;
PRBool ret = PR_FALSE;
while (count && protocolID != desc->protocolID) {
++desc;
--count;
}
if (count > 0)
ret = desc->preferred;
return ret;
}
PRBool
SECNAV_AlgAllowed(long protocolID)
{
policyAlgorithmDesc *desc = algTable;
int count = tableSize;
PRBool ret = PR_FALSE;
while (count && protocolID != desc->protocolID) {
++desc;
--count;
}
if (count > 0)
ret = desc->allowed;
return ret;
}
PRBool
SECNAV_AlgOKToDo(long protocolID)
{
policyAlgorithmDesc *desc = algTable;
int count = tableSize;
while (count && protocolID != desc->protocolID) {
++desc;
--count;
}
return (PRBool)(count > 0 && desc->preferred && desc->allowed);
}
long
SECNAV_getMaxKeyGenBits(void)
{
return algTable[ALGNDX_KEYGEN_BITS].longValue;
}
const char *
SECNAV_GetProtoName(long protocolID)
{
policyAlgorithmDesc *desc = algTable;
int count = tableSize;
const char * ret = NULL;
while (count && protocolID != desc->protocolID) {
++desc;
--count;
}
if (count > 0)
ret = (const char *)desc->prefName;
return ret;
}
const char *
SECNAV_GetProtoDesc(long protocolID)
{
policyAlgorithmDesc *desc = algTable;
int count = tableSize;
const char * ret = NULL;
while (count && protocolID != desc->protocolID) {
++desc;
--count;
}
if (count > 0)
ret = (const char *)XP_GetString(desc->descNum[0]);
return ret;
}