1/*
2 * pemtool - convert between DER and PEM format
3 */
4#include <stdlib.h>
5#include <stdio.h>
6#include <strings.h>
7#include <security_cdsa_utils/cuFileIo.h>
8#include <security_cdsa_utils/cuPem.h>		/* private from CdsaUtils */
9#include <security_cdsa_utils/cuEnc64.h>	/* private from CdsaUtils */
10
11static void usage (char **argv)
12{
13	printf("Usage:\n");
14	printf("  %s e infile outfile header_string [q(uiet)]  -- to PEM encode\n",
15		argv[0]);
16	printf("  %s d infile outfile [q(uiet)]                -- to PEM decode\n",
17		argv[0]);
18	exit(1);
19}
20
21int main(int argc, char **argv)
22{
23	char *outFileName;
24	unsigned char *inFile = NULL;
25	unsigned inFileLen;
26	unsigned char *outFile = NULL;
27	unsigned outFileLen;
28	char encFlag = 0;
29	int arg;
30	int rtn;
31	int quiet = 0;
32	int optarg = 0;
33
34	if(argc < 4) {
35		usage(argv);
36	}
37	switch(argv[1][0]) {
38		case 'e':
39			encFlag = 1;
40			if(argc < 5) {
41				usage(argv);
42			}
43			optarg = 5;
44			break;
45		case 'd':
46			encFlag = 0;
47			if(argc < 4) {
48				usage(argv);
49			}
50			optarg = 4;
51			break;
52		default:
53			usage(argv);
54	}
55	for(arg=optarg; arg<argc; arg++) {
56		switch(argv[arg][0]) {
57			case 'q':
58				quiet = 1;
59				break;
60			default:
61				usage(argv);
62		}
63	}
64	if(readFile(argv[2], &inFile, &inFileLen)) {
65		printf("***Error reading %s; aborting.\n", argv[2]);
66		exit(1);
67	}
68	outFileName = argv[3];
69	if(encFlag) {
70		rtn = pemEncode(inFile, inFileLen, &outFile, &outFileLen,
71			argv[4]);
72	}
73	else {
74		if(isPem(inFile, inFileLen)) {
75			rtn = pemDecode(inFile, inFileLen, &outFile, &outFileLen);
76		}
77		else {
78			/* Maybe it's just base64, i.e., PEM without the header */
79			outFile = cuDec64(inFile, inFileLen, &outFileLen);
80			if(outFile == NULL) {
81				rtn = 1;
82				printf("***Error on base64 decode\n");
83			}
84			else {
85				rtn = 0;
86			}
87		}
88	}
89	if(rtn == 0) {
90		rtn = writeFile(outFileName, outFile, outFileLen);
91		if(rtn) {
92				printf("***Error writing to %s\n", outFileName);
93		}
94		else if(!quiet) {
95			printf("...wrote %u bytes to %s.\n", outFileLen, outFileName);
96		}
97	}
98	else {
99		printf("***Error processing %s.\n", argv[2]);
100	}
101	if(inFile) {
102		free(inFile);
103	}
104	if(outFile) {
105		free(outFile);
106	}
107	return rtn;
108}
109