~sircmpwn/himitsu-ssh

c8cbc9e809685bae7a5f59cfd5121b6fd3582b7f — Armin Preiml 3 months ago 69daaa1
use raw key functions instead of direct access
2 files changed, 36 insertions(+), 13 deletions(-)

M cmd/hissh-agent/main.ha
M cmd/hissh-import/main.ha
M cmd/hissh-agent/main.ha => cmd/hissh-agent/main.ha +26 -8
@@ 179,11 179,20 @@ fn handle_req_ident(agent: *agent::agent) (void | agent::error | net::error) = {
			yield "";
		};

		let edkey = ssh::ed25519key { ... };
		edkey.pubkey[..] = pkey[..];
		let key = ssh::newed25519key();
		defer ssh::key_free(key);
		let pkeybuf = bufio::fixed(pkey, io::mode::READ);
		match (ssh::key_decoderawpub(key, &pkeybuf)) {
		case ssh::error =>
			log::printfln("Invalid SSH key: {}",
				strings::fromutf8(buf)!);
			continue;
		case =>
			yield;
		};

		const sink = bufio::dynamic(io::mode::WRITE);
		ssh::encode_pubkey(&sink, &edkey)!;
		ssh::encode_pubkey(&sink, key)!;

		append(idents, agent::identity {
			pubkey = bufio::buffer(&sink),


@@ 206,19 215,21 @@ fn handle_sign_request(
) (void | agent::error | net::error) = {
	const source = bufio::fixed(msg.key, io::mode::READ);
	const key = match (ssh::decodepublic(&source)) {
	case let key: ssh::key =>
	case let key: *ssh::key =>
		yield key;
	case ssh::error =>
		const answer: agent::message = agent::agent_failure;
		agent::writemsg(agent, &answer)!;
		return;
	};
	defer bytes::zero(key.privkey);
	defer ssh::key_free(key);

	let req = bufio::dynamic(io::mode::WRITE);
	defer io::close(&req)!;
	fmt::fprint(&req, "query -d proto=ssh pkey=")?;
	base64::encode(&req, &base64::std_encoding, key.pubkey)!;
	let b64en = base64::newencoder(&base64::std_encoding, &req);
	ssh::key_encoderawpub(key, &b64en)!;
	io::close(&b64en)!;
	fmt::fprintln(&req)!;

	const himitsu = himitsu_connect()?;


@@ 290,7 301,14 @@ fn handle_sign_request(
			yield "";
		};

		key.privkey[..] = skey[..];
		let keybuf = bufio::fixed(skey, io::mode::READ);
		match (ssh::key_decoderawpriv(key, &keybuf)) {
		case ssh::error =>
			log::printfln("Invalid SSH key: {}",
				strings::fromutf8(buf)!);
		case =>
			yield;
		};
		found = true;
		break;
	};


@@ 304,7 322,7 @@ fn handle_sign_request(

	let buf = bufio::dynamic(io::mode::WRITE);
	defer io::close(&buf)!;
	ssh::sign(&buf, &key, msg.data)!;
	ssh::sign(&buf, key, msg.data)!;

	const answer: agent::message = agent::sign_response {
		signature = bufio::buffer(&buf),

M cmd/hissh-import/main.ha => cmd/hissh-import/main.ha +10 -5
@@ 25,20 25,25 @@ export fn main() void = {
		decrypt(&key);
	};

	const privkey = match (ssh::decodeprivate(&key)) {
	case let key: ssh::key =>
	let privkey = match (ssh::decodeprivate(&key)) {
	case let key: *ssh::key =>
		yield key;
	case let err: ssh::error =>
		fmt::fatal("Error decoding private key:", ssh::strerror(err));
	};
	defer ssh::key_free(privkey);

	// TODO: Support more key types
	let buf = bufio::dynamic(io::mode::WRITE);
	defer io::close(&buf)!;
	fmt::fprint(&buf, "add proto=ssh type=ssh-ed25519 pkey='")!;
	base64::encode(&buf, &base64::std_encoding, privkey.pubkey)!;
	fmt::fprintf(&buf, "add proto=ssh type={} pkey='", ssh::keytype(privkey))!;
	let b64 = base64::newencoder(&base64::std_encoding, &buf);
	ssh::key_encoderawpub(privkey, &b64)!;
	io::close(&b64)!;
	fmt::fprint(&buf, "' skey!='")!;
	base64::encode(&buf, &base64::std_encoding, privkey.privkey)!;
	let b64 = base64::newencoder(&base64::std_encoding, &buf);
	ssh::key_encoderawpriv(privkey, &b64)!;
	io::close(&b64)!;
	fmt::fprint(&buf, "'")!;
	if (privkey.comment != "") {
		fmt::fprint(&buf, " comment=")!;