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));
140 if(s.st_mode & ~0100700u) {
141 logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for Ed25519 private key file `%s'!", fname);
146 ecdsa_t *key = ecdsa_read_pem_private_key(fp);
150 logger(DEBUG_ALWAYS, LOG_ERR, "Reading Ed25519 private key file `%s' failed", fname);
164 bool read_ecdsa_public_key(ecdsa_t **ecdsa, splay_tree_t **config_tree, const char *name) {
165 if(ecdsa_active(*ecdsa)) {
174 *config_tree = create_configuration();
176 if(!read_host_config(*config_tree, name, true)) {
181 /* First, check for simple Ed25519PublicKey statement */
183 if(get_config_string(lookup_config(*config_tree, "Ed25519PublicKey"), &p)) {
184 *ecdsa = ecdsa_set_base64_public_key(p);
186 return *ecdsa != NULL;
189 /* Else, check for Ed25519PublicKeyFile statement and read it */
191 if(!get_config_string(lookup_config(*config_tree, "Ed25519PublicKeyFile"), &fname)) {
192 xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
195 fp = fopen(fname, "r");
198 logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 public key file `%s': %s",
199 fname, strerror(errno));
204 *ecdsa = ecdsa_read_pem_public_key(fp);
206 if(!*ecdsa && errno != ENOENT) {
207 logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname);
213 return *ecdsa != NULL;
216 #ifndef DISABLE_LEGACY
217 rsa_t *read_rsa_private_key(splay_tree_t *config_tree, char **keyfile) {
223 /* First, check for simple PrivateKey statement */
225 config_t *rsa_priv_conf = lookup_config(config_tree, "PrivateKey");
227 if(get_config_string(rsa_priv_conf, &d)) {
228 if(!get_config_string(lookup_config(config_tree, "PublicKey"), &n)) {
229 logger(DEBUG_ALWAYS, LOG_ERR, "PrivateKey used but no PublicKey found!");
234 key = rsa_set_hex_private_key(n, "FFFF", d);
238 if(key && keyfile && rsa_priv_conf->file) {
239 *keyfile = xstrdup(rsa_priv_conf->file);
245 /* Else, check for PrivateKeyFile statement and read it */
247 if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) {
248 xasprintf(&fname, "%s" SLASH "rsa_key.priv", confbase);
251 fp = fopen(fname, "r");
254 logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA private key file `%s': %s",
255 fname, strerror(errno));
257 if(errno == ENOENT) {
258 logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA key pair with `tinc -n %s generate-rsa-keys'.", netname ? netname : ".");
268 if(fstat(fileno(fp), &s)) {
269 logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat RSA private key file `%s': %s'", fname, strerror(errno));
274 if(s.st_mode & ~0100700u) {
275 logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname);
280 key = rsa_read_pem_private_key(fp);
284 logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno));
298 bool read_rsa_public_key(rsa_t **rsa, splay_tree_t *config_tree, const char *name) {
303 /* First, check for simple PublicKey statement */
305 if(get_config_string(lookup_config(config_tree, "PublicKey"), &n)) {
306 *rsa = rsa_set_hex_public_key(n, "FFFF");
311 /* Else, check for PublicKeyFile statement and read it */
313 if(!get_config_string(lookup_config(config_tree, "PublicKeyFile"), &fname)) {
314 xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
317 fp = fopen(fname, "r");
320 logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno));
325 *rsa = rsa_read_pem_public_key(fp);
329 logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno));