зеркало из https://github.com/mozilla/gecko-dev.git
Fix for bug 265003: Add CRL generation to crlutil. Reviewed JP+
This commit is contained in:
Родитель
e4e03bd453
Коммит
d2f6e314c7
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче