#include "asnUtils.h"
#include <Security/nameTemplates.h>
#include <Security/SecAsn1Coder.h>
#include <string.h>
#include <stdio.h>
#include <Security/Security.h>
#include <Security/oidsattr.h>
#include <security_cdsa_utils/cuCdsaUtils.h>
static CSSM_CL_HANDLE gClHand = 0;
static CSSM_CL_HANDLE getClHand()
{
if(gClHand) {
return gClHand;
}
gClHand = cuClStartup();
return gClHand;
}
unsigned pkiNssArraySize(
const void **array)
{
unsigned count = 0;
if (array) {
while (*array++) {
count++;
}
}
return count;
}
bool compareCssmData(
const CSSM_DATA *data1,
const CSSM_DATA *data2)
{
if((data1 == NULL) || (data1->Data == NULL) ||
(data2 == NULL) || (data2->Data == NULL) ||
(data1->Length != data2->Length)) {
return false;
}
if(data1->Length != data2->Length) {
return false;
}
if(memcmp(data1->Data, data2->Data, data1->Length) == 0) {
return true;
}
else {
return false;
}
}
void printString(
const CSSM_DATA *str)
{
unsigned i;
char *cp = (char *)str->Data;
for(i=0; i<str->Length; i++) {
printf("%c", *cp++);
}
printf("\n");
}
void printData(
const CSSM_DATA *cd)
{
for(unsigned dex=0; dex<cd->Length; dex++) {
printf("%02X", cd->Data[dex]);
if((dex % 4) == 3) {
printf(" ");
}
}
printf("\n");
}
void printAtv(
const NSS_ATV *atv)
{
const CSSM_OID *oid = &atv->type;
const char *fieldName = "Other";
if(compareCssmData(oid, &CSSMOID_CountryName)) {
fieldName = "Country ";
}
else if(compareCssmData(oid, &CSSMOID_OrganizationName)) {
fieldName = "Org ";
}
else if(compareCssmData(oid, &CSSMOID_LocalityName)) {
fieldName = "Locality ";
}
else if(compareCssmData(oid, &CSSMOID_OrganizationalUnitName)) {
fieldName = "OrgUnit ";
}
else if(compareCssmData(oid, &CSSMOID_CommonName)) {
fieldName = "Common Name ";
}
else if(compareCssmData(oid, &CSSMOID_Surname)) {
fieldName = "Surname ";
}
else if(compareCssmData(oid, &CSSMOID_Title)) {
fieldName = "Title ";
}
else if(compareCssmData(oid, &CSSMOID_Surname)) {
fieldName = "Surname ";
}
else if(compareCssmData(oid, &CSSMOID_StateProvinceName)) {
fieldName = "State ";
}
else if(compareCssmData(oid, &CSSMOID_CollectiveStateProvinceName)) {
fieldName = "Coll. State ";
}
else if(compareCssmData(oid, &CSSMOID_EmailAddress)) {
fieldName = "Email addrs ";
}
else {
fieldName = "Other name ";
}
printf(" %s : ", fieldName);
switch(atv->value.tag) {
case SEC_ASN1_PRINTABLE_STRING:
case SEC_ASN1_IA5_STRING:
case SEC_ASN1_T61_STRING: case SEC_ASN1_UTF8_STRING: printString(&atv->value.item);
break;
default:
printData(&atv->value.item);
break;
}
}
void printName(
const char *title,
unsigned char *name,
unsigned nameLen)
{
SecAsn1CoderRef coder;
if(SecAsn1CoderCreate(&coder)) {
printf("*****Screwup in SecAsn1CoderCreate\n");
return;
}
CSSM_DATA der = {nameLen, name};
NSS_Name nssName;
if(SecAsn1DecodeData(coder, &der, kSecAsn1NameTemplate, &nssName)) {
printf("***Error decoding %s\n", title);
return;
}
printf(" %s:\n", title);
unsigned numRdns = pkiNssArraySize((const void **)nssName.rdns);
for(unsigned rdnDex=0; rdnDex<numRdns; rdnDex++) {
NSS_RDN *rdn = nssName.rdns[rdnDex];
unsigned numAtvs = pkiNssArraySize((const void **)rdn->atvs);
for(unsigned atvDex=0; atvDex<numAtvs; atvDex++) {
printAtv(rdn->atvs[atvDex]);
}
}
}
static void printOneCertName(
CSSM_CL_HANDLE clHand,
CSSM_HANDLE cacheHand,
const char *title,
const CSSM_OID *oid)
{
CSSM_HANDLE resultHand = 0;
CSSM_DATA_PTR field = NULL;
uint32 numFields;
CSSM_RETURN crtn;
crtn = CSSM_CL_CertGetFirstCachedFieldValue(clHand, cacheHand,
oid, &resultHand, &numFields, &field);
if(crtn) {
printf("***Error parsing cert\n");
cssmPerror("CSSM_CL_CertGetFirstCachedFieldValue", crtn);
return;
}
printName(title, field->Data, field->Length);
CSSM_CL_FreeFieldValue(clHand, oid, field);
}
void printCertName(
const unsigned char *cert,
unsigned certLen,
WhichName whichName)
{
CSSM_CL_HANDLE clHand = getClHand();
CSSM_HANDLE cacheHand;
CSSM_DATA certData = {certLen, (uint8 *)cert};
CSSM_RETURN crtn;
bool printSubj = false;
bool printIssuer = false;
switch(whichName) {
case NameBoth:
printSubj = true;
printIssuer = true;
break;
case NameSubject:
printSubj = true;
break;
case NameIssuer:
printIssuer = true;
break;
default:
printf("***BRRZAP! Illegal whichName argument\n");
return;
}
crtn = CSSM_CL_CertCache(clHand, &certData, &cacheHand);
if(crtn) {
printf("***Error parsing cert\n");
cssmPerror("CSSM_CL_CertCache", crtn);
return;
}
if(printSubj) {
printOneCertName(clHand, cacheHand, "Subject", &CSSMOID_X509V1SubjectNameStd);
}
if(printIssuer) {
printOneCertName(clHand, cacheHand, "Issuer", &CSSMOID_X509V1IssuerNameStd);
}
CSSM_CL_CertAbortCache(clHand, cacheHand);
return;
}