1#include <Security/Security.h>
2#include "printCertName.h"
3#include <clAppUtils/clutils.h>
4#include <utilLib/common.h>
5
6static CSSM_CL_HANDLE gClHand = 0;
7
8static CSSM_CL_HANDLE getClHand()
9{
10    if(gClHand) {
11		return gClHand;
12    }
13    gClHand = clStartup();
14    return gClHand;
15}
16
17static void printString(
18    const CSSM_DATA *str)
19{
20    unsigned i;
21    char *cp = (char *)str->Data;
22    for(i=0; i<str->Length; i++) {
23		printf("%c", *cp++);
24    }
25    printf("\n");
26}
27
28static void printData(
29    const CSSM_DATA *cd)
30{
31    for(unsigned dex=0; dex<cd->Length; dex++) {
32		printf("%02X", cd->Data[dex]);
33		if((dex % 4) == 3) {
34			printf(" ");
35		}
36	}
37    printf("\n");
38}
39
40/*
41 * Print an CSSM_X509_TYPE_VALUE_PAIR
42 */
43static void printAtv(
44    const CSSM_X509_TYPE_VALUE_PAIR_PTR atv)
45{
46    const CSSM_OID *oid = &atv->type;
47    const char *fieldName = "Other";
48    if(appCompareCssmData(oid, &CSSMOID_CountryName)) {
49		fieldName = "Country       ";
50    }
51    else if(appCompareCssmData(oid, &CSSMOID_OrganizationName)) {
52		fieldName = "Org           ";
53    }
54    else if(appCompareCssmData(oid, &CSSMOID_LocalityName)) {
55		fieldName = "Locality      ";
56    }
57    else if(appCompareCssmData(oid, &CSSMOID_OrganizationalUnitName)) {
58		fieldName = "OrgUnit       ";
59    }
60    else if(appCompareCssmData(oid, &CSSMOID_CommonName)) {
61		fieldName = "Common Name   ";
62    }
63    else if(appCompareCssmData(oid, &CSSMOID_Surname)) {
64		fieldName = "Surname       ";
65    }
66    else if(appCompareCssmData(oid, &CSSMOID_Title)) {
67		fieldName = "Title         ";
68    }
69    else if(appCompareCssmData(oid, &CSSMOID_Surname)) {
70		fieldName = "Surname       ";
71    }
72    else if(appCompareCssmData(oid, &CSSMOID_StateProvinceName)) {
73		fieldName = "State         ";
74    }
75    else if(appCompareCssmData(oid, &CSSMOID_CollectiveStateProvinceName)) {
76		fieldName = "Coll. State   ";
77    }
78    else if(appCompareCssmData(oid, &CSSMOID_EmailAddress)) {
79		/* deprecated, used by Thawte */
80		fieldName = "Email addrs   ";
81    }
82    else {
83		fieldName = "Other name    ";
84    }
85    printf("      %s : ", fieldName);
86    switch(atv->valueType) {
87		case BER_TAG_PRINTABLE_STRING:
88		case BER_TAG_IA5_STRING:
89		case BER_TAG_T61_STRING:		// mostly printable....
90		case BER_TAG_PKIX_UTF8_STRING:	// ditto
91			printString(&atv->value);
92			break;
93		default:
94			printData(&atv->value);
95			break;
96    }
97}
98
99/*
100 * Print contents of a CSSM_X509_NAME.
101 */
102static void printName(
103    const char *title,
104	const CSSM_X509_NAME *name)
105{
106    printf("   %s:\n", title);
107    unsigned numRdns = name->numberOfRDNs;
108    for(unsigned rdnDex=0; rdnDex<numRdns; rdnDex++) {
109		const CSSM_X509_RDN *rdn = &name->RelativeDistinguishedName[rdnDex];
110		unsigned numAtvs = rdn->numberOfPairs;
111		for(unsigned atvDex=0; atvDex<numAtvs; atvDex++) {
112			printAtv(&rdn->AttributeTypeAndValue[atvDex]);
113		}
114    }
115}
116
117static void printOneCertName(
118    CSSM_CL_HANDLE clHand,
119    CSSM_HANDLE cacheHand,
120    const char *title,
121    const CSSM_OID *oid)
122{
123    CSSM_HANDLE resultHand = 0;
124    CSSM_DATA_PTR field = NULL;
125    uint32 numFields;
126    CSSM_RETURN crtn;
127
128    crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand, cacheHand,
129		oid, &resultHand, &numFields, &field);
130    if(crtn) {
131		printf("***Error parsing cert\n");
132		cssmPerror("CSSM_CL_CertGetFirstCachedFieldValue", crtn);
133		return;
134    }
135    printName(title, (CSSM_X509_NAME_PTR)field->Data);
136    CSSM_CL_FreeFieldValue(clHand, oid, field);
137	CSSM_CL_CertAbortQuery(clHand, resultHand);
138}
139
140/*
141 * Print subject and/or issuer of a cert.
142 */
143void printCertName(
144    const unsigned char *cert,
145    unsigned certLen,
146    WhichName whichName)
147{
148    CSSM_CL_HANDLE clHand = getClHand();
149    CSSM_HANDLE cacheHand;
150    CSSM_DATA certData = {certLen, (uint8 *)cert};
151    CSSM_RETURN crtn;
152    bool printSubj = false;
153    bool printIssuer = false;
154
155    switch(whichName) {
156		case NameBoth:
157			printSubj = true;
158			printIssuer = true;
159			break;
160		case NameSubject:
161			printSubj = true;
162			break;
163		case NameIssuer:
164			printIssuer = true;
165			break;
166		default:
167			printf("***BRRZAP! Illegal whichName argument\n");
168			return;
169    }
170
171    crtn = CSSM_CL_CertCache(clHand, &certData, &cacheHand);
172    if(crtn) {
173		printf("***Error parsing cert\n");
174		cssmPerror("CSSM_CL_CertCache", crtn);
175		return;
176    }
177
178    if(printSubj) {
179		printOneCertName(clHand, cacheHand, "Subject", &CSSMOID_X509V1SubjectNameCStruct);
180    }
181    if(printIssuer) {
182		printOneCertName(clHand, cacheHand, "Issuer", &CSSMOID_X509V1IssuerNameCStruct);
183    }
184    CSSM_CL_CertAbortCache(clHand, cacheHand);
185    return;
186}
187