Fix for bug 265003: Add CRL generation to crlutil. Reviewed JP+

This commit is contained in:
alexei.volkov.bugs%sun.com 2005-04-12 02:24:17 +00:00
Родитель e4e03bd453
Коммит d2f6e314c7
17 изменённых файлов: 5212 добавлений и 133 удалений

Просмотреть файл

@ -110,13 +110,15 @@ GetGeneralName (PRArenaPool *arena)
PORT_SetError(SEC_ERROR_INPUT_LEN);
GEN_BREAK (SECFailure);
}
/*
* Should use ZAlloc instead of Alloc to avoid problem with garbage
* initialized pointers in CERT_CopyName
*/
if (intValue >= certOtherName || intValue <= certRegisterID) {
if (namesList == NULL) {
namesList = current = tail = (CERTGeneralName *) PORT_ArenaAlloc
(arena, sizeof (CERTGeneralName));
namesList = current = tail = PORT_ArenaZNew(arena, CERTGeneralName);
} else {
current = (CERTGeneralName *) PORT_ArenaAlloc(arena,
sizeof (CERTGeneralName));
current = PORT_ArenaZNew(arena, CERTGeneralName);
}
if (current == NULL) {
GEN_BREAK (SECFailure);
@ -356,53 +358,6 @@ AddCert(PK11SlotInfo *slot, CERTCertDBHandle *handle, char *name, char *trusts,
return rv;
}
/* This function belongs in libNSS somewhere. */
static SECOidTag
getSignatureOidTag(KeyType keyType, SECOidTag hashAlgTag)
{
SECOidTag sigTag = SEC_OID_UNKNOWN;
switch (keyType) {
case rsaKey:
switch (hashAlgTag) {
case SEC_OID_MD2:
sigTag = SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION; break;
case SEC_OID_UNKNOWN: /* default for RSA if not specified */
case SEC_OID_MD5:
sigTag = SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION; break;
case SEC_OID_SHA1:
sigTag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION; break;
case SEC_OID_SHA256:
sigTag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION; break;
case SEC_OID_SHA384:
sigTag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION; break;
case SEC_OID_SHA512:
sigTag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION; break;
default:
break;
}
break;
case dsaKey:
switch (hashAlgTag) {
case SEC_OID_UNKNOWN: /* default for DSA if not specified */
case SEC_OID_SHA1:
sigTag = SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST; break;
default:
break;
}
break;
#ifdef NSS_ENABLE_ECC
case ecKey:
/* XXX For now only ECDSA with SHA1 is supported */
sigTag = SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST;
break;
#endif /* NSS_ENABLE_ECC */
default:
break;
}
return sigTag;
}
static SECStatus
AddExtensions(void *, const char *, const char *, PRBool, PRBool, PRBool, PRBool,
PRBool, PRBool);
@ -472,7 +427,7 @@ CertReq(SECKEYPrivateKey *privk, SECKEYPublicKey *pubk, KeyType keyType,
}
/* Sign the request */
signAlgTag = getSignatureOidTag(keyType, hashAlgTag);
signAlgTag = SEC_GetSignatureAlgorithmOidTag(keyType, hashAlgTag);
if (signAlgTag == SEC_OID_UNKNOWN) {
SECU_PrintError(progName, "unknown Key or Hash type");
return SECFailure;
@ -1799,36 +1754,6 @@ AddDNSSubjectAlt(PRArenaPool *arena, CERTGeneralName **existingListp,
}
typedef SECStatus (* EXTEN_VALUE_ENCODER)
(PRArenaPool *extHandle, void *value, SECItem *encodedValue);
static SECStatus
EncodeAndAddExtensionValue(
PRArenaPool * arena,
void * extHandle,
void * value,
PRBool criticality,
int extenType,
EXTEN_VALUE_ENCODER EncodeValueFn)
{
SECItem encodedValue;
SECStatus rv;
encodedValue.data = NULL;
encodedValue.len = 0;
do {
rv = (*EncodeValueFn)(arena, value, &encodedValue);
if (rv != SECSuccess)
break;
rv = CERT_AddExtension
(extHandle, extenType, &encodedValue, criticality,PR_TRUE);
} while (0);
return (rv);
}
static SECStatus
AddBasicConstraint(void *extHandle)
{
@ -1898,7 +1823,7 @@ SignCert(CERTCertDBHandle *handle, CERTCertificate *cert, PRBool selfsign,
arena = cert->arena;
algID = getSignatureOidTag(privKey->keyType, hashAlgTag);
algID = SEC_GetSignatureAlgorithmOidTag(privKey->keyType, hashAlgTag);
if (algID == SEC_OID_UNKNOWN) {
fprintf(stderr, "Unknown key or hash type for issuer.");
goto done;
@ -1983,11 +1908,11 @@ AddAuthKeyID (void *extHandle)
puts ("Is this a critical extension [y/n]? ");
gets (buffer);
rv = EncodeAndAddExtensionValue
rv = SECU_EncodeAndAddExtensionValue
(arena, extHandle, authKeyID,
(buffer[0] == 'y' || buffer[0] == 'Y') ? PR_TRUE : PR_FALSE,
SEC_OID_X509_AUTH_KEY_ID,
(EXTEN_VALUE_ENCODER) CERT_EncodeAuthKeyID);
(EXTEN_EXT_VALUE_ENCODER) CERT_EncodeAuthKeyID);
if (rv)
break;
@ -2106,10 +2031,10 @@ AddCrlDistPoint(void *extHandle)
puts ("Is this a critical extension [y/n]? ");
gets (buffer);
rv = EncodeAndAddExtensionValue(arena, extHandle, crlDistPoints,
rv = SECU_EncodeAndAddExtensionValue(arena, extHandle, crlDistPoints,
(buffer[0] == 'Y' || buffer[0] == 'y') ? PR_TRUE : PR_FALSE,
SEC_OID_X509_CRL_DIST_POINTS,
(EXTEN_VALUE_ENCODER) CERT_EncodeCRLDistributionPoints);
(EXTEN_EXT_VALUE_ENCODER) CERT_EncodeCRLDistributionPoints);
}
if (arena)
PORT_FreeArena (arena, PR_FALSE);
@ -2514,21 +2439,8 @@ secuCommandFlag certutil_options[] =
/* -Z hash type */
if (certutil.options[opt_Hash].activated) {
char * arg = certutil.options[opt_Hash].arg;
if (!PL_strcmp(arg, "MD2")) {
hashAlgTag = SEC_OID_MD2;
} else if (!PL_strcmp(arg, "MD4")) {
hashAlgTag = SEC_OID_MD4;
} else if (!PL_strcmp(arg, "MD5")) {
hashAlgTag = SEC_OID_MD5;
} else if (!PL_strcmp(arg, "SHA1")) {
hashAlgTag = SEC_OID_SHA1;
} else if (!PL_strcmp(arg, "SHA256")) {
hashAlgTag = SEC_OID_SHA256;
} else if (!PL_strcmp(arg, "SHA384")) {
hashAlgTag = SEC_OID_SHA384;
} else if (!PL_strcmp(arg, "SHA512")) {
hashAlgTag = SEC_OID_SHA512;
} else {
hashAlgTag = SECU_StringToSignatureAlgTag(arg);
if (hashAlgTag == SEC_OID_UNKNOWN) {
PR_fprintf(PR_STDERR, "%s -Z: %s is not a recognized type.\n",
progName, arg);
return 255;

Просмотреть файл

@ -74,7 +74,12 @@ include $(CORE_DEPTH)/coreconf/rules.mk
# (7) Execute "local" rules. (OPTIONAL). #
#######################################################################
#
# crlgen_lex can be generated on linux by flex or solaris by lex
#
crlgen_lex:
${LEX} -t crlgen_lex_orig.l > crlgen_lex_fix.c
sed -f crlgen_lex_fix.sed < crlgen_lex_fix.c > crlgen_lex.c
rm -f crlgen_lex_fix.c
include ../platrules.mk

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,182 @@
#ifndef _CRLGEN_H_
#define _CRLGEN_H_
#include "prio.h"
#include "prprf.h"
#include "plhash.h"
#include "seccomon.h"
#include "certt.h"
#include "secoidt.h"
#define CRLGEN_UNKNOWN_CONTEXT 0
#define CRLGEN_ISSUER_CONTEXT 1
#define CRLGEN_UPDATE_CONTEXT 2
#define CRLGEN_NEXT_UPDATE_CONTEXT 3
#define CRLGEN_ADD_EXTENSION_CONTEXT 4
#define CRLGEN_ADD_CERT_CONTEXT 6
#define CRLGEN_CHANGE_RANGE_CONTEXT 7
#define CRLGEN_RM_CERT_CONTEXT 8
#define CRLGEN_TYPE_DATE 0
#define CRLGEN_TYPE_ZDATE 1
#define CRLGEN_TYPE_DIGIT 2
#define CRLGEN_TYPE_DIGIT_RANGE 3
#define CRLGEN_TYPE_OID 4
#define CRLGEN_TYPE_STRING 5
#define CRLGEN_TYPE_ID 6
typedef struct CRLGENGeneratorDataStr CRLGENGeneratorData;
typedef struct CRLGENEntryDataStr CRLGENEntryData;
typedef struct CRLGENExtensionEntryStr CRLGENExtensionEntry;
typedef struct CRLGENCertEntrySrt CRLGENCertEntry;
typedef struct CRLGENCrlFieldStr CRLGENCrlField;
typedef struct CRLGENEntriesSortedDataStr CRLGENEntriesSortedData;
/* Exported functions */
/* Used for initialization of extension handles for crl and certs
* extensions from existing CRL data then modifying existing CRL.*/
extern SECStatus CRLGEN_ExtHandleInit(CRLGENGeneratorData *crlGenData);
/* Commits all added entries and their's extensions into CRL. */
extern SECStatus CRLGEN_CommitExtensionsAndEntries(CRLGENGeneratorData *crlGenData);
/* Lunches the crl generation script parse */
extern SECStatus CRLGEN_StartCrlGen(CRLGENGeneratorData *crlGenData);
/* Closes crl generation script file and frees crlGenData */
extern void CRLGEN_FinalizeCrlGeneration(CRLGENGeneratorData *crlGenData);
/* Parser initialization function. Creates CRLGENGeneratorData structure
* for the current thread */
extern CRLGENGeneratorData* CRLGEN_InitCrlGeneration(CERTSignedCrl *newCrl,
PRFileDesc *src);
/* This lock is defined in crlgen_lex.c(derived from crlgen_lex.l).
* It controls access to invocation of yylex, allows to parse one
* script at a time */
extern void CRLGEN_InitCrlGenParserLock();
extern void CRLGEN_DestroyCrlGenParserLock();
/* The following function types are used to define functions for each of
* CRLGENExtensionEntryStr, CRLGENCertEntrySrt, CRLGENCrlFieldStr to
* provide functionality needed for these structures*/
typedef SECStatus updateCrlFn_t(CRLGENGeneratorData *crlGenData, void *str);
typedef SECStatus setNextDataFn_t(CRLGENGeneratorData *crlGenData, void *str,
void *data, unsigned short dtype);
typedef SECStatus createNewLangStructFn_t(CRLGENGeneratorData *crlGenData,
void *str, unsigned i);
/* Sets reports failure to parser if anything goes wrong */
extern void crlgen_setFailure(CRLGENGeneratorData *str, char *);
/* Collects data in to one of the current data structure that corresponds
* to the correct context type. This function gets called after each token
* is found for a particular line */
extern SECStatus crlgen_setNextData(CRLGENGeneratorData *str, void *data,
unsigned short dtype);
/* initiates crl update with collected data. This function is called at the
* end of each line */
extern SECStatus crlgen_updateCrl(CRLGENGeneratorData *str);
/* Creates new context structure depending on token that was parsed
* at the beginning of a line */
extern SECStatus crlgen_createNewLangStruct(CRLGENGeneratorData *str,
unsigned structType);
/* CRLGENExtensionEntry is used to store addext request data for either
* CRL extensions or CRL entry extensions. The differentiation between
* is based on order and type of extension been added.
* - extData : all data in request staring from name of the extension are
* in saved here.
* - nextUpdatedData: counter of elements added to extData
*/
struct CRLGENExtensionEntryStr {
char **extData;
int nextUpdatedData;
updateCrlFn_t *updateCrlFn;
setNextDataFn_t *setNextDataFn;
};
/* CRLGENCeryestEntry is used to store addcert request data
* - certId : certificate id or range of certificate with dash as a delimiter
* All certs from range will be inclusively added to crl
* - revocationTime: revocation time of cert(s)
*/
struct CRLGENCertEntrySrt {
char *certId;
char *revocationTime;
updateCrlFn_t *updateCrlFn;
setNextDataFn_t *setNextDataFn;
};
/* CRLGENCrlField is used to store crl fields record like update time, next
* update time, etc.
* - value: value of the parsed field data*/
struct CRLGENCrlFieldStr {
char *value;
updateCrlFn_t *updateCrlFn;
setNextDataFn_t *setNextDataFn;
};
/* Can not create entries extension until completely done with parsing.
* Therefore need to keep joined data
* - certId : serial number of certificate
* - extHandle: head pointer to a list of extensions that belong to
* entry
* - entry : CERTCrlEntry structure pointer*/
struct CRLGENEntryDataStr {
SECItem *certId;
void *extHandle;
CERTCrlEntry *entry;
};
/* Crl generator/parser main structure. Keeps info regarding current state of
* parser(context, status), parser helper functions pointers, parsed data and
* generated data.
* - contextId : current parsing context. Context in this parser environment
* defines what type of crl operations parser is going through
* in the current line of crl generation script.
* setting or new cert or an extension addition, etc.
* - createNewLangStructFn: pointer to top level function which creates
* data structures according contextId
* - setNextDataFn : pointer to top level function which sets new parsed data
* in temporary structure
* - updateCrlFn : pointer to top level function which triggers actual
* crl update functions with gathered data
* - union : data union create according to contextId
* - rangeFrom, rangeTo : holds last range in which certs was added
* - newCrl : pointer to CERTSignedCrl newly created crl
* - crlExtHandle : pointer to crl extension handle
* - entryDataHashTable: hash of CRLGENEntryData.
* key: cert serial number
* data: CRLGENEntryData pointer
* - parserStatus : current status of parser. Triggers parser to abort when
* set to SECFailure
* - src : PRFileDesc structure pointer of crl generator config file
* - parsedLineNum : currently parsing line. Keeping it to report errors */
struct CRLGENGeneratorDataStr {
unsigned short contextId;
CRLGENCrlField *crlField;
CRLGENCertEntry *certEntry;
CRLGENExtensionEntry *extensionEntry;
PRUint64 rangeFrom;
PRUint64 rangeTo;
CERTSignedCrl *signCrl;
void *crlExtHandle;
PLHashTable *entryDataHashTable;
PRFileDesc *src;
int parsedLineNum;
};
#endif /* _CRLGEN_H_ */

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,4 @@
/<unistd.h>/ {
i #ifndef _WIN32
a #endif
}

Просмотреть файл

@ -0,0 +1,177 @@
%{
#include "crlgen.h"
static SECStatus parserStatus = SECSuccess;
static CRLGENGeneratorData *parserData;
static PRFileDesc *src;
#define YY_INPUT(buf,result,max_size) \
if ( parserStatus != SECFailure) { \
if (((result = PR_Read(src, buf, max_size)) == 0) && \
ferror( yyin )) \
return SECFailure; \
} else { return SECFailure; }
%}
%a 5000
DIGIT [0-9]+
DIGIT_RANGE [0-9]+-[0-9]+
ID [a-zA-Z][a-zA-Z0-9]*
OID [0-9]+\.[\.0-9]+
DATE [0-9]{4}[01][0-9][0-3][0-9][0-2][0-9][0-6][0-9][0-6][0-9]
ZDATE [0-9]{4}[01][0-9][0-3][0-9][0-2][0-9][0-6][0-9][0-6][0-9]Z
N_SP_STRING [a-zA-Z0-9\:\|\.]+
%%
{ZDATE} {
parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_ZDATE);
if (parserStatus != SECSuccess)
return parserStatus;
}
{DIGIT} {
parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_DIGIT);
if (parserStatus != SECSuccess)
return parserStatus;
}
{DIGIT_RANGE} {
parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_DIGIT_RANGE);
if (parserStatus != SECSuccess)
return parserStatus;
}
{OID} {
parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_OID);
if (parserStatus != SECSuccess)
return parserStatus;
}
issuer {
parserStatus = crlgen_createNewLangStruct(parserData, CRLGEN_ISSUER_CONTEXT);
if (parserStatus != SECSuccess)
return parserStatus;
}
update {
parserStatus = crlgen_createNewLangStruct(parserData, CRLGEN_UPDATE_CONTEXT);
if (parserStatus != SECSuccess)
return parserStatus;
}
nextupdate {
parserStatus = crlgen_createNewLangStruct(parserData, CRLGEN_NEXT_UPDATE_CONTEXT);
if (parserStatus != SECSuccess)
return parserStatus;
}
range {
parserStatus = crlgen_createNewLangStruct(parserData, CRLGEN_CHANGE_RANGE_CONTEXT);
if (parserStatus != SECSuccess)
return parserStatus;
}
{ID} {
if (strcmp(yytext, "addcert") == 0) {
parserStatus = crlgen_createNewLangStruct(parserData,
CRLGEN_ADD_CERT_CONTEXT);
if (parserStatus != SECSuccess)
return parserStatus;
} else if (strcmp(yytext, "rmcert") == 0) {
parserStatus = crlgen_createNewLangStruct(parserData,
CRLGEN_RM_CERT_CONTEXT);
if (parserStatus != SECSuccess)
return parserStatus;
} else if (strcmp(yytext, "addext") == 0) {
parserStatus = crlgen_createNewLangStruct(parserData,
CRLGEN_ADD_EXTENSION_CONTEXT);
if (parserStatus != SECSuccess)
return parserStatus;
} else {
parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_ID);
if (parserStatus != SECSuccess)
return parserStatus;
}
}
"="
\"[^\"]* {
if (yytext[yyleng-1] == '\\') {
yymore();
} else {
register int c;
c = input();
if (c != '\"') {
printf( "Error: Line ending \" is missing: %c\n", c);
unput(c);
} else {
parserStatus = crlgen_setNextData(parserData, yytext + 1,
CRLGEN_TYPE_STRING);
if (parserStatus != SECSuccess)
return parserStatus;
}
}
}
{N_SP_STRING} {
parserStatus = crlgen_setNextData(parserData, yytext, CRLGEN_TYPE_STRING);
if (parserStatus != SECSuccess)
return parserStatus;
}
^#[^\n]* /* eat up one-line comments */ {}
[ \t]+ {}
(\n|\r\n) {
parserStatus = crlgen_updateCrl(parserData);
if (parserStatus != SECSuccess)
return parserStatus;
}
. {
fprintf(stderr, "Syntax error at line %d: unknown token %s\n",
parserData->parsedLineNum, yytext);
return SECFailure;
}
%%
#include "prlock.h"
static PRLock *parserInvocationLock;
void CRLGEN_InitCrlGenParserLock()
{
parserInvocationLock = PR_NewLock();
}
void CRLGEN_DestroyCrlGenParserLock()
{
PR_DestroyLock(parserInvocationLock);
}
SECStatus CRLGEN_StartCrlGen(CRLGENGeneratorData *parserCtlData)
{
SECStatus rv;
PR_Lock(parserInvocationLock);
parserStatus = SECSuccess;
parserData = parserCtlData;
src = parserCtlData->src;
rv = yylex();
PR_Unlock(parserInvocationLock);
return rv;
}
int yywrap() {return 1;}

Просмотреть файл

@ -46,9 +46,11 @@
#include "plgetopt.h"
#include "secutil.h"
#include "cert.h"
#include "certi.h"
#include "certdb.h"
#include "nss.h"
#include "pk11func.h"
#include "crlgen.h"
#define SEC_CERT_DB_EXISTS 0
#define SEC_CREATE_CERT_DB 1
@ -182,9 +184,9 @@ static SECStatus DeleteCRL (CERTCertDBHandle *certHandle, char *name, int type)
rv = SEC_DeletePermCRL (crl);
SEC_DestroyCrl(crl);
if (rv != SECSuccess) {
SECU_PrintError
(progName, "fail to delete the issuer %s's CRL from the perm database (reason: %s)",
name, SECU_Strerror(PORT_GetError()));
SECU_PrintError(progName, "fail to delete the issuer %s's CRL "
"from the perm database (reason: %s)",
name, SECU_Strerror(PORT_GetError()));
return SECFailure;
}
return (rv);
@ -247,16 +249,449 @@ SECStatus ImportCRL (CERTCertDBHandle *certHandle, char *url, int type,
}
return (rv);
}
static CERTCertificate*
FindSigningCert(CERTCertDBHandle *certHandle, CERTSignedCrl *signCrl,
char *certNickName)
{
CERTCertificate *cert = NULL, *certTemp = NULL;
SECStatus rv = SECFailure;
CERTAuthKeyID* authorityKeyID = NULL;
SECItem* subject = NULL;
PORT_Assert(certHandle != NULL);
if (!certHandle || (!signCrl && !certNickName)) {
SECU_PrintError(progName, "invalid args for function "
"FindSigningCert \n");
return NULL;
}
if (signCrl) {
#if 0
authorityKeyID = SECU_FindCRLAuthKeyIDExten(tmpArena, scrl);
#endif
subject = &signCrl->crl.derName;
} else {
certTemp = CERT_FindCertByNickname(certHandle, certNickName);
if (!certTemp) {
SECU_PrintError(progName, "could not find certificate \"%s\" "
"in database", certNickName);
goto loser;
}
subject = &certTemp->derSubject;
}
cert = SECU_FindCrlIssuer(certHandle, subject, authorityKeyID, PR_Now());
if (!cert) {
SECU_PrintError(progName, "could not find signing certificate "
"in database");
goto loser;
} else {
rv = SECSuccess;
}
loser:
if (certTemp)
CERT_DestroyCertificate(certTemp);
if (cert && rv != SECSuccess)
CERT_DestroyCertificate(cert);
return cert;
}
static CERTSignedCrl*
DuplicateModCrl(PRArenaPool *arena, CERTCertDBHandle *certHandle,
CERTCertificate **cert, char *certNickName,
PRFileDesc *inFile, PRInt32 decodeOptions,
PRInt32 importOptions)
{
SECItem crlDER;
CERTSignedCrl *signCrl = NULL;
CERTSignedCrl *modCrl = NULL;
PRArenaPool *modArena = NULL;
SECStatus rv = SECSuccess;
PORT_Assert(arena != NULL && certHandle != NULL &&
certNickName != NULL);
if (!arena || !certHandle || !certNickName) {
SECU_PrintError(progName, "DuplicateModCrl: invalid args\n");
return NULL;
}
modArena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if (!modArena) {
SECU_PrintError(progName, "fail to allocate memory\n");
return NULL;
}
if (inFile != NULL) {
rv = SECU_ReadDERFromFile(&crlDER, inFile, PR_FALSE);
if (rv != SECSuccess) {
SECU_PrintError(progName, "unable to read input file");
PORT_FreeArena(modArena, PR_FALSE);
goto loser;
}
decodeOptions |= CRL_DECODE_DONT_COPY_DER;
modCrl = CERT_DecodeDERCrlWithFlags(modArena, &crlDER, SEC_CRL_TYPE,
decodeOptions);
if (!modCrl) {
SECU_PrintError(progName, "fail to decode CRL");
goto loser;
}
if (0 == (importOptions & CRL_IMPORT_BYPASS_CHECKS)){
/* If caCert is a v2 certificate, make sure that it
* can be used for crl signing purpose */
*cert = FindSigningCert(certHandle, modCrl, NULL);
if (!*cert) {
goto loser;
}
rv = CERT_VerifySignedData(&modCrl->signatureWrap, *cert,
PR_Now(), NULL);
if (rv != SECSuccess) {
SECU_PrintError(progName, "fail to verify signed data\n");
goto loser;
}
}
} else {
modCrl = FindCRL(certHandle, certNickName, SEC_CRL_TYPE);
if (!modCrl) {
SECU_PrintError(progName, "fail to find crl %s in database\n",
certNickName);
goto loser;
}
}
signCrl = PORT_ArenaZNew(arena, CERTSignedCrl);
if (signCrl == NULL) {
SECU_PrintError(progName, "fail to allocate memory\n");
goto loser;
}
rv = SECU_CopyCRL(arena, &signCrl->crl, &modCrl->crl);
if (rv != SECSuccess) {
SECU_PrintError(progName, "unable to dublicate crl for "
"modification.");
goto loser;
}
signCrl->arena = arena;
loser:
SECITEM_FreeItem(&crlDER, PR_FALSE);
if (modCrl)
SEC_DestroyCrl(modCrl);
if (rv != SECSuccess && signCrl) {
SEC_DestroyCrl(signCrl);
signCrl = NULL;
}
return signCrl;
}
static CERTSignedCrl*
CreateNewCrl(PRArenaPool *arena, CERTCertDBHandle *certHandle,
CERTCertificate *cert)
{
CERTSignedCrl *signCrl = NULL;
void *dummy = NULL;
SECStatus rv;
void* mark = NULL;
/* if the CERTSignedCrl structure changes, this function will need to be
updated as well */
PORT_Assert(cert != NULL);
if (!cert || !arena) {
SECU_PrintError(progName, "invalid args for function "
"CreateNewCrl\n");
return NULL;
}
mark = PORT_ArenaMark(arena);
signCrl = PORT_ArenaZNew(arena, CERTSignedCrl);
if (signCrl == NULL) {
SECU_PrintError(progName, "fail to allocate memory\n");
return NULL;
}
dummy = SEC_ASN1EncodeInteger(arena, &signCrl->crl.version,
SEC_CRL_VERSION_2);
/* set crl->version */
if (!dummy) {
SECU_PrintError(progName, "fail to create crl version data "
"container\n");
goto loser;
}
/* copy SECItem name from cert */
rv = SECITEM_CopyItem(arena, &signCrl->crl.derName, &cert->derSubject);
if (rv != SECSuccess) {
SECU_PrintError(progName, "fail to duplicate der name from "
"certificate.\n");
goto loser;
}
/* copy CERTName name structure from cert issuer */
rv = CERT_CopyName (arena, &signCrl->crl.name, &cert->subject);
if (rv != SECSuccess) {
SECU_PrintError(progName, "fail to duplicate RD name from "
"certificate.\n");
goto loser;
}
rv = DER_EncodeTimeChoice(arena, &signCrl->crl.lastUpdate, PR_Now());
if (rv != SECSuccess) {
SECU_PrintError(progName, "fail to encode current time\n");
goto loser;
}
/* set fields */
signCrl->arena = arena;
signCrl->dbhandle = certHandle;
signCrl->crl.arena = arena;
return signCrl;
loser:
PORT_ArenaRelease(arena, mark);
return NULL;
}
static SECStatus
UpdateCrl(CERTSignedCrl *signCrl, PRFileDesc *inCrlInitFile)
{
CRLGENGeneratorData *crlGenData = NULL;
SECStatus rv;
PORT_Assert(signCrl != NULL && inCrlInitFile != NULL);
if (!signCrl || !inCrlInitFile) {
SECU_PrintError(progName, "invalid args for function "
"CreateNewCrl\n");
return SECFailure;
}
crlGenData = CRLGEN_InitCrlGeneration(signCrl, inCrlInitFile);
if (!crlGenData) {
SECU_PrintError(progName, "can not initialize parser structure.\n");
return SECFailure;
}
rv = CRLGEN_ExtHandleInit(crlGenData);
if (rv == SECFailure) {
SECU_PrintError(progName, "can not initialize entries handle.\n");
goto loser;
}
rv = CRLGEN_StartCrlGen(crlGenData);
if (rv != SECSuccess) {
SECU_PrintError(progName, "crl generation failed");
goto loser;
}
loser:
/* CommitExtensionsAndEntries is partially responsible for freeing
* up memory that was used for CRL generation. Should be called regardless
* of previouse call status, but only after initialization of
* crlGenData was done. It will commit all changes that was done before
* an error has occured.
*/
if (SECSuccess != CRLGEN_CommitExtensionsAndEntries(crlGenData)) {
SECU_PrintError(progName, "crl generation failed");
rv = SECFailure;
}
CRLGEN_FinalizeCrlGeneration(crlGenData);
return rv;
}
static SECStatus
SignAndStoreCrl(CERTSignedCrl *signCrl, CERTCertificate *cert,
char *outFileName, SECOidTag hashAlgTag, int ascii,
char *slotName, char *url, secuPWData *pwdata)
{
PK11SlotInfo *slot = NULL;
PRFileDesc *outFile = NULL;
SECStatus rv;
SignAndEncodeFuncExitStat errCode;
PORT_Assert(signCrl && (!ascii || outFileName));
if (!signCrl || (ascii && !outFileName)) {
SECU_PrintError(progName, "invalid args for function "
"SignAndStoreCrl\n");
return SECFailure;
}
if (!slotName || !PL_strcmp(slotName, "internal"))
slot = PK11_GetInternalKeySlot();
else
slot = PK11_FindSlotByName(slotName);
if (!slot) {
SECU_PrintError(progName, "can not find requested slot");
return SECFailure;
}
if (PK11_NeedLogin(slot)) {
rv = PK11_Authenticate(slot, PR_TRUE, pwdata);
if (rv != SECSuccess)
goto loser;
}
rv = SECU_SignAndEncodeCRL(cert, signCrl, hashAlgTag, &errCode);
if (rv != SECSuccess) {
char* errMsg = NULL;
switch (errCode)
{
case noKeyFound:
errMsg = "No private key found of signing cert";
break;
case noSignatureMatch:
errMsg = "Key and Algorithm OId are do not match";
break;
default:
case failToEncode:
errMsg = "Failed to encode crl structure";
break;
case failToSign:
errMsg = "Failed to sign crl structure";
break;
case noMem:
errMsg = "Can not allocate memory";
break;
}
SECU_PrintError(progName, "%s\n", errMsg);
goto loser;
}
if (outFileName) {
outFile = PR_Open(outFileName, PR_WRONLY|PR_CREATE_FILE, PR_IRUSR | PR_IWUSR);
if (!outFile) {
SECU_PrintError(progName, "unable to open \"%s\" for writing\n",
outFileName);
goto loser;
}
}
rv = SECU_StoreCRL(slot, signCrl->derCrl, outFile, ascii, url);
if (rv != SECSuccess) {
SECU_PrintError(progName, "fail to save CRL\n");
}
loser:
if (outFile)
PR_Close(outFile);
if (slot)
PK11_FreeSlot(slot);
return rv;
}
static SECStatus
GenerateCRL (CERTCertDBHandle *certHandle, char *certNickName,
PRFileDesc *inCrlInitFile, PRFileDesc *inFile,
char *outFileName, int ascii, char *slotName,
PRInt32 importOptions, char *alg, PRBool quiet,
PRInt32 decodeOptions, char *url, secuPWData *pwdata,
int modifyFlag)
{
CERTCertificate *cert = NULL;
CERTSignedCrl *signCrl = NULL;
PRArenaPool *arena = NULL;
SECStatus rv;
SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
if (alg) {
hashAlgTag = SECU_StringToSignatureAlgTag(alg);
if (hashAlgTag == SEC_OID_UNKNOWN) {
SECU_PrintError(progName, "%s -Z: %s is not a recognized type.\n",
progName, alg);
return SECFailure;
}
} else {
hashAlgTag = SEC_OID_UNKNOWN;
}
arena = PORT_NewArena (SEC_ASN1_DEFAULT_ARENA_SIZE);
if (!arena) {
SECU_PrintError(progName, "fail to allocate memory\n");
return SECFailure;
}
if (modifyFlag == PR_TRUE) {
signCrl = DuplicateModCrl(arena, certHandle, &cert, certNickName,
inFile, decodeOptions, importOptions);
if (signCrl == NULL) {
goto loser;
}
}
if (!cert) {
cert = FindSigningCert(certHandle, signCrl, certNickName);
if (cert == NULL) {
goto loser;
}
}
if (!signCrl) {
if (modifyFlag == PR_TRUE) {
if (!outFileName) {
int len = strlen(certNickName) + 5;
outFileName = PORT_ArenaAlloc(arena, len);
PR_snprintf(outFileName, len, "%s.crl", certNickName);
}
SECU_PrintError(progName, "Will try to generate crl. "
"It will be saved in file: %s",
outFileName);
}
signCrl = CreateNewCrl(arena, certHandle, cert);
if (!signCrl)
goto loser;
}
rv = UpdateCrl(signCrl, inCrlInitFile);
if (rv != SECSuccess) {
goto loser;
}
rv = SignAndStoreCrl(signCrl, cert, outFileName, hashAlgTag, ascii,
slotName, url, pwdata);
if (rv != SECSuccess) {
goto loser;
}
if (signCrl && !quiet) {
SECU_PrintCRLInfo (stdout, &signCrl->crl, "CRL Info:\n", 0);
}
loser:
if (arena && (!signCrl || !signCrl->arena))
PORT_FreeArena (arena, PR_FALSE);
if (signCrl)
SEC_DestroyCrl (signCrl);
if (cert)
CERT_DestroyCertificate (cert);
return (rv);
}
static void Usage(char *progName)
{
fprintf(stderr,
"Usage: %s -L [-n nickname] [-d keydir] [-P dbprefix] [-t crlType]\n"
" %s -D -n nickname [-d keydir] [-P dbprefix]\n"
" %s -I -i crl -t crlType [-u url] [-d keydir] [-P dbprefix] [-B]\n"
" %s -I -i crl -t crlType [-u url] [-d keydir] [-P dbprefix] [-B] "
"[-p pwd-file] -w [pwd-string]\n"
" %s -E -t crlType [-d keydir] [-P dbprefix]\n"
" %s -T\n", progName, progName, progName, progName, progName);
" %s -T\n"
" %s -G|-M -c crl-init-file -n nickname [-i crl] [-u url] "
"[-d keydir] [-P dbprefix] [-Z alg] ] [-p pwd-file] -w [pwd-string] "
"[-a] [-B]\n",
progName, progName, progName, progName, progName, progName);
fprintf (stderr, "%-15s List CRL\n", "-L");
fprintf(stderr, "%-20s Specify the nickname of the CA certificate\n",
@ -300,6 +735,28 @@ static void Usage(char *progName)
fprintf(stderr, "\n%-20s Bypass CA certificate checks.\n", "-B");
fprintf(stderr, "\n%-20s Partial decode for faster operation.\n", "-p");
fprintf(stderr, "%-20s Repeat the operation.\n", "-r <iterations>");
fprintf(stderr, "\n%-15s Create CRL\n", "-G");
fprintf(stderr, "%-15s Modify CRL\n", "-M");
fprintf(stderr, "%-20s Specify crl initialization file\n",
"-c crl-conf-file");
fprintf(stderr, "%-20s Specify the nickname of the CA certificate\n",
"-n nickname");
fprintf(stderr, "%-20s Specify the file which contains the CRL to import\n",
"-i crl");
fprintf(stderr, "%-20s Specify a CRL output file\n",
"-o crl-output-file");
fprintf(stderr, "%-20s Specify to use base64 encoded CRL output format\n",
"-a");
fprintf(stderr, "%-20s Key database directory (default is ~/.netscape)\n",
"-d keydir");
fprintf(stderr, "%-20s Provide path to a default pwd file\n",
"-f pwd-file");
fprintf(stderr, "%-20s Provide db password in command line\n",
"-w pwd-string");
fprintf(stderr, "%-20s Cert & Key database prefix (default is \"\")\n",
"-P dbprefix");
fprintf(stderr, "%-20s Specify the url.\n", "-u url");
fprintf(stderr, "\n%-20s Bypass CA certificate checks.\n", "-B");
exit(-1);
}
@ -310,6 +767,9 @@ int main(int argc, char **argv)
CERTCertDBHandle *certHandle;
FILE *certFile;
PRFileDesc *inFile;
PRFileDesc *inCrlInitFile = NULL;
int generateCRL;
int modifyCRL;
int listCRL;
int importCRL;
int deleteCRL;
@ -317,22 +777,29 @@ int main(int argc, char **argv)
char *nickName;
char *url;
char *dbPrefix = "";
char *alg = NULL;
char *outFile = NULL;
char *slotName = NULL;
int ascii = 0;
int crlType;
PLOptState *optstate;
PLOptStatus status;
SECStatus secstatus;
PRInt32 decodeOptions = CRL_DECODE_DEFAULT_OPTIONS;
PRInt32 importOptions = CRL_IMPORT_DEFAULT_OPTIONS;
PRBool quiet = PR_FALSE;
PRBool test = PR_FALSE;
PRBool erase = PR_FALSE;
PRInt32 i = 0;
PRInt32 iterations = 1;
secuPWData pwdata = { PW_NONE, 0 };
progName = strrchr(argv[0], '/');
progName = progName ? progName+1 : argv[0];
rv = 0;
deleteCRL = importCRL = listCRL = 0;
deleteCRL = importCRL = listCRL = generateCRL = modifyCRL = 0;
certFile = NULL;
inFile = NULL;
nickName = url = NULL;
@ -342,7 +809,7 @@ int main(int argc, char **argv)
/*
* Parse command line arguments
*/
optstate = PL_CreateOptState(argc, argv, "BCDILP:d:i:n:pt:u:TEr:");
optstate = PL_CreateOptState(argc, argv, "sqBCDGILMTEP:f:d:i:h:n:p:t:u:r:aZ:o:c:");
while ((status = PL_GetNextOpt(optstate)) == PL_OPT_OK) {
switch (optstate->option) {
case '?':
@ -361,9 +828,13 @@ int main(int argc, char **argv)
importOptions |= CRL_IMPORT_BYPASS_CHECKS;
break;
case 'C':
listCRL = 1;
break;
case 'G':
generateCRL = 1;
break;
case 'M':
modifyCRL = 1;
break;
case 'D':
deleteCRL = 1;
@ -373,22 +844,50 @@ int main(int argc, char **argv)
importCRL = 1;
break;
case 'C':
case 'L':
listCRL = 1;
break;
case 'P':
dbPrefix = strdup(optstate->value);
break;
dbPrefix = strdup(optstate->value);
break;
case 'Z':
alg = strdup(optstate->value);
break;
case 'a':
ascii = 1;
break;
case 'c':
inCrlInitFile = PR_Open(optstate->value, PR_RDONLY, 0);
if (!inCrlInitFile) {
PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading\n",
progName, optstate->value);
PL_DestroyOptState(optstate);
return -1;
}
break;
case 'd':
SECU_ConfigDirectory(optstate->value);
break;
SECU_ConfigDirectory(optstate->value);
break;
case 'f':
pwdata.source = PW_FROMFILE;
pwdata.data = strdup(optstate->value);
break;
case 'h':
slotName = strdup(optstate->value);
break;
case 'i':
inFile = PR_Open(optstate->value, PR_RDONLY, 0);
if (!inFile) {
fprintf(stderr, "%s: unable to open \"%s\" for reading\n",
PR_fprintf(PR_STDERR, "%s: unable to open \"%s\" for reading\n",
progName, optstate->value);
PL_DestroyOptState(optstate);
return -1;
@ -399,6 +898,10 @@ int main(int argc, char **argv)
nickName = strdup(optstate->value);
break;
case 'o':
outFile = strdup(optstate->value);
break;
case 'p':
decodeOptions |= CRL_DECODE_SKIP_ENTRIES;
break;
@ -416,25 +919,41 @@ int main(int argc, char **argv)
type = strdup(optstate->value);
crlType = atoi (type);
if (crlType != SEC_CRL_TYPE && crlType != SEC_KRL_TYPE) {
fprintf(stderr, "%s: invalid crl type\n", progName);
PR_fprintf(PR_STDERR, "%s: invalid crl type\n", progName);
PL_DestroyOptState(optstate);
return -1;
}
break;
case 'q':
quiet = PR_TRUE;
break;
case 'w':
pwdata.source = PW_PLAINTEXT;
pwdata.data = strdup(optstate->value);
break;
case 'u':
url = strdup(optstate->value);
break;
}
}
}
PL_DestroyOptState(optstate);
if (deleteCRL && !nickName) Usage (progName);
if (!(listCRL || deleteCRL || importCRL || test || erase)) Usage (progName);
if (importCRL && !inFile) Usage (progName);
if ((generateCRL && !nickName) ||
(modifyCRL && !inFile && !nickName)) Usage (progName);
if (!(listCRL || deleteCRL || importCRL || generateCRL ||
modifyCRL || test || erase)) Usage (progName);
PR_Init( PR_SYSTEM_THREAD, PR_PRIORITY_NORMAL, 1);
PK11_SetPasswordFunc(SECU_GetModulePassword);
secstatus = NSS_Initialize(SECU_ConfigDirectory(NULL), dbPrefix, dbPrefix,
"secmod.db", 0);
if (secstatus != SECSuccess) {
@ -451,6 +970,8 @@ int main(int argc, char **argv)
return (-1);
}
CRLGEN_InitCrlGenParserLock();
for (i=0; i<iterations; i++) {
/* Read in the private key info */
if (deleteCRL)
@ -461,6 +982,14 @@ int main(int argc, char **argv)
else if (importCRL) {
rv = ImportCRL (certHandle, url, crlType, inFile, importOptions,
decodeOptions);
} else if (generateCRL || modifyCRL) {
if (!inCrlInitFile)
inCrlInitFile = PR_STDIN;
rv = GenerateCRL (certHandle, nickName, inCrlInitFile,
inFile, outFile, ascii, slotName,
importOptions, alg, quiet,
decodeOptions, url, &pwdata,
modifyCRL);
}
else if (erase) {
/* list and delete all CRLs */
@ -480,6 +1009,9 @@ int main(int argc, char **argv)
}
#endif
}
CRLGEN_DestroyCrlGenParserLock();
if (NSS_Shutdown() != SECSuccess) {
rv = SECFailure;
}

