#include <stdlib.h>
#include <strings.h>
#include <stdio.h>
#include <unistd.h>
#include <libDER/libDER.h>
#include <libDER/asn1Types.h>
#include <libDER/DER_CertCrl.h>
#include <libDER/DER_Keys.h>
#include <libDERUtils/fileIo.h>
#include <libDERUtils/libDERUtils.h>
#include <libDERUtils/printFields.h>
static void usage(char **argv)
{
printf("usage: %s crlFile [options]\n", argv[0]);
printf("Options:\n");
printf(" -v -- verbose \n");
exit(1);
}
static void printRevokedCerts(
DERItem *revokedCerts,
int verbose)
{
DERReturn drtn;
DERDecodedInfo currItem;
DERSequence seq;
unsigned certNum;
DERRevokedCert revoked;
drtn = DERDecodeSeqContentInit(revokedCerts, &seq);
if(drtn) {
DERPerror("DERDecodeSeqContentInit(revokedCerts)", drtn);
return;
}
for(certNum=0; ; certNum++) {
drtn = DERDecodeSeqNext(&seq, &currItem);
switch(drtn) {
case DR_EndOfSequence:
return;
default:
DERPerror("DERDecodeSeqNext", drtn);
return;
case DR_Success:
doIndent();
printf("revoked cert %u\n", certNum);
incrIndent();
drtn = DERParseSequenceContent(&currItem.content,
DERNumRevokedCertItemSpecs, DERRevokedCertItemSpecs,
&revoked, sizeof(revoked));
if(drtn) {
DERPerror("DERParseSequenceContent(RevokedCert)", drtn);
decrIndent();
return;
}
printItem("serialNum", IT_Leaf, verbose, ASN1_INTEGER, &revoked.serialNum);
decodePrintItem("revocationDate", IT_Leaf, verbose, &revoked.revocationDate);
printItem("extensions", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &revoked.extensions);
decrIndent();
}
}
}
int main(int argc, char **argv)
{
unsigned char *crlData = NULL;
unsigned crlDataLen = 0;
DERSignedCertCrl signedCrl;
DERTBSCrl tbs;
DERReturn drtn;
DERItem item;
int verbose = 0;
extern char *optarg;
int arg;
extern int optind;
if(argc < 2) {
usage(argv);
}
if(readFile(argv[1], &crlData, &crlDataLen)) {
printf("***Error reading CRL from %s. Aborting.\n", argv[1]);
exit(1);
}
optind = 2;
while ((arg = getopt(argc, argv, "vh")) != -1) {
switch (arg) {
case 'v':
verbose = 1;
break;
case 'h':
usage(argv);
}
}
if(optind != argc) {
usage(argv);
}
item.data = crlData;
item.length = crlDataLen;
drtn = DERParseSequence(&item, DERNumSignedCertCrlItemSpecs, DERSignedCertCrlItemSpecs,
&signedCrl, sizeof(signedCrl));
if(drtn) {
DERPerror("DERParseSequence(SignedCrl)", drtn);
exit(1);
}
printItem("TBSCrl", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &signedCrl.tbs);
incrIndent();
drtn = DERParseSequence(&signedCrl.tbs,
DERNumTBSCrlItemSpecs, DERTBSCrlItemSpecs,
&tbs, sizeof(tbs));
if(drtn) {
DERPerror("DERParseSequenceContent(TBSCrl)", drtn);
exit(1);
}
if(tbs.version.data) {
printItem("version", IT_Leaf, verbose, ASN1_INTEGER, &tbs.version);
}
printItem("tbsSigAlg", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &tbs.tbsSigAlg);
incrIndent();
printAlgId(&tbs.tbsSigAlg, verbose);
decrIndent();
printItem("issuer", IT_Leaf, verbose, ASN1_CONSTR_SEQUENCE, &tbs.issuer);
decodePrintItem("thisUpdate", IT_Leaf, verbose, &tbs.thisUpdate);
decodePrintItem("nextUpdate", IT_Leaf, verbose, &tbs.nextUpdate);
if(tbs.revokedCerts.data) {
printItem("version", IT_Leaf, verbose, ASN1_CONSTR_SEQUENCE, &tbs.revokedCerts);
incrIndent();
printRevokedCerts(&tbs.revokedCerts, verbose);
decrIndent();
}
if(tbs.extensions.data) {
printItem("extensions", IT_Leaf, verbose, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 3,
&tbs.extensions);
}
printItem("sigAlg", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &signedCrl.sigAlg);
incrIndent();
printAlgId(&signedCrl.sigAlg, verbose);
decrIndent();
printItem("sig", IT_Leaf, verbose, ASN1_BIT_STRING, &signedCrl.sig);
return 0;
}