1/* 2 * Copyright (c) 2005-2007,2010-2011 Apple Inc. All Rights Reserved. 3 * 4 * parseCert.c - parse a DER-encoded X509 certificate 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 certFile [options]\n", argv[0]); 22 printf("Options:\n"); 23 printf(" -v -- verbose \n"); 24 /* etc. */ 25 exit(1); 26} 27 28static void printValidity( 29 DERItem *validity, 30 int verbose) 31{ 32 DERReturn drtn; 33 DERValidity derv; 34 35 drtn = DERParseSequenceContent(validity, 36 DERNumValidityItemSpecs, DERValidityItemSpecs, 37 &derv, sizeof(derv)); 38 if(drtn) { 39 DERPerror("DERParseSequenceContent(validity)", drtn); 40 return; 41 } 42 decodePrintItem("notBefore", IT_Leaf, verbose, &derv.notBefore); 43 decodePrintItem("notAfter", IT_Leaf, verbose, &derv.notAfter); 44 45} 46 47int main(int argc, char **argv) 48{ 49 unsigned char *certData = NULL; 50 unsigned certDataLen = 0; 51 DERSignedCertCrl signedCert; 52 DERTBSCert tbs; 53 DERReturn drtn; 54 DERItem item; 55 int verbose = 0; 56 extern char *optarg; 57 int arg; 58 extern int optind; 59 60 if(argc < 2) { 61 usage(argv); 62 } 63 if(readFile(argv[1], &certData, &certDataLen)) { 64 printf("***Error reading cert from %s. Aborting.\n", argv[1]); 65 exit(1); 66 } 67 68 optind = 2; 69 while ((arg = getopt(argc, argv, "vh")) != -1) { 70 switch (arg) { 71 case 'v': 72 verbose = 1; 73 break; 74 case 'h': 75 usage(argv); 76 } 77 } 78 if(optind != argc) { 79 usage(argv); 80 } 81 82 /* Top level decode of signed cert into 3 components */ 83 item.data = certData; 84 item.length = certDataLen; 85 drtn = DERParseSequence(&item, DERNumSignedCertCrlItemSpecs, DERSignedCertCrlItemSpecs, 86 &signedCert, sizeof(signedCert)); 87 if(drtn) { 88 DERPerror("DERParseSequence(SignedCert)", drtn); 89 exit(1); 90 } 91 printItem("TBSCert", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &signedCert.tbs); 92 93 incrIndent(); 94 95 /* decode the TBSCert - it was saved in full DER form */ 96 drtn = DERParseSequence(&signedCert.tbs, 97 DERNumTBSCertItemSpecs, DERTBSCertItemSpecs, 98 &tbs, sizeof(tbs)); 99 if(drtn) { 100 DERPerror("DERParseSequenceContent(TBSCert)", drtn); 101 exit(1); 102 } 103 if(tbs.version.data) { 104 /* unwrap the explicitly tagged integer.... */ 105 decodePrintItem("version", IT_Leaf, verbose, &tbs.version); 106 } 107 printItem("serialNum", IT_Leaf, verbose, ASN1_INTEGER, &tbs.serialNum); 108 109 printItem("tbsSigAlg", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &tbs.tbsSigAlg); 110 incrIndent(); 111 printAlgId(&tbs.tbsSigAlg, verbose); 112 decrIndent(); 113 114 printItem("issuer", IT_Leaf, verbose, ASN1_CONSTR_SEQUENCE, &tbs.issuer); 115 printItem("subject", IT_Leaf, verbose, ASN1_CONSTR_SEQUENCE, &tbs.subject); 116 117 printItem("validity", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &tbs.validity); 118 incrIndent(); 119 printValidity(&tbs.validity, verbose); 120 decrIndent(); 121 122 printItem("subjectPubKey", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, 123 &tbs.subjectPubKey); 124 incrIndent(); 125 printSubjPubKeyInfo(&tbs.subjectPubKey, verbose); 126 decrIndent(); 127 128 if(tbs.issuerID.data) { 129 /* found tag is implicit context specific: tell printItem what it really is */ 130 printItem("issuerID", IT_Leaf, verbose, ASN1_BIT_STRING, &tbs.issuerID); 131 } 132 if(tbs.subjectID.data) { 133 printItem("subjectID", IT_Leaf, verbose, ASN1_BIT_STRING, &tbs.subjectID); 134 } 135 if(tbs.extensions.data) { 136 printItem("extensions", IT_Leaf, verbose, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC | 3, 137 &tbs.extensions); 138 } 139 decrIndent(); 140 141 printItem("sigAlg", IT_Branch, verbose, ASN1_CONSTR_SEQUENCE, &signedCert.sigAlg); 142 incrIndent(); 143 printAlgId(&signedCert.sigAlg, verbose); 144 decrIndent(); 145 146 printItem("sig", IT_Leaf, verbose, ASN1_BIT_STRING, &signedCert.sig); 147 148 return 0; 149} 150