1/* 2 * Copyright (c) 2005-2007,2010 Apple Inc. All Rights Reserved. 3 * 4 * parseCrl.c - parse a DER-encoded X509 CRL using libDER. 5 */ 6 7#include <stdlib.h> 8#include <strings.h> 9#include <stdio.h> 10#include <unistd.h> 11#include <libDER/libDER.h> 12#include <libDER/asn1Types.h> 13#include <libDER/DER_CertCrl.h> 14#include <libDER/DER_Keys.h> 15#include <libDERUtils/fileIo.h> 16#include <libDERUtils/libDERUtils.h> 17#include <libDERUtils/printFields.h> 18 19static void usage(char **argv) 20{ 21 printf("usage: %s crlFile [options]\n", argv[0]); 22 printf("Options:\n"); 23 printf(" -v -- verbose \n"); 24 /* etc. */ 25 exit(1); 26} 27 28/* 29 * This is a SEQUENCE OF so we use the low-level DERDecodeSeq* routines to snag one entry 30 * at a time. 31 */ 32static void printRevokedCerts( 33 DERItem *revokedCerts, 34 int verbose) 35{ 36 DERReturn drtn; 37 DERDecodedInfo currItem; 38 DERSequence seq; 39 unsigned certNum; 40 DERRevokedCert revoked; 41 42 drtn = DERDecodeSeqContentInit(revokedCerts, &seq); 43 if(drtn) { 44 DERPerror("DERDecodeSeqContentInit(revokedCerts)", drtn); 45 return; 46 } 47 48 for(certNum=0; ; certNum++) { 49 drtn = DERDecodeSeqNext(&seq, &currItem); 50 switch(drtn) { 51 case DR_EndOfSequence: 52 /* normal termination */ 53 return; 54 default: 55 DERPerror("DERDecodeSeqNext", drtn); 56 return; 57 case DR_Success: 58 doIndent(); 59 printf("revoked cert %u\n", certNum); 60 incrIndent(); 61 drtn = DERParseSequenceContent(&currItem.content, 62 DERNumRevokedCertItemSpecs, DERRevokedCertItemSpecs, 63 &revoked, sizeof(revoked)); 64 if(drtn) { 65 DERPerror("DERParseSequenceContent(RevokedCert)", drtn); 66 decrIndent(); 67 return; 68 } 69 printItem("serialNum", IT_Leaf, verbose, ASN1_INTEGER, &revoked.serialNum); 70 decodePrintItem("revocationDate", IT_Leaf, verbose, &revoked.revocationDate); 71 printItem("extensions", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &revoked.extensions); 72 decrIndent(); 73 } 74 } 75} 76 77int main(int argc, char **argv) 78{ 79 unsigned char *crlData = NULL; 80 unsigned crlDataLen = 0; 81 DERSignedCertCrl signedCrl; 82 DERTBSCrl tbs; 83 DERReturn drtn; 84 DERItem item; 85 int verbose = 0; 86 extern char *optarg; 87 int arg; 88 extern int optind; 89 90 if(argc < 2) { 91 usage(argv); 92 } 93 if(readFile(argv[1], &crlData, &crlDataLen)) { 94 printf("***Error reading CRL from %s. Aborting.\n", argv[1]); 95 exit(1); 96 } 97 98 optind = 2; 99 while ((arg = getopt(argc, argv, "vh")) != -1) { 100 switch (arg) { 101 case 'v': 102 verbose = 1; 103 break; 104 case 'h': 105 usage(argv); 106 } 107 } 108 if(optind != argc) { 109 usage(argv); 110 } 111 112 /* Top level decode of signed CRL into 3 components */ 113 item.data = crlData; 114 item.length = crlDataLen; 115 drtn = DERParseSequence(&item, DERNumSignedCertCrlItemSpecs, DERSignedCertCrlItemSpecs, 116 &signedCrl, sizeof(signedCrl)); 117 if(drtn) { 118 DERPerror("DERParseSequence(SignedCrl)", drtn); 119 exit(1); 120 } 121 printItem("TBSCrl", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &signedCrl.tbs); 122 123 incrIndent(); 124 125 /* decode the TBSCrl - it was saved in full DER form */ 126 drtn = DERParseSequence(&signedCrl.tbs, 127 DERNumTBSCrlItemSpecs, DERTBSCrlItemSpecs, 128 &tbs, sizeof(tbs)); 129 if(drtn) { 130 DERPerror("DERParseSequenceContent(TBSCrl)", drtn); 131 exit(1); 132 } 133 if(tbs.version.data) { 134 printItem("version", IT_Leaf, verbose, ASN1_INTEGER, &tbs.version); 135 } 136 137 printItem("tbsSigAlg", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &tbs.tbsSigAlg); 138 incrIndent(); 139 printAlgId(&tbs.tbsSigAlg, verbose); 140 decrIndent(); 141 142 printItem("issuer", IT_Leaf, verbose, ASN1_CONSTR_SEQUENCE, &tbs.issuer); 143 144 decodePrintItem("thisUpdate", IT_Leaf, verbose, &tbs.thisUpdate); 145 decodePrintItem("nextUpdate", IT_Leaf, verbose, &tbs.nextUpdate); 146 147 if(tbs.revokedCerts.data) { 148 printItem("version", IT_Leaf, verbose, ASN1_CONSTR_SEQUENCE, &tbs.revokedCerts); 149 incrIndent(); 150 printRevokedCerts(&tbs.revokedCerts, verbose); 151 decrIndent(); 152 } 153 154 if(tbs.extensions.data) { 155 printItem("extensions", IT_Leaf, verbose, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 3, 156 &tbs.extensions); 157 } 158 159 printItem("sigAlg", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &signedCrl.sigAlg); 160 incrIndent(); 161 printAlgId(&signedCrl.sigAlg, verbose); 162 decrIndent(); 163 164 printItem("sig", IT_Leaf, verbose, ASN1_BIT_STRING, &signedCrl.sig); 165 166 return 0; 167} 168