10 bool disable_old_keys(const char *filename, const char *what) {
11 char tmpfile[PATH_MAX] = "";
13 bool disabled = false;
17 FILE *r = fopen(filename, "r");
24 size_t result = snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", filename);
26 if(result < sizeof(tmpfile)) {
27 struct stat st = {.st_mode = 0600};
28 fstat(fileno(r), &st);
29 w = fopenmask(tmpfile, "w", st.st_mode);
32 while(fgets(buf, sizeof(buf), r)) {
33 if(!block && !strncmp(buf, "-----BEGIN ", 11)) {
34 if((strstr(buf, " ED25519 ") && strstr(what, "Ed25519")) || (strstr(buf, " RSA ") && strstr(what, "RSA"))) {
40 bool ed25519pubkey = !strncasecmp(buf, "Ed25519PublicKey", 16) && strchr(" \t=", buf[16]) && strstr(what, "Ed25519");
47 if(block || ed25519pubkey) {
51 if(fputs(buf, w) < 0) {
57 if(block && !strncmp(buf, "-----END ", 9)) {
67 if(ferror(r) || fclose(r) < 0) {
73 fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n");
83 // We cannot atomically replace files on Windows.
84 char bakfile[PATH_MAX] = "";
85 snprintf(bakfile, sizeof(bakfile), "%s.bak", filename);
87 if(rename(filename, bakfile) || rename(tmpfile, filename)) {
88 rename(bakfile, filename);
91 if(rename(tmpfile, filename)) {
93 fprintf(stderr, "Warning: old key(s) found, remove them by hand!\n");
101 fprintf(stderr, "Warning: old key(s) found and disabled.\n");
108 ecdsa_t *read_ecdsa_private_key(splay_tree_t *config_tree, char **keyfile) {
112 /* Check for PrivateKeyFile statement and read it */
114 if(!get_config_string(lookup_config(config_tree, "Ed25519PrivateKeyFile"), &fname)) {
115 xasprintf(&fname, "%s" SLASH "ed25519_key.priv", confbase);
118 fp = fopen(fname, "r");
121 logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 private key file `%s': %s", fname, strerror(errno));
123 if(errno == ENOENT) {
124 logger(DEBUG_ALWAYS, LOG_INFO, "Create an Ed25519 key pair with `tinc -n %s generate-ed25519-keys'.", netname ? netname : ".");
134 if(fstat(fileno(fp), &s)) {
135 logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat Ed25519 private key file `%s': %s'", fname, strerror(errno));
141 if(s.st_mode & ~0100700u) {
142 logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for Ed25519 private key file `%s'!", fname);
147 ecdsa_t *key = ecdsa_read_pem_private_key(fp);
151 logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname);
165 ecdsa_t *read_ecdsa_public_key(splay_tree_t **config_tree, const char *name) {
171 *config_tree = create_configuration();
173 if(!read_host_config(*config_tree, name, true)) {
178 /* First, check for simple Ed25519PublicKey statement */
180 if(get_config_string(lookup_config(*config_tree, "Ed25519PublicKey"), &p)) {
181 ecdsa_t *ecdsa = ecdsa_set_base64_public_key(p);
186 /* Else, check for Ed25519PublicKeyFile statement and read it */
188 if(!get_config_string(lookup_config(*config_tree, "Ed25519PublicKeyFile"), &fname)) {
189 xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
192 fp = fopen(fname, "r");
195 logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 public key file `%s': %s",
196 fname, strerror(errno));
201 ecdsa_t *ecdsa = ecdsa_read_pem_public_key(fp);
203 if(!ecdsa && errno != ENOENT) {
204 logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname);
213 #ifndef DISABLE_LEGACY
214 rsa_t *read_rsa_private_key(splay_tree_t *config_tree, char **keyfile) {
220 /* First, check for simple PrivateKey statement */
222 config_t *rsa_priv_conf = lookup_config(config_tree, "PrivateKey");
224 if(get_config_string(rsa_priv_conf, &d)) {
225 if(!get_config_string(lookup_config(config_tree, "PublicKey"), &n)) {
226 logger(DEBUG_ALWAYS, LOG_ERR, "PrivateKey used but no PublicKey found!");
231 key = rsa_set_hex_private_key(n, "FFFF", d);
235 if(key && keyfile && rsa_priv_conf->file) {
236 *keyfile = xstrdup(rsa_priv_conf->file);
242 /* Else, check for PrivateKeyFile statement and read it */
244 if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) {
245 xasprintf(&fname, "%s" SLASH "rsa_key.priv", confbase);
248 fp = fopen(fname, "r");
251 logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA private key file `%s': %s",
252 fname, strerror(errno));
254 if(errno == ENOENT) {
255 logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA key pair with `tinc -n %s generate-rsa-keys'.", netname ? netname : ".");
265 if(fstat(fileno(fp), &s)) {
266 logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat RSA private key file `%s': %s'", fname, strerror(errno));
272 if(s.st_mode & ~0100700u) {
273 logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname);
278 key = rsa_read_pem_private_key(fp);
282 logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno));
296 rsa_t *read_rsa_public_key(splay_tree_t *config_tree, const char *name) {
301 /* First, check for simple PublicKey statement */
303 if(get_config_string(lookup_config(config_tree, "PublicKey"), &n)) {
304 rsa_t *rsa = rsa_set_hex_public_key(n, "FFFF");
309 /* Else, check for PublicKeyFile statement and read it */
311 if(!get_config_string(lookup_config(config_tree, "PublicKeyFile"), &fname)) {
312 xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
315 fp = fopen(fname, "r");
318 logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno));
323 rsa_t *rsa = rsa_read_pem_public_key(fp);
327 logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno));