]> git.saurik.com Git - apple/security.git/blobdiff - SecurityTests/clxutils/p12/p12Decode.cpp
Security-57031.1.35.tar.gz
[apple/security.git] / SecurityTests / clxutils / p12 / p12Decode.cpp
diff --git a/SecurityTests/clxutils/p12/p12Decode.cpp b/SecurityTests/clxutils/p12/p12Decode.cpp
new file mode 100644 (file)
index 0000000..b690f0e
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * Decode P12 PFX using either C++ P12Coder or public
+ * C API (both from SecurityNssPkcs12)
+ */
+
+#include <security_pkcs12/pkcs12Coder.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <Security/cssmtype.h>
+#include <security_cdsa_utils/cuPrintCert.h>
+#include <security_cdsa_utils/cuCdsaUtils.h>
+#include "p12GetPassKey.h"
+#include "p12.h"
+
+/* use this option to debug the P12Coder class directly */
+#define P12_DECODE_VIA_CPP             0
+
+/*
+ * Print CFString - stored as unicode, we get the C string,
+ * print it plus newline
+ */
+static void printUcStr(
+       CFStringRef cfstr)
+{
+       CFIndex len = CFStringGetLength(cfstr) + 1;
+       char *outStr = (char *)malloc(len);
+       if(CFStringGetCString(cfstr, outStr, len, kCFStringEncodingASCII)) {
+               printf("%s\n", outStr);
+       }
+       else {
+               printf("***Error converting from unicode to ASCII\n");
+       }
+       free(outStr);
+}
+
+static void printDataAsHex(
+       CFDataRef d,
+       unsigned maxToPrint = 0)                // optional, 0 means print it all
+{
+       unsigned i;
+       bool more = false;
+       uint32 len = CFDataGetLength(d);
+       const uint8 *cp = CFDataGetBytePtr(d);
+       
+       if((maxToPrint != 0) && (len > maxToPrint)) {
+               len = maxToPrint;
+               more = true;
+       }       
+       for(i=0; i<len; i++) {
+               printf("%02X ", ((unsigned char *)cp)[i]);
+       }
+       if(more) {
+               printf("...\n");
+       }
+       else {
+               printf("\n");
+       }
+}
+
+static void printAlgAsString(
+       CSSM_ALGORITHMS alg)
+{
+       char *s = "unknown alg";
+       switch(alg) {
+               case CSSM_ALGID_RSA:
+                       s = "RSA";
+                       break;
+               case CSSM_ALGID_DSA:
+                       s = "DSA";
+                       break;
+               case CSSM_ALGID_FEE:
+                       s = "FEE";
+                       break;
+               default:
+                       break;
+       }
+       printf("%s\n", s);
+}
+
+#if            P12_DECODE_VIA_CPP
+
+/* common bag attrs - friendlyName, localKeyId */
+static void printBagAttrs(
+       P12SafeBag &bag)
+{
+       CFStringRef friendlyName = bag.friendlyName();
+       if(friendlyName) {
+               printf("   friendlyName : ");
+               printUcStr(friendlyName);
+               CFRelease(friendlyName);
+       }
+
+       CFDataRef keyId = bag.localKeyId();
+       if(keyId) {
+               printf("   localKeyId   : ");
+               printDataAsHex(keyId, 16);
+               CFRelease(keyId);
+       }
+       if((friendlyName == NULL) && (keyId == NULL)) {
+               printf("   <no attributes found>\n");
+       }
+}
+
+OSStatus p12Decode(
+       const CSSM_DATA &pfx,
+       CSSM_CSP_HANDLE cspHand,
+       CFStringRef pwd,
+       bool verbose,
+       unsigned loops)
+{
+       OSStatus ourRtn;
+       
+       for(unsigned loop=0; loop<loops; loop++) {
+               {
+                       /* localize scope of coder for malloc test */
+                       P12Coder coder;
+                       CFDataRef cfd = CFDataCreate(NULL, pfx.Data, pfx.Length);
+                       ourRtn = noErr;
+                       
+                       try { 
+                               coder.setCsp(cspHand);
+                               coder.setMacPassPhrase(pwd);
+                               coder.decode(cfd);
+                       }
+                       catch(...) {
+                               printf("***decode error\n");
+                               ourRtn = 1;
+                       }
+                       CFRelease(cfd);
+                       
+                       try {
+                               unsigned i;
+
+                               unsigned numCerts = coder.numCerts();
+                               printf("\n%u certs found\n", numCerts);
+                               for(i=0; i<numCerts; i++) {
+                                       P12CertBag *cert = coder.getCert(i);
+                                       printf("=== Cert %u ===\n", i);
+                                       printBagAttrs(*cert);
+                                       if(verbose) {
+                                               CSSM_DATA &certData = cert->certData();
+                                               printCert(certData.Data, certData.Length,
+                                                       CSSM_FALSE);
+
+                                       }
+                                       printf("\n");
+                               }
+                               
+                               unsigned numCrls = coder.numCrls();
+                               printf("%u crls  found\n", numCrls);
+                               for(i=0; i<numCrls; i++) {
+                                       P12CrlBag *crl = coder.getCrl(i);
+                                       printf("=== Crl %u ===\n", i);
+                                       printBagAttrs(*crl);
+                                       if(verbose) {
+                                               CSSM_DATA &crlData = crl->crlData();
+                                               printCrl(crlData.Data, crlData.Length, CSSM_FALSE);
+
+                                       }
+                                       printf("\n");
+                               }
+
+                               unsigned numKeys = coder.numKeys();
+                               printf("%u keys  found\n", numKeys);
+                               for(i=0; i<numKeys; i++) {
+                                       P12KeyBag *key = coder.getKey(i);
+                                       printf("\n=== Key %u ===\n", i);
+                                       printBagAttrs(*key);
+                                       /* fix this up */
+                                       CSSM_KEY_PTR ckey = key->key();
+                                       CSSM_KEYHEADER &hdr = ckey->KeyHeader;
+                                       printf("   Key Alg      : ");
+                                       printAlgAsString(hdr.AlgorithmId);
+                                       printf("   Key Size     : %u bits\n", 
+                                               (unsigned)hdr.LogicalKeySizeInBits);
+                                       printf("\n");
+                               }
+
+                               unsigned numBlobs = coder.numOpaqueBlobs();
+                               printf("%u blobs found\n", numBlobs);
+                       } 
+                       catch(...) {
+                               printf("***exception extracting fields\n");
+                               ourRtn = 1;
+                       }
+               }
+               if(loops > 1) {
+                       fpurge(stdin);
+                       printf("CR to continue: ");
+                       getchar();
+               }
+               if(ourRtn) {
+                       return ourRtn;
+               }
+       }
+       return ourRtn;
+}
+
+#else  /* P12_DECODE_VIA_CPP */
+
+/* Normal decode using public API in SecPkcs12.h */
+
+/* common bag attrs - friendlyName, localKeyId */
+static void printBagAttrs(
+       CFStringRef friendlyName,
+       CFDataRef localKeyId)
+{
+       if(friendlyName) {
+               printf("   friendlyName : ");
+               printUcStr(friendlyName);
+       }
+
+       if(localKeyId) {
+               printf("   localKeyId   : ");
+               printDataAsHex(localKeyId, 20);
+       }
+       if((friendlyName == NULL) && (localKeyId == NULL)) {
+               printf("   <no attributes found>\n");
+       }
+}
+
+/* release attrs if present */
+static void releaseAttrs(
+       CFStringRef friendlyName,
+       CFDataRef localKeyId,
+       SecPkcs12AttrsRef attrs)
+{
+       if(friendlyName) {
+               CFRelease(friendlyName);
+       }
+       if(localKeyId) {
+               CFRelease(localKeyId);
+       }
+       if(attrs) {
+               SecPkcs12AttrsRelease(attrs);
+       }
+}
+       
+static void printOsError(
+       const char *op,
+       OSStatus ortn)
+{
+       /* may want to parse out CSSM errors */
+       cssmPerror(op, ortn);
+       printf("\n");
+}
+
+/* Sec calls all return 1 - not the fault of SecNssPkcs12 */
+#define GET_CERTS_WORKING      1
+
+OSStatus p12Decode(
+       const CSSM_DATA &pfx,
+       CSSM_CSP_HANDLE cspHand,
+       CFStringRef pwd,                        // explicit passphrase, mutually exclusive with...
+       bool usePassKey,                        // use SECURE_PASSPHRASE key
+       bool verbose,
+       unsigned loops)
+{
+       OSStatus ortn;
+       CSSM_KEY                passKey;
+       CSSM_KEY_PTR    passKeyPtr = NULL;
+       
+       CFDataRef cfd = CFDataCreate(NULL, pfx.Data, pfx.Length);
+       if(usePassKey) {
+               ortn = p12GetPassKey(cspHand, GPK_Decode, true, &passKey);
+               if(ortn) {
+                       return ortn;
+               }
+               passKeyPtr = &passKey;
+       }
+       for(unsigned loop=0; loop<loops; loop++) {
+               SecPkcs12CoderRef coder;
+               ortn = SecPkcs12CoderCreate(&coder);
+               if(ortn) {
+                       printOsError("SecPkcs12CoderCreate", ortn);
+                       return ortn;
+               }
+
+               ortn = SecPkcs12SetCspHandle(coder, cspHand);
+               if(ortn) {
+                       printOsError("SecPkcs12SetCspHandle", ortn);
+                       return ortn;
+               }
+               
+               if(usePassKey) {
+                       ortn = SecPkcs12SetMACPassKey(coder, passKeyPtr);
+                       if(ortn) {
+                               printOsError("SecPkcs12SetMACPassKey", ortn);
+                               return ortn;
+                       }
+               }
+               else {
+                       ortn = SecPkcs12SetMACPassphrase(coder, pwd);
+                       if(ortn) {
+                               printOsError("SecPkcs12SetMACPassphrase", ortn);
+                               return ortn;
+                       }
+               }
+               ortn = SecPkcs12Decode(coder, cfd);
+               if(ortn) {
+                       printOsError("SecPkcs12Decode", ortn);
+                       return ortn;
+               }
+               
+               CFIndex i;
+               CFStringRef fname;
+               CFDataRef keyId;
+
+               CFIndex numCerts;
+               SecPkcs12CertificateCount(coder, &numCerts);
+               printf("\n=== %ld certs found ===\n", numCerts);
+               #if GET_CERTS_WORKING
+               for(i=0; i<numCerts; i++) {
+                       SecCertificateRef secCert;
+                       ortn = SecPkcs12CopyCertificate(coder,
+                               i,
+                               &secCert,
+                               &fname,
+                               &keyId,
+                               NULL);          // attrs
+                       if(ortn) {
+                               printOsError("SecPkcs12CopyCertificate", ortn);
+                               return ortn;
+                       }
+                       printf("Cert %ld:\n", i);
+                       printBagAttrs(fname, keyId);
+                       if(verbose) {
+                               CSSM_DATA certData;
+                               ortn = SecCertificateGetData(secCert, &certData);
+                               if(ortn) {
+                                       printOsError("SecCertificateGetData", ortn);
+                                       return ortn;
+                               }
+                               printCert(certData.Data, certData.Length,
+                                       CSSM_FALSE);
+
+                       }
+                       releaseAttrs(fname, keyId, NULL);
+                       CFRelease(secCert);
+                       printf("\n");
+               }
+               #endif  /* GET_CERTS_WORKING */
+               
+               CFIndex numCrls;
+               SecPkcs12CrlCount(coder, &numCrls);
+               printf("=== %ld crls  found ===\n", numCrls);
+               for(i=0; i<numCrls; i++) {
+                       CFDataRef crl;
+                       ortn = SecPkcs12CopyCrl(coder,
+                               i,
+                               &crl,
+                               &fname,
+                               &keyId,
+                               NULL);          // attrs
+                       if(ortn) {
+                               printOsError("SecPkcs12CopyCrl", ortn);
+                               return ortn;
+                       }
+                       printf("Crl %ld:\n", i);
+                       printBagAttrs(fname, keyId);
+                       if(verbose) {
+                               const CSSM_DATA crlData = {
+                                       CFDataGetLength(crl),
+                                       (uint8 *)CFDataGetBytePtr(crl) };
+                               printCrl(crlData.Data, crlData.Length, CSSM_FALSE);
+
+                       }
+                       releaseAttrs(fname, keyId, NULL);
+                       CFRelease(crl);
+                       printf("\n");
+               }
+
+               CFIndex numKeys;
+               SecPkcs12PrivateKeyCount(coder, &numKeys);
+               printf("=== %ld keys  found ===\n", numKeys);
+               for(i=0; i<numKeys; i++) {
+                       CSSM_KEY_PTR key;
+                       ortn = SecPkcs12GetCssmPrivateKey(coder,
+                               i,
+                               &key,
+                               &fname,
+                               &keyId,
+                               NULL);
+                               
+                       printf("Key %ld:\n", i);
+                       printBagAttrs(fname, keyId);
+                       /* fix this up */
+                       CSSM_KEYHEADER &hdr = key->KeyHeader;
+                       printf("   Key Alg      : ");
+                       printAlgAsString(hdr.AlgorithmId);
+                       printf("   Key Size     : %u bits\n", 
+                               (unsigned)hdr.LogicalKeySizeInBits);
+                       printf("\n");
+                       releaseAttrs(fname, keyId, NULL);
+               }
+
+               CFIndex numBlobs;
+               SecPkcs12OpaqueBlobCount(coder, &numBlobs);
+               if(numBlobs != 0) {
+                       printf("%ld blobs found\n", numBlobs);
+               }
+
+               /* this should free all memory allocated in the decode */
+               SecPkcs12CoderRelease(coder);
+               
+               if(loops > 1) {
+                       fpurge(stdin);
+                       printf("CR to continue: ");
+                       getchar();
+               }
+       }
+       return 0;
+}
+
+
+#endif /* P12_DECODE_VIA_CPP */