annotate gensignkey.c @ 1659:d32bcb5c557d

Add Ed25519 support (#91) * Add support for Ed25519 as a public key type Ed25519 is a elliptic curve signature scheme that offers better security than ECDSA and DSA and good performance. It may be used for both user and host keys. OpenSSH key import and fuzzer are not supported yet. Initially inspired by Peter Szabo. * Add curve25519 and ed25519 fuzzers * Add import and export of Ed25519 keys
author Vladislav Grishenko <themiron@users.noreply.github.com>
date Wed, 11 Mar 2020 21:09:45 +0500
parents 7402218141d4
children c795520269f9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
1 #include "includes.h"
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
2 #include "dbutil.h"
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
3 #include "buffer.h"
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
4 #include "ecdsa.h"
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
5 #include "genrsa.h"
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
6 #include "gendss.h"
1659
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1658
diff changeset
7 #include "gened25519.h"
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
8 #include "signkey.h"
858
220f55d540ae rename random.h to dbrandom.h since some OSes have a system random.h
Matt Johnston <matt@ucc.asn.au>
parents: 857
diff changeset
9 #include "dbrandom.h"
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
10
857
c19acba28590 use oldstyle comments
Matt Johnston <matt@ucc.asn.au>
parents: 855
diff changeset
11 /* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
12 static int buf_writefile(buffer * buf, const char * filename) {
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
13 int ret = DROPBEAR_FAILURE;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
14 int fd = -1;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
15
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
16 fd = open(filename, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
17 if (fd < 0) {
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
18 dropbear_log(LOG_ERR, "Couldn't create new file %s: %s",
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
19 filename, strerror(errno));
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
20 goto out;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
21 }
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
22
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
23 /* write the file now */
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
24 while (buf->pos != buf->len) {
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
25 int len = write(fd, buf_getptr(buf, buf->len - buf->pos),
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
26 buf->len - buf->pos);
888
6e6ae84d3dba Fix check for EINTR
Matt Johnston <matt@ucc.asn.au>
parents: 858
diff changeset
27 if (len == -1 && errno == EINTR) {
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
28 continue;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
29 }
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
30 if (len <= 0) {
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
31 dropbear_log(LOG_ERR, "Failed writing file %s: %s",
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
32 filename, strerror(errno));
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
33 goto out;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
34 }
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
35 buf_incrpos(buf, len);
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
36 }
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
37
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
38 ret = DROPBEAR_SUCCESS;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
39
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
40 out:
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
41 if (fd >= 0) {
983
2b62f26cf808 Open directories O_RDONLY for fsync, add debugging if it fails
Matt Johnston <matt@ucc.asn.au>
parents: 982
diff changeset
42 if (fsync(fd) != 0) {
2b62f26cf808 Open directories O_RDONLY for fsync, add debugging if it fails
Matt Johnston <matt@ucc.asn.au>
parents: 982
diff changeset
43 dropbear_log(LOG_ERR, "fsync of %s failed: %s", filename, strerror(errno));
2b62f26cf808 Open directories O_RDONLY for fsync, add debugging if it fails
Matt Johnston <matt@ucc.asn.au>
parents: 982
diff changeset
44 }
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
45 m_close(fd);
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
46 }
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
47 return ret;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
48 }
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
49
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
50 /* returns 0 on failure */
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
51 static int get_default_bits(enum signkey_type keytype)
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
52 {
1250
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
53 switch (keytype) {
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1250
diff changeset
54 #if DROPBEAR_RSA
1250
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
55 case DROPBEAR_SIGNKEY_RSA:
1438
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
56 return DROPBEAR_DEFAULT_RSA_SIZE;
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
57 #endif
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1250
diff changeset
58 #if DROPBEAR_DSS
1250
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
59 case DROPBEAR_SIGNKEY_DSS:
1438
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
60 /* DSS for SSH only defines 1024 bits */
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
61 return 1024;
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
62 #endif
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1250
diff changeset
63 #if DROPBEAR_ECDSA
1250
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
64 case DROPBEAR_SIGNKEY_ECDSA_KEYGEN:
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
65 return ECDSA_DEFAULT_SIZE;
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
66 case DROPBEAR_SIGNKEY_ECDSA_NISTP521:
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
67 return 521;
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
68 case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
69 return 384;
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
70 case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
71 return 256;
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
72 #endif
1659
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1658
diff changeset
73 #if DROPBEAR_ED25519
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1658
diff changeset
74 case DROPBEAR_SIGNKEY_ED25519:
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1658
diff changeset
75 return 256;
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1658
diff changeset
76 #endif
1250
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
77 default:
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
78 return 0;
2bb4c662d1c2 more hard tab
Francois Perrad <francois.perrad@gadz.org>
parents: 983
diff changeset
79 }
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
80 }
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
81
1438
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
82 int signkey_generate_get_bits(enum signkey_type keytype, int bits) {
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
83 if (bits == 0)
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
84 {
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
85 bits = get_default_bits(keytype);
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
86 }
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
87 return bits;
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
88 }
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
89
1329
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
90 /* if skip_exist is set it will silently return if the key file exists */
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
91 int signkey_generate(enum signkey_type keytype, int bits, const char* filename, int skip_exist)
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
92 {
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
93 sign_key * key = NULL;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
94 buffer *buf = NULL;
1329
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
95 char *fn_temp = NULL;
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
96 int ret = DROPBEAR_FAILURE;
1438
4f8eb331174f add configuration option for default RSA size.
Matt Johnston <matt@ucc.asn.au>
parents: 1343
diff changeset
97 bits = signkey_generate_get_bits(keytype, bits);
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
98
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
99 /* now we can generate the key */
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
100 key = new_sign_key();
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
101
852
7540c0822374 Various cleanups and fixes for warnings
Matt Johnston <matt@ucc.asn.au>
parents: 847
diff changeset
102 seedrandom();
7540c0822374 Various cleanups and fixes for warnings
Matt Johnston <matt@ucc.asn.au>
parents: 847
diff changeset
103
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
104 switch(keytype) {
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1250
diff changeset
105 #if DROPBEAR_RSA
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
106 case DROPBEAR_SIGNKEY_RSA:
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
107 key->rsakey = gen_rsa_priv_key(bits);
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
108 break;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
109 #endif
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1250
diff changeset
110 #if DROPBEAR_DSS
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
111 case DROPBEAR_SIGNKEY_DSS:
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
112 key->dsskey = gen_dss_priv_key(bits);
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
113 break;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
114 #endif
1295
750ec4ec4cbe Convert #ifdef to #if, other build changes
Matt Johnston <matt@ucc.asn.au>
parents: 1250
diff changeset
115 #if DROPBEAR_ECDSA
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
116 case DROPBEAR_SIGNKEY_ECDSA_KEYGEN:
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
117 case DROPBEAR_SIGNKEY_ECDSA_NISTP521:
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
118 case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
119 case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
120 {
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
121 ecc_key *ecckey = gen_ecdsa_priv_key(bits);
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
122 keytype = ecdsa_signkey_type(ecckey);
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
123 *signkey_key_ptr(key, keytype) = ecckey;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
124 }
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
125 break;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
126 #endif
1659
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1658
diff changeset
127 #if DROPBEAR_ED25519
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1658
diff changeset
128 case DROPBEAR_SIGNKEY_ED25519:
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1658
diff changeset
129 key->ed25519key = gen_ed25519_priv_key(bits);
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1658
diff changeset
130 break;
d32bcb5c557d Add Ed25519 support (#91)
Vladislav Grishenko <themiron@users.noreply.github.com>
parents: 1658
diff changeset
131 #endif
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
132 default:
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
133 dropbear_exit("Internal error");
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
134 }
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
135
852
7540c0822374 Various cleanups and fixes for warnings
Matt Johnston <matt@ucc.asn.au>
parents: 847
diff changeset
136 seedrandom();
7540c0822374 Various cleanups and fixes for warnings
Matt Johnston <matt@ucc.asn.au>
parents: 847
diff changeset
137
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
138 buf = buf_new(MAX_PRIVKEY_SIZE);
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
139
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
140 buf_put_priv_key(buf, key, keytype);
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
141 sign_key_free(key);
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
142 key = NULL;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
143 buf_setpos(buf, 0);
1329
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
144
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
145 fn_temp = m_malloc(strlen(filename) + 30);
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
146 snprintf(fn_temp, strlen(filename)+30, "%s.tmp%d", filename, getpid());
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
147 ret = buf_writefile(buf, fn_temp);
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
148
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
149 if (ret == DROPBEAR_FAILURE) {
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
150 goto out;
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
151 }
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
152
1329
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
153 if (link(fn_temp, filename) < 0) {
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
154 /* If generating keys on connection (skipexist) it's OK to get EEXIST
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
155 - we probably just lost a race with another connection to generate the key */
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
156 if (!(skip_exist && errno == EEXIST)) {
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
157 dropbear_log(LOG_ERR, "Failed moving key file to %s: %s", filename,
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
158 strerror(errno));
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
159 /* XXX fallback to non-atomic copy for some filesystems? */
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
160 ret = DROPBEAR_FAILURE;
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
161 goto out;
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
162 }
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
163 }
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
164
1658
7402218141d4 bring back fsync_parent_dir
Matt Johnston <matt@ucc.asn.au>
parents: 1438
diff changeset
165 /* ensure directory update is flushed to disk, otherwise we can end up
7402218141d4 bring back fsync_parent_dir
Matt Johnston <matt@ucc.asn.au>
parents: 1438
diff changeset
166 with zero-byte hostkey files if the power goes off */
7402218141d4 bring back fsync_parent_dir
Matt Johnston <matt@ucc.asn.au>
parents: 1438
diff changeset
167 fsync_parent_dir(filename);
7402218141d4 bring back fsync_parent_dir
Matt Johnston <matt@ucc.asn.au>
parents: 1438
diff changeset
168
1329
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
169 out:
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
170 if (buf) {
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
171 buf_burn(buf);
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
172 buf_free(buf);
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
173 }
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
174
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
175 if (fn_temp) {
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
176 unlink(fn_temp);
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
177 m_free(fn_temp);
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
178 }
185c14fa504d Use atomic key generation in all cases
Matt Johnston <matt@ucc.asn.au>
parents: 1295
diff changeset
179
846
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
180 return ret;
b298bb438625 refactor key generation, make it generate as required.
Matt Johnston <matt@ucc.asn.au>
parents:
diff changeset
181 }