1 /** Practical One-time Pad Library
12 #define MARKER_TO "to:"
13 #define MARKER_BEGIN "--EMOTP_BEGIN--"
14 #define MARKER_END "--EMOTP_END--"
16 #define OFFSET_FILE_EXTENSION ".off"
17 #define OFFSET_SIZE 11 /* strlen("4294967296") + 1 */
19 /** Packaged up encrypted message, ready for transport. */
20 typedef struct _PACKAGE
{
31 /* Use read_offset() and write_offset() to access offset. */
36 /** Show a list of all loaded pads. */
41 for (p
= pads
; p
; p
= p
->next
) {
42 printf("Pad: %s: %s\n", p
->name
, p
->local_filename
);
46 /** Open a companion offset file for given pad. Caller must close.
48 * @param mode Either "rt" or "wt", for reading or writing.
50 FILE *open_offset_file(PAD
*p
, char *mode
)
53 char *offset_filename
;
54 size_t filename_length
;
56 /* Offset is stored in a separate file; pad plus OFFSET_FILE_NAME_EXTENSION. */
57 filename_length
= strlen(p
->local_filename
) + strlen(OFFSET_FILE_EXTENSION
) + 1;
58 offset_filename
= malloc(filename_length
);
59 if (!offset_filename
) {
63 snprintf(offset_filename
, filename_length
, "%s" OFFSET_FILE_EXTENSION
, p
->local_filename
);
65 /* Read offset from file. */
66 ofp
= fopen(offset_filename
, mode
);
68 fprintf(stderr
, "opening offset file %s failed\n", offset_filename
);
70 free(offset_filename
);
73 free(offset_filename
);
78 /** Read the pad offset of a given pad. */
79 unsigned long read_offset(PAD
*p
)
82 char buffer
[OFFSET_SIZE
];
85 ofp
= open_offset_file(p
, "rt");
87 memset(buffer
, 0, OFFSET_SIZE
);
88 if (fread(buffer
, 1, OFFSET_SIZE
- 1, ofp
) < 1) {
89 fprintf(stderr
, "could not read offset file for %s\n", p
->local_filename
);
93 if (fclose(ofp
) != 0) {
94 fprintf(stderr
, "error closing offset file for reading for %s\n", p
->local_filename
);
99 /* We finally got it! */
100 offset
= atol(buffer
);
105 /** Write the pad offset to the given pad. */
106 void write_offset(PAD
*p
, unsigned long offset
)
109 char buffer
[OFFSET_SIZE
];
111 ofp
= open_offset_file(p
, "wt");
113 memset(buffer
, 0, OFFSET_SIZE
);
114 snprintf(buffer
, OFFSET_SIZE
- 1, "%ld", offset
);
115 printf("buffer=%s\n", buffer
);
116 if (fwrite(buffer
, strlen(buffer
), 1, ofp
) != 1) {
117 fprintf(stderr
, "write error saving offset %ld for %s\n", offset
, p
->local_filename
);
122 if (fclose(ofp
) != 0) {
123 fprintf(stderr
, "error closing offset file for writing for %s\n", p
->local_filename
);
129 /** Load a pad file from disk, adding to 'pads' global. */
130 void load_pad(char *local_filename
)
135 fp
= fopen("/Volumes/Not Backed Up/otp/otp-dazzlement", "rb");
141 new_pad
= malloc(sizeof(PAD
));
144 exit(EX_UNAVAILABLE
);
147 new_pad
->local_filename
= strdup(local_filename
);
148 new_pad
->name
= strdup("dc"); /* TODO */
150 new_pad
->next
= NULL
;
152 /* Add to linked list. */
159 for (p
= pads
; p
; p
= p
->next
)
161 tail
->next
= new_pad
;
165 /** Close all pads and free allocated memory. */
170 for (p
= pads
; p
; p
= next
) {
172 free(p
->local_filename
);
181 load_pad("/Volumes/Not Backed Up/otp/otp-dazzlement");
182 load_pad("/Volumes/Not Backed Up/otp/otp-dazzlement");
183 load_pad("/Volumes/Not Backed Up/otp/otp-dazzlement");
185 printf("offset=%ld\n", read_offset(pads
));
186 write_offset(pads
, 1213475);
187 printf("offset=%ld\n", read_offset(pads
));