Просмотреть файл

@ -48,7 +48,7 @@ REQUIRES = seccmd dbm
DEFINES = -DNSPR20
CSRCS = crlutil.c
CSRCS = crlgen_lex.c crlgen.c crlutil.c
# this has to be different for NT and UNIX.
# PROGRAM = ./$(OBJDIR)/crlutil.exe

Просмотреть файл

@ -48,6 +48,7 @@
#include "prenv.h"
#include "prnetdb.h"
#include "cryptohi.h"
#include "secutil.h"
#include "secpkcs7.h"
#include <stdarg.h>
@ -3346,3 +3347,333 @@ SECU_printCertProblems(FILE *outfile, CERTCertDBHandle *handle,
}
PORT_SetError(err); /* restore original error code */
}
SECOidTag
SECU_StringToSignatureAlgTag(const char *alg)
{
SECOidTag hashAlgTag = SEC_OID_UNKNOWN;
if (alg) {
if (!PL_strcmp(alg, "MD2")) {
hashAlgTag = SEC_OID_MD2;
} else if (!PL_strcmp(alg, "MD4")) {
hashAlgTag = SEC_OID_MD4;
} else if (!PL_strcmp(alg, "MD5")) {
hashAlgTag = SEC_OID_MD5;
} else if (!PL_strcmp(alg, "SHA1")) {
hashAlgTag = SEC_OID_SHA1;
} else if (!PL_strcmp(alg, "SHA256")) {
hashAlgTag = SEC_OID_SHA256;
} else if (!PL_strcmp(alg, "SHA384")) {
hashAlgTag = SEC_OID_SHA384;
} else if (!PL_strcmp(alg, "SHA512")) {
hashAlgTag = SEC_OID_SHA512;
}
}
return hashAlgTag;
}
SECStatus
SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl, PRFileDesc *outFile,
const PRBool ascii, char *url)
{
PORT_Assert(derCrl != NULL);
if (!derCrl) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
if (outFile != NULL) {
if (ascii) {
PR_fprintf(outFile, "%s\n%s\n%s\n", NS_CRL_HEADER,
BTOA_DataToAscii(derCrl->data, derCrl->len),
NS_CRL_TRAILER);
} else {
if (PR_Write(outFile, derCrl->data, derCrl->len) != derCrl->len) {
return SECFailure;
}
}
}
if (slot) {
CERTSignedCrl *newCrl = PK11_ImportCRL(slot, derCrl, url,
SEC_CRL_TYPE, NULL, 0, NULL, 0);
if (newCrl != NULL) {
SEC_DestroyCrl(newCrl);
return SECSuccess;
}
return SECFailure;
}
if (!outFile && !slot) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
return SECSuccess;
}
SECStatus
SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode)
{
SECItem der;
SECKEYPrivateKey *caPrivateKey = NULL;
SECStatus rv;
PRArenaPool *arena;
SECOidTag algID;
void *dummy;
PORT_Assert(issuer != NULL && signCrl != NULL);
if (!issuer || !signCrl) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
arena = signCrl->arena;
caPrivateKey = PK11_FindKeyByAnyCert(issuer, NULL);
if (caPrivateKey == NULL) {
*resCode = noKeyFound;
return SECFailure;
}
algID = SEC_GetSignatureAlgorithmOidTag(caPrivateKey->keyType, hashAlgTag);
if (algID == SEC_OID_UNKNOWN) {
*resCode = noSignatureMatch;
rv = SECFailure;
goto done;
}
if (!signCrl->crl.signatureAlg.parameters.data) {
rv = SECOID_SetAlgorithmID(arena, &signCrl->crl.signatureAlg, algID, 0);
if (rv != SECSuccess) {
*resCode = failToEncode;
goto done;
}
}
der.len = 0;
der.data = NULL;
dummy = SEC_ASN1EncodeItem(arena, &der, &signCrl->crl,
SEC_ASN1_GET(CERT_CrlTemplate));
if (!dummy) {
*resCode = failToEncode;
rv = SECFailure;
goto done;
}
rv = SECU_DerSignDataCRL(arena, &signCrl->signatureWrap,
der.data, der.len, caPrivateKey, algID);
if (rv != SECSuccess) {
*resCode = failToSign;
goto done;
}
signCrl->derCrl = PORT_ArenaZNew(arena, SECItem);
if (signCrl->derCrl == NULL) {
*resCode = noMem;
PORT_SetError(SEC_ERROR_NO_MEMORY);
rv = SECFailure;
goto done;
}
signCrl->derCrl->len = 0;
signCrl->derCrl->data = NULL;
dummy = SEC_ASN1EncodeItem (arena, signCrl->derCrl, signCrl,
SEC_ASN1_GET(CERT_SignedCrlTemplate));
if (!dummy) {
*resCode = failToEncode;
rv = SECFailure;
goto done;
}
done:
if (caPrivateKey) {
SECKEY_DestroyPrivateKey(caPrivateKey);
}
return rv;
}
SECStatus
SECU_CopyCRL(PRArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl)
{
void *dummy;
SECStatus rv = SECSuccess;
SECItem der;
PORT_Assert(destArena && srcCrl && destCrl);
if (!destArena || !srcCrl || !destCrl) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
der.len = 0;
der.data = NULL;
dummy = SEC_ASN1EncodeItem (destArena, &der, srcCrl,
SEC_ASN1_GET(CERT_CrlTemplate));
if (!dummy) {
return SECFailure;
}
rv = SEC_QuickDERDecodeItem(destArena, destCrl,
SEC_ASN1_GET(CERT_CrlTemplate), &der);
if (rv != SECSuccess) {
return SECFailure;
}
destCrl->arena = destArena;
return rv;
}
SECStatus
SECU_DerSignDataCRL(PRArenaPool *arena, CERTSignedData *sd,
unsigned char *buf, int len, SECKEYPrivateKey *pk,
SECOidTag algID)
{
SECItem it;
SECStatus rv;
it.data = 0;
/* XXX We should probably have some asserts here to make sure the key type
* and algID match
*/
/* 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 = buf;
sd->data.len = len;
sd->signature.data = it.data;
sd->signature.len = it.len << 3; /* convert to bit string */
if (!sd->signatureAlgorithm.parameters.data) {
rv = SECOID_SetAlgorithmID(arena, &sd->signatureAlgorithm, algID, 0);
if (rv) goto loser;
}
return rv;
loser:
PORT_Free(it.data);
return rv;
}
#if 0
/* we need access to the private function cert_FindExtension for this code to work */
CERTAuthKeyID *
SECU_FindCRLAuthKeyIDExten (PRArenaPool *arena, CERTSignedCrl *scrl)
{
SECItem encodedExtenValue;
SECStatus rv;
CERTAuthKeyID *ret;
CERTCrl* crl;
if (!scrl) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
crl = &scrl->crl;
encodedExtenValue.data = NULL;
encodedExtenValue.len = 0;
rv = cert_FindExtension(crl->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);
}
#endif
/*
* Find the issuer of a Crl. Use the authorityKeyID if it exists.
*/
CERTCertificate *
SECU_FindCrlIssuer(CERTCertDBHandle *dbhandle, SECItem* subject,
CERTAuthKeyID* authorityKeyID, PRTime validTime)
{
CERTCertListNode *node;
CERTCertificate * issuerCert = NULL, *cert = NULL;
CERTCertList *certList = NULL;
SECStatus rv = SECFailure;
if (!subject) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return NULL;
}
certList =
CERT_CreateSubjectCertList(NULL, dbhandle, subject,
validTime, PR_TRUE);
if (!certList) {
goto loser;
}
node = CERT_LIST_HEAD(certList);
/* XXX and authoritykeyid in the future */
while ( ! CERT_LIST_END(node, certList) ) {
cert = node->cert;
if (CERT_CheckCertUsage(cert, KU_CRL_SIGN) != SECSuccess ||
!cert->trust) {
continue;
}
/* select the first (newest) user cert */
if (CERT_IsUserCert(cert)) {
rv = SECSuccess;
goto success;
}
}
success:
if (rv == SECSuccess) {
issuerCert = CERT_DupCertificate(cert);
}
loser:
if (certList) {
CERT_DestroyCertList(certList);
}
return(issuerCert);
}
/* Encodes and adds extensions to the CRL or CRL entries. */
SECStatus
SECU_EncodeAndAddExtensionValue(PRArenaPool *arena, void *extHandle,
void *value, PRBool criticality, int extenType,
EXTEN_EXT_VALUE_ENCODER EncodeValueFn)
{
SECItem encodedValue;
SECStatus rv;
encodedValue.data = NULL;
encodedValue.len = 0;
do {
rv = (*EncodeValueFn)(arena, value, &encodedValue);
if (rv != SECSuccess)
break;
rv = CERT_AddExtension(extHandle, extenType, &encodedValue,
criticality, PR_TRUE);
if (rv != SECSuccess)
break;
} while (0);
return (rv);
}

