version 1.9, 1999/11/24 00:26:00 |
version 1.10, 1999/11/24 19:53:44 |
|
|
/* Version identification string for identity files. */ |
/* Version identification string for identity files. */ |
#define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n" |
#define AUTHFILE_ID_STRING "SSH PRIVATE KEY FILE FORMAT 1.1\n" |
|
|
/* Saves the authentication (private) key in a file, encrypting it with |
/* |
passphrase. The identification of the file (lowest 64 bits of n) |
* Saves the authentication (private) key in a file, encrypting it with |
will precede the key to provide identification of the key without |
* passphrase. The identification of the file (lowest 64 bits of n) will |
needing a passphrase. */ |
* precede the key to provide identification of the key without needing a |
|
* passphrase. |
|
*/ |
|
|
int |
int |
save_private_key(const char *filename, const char *passphrase, |
save_private_key(const char *filename, const char *passphrase, |
|
|
int cipher_type; |
int cipher_type; |
u_int32_t rand; |
u_int32_t rand; |
|
|
/* If the passphrase is empty, use SSH_CIPHER_NONE to ease |
/* |
converting to another cipher; otherwise use |
* If the passphrase is empty, use SSH_CIPHER_NONE to ease converting |
SSH_AUTHFILE_CIPHER. */ |
* to another cipher; otherwise use SSH_AUTHFILE_CIPHER. |
|
*/ |
if (strcmp(passphrase, "") == 0) |
if (strcmp(passphrase, "") == 0) |
cipher_type = SSH_CIPHER_NONE; |
cipher_type = SSH_CIPHER_NONE; |
else |
else |
|
|
buf[3] = buf[1]; |
buf[3] = buf[1]; |
buffer_append(&buffer, buf, 4); |
buffer_append(&buffer, buf, 4); |
|
|
/* Store the private key (n and e will not be stored because they |
/* |
will be stored in plain text, and storing them also in |
* Store the private key (n and e will not be stored because they |
encrypted format would just give known plaintext). */ |
* will be stored in plain text, and storing them also in encrypted |
|
* format would just give known plaintext). |
|
*/ |
buffer_put_bignum(&buffer, key->d); |
buffer_put_bignum(&buffer, key->d); |
buffer_put_bignum(&buffer, key->iqmp); |
buffer_put_bignum(&buffer, key->iqmp); |
buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */ |
buffer_put_bignum(&buffer, key->q); /* reverse from SSL p */ |
|
|
memset(buf, 0, sizeof(buf)); |
memset(buf, 0, sizeof(buf)); |
buffer_free(&buffer); |
buffer_free(&buffer); |
|
|
/* Write to a file. */ |
|
f = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); |
f = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); |
if (f < 0) |
if (f < 0) |
return 0; |
return 0; |
|
|
if (write(f, buffer_ptr(&encrypted), buffer_len(&encrypted)) != |
if (write(f, buffer_ptr(&encrypted), buffer_len(&encrypted)) != |
buffer_len(&encrypted)) { |
buffer_len(&encrypted)) { |
debug("Write to key file %.200s failed: %.100s", filename, |
debug("Write to key file %.200s failed: %.100s", filename, |
|
|
return 1; |
return 1; |
} |
} |
|
|
/* Loads the public part of the key file. Returns 0 if an error |
/* |
was encountered (the file does not exist or is not readable), and |
* Loads the public part of the key file. Returns 0 if an error was |
non-zero otherwise. */ |
* encountered (the file does not exist or is not readable), and non-zero |
|
* otherwise. |
|
*/ |
|
|
int |
int |
load_public_key(const char *filename, RSA * pub, |
load_public_key(const char *filename, RSA * pub, |
|
|
Buffer buffer; |
Buffer buffer; |
char *cp; |
char *cp; |
|
|
/* Read data from the file into the buffer. */ |
|
f = open(filename, O_RDONLY); |
f = open(filename, O_RDONLY); |
if (f < 0) |
if (f < 0) |
return 0; |
return 0; |
|
|
len = lseek(f, (off_t) 0, SEEK_END); |
len = lseek(f, (off_t) 0, SEEK_END); |
lseek(f, (off_t) 0, SEEK_SET); |
lseek(f, (off_t) 0, SEEK_SET); |
|
|
|
|
buffer_free(&buffer); |
buffer_free(&buffer); |
return 0; |
return 0; |
} |
} |
/* Make sure it begins with the id string. Consume the id string |
/* |
from the buffer. */ |
* Make sure it begins with the id string. Consume the id string |
|
* from the buffer. |
|
*/ |
for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) |
for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) |
if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { |
if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { |
debug("Bad key file %.200s.", filename); |
debug("Bad key file %.200s.", filename); |
|
|
return 1; |
return 1; |
} |
} |
|
|
/* Loads the private key from the file. Returns 0 if an error is encountered |
/* |
(file does not exist or is not readable, or passphrase is bad). |
* Loads the private key from the file. Returns 0 if an error is encountered |
This initializes the private key. */ |
* (file does not exist or is not readable, or passphrase is bad). This |
|
* initializes the private key. |
|
* Assumes we are called under uid of the owner of the file. |
|
*/ |
|
|
int |
int |
load_private_key(const char *filename, const char *passphrase, |
load_private_key(const char *filename, const char *passphrase, |
|
|
BIGNUM *aux; |
BIGNUM *aux; |
struct stat st; |
struct stat st; |
|
|
/* Read the file into the buffer. */ |
|
f = open(filename, O_RDONLY); |
f = open(filename, O_RDONLY); |
if (f < 0) |
if (f < 0) |
return 0; |
return 0; |
|
|
/* We assume we are called under uid of the owner of the file */ |
/* check owner and modes */ |
if (fstat(f, &st) < 0 || |
if (fstat(f, &st) < 0 || |
(st.st_uid != 0 && st.st_uid != getuid()) || |
(st.st_uid != 0 && st.st_uid != getuid()) || |
(st.st_mode & 077) != 0) { |
(st.st_mode & 077) != 0) { |
|
|
buffer_free(&buffer); |
buffer_free(&buffer); |
return 0; |
return 0; |
} |
} |
/* Make sure it begins with the id string. Consume the id string |
/* |
from the buffer. */ |
* Make sure it begins with the id string. Consume the id string |
|
* from the buffer. |
|
*/ |
for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) |
for (i = 0; i < (unsigned int) strlen(AUTHFILE_ID_STRING) + 1; i++) |
if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { |
if (buffer_get_char(&buffer) != (unsigned char) AUTHFILE_ID_STRING[i]) { |
debug("Bad key file %.200s.", filename); |
debug("Bad key file %.200s.", filename); |