summaryrefslogtreecommitdiff
path: root/authfile.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2011-01-24 11:46:57 +0000
committerColin Watson <cjwatson@debian.org>2011-01-24 11:46:57 +0000
commit0970072c89b079b022538e3c366fbfa2c53fc821 (patch)
treeb7024712d74234bb5a8b036ccbc9109e2e211296 /authfile.c
parent4e8aa4da57000c7bba8e5c49163bc0c0ca383f78 (diff)
parent478ff799463ca926a8dfbabf058f4e84aaffc65a (diff)
merge 5.7p1
Diffstat (limited to 'authfile.c')
-rw-r--r--authfile.c474
1 files changed, 283 insertions, 191 deletions
diff --git a/authfile.c b/authfile.c
index 2bd887845..f2aec267a 100644
--- a/authfile.c
+++ b/authfile.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: authfile.c,v 1.82 2010/08/04 05:49:22 djm Exp $ */ 1/* $OpenBSD: authfile.c,v 1.87 2010/11/29 18:57:04 markus 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
@@ -74,19 +74,18 @@ static const char authfile_id_string[] =
74 "SSH PRIVATE KEY FILE FORMAT 1.1\n"; 74 "SSH PRIVATE KEY FILE FORMAT 1.1\n";
75 75
76/* 76/*
77 * Saves the authentication (private) key in a file, encrypting it with 77 * Serialises the authentication (private) key to a blob, encrypting it with
78 * passphrase. The identification of the file (lowest 64 bits of n) will 78 * passphrase. The identification of the blob (lowest 64 bits of n) will
79 * precede the key to provide identification of the key without needing a 79 * precede the key to provide identification of the key without needing a
80 * passphrase. 80 * passphrase.
81 */ 81 */
82
83static int 82static int
84key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, 83key_private_rsa1_to_blob(Key *key, Buffer *blob, const char *passphrase,
85 const char *comment) 84 const char *comment)
86{ 85{
87 Buffer buffer, encrypted; 86 Buffer buffer, encrypted;
88 u_char buf[100], *cp; 87 u_char buf[100], *cp;
89 int fd, i, cipher_num; 88 int i, cipher_num;
90 CipherContext ciphercontext; 89 CipherContext ciphercontext;
91 Cipher *cipher; 90 Cipher *cipher;
92 u_int32_t rnd; 91 u_int32_t rnd;
@@ -157,156 +156,222 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
157 memset(buf, 0, sizeof(buf)); 156 memset(buf, 0, sizeof(buf));
158 buffer_free(&buffer); 157 buffer_free(&buffer);
159 158
160 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); 159 buffer_append(blob, buffer_ptr(&encrypted), buffer_len(&encrypted));
161 if (fd < 0) {
162 error("open %s failed: %s.", filename, strerror(errno));
163 buffer_free(&encrypted);
164 return 0;
165 }
166 if (atomicio(vwrite, fd, buffer_ptr(&encrypted),
167 buffer_len(&encrypted)) != buffer_len(&encrypted)) {
168 error("write to key file %s failed: %s", filename,
169 strerror(errno));
170 buffer_free(&encrypted);
171 close(fd);
172 unlink(filename);
173 return 0;
174 }
175 close(fd);
176 buffer_free(&encrypted); 160 buffer_free(&encrypted);
161
177 return 1; 162 return 1;
178} 163}
179 164
180/* save SSH v2 key in OpenSSL PEM format */ 165/* convert SSH v2 key in OpenSSL PEM format */
181static int 166static int
182key_save_private_pem(Key *key, const char *filename, const char *_passphrase, 167key_private_pem_to_blob(Key *key, Buffer *blob, const char *_passphrase,
183 const char *comment) 168 const char *comment)
184{ 169{
185 FILE *fp;
186 int fd;
187 int success = 0; 170 int success = 0;
188 int len = strlen(_passphrase); 171 int blen, len = strlen(_passphrase);
189 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL; 172 u_char *passphrase = (len > 0) ? (u_char *)_passphrase : NULL;
190#if (OPENSSL_VERSION_NUMBER < 0x00907000L) 173#if (OPENSSL_VERSION_NUMBER < 0x00907000L)
191 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL; 174 const EVP_CIPHER *cipher = (len > 0) ? EVP_des_ede3_cbc() : NULL;
192#else 175#else
193 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL; 176 const EVP_CIPHER *cipher = (len > 0) ? EVP_aes_128_cbc() : NULL;
194#endif 177#endif
178 const u_char *bptr;
179 BIO *bio;
195 180
196 if (len > 0 && len <= 4) { 181 if (len > 0 && len <= 4) {
197 error("passphrase too short: have %d bytes, need > 4", len); 182 error("passphrase too short: have %d bytes, need > 4", len);
198 return 0; 183 return 0;
199 } 184 }
200 fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); 185 if ((bio = BIO_new(BIO_s_mem())) == NULL) {
201 if (fd < 0) { 186 error("%s: BIO_new failed", __func__);
202 error("open %s failed: %s.", filename, strerror(errno));
203 return 0;
204 }
205 fp = fdopen(fd, "w");
206 if (fp == NULL) {
207 error("fdopen %s failed: %s.", filename, strerror(errno));
208 close(fd);
209 return 0; 187 return 0;
210 } 188 }
211 switch (key->type) { 189 switch (key->type) {
212 case KEY_DSA: 190 case KEY_DSA:
213 success = PEM_write_DSAPrivateKey(fp, key->dsa, 191 success = PEM_write_bio_DSAPrivateKey(bio, key->dsa,
214 cipher, passphrase, len, NULL, NULL); 192 cipher, passphrase, len, NULL, NULL);
215 break; 193 break;
194#ifdef OPENSSL_HAS_ECC
195 case KEY_ECDSA:
196 success = PEM_write_bio_ECPrivateKey(bio, key->ecdsa,
197 cipher, passphrase, len, NULL, NULL);
198 break;
199#endif
216 case KEY_RSA: 200 case KEY_RSA:
217 success = PEM_write_RSAPrivateKey(fp, key->rsa, 201 success = PEM_write_bio_RSAPrivateKey(bio, key->rsa,
218 cipher, passphrase, len, NULL, NULL); 202 cipher, passphrase, len, NULL, NULL);
219 break; 203 break;
220 } 204 }
221 fclose(fp); 205 if (success) {
206 if ((blen = BIO_get_mem_data(bio, &bptr)) <= 0)
207 success = 0;
208 else
209 buffer_append(blob, bptr, blen);
210 }
211 BIO_free(bio);
222 return success; 212 return success;
223} 213}
224 214
225int 215/* Save a key blob to a file */
226key_save_private(Key *key, const char *filename, const char *passphrase, 216static int
217key_save_private_blob(Buffer *keybuf, const char *filename)
218{
219 int fd;
220
221 if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) {
222 error("open %s failed: %s.", filename, strerror(errno));
223 return 0;
224 }
225 if (atomicio(vwrite, fd, buffer_ptr(keybuf),
226 buffer_len(keybuf)) != buffer_len(keybuf)) {
227 error("write to key file %s failed: %s", filename,
228 strerror(errno));
229 close(fd);
230 unlink(filename);
231 return 0;
232 }
233 close(fd);
234 return 1;
235}
236
237/* Serialise "key" to buffer "blob" */
238static int
239key_private_to_blob(Key *key, Buffer *blob, const char *passphrase,
227 const char *comment) 240 const char *comment)
228{ 241{
229 switch (key->type) { 242 switch (key->type) {
230 case KEY_RSA1: 243 case KEY_RSA1:
231 return key_save_private_rsa1(key, filename, passphrase, 244 return key_private_rsa1_to_blob(key, blob, passphrase, comment);
232 comment);
233 case KEY_DSA: 245 case KEY_DSA:
246 case KEY_ECDSA:
234 case KEY_RSA: 247 case KEY_RSA:
235 return key_save_private_pem(key, filename, passphrase, 248 return key_private_pem_to_blob(key, blob, passphrase, comment);
236 comment);
237 default: 249 default:
238 break; 250 error("%s: cannot save key type %d", __func__, key->type);
251 return 0;
239 } 252 }
240 error("key_save_private: cannot save key type %d", key->type); 253}
241 return 0; 254
255int
256key_save_private(Key *key, const char *filename, const char *passphrase,
257 const char *comment)
258{
259 Buffer keyblob;
260 int success = 0;
261
262 buffer_init(&keyblob);
263 if (!key_private_to_blob(key, &keyblob, passphrase, comment))
264 goto out;
265 if (!key_save_private_blob(&keyblob, filename))
266 goto out;
267 success = 1;
268 out:
269 buffer_free(&keyblob);
270 return success;
242} 271}
243 272
244/* 273/*
245 * Loads the public part of the ssh v1 key file. Returns NULL if an error was 274 * Parse the public, unencrypted portion of a RSA1 key.
246 * encountered (the file does not exist or is not readable), and the key
247 * otherwise.
248 */ 275 */
249
250static Key * 276static Key *
251key_load_public_rsa1(int fd, const char *filename, char **commentp) 277key_parse_public_rsa1(Buffer *blob, char **commentp)
252{ 278{
253 Buffer buffer;
254 Key *pub; 279 Key *pub;
255 struct stat st; 280
256 char *cp; 281 /* Check that it is at least big enough to contain the ID string. */
257 u_int i; 282 if (buffer_len(blob) < sizeof(authfile_id_string)) {
283 debug3("Truncated RSA1 identifier");
284 return NULL;
285 }
286
287 /*
288 * Make sure it begins with the id string. Consume the id string
289 * from the buffer.
290 */
291 if (memcmp(buffer_ptr(blob), authfile_id_string,
292 sizeof(authfile_id_string)) != 0) {
293 debug3("Incorrect RSA1 identifier");
294 return NULL;
295 }
296 buffer_consume(blob, sizeof(authfile_id_string));
297
298 /* Skip cipher type and reserved data. */
299 (void) buffer_get_char(blob); /* cipher type */
300 (void) buffer_get_int(blob); /* reserved */
301
302 /* Read the public key from the buffer. */
303 (void) buffer_get_int(blob);
304 pub = key_new(KEY_RSA1);
305 buffer_get_bignum(blob, pub->rsa->n);
306 buffer_get_bignum(blob, pub->rsa->e);
307 if (commentp)
308 *commentp = buffer_get_string(blob, NULL);
309 /* The encrypted private part is not parsed by this function. */
310 buffer_clear(blob);
311
312 return pub;
313}
314
315/* Load the contents of a key file into a buffer */
316static int
317key_load_file(int fd, const char *filename, Buffer *blob)
318{
258 size_t len; 319 size_t len;
320 u_char *cp;
321 struct stat st;
259 322
260 if (fstat(fd, &st) < 0) { 323 if (fstat(fd, &st) < 0) {
261 error("fstat for key file %.200s failed: %.100s", 324 error("%s: fstat of key file %.200s%sfailed: %.100s", __func__,
262 filename, strerror(errno)); 325 filename == NULL ? "" : filename,
263 return NULL; 326 filename == NULL ? "" : " ",
327 strerror(errno));
328 close(fd);
329 return 0;
264 } 330 }
265 if (st.st_size > 1*1024*1024) { 331 if (st.st_size > 1*1024*1024) {
266 error("key file %.200s too large", filename); 332 error("%s: key file %.200s%stoo large", __func__,
267 return NULL; 333 filename == NULL ? "" : filename,
334 filename == NULL ? "" : " ");
335 close(fd);
336 return 0;
268 } 337 }
269 len = (size_t)st.st_size; /* truncated */ 338 len = (size_t)st.st_size; /* truncated */
270 339
271 buffer_init(&buffer); 340 buffer_init(blob);
272 cp = buffer_append_space(&buffer, len); 341 cp = buffer_append_space(blob, len);
273 342
274 if (atomicio(read, fd, cp, len) != len) { 343 if (atomicio(read, fd, cp, len) != len) {
275 debug("Read from key file %.200s failed: %.100s", filename, 344 debug("%s: read from key file %.200s%sfailed: %.100s", __func__,
345 filename == NULL ? "" : filename,
346 filename == NULL ? "" : " ",
276 strerror(errno)); 347 strerror(errno));
277 buffer_free(&buffer); 348 buffer_clear(blob);
278 return NULL; 349 close(fd);
350 return 0;
279 } 351 }
352 return 1;
353}
280 354
281 /* Check that it is at least big enough to contain the ID string. */ 355/*
282 if (len < sizeof(authfile_id_string)) { 356 * Loads the public part of the ssh v1 key file. Returns NULL if an error was
283 debug3("Not a RSA1 key file %.200s.", filename); 357 * encountered (the file does not exist or is not readable), and the key
358 * otherwise.
359 */
360static Key *
361key_load_public_rsa1(int fd, const char *filename, char **commentp)
362{
363 Buffer buffer;
364 Key *pub;
365
366 buffer_init(&buffer);
367 if (!key_load_file(fd, filename, &buffer)) {
284 buffer_free(&buffer); 368 buffer_free(&buffer);
285 return NULL; 369 return NULL;
286 } 370 }
287 /*
288 * Make sure it begins with the id string. Consume the id string
289 * from the buffer.
290 */
291 for (i = 0; i < sizeof(authfile_id_string); i++)
292 if (buffer_get_char(&buffer) != authfile_id_string[i]) {
293 debug3("Not a RSA1 key file %.200s.", filename);
294 buffer_free(&buffer);
295 return NULL;
296 }
297 /* Skip cipher type and reserved data. */
298 (void) buffer_get_char(&buffer); /* cipher type */
299 (void) buffer_get_int(&buffer); /* reserved */
300
301 /* Read the public key from the buffer. */
302 (void) buffer_get_int(&buffer);
303 pub = key_new(KEY_RSA1);
304 buffer_get_bignum(&buffer, pub->rsa->n);
305 buffer_get_bignum(&buffer, pub->rsa->e);
306 if (commentp)
307 *commentp = buffer_get_string(&buffer, NULL);
308 /* The encrypted private part is not parsed by this function. */
309 371
372 pub = key_parse_public_rsa1(&buffer, commentp);
373 if (pub == NULL)
374 debug3("Could not load \"%s\" as a RSA1 public key", filename);
310 buffer_free(&buffer); 375 buffer_free(&buffer);
311 return pub; 376 return pub;
312} 377}
@@ -329,113 +394,73 @@ key_load_public_type(int type, const char *filename, char **commentp)
329 return NULL; 394 return NULL;
330} 395}
331 396
332/*
333 * Loads the private key from the file. Returns 0 if an error is encountered
334 * (file does not exist or is not readable, or passphrase is bad). This
335 * initializes the private key.
336 * Assumes we are called under uid of the owner of the file.
337 */
338
339static Key * 397static Key *
340key_load_private_rsa1(int fd, const char *filename, const char *passphrase, 398key_parse_private_rsa1(Buffer *blob, const char *passphrase, char **commentp)
341 char **commentp)
342{ 399{
343 u_int i;
344 int check1, check2, cipher_type; 400 int check1, check2, cipher_type;
345 size_t len; 401 Buffer decrypted;
346 Buffer buffer, decrypted;
347 u_char *cp; 402 u_char *cp;
348 CipherContext ciphercontext; 403 CipherContext ciphercontext;
349 Cipher *cipher; 404 Cipher *cipher;
350 Key *prv = NULL; 405 Key *prv = NULL;
351 struct stat st;
352
353 if (fstat(fd, &st) < 0) {
354 error("fstat for key file %.200s failed: %.100s",
355 filename, strerror(errno));
356 close(fd);
357 return NULL;
358 }
359 if (st.st_size > 1*1024*1024) {
360 error("key file %.200s too large", filename);
361 close(fd);
362 return (NULL);
363 }
364 len = (size_t)st.st_size; /* truncated */
365
366 buffer_init(&buffer);
367 cp = buffer_append_space(&buffer, len);
368
369 if (atomicio(read, fd, cp, len) != len) {
370 debug("Read from key file %.200s failed: %.100s", filename,
371 strerror(errno));
372 buffer_free(&buffer);
373 close(fd);
374 return NULL;
375 }
376 406
377 /* Check that it is at least big enough to contain the ID string. */ 407 /* Check that it is at least big enough to contain the ID string. */
378 if (len < sizeof(authfile_id_string)) { 408 if (buffer_len(blob) < sizeof(authfile_id_string)) {
379 debug3("Not a RSA1 key file %.200s.", filename); 409 debug3("Truncated RSA1 identifier");
380 buffer_free(&buffer);
381 close(fd);
382 return NULL; 410 return NULL;
383 } 411 }
412
384 /* 413 /*
385 * Make sure it begins with the id string. Consume the id string 414 * Make sure it begins with the id string. Consume the id string
386 * from the buffer. 415 * from the buffer.
387 */ 416 */
388 for (i = 0; i < sizeof(authfile_id_string); i++) 417 if (memcmp(buffer_ptr(blob), authfile_id_string,
389 if (buffer_get_char(&buffer) != authfile_id_string[i]) { 418 sizeof(authfile_id_string)) != 0) {
390 debug3("Not a RSA1 key file %.200s.", filename); 419 debug3("Incorrect RSA1 identifier");
391 buffer_free(&buffer); 420 return NULL;
392 close(fd); 421 }
393 return NULL; 422 buffer_consume(blob, sizeof(authfile_id_string));
394 }
395 423
396 /* Read cipher type. */ 424 /* Read cipher type. */
397 cipher_type = buffer_get_char(&buffer); 425 cipher_type = buffer_get_char(blob);
398 (void) buffer_get_int(&buffer); /* Reserved data. */ 426 (void) buffer_get_int(blob); /* Reserved data. */
399 427
400 /* Read the public key from the buffer. */ 428 /* Read the public key from the buffer. */
401 (void) buffer_get_int(&buffer); 429 (void) buffer_get_int(blob);
402 prv = key_new_private(KEY_RSA1); 430 prv = key_new_private(KEY_RSA1);
403 431
404 buffer_get_bignum(&buffer, prv->rsa->n); 432 buffer_get_bignum(blob, prv->rsa->n);
405 buffer_get_bignum(&buffer, prv->rsa->e); 433 buffer_get_bignum(blob, prv->rsa->e);
406 if (commentp) 434 if (commentp)
407 *commentp = buffer_get_string(&buffer, NULL); 435 *commentp = buffer_get_string(blob, NULL);
408 else 436 else
409 xfree(buffer_get_string(&buffer, NULL)); 437 (void)buffer_get_string_ptr(blob, NULL);
410 438
411 /* Check that it is a supported cipher. */ 439 /* Check that it is a supported cipher. */
412 cipher = cipher_by_number(cipher_type); 440 cipher = cipher_by_number(cipher_type);
413 if (cipher == NULL) { 441 if (cipher == NULL) {
414 debug("Unsupported cipher %d used in key file %.200s.", 442 debug("Unsupported RSA1 cipher %d", cipher_type);
415 cipher_type, filename);
416 buffer_free(&buffer);
417 goto fail; 443 goto fail;
418 } 444 }
419 /* Initialize space for decrypted data. */ 445 /* Initialize space for decrypted data. */
420 buffer_init(&decrypted); 446 buffer_init(&decrypted);
421 cp = buffer_append_space(&decrypted, buffer_len(&buffer)); 447 cp = buffer_append_space(&decrypted, buffer_len(blob));
422 448
423 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ 449 /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
424 cipher_set_key_string(&ciphercontext, cipher, passphrase, 450 cipher_set_key_string(&ciphercontext, cipher, passphrase,
425 CIPHER_DECRYPT); 451 CIPHER_DECRYPT);
426 cipher_crypt(&ciphercontext, cp, 452 cipher_crypt(&ciphercontext, cp,
427 buffer_ptr(&buffer), buffer_len(&buffer)); 453 buffer_ptr(blob), buffer_len(blob));
428 cipher_cleanup(&ciphercontext); 454 cipher_cleanup(&ciphercontext);
429 memset(&ciphercontext, 0, sizeof(ciphercontext)); 455 memset(&ciphercontext, 0, sizeof(ciphercontext));
430 buffer_free(&buffer); 456 buffer_clear(blob);
431 457
432 check1 = buffer_get_char(&decrypted); 458 check1 = buffer_get_char(&decrypted);
433 check2 = buffer_get_char(&decrypted); 459 check2 = buffer_get_char(&decrypted);
434 if (check1 != buffer_get_char(&decrypted) || 460 if (check1 != buffer_get_char(&decrypted) ||
435 check2 != buffer_get_char(&decrypted)) { 461 check2 != buffer_get_char(&decrypted)) {
436 if (strcmp(passphrase, "") != 0) 462 if (strcmp(passphrase, "") != 0)
437 debug("Bad passphrase supplied for key file %.200s.", 463 debug("Bad passphrase supplied for RSA1 key");
438 filename);
439 /* Bad passphrase. */ 464 /* Bad passphrase. */
440 buffer_free(&decrypted); 465 buffer_free(&decrypted);
441 goto fail; 466 goto fail;
@@ -454,38 +479,37 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
454 479
455 /* enable blinding */ 480 /* enable blinding */
456 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 481 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
457 error("key_load_private_rsa1: RSA_blinding_on failed"); 482 error("%s: RSA_blinding_on failed", __func__);
458 goto fail; 483 goto fail;
459 } 484 }
460 close(fd);
461 return prv; 485 return prv;
462 486
463fail: 487fail:
464 if (commentp) 488 if (commentp)
465 xfree(*commentp); 489 xfree(*commentp);
466 close(fd);
467 key_free(prv); 490 key_free(prv);
468 return NULL; 491 return NULL;
469} 492}
470 493
471Key * 494static Key *
472key_load_private_pem(int fd, int type, const char *passphrase, 495key_parse_private_pem(Buffer *blob, int type, const char *passphrase,
473 char **commentp) 496 char **commentp)
474{ 497{
475 FILE *fp;
476 EVP_PKEY *pk = NULL; 498 EVP_PKEY *pk = NULL;
477 Key *prv = NULL; 499 Key *prv = NULL;
478 char *name = "<no key>"; 500 char *name = "<no key>";
501 BIO *bio;
479 502
480 fp = fdopen(fd, "r"); 503 if ((bio = BIO_new_mem_buf(buffer_ptr(blob),
481 if (fp == NULL) { 504 buffer_len(blob))) == NULL) {
482 error("fdopen failed: %s", strerror(errno)); 505 error("%s: BIO_new_mem_buf failed", __func__);
483 close(fd);
484 return NULL; 506 return NULL;
485 } 507 }
486 pk = PEM_read_PrivateKey(fp, NULL, NULL, (char *)passphrase); 508
509 pk = PEM_read_bio_PrivateKey(bio, NULL, NULL, (char *)passphrase);
510 BIO_free(bio);
487 if (pk == NULL) { 511 if (pk == NULL) {
488 debug("PEM_read_PrivateKey failed"); 512 debug("%s: PEM_read_PrivateKey failed", __func__);
489 (void)ERR_get_error(); 513 (void)ERR_get_error();
490 } else if (pk->type == EVP_PKEY_RSA && 514 } else if (pk->type == EVP_PKEY_RSA &&
491 (type == KEY_UNSPEC||type==KEY_RSA)) { 515 (type == KEY_UNSPEC||type==KEY_RSA)) {
@@ -497,7 +521,7 @@ key_load_private_pem(int fd, int type, const char *passphrase,
497 RSA_print_fp(stderr, prv->rsa, 8); 521 RSA_print_fp(stderr, prv->rsa, 8);
498#endif 522#endif
499 if (RSA_blinding_on(prv->rsa, NULL) != 1) { 523 if (RSA_blinding_on(prv->rsa, NULL) != 1) {
500 error("key_load_private_pem: RSA_blinding_on failed"); 524 error("%s: RSA_blinding_on failed", __func__);
501 key_free(prv); 525 key_free(prv);
502 prv = NULL; 526 prv = NULL;
503 } 527 }
@@ -510,11 +534,31 @@ key_load_private_pem(int fd, int type, const char *passphrase,
510#ifdef DEBUG_PK 534#ifdef DEBUG_PK
511 DSA_print_fp(stderr, prv->dsa, 8); 535 DSA_print_fp(stderr, prv->dsa, 8);
512#endif 536#endif
537#ifdef OPENSSL_HAS_ECC
538 } else if (pk->type == EVP_PKEY_EC &&
539 (type == KEY_UNSPEC||type==KEY_ECDSA)) {
540 prv = key_new(KEY_UNSPEC);
541 prv->ecdsa = EVP_PKEY_get1_EC_KEY(pk);
542 prv->type = KEY_ECDSA;
543 if ((prv->ecdsa_nid = key_ecdsa_key_to_nid(prv->ecdsa)) == -1 ||
544 key_curve_nid_to_name(prv->ecdsa_nid) == NULL ||
545 key_ec_validate_public(EC_KEY_get0_group(prv->ecdsa),
546 EC_KEY_get0_public_key(prv->ecdsa)) != 0 ||
547 key_ec_validate_private(prv->ecdsa) != 0) {
548 error("%s: bad ECDSA key", __func__);
549 key_free(prv);
550 prv = NULL;
551 }
552 name = "ecdsa w/o comment";
553#ifdef DEBUG_PK
554 if (prv != NULL && prv->ecdsa != NULL)
555 key_dump_ec_key(prv->ecdsa);
556#endif
557#endif /* OPENSSL_HAS_ECC */
513 } else { 558 } else {
514 error("PEM_read_PrivateKey: mismatch or " 559 error("%s: PEM_read_PrivateKey: mismatch or "
515 "unknown EVP_PKEY save_type %d", pk->save_type); 560 "unknown EVP_PKEY save_type %d", __func__, pk->save_type);
516 } 561 }
517 fclose(fp);
518 if (pk != NULL) 562 if (pk != NULL)
519 EVP_PKEY_free(pk); 563 EVP_PKEY_free(pk);
520 if (prv != NULL && commentp) 564 if (prv != NULL && commentp)
@@ -524,6 +568,23 @@ key_load_private_pem(int fd, int type, const char *passphrase,
524 return prv; 568 return prv;
525} 569}
526 570
571Key *
572key_load_private_pem(int fd, int type, const char *passphrase,
573 char **commentp)
574{
575 Buffer buffer;
576 Key *prv;
577
578 buffer_init(&buffer);
579 if (!key_load_file(fd, NULL, &buffer)) {
580 buffer_free(&buffer);
581 return NULL;
582 }
583 prv = key_parse_private_pem(&buffer, type, passphrase, commentp);
584 buffer_free(&buffer);
585 return prv;
586}
587
527int 588int
528key_perm_ok(int fd, const char *filename) 589key_perm_ok(int fd, const char *filename)
529{ 590{
@@ -552,11 +613,31 @@ key_perm_ok(int fd, const char *filename)
552 return 1; 613 return 1;
553} 614}
554 615
616static Key *
617key_parse_private_type(Buffer *blob, int type, const char *passphrase,
618 char **commentp)
619{
620 switch (type) {
621 case KEY_RSA1:
622 return key_parse_private_rsa1(blob, passphrase, commentp);
623 case KEY_DSA:
624 case KEY_ECDSA:
625 case KEY_RSA:
626 case KEY_UNSPEC:
627 return key_parse_private_pem(blob, type, passphrase, commentp);
628 default:
629 break;
630 }
631 return NULL;
632}
633
555Key * 634Key *
556key_load_private_type(int type, const char *filename, const char *passphrase, 635key_load_private_type(int type, const char *filename, const char *passphrase,
557 char **commentp, int *perm_ok) 636 char **commentp, int *perm_ok)
558{ 637{
559 int fd; 638 int fd;
639 Key *ret;
640 Buffer buffer;
560 641
561 fd = open(filename, O_RDONLY); 642 fd = open(filename, O_RDONLY);
562 if (fd < 0) { 643 if (fd < 0) {
@@ -575,21 +656,17 @@ key_load_private_type(int type, const char *filename, const char *passphrase,
575 } 656 }
576 if (perm_ok != NULL) 657 if (perm_ok != NULL)
577 *perm_ok = 1; 658 *perm_ok = 1;
578 switch (type) { 659
579 case KEY_RSA1: 660 buffer_init(&buffer);
580 return key_load_private_rsa1(fd, filename, passphrase, 661 if (!key_load_file(fd, filename, &buffer)) {
581 commentp); 662 buffer_free(&buffer);
582 /* closes fd */
583 case KEY_DSA:
584 case KEY_RSA:
585 case KEY_UNSPEC:
586 return key_load_private_pem(fd, type, passphrase, commentp);
587 /* closes fd */
588 default:
589 close(fd); 663 close(fd);
590 break; 664 return NULL;
591 } 665 }
592 return NULL; 666 close(fd);
667 ret = key_parse_private_type(&buffer, type, passphrase, commentp);
668 buffer_free(&buffer);
669 return ret;
593} 670}
594 671
595Key * 672Key *
@@ -597,6 +674,7 @@ key_load_private(const char *filename, const char *passphrase,
597 char **commentp) 674 char **commentp)
598{ 675{
599 Key *pub, *prv; 676 Key *pub, *prv;
677 Buffer buffer, pubcopy;
600 int fd; 678 int fd;
601 679
602 fd = open(filename, O_RDONLY); 680 fd = open(filename, O_RDONLY);
@@ -610,20 +688,33 @@ key_load_private(const char *filename, const char *passphrase,
610 close(fd); 688 close(fd);
611 return NULL; 689 return NULL;
612 } 690 }
613 pub = key_load_public_rsa1(fd, filename, commentp); 691
614 lseek(fd, (off_t) 0, SEEK_SET); /* rewind */ 692 buffer_init(&buffer);
693 if (!key_load_file(fd, filename, &buffer)) {
694 buffer_free(&buffer);
695 close(fd);
696 return NULL;
697 }
698 close(fd);
699
700 buffer_init(&pubcopy);
701 buffer_append(&pubcopy, buffer_ptr(&buffer), buffer_len(&buffer));
702 /* it's a SSH v1 key if the public key part is readable */
703 pub = key_parse_public_rsa1(&pubcopy, commentp);
704 buffer_free(&pubcopy);
615 if (pub == NULL) { 705 if (pub == NULL) {
616 /* closes fd */ 706 prv = key_parse_private_type(&buffer, KEY_UNSPEC,
617 prv = key_load_private_pem(fd, KEY_UNSPEC, passphrase, NULL); 707 passphrase, NULL);
618 /* use the filename as a comment for PEM */ 708 /* use the filename as a comment for PEM */
619 if (commentp && prv) 709 if (commentp && prv)
620 *commentp = xstrdup(filename); 710 *commentp = xstrdup(filename);
621 } else { 711 } else {
622 /* it's a SSH v1 key if the public key part is readable */
623 key_free(pub); 712 key_free(pub);
624 /* closes fd */ 713 /* key_parse_public_rsa1() has already loaded the comment */
625 prv = key_load_private_rsa1(fd, filename, passphrase, NULL); 714 prv = key_parse_private_type(&buffer, KEY_RSA1, passphrase,
715 NULL);
626 } 716 }
717 buffer_free(&buffer);
627 return prv; 718 return prv;
628} 719}
629 720
@@ -721,6 +812,7 @@ key_load_private_cert(int type, const char *filename, const char *passphrase,
721 switch (type) { 812 switch (type) {
722 case KEY_RSA: 813 case KEY_RSA:
723 case KEY_DSA: 814 case KEY_DSA:
815 case KEY_ECDSA:
724 break; 816 break;
725 default: 817 default:
726 error("%s: unsupported key type", __func__); 818 error("%s: unsupported key type", __func__);