cotp: fix off-by-one bug in expanding input buffer.
[easyotp.git] / cotp.c
blob3c5b3b797bcf5d9362ca27d5160239e6e7de181b
1 /** Practical One-time Pad Library
3 * Created:20080514
4 * By Jeff Connelly
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <getopt.h>
11 #include <sysexits.h>
13 #include "libotp.h"
15 extern PAD *pads;
17 extern char *optarg;
18 extern int optind;
20 void test()
22 char *o;
23 unsigned int i;
25 load_config("otp.conf");
26 show_pads();
29 printf("offset=%ld\n", read_offset(pads));
30 write_offset(pads, 1213475);
31 printf("offset=%ld\n", read_offset(pads));
34 otp_decrypt("--EMOTP_BEGIN--1213434,\n"
35 "gK1O22FPbxLmxrROfFHDCsM1LTsOAjjbRlHVM1p+WG+s6yslYVfzvtc=\n"
36 "--EMOTP_END--\n", &o);
37 puts(o);
38 free(o);
40 otp_decrypt("--EMOTP_BEGIN--978,dc,\n"
41 "hUZm1q0gX7pa6Alzbo9OZiT8wA==\n"
42 "--EMOTP_END--\n", &o);
43 puts(o);
44 free(o);
46 o = otp_encrypt("hello world", strlen("hello world"), "dc", &i);
47 printf("encrypt = %s\n", o);
48 free(o);
50 otp_decrypt("junkasdsjdfldjf jdsfjunk--EMOTP_BEGIN--1213475,dc,\n"
51 "v7jlXbCCvPv4S0k=\n"
52 "--EMOTP_END--\n-tasjdktrailingjunkksjdjf", &o);
53 puts(o);
54 free(o);
56 free_pads();
59 /* Operation mode - trinary :) */
60 #define ENCRYPT -1
61 #define AUTO 0
62 #define DECRYPT 1
64 void usage()
66 fprintf(stderr, "usage: otp [-e | -d | ] [-t <pad_name>]\n"
67 "\n"
68 "Mode selection:\n"
69 "-e Encrypt\n"
70 "-d Decrypt with <pad_name>\n"
71 "Default is automatic.\n"
72 "\n"
73 "-t Specify pad name to encrypt with. Default: first pad.\n");
74 exit(EX_USAGE);
77 /* Read input data.
79 * @param size Set to number of bytes read.
81 * @return Input, caller frees.
83 char *read_input(unsigned int *size)
85 unsigned int i, buffer_size;
86 char *input;
88 i = 0;
89 buffer_size = 1024;
90 input = malloc(buffer_size);
91 if (!input) {
92 perror("malloc input buffer");
93 exit(EX_UNAVAILABLE);
96 while(!feof(stdin)) {
97 input[i++] = fgetc(stdin);
98 if (input[i - 1] == EOF)
99 break;
100 if (i >= buffer_size) {
101 buffer_size += 1024;
102 input = realloc(input, buffer_size);
103 if (!input) {
104 perror("realloc input buffer");
105 exit(EX_UNAVAILABLE);
109 input[i - 1] = 0;
110 *size = i - 1;
112 return input;
115 int main(int argc, char **argv)
117 int ch, mode;
118 unsigned int length, output_length;
119 char *to, *input, *output;
121 mode = AUTO;
122 to = NULL;
124 while((ch = getopt(argc, argv, "edt:")) != -1) {
125 switch(ch)
127 case 'e':
128 mode = ENCRYPT;
129 break;
130 case 'd':
131 mode = DECRYPT;
132 break;
133 case 't':
134 to = optarg;
135 break;
136 case '?':
137 default:
138 usage();
141 argc -= optind;
142 argv += optind;
144 input = read_input(&length);
146 /* Automatic mode - guess based on magic markers.
147 * Explicit modes still allowed so can encrypt data with
148 * magic markers in it (if you ever want to). */
149 if (mode == AUTO) {
150 if (strstr(input, MARKER_BEGIN))
151 mode = DECRYPT;
152 else
153 mode = ENCRYPT;
156 load_config("otp.conf");
158 if (mode == ENCRYPT) {
159 output = otp_encrypt(input, length, to, &output_length);
160 } else if (mode == DECRYPT) {
161 output_length = otp_decrypt(input, &output);
164 printf("%s", output);
166 free(output);
167 free_pads();
169 return 0;