Annotation of embedtools/src/voucher.c, revision 1.1.2.4
1.1.2.1 misho 1: #include "global.h"
1.1.2.3 misho 2: #include <openssl/pem.h>
3: #include <openssl/rsa.h>
4: #include <openssl/err.h>
1.1.2.1 misho 5:
1.1.2.2 misho 6:
7: cfg_root_t cfg;
1.1.2.4 ! misho 8: array_t *vs;
1.1.2.2 misho 9: FILE *output;
1.1.2.4 ! misho 10: int Verbose;
1.1.2.2 misho 11: char szConfig[MAXPATHLEN] = VOUCHER_CFG;
12: extern char compiled[], compiledby[], compilehost[];
13:
14:
15: static void
16: Usage()
17: {
18: printf( " -= VOUCHER =- management tool\n"
19: "=== %s === %s@%s ===\n\n"
20: "Syntax: voucher [options] -r <RollID> [count]\n"
21: "\tvoucher [options] -t <voucher> [voucher [voucher ...]]\n\n"
22: "\t-v\t\tVerbose (more -v more verbosity)\n"
23: "\t-r\t\tRequest new voucher(s) mode\n"
24: "\t-t\t\tTest voucher(s) mode\n"
1.1.2.3 misho 25: "\t-g\t\tRequest new RSA pair mode\n"
1.1.2.2 misho 26: "\t-c <config>\tConfig file\n"
27: "\t-o <output>\tOutput file [default=-]\n"
28: "\n", compiled, compiledby, compilehost);
29: }
30:
31: static void
32: AtExit()
33: {
1.1.2.4 ! misho 34: io_freeVars(&vs);
1.1.2.2 misho 35: if (output != stdout)
36: fclose(output);
37: }
38:
39: static inline int
40: RedirOutput(const char *name)
41: {
42: AtExit();
43:
44: if (strcmp(name, "-")) {
45: output = fopen(name, "w+");
46: if (!output) {
47: printf("Error:: can't redirect output #%d - %s\n",
48: errno, strerror(errno));
49: return -1;
50: }
51: } else
52: output = stdout;
53: return 0;
54: }
55:
1.1.2.3 misho 56: static int
57: NewRSA()
58: {
59: RSA *k = RSA_generate_key(VOUCHER_MAX_RSA * 8, 65537, NULL, NULL);
60: if (!k) {
61: printf("Error:: can't generate RSA key\n");
62: return 2;
63: }
64:
65: PEM_write_RSAPrivateKey(output, k, NULL, NULL, 0, NULL, NULL);
66: PEM_write_RSA_PUBKEY(output, k);
67: return 0;
68: }
69:
1.1.2.4 ! misho 70: static RSA *
! 71: LoadKey(char mode)
! 72: {
! 73: FILE *f;
! 74: RSA *key = NULL;
! 75: ait_val_t v;
! 76:
! 77: #ifndef NDEBUG
! 78: ERR_load_crypto_strings();
! 79: #endif
! 80:
! 81: AIT_INIT_VAL(&v);
! 82: if (mode == 1)
! 83: cfg_loadAttribute(&cfg, "voucher", "key_private", &v, VOUCHER_KEY);
! 84: else
! 85: cfg_loadAttribute(&cfg, "voucher", "key_public", &v, VOUCHER_CRT);
! 86:
! 87: f = fopen(AIT_GET_STR(&v), "r");
! 88: AIT_FREE_VAL(&v);
! 89: if (!f) {
! 90: printf("Error:: open key #%d - %s\n", errno, strerror(errno));
! 91: return NULL;
! 92: }
! 93:
! 94: if (mode == 1)
! 95: key = PEM_read_RSAPrivateKey(f, NULL, NULL, NULL);
! 96: else
! 97: key = PEM_read_RSA_PUBKEY(f, NULL, NULL, NULL);
! 98:
! 99: fclose(f);
! 100:
! 101: if (!key)
! 102: printf("Error:: wrong key !!!\n");
! 103: return key;
! 104: }
! 105:
! 106: static void
! 107: ShowConfig(char mode, int rid, int cnt)
! 108: {
! 109: register int i;
! 110:
! 111: if (mode == 1)
! 112: printf(">>> Request voucher ticket(s) %d for Roll %d\n", cnt, rid);
! 113: else
! 114: printf(">>> Test voucher ticket(s) %d\n", cnt);
! 115:
! 116: for (i = 0; i < io_arraySize(vs); i++)
! 117: printf(" + Voucher[%d]= %s\n", i, AIT_GET_STR(io_getVars(&vs, i)));
! 118: printf(" + Roll ID %d bits\n", (int)
! 119: strtol(cfg_getAttribute(&cfg, "voucher", "rollbits"), NULL, 0));
! 120: printf(" + Ticket ID %d bits\n", (int)
! 121: strtol(cfg_getAttribute(&cfg, "voucher", "ticketbits"), NULL, 0));
! 122: printf(" + CheckSum %d bits\n", (int)
! 123: strtol(cfg_getAttribute(&cfg, "voucher", "cksumbits"), NULL, 0));
! 124: printf(" + Magic 0x%llx\n", (uint64_t)
! 125: strtoll(cfg_getAttribute(&cfg, "voucher", "magic"), NULL, 0));
! 126: printf(" + Charset %s\n", cfg_getAttribute(&cfg, "voucher", "charset"));
! 127: if (!cfg_getAttribute(&cfg, "voucher", "key_private"))
! 128: cfg_setAttribute(&cfg, "voucher", "key_private", VOUCHER_KEY);
! 129: printf(" + Private key %s\n", cfg_getAttribute(&cfg, "voucher", "key_private"));
! 130: if (!cfg_getAttribute(&cfg, "voucher", "key_public"))
! 131: cfg_setAttribute(&cfg, "voucher", "key_public", VOUCHER_CRT);
! 132: printf(" + Public key %s\n", cfg_getAttribute(&cfg, "voucher", "key_public"));
! 133: }
! 134:
! 135: static int
! 136: CheckConfig(char mode, int rid, int cnt)
! 137: {
! 138: const char *str;
! 139:
! 140: str = cfg_getAttribute(&cfg, "voucher", "charset");
! 141: if (!str || strlen(str) < 2) {
! 142: printf("Error:: charset too short ... '%s'\n", str);
! 143: return -1;
! 144: }
! 145: if (strtol(cfg_getAttribute(&cfg, "voucher", "rollbits"), NULL, 0) > 31 ||
! 146: strtol(cfg_getAttribute(&cfg, "voucher", "ticketbits"), NULL, 0) > 31 ||
! 147: strtol(cfg_getAttribute(&cfg, "voucher", "cksumbits"), NULL, 0) > 31) {
! 148: printf("Error:: bits must be between 1..31\n");
! 149: return -1;
! 150: }
! 151: if (mode == 1) {
! 152: if (rid >= 1LL << strtol(cfg_getAttribute(&cfg, "voucher", "rollbits"), NULL, 0)) {
! 153: printf("Error:: Roll bits must be 0..%lu\n",
! 154: strtol(cfg_getAttribute(&cfg, "voucher", "rollbits"), NULL, 0));
! 155: return -1;
! 156: }
! 157: if (cnt < 1 || cnt >= 1LL << strtol(cfg_getAttribute(&cfg, "voucher", "ticketbits"), NULL, 0)) {
! 158: printf("Error:: Ticket bits count must be 1..%lu\n",
! 159: strtol(cfg_getAttribute(&cfg, "voucher", "ticketbits"), NULL, 0));
! 160: return -1;
! 161: }
! 162: }
! 163:
! 164: return 0;
! 165: }
! 166:
! 167: static int
! 168: ComputeVouchers(RSA * __restrict key)
! 169: {
! 170: int base, vlen, clen, alen;
! 171: u_int roll, ticket, cksum, mb;
! 172: uint64_t clrcode, magic;
! 173:
! 174: /* prepare vars */
! 175: roll = strtol(cfg_getAttribute(&cfg, "voucher", "rollbits"), NULL, 0);
! 176: ticket = strtol(cfg_getAttribute(&cfg, "voucher", "ticketbits"), NULL, 0);
! 177: cksum = strtol(cfg_getAttribute(&cfg, "voucher", "cksumbits"), NULL, 0);
! 178:
! 179: magic = strtoll(cfg_getAttribute(&cfg, "voucher", "magic"), NULL, 0);
! 180:
! 181: base = strlen(cfg_getAttribute(&cfg, "voucher", "charset"));
! 182: vlen = ((roll + ticket + cksum) >> 3) + 1;
! 183: clen = RSA_size(key);
! 184: alen = clen < sizeof(clrcode) ? clen : sizeof(clrcode);
! 185: if (vlen > alen) {
! 186: printf("Error: roll+ticket+cksum bits too large for given key\n");
! 187: return -1;
! 188: }
! 189:
! 190: mb = alen * 8 - (roll + ticket + cksum + 1);
! 191: if (mb > 0)
! 192: magic &= (1LL << mb) - 1;
! 193: else {
! 194: mb ^= mb;
! 195: magic ^= magic;
! 196: }
! 197:
! 198: return 0;
! 199: }
! 200:
1.1.2.2 misho 201:
1.1.2.1 misho 202: int
203: main(int argc, char **argv)
204: {
1.1.2.2 misho 205: char ch, mode = 0;
1.1.2.4 ! misho 206: int rid = 0, cnt = 1;
! 207: register int i;
! 208: RSA *key;
1.1.2.2 misho 209:
210: output = stdout;
211: atexit(AtExit);
212:
1.1.2.3 misho 213: while ((ch = getopt(argc, argv, "hvrtgc:o:")) != -1)
1.1.2.2 misho 214: switch (ch) {
215: case 'r':
216: mode = 1;
217: break;
218: case 't':
219: mode = 2;
220: break;
1.1.2.3 misho 221: case 'g':
222: return NewRSA();
1.1.2.2 misho 223: case 'c':
224: strlcpy(szConfig, optarg, sizeof szConfig);
225: break;
226: case 'o':
227: RedirOutput(optarg);
228: break;
229: case 'v':
1.1.2.4 ! misho 230: Verbose++;
1.1.2.2 misho 231: break;
232: case 'h':
233: default:
234: Usage();
235: return 1;
236: }
237: argc -= optind;
238: argv += optind;
1.1.2.4 ! misho 239: if (!argc || !mode || mode > 2) {
1.1.2.2 misho 240: printf("Error:: not enough parameter or unspecified mode ...\n\n");
241: Usage();
242: return 1;
243: }
1.1.2.4 ! misho 244: if (mode == 1) {
! 245: if (argc > 1)
! 246: cnt = strtol(argv[1], NULL, 0);
! 247: rid = strtol(argv[0], NULL, 0);
! 248: } else {
! 249: cnt = argc;
! 250: vs = io_allocVars(cnt);
! 251: for (i = 0; i < argc; i++)
! 252: AIT_SET_STR(io_getVars(&vs, i), argv[i]);
! 253: }
! 254:
1.1.2.2 misho 255: if (cfgLoadConfig(szConfig, &cfg)) {
256: printf("Error:: load config #%d - %s\n", cfg_GetErrno(), cfg_GetError());
1.1.2.3 misho 257: return 3;
1.1.2.4 ! misho 258: } else {
! 259: VERB(1) ShowConfig(mode, rid, cnt);
! 260: if (CheckConfig(mode, rid, cnt)) {
! 261: cfgUnloadConfig(&cfg);
! 262: return 3;
! 263: }
! 264: }
! 265:
! 266: if (!(key = LoadKey(mode))) {
! 267: cfgUnloadConfig(&cfg);
! 268: return 4;
! 269: }
! 270: if (RSA_size(key) > VOUCHER_MAX_RSA) {
! 271: printf("Error:: RSA key size %d bits. Max %d bits\n",
! 272: RSA_size(key) * 8, VOUCHER_MAX_RSA * 8);
! 273: RSA_free(key);
! 274: cfgUnloadConfig(&cfg);
! 275: return 5;
! 276: } else
! 277: VERB(1) printf(" + Key size %d bits\n\n", RSA_size(key) * 8);
! 278:
! 279: if (ComputeVouchers(key)) {
! 280: RSA_free(key);
! 281: cfgUnloadConfig(&cfg);
! 282: return 6;
1.1.2.2 misho 283: }
284:
1.1.2.4 ! misho 285: RSA_free(key);
1.1.2.2 misho 286: cfgUnloadConfig(&cfg);
1.1.2.1 misho 287: return 0;
288: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>