Mercurial > dropbear
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 |
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 | 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 | 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 | 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 | 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 | 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 | 64 case DROPBEAR_SIGNKEY_ECDSA_KEYGEN: |
65 return ECDSA_DEFAULT_SIZE; | |
66 case DROPBEAR_SIGNKEY_ECDSA_NISTP521: | |
67 return 521; | |
68 case DROPBEAR_SIGNKEY_ECDSA_NISTP384: | |
69 return 384; | |
70 case DROPBEAR_SIGNKEY_ECDSA_NISTP256: | |
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 | 77 default: |
78 return 0; | |
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 } |