/*
* Generic SSH public-key handling operations. In particular,
* reading of SSH public-key files, and also the generic `sign'
- * operation for ssh2 (which checks the type of the key and
+ * operation for SSH-2 (which checks the type of the key and
* dispatches to the appropriate key-type specific function).
*/
#include "ssh.h"
#include "misc.h"
-#define PUT_32BIT(cp, value) do { \
- (cp)[3] = (value); \
- (cp)[2] = (value) >> 8; \
- (cp)[1] = (value) >> 16; \
- (cp)[0] = (value) >> 24; } while (0)
-
-#define GET_32BIT(cp) \
- (((unsigned long)(unsigned char)(cp)[0] << 24) | \
- ((unsigned long)(unsigned char)(cp)[1] << 16) | \
- ((unsigned long)(unsigned char)(cp)[2] << 8) | \
- ((unsigned long)(unsigned char)(cp)[3]))
-
#define rsa_signature "SSH PRIVATE KEY FILE FORMAT 1.1\n"
#define BASE64_TOINT(x) ( (x)-'A'<26 ? (x)-'A'+0 :\
|| buf[i + 3] != 0) goto end; /* reserved field nonzero, panic! */
i += 4;
- /* Now the serious stuff. An ordinary SSH 1 public key. */
+ /* Now the serious stuff. An ordinary SSH-1 public key. */
i += makekey(buf + i, len, key, NULL, 1);
if (i < 0)
goto end; /* overran */
- if (pub_only) {
- ret = 1;
- goto end;
- }
-
/* Next, the comment field. */
j = GET_32BIT(buf + i);
i += 4;
}
i += j;
if (commentptr)
- *commentptr = comment;
+ *commentptr = dupstr(comment);
if (key)
key->comment = comment;
+ else
+ sfree(comment);
+
+ if (pub_only) {
+ ret = 1;
+ goto end;
+ }
+
if (!key) {
ret = ciphertype != 0;
*error = NULL;
* exponent, modulus).
*/
int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen,
- const char **errorstr)
+ char **commentptr, const char **errorstr)
{
FILE *fp;
char buf[64];
*/
if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) {
memset(&key, 0, sizeof(key));
- if (loadrsakey_main(fp, &key, TRUE, NULL, NULL, &error)) {
+ if (loadrsakey_main(fp, &key, TRUE, commentptr, NULL, &error)) {
*blob = rsa_public_blob(&key, bloblen);
freersakey(&key);
ret = 1;
p += 4;
/*
- * An ordinary SSH 1 public key consists of: a uint32
+ * An ordinary SSH-1 public key consists of: a uint32
* containing the bit count, then two bignums containing the
* modulus and exponent respectively.
*/
}
/* ----------------------------------------------------------------------
- * SSH2 private key load/store functions.
+ * SSH-2 private key load/store functions.
*/
/*
- * PuTTY's own format for SSH2 keys is as follows:
+ * PuTTY's own format for SSH-2 keys is as follows:
*
* The file is text. Lines are terminated by CRLF, although CR-only
* and LF-only are tolerated on input.
*
* Next there is a line saying "Public-Lines: " plus a number N.
* The following N lines contain a base64 encoding of the public
- * part of the key. This is encoded as the standard SSH2 public key
+ * part of the key. This is encoded as the standard SSH-2 public key
* blob (with no initial length): so for RSA, for example, it will
* read
*
sfree(text);
return NULL;
}
- if (len + 1 > size) {
+ if (len + 1 >= size) {
size += 128;
text = sresize(text, size, char);
}
}
char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm,
- int *pub_blob_len, const char **errorstr)
+ int *pub_blob_len, char **commentptr,
+ const char **errorstr)
{
FILE *fp;
char header[40], *b;
int public_blob_len;
int i;
const char *error = NULL;
+ char *comment;
public_blob = NULL;
error = "file format error";
if ((b = read_body(fp)) == NULL)
goto error;
- /* Select key algorithm structure. Currently only ssh-rsa. */
+ /* Select key algorithm structure. */
alg = find_pubkey_alg(b);
if (!alg) {
sfree(b);
/* Read the Comment header line. */
if (!read_header(fp, header) || 0 != strcmp(header, "Comment"))
goto error;
- if ((b = read_body(fp)) == NULL)
+ if ((comment = read_body(fp)) == NULL)
goto error;
- sfree(b); /* we don't care */
+
+ if (commentptr)
+ *commentptr = comment;
+ else
+ sfree(comment);
/* Read the Public-Lines header line and the public blob. */
if (!read_header(fp, header) || 0 != strcmp(header, "Public-Lines"))
switch (type) {
case SSH_KEYTYPE_UNOPENABLE: return "unable to open file"; break;
case SSH_KEYTYPE_UNKNOWN: return "not a private key"; break;
- case SSH_KEYTYPE_SSH1: return "SSH1 private key"; break;
- case SSH_KEYTYPE_SSH2: return "PuTTY SSH2 private key"; break;
- case SSH_KEYTYPE_OPENSSH: return "OpenSSH SSH2 private key"; break;
- case SSH_KEYTYPE_SSHCOM: return "ssh.com SSH2 private key"; break;
+ case SSH_KEYTYPE_SSH1: return "SSH-1 private key"; break;
+ case SSH_KEYTYPE_SSH2: return "PuTTY SSH-2 private key"; break;
+ case SSH_KEYTYPE_OPENSSH: return "OpenSSH SSH-2 private key"; break;
+ case SSH_KEYTYPE_SSHCOM: return "ssh.com SSH-2 private key"; break;
default: return "INTERNAL ERROR"; break;
}
}