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