Wipe (some) secrets from memory after use
[tinc] / src / sptps_keypair.c
1 /*
2     sptps_test.c -- Simple Peer-to-Peer Security test program
3     Copyright (C) 2011-2022 Guus Sliepen <guus@tinc-vpn.org>,
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License along
16     with this program; if not, write to the Free Software Foundation, Inc.,
17     51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include "system.h"
21
22 #include "crypto.h"
23 #include "random.h"
24 #include "ecdsagen.h"
25 #include "logger.h"
26 #include "names.h"
27
28 void logger(debug_t level, int priority, const char *format, ...) {
29         (void)level;
30         (void)priority;
31         va_list ap;
32
33         va_start(ap, format);
34         vfprintf(stderr, format, ap);
35         va_end(ap);
36
37         fputc('\n', stderr);
38 }
39
40 static void usage(void) {
41         fprintf(stderr, "Usage: %s [options] private_key_file public_key_file\n\n", program_name);
42         fprintf(stderr, "Valid options are:\n"
43                 "  --help  Display this help and exit.\n"
44                 "\n");
45         fprintf(stderr, "Report bugs to tinc@tinc-vpn.org.\n");
46 }
47
48 static struct option const long_options[] = {
49         {"help", no_argument, NULL, 1},
50         {NULL, 0, NULL, 0}
51 };
52
53 static int generate_keypair(char *argv[]) {
54         ecdsa_t *key = ecdsa_generate();
55
56         if(!key) {
57                 return 1;
58         }
59
60         FILE *fp = fopen(argv[1], "w");
61
62         if(fp) {
63                 if(!ecdsa_write_pem_private_key(key, fp)) {
64                         fprintf(stderr, "Could not write ECDSA private key\n");
65                         ecdsa_free(key);
66                         return 1;
67                 }
68
69                 fclose(fp);
70         } else {
71                 fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[1], strerror(errno));
72                 ecdsa_free(key);
73                 return 1;
74         }
75
76         fp = fopen(argv[2], "w");
77
78         if(fp) {
79                 if(!ecdsa_write_pem_public_key(key, fp)) {
80                         fprintf(stderr, "Could not write ECDSA public key\n");
81                 }
82
83                 ecdsa_free(key);
84                 fclose(fp);
85                 return 0;
86         } else {
87                 fprintf(stderr, "Could not open '%s' for writing: %s\n", argv[2], strerror(errno));
88                 ecdsa_free(key);
89                 return 1;
90         }
91 }
92
93 int main(int argc, char *argv[]) {
94         program_name = argv[0];
95         int r;
96         int option_index = 0;
97
98         while((r = getopt_long(argc, argv, "", long_options, &option_index)) != EOF) {
99                 switch(r) {
100                 case 0:   /* long option */
101                         break;
102
103                 case '?': /* wrong options */
104                         usage();
105                         return 1;
106
107                 case 1: /* help */
108                         usage();
109                         return 0;
110
111                 default:
112                         break;
113                 }
114         }
115
116         argc -= optind - 1;
117         argv += optind - 1;
118
119         if(argc != 3) {
120                 fprintf(stderr, "Wrong number of arguments.\n");
121                 usage();
122                 return 1;
123         }
124
125         random_init();
126         crypto_init();
127
128         int result = generate_keypair(argv);
129
130         random_exit();
131
132         return result;
133 }