+int verify_ssh_manual_host_key(Ssh ssh, const char *fingerprint,
+ const struct ssh_signkey *ssh2keytype,
+ void *ssh2keydata)
+{
+ if (!conf_get_str_nthstrkey(ssh->conf, CONF_ssh_manual_hostkeys, 0)) {
+ return -1; /* no manual keys configured */
+ }
+
+ if (fingerprint) {
+ /*
+ * The fingerprint string we've been given will have things
+ * like 'ssh-rsa 2048' at the front of it. Strip those off and
+ * narrow down to just the colon-separated hex block at the
+ * end of the string.
+ */
+ const char *p = strrchr(fingerprint, ' ');
+ fingerprint = p ? p+1 : fingerprint;
+ /* Quick sanity checks, including making sure it's in lowercase */
+ assert(strlen(fingerprint) == 16*3 - 1);
+ assert(fingerprint[2] == ':');
+ assert(fingerprint[strspn(fingerprint, "0123456789abcdef:")] == 0);
+
+ if (conf_get_str_str_opt(ssh->conf, CONF_ssh_manual_hostkeys,
+ fingerprint))
+ return 1; /* success */
+ }
+
+ if (ssh2keydata) {
+ /*
+ * Construct the base64-encoded public key blob and see if
+ * that's listed.
+ */
+ unsigned char *binblob;
+ char *base64blob;
+ int binlen, atoms, i;
+ binblob = ssh2keytype->public_blob(ssh2keydata, &binlen);
+ atoms = (binlen + 2) / 3;
+ base64blob = snewn(atoms * 4 + 1, char);
+ for (i = 0; i < atoms; i++)
+ base64_encode_atom(binblob + 3*i, binlen - 3*i, base64blob + 4*i);
+ base64blob[atoms * 4] = '\0';
+ sfree(binblob);
+ if (conf_get_str_str_opt(ssh->conf, CONF_ssh_manual_hostkeys,
+ base64blob)) {
+ sfree(base64blob);
+ return 1; /* success */
+ }
+ sfree(base64blob);
+ }
+
+ return 0;
+}
+