]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/clxutils/rootStoreTool/rootUtils.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / rootStoreTool / rootUtils.cpp
diff --git a/SecurityTests/clxutils/rootStoreTool/rootUtils.cpp b/SecurityTests/clxutils/rootStoreTool/rootUtils.cpp
new file mode 100644 (file)
index 0000000..8854f9f
--- /dev/null
@@ -0,0 +1,378 @@
+/*
+ * rootUtils.cpp - utility routines for rootStoreTool
+ */
+#include <stdlib.h>
+#include <strings.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "rootUtils.h"
+#include <Security/SecCertificatePriv.h>
+#include <Security/SecBasePriv.h>
+#include <Security/SecTrustSettings.h>
+#include <Security/TrustSettingsSchema.h>              /* private header */
+#include <Security/SecAsn1Coder.h>
+#include <Security/nameTemplates.h>                            /* oh frabjous day */
+
+#include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
+
+static int indentSize = 0;
+void indentIncr(void)  { indentSize += 3; }
+void indentDecr(void)  { indentSize -= 3; }
+
+void indent(void)
+{
+       if(indentSize < 0) {
+               printf("***indent screwup\n");
+               indentSize = 0;
+       }
+       for (int dex=0; dex<indentSize; dex++) {
+               putchar(' ');
+       }
+}
+
+void printAscii(
+       const char *buf,
+       unsigned len,
+       unsigned maxLen)
+{
+       bool doEllipsis = false;
+       if(len > maxLen) {
+               len = maxLen;
+               doEllipsis = true;
+       }
+       for(unsigned dex=0; dex<len; dex++) {
+               char c = *buf++;
+               if(isalnum(c) || (c == ' ')) {
+                       putchar(c);
+               }
+               else {
+                       putchar('.');
+               }
+               fflush(stdout);
+       }
+       if(doEllipsis) {
+               printf("...etc.");
+       }
+}
+
+void printHex(
+       const unsigned char *buf,
+       unsigned len,
+       unsigned maxLen)
+{
+       bool doEllipsis = false;
+       if(len > maxLen) {
+               len = maxLen;
+               doEllipsis = true;
+       }
+       for(unsigned dex=0; dex<len; dex++) {
+               printf("%02X ", *buf++);
+       }
+       if(doEllipsis) {
+               printf("...etc.");
+       }
+}
+
+void printOid(
+       const void *buf, 
+       unsigned len, 
+       OidParser &parser)
+{
+       char outstr[OID_PARSER_STRING_SIZE];
+       parser.oidParse((const unsigned char *)buf, len, outstr);
+       printf("%s", outstr);
+}
+
+void printData(
+       const char *label,
+       CFDataRef data,
+       PrintDataType whichType,
+       OidParser &parser)
+{
+       const unsigned char *buf = CFDataGetBytePtr(data);
+       unsigned len = CFDataGetLength(data);
+       
+       printf("%s: ", label);
+       switch(whichType) {
+               case PD_Hex:
+                       printHex(buf, len, 16);
+                       break;
+               case PD_ASCII:
+                       printAscii((const char *)buf, len, 50);
+                       break;
+               case PD_OID:
+                       printOid(buf, len, parser);
+       }
+       putchar('\n');
+}
+
+/* print the contents of a CFString */
+void printCfStr(
+       CFStringRef cfstr)
+{
+       CFDataRef strData = CFStringCreateExternalRepresentation(NULL, cfstr,
+               kCFStringEncodingUTF8, true);
+       if(strData == NULL) {
+               printf("<<string decode error>>");
+               return;
+       }
+       const char *cp = (const char *)CFDataGetBytePtr(strData);
+       CFIndex len = CFDataGetLength(strData);
+       for(CFIndex dex=0; dex<len; dex++) {
+               putchar(*cp++);
+       }
+       CFRelease(strData);
+}
+
+/* print a CFDateRef */
+static const char *months[12] = {
+       "Jan", "Feb", "Mar", "Apr", "May", "Jun", 
+       "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
+};
+
+void printCFDate(
+       CFDateRef dateRef)
+{
+       CFAbsoluteTime absTime = CFDateGetAbsoluteTime(dateRef);
+       if(absTime == 0.0) {
+               printf("<<Malformed CFDateeRef>>\n");
+               return;
+       }
+       CFGregorianDate gregDate = CFAbsoluteTimeGetGregorianDate(absTime, NULL);
+       const char *month = "Unknown";
+       if((gregDate.month > 12) || (gregDate.month <= 0)) {
+               printf("Huh? GregDate.month > 11. These amps only GO to 11.\n");
+       }
+       else {
+               month = months[gregDate.month - 1];
+       }
+       printf("%s %d, %ld %02d:%02d",
+               month, gregDate.day, gregDate.year, gregDate.hour, gregDate.minute);
+}
+
+/* print a CFNumber */
+void printCfNumber(
+       CFNumberRef cfNum)
+{
+       SInt32 s;
+       if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &s)) {
+               printf("***CFNumber overflow***");
+               return;
+       }
+       printf("%ld", s);
+}
+
+/* print a CFNumber as a SecTrustSettingsResult */
+void printResult(
+       CFNumberRef cfNum)
+{
+       SInt32 n;
+       if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &n)) {
+               printf("***CFNumber overflow***");
+               return;
+       }
+       const char *s;
+       char bogus[100];
+       switch(n) {
+               case kSecTrustSettingsResultInvalid: s = "kSecTrustSettingsResultInvalid"; break;
+               case kSecTrustSettingsResultTrustRoot: s = "kSecTrustSettingsResultTrustRoot"; break;
+               case kSecTrustSettingsResultTrustAsRoot: s = "kSecTrustSettingsResultTrustAsRoot"; break;
+               case kSecTrustSettingsResultDeny: s = "kSecTrustSettingsResultDeny"; break;
+               case kSecTrustSettingsResultUnspecified:    s = "kSecTrustSettingsResultUnspecified"; break;
+               default:
+                       sprintf(bogus, "Unknown SecTrustSettingsResult (%ld)", n);
+                       s = bogus;
+                       break;
+       }       
+       printf("%s", s);
+}
+
+/* print a CFNumber as SecTrustSettingsKeyUsage */
+void printKeyUsage(
+       CFNumberRef cfNum)
+{
+       SInt32 s;
+       if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &s)) {
+               printf("***CFNumber overflow***");
+               return;
+       }
+       uint32 n = (uint32)s;
+       if(n == kSecTrustSettingsKeyUseAny) {
+               printf("<any>");
+               return;
+       }
+       else if(n == 0) {
+               printf("<none>");
+               return;
+       }
+       printf("< ");
+       if(n & kSecTrustSettingsKeyUseSignature) {
+               printf("Signature ");
+       }
+       if(n & kSecTrustSettingsKeyUseEnDecryptData) {
+               printf("EnDecryptData ");
+       }
+       if(n & kSecTrustSettingsKeyUseEnDecryptKey) {
+               printf("EnDecryptKey ");
+       }
+       if(n & kSecTrustSettingsKeyUseSignCert) {
+               printf("SignCert ");
+       }
+       if(n & kSecTrustSettingsKeyUseSignRevocation) {
+               printf("SignRevocation ");
+       }
+       if(n & kSecTrustSettingsKeyUseKeyExchange) {
+               printf("KeyExchange ");
+       }
+       printf(" >");
+}
+
+/* print a CFNumber as CSSM_RETURN string */
+void printCssmErr(
+       CFNumberRef cfNum)
+{
+       SInt32 s;
+       if(!CFNumberGetValue(cfNum, kCFNumberSInt32Type, &s)) {
+               printf("***CFNumber overflow***");
+               return;
+       }
+       printf("%s", cssmErrorString((CSSM_RETURN)s));
+}
+
+/* print cert's label (the one SecCertificate infers) */
+OSStatus printCertLabel(
+       SecCertificateRef certRef)
+{
+       OSStatus ortn;
+       CFStringRef label;
+       
+       ortn = SecCertificateInferLabel(certRef, &label);
+       if(ortn) {
+               cssmPerror("SecCertificateInferLabel", ortn);
+               return ortn;
+       }
+       printCfStr(label);
+       CFRelease(label);
+       return noErr;
+}
+
+/*
+ * How many items in a NULL-terminated array of pointers?
+ */
+static unsigned nssArraySize(
+       const void **array)
+{
+    unsigned count = 0;
+    if (array) {
+               while (*array++) {
+                       count++;
+               }
+    }
+    return count;
+}
+
+static int compareOids(
+       const CSSM_OID *data1,
+       const CSSM_OID *data2)
+{      
+       if((data1 == NULL) || (data1->Data == NULL) || 
+          (data2 == NULL) || (data2->Data == NULL) ||
+          (data1->Length != data2->Length)) {
+               return 0;
+       }
+       if(data1->Length != data2->Length) {
+               return 0;
+       }
+       return memcmp(data1->Data, data2->Data, data1->Length) == 0;
+}
+
+static void printRdn(const NSS_RDN *rdn, OidParser &parser)
+{
+       unsigned numAtvs = nssArraySize((const void **)rdn->atvs);
+       char                                            *fieldName;
+
+       for(unsigned dex=0; dex<numAtvs; dex++) {
+               const NSS_ATV *atv = rdn->atvs[dex];
+               if(compareOids(&atv->type, &CSSMOID_CountryName)) {
+                       fieldName = "Country       ";      
+               }
+               else if(compareOids(&atv->type, &CSSMOID_OrganizationName)) {
+                       fieldName = "Org           ";      
+               }
+               else if(compareOids(&atv->type, &CSSMOID_LocalityName)) {
+                       fieldName = "Locality      ";      
+               }
+               else if(compareOids(&atv->type, &CSSMOID_OrganizationalUnitName)) {
+                       fieldName = "OrgUnit       ";      
+               }
+               else if(compareOids(&atv->type, &CSSMOID_CommonName)) {
+                       fieldName = "Common Name   ";      
+               }
+               else if(compareOids(&atv->type, &CSSMOID_Surname)) {
+                       fieldName = "Surname       ";      
+               }
+               else if(compareOids(&atv->type, &CSSMOID_Title)) {
+                       fieldName = "Title         ";      
+               }
+               else if(compareOids(&atv->type, &CSSMOID_Surname)) {
+                       fieldName = "Surname       ";      
+               }
+               else if(compareOids(&atv->type, &CSSMOID_StateProvinceName)) {
+                       fieldName = "State         ";      
+               }
+               else if(compareOids(&atv->type, &CSSMOID_CollectiveStateProvinceName)) {
+                       fieldName = "Coll. State   ";      
+               }
+               else if(compareOids(&atv->type, &CSSMOID_EmailAddress)) {
+                       /* deprecated, used by Thawte */
+                       fieldName = "Email addrs   ";      
+               }
+               else {
+                       fieldName = "Other name    ";      
+               }
+               indent(); printf("%s      : ", fieldName);
+               /* Not strictly true here, but we'll just assume we can print everything */
+               printAscii((char *)atv->value.item.Data, atv->value.item.Length,
+                       atv->value.item.Length);
+               putchar('\n');
+       }
+}
+
+/* print a CFData as an X509 Name (i.e., subject or issuer) */
+void printCfName(
+       CFDataRef nameData,
+       OidParser &parser)
+{
+       SecAsn1CoderRef coder = NULL;
+       OSStatus ortn;
+
+       ortn = SecAsn1CoderCreate(&coder);
+       if(ortn) {
+               cssmPerror("SecAsn1CoderCreate", ortn);
+               return;
+       }
+       /* subsequent errors to errOut: */
+
+       NSS_Name nssName = {NULL};
+       unsigned numRdns;
+
+       ortn = SecAsn1Decode(coder, 
+               CFDataGetBytePtr(nameData), CFDataGetLength(nameData),
+               kSecAsn1NameTemplate,
+               &nssName);
+       if(ortn) {
+               printf("***Error decoding NSS_Name\n");
+               goto errOut;
+       }       
+       numRdns = nssArraySize((const void **)nssName.rdns);
+       for(unsigned dex=0; dex<numRdns; dex++) {
+               printRdn(nssName.rdns[dex], parser);
+       }
+
+errOut:
+       if(coder) {
+               SecAsn1CoderRelease(coder);
+       }
+}
+