1/* 2 * multipurpose pkcs12 tool. 3 */ 4#include <security_cdsa_utils/cuFileIo.h> 5#include <stdlib.h> 6#include <stdio.h> 7#include <CoreFoundation/CoreFoundation.h> 8#include "p12.h" 9#include <security_cdsa_utils/cuCdsaUtils.h> 10 11static void usage(char **argv) 12{ 13 printf("Usage:\n"); 14 printf(" %s p infile [options] parse\n", argv[0]); 15 printf(" %s d infile [options] decode\n", argv[0]); 16 printf(" %s e infile [options] decode-->encode\n", argv[0]); 17 printf(" %s i infile keychain import to keychain\n", argv[0]); 18 printf(" %s x outfile keychain export from keychain\n", argv[0]); 19 20 printf("Options:\n"); 21 printf(" p=password\n"); 22 printf(" z=keychainPassword\n"); 23 printf(" P (use secure passphrase)\n"); 24 printf(" k=keychain\n"); 25 printf(" l=loops\n"); 26 printf(" n(o prompt; export only)\n"); 27 printf(" v(erbose)\n"); 28 /* others here */ 29 exit(1); 30} 31 32typedef enum { 33 PR_Parse, 34 PR_Decode, 35 PR_Reencode, 36 PR_Import, 37 PR_Export 38} P12op; 39 40int main(int argc, char **argv) 41{ 42 char *inFile; 43 P12op op; 44 int minArgs = 1; 45 CFStringRef pwd = NULL; 46 bool verbose = false; 47 unsigned loops = 1; 48 char *kcName = NULL; 49 bool noPrompt = false; 50 char *kcPwd = NULL; 51 bool usePassKey = false; 52 53 if(argc < 2) { 54 usage(argv); 55 } 56 switch(argv[1][0]) { 57 case 'p': 58 op = PR_Parse; 59 minArgs = 3; 60 break; 61 case 'd': 62 op = PR_Decode; 63 minArgs = 3; 64 break; 65 case 'e': 66 op = PR_Reencode; 67 minArgs = 3; 68 break; 69 case 'i': 70 op = PR_Import; 71 minArgs = 4; 72 break; 73 case 'x': 74 op = PR_Export; 75 minArgs = 4; 76 break; 77 default: 78 usage(argv); 79 } 80 if(argc < minArgs) { 81 usage(argv); 82 } 83 for(int arg=minArgs; arg<argc; arg++) { 84 char *argp = argv[arg]; 85 switch(argp[0]) { 86 case 'p': 87 pwd = CFStringCreateWithCString(NULL, &argp[2], 88 kCFStringEncodingASCII); 89 break; 90 case 'k': 91 kcName = &argp[2]; 92 break; 93 case 'P': 94 usePassKey = true; 95 break; 96 case 'v': 97 verbose = true; 98 break; 99 case 'n': 100 noPrompt = true; 101 break; 102 case 'l': 103 loops = atoi(&argp[2]); 104 break; 105 case 'z': 106 kcPwd = &argp[2]; 107 break; 108 default: 109 usage(argv); 110 111 } 112 } 113 114 /* import/export - ready to go right now */ 115 switch(op) { 116 case PR_Import: 117 return p12Import(argv[2], argv[3], pwd, usePassKey, kcPwd); 118 case PR_Export: 119 return p12Export(argv[2], argv[3], pwd, usePassKey, kcPwd, noPrompt); 120 default: 121 break; 122 } 123 124 /* all other ops: read infile */ 125 inFile = argv[2]; 126 CSSM_DATA rawBlob; 127 unsigned len; 128 if(readFile(inFile, &rawBlob.Data, &len)) { 129 printf("***Error reading %s. Aborting.\n", inFile); 130 exit(1); 131 } 132 rawBlob.Length = len; 133 134 CSSM_CSP_HANDLE cspHand = cuCspStartup(CSSM_TRUE); 135 int rtn = 0; 136 switch(op) { 137 case PR_Decode: 138 rtn = p12Decode(rawBlob, cspHand, pwd, usePassKey, verbose, loops); 139 break; 140 case PR_Reencode: 141 rtn = p12Reencode(rawBlob, cspHand, pwd, verbose, loops); 142 break; 143 case PR_Parse: 144 rtn = p12ParseTop(rawBlob, cspHand, pwd, verbose); 145 break; 146 default: 147 /* NOT REACHED */ 148 printf("GAK!\n"); 149 rtn = -1; 150 break; 151 } 152 return rtn; 153} 154