/* * Return a malloc'ed chunk of memory containing the public blob of * an RSA key, as given in the agent protocol (modulus bits, * exponent, modulus). */ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen, char **commentptr, const char **errorstr) { FILE *fp; char buf[64]; struct RSAKey key; int ret; const char *error = NULL; /* Default return if we fail. */ *blob = NULL; *bloblen = 0; ret = 0; fp = f_open(filename, "rb", FALSE); if (!fp) { error = "can't open file"; goto end; } /* * Read the first line of the file and see if it's a v1 private * key file. */ if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) { memset(&key, 0, sizeof(key)); if (loadrsakey_main(fp, &key, TRUE, commentptr, NULL, &error)) { *blob = rsa_public_blob(&key, bloblen); freersakey(&key); ret = 1; } fp = NULL; /* loadrsakey_main unconditionally closes fp */ } else { error = "not an SSH-1 RSA file"; } end: if (fp) fclose(fp); if ((ret != 1) && errorstr) *errorstr = error; return ret; }
int loadrsakey(const Filename *filename, struct RSAKey *key, char *passphrase, const char **errorstr) { FILE *fp; char buf[64]; int ret = 0; const char *error = NULL; fp = f_open(filename, "rb", FALSE); if (!fp) { error = "can't open file"; goto end; } /* * Read the first line of the file and see if it's a v1 private * 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. */ error = "not an SSH-1 RSA file"; end: if (fp) fclose(fp); if ((ret != 1) && errorstr) *errorstr = error; return ret; }
/* * See whether an RSA key is encrypted. Return its comment field as * well. */ int rsakey_encrypted(const Filename *filename, char **comment) { FILE *fp; char buf[64]; fp = f_open(filename, "rb", FALSE); if (!fp) return 0; /* doesn't even exist */ /* * Read the first line of the file and see if it's a v1 private * key file. */ 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); return 0; /* wasn't the right kind of file */ }
/* * Return a malloc'ed chunk of memory containing the public blob of * an RSA key, as given in the agent protocol (modulus bits, * exponent, modulus). */ int rsakey_pubblob(const Filename *filename, void **blob, int *bloblen, char **commentptr, const char **errorstr) { FILE *fp; char buf[64]; struct RSAKey key; int ret; const char *error = NULL; /* Default return if we fail. */ *blob = NULL; *bloblen = 0; ret = 0; fp = f_open(filename, "rb", FALSE); if (!fp) { error = "can't open file"; goto end; } /* * Read the first line of the file and see if it's a v1 private * key file. */ if (fgets(buf, sizeof(buf), fp) && !strcmp(buf, rsa_signature)) { memset(&key, 0, sizeof(key)); if (loadrsakey_main(fp, &key, TRUE, commentptr, NULL, &error)) { *blob = rsa_public_blob(&key, bloblen); freersakey(&key); ret = 1; } fp = NULL; /* loadrsakey_main unconditionally closes fp */ } else { /* * Try interpreting the file as an SSH-1 public key. */ char *line, *p, *bitsp, *expp, *modp, *commentp; rewind(fp); line = chomp(fgetline(fp)); p = line; bitsp = p; p += strspn(p, "0123456789"); if (*p != ' ') goto not_public_either; *p++ = '\0'; expp = p; p += strspn(p, "0123456789"); if (*p != ' ') goto not_public_either; *p++ = '\0'; modp = p; p += strspn(p, "0123456789"); if (*p) { if (*p != ' ') goto not_public_either; *p++ = '\0'; commentp = p; } else { commentp = NULL; } memset(&key, 0, sizeof(key)); key.exponent = bignum_from_decimal(expp); key.modulus = bignum_from_decimal(modp); if (atoi(bitsp) != bignum_bitcount(key.modulus)) { freebn(key.exponent); freebn(key.modulus); sfree(line); error = "key bit count does not match in SSH-1 public key file"; goto end; } if (commentptr) *commentptr = commentp ? dupstr(commentp) : NULL; *blob = rsa_public_blob(&key, bloblen); freersakey(&key); return 1; not_public_either: sfree(line); error = "not an SSH-1 RSA file"; } end: if (fp) fclose(fp); if ((ret != 1) && errorstr) *errorstr = error; return ret; }