diff options
author | Colin Watson <cjwatson@debian.org> | 2014-02-10 00:18:28 +0000 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2014-02-10 00:18:28 +0000 |
commit | 9a975a9faed7c4f334e8c8490db3e77e102f2b21 (patch) | |
tree | 764a885ec9a963f6a8b15de6e1765f16b9ac4738 /authfile.c | |
parent | ee196dab7c5f97f0b80c8099343a375bead92010 (diff) | |
parent | cdb6c90811caa5df2df856be9b0b16db020fe31d (diff) |
Import openssh_6.5p1.orig.tar.gz
Diffstat (limited to 'authfile.c')
-rw-r--r-- | authfile.c | 382 |
1 files changed, 372 insertions, 10 deletions
diff --git a/authfile.c b/authfile.c index 63ae16bbd..7eccbb2c9 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: authfile.c,v 1.97 2013/05/17 00:13:13 djm Exp $ */ | 1 | /* $OpenBSD: authfile.c,v 1.101 2013/12/29 04:35:50 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -13,7 +13,7 @@ | |||
13 | * called by a name other than "ssh" or "Secure Shell". | 13 | * called by a name other than "ssh" or "Secure Shell". |
14 | * | 14 | * |
15 | * | 15 | * |
16 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 16 | * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. |
17 | * | 17 | * |
18 | * Redistribution and use in source and binary forms, with or without | 18 | * Redistribution and use in source and binary forms, with or without |
19 | * modification, are permitted provided that the following conditions | 19 | * modification, are permitted provided that the following conditions |
@@ -50,6 +50,8 @@ | |||
50 | /* compatibility with old or broken OpenSSL versions */ | 50 | /* compatibility with old or broken OpenSSL versions */ |
51 | #include "openbsd-compat/openssl-compat.h" | 51 | #include "openbsd-compat/openssl-compat.h" |
52 | 52 | ||
53 | #include "crypto_api.h" | ||
54 | |||
53 | #include <errno.h> | 55 | #include <errno.h> |
54 | #include <fcntl.h> | 56 | #include <fcntl.h> |
55 | #include <stdarg.h> | 57 | #include <stdarg.h> |
@@ -58,6 +60,10 @@ | |||
58 | #include <string.h> | 60 | #include <string.h> |
59 | #include <unistd.h> | 61 | #include <unistd.h> |
60 | 62 | ||
63 | #ifdef HAVE_UTIL_H | ||
64 | #include <util.h> | ||
65 | #endif | ||
66 | |||
61 | #include "xmalloc.h" | 67 | #include "xmalloc.h" |
62 | #include "cipher.h" | 68 | #include "cipher.h" |
63 | #include "buffer.h" | 69 | #include "buffer.h" |
@@ -68,6 +74,16 @@ | |||
68 | #include "rsa.h" | 74 | #include "rsa.h" |
69 | #include "misc.h" | 75 | #include "misc.h" |
70 | #include "atomicio.h" | 76 | #include "atomicio.h" |
77 | #include "uuencode.h" | ||
78 | |||
79 | /* openssh private key file format */ | ||
80 | #define MARK_BEGIN "-----BEGIN OPENSSH PRIVATE KEY-----\n" | ||
81 | #define MARK_END "-----END OPENSSH PRIVATE KEY-----\n" | ||
82 | #define KDFNAME "bcrypt" | ||
83 | #define AUTH_MAGIC "openssh-key-v1" | ||
84 | #define SALT_LEN 16 | ||
85 | #define DEFAULT_CIPHERNAME "aes256-cbc" | ||
86 | #define DEFAULT_ROUNDS 16 | ||
71 | 87 | ||
72 | #define MAX_KEY_FILE_SIZE (1024 * 1024) | 88 | #define MAX_KEY_FILE_SIZE (1024 * 1024) |
73 | 89 | ||
@@ -75,6 +91,333 @@ | |||
75 | static const char authfile_id_string[] = | 91 | static const char authfile_id_string[] = |
76 | "SSH PRIVATE KEY FILE FORMAT 1.1\n"; | 92 | "SSH PRIVATE KEY FILE FORMAT 1.1\n"; |
77 | 93 | ||
94 | static int | ||
95 | key_private_to_blob2(Key *prv, Buffer *blob, const char *passphrase, | ||
96 | const char *comment, const char *ciphername, int rounds) | ||
97 | { | ||
98 | u_char *key, *cp, salt[SALT_LEN]; | ||
99 | size_t keylen, ivlen, blocksize, authlen; | ||
100 | u_int len, check; | ||
101 | int i, n; | ||
102 | const Cipher *c; | ||
103 | Buffer encoded, b, kdf; | ||
104 | CipherContext ctx; | ||
105 | const char *kdfname = KDFNAME; | ||
106 | |||
107 | if (rounds <= 0) | ||
108 | rounds = DEFAULT_ROUNDS; | ||
109 | if (passphrase == NULL || !strlen(passphrase)) { | ||
110 | ciphername = "none"; | ||
111 | kdfname = "none"; | ||
112 | } else if (ciphername == NULL) | ||
113 | ciphername = DEFAULT_CIPHERNAME; | ||
114 | else if (cipher_number(ciphername) != SSH_CIPHER_SSH2) | ||
115 | fatal("invalid cipher"); | ||
116 | |||
117 | if ((c = cipher_by_name(ciphername)) == NULL) | ||
118 | fatal("unknown cipher name"); | ||
119 | buffer_init(&kdf); | ||
120 | blocksize = cipher_blocksize(c); | ||
121 | keylen = cipher_keylen(c); | ||
122 | ivlen = cipher_ivlen(c); | ||
123 | authlen = cipher_authlen(c); | ||
124 | key = xcalloc(1, keylen + ivlen); | ||
125 | if (strcmp(kdfname, "none") != 0) { | ||
126 | arc4random_buf(salt, SALT_LEN); | ||
127 | if (bcrypt_pbkdf(passphrase, strlen(passphrase), | ||
128 | salt, SALT_LEN, key, keylen + ivlen, rounds) < 0) | ||
129 | fatal("bcrypt_pbkdf failed"); | ||
130 | buffer_put_string(&kdf, salt, SALT_LEN); | ||
131 | buffer_put_int(&kdf, rounds); | ||
132 | } | ||
133 | cipher_init(&ctx, c, key, keylen, key + keylen , ivlen, 1); | ||
134 | memset(key, 0, keylen + ivlen); | ||
135 | free(key); | ||
136 | |||
137 | buffer_init(&encoded); | ||
138 | buffer_append(&encoded, AUTH_MAGIC, sizeof(AUTH_MAGIC)); | ||
139 | buffer_put_cstring(&encoded, ciphername); | ||
140 | buffer_put_cstring(&encoded, kdfname); | ||
141 | buffer_put_string(&encoded, buffer_ptr(&kdf), buffer_len(&kdf)); | ||
142 | buffer_put_int(&encoded, 1); /* number of keys */ | ||
143 | key_to_blob(prv, &cp, &len); /* public key */ | ||
144 | buffer_put_string(&encoded, cp, len); | ||
145 | |||
146 | memset(cp, 0, len); | ||
147 | free(cp); | ||
148 | |||
149 | buffer_free(&kdf); | ||
150 | |||
151 | /* set up the buffer that will be encrypted */ | ||
152 | buffer_init(&b); | ||
153 | |||
154 | /* Random check bytes */ | ||
155 | check = arc4random(); | ||
156 | buffer_put_int(&b, check); | ||
157 | buffer_put_int(&b, check); | ||
158 | |||
159 | /* append private key and comment*/ | ||
160 | key_private_serialize(prv, &b); | ||
161 | buffer_put_cstring(&b, comment); | ||
162 | |||
163 | /* padding */ | ||
164 | i = 0; | ||
165 | while (buffer_len(&b) % blocksize) | ||
166 | buffer_put_char(&b, ++i & 0xff); | ||
167 | |||
168 | /* length */ | ||
169 | buffer_put_int(&encoded, buffer_len(&b)); | ||
170 | |||
171 | /* encrypt */ | ||
172 | cp = buffer_append_space(&encoded, buffer_len(&b) + authlen); | ||
173 | if (cipher_crypt(&ctx, 0, cp, buffer_ptr(&b), buffer_len(&b), 0, | ||
174 | authlen) != 0) | ||
175 | fatal("%s: cipher_crypt failed", __func__); | ||
176 | buffer_free(&b); | ||
177 | cipher_cleanup(&ctx); | ||
178 | |||
179 | /* uuencode */ | ||
180 | len = 2 * buffer_len(&encoded); | ||
181 | cp = xmalloc(len); | ||
182 | n = uuencode(buffer_ptr(&encoded), buffer_len(&encoded), | ||
183 | (char *)cp, len); | ||
184 | if (n < 0) | ||
185 | fatal("%s: uuencode", __func__); | ||
186 | |||
187 | buffer_clear(blob); | ||
188 | buffer_append(blob, MARK_BEGIN, sizeof(MARK_BEGIN) - 1); | ||
189 | for (i = 0; i < n; i++) { | ||
190 | buffer_put_char(blob, cp[i]); | ||
191 | if (i % 70 == 69) | ||
192 | buffer_put_char(blob, '\n'); | ||
193 | } | ||
194 | if (i % 70 != 69) | ||
195 | buffer_put_char(blob, '\n'); | ||
196 | buffer_append(blob, MARK_END, sizeof(MARK_END) - 1); | ||
197 | free(cp); | ||
198 | |||
199 | return buffer_len(blob); | ||
200 | } | ||
201 | |||
202 | static Key * | ||
203 | key_parse_private2(Buffer *blob, int type, const char *passphrase, | ||
204 | char **commentp) | ||
205 | { | ||
206 | u_char *key = NULL, *cp, *salt = NULL, pad, last; | ||
207 | char *comment = NULL, *ciphername = NULL, *kdfname = NULL, *kdfp; | ||
208 | u_int keylen = 0, ivlen, blocksize, slen, klen, len, rounds, nkeys; | ||
209 | u_int check1, check2, m1len, m2len; | ||
210 | size_t authlen; | ||
211 | const Cipher *c; | ||
212 | Buffer b, encoded, copy, kdf; | ||
213 | CipherContext ctx; | ||
214 | Key *k = NULL; | ||
215 | int dlen, ret, i; | ||
216 | |||
217 | buffer_init(&b); | ||
218 | buffer_init(&kdf); | ||
219 | buffer_init(&encoded); | ||
220 | buffer_init(©); | ||
221 | |||
222 | /* uudecode */ | ||
223 | m1len = sizeof(MARK_BEGIN) - 1; | ||
224 | m2len = sizeof(MARK_END) - 1; | ||
225 | cp = buffer_ptr(blob); | ||
226 | len = buffer_len(blob); | ||
227 | if (len < m1len || memcmp(cp, MARK_BEGIN, m1len)) { | ||
228 | debug("%s: missing begin marker", __func__); | ||
229 | goto out; | ||
230 | } | ||
231 | cp += m1len; | ||
232 | len -= m1len; | ||
233 | while (len) { | ||
234 | if (*cp != '\n' && *cp != '\r') | ||
235 | buffer_put_char(&encoded, *cp); | ||
236 | last = *cp; | ||
237 | len--; | ||
238 | cp++; | ||
239 | if (last == '\n') { | ||
240 | if (len >= m2len && !memcmp(cp, MARK_END, m2len)) { | ||
241 | buffer_put_char(&encoded, '\0'); | ||
242 | break; | ||
243 | } | ||
244 | } | ||
245 | } | ||
246 | if (!len) { | ||
247 | debug("%s: no end marker", __func__); | ||
248 | goto out; | ||
249 | } | ||
250 | len = buffer_len(&encoded); | ||
251 | if ((cp = buffer_append_space(©, len)) == NULL) { | ||
252 | error("%s: buffer_append_space", __func__); | ||
253 | goto out; | ||
254 | } | ||
255 | if ((dlen = uudecode(buffer_ptr(&encoded), cp, len)) < 0) { | ||
256 | error("%s: uudecode failed", __func__); | ||
257 | goto out; | ||
258 | } | ||
259 | if ((u_int)dlen > len) { | ||
260 | error("%s: crazy uudecode length %d > %u", __func__, dlen, len); | ||
261 | goto out; | ||
262 | } | ||
263 | buffer_consume_end(©, len - dlen); | ||
264 | if (buffer_len(©) < sizeof(AUTH_MAGIC) || | ||
265 | memcmp(buffer_ptr(©), AUTH_MAGIC, sizeof(AUTH_MAGIC))) { | ||
266 | error("%s: bad magic", __func__); | ||
267 | goto out; | ||
268 | } | ||
269 | buffer_consume(©, sizeof(AUTH_MAGIC)); | ||
270 | |||
271 | ciphername = buffer_get_cstring_ret(©, NULL); | ||
272 | if (ciphername == NULL || | ||
273 | (c = cipher_by_name(ciphername)) == NULL) { | ||
274 | error("%s: unknown cipher name", __func__); | ||
275 | goto out; | ||
276 | } | ||
277 | if ((passphrase == NULL || !strlen(passphrase)) && | ||
278 | strcmp(ciphername, "none") != 0) { | ||
279 | /* passphrase required */ | ||
280 | goto out; | ||
281 | } | ||
282 | kdfname = buffer_get_cstring_ret(©, NULL); | ||
283 | if (kdfname == NULL || | ||
284 | (!strcmp(kdfname, "none") && !strcmp(kdfname, "bcrypt"))) { | ||
285 | error("%s: unknown kdf name", __func__); | ||
286 | goto out; | ||
287 | } | ||
288 | if (!strcmp(kdfname, "none") && strcmp(ciphername, "none") != 0) { | ||
289 | error("%s: cipher %s requires kdf", __func__, ciphername); | ||
290 | goto out; | ||
291 | } | ||
292 | /* kdf options */ | ||
293 | kdfp = buffer_get_string_ptr_ret(©, &klen); | ||
294 | if (kdfp == NULL) { | ||
295 | error("%s: kdf options not set", __func__); | ||
296 | goto out; | ||
297 | } | ||
298 | if (klen > 0) { | ||
299 | if ((cp = buffer_append_space(&kdf, klen)) == NULL) { | ||
300 | error("%s: kdf alloc failed", __func__); | ||
301 | goto out; | ||
302 | } | ||
303 | memcpy(cp, kdfp, klen); | ||
304 | } | ||
305 | /* number of keys */ | ||
306 | if (buffer_get_int_ret(&nkeys, ©) < 0) { | ||
307 | error("%s: key counter missing", __func__); | ||
308 | goto out; | ||
309 | } | ||
310 | if (nkeys != 1) { | ||
311 | error("%s: only one key supported", __func__); | ||
312 | goto out; | ||
313 | } | ||
314 | /* pubkey */ | ||
315 | if ((cp = buffer_get_string_ret(©, &len)) == NULL) { | ||
316 | error("%s: pubkey not found", __func__); | ||
317 | goto out; | ||
318 | } | ||
319 | free(cp); /* XXX check pubkey against decrypted private key */ | ||
320 | |||
321 | /* size of encrypted key blob */ | ||
322 | len = buffer_get_int(©); | ||
323 | blocksize = cipher_blocksize(c); | ||
324 | authlen = cipher_authlen(c); | ||
325 | if (len < blocksize) { | ||
326 | error("%s: encrypted data too small", __func__); | ||
327 | goto out; | ||
328 | } | ||
329 | if (len % blocksize) { | ||
330 | error("%s: length not multiple of blocksize", __func__); | ||
331 | goto out; | ||
332 | } | ||
333 | |||
334 | /* setup key */ | ||
335 | keylen = cipher_keylen(c); | ||
336 | ivlen = cipher_ivlen(c); | ||
337 | key = xcalloc(1, keylen + ivlen); | ||
338 | if (!strcmp(kdfname, "bcrypt")) { | ||
339 | if ((salt = buffer_get_string_ret(&kdf, &slen)) == NULL) { | ||
340 | error("%s: salt not set", __func__); | ||
341 | goto out; | ||
342 | } | ||
343 | if (buffer_get_int_ret(&rounds, &kdf) < 0) { | ||
344 | error("%s: rounds not set", __func__); | ||
345 | goto out; | ||
346 | } | ||
347 | if (bcrypt_pbkdf(passphrase, strlen(passphrase), salt, slen, | ||
348 | key, keylen + ivlen, rounds) < 0) { | ||
349 | error("%s: bcrypt_pbkdf failed", __func__); | ||
350 | goto out; | ||
351 | } | ||
352 | } | ||
353 | |||
354 | cp = buffer_append_space(&b, len); | ||
355 | cipher_init(&ctx, c, key, keylen, key + keylen, ivlen, 0); | ||
356 | ret = cipher_crypt(&ctx, 0, cp, buffer_ptr(©), len, 0, authlen); | ||
357 | cipher_cleanup(&ctx); | ||
358 | buffer_consume(©, len); | ||
359 | |||
360 | /* fail silently on decryption errors */ | ||
361 | if (ret != 0) { | ||
362 | debug("%s: decrypt failed", __func__); | ||
363 | goto out; | ||
364 | } | ||
365 | |||
366 | if (buffer_len(©) != 0) { | ||
367 | error("%s: key blob has trailing data (len = %u)", __func__, | ||
368 | buffer_len(©)); | ||
369 | goto out; | ||
370 | } | ||
371 | |||
372 | /* check bytes */ | ||
373 | if (buffer_get_int_ret(&check1, &b) < 0 || | ||
374 | buffer_get_int_ret(&check2, &b) < 0) { | ||
375 | error("check bytes missing"); | ||
376 | goto out; | ||
377 | } | ||
378 | if (check1 != check2) { | ||
379 | debug("%s: decrypt failed: 0x%08x != 0x%08x", __func__, | ||
380 | check1, check2); | ||
381 | goto out; | ||
382 | } | ||
383 | |||
384 | k = key_private_deserialize(&b); | ||
385 | |||
386 | /* comment */ | ||
387 | comment = buffer_get_cstring_ret(&b, NULL); | ||
388 | |||
389 | i = 0; | ||
390 | while (buffer_len(&b)) { | ||
391 | if (buffer_get_char_ret(&pad, &b) == -1 || | ||
392 | pad != (++i & 0xff)) { | ||
393 | error("%s: bad padding", __func__); | ||
394 | key_free(k); | ||
395 | k = NULL; | ||
396 | goto out; | ||
397 | } | ||
398 | } | ||
399 | |||
400 | if (k && commentp) { | ||
401 | *commentp = comment; | ||
402 | comment = NULL; | ||
403 | } | ||
404 | |||
405 | /* XXX decode pubkey and check against private */ | ||
406 | out: | ||
407 | free(ciphername); | ||
408 | free(kdfname); | ||
409 | free(salt); | ||
410 | free(comment); | ||
411 | if (key) | ||
412 | memset(key, 0, keylen + ivlen); | ||
413 | free(key); | ||
414 | buffer_free(&encoded); | ||
415 | buffer_free(©); | ||
416 | buffer_free(&kdf); | ||
417 | buffer_free(&b); | ||
418 | return k; | ||
419 | } | ||
420 | |||
78 | /* | 421 | /* |
79 | * Serialises the authentication (private) key to a blob, encrypting it with | 422 | * Serialises the authentication (private) key to a blob, encrypting it with |
80 | * passphrase. The identification of the blob (lowest 64 bits of n) will | 423 | * passphrase. The identification of the blob (lowest 64 bits of n) will |
@@ -149,8 +492,9 @@ key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase, | |||
149 | 492 | ||
150 | cipher_set_key_string(&ciphercontext, cipher, passphrase, | 493 | cipher_set_key_string(&ciphercontext, cipher, passphrase, |
151 | CIPHER_ENCRYPT); | 494 | CIPHER_ENCRYPT); |
152 | cipher_crypt(&ciphercontext, cp, | 495 | if (cipher_crypt(&ciphercontext, 0, cp, |
153 | buffer_ptr(&buffer), buffer_len(&buffer), 0, 0); | 496 | buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0) |
497 | fatal("%s: cipher_crypt failed", __func__); | ||
154 | cipher_cleanup(&ciphercontext); | 498 | cipher_cleanup(&ciphercontext); |
155 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | 499 | memset(&ciphercontext, 0, sizeof(ciphercontext)); |
156 | 500 | ||
@@ -239,7 +583,8 @@ key_save_private_blob(Buffer *keybuf, const char *filename) | |||
239 | /* Serialise "key" to buffer "blob" */ | 583 | /* Serialise "key" to buffer "blob" */ |
240 | static int | 584 | static int |
241 | key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, | 585 | key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, |
242 | const char *comment) | 586 | const char *comment, int force_new_format, const char *new_format_cipher, |
587 | int new_format_rounds) | ||
243 | { | 588 | { |
244 | switch (key->type) { | 589 | switch (key->type) { |
245 | case KEY_RSA1: | 590 | case KEY_RSA1: |
@@ -247,7 +592,14 @@ key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, | |||
247 | case KEY_DSA: | 592 | case KEY_DSA: |
248 | case KEY_ECDSA: | 593 | case KEY_ECDSA: |
249 | case KEY_RSA: | 594 | case KEY_RSA: |
595 | if (force_new_format) { | ||
596 | return key_private_to_blob2(key, blob, passphrase, | ||
597 | comment, new_format_cipher, new_format_rounds); | ||
598 | } | ||
250 | return key_private_pem_to_blob(key, blob, passphrase, comment); | 599 | return key_private_pem_to_blob(key, blob, passphrase, comment); |
600 | case KEY_ED25519: | ||
601 | return key_private_to_blob2(key, blob, passphrase, | ||
602 | comment, new_format_cipher, new_format_rounds); | ||
251 | default: | 603 | default: |
252 | error("%s: cannot save key type %d", __func__, key->type); | 604 | error("%s: cannot save key type %d", __func__, key->type); |
253 | return 0; | 605 | return 0; |
@@ -256,13 +608,15 @@ key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, | |||
256 | 608 | ||
257 | int | 609 | int |
258 | key_save_private(Key *key, const char *filename, const char *passphrase, | 610 | key_save_private(Key *key, const char *filename, const char *passphrase, |
259 | const char *comment) | 611 | const char *comment, int force_new_format, const char *new_format_cipher, |
612 | int new_format_rounds) | ||
260 | { | 613 | { |
261 | Buffer keyblob; | 614 | Buffer keyblob; |
262 | int success = 0; | 615 | int success = 0; |
263 | 616 | ||
264 | buffer_init(&keyblob); | 617 | buffer_init(&keyblob); |
265 | if (!key_private_to_blob(key, &keyblob, passphrase, comment)) | 618 | if (!key_private_to_blob(key, &keyblob, passphrase, comment, |
619 | force_new_format, new_format_cipher, new_format_rounds)) | ||
266 | goto out; | 620 | goto out; |
267 | if (!key_save_private_blob(&keyblob, filename)) | 621 | if (!key_save_private_blob(&keyblob, filename)) |
268 | goto out; | 622 | goto out; |
@@ -473,8 +827,9 @@ key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp) | |||
473 | /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ | 827 | /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ |
474 | cipher_set_key_string(&ciphercontext, cipher, passphrase, | 828 | cipher_set_key_string(&ciphercontext, cipher, passphrase, |
475 | CIPHER_DECRYPT); | 829 | CIPHER_DECRYPT); |
476 | cipher_crypt(&ciphercontext, cp, | 830 | if (cipher_crypt(&ciphercontext, 0, cp, |
477 | buffer_ptr(©), buffer_len(©), 0, 0); | 831 | buffer_ptr(©), buffer_len(©), 0, 0) != 0) |
832 | fatal("%s: cipher_crypt failed", __func__); | ||
478 | cipher_cleanup(&ciphercontext); | 833 | cipher_cleanup(&ciphercontext); |
479 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | 834 | memset(&ciphercontext, 0, sizeof(ciphercontext)); |
480 | buffer_free(©); | 835 | buffer_free(©); |
@@ -641,13 +996,20 @@ static Key * | |||
641 | key_parse_private_type(Buffer *blob, int type, const char *passphrase, | 996 | key_parse_private_type(Buffer *blob, int type, const char *passphrase, |
642 | char **commentp) | 997 | char **commentp) |
643 | { | 998 | { |
999 | Key *k; | ||
1000 | |||
644 | switch (type) { | 1001 | switch (type) { |
645 | case KEY_RSA1: | 1002 | case KEY_RSA1: |
646 | return key_parse_private_rsa1(blob, passphrase, commentp); | 1003 | return key_parse_private_rsa1(blob, passphrase, commentp); |
647 | case KEY_DSA: | 1004 | case KEY_DSA: |
648 | case KEY_ECDSA: | 1005 | case KEY_ECDSA: |
649 | case KEY_RSA: | 1006 | case KEY_RSA: |
1007 | return key_parse_private_pem(blob, type, passphrase, commentp); | ||
1008 | case KEY_ED25519: | ||
1009 | return key_parse_private2(blob, type, passphrase, commentp); | ||
650 | case KEY_UNSPEC: | 1010 | case KEY_UNSPEC: |
1011 | if ((k = key_parse_private2(blob, type, passphrase, commentp))) | ||
1012 | return k; | ||
651 | return key_parse_private_pem(blob, type, passphrase, commentp); | 1013 | return key_parse_private_pem(blob, type, passphrase, commentp); |
652 | default: | 1014 | default: |
653 | error("%s: cannot parse key type %d", __func__, type); | 1015 | error("%s: cannot parse key type %d", __func__, type); |
@@ -851,6 +1213,7 @@ key_load_private_cert(int type, const char *filename, const char *passphrase, | |||
851 | case KEY_RSA: | 1213 | case KEY_RSA: |
852 | case KEY_DSA: | 1214 | case KEY_DSA: |
853 | case KEY_ECDSA: | 1215 | case KEY_ECDSA: |
1216 | case KEY_ED25519: | ||
854 | break; | 1217 | break; |
855 | default: | 1218 | default: |
856 | error("%s: unsupported key type", __func__); | 1219 | error("%s: unsupported key type", __func__); |
@@ -943,4 +1306,3 @@ key_in_file(Key *key, const char *filename, int strict_type) | |||
943 | fclose(f); | 1306 | fclose(f); |
944 | return ret; | 1307 | return ret; |
945 | } | 1308 | } |
946 | |||