1/*
2 * keySizePref.cpp - set/examime max RSA key size per system
3 */
4
5#include <stdlib.h>
6#include <strings.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <CoreFoundation/CoreFoundation.h>
10#include <security_utilities/simpleprefs.h>
11
12#define kRSAKeySizePrefsDomain		"com.apple.crypto"
13#define kRSAMaxKeySizePref			CFSTR("RSAMaxKeySize")
14#define kRSAMacPublicExponentPref	CFSTR("RSAMaxPublicExponent")
15
16static void usage(char **argv)
17{
18	printf("usage: \n");
19	printf("   %s set keysize|pubexpsize <val>\n", argv[0]);
20	printf("   %s get keysize|pubexpsize\n", argv[0]);
21	printf("   %s illegal    -- set illegally large values for both\n", argv[0]);
22	exit(1);
23}
24
25int main(int argc, char **argv)
26{
27	bool doSet = false;
28	CFStringRef which = NULL;
29	char *cWhich = NULL;
30	int ourRtn = 0;
31	bool doIllegal = false;
32
33	if(argc < 2) {
34		usage(argv);
35	}
36	if(!strcmp(argv[1], "set")) {
37		doSet = true;
38		if(argc != 4) {
39			usage(argv);
40		}
41	}
42	else if(!strcmp(argv[1], "get")) {
43		if(argc != 3) {
44			usage(argv);
45		}
46	}
47	else if(!strcmp(argv[1], "illegal")) {
48		if(argc != 2) {
49			usage(argv);
50		}
51		doIllegal = true;
52	}
53	else {
54		usage(argv);
55	}
56	if(!doIllegal) {
57		if(!strcmp(argv[2], "keysize")) {
58			which = kRSAMaxKeySizePref;
59			cWhich = "Max Key Size";
60		}
61		else if(!strcmp(argv[2], "pubexpsize")) {
62			which = kRSAMacPublicExponentPref;
63			cWhich = "Max Public Exponent";
64		}
65		else {
66			usage(argv);
67		}
68	}
69
70	if(doSet || doIllegal) {
71		MutableDictionary *prefs = NULL;
72		UInt32 iVal = 0;
73		try {
74			prefs = new MutableDictionary(kRSAKeySizePrefsDomain, Dictionary::US_System);
75		}
76		catch(...) {
77			/* create a new one */
78			prefs = new MutableDictionary();
79		}
80
81		if(doIllegal) {
82			SInt64 bigBad = 0x100000000LL;
83			CFNumberRef cfVal = CFNumberCreate(NULL, kCFNumberSInt64Type, &bigBad);
84			prefs->setValue(kRSAMaxKeySizePref, cfVal);
85			prefs->setValue(kRSAMacPublicExponentPref, cfVal);
86		}
87		else {
88			iVal = atoi(argv[3]);
89			if(iVal == 0) {
90				/* this means "remove" */
91				prefs->removeValue(which);
92			}
93			else {
94				CFNumberRef cfVal = CFNumberCreate(NULL, kCFNumberSInt32Type, &iVal);
95				prefs->setValue(which, cfVal);
96			}
97		}
98		bool success = prefs->writePlistToPrefs(kRSAKeySizePrefsDomain,
99			Dictionary::US_System);
100		if(success) {
101			if(doIllegal) {
102				printf("Both prefs set to 0x100000000LL\n");
103			}
104			else if(iVal == 0) {
105				printf("%s preference removed.\n", cWhich);
106			}
107			else {
108				printf("%s set to %lu\n", cWhich, (unsigned long) iVal);
109			}
110		}
111		else {
112			printf("***Error setting %s\n", cWhich);
113			ourRtn = -1;
114		}
115		delete prefs;
116	}
117	else {
118		try {
119			Dictionary prefs(kRSAKeySizePrefsDomain, Dictionary::US_System);
120			CFNumberRef cfVal = (CFNumberRef)prefs.getValue(which);
121			if(cfVal == NULL) {
122				printf("...no %s pref found\n", cWhich);
123				return 0;
124			}
125			if(CFGetTypeID(cfVal) != CFNumberGetTypeID()) {
126				printf("***Badly formatted %s pref (1)\n", cWhich);
127				return -1;
128			}
129			UInt32 u;
130			if(!CFNumberGetValue(cfVal, kCFNumberSInt32Type, &u)) {
131				printf("***Badly formatted %s pref (2)\n", cWhich);
132			}
133			printf("%s preference is currently %lu\n", cWhich, (unsigned long)u);
134		}
135		catch(...) {
136			printf("...no %s prefs found\n", kRSAKeySizePrefsDomain);
137		}
138	}
139	return 0;
140}
141