X-Git-Url: https://git.distorted.org.uk/u/mdw/putty/blobdiff_plain/222d54dc209210b6e43589c798e35e21273b4082..05bea829b8868f5db4ac048897e944ed05dfc457:/sshpubk.c diff --git a/sshpubk.c b/sshpubk.c index 1659acec..13a182a5 100644 --- a/sshpubk.c +++ b/sshpubk.c @@ -79,8 +79,8 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, i += 4; /* Now the serious stuff. An ordinary SSH 1 public key. */ - i += makekey(buf + i, key, NULL, 1); - if (len - i < 0) + i += makekey(buf + i, len, key, NULL, 1); + if (i < 0) goto end; /* overran */ if (pub_only) { @@ -138,18 +138,18 @@ static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only, * decryption exponent, and then the three auxiliary values * (iqmp, q, p). */ - i += makeprivate(buf + i, key); - if (len - i < 0) - goto end; - i += ssh1_read_bignum(buf + i, &key->iqmp); - if (len - i < 0) - goto end; - i += ssh1_read_bignum(buf + i, &key->q); - if (len - i < 0) - goto end; - i += ssh1_read_bignum(buf + i, &key->p); - if (len - i < 0) - goto end; + j = makeprivate(buf + i, len - i, key); + if (j < 0) goto end; + i += j; + j = ssh1_read_bignum(buf + i, len - i, &key->iqmp); + if (j < 0) goto end; + i += j; + j = ssh1_read_bignum(buf + i, len - i, &key->q); + if (j < 0) goto end; + i += j; + j = ssh1_read_bignum(buf + i, len - i, &key->p); + if (j < 0) goto end; + i += j; if (!rsa_verify(key)) { *error = "rsa_verify failed"; @@ -182,17 +182,22 @@ int loadrsakey(const Filename *filename, struct RSAKey *key, char *passphrase, * key file. */ if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) { + /* + * This routine will take care of calling fclose() for us. + */ ret = loadrsakey_main(fp, key, FALSE, NULL, passphrase, &error); + fp = NULL; goto end; } /* * Otherwise, we have nothing. Return empty-handed. */ - fclose(fp); error = "not an SSH-1 RSA file"; end: + if (fp) + fclose(fp); if ((ret != 1) && errorstr) *errorstr = error; return ret; @@ -217,6 +222,9 @@ int rsakey_encrypted(const Filename *filename, char **comment) */ if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) { const char *dummy; + /* + * This routine will take care of calling fclose() for us. + */ return loadrsakey_main(fp, NULL, FALSE, comment, NULL, &dummy); } fclose(fp); @@ -258,13 +266,15 @@ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen, *blob = rsa_public_blob(&key, bloblen); freersakey(&key); ret = 1; + fp = NULL; } } else { error = "not an SSH-1 RSA file"; - fclose(fp); } end: + if (fp) + fclose(fp); if ((ret != 1) && errorstr) *errorstr = error; return ret; @@ -433,8 +443,7 @@ int saversakey(const Filename *filename, struct RSAKey *key, char *passphrase) * data "putty-private-key-file-mac-key" * data passphrase * - * Encrypted keys should have a MAC, whereas unencrypted ones must - * have a hash. + * (An empty passphrase is used for unencrypted keys.) * * If the key is encrypted, the encryption key is derived from the * passphrase by means of a succession of SHA-1 hashes. Each hash @@ -606,6 +615,16 @@ struct ssh2_userkey ssh2_wrong_passphrase = { NULL, NULL, NULL }; +const struct ssh_signkey *find_pubkey_alg(const char *name) +{ + if (!strcmp(name, "ssh-rsa")) + return &ssh_rsa; + else if (!strcmp(name, "ssh-dss")) + return &ssh_dss; + else + return NULL; +} + struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, char *passphrase, const char **errorstr) { @@ -647,11 +666,8 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, if ((b = read_body(fp)) == NULL) goto error; /* Select key algorithm structure. */ - if (!strcmp(b, "ssh-rsa")) - alg = &ssh_rsa; - else if (!strcmp(b, "ssh-dss")) - alg = &ssh_dss; - else { + alg = find_pubkey_alg(b); + if (!alg) { sfree(b); goto error; } @@ -784,7 +800,7 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, SHA_Init(&s); SHA_Bytes(&s, header, sizeof(header)-1); - if (passphrase) + if (cipher && passphrase) SHA_Bytes(&s, passphrase, passlen); SHA_Final(&s, mackey); @@ -808,6 +824,7 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, /* An incorrect MAC is an unconditional Error if the key is * unencrypted. Otherwise, it means Wrong Passphrase. */ if (cipher) { + error = "wrong passphrase"; ret = SSH2_WRONG_PASSPHRASE; } else { error = "MAC failed"; @@ -836,7 +853,8 @@ struct ssh2_userkey *ssh2_load_userkey(const Filename *filename, sfree(public_blob); sfree(private_blob); sfree(encryption); - *errorstr = NULL; + if (errorstr) + *errorstr = NULL; return ret; /* @@ -890,11 +908,8 @@ char *ssh2_userkey_loadpub(const Filename *filename, char **algorithm, if ((b = read_body(fp)) == NULL) goto error; /* Select key algorithm structure. Currently only ssh-rsa. */ - if (!strcmp(b, "ssh-rsa")) - alg = &ssh_rsa; - else if (!strcmp(b, "ssh-dss")) - alg = &ssh_dss; - else { + alg = find_pubkey_alg(b); + if (!alg) { sfree(b); goto error; }