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 bool read_ecdsa_public_key(ecdsa_t **ecdsa, splay_tree_t **config_tree, const char *name) {
166 if(ecdsa_active(*ecdsa)) {
175 *config_tree = create_configuration();
177 if(!read_host_config(*config_tree, name, true)) {
182 /* First, check for simple Ed25519PublicKey statement */
184 if(get_config_string(lookup_config(*config_tree, "Ed25519PublicKey"), &p)) {
185 *ecdsa = ecdsa_set_base64_public_key(p);
187 return *ecdsa != NULL;
190 /* Else, check for Ed25519PublicKeyFile statement and read it */
192 if(!get_config_string(lookup_config(*config_tree, "Ed25519PublicKeyFile"), &fname)) {
193 xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
196 fp = fopen(fname, "r");
199 logger(DEBUG_ALWAYS, LOG_ERR, "Error reading Ed25519 public key file `%s': %s",
200 fname, strerror(errno));
205 *ecdsa = ecdsa_read_pem_public_key(fp);
207 if(!*ecdsa && errno != ENOENT) {
208 logger(DEBUG_ALWAYS, LOG_ERR, "Parsing Ed25519 public key file `%s' failed.", fname);
214 return *ecdsa != NULL;
217 #ifndef DISABLE_LEGACY
218 rsa_t *read_rsa_private_key(splay_tree_t *config_tree, char **keyfile) {
224 /* First, check for simple PrivateKey statement */
226 config_t *rsa_priv_conf = lookup_config(config_tree, "PrivateKey");
228 if(get_config_string(rsa_priv_conf, &d)) {
229 if(!get_config_string(lookup_config(config_tree, "PublicKey"), &n)) {
230 logger(DEBUG_ALWAYS, LOG_ERR, "PrivateKey used but no PublicKey found!");
235 key = rsa_set_hex_private_key(n, "FFFF", d);
239 if(key && keyfile && rsa_priv_conf->file) {
240 *keyfile = xstrdup(rsa_priv_conf->file);
246 /* Else, check for PrivateKeyFile statement and read it */
248 if(!get_config_string(lookup_config(config_tree, "PrivateKeyFile"), &fname)) {
249 xasprintf(&fname, "%s" SLASH "rsa_key.priv", confbase);
252 fp = fopen(fname, "r");
255 logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA private key file `%s': %s",
256 fname, strerror(errno));
258 if(errno == ENOENT) {
259 logger(DEBUG_ALWAYS, LOG_INFO, "Create an RSA key pair with `tinc -n %s generate-rsa-keys'.", netname ? netname : ".");
269 if(fstat(fileno(fp), &s)) {
270 logger(DEBUG_ALWAYS, LOG_ERR, "Could not stat RSA private key file `%s': %s'", fname, strerror(errno));
276 if(s.st_mode & ~0100700u) {
277 logger(DEBUG_ALWAYS, LOG_WARNING, "Warning: insecure file permissions for RSA private key file `%s'!", fname);
282 key = rsa_read_pem_private_key(fp);
286 logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA private key file `%s' failed: %s", fname, strerror(errno));
300 rsa_t *read_rsa_public_key(splay_tree_t *config_tree, const char *name) {
305 /* First, check for simple PublicKey statement */
307 if(get_config_string(lookup_config(config_tree, "PublicKey"), &n)) {
308 rsa_t *rsa = rsa_set_hex_public_key(n, "FFFF");
313 /* Else, check for PublicKeyFile statement and read it */
315 if(!get_config_string(lookup_config(config_tree, "PublicKeyFile"), &fname)) {
316 xasprintf(&fname, "%s" SLASH "hosts" SLASH "%s", confbase, name);
319 fp = fopen(fname, "r");
322 logger(DEBUG_ALWAYS, LOG_ERR, "Error reading RSA public key file `%s': %s", fname, strerror(errno));
327 rsa_t *rsa = rsa_read_pem_public_key(fp);
331 logger(DEBUG_ALWAYS, LOG_ERR, "Reading RSA public key file `%s' failed: %s", fname, strerror(errno));