1 |
< |
/* $OpenBSD: authfile.c,v 1.97 2013/05/17 00:13:13 djm Exp $ */ |
1 |
> |
/* $OpenBSD: authfile.c,v 1.103 2014/02/02 03:44:31 djm Exp $ */ |
2 |
|
/* |
3 |
|
* Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 |
|
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
13 |
|
* called by a name other than "ssh" or "Secure Shell". |
14 |
|
* |
15 |
|
* |
16 |
< |
* Copyright (c) 2000 Markus Friedl. All rights reserved. |
16 |
> |
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. |
17 |
|
* |
18 |
|
* Redistribution and use in source and binary forms, with or without |
19 |
|
* modification, are permitted provided that the following conditions |
50 |
|
/* compatibility with old or broken OpenSSL versions */ |
51 |
|
#include "openbsd-compat/openssl-compat.h" |
52 |
|
|
53 |
+ |
#include "crypto_api.h" |
54 |
+ |
|
55 |
|
#include <errno.h> |
56 |
|
#include <fcntl.h> |
57 |
|
#include <stdarg.h> |
60 |
|
#include <string.h> |
61 |
|
#include <unistd.h> |
62 |
|
|
63 |
+ |
#ifdef HAVE_UTIL_H |
64 |
+ |
#include <util.h> |
65 |
+ |
#endif |
66 |
+ |
|
67 |
|
#include "xmalloc.h" |
68 |
|
#include "cipher.h" |
69 |
|
#include "buffer.h" |
74 |
|
#include "rsa.h" |
75 |
|
#include "misc.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 |
87 |
+ |
|
88 |
|
#define MAX_KEY_FILE_SIZE (1024 * 1024) |
89 |
|
|
90 |
|
/* Version identification string for SSH v1 identity files. */ |
91 |
|
static const char authfile_id_string[] = |
92 |
|
"SSH PRIVATE KEY FILE FORMAT 1.1\n"; |
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 |
+ |
explicit_bzero(key, 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 |
+ |
explicit_bzero(cp, 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 |
+ |
explicit_bzero(key, 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 |
+ |
|
421 |
|
/* |
422 |
|
* Serialises the authentication (private) key to a blob, encrypting it with |
423 |
|
* passphrase. The identification of the blob (lowest 64 bits of n) will |
492 |
|
|
493 |
|
cipher_set_key_string(&ciphercontext, cipher, passphrase, |
494 |
|
CIPHER_ENCRYPT); |
495 |
< |
cipher_crypt(&ciphercontext, cp, |
496 |
< |
buffer_ptr(&buffer), buffer_len(&buffer), 0, 0); |
495 |
> |
if (cipher_crypt(&ciphercontext, 0, cp, |
496 |
> |
buffer_ptr(&buffer), buffer_len(&buffer), 0, 0) != 0) |
497 |
> |
fatal("%s: cipher_crypt failed", __func__); |
498 |
|
cipher_cleanup(&ciphercontext); |
499 |
< |
memset(&ciphercontext, 0, sizeof(ciphercontext)); |
499 |
> |
explicit_bzero(&ciphercontext, sizeof(ciphercontext)); |
500 |
|
|
501 |
|
/* Destroy temporary data. */ |
502 |
< |
memset(buf, 0, sizeof(buf)); |
502 |
> |
explicit_bzero(buf, sizeof(buf)); |
503 |
|
buffer_free(&buffer); |
504 |
|
|
505 |
|
buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted)); |
583 |
|
/* Serialise "key" to buffer "blob" */ |
584 |
|
static int |
585 |
|
key_private_to_blob(Key *key, Buffer *blob, const char *passphrase, |
586 |
< |
const char *comment) |
586 |
> |
const char *comment, int force_new_format, const char *new_format_cipher, |
587 |
> |
int new_format_rounds) |
588 |
|
{ |
589 |
|
switch (key->type) { |
590 |
|
case KEY_RSA1: |
592 |
|
case KEY_DSA: |
593 |
|
case KEY_ECDSA: |
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 |
+ |
} |
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); |
603 |
|
default: |
604 |
|
error("%s: cannot save key type %d", __func__, key->type); |
605 |
|
return 0; |
608 |
|
|
609 |
|
int |
610 |
|
key_save_private(Key *key, const char *filename, const char *passphrase, |
611 |
< |
const char *comment) |
611 |
> |
const char *comment, int force_new_format, const char *new_format_cipher, |
612 |
> |
int new_format_rounds) |
613 |
|
{ |
614 |
|
Buffer keyblob; |
615 |
|
int success = 0; |
616 |
|
|
617 |
|
buffer_init(&keyblob); |
618 |
< |
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)) |
620 |
|
goto out; |
621 |
|
if (!key_save_private_blob(&keyblob, filename)) |
622 |
|
goto out; |
703 |
|
__func__, filename == NULL ? "" : filename, |
704 |
|
filename == NULL ? "" : " ", strerror(errno)); |
705 |
|
buffer_clear(blob); |
706 |
< |
bzero(buf, sizeof(buf)); |
706 |
> |
explicit_bzero(buf, sizeof(buf)); |
707 |
|
return 0; |
708 |
|
} |
709 |
|
buffer_append(blob, buf, len); |
710 |
|
if (buffer_len(blob) > MAX_KEY_FILE_SIZE) { |
711 |
|
buffer_clear(blob); |
712 |
< |
bzero(buf, sizeof(buf)); |
712 |
> |
explicit_bzero(buf, sizeof(buf)); |
713 |
|
goto toobig; |
714 |
|
} |
715 |
|
} |
716 |
< |
bzero(buf, sizeof(buf)); |
716 |
> |
explicit_bzero(buf, sizeof(buf)); |
717 |
|
if ((st.st_mode & (S_IFSOCK|S_IFCHR|S_IFIFO)) == 0 && |
718 |
|
st.st_size != buffer_len(blob)) { |
719 |
|
debug("%s: key file %.200s%schanged size while reading", |
827 |
|
/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ |
828 |
|
cipher_set_key_string(&ciphercontext, cipher, passphrase, |
829 |
|
CIPHER_DECRYPT); |
830 |
< |
cipher_crypt(&ciphercontext, cp, |
831 |
< |
buffer_ptr(©), buffer_len(©), 0, 0); |
830 |
> |
if (cipher_crypt(&ciphercontext, 0, cp, |
831 |
> |
buffer_ptr(©), buffer_len(©), 0, 0) != 0) |
832 |
> |
fatal("%s: cipher_crypt failed", __func__); |
833 |
|
cipher_cleanup(&ciphercontext); |
834 |
< |
memset(&ciphercontext, 0, sizeof(ciphercontext)); |
834 |
> |
explicit_bzero(&ciphercontext, sizeof(ciphercontext)); |
835 |
|
buffer_free(©); |
836 |
|
|
837 |
|
check1 = buffer_get_char(&decrypted); |
996 |
|
key_parse_private_type(Buffer *blob, int type, const char *passphrase, |
997 |
|
char **commentp) |
998 |
|
{ |
999 |
+ |
Key *k; |
1000 |
+ |
|
1001 |
|
switch (type) { |
1002 |
|
case KEY_RSA1: |
1003 |
|
return key_parse_private_rsa1(blob, passphrase, commentp); |
1004 |
|
case KEY_DSA: |
1005 |
|
case KEY_ECDSA: |
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); |
1010 |
|
case KEY_UNSPEC: |
1011 |
+ |
if ((k = key_parse_private2(blob, type, passphrase, commentp))) |
1012 |
+ |
return k; |
1013 |
|
return key_parse_private_pem(blob, type, passphrase, commentp); |
1014 |
|
default: |
1015 |
|
error("%s: cannot parse key type %d", __func__, type); |
1213 |
|
case KEY_RSA: |
1214 |
|
case KEY_DSA: |
1215 |
|
case KEY_ECDSA: |
1216 |
+ |
case KEY_ED25519: |
1217 |
|
break; |
1218 |
|
default: |
1219 |
|
error("%s: unsupported key type", __func__); |
1306 |
|
fclose(f); |
1307 |
|
return ret; |
1308 |
|
} |
946 |
– |
|