]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/clxutils/extenGrab/extenGrab.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / extenGrab / extenGrab.cpp
diff --git a/SecurityTests/clxutils/extenGrab/extenGrab.cpp b/SecurityTests/clxutils/extenGrab/extenGrab.cpp
new file mode 100644 (file)
index 0000000..01410d3
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ * extenGrab - write the unparsed extension blobs of a specified
+ * cert to files for external examination
+ */
+#include <Security/SecAsn1Coder.h>
+#include <Security/X509Templates.h>
+#include <Security/cssmapple.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <security_cdsa_utils/cuOidParser.h>
+#include <security_cdsa_utils/cuFileIo.h>
+
+static void usage(char **argv)
+{
+       printf("Usage: %s certFile outFileBase [r for CRL, default is cert]\n",
+               argv[0]);
+       exit(1);
+}
+
+/*
+ * 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;
+}
+
+int main(int argc, char **argv)
+{
+       if(argc < 3) {
+               usage(argv);
+       }
+       
+       bool                                    doCert = true;
+       NSS_Certificate                 signedCert;
+       NSS_Crl                                 signedCrl;
+       void                                    *decodeTarget;
+       const SecAsn1Template   *templ;
+       NSS_CertExtension               ***extenp;
+       
+       for(int arg=3; arg<argc; arg++) {
+               switch(argv[arg][0]) {
+                       case 'r':
+                               doCert = false;         // i.e. CRL
+                               break;
+                       default:
+                               usage(argv);
+               }
+       }
+       
+       if(doCert) {
+               memset(&signedCert, 0, sizeof(signedCert));
+               decodeTarget = &signedCert;
+               templ = kSecAsn1SignedCertTemplate;
+               extenp = &signedCert.tbs.extensions;
+       }
+       else {
+               memset(&signedCrl, 0, sizeof(signedCrl));
+               decodeTarget = &signedCrl;
+               templ = kSecAsn1SignedCrlTemplate;
+               extenp = &signedCrl.tbs.extensions;
+       }
+       
+       const char *certFile = argv[1];
+       const char *outBase = argv[2];
+       unsigned char *rawCert;
+       unsigned rawCertLen;
+       
+       if(readFile(certFile, &rawCert, &rawCertLen)) {
+               printf("***Can't read cert file. Abortihng.\n");
+               exit(1);
+       }
+       
+       SecAsn1CoderRef         coder;
+       CSSM_DATA                       rawItem = {rawCertLen, rawCert};
+       
+       OSStatus ortn = SecAsn1CoderCreate(&coder);
+       if(ortn) {
+               cssmPerror("SecAsn1CoderCreate", ortn);
+               
+       }
+       if(SecAsn1DecodeData(coder, &rawItem, templ, decodeTarget)) {
+               printf("SecAsn1DecodeData(signed) error\n");
+               exit(1);
+       }
+       
+       NSS_CertExtension **extens = *extenp;
+       unsigned numExtens = nssArraySize((const void **)extens);
+       if(numExtens == 0) {
+               printf("There appear to be zero extensions in this item.\n");
+               exit(0);
+       }
+       
+       OidParser parser;
+       char oidStr[OID_PARSER_STRING_SIZE];
+       char outFileName[200];
+       
+       for(unsigned dex=0; dex<numExtens; dex++) {
+               NSS_CertExtension *exten = extens[dex];
+               parser.oidParse(exten->extnId.Data, exten->extnId.Length, oidStr);
+               printf("Extension %u : %s\n", dex, oidStr);
+               sprintf(outFileName, "%s_%u", outBase, dex);
+               if(writeFile(outFileName, exten->value.Data, exten->value.Length)) {
+                       printf("***Error writing %s. Aborting.\n",
+                               outFileName);
+                       exit(1);
+               }
+               else {
+                       printf("...wrote %lu bytes to %s\n", 
+                               exten->value.Length, outFileName);
+               }
+       }
+       SecAsn1CoderRelease(coder);
+       printf("..done.\n");
+       return 0;
+}