Просмотреть файл

@ -59,6 +59,9 @@
#define NS_CERT_HEADER "-----BEGIN CERTIFICATE-----"
#define NS_CERT_TRAILER "-----END CERTIFICATE-----"
#define NS_CRL_HEADER "-----BEGIN CRL-----"
#define NS_CRL_TRAILER "-----END CRL-----"
/* From libsec/pcertdb.c --- it's not declared in sec.h */
extern SECStatus SEC_AddPermCertificate(CERTCertDBHandle *handle,
SECItem *derCert, char *nickname, CERTCertTrust *trust);
@ -299,6 +302,74 @@ extern void SECU_PrintPRandOSError(char *progName);
extern SECStatus SECU_RegisterDynamicOids(void);
/* Identifies hash algorithm tag by its string representation. */
extern SECOidTag SECU_StringToSignatureAlgTag(const char *alg);
/* Store CRL in output file or pk11 db. Also
* encodes with base64 and exports to file if ascii flag is set
* and file is not NULL. */
extern SECStatus SECU_StoreCRL(PK11SlotInfo *slot, SECItem *derCrl,
PRFileDesc *outFile, int ascii, char *url);
/*
** DER sign a single block of data using private key encryption and the
** MD5 hashing algorithm. This routine first computes a digital signature
** using SEC_SignData, then wraps it with an CERTSignedData and then der
** encodes the result.
** "arena" is the memory arena to use to allocate data from
** "sd" returned CERTSignedData
** "result" the final der encoded data (memory is allocated)
** "buf" the input data to sign
** "len" the amount of data to sign
** "pk" the private key to encrypt with
*/
extern SECStatus SECU_DerSignDataCRL(PRArenaPool *arena, CERTSignedData *sd,
unsigned char *buf, int len,
SECKEYPrivateKey *pk, SECOidTag algID);
typedef enum {
noKeyFound = 1,
noSignatureMatch = 2,
failToEncode = 3,
failToSign = 4,
noMem = 5
} SignAndEncodeFuncExitStat;
extern SECStatus
SECU_SignAndEncodeCRL(CERTCertificate *issuer, CERTSignedCrl *signCrl,
SECOidTag hashAlgTag, SignAndEncodeFuncExitStat *resCode);
extern SECStatus
SECU_CopyCRL(PRArenaPool *destArena, CERTCrl *destCrl, CERTCrl *srcCrl);
/*
** Finds the crl Authority Key Id extension. Returns NULL if no such extension
** was found.
*/
CERTAuthKeyID *
SECU_FindCRLAuthKeyIDExten (PRArenaPool *arena, CERTSignedCrl *crl);
/*
* Find the issuer of a crl. Cert usage should be checked before signing a crl.
*/
CERTCertificate *
SECU_FindCrlIssuer(CERTCertDBHandle *dbHandle, SECItem* subject,
CERTAuthKeyID* id, PRTime validTime);
/* call back function used in encoding of an extension. Called from
* SECU_EncodeAndAddExtensionValue */
typedef SECStatus (* EXTEN_EXT_VALUE_ENCODER) (PRArenaPool *extHandleArena,
void *value, SECItem *encodedValue);
/* Encodes and adds extensions to the CRL or CRL entries. */
SECStatus
SECU_EncodeAndAddExtensionValue(PRArenaPool *arena, void *extHandle,
void *value, PRBool criticality, int extenType,
EXTEN_EXT_VALUE_ENCODER EncodeValueFn);
/*
*
* Utilities for parsing security tools command lines

Просмотреть файл

@ -36,7 +36,7 @@
/*
* certt.h - public data structures for the certificate library
*
* $Id: certt.h,v 1.29 2005/03/05 08:03:03 nelsonb%netscape.com Exp $
* $Id: certt.h,v 1.30 2005/04/12 02:24:15 alexei.volkov.bugs%sun.com Exp $
*/
#ifndef _CERTT_H_
#define _CERTT_H_
@ -843,6 +843,7 @@ extern const SEC_ASN1Template CERT_SetOfSignedCrlTemplate[];
extern const SEC_ASN1Template CERT_RDNTemplate[];
extern const SEC_ASN1Template CERT_SignedDataTemplate[];
extern const SEC_ASN1Template CERT_CrlTemplate[];
extern const SEC_ASN1Template CERT_SignedCrlTemplate[];
/*
** XXX should the attribute stuff be centralized for all of ns/security?
@ -863,6 +864,7 @@ SEC_ASN1_CHOOSER_DECLARE(CERT_SetOfSignedCrlTemplate)
SEC_ASN1_CHOOSER_DECLARE(CERT_SignedDataTemplate)
SEC_ASN1_CHOOSER_DECLARE(CERT_SubjectPublicKeyInfoTemplate)
SEC_ASN1_CHOOSER_DECLARE(SEC_SignedCertificateTemplate)
SEC_ASN1_CHOOSER_DECLARE(CERT_SignedCrlTemplate)
SEC_ASN1_CHOOSER_DECLARE(CERT_TimeChoiceTemplate)
SEC_END_PROTOS

Просмотреть файл

@ -37,7 +37,7 @@
/*
* Moved from secpkcs7.c
*
* $Id: crl.c,v 1.46 2005/03/03 04:07:26 julien.pierre.bugs%sun.com Exp $
* $Id: crl.c,v 1.47 2005/04/12 02:24:15 alexei.volkov.bugs%sun.com Exp $
*/
#include "cert.h"
@ -231,7 +231,7 @@ const SEC_ASN1Template CERT_CrlTemplateEntriesOnly[] = {
{ 0 }
};
static const SEC_ASN1Template cert_SignedCrlTemplate[] = {
const SEC_ASN1Template CERT_SignedCrlTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(CERTSignedCrl) },
{ SEC_ASN1_SAVE,
@ -264,7 +264,7 @@ static const SEC_ASN1Template cert_SignedCrlTemplateNoEntries[] = {
};
const SEC_ASN1Template CERT_SetOfSignedCrlTemplate[] = {
{ SEC_ASN1_SET_OF, 0, cert_SignedCrlTemplate },
{ SEC_ASN1_SET_OF, 0, CERT_SignedCrlTemplate },
};
/* get CRL version */
@ -462,7 +462,7 @@ CERT_DecodeDERCrlWithFlags(PRArenaPool *narena, SECItem *derSignedCrl,
CERTSignedCrl *crl;
SECStatus rv;
OpaqueCRLFields* extended = NULL;
const SEC_ASN1Template* crlTemplate = cert_SignedCrlTemplate;
const SEC_ASN1Template* crlTemplate = CERT_SignedCrlTemplate;
if (!derSignedCrl ||
( (options & CRL_DECODE_ADOPT_HEAP_DER) && /* adopting DER requires
@ -827,10 +827,13 @@ SEC_DestroyCrl(CERTSignedCrl *crl)
if (crl->slot) {
PK11_FreeSlot(crl->slot);
}
if (PR_TRUE == GetOpaqueCRLFields(crl)->heapDER) {
if (GetOpaqueCRLFields(crl) &&
PR_TRUE == GetOpaqueCRLFields(crl)->heapDER) {
SECITEM_FreeItem(crl->derCrl, PR_TRUE);
}
PORT_FreeArena(crl->arena, PR_FALSE);
if (crl->arena) {
PORT_FreeArena(crl->arena, PR_FALSE);
}
}
return SECSuccess;
} else {
@ -879,6 +882,7 @@ SEC_LookupCrls(CERTCertDBHandle *handle, CERTCrlHeadNode **nodes, int type)
*/
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_IssuerAndSNTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_CrlTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SignedCrlTemplate)
SEC_ASN1_CHOOSER_IMPLEMENT(CERT_SetOfSignedCrlTemplate)
/* CRL cache code starts here */
@ -2998,3 +3002,5 @@ static SECStatus CachedCrl_Compare(CachedCrl* a, CachedCrl* b, PRBool* isDupe,
return SECSuccess;
}

Просмотреть файл

@ -844,7 +844,9 @@ SECOID_AddEntry;
;+#
;+# Don't export these DATA symbols on Windows because they don't work right.
;;CERT_SequenceOfCertExtensionTemplate DATA ;
;;CERT_SignedCrlTemplate DATA ;
NSS_Get_CERT_SequenceOfCertExtensionTemplate;
NSS_Get_CERT_SignedCrlTemplate;
;+ local:
;+ *;
;+};

Просмотреть файл

@ -74,7 +74,8 @@ cert_init()
. ./init.sh
fi
SCRIPTNAME="cert.sh"
html_head "Certutil Tests"
CRL_GRP_DATE=`date "+%Y%m%d%H%M%SZ"`
html_head "Certutil and Crlutil Tests"
################## Generate noise for our CA cert. ######################
# NOTE: these keys are only suitable for testing, as this whole thing
@ -139,6 +140,31 @@ certu()
return $RET
}
################################ certu #################################
# local shell function to call crlutil, also: writes action and options to
# stdout, sets variable RET and writes results to the html file results
########################################################################
crlu()
{
echo "$SCRIPTNAME: ${CU_ACTION} --------------------------"
CRLUTIL=crlutil
echo "$CRLUTIL $*"
$CRLUTIL $*
RET=$?
if [ "$RET" -ne 0 ]; then
CRLFAILED=$RET
html_failed "<TR><TD>${CU_ACTION} ($RET) "
cert_log "ERROR: ${CU_ACTION} failed $RET"
else
html_passed "<TR><TD>${CU_ACTION}"
fi
# echo "Contine?"
# cat > /dev/null
return $RET
}
############################# cert_init_cert ##########################
# local shell function to initialize creation of client and server certs
########################################################################
@ -346,6 +372,7 @@ cert_CA()
certu -S -n $NICKNAME -t $TRUSTARG -v 600 $SIGNER -d ${LPROFILE} -1 -2 -5 \
-f ${R_PWFILE} -z ${R_NOISE_FILE} -m $CERTSERIAL 2>&1 <<CERTSCRIPT
5
6
9
n
y
@ -628,6 +655,131 @@ MODSCRIPT
fi
}
############################## cert_stresscerts ################################
# local shell function to generate certs and crls for SSL tests
########################################################################
cert_crl_ssl()
{
################# Creating Certs ###################################
#
CERTFAILED=0
CERTSERIAL=${CRL_GRP_1_BEGIN}
cd $CADIR
PROFILEDIR=${CLIENTDIR}
CRL_GRPS_END=`expr ${CRL_GRP_1_BEGIN} + ${TOTAL_CRL_RANGE} - 1`
echo "$SCRIPTNAME: Creating Client CA Issued Certificates Range $CRL_GRP_1_BEGIN - $CRL_GRPS_END ==="
CU_ACTION="Creating client test certs"
while [ $CERTSERIAL -le $CRL_GRPS_END ]
do
CERTNAME="TestUser$CERTSERIAL"
cert_add_cert
CERTSERIAL=`expr $CERTSERIAL + 1 `
done
#################### CRL Creation ##############################
CRL_GEN_RES=0
echo "$SCRIPTNAME: Creating CA CRL ====================================="
CRL_GRP_END=`expr ${CRL_GRP_1_BEGIN} + ${CRL_GRP_1_RANGE} - 1`
CRL_FILE_GRP_1=${R_SERVERDIR}/root.crl_${CRL_GRP_1_BEGIN}-${CRL_GRP_END}
CRL_FILE=${CRL_FILE_GRP_1}
CRLUPDATE=`date +%Y%m%d%H%M%SZ`
CU_ACTION="Generating CRL for range ${CRL_GRP_1_BEGIN}-${CRL_GRP_END} TestCA authority"
CRL_GRP_END_=`expr ${CRL_GRP_END} - 1`
crlu -d $CADIR -G -n "TestCA" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}_or <<EOF_CRLINI
update=$CRLUPDATE
addcert ${CRL_GRP_1_BEGIN}-${CRL_GRP_END_} $CRL_GRP_DATE
addext reasonCode 0 4
addext issuerAltNames 0 "rfc822Name:caemail@ca.com|dnsName:ca.com|x400Address:x400Address|directoryName:CN=NSS Test CA,O=BOGUS NSS,L=Mountain View,ST=California,C=US|URI:http://ca.com|ipAddress:192.168.0.1|registerID=reg CA"
EOF_CRLINI
# This extension should be added to the list, but currently nss has bug
#addext authKeyId 0 "CN=NSS Test CA,O=BOGUS NSS,L=Mountain View,ST=California,C=US" 1
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
chmod 600 ${CRL_FILE_GRP_1}_or
echo test > file
############################# Modification ##################################
echo "$SCRIPTNAME: Modifying CA CRL by adding one more cert ============"
sleep 2
CRL_GRP_DATE=`date "+%Y%m%d%H%M%SZ"`
CU_ACTION="Modification CRL by adding one more cert"
crlu -d $CADIR -M -n "TestCA" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1}_or1 \
-i ${CRL_FILE_GRP_1}_or <<EOF_CRLINI
addcert ${CRL_GRP_END} $CRL_GRP_DATE
EOF_CRLINI
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
chmod 600 ${CRL_FILE_GRP_1}_or1
TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or"
########### Removing one cert ${UNREVOKED_CERT_GRP_1} #######################
echo "$SCRIPTNAME: Modifying CA CRL by removing one cert ==============="
CU_ACTION="Modification CRL by removing one cert"
crlu -d $CADIR -M -n "TestCA" -f ${R_PWFILE} -o ${CRL_FILE_GRP_1} \
-i ${CRL_FILE_GRP_1}_or1 <<EOF_CRLINI
rmcert ${UNREVOKED_CERT_GRP_1}
EOF_CRLINI
chmod 600 ${CRL_FILE_GRP_1}
TEMPFILES="$TEMPFILES ${CRL_FILE_GRP_1}_or1"
########### Creating second CRL which includes groups 1 and 2 ##############
CRL_GRP_END=`expr ${CRL_GRP_2_BEGIN} + ${CRL_GRP_2_RANGE} - 1`
CRL_FILE_GRP_2=${R_SERVERDIR}/root.crl_${CRL_GRP_2_BEGIN}-${CRL_GRP_END}
echo "$SCRIPTNAME: Creating CA CRL for groups 1 and 2 ==============="
CRLUPDATE=`date "+%Y%m%d%H%M%SZ"`
CRL_GRP_DATE=`date "+%Y%m%d%H%M%SZ"`
CU_ACTION="Creating CRL for groups 1 and 2"
crlu -d $CADIR -M -n "TestCA" -f ${R_PWFILE} -o ${CRL_FILE_GRP_2} \
-i ${CRL_FILE_GRP_1} <<EOF_CRLINI
update=$CRLUPDATE
addcert ${CRL_GRP_2_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
addext invalidityDate 0 $CRLUPDATE
rmcert ${UNREVOKED_CERT_GRP_2}
EOF_CRLINI
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
chmod 600 ${CRL_FILE_GRP_2}
########### Creating second CRL which includes groups 1, 2 and 3 ##############
CRL_GRP_END=`expr ${CRL_GRP_3_BEGIN} + ${CRL_GRP_3_RANGE} - 1`
CRL_FILE_GRP_3=${R_SERVERDIR}/root.crl_${CRL_GRP_3_BEGIN}-${CRL_GRP_END}
echo "$SCRIPTNAME: Creating CA CRL for groups 1, 2 and 3 ==============="
sleep 2
CRLUPDATE=`date "+%Y%m%d%H%M%SZ"`
CRL_GRP_DATE=`date "+%Y%m%d%H%M%SZ"`
CU_ACTION="Creating CRL for groups 1, 2 and 3"
crlu -d $CADIR -M -n "TestCA" -f ${R_PWFILE} -o ${CRL_FILE_GRP_3} \
-i ${CRL_FILE_GRP_2} <<EOF_CRLINI
update=$CRLUPDATE
addcert ${CRL_GRP_3_BEGIN}-${CRL_GRP_END} $CRL_GRP_DATE
rmcert ${UNREVOKED_CERT_GRP_3}
addext crlNumber 0 2
EOF_CRLINI
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
chmod 600 ${CRL_FILE_GRP_3}
############ Importing Server CA Issued CRL for certs of first group #######
echo "$SCRIPTNAME: Importing Server CA Issued CRL for certs ${CRL_GRP_BEGIN} trough ${CRL_GRP_END}"
CU_ACTION="Importing CRL for groups 1"
crlu -I -i ${CRL_FILE} -n "TestCA" -f "${R_PWFILE}" -d "${R_SERVERDIR}"
CRL_GEN_RES=`expr $? + $CRL_GEN_RES`
if [ "$CERTFAILED" != 0 -o "$CRL_GEN_RES" != 0 ] ; then
cert_log "ERROR: SSL CRL prep failed $CERTFAILED : $CRL_GEN_RES"
else
cert_log "SUCCESS: SSL CRL prep passed"
fi
}
############################## cert_cleanup ############################
# local shell function to finish this script (no exit since it might be
# sourced)
@ -648,6 +800,7 @@ cert_extended_ssl
cert_ssl
cert_smime_client
cert_fips
cert_crl_ssl
if [ -n "$DO_DIST_ST" -a "$DO_DIST_ST" = "TRUE" ] ; then
cert_stresscerts
#following lines to be used when databases are to be reused

Просмотреть файл

@ -467,6 +467,30 @@ if [ -z "${INIT_SOURCED}" -o "${INIT_SOURCED}" != "TRUE" ]; then
MAX_CERT=$GLOB_MAX_CERT
fi
#################################################
# CRL SSL testing constatnts
#
CRL_GRP_1_BEGIN=40
CRL_GRP_1_RANGE=3
UNREVOKED_CERT_GRP_1=41
CRL_GRP_2_BEGIN=43
CRL_GRP_2_RANGE=6
UNREVOKED_CERT_GRP_2=46
CRL_GRP_3_BEGIN=49
CRL_GRP_3_RANGE=4
UNREVOKED_CERT_GRP_3=51
TOTAL_CRL_RANGE=`expr ${CRL_GRP_1_RANGE} + ${CRL_GRP_2_RANGE} + \
${CRL_GRP_3_RANGE}`
TOTAL_GRP_NUM=3
RELOAD_CRL=1
SCRIPTNAME=$0
INIT_SOURCED=TRUE #whatever one does - NEVER export this one please
fi

Просмотреть файл

@ -73,7 +73,8 @@ ssl_init()
SCRIPTNAME=ssl.sh
echo "$SCRIPTNAME: SSL tests ==============================="
grep "SUCCESS: SSL passed" $CERT_LOG_FILE >/dev/null || {
grep "SUCCESS: SSL passed" $CERT_LOG_FILE >/dev/null &&
grep "SUCCESS: SSL CRL prep passed" $CERT_LOG_FILE >/dev/null || {
html_head "SSL Test failure"
Exit 8 "Fatal - SSL of cert.sh needs to pass first"
}
@ -330,6 +331,271 @@ ssl_stress()
html "</TABLE><BR>"
}
############################## ssl_crl #################################
# local shell function to perform SSL test with/out revoked certs tests
########################################################################
ssl_crl_ssl()
{
html_head "CRL SSL Client Tests $NORM_EXT"
# Using First CRL Group for this test. There are $CRL_GRP_1_RANGE certs in it.
# Cert number $UNREVOKED_CERT_GRP_1 was not revoked
CRL_GROUP_BEGIN=$CRL_GRP_1_BEGIN
CRL_GROUP_RANGE=$CRL_GRP_1_RANGE
UNREVOKED_CERT=$UNREVOKED_CERT_GRP_1
while read value sparam cparam testname
do
if [ $value != "#" ]; then
servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'`
pwd=`echo $cparam | grep nss`
user=`echo $cparam | grep TestUser`
_cparam=$cparam
case $servarg in
1) if [ -z "$pwd" -o -z "$user" ]; then
rev_modvalue=0
else
rev_modvalue=254
fi
;;
2) rev_modvalue=254 ;;
3) if [ -z "$pwd" -o -z "$user" ]; then
rev_modvalue=0
else
rev_modvalue=1
fi
;;
4) rev_modvalue=1 ;;
esac
TEMP_NUM=0
while [ $TEMP_NUM -lt $CRL_GROUP_RANGE ]
do
CURR_SER_NUM=`expr ${CRL_GROUP_BEGIN} + ${TEMP_NUM}`
TEMP_NUM=`expr $TEMP_NUM + 1`
USER_NICKNAME="TestUser${CURR_SER_NUM}"
cparam=`echo $_cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" `
start_selfserv
echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} \\"
echo " ${cparam} < ${REQUEST_FILE}"
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
tstclnt -p ${PORT} -h ${HOSTADDR} -f ${cparam} \
-d ${R_CLIENTDIR} < ${REQUEST_FILE} \
>${TMP}/$HOST.tmp.$$ 2>&1
ret=$?
cat ${TMP}/$HOST.tmp.$$
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
if [ $CURR_SER_NUM -ne $UNREVOKED_CERT ]; then
modvalue=$rev_modvalue
else
modvalue=$value
fi
html_msg $ret $modvalue "${testname}" \
"produced a returncode of $ret, expected is $modvalue"
kill_selfserv
done
fi
done < ${SSLAUTH}
html "</TABLE><BR>"
}
############################## ssl_crl #################################
# local shell function to perform SSL test for crl cache functionality
# with/out revoked certs
########################################################################
is_revoked() {
certNum=$1
currLoadedGrp=$2
found=0
ownerGrp=1
while [ $ownerGrp -le $TOTAL_GRP_NUM -a $found -eq 0 ]
do
currGrpBegin=`eval echo \$\{CRL_GRP_${ownerGrp}_BEGIN\}`
currGrpRange=`eval echo \$\{CRL_GRP_${ownerGrp}_RANGE\}`
currGrpEnd=`expr $currGrpBegin + $currGrpRange - 1`
if [ $certNum -ge $currGrpBegin -a $certNum -le $currGrpEnd ]; then
found=1
else
ownerGrp=`expr $ownerGrp + 1`
fi
done
if [ $found -eq 1 -a $currLoadedGrp -lt $ownerGrp ]; then
return 1
fi
if [ $found -eq 0 ]; then
return 1
fi
unrevokedGrpCert=`eval echo \$\{UNREVOKED_CERT_GRP_${ownerGrp}\}`
if [ $certNum -eq $unrevokedGrpCert ]; then
return 1
fi
return 0
}
load_group_crl() {
group=$1
OUTFILE_TMP=${TMP}/$HOST.tmp.$$
grpBegin=`eval echo \$\{CRL_GRP_${group}_BEGIN\}`
grpRange=`eval echo \$\{CRL_GRP_${group}_RANGE\}`
grpEnd=`expr $grpBegin + $grpRange - 1`
if [ "$grpBegin" = "" -o "$grpRange" = "" ]; then
ret=1
return 1;
fi
if [ "$RELOAD_CRL" != "" ]; then
if [ $group -eq 1 ]; then
echo "==================== Resetting to group 1 crl ==================="
kill_selfserv
start_selfserv
is_selfserv_alive
fi
echo "================= Reloading CRL for group $grpBegin - $grpEnd ============="
echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} \\"
echo " -w nss -n TestUser${UNREVOKED_CERT_GRP_1}"
echo "Request:"
echo "GET crl://${SERVERDIR}/root.crl_${grpBegin}-${grpEnd}"
echo ""
echo "RELOAD time $i"
tstclnt -p ${PORT} -h ${HOSTADDR} -f \
-d ${R_CLIENTDIR} -w nss -n TestUser${UNREVOKED_CERT_GRP_1} \
<<_EOF_REQUEST_ >${OUTFILE_TMP} 2>&1
GET crl://${SERVERDIR}/root.crl_${grpBegin}-${grpEnd}
_EOF_REQUEST_
cat ${OUTFILE_TMP}
grep "CRL ReCache Error" ${OUTFILE_TMP}
if [ $? -eq 0 ]; then
ret=1
return 1
fi
else
echo "=== Updating DB for group $grpBegin - $grpEnd and restarting selfserv ====="
kill_selfserv
CU_ACTION="Importing CRL for groups $grpBegin - $grpEnd"
crlu -d ${R_SERVERDIR} -I -i ${SERVERDIR}/root.crl_${grpBegin}-${grpEnd} \
-p ../tests.pw.928
ret=$?
if [ "$ret" -eq 0 ]; then
return 1
fi
start_selfserv
fi
is_selfserv_alive
ret=$?
echo "================= CRL Reloaded ============="
}
ssl_crl_cache()
{
html_head "Cache CRL SSL Client Tests $NORM_EXT"
SSLAUTH_TMP=${TMP}/authin.tl.tmp
SERV_ARG=-r_-r
rm -f ${SSLAUTH_TMP}
echo ${SSLAUTH_TMP}
grep -- " $SERV_ARG " ${SSLAUTH} | grep -v "^#" | grep -v none | grep -v bogus > ${SSLAUTH_TMP}
echo $?
while [ $? -eq 0 -a -f ${SSLAUTH_TMP} ]
do
sparam=$SERV_ARG
start_selfserv
while read value sparam cparam testname
do
servarg=`echo $sparam | awk '{r=split($0,a,"-r") - 1;print r;}'`
pwd=`echo $cparam | grep nss`
user=`echo $cparam | grep TestUser`
_cparam=$cparam
case $servarg in
1) if [ -z "$pwd" -o -z "$user" ]; then
rev_modvalue=0
else
rev_modvalue=254
fi
;;
2) rev_modvalue=254 ;;
3) if [ -z "$pwd" -o -z "$user" ]; then
rev_modvalue=0
else
rev_modvalue=1
fi
;;
4) rev_modvalue=1 ;;
esac
TEMP_NUM=0
LOADED_GRP=1
while [ ${LOADED_GRP} -le ${TOTAL_GRP_NUM} ]
do
while [ $TEMP_NUM -lt $TOTAL_CRL_RANGE ]
do
CURR_SER_NUM=`expr ${CRL_GRP_1_BEGIN} + ${TEMP_NUM}`
TEMP_NUM=`expr $TEMP_NUM + 1`
USER_NICKNAME="TestUser${CURR_SER_NUM}"
cparam=`echo $_cparam | sed -e 's;_; ;g' -e "s/TestUser/$USER_NICKNAME/g" `
echo "Server Args: $SERV_ARG"
echo "tstclnt -p ${PORT} -h ${HOSTADDR} -f -d ${R_CLIENTDIR} \\"
echo " ${cparam} < ${REQUEST_FILE}"
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
tstclnt -p ${PORT} -h ${HOSTADDR} -f ${cparam} \
-d ${R_CLIENTDIR} < ${REQUEST_FILE} \
>${TMP}/$HOST.tmp.$$ 2>&1
ret=$?
cat ${TMP}/$HOST.tmp.$$
rm ${TMP}/$HOST.tmp.$$ 2>/dev/null
is_revoked ${CURR_SER_NUM} ${LOADED_GRP}
isRevoked=$?
if [ $isRevoked -eq 0 ]; then
modvalue=$rev_modvalue
testAddMsg="is revoked"
else
modvalue=$value
testAddMsg="is not revoked"
fi
is_selfserv_alive
ss_status=$?
if [ "$ss_status" -ne 0 ]; then
html_msg $ret $modvalue \
"${testname}(cert ${USER_NICKNAME} - $testAddMsg)" \
"produced a returncode of $ret, expected is $modvalue. " \
"selfserv is not alive!"
else
html_msg $ret $modvalue \
"${testname}(cert ${USER_NICKNAME} - $testAddMsg)" \
"produced a returncode of $ret, expected is $modvalue"
fi
done
LOADED_GRP=`expr $LOADED_GRP + 1`
TEMP_NUM=0
if [ "$LOADED_GRP" -le "$TOTAL_GRP_NUM" ]; then
load_group_crl $LOADED_GRP
html_msg $ret 0 "Load group $LOADED_GRP crl " \
"produced a returncode of $ret, expected is 0"
fi
done
load_group_crl 1
done < ${SSLAUTH_TMP}
kill_selfserv
SERV_ARG="${SERV_ARG}_-r"
rm -f ${SSLAUTH_TMP}
grep -- " $SERV_ARG " ${SSLAUTH} | grep -v none | grep -v bogus > ${SSLAUTH_TMP}
done
TEMPFILES=${SSLAUTH_TMP}
html "</TABLE><BR>"
}
############################## ssl_cleanup #############################
# local shell function to finish this script (no exit since it might be
@ -350,6 +616,8 @@ if [ -z "$DO_REM_ST" -a -z "$DO_DIST_ST" ] ; then
ssl_init
ssl_cov
ssl_auth
ssl_crl_ssl
ssl_crl_cache
ssl_stress
SERVERDIR=$EXT_SERVERDIR