예제 #1
0
/* ask agent to sign data, returns err.h code on error, 0 on success */
int
ssh_agent_sign(int sock, struct sshkey *key,
    u_char **sigp, size_t *lenp,
    const u_char *data, size_t datalen, u_int compat)
{
	struct sshbuf *msg;
	u_char *blob = NULL, type;
	size_t blen = 0, len = 0;
	u_int flags = 0;
	int r = SSH_ERR_INTERNAL_ERROR;

	*sigp = NULL;
	*lenp = 0;

	if (datalen > SSH_KEY_MAX_SIGN_DATA_SIZE)
		return SSH_ERR_INVALID_ARGUMENT;
	if (compat & SSH_BUG_SIGBLOB)
		flags |= SSH_AGENT_OLD_SIGNATURE;
	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
		goto out;
	if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
	    (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
	    (r = sshbuf_put_string(msg, data, datalen)) != 0 ||
	    (r = sshbuf_put_u32(msg, flags)) != 0)
		goto out;
	if ((r = ssh_request_reply(sock, msg, msg) != 0))
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	if (agent_failed(type)) {
		r = SSH_ERR_AGENT_FAILURE;
		goto out;
	} else if (type != SSH2_AGENT_SIGN_RESPONSE) {
		r = SSH_ERR_INVALID_FORMAT;
		goto out;
	}
	if ((r = sshbuf_get_string(msg, sigp, &len)) != 0)
		goto out;
	*lenp = len;
	r = 0;
 out:
	if (blob != NULL) {
		explicit_bzero(blob, blen);
		free(blob);
	}
	sshbuf_free(msg);
	return r;
}
예제 #2
0
int
kex_c25519_hash(
    int hash_alg,
    const char *client_version_string,
    const char *server_version_string,
    const char *ckexinit, size_t ckexinitlen,
    const char *skexinit, size_t skexinitlen,
    const u_char *serverhostkeyblob, size_t sbloblen,
    const u_char client_dh_pub[CURVE25519_SIZE],
    const u_char server_dh_pub[CURVE25519_SIZE],
    const u_char *shared_secret, size_t secretlen,
    u_char *hash, size_t *hashlen)
{
	struct sshbuf *b;
	int r;

	if (*hashlen < ssh_digest_bytes(hash_alg))
		return SSH_ERR_INVALID_ARGUMENT;
	if ((b = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_cstring(b, client_version_string)) < 0 ||
	    (r = sshbuf_put_cstring(b, server_version_string)) < 0 ||
	    /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
	    (r = sshbuf_put_u32(b, ckexinitlen+1)) < 0 ||
	    (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 ||
	    (r = sshbuf_put(b, ckexinit, ckexinitlen)) < 0 ||
	    (r = sshbuf_put_u32(b, skexinitlen+1)) < 0 ||
	    (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 ||
	    (r = sshbuf_put(b, skexinit, skexinitlen)) < 0 ||
	    (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) < 0 ||
	    (r = sshbuf_put_string(b, client_dh_pub, CURVE25519_SIZE)) < 0 ||
	    (r = sshbuf_put_string(b, server_dh_pub, CURVE25519_SIZE)) < 0 ||
	    (r = sshbuf_put(b, shared_secret, secretlen)) < 0) {
		sshbuf_free(b);
		return r;
	}
#ifdef DEBUG_KEX
	sshbuf_dump(b, stderr);
#endif
	if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) {
		sshbuf_free(b);
		return SSH_ERR_LIBCRYPTO_ERROR;
	}
	sshbuf_free(b);
	*hashlen = ssh_digest_bytes(hash_alg);
#ifdef DEBUG_KEX
	dump_digest("hash", hash, *hashlen);
#endif
	return 0;
}
예제 #3
0
파일: kexdh.c 프로젝트: djmdjm/libopenssh
int
kex_dh_hash(
    const char *client_version_string,
    const char *server_version_string,
    const u_char *ckexinit, size_t ckexinitlen,
    const u_char *skexinit, size_t skexinitlen,
    const u_char *serverhostkeyblob, size_t sbloblen,
    const BIGNUM *client_dh_pub,
    const BIGNUM *server_dh_pub,
    const BIGNUM *shared_secret,
    u_char **hash, size_t *hashlen)
{
	struct sshbuf *b;
	static u_char digest[SSH_DIGEST_MAX_LENGTH];
	int r;

	if ((b = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_cstring(b, client_version_string)) != 0 ||
	    (r = sshbuf_put_cstring(b, server_version_string)) != 0 ||
	    /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
	    (r = sshbuf_put_u32(b, ckexinitlen+1)) != 0 ||
	    (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
	    (r = sshbuf_put(b, ckexinit, ckexinitlen)) != 0 ||
	    (r = sshbuf_put_u32(b, skexinitlen+1)) != 0 ||
	    (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
	    (r = sshbuf_put(b, skexinit, skexinitlen)) != 0 ||
	    (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 ||
	    (r = sshbuf_put_bignum2(b, client_dh_pub)) != 0 ||
	    (r = sshbuf_put_bignum2(b, server_dh_pub)) != 0 ||
	    (r = sshbuf_put_bignum2(b, shared_secret)) != 0) {
		sshbuf_free(b);
		return r;
	}
#ifdef DEBUG_KEX
	sshbuf_dump(b, stderr);
#endif
	if (ssh_digest_buffer(SSH_DIGEST_SHA1, b, digest, sizeof(digest)) != 0) {
		sshbuf_free(b);
		return SSH_ERR_LIBCRYPTO_ERROR;
	}
	sshbuf_free(b);

	*hash = digest;
	*hashlen = ssh_digest_bytes(SSH_DIGEST_SHA1);
#ifdef DEBUG_KEX
	dump_digest("hash", digest, *hashlen);
#endif
	return 0;
}
예제 #4
0
static int
input_gssapi_mic(int type, u_int32_t plen, struct ssh *ssh)
{
	Authctxt *authctxt = ssh->authctxt;
	Gssctxt *gssctxt;
	int r, authenticated = 0;
	struct sshbuf *b;
	gss_buffer_desc mic, gssbuf;
	const char *displayname;
	u_char *p;
	size_t len;

	if (authctxt == NULL || (authctxt->methoddata == NULL && !use_privsep))
		fatal("No authentication or GSSAPI context");

	gssctxt = authctxt->methoddata;

	if ((r = sshpkt_get_string(ssh, &p, &len)) != 0)
		fatal("%s: %s", __func__, ssh_err(r));
	if ((b = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);
	mic.value = p;
	mic.length = len;
	ssh_gssapi_buildmic(b, authctxt->user, authctxt->service,
	    "gssapi-with-mic");

	if ((gssbuf.value = sshbuf_mutable_ptr(b)) == NULL)
		fatal("%s: sshbuf_mutable_ptr failed", __func__);
	gssbuf.length = sshbuf_len(b);

	if (!GSS_ERROR(PRIVSEP(ssh_gssapi_checkmic(gssctxt, &gssbuf, &mic))))
		authenticated = PRIVSEP(ssh_gssapi_userok(authctxt->user));
	else
		logit("GSSAPI MIC check failed");

	sshbuf_free(b);
	free(mic.value);

	if ((!use_privsep || mm_is_monitor()) &&
	    (displayname = ssh_gssapi_displayname()) != NULL)
		auth2_record_info(authctxt, "%s", displayname);

	authctxt->postponed = 0;
	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL);
	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_ERRTOK, NULL);
	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_MIC, NULL);
	ssh_dispatch_set(ssh, SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL);
	userauth_finish(ssh, authenticated, "gssapi-with-mic", NULL);
	return 0;
}
예제 #5
0
파일: kex.c 프로젝트: sokoow/openssh
int
kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen,
    const BIGNUM *secret)
{
	struct sshbuf *shared_secret;
	int r;

	if ((shared_secret = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_bignum2(shared_secret, secret)) == 0)
		r = kex_derive_keys(ssh, hash, hashlen, shared_secret);
	sshbuf_free(shared_secret);
	return r;
}
예제 #6
0
char *
ssh_gssapi_last_error(Gssctxt *ctxt, OM_uint32 *major_status,
    OM_uint32 *minor_status)
{
	OM_uint32 lmin;
	gss_buffer_desc msg = GSS_C_EMPTY_BUFFER;
	OM_uint32 ctx;
	struct sshbuf *b;
	char *ret;
	int r;

	if ((b = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);

	if (major_status != NULL)
		*major_status = ctxt->major;
	if (minor_status != NULL)
		*minor_status = ctxt->minor;

	ctx = 0;
	/* The GSSAPI error */
	do {
		gss_display_status(&lmin, ctxt->major,
		    GSS_C_GSS_CODE, ctxt->oid, &ctx, &msg);

		if ((r = sshbuf_put(b, msg.value, msg.length)) != 0 ||
		    (r = sshbuf_put_u8(b, '\n')) != 0)
			fatal("%s: buffer error: %s", __func__, ssh_err(r));

		gss_release_buffer(&lmin, &msg);
	} while (ctx != 0);

	/* The mechanism specific error */
	do {
		gss_display_status(&lmin, ctxt->minor,
		    GSS_C_MECH_CODE, ctxt->oid, &ctx, &msg);

		if ((r = sshbuf_put(b, msg.value, msg.length)) != 0 ||
		    (r = sshbuf_put_u8(b, '\n')) != 0)
			fatal("%s: buffer error: %s", __func__, ssh_err(r));

		gss_release_buffer(&lmin, &msg);
	} while (ctx != 0);

	if ((r = sshbuf_put_u8(b, '\n')) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	ret = xstrdup((const char *)sshbuf_ptr(b));
	sshbuf_free(b);
	return (ret);
}
예제 #7
0
static void
send_data_or_handle(char type, u_int32_t id, const u_char *data, int dlen)
{
	struct sshbuf *msg;
	int r;

	if ((msg = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);
	if ((r = sshbuf_put_u8(msg, type)) != 0 ||
	    (r = sshbuf_put_u32(msg, id)) != 0 ||
	    (r = sshbuf_put_string(msg, data, dlen)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	send_msg(msg);
	sshbuf_free(msg);
}
예제 #8
0
static void
send_attrib(u_int32_t id, const Attrib *a)
{
	struct sshbuf *msg;
	int r;

	debug("request %u: sent attrib have 0x%x", id, a->flags);
	if ((msg = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);
	if ((r = sshbuf_put_u8(msg, SSH2_FXP_ATTRS)) != 0 ||
	    (r = sshbuf_put_u32(msg, id)) != 0 ||
	    (r = encode_attrib(msg, a)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	send_msg(msg);
	sshbuf_free(msg);
}
예제 #9
0
void
mm_send_keystate(struct monitor *monitor)
{
	struct ssh *ssh = active_state;		/* XXX */
	struct sshbuf *m;
	int r;

	if ((m = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);
	if ((r = ssh_packet_get_state(ssh, m)) != 0)
		fatal("%s: get_state failed: %s",
		    __func__, ssh_err(r));
	mm_request_send(monitor->m_recvfd, MONITOR_REQ_KEYEXPORT, m);
	debug3("%s: Finished sending state", __func__);
	sshbuf_free(m);
}
예제 #10
0
/*
 * Removes an identity from the authentication server.
 * This call is intended only for use by ssh-add(1) and like applications.
 */
int
ssh_remove_identity(int sock, struct sshkey *key)
{
	struct sshbuf *msg;
	int r;
	u_char type, *blob = NULL;
	size_t blen;

	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;

#ifdef WITH_SSH1
	if (key->type == KEY_RSA1) {
		if ((r = sshbuf_put_u8(msg,
		    SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 ||
		    (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
		    (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
		    (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0)
			goto out;
	} else
#endif
	if (key->type != KEY_UNSPEC) {
		if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
			goto out;
		if ((r = sshbuf_put_u8(msg,
		    SSH2_AGENTC_REMOVE_IDENTITY)) != 0 ||
		    (r = sshbuf_put_string(msg, blob, blen)) != 0)
			goto out;
	} else {
		r = SSH_ERR_INVALID_ARGUMENT;
		goto out;
	}
	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	r = decode_reply(type);
 out:
	if (blob != NULL) {
		explicit_bzero(blob, blen);
		free(blob);
	}
	sshbuf_free(msg);
	return r;
}
예제 #11
0
static struct sshkey *
keygrab_ssh1(con *c)
{
	static struct sshkey *rsa;
	static struct sshbuf *msg;
	int r;
	u_char type;

	if (rsa == NULL) {
		if ((rsa = sshkey_new(KEY_RSA1)) == NULL) {
			error("%s: sshkey_new failed", __func__);
			return NULL;
		}
		if ((msg = sshbuf_new()) == NULL)
			fatal("%s: sshbuf_new failed", __func__);
	}
	if ((r = sshbuf_put(msg, c->c_data, c->c_plen)) != 0 ||
	    (r = sshbuf_consume(msg, 8 - (c->c_plen & 7))) != 0 || /* padding */
	    (r = sshbuf_get_u8(msg, &type)) != 0)
		goto buf_err;
	if (type != (int) SSH_SMSG_PUBLIC_KEY) {
		error("%s: invalid packet type", c->c_name);
		sshbuf_reset(msg);
		return NULL;
	}
	if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */
	    /* server key */
	    (r = sshbuf_get_u32(msg, NULL)) != 0 ||
	    (r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
	    (r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
	    /* host key */
	    (r = sshbuf_get_u32(msg, NULL)) != 0 ||
	    (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 ||
	    (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) {
 buf_err:
		error("%s: buffer error: %s", __func__, ssh_err(r));
		sshbuf_reset(msg);
		return NULL;
	}

	sshbuf_reset(msg);

	return (rsa);
}
예제 #12
0
int
pkcs11_add_provider(char *name, char *pin, struct sshkey ***keysp)
{
	struct sshkey *k;
	int r;
	u_char *blob;
	size_t blen;
	u_int nkeys, i;
	struct sshbuf *msg;

	if (fd < 0 && pkcs11_start_helper() < 0)
		return (-1);

	if ((msg = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);
	if ((r = sshbuf_put_u8(msg, SSH_AGENTC_ADD_SMARTCARD_KEY)) != 0 ||
	    (r = sshbuf_put_cstring(msg, name)) != 0 ||
	    (r = sshbuf_put_cstring(msg, pin)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	send_msg(msg);
	sshbuf_reset(msg);

	if (recv_msg(msg) == SSH2_AGENT_IDENTITIES_ANSWER) {
		if ((r = sshbuf_get_u32(msg, &nkeys)) != 0)
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
		*keysp = xcalloc(nkeys, sizeof(struct sshkey *));
		for (i = 0; i < nkeys; i++) {
			/* XXX clean up properly instead of fatal() */
			if ((r = sshbuf_get_string(msg, &blob, &blen)) != 0 ||
			    (r = sshbuf_skip_string(msg)) != 0)
				fatal("%s: buffer error: %s",
				    __func__, ssh_err(r));
			if ((r = sshkey_from_blob(blob, blen, &k)) != 0)
				fatal("%s: bad key: %s", __func__, ssh_err(r));
			wrap_key(k->rsa);
			(*keysp)[i] = k;
			xfree(blob);
		}
	} else {
		nkeys = -1;
	}
	sshbuf_free(msg);
	return (nkeys);
}
예제 #13
0
int
sshkey_save_private(struct sshkey *key, const char *filename,
    const char *passphrase, const char *comment)
{
	struct sshbuf *keyblob = NULL;
	int r;

	if ((keyblob = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshkey_private_to_blob(key, keyblob, passphrase,
	    comment)) != 0)
		goto out;
	if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
		goto out;
	r = 0;
 out:
	sshbuf_free(keyblob);
	return r;
}
예제 #14
0
/* XXX - see also comment in auth-chall.c:verify_response */
static int
sshpam_respond(void *ctx, u_int num, char **resp)
{
	struct sshbuf *buffer;
	struct pam_ctxt *ctxt = ctx;
	char *fake;
	int r;

	debug2("PAM: %s entering, %u responses", __func__, num);
	switch (ctxt->pam_done) {
	case 1:
		sshpam_authenticated = 1;
		return (0);
	case 0:
		break;
	default:
		return (-1);
	}
	if (num != 1) {
		error("PAM: expected one response, got %u", num);
		return (-1);
	}
	if ((buffer = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);
	if (sshpam_authctxt->valid &&
	    (sshpam_authctxt->pw->pw_uid != 0 ||
	    options.permit_root_login == PERMIT_YES)) {
		if ((r = sshbuf_put_cstring(buffer, *resp)) != 0)
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
	} else {
		fake = fake_password(*resp);
		if ((r = sshbuf_put_cstring(buffer, fake)) != 0)
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
		free(fake);
	}
	if (ssh_msg_send(ctxt->pam_psock, PAM_AUTHTOK, buffer) == -1) {
		sshbuf_free(buffer);
		return (-1);
	}
	sshbuf_free(buffer);
	return (1);
}
예제 #15
0
int
sshkey_save_private(struct sshkey *key, const char *filename,
    const char *passphrase, const char *comment,
    int force_new_format, const char *new_format_cipher, int new_format_rounds)
{
	struct sshbuf *keyblob = NULL;
	int r;

	if ((keyblob = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshkey_private_to_fileblob(key, keyblob, passphrase, comment,
	    force_new_format, new_format_cipher, new_format_rounds)) != 0)
		goto out;
	if ((r = sshkey_save_private_blob(keyblob, filename)) != 0)
		goto out;
	r = 0;
 out:
	sshbuf_free(keyblob);
	return r;
}
예제 #16
0
int
pkcs11_del_provider(char *name)
{
	int r, ret = -1;
	struct sshbuf *msg;

	if ((msg = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);
	if ((r = sshbuf_put_u8(msg, SSH_AGENTC_REMOVE_SMARTCARD_KEY)) != 0 ||
	    (r = sshbuf_put_cstring(msg, name)) != 0 ||
	    (r = sshbuf_put_cstring(msg, "")) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	send_msg(msg);
	sshbuf_reset(msg);

	if (recv_msg(msg) == SSH_AGENT_SUCCESS)
		ret = 0;
	sshbuf_free(msg);
	return (ret);
}
예제 #17
0
/* XXX kill perm_ok now that we have SSH_ERR_KEY_BAD_PERMISSIONS? */
int
sshkey_load_private_type(int type, const char *filename, const char *passphrase,
    struct sshkey **keyp, char **commentp, int *perm_ok)
{
	int fd, r;
	struct sshbuf *buffer = NULL;

	*keyp = NULL;
	if (commentp != NULL)
		*commentp = NULL;

	if ((fd = open(filename, O_RDONLY)) < 0) {
		if (perm_ok != NULL)
			*perm_ok = 0;
		return SSH_ERR_SYSTEM_ERROR;
	}
	if (!sshkey_perm_ok(fd, filename)) {
		if (perm_ok != NULL)
			*perm_ok = 0;
		r = SSH_ERR_KEY_BAD_PERMISSIONS;
		goto out;
	}
	if (perm_ok != NULL)
		*perm_ok = 1;

	if ((buffer = sshbuf_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((r = sshkey_load_file(fd, filename, buffer)) != 0)
		goto out;
	if ((r = sshkey_parse_private_type(buffer, type, passphrase,
	    keyp, commentp)) != 0)
		goto out;
	r = 0;
 out:
	close(fd);
	if (buffer != NULL)
		sshbuf_free(buffer);
	return r;
}
예제 #18
0
static int
pkcs11_rsa_private_encrypt(int flen, const u_char *from, u_char *to, RSA *rsa,
    int padding)
{
	struct sshkey key;
	u_char *blob, *signature = NULL;
	size_t blen, slen = 0;
	int r, ret = -1;
	struct sshbuf *msg;

	if (padding != RSA_PKCS1_PADDING)
		return (-1);
	key.type = KEY_RSA;
	key.rsa = rsa;
	if ((r = sshkey_to_blob(&key, &blob, &blen)) != 0) {
		error("%s: sshkey_to_blob: %s", __func__, ssh_err(r));
		return -1;
	}
	if ((msg = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);
	if ((r = sshbuf_put_u8(msg, SSH2_AGENTC_SIGN_REQUEST)) != 0 ||
	    (r = sshbuf_put_string(msg, blob, blen)) != 0 ||
	    (r = sshbuf_put_string(msg, from, flen)) != 0 ||
	    (r = sshbuf_put_u32(msg, 0)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	xfree(blob);
	send_msg(msg);
	sshbuf_reset(msg);

	if (recv_msg(msg) == SSH2_AGENT_SIGN_RESPONSE) {
		if ((r = sshbuf_get_string(msg, &signature, &slen)) != 0)
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
		if (slen <= (size_t)RSA_size(rsa)) {
			memcpy(to, signature, slen);
			ret = slen;
		}
		xfree(signature);
	}
	sshbuf_free(msg);
	return (ret);
}
예제 #19
0
/* Lock/unlock agent */
int
ssh_lock_agent(int sock, int lock, const char *password)
{
	int r;
	u_char type = lock ? SSH_AGENTC_LOCK : SSH_AGENTC_UNLOCK;
	struct sshbuf *msg;

	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_u8(msg, type)) != 0 ||
	    (r = sshbuf_put_cstring(msg, password)) != 0)
		goto out;
	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	r = decode_reply(type);
 out:
	sshbuf_free(msg);
	return r;
}
예제 #20
0
/*
 * Loads the public part of the ssh v1 key file.  Returns NULL if an error was
 * encountered (the file does not exist or is not readable), and the key
 * otherwise.
 */
static int
sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp)
{
	struct sshbuf *b = NULL;
	int r;

	*keyp = NULL;
	if (commentp != NULL)
		*commentp = NULL;

	if ((b = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshkey_load_file(fd, b)) != 0)
		goto out;
	if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)
		goto out;
	r = 0;
 out:
	sshbuf_free(b);
	return r;
}
예제 #21
0
파일: kexc25519.c 프로젝트: mfriedl/openssh
int
kex_c25519_keypair(struct kex *kex)
{
	struct sshbuf *buf = NULL;
	u_char *cp = NULL;
	int r;

	if ((buf = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_reserve(buf, CURVE25519_SIZE, &cp)) != 0)
		goto out;
	kexc25519_keygen(kex->c25519_client_key, cp);
#ifdef DEBUG_KEXECDH
	dump_digest("client public key c25519:", cp, CURVE25519_SIZE);
#endif
	kex->client_pub = buf;
	buf = NULL;
 out:
	sshbuf_free(buf);
	return r;
}
예제 #22
0
파일: kex.c 프로젝트: mpitzl/libopenssh
/* parse buffer and return algorithm proposal */
int
kex_buf2prop(struct sshbuf *raw, int *first_kex_follows, char ***propp)
{
	struct sshbuf *b = NULL;
	u_char v;
	u_int i;
	char **proposal = NULL;
	int r;

	if ((proposal = calloc(PROPOSAL_MAX, sizeof(char *))) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((b = sshbuf_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((r = sshbuf_putb(b, raw)) != 0 ||
	    (r = sshbuf_consume(b, KEX_COOKIE_LEN)) != 0) /* skip cookie */
		goto out;
	/* extract kex init proposal strings */
	for (i = 0; i < PROPOSAL_MAX; i++) {
		if ((r = sshbuf_get_cstring(b, &(proposal[i]), NULL)) != 0)
			goto out;
		debug2("kex_parse_kexinit: %s", proposal[i]);
	}
	/* first kex follows / reserved */
	if ((r = sshbuf_get_u8(b, &v)) != 0 ||
	    (r = sshbuf_get_u32(b, &i)) != 0)
		goto out;
	if (first_kex_follows != NULL)
		*first_kex_follows = i;
	debug2("kex_parse_kexinit: first_kex_follows %d ", v);
	debug2("kex_parse_kexinit: reserved %u ", i);
	r = 0;
	*propp = proposal;
 out:
	if (r != 0 && proposal != NULL)
		kex_prop_free(proposal);
	sshbuf_free(b);
	return r;
}
static void
attempt_parse_blob(u_char *blob, size_t len)
{
	struct sshbuf *p1;
	BIGNUM *bn;
#ifdef OPENSSL_HAS_NISTP256
	EC_KEY *eck;
#endif
	u_char *s;
	size_t l;
	u_int8_t u8;
	u_int16_t u16;
	u_int32_t u32;
	u_int64_t u64;

	p1 = sshbuf_new();
	ASSERT_PTR_NE(p1, NULL);
	ASSERT_INT_EQ(sshbuf_put(p1, blob, len), 0);
	sshbuf_get_u8(p1, &u8);
	sshbuf_get_u16(p1, &u16);
	sshbuf_get_u32(p1, &u32);
	sshbuf_get_u64(p1, &u64);
	if (sshbuf_get_string(p1, &s, &l) == 0) {
		bzero(s, l);
		free(s);
	}
	bn = BN_new();
	sshbuf_get_bignum1(p1, bn);
	BN_clear_free(bn);
	bn = BN_new();
	sshbuf_get_bignum2(p1, bn);
	BN_clear_free(bn);
#ifdef OPENSSL_HAS_NISTP256
	eck = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1);
	ASSERT_PTR_NE(eck, NULL);
	sshbuf_get_eckey(p1, eck);
	EC_KEY_free(eck);
#endif
	sshbuf_free(p1);
}
예제 #24
0
/*
 * Updates authctxt->session_info with details of authentication. Should be
 * whenever an authentication method succeeds.
 */
void
auth2_update_session_info(Authctxt *authctxt, const char *method,
    const char *submethod)
{
	int r;

	if (authctxt->session_info == NULL) {
		if ((authctxt->session_info = sshbuf_new()) == NULL)
			fatal("%s: sshbuf_new", __func__);
	}

	/* Append method[/submethod] */
	if ((r = sshbuf_putf(authctxt->session_info, "%s%s%s",
	    method, submethod == NULL ? "" : "/",
	    submethod == NULL ? "" : submethod)) != 0)
		fatal("%s: append method: %s", __func__, ssh_err(r));

	/* Append key if present */
	if (authctxt->auth_method_key != NULL) {
		if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
		    (r = sshkey_format_text(authctxt->auth_method_key,
		    authctxt->session_info)) != 0)
			fatal("%s: append key: %s", __func__, ssh_err(r));
	}

	if (authctxt->auth_method_info != NULL) {
		/* Ensure no ambiguity here */
		if (strchr(authctxt->auth_method_info, '\n') != NULL)
			fatal("%s: auth_method_info contains \\n", __func__);
		if ((r = sshbuf_put_u8(authctxt->session_info, ' ')) != 0 ||
		    (r = sshbuf_putf(authctxt->session_info, "%s",
		    authctxt->auth_method_info)) != 0) {
			fatal("%s: append method info: %s",
			    __func__, ssh_err(r));
		}
	}
	if ((r = sshbuf_put_u8(authctxt->session_info, '\n')) != 0)
		fatal("%s: append: %s", __func__, ssh_err(r));
}
예제 #25
0
/*
 * Loads the public part of the ssh v1 key file.  Returns NULL if an error was
 * encountered (the file does not exist or is not readable), and the key
 * otherwise.
 */
static int
sshkey_load_public_rsa1(int fd, const char *filename,
    struct sshkey **keyp, char **commentp)
{
	struct sshbuf *buffer = NULL;
	int r;

	*keyp = NULL;
	if (commentp != NULL)
		*commentp = NULL;

	if ((buffer = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshkey_load_file(fd, filename, buffer)) != 0)
		goto out;
	if ((r = sshkey_parse_public_rsa1(buffer, keyp, commentp)) != 0)
		goto out;
	r = 0;
 out:
	sshbuf_free(buffer);
	return r;
}
예제 #26
0
static void
send_names(u_int32_t id, int count, const Stat *stats)
{
	struct sshbuf *msg;
	int i, r;

	if ((msg = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);
	if ((r = sshbuf_put_u8(msg, SSH2_FXP_NAME)) != 0 ||
	    (r = sshbuf_put_u32(msg, id)) != 0 ||
	    (r = sshbuf_put_u32(msg, count)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	debug("request %u: sent names count %d", id, count);
	for (i = 0; i < count; i++) {
		if ((r = sshbuf_put_cstring(msg, stats[i].name)) != 0 ||
		    (r = sshbuf_put_cstring(msg, stats[i].long_name)) != 0 ||
		    (r = encode_attrib(msg, &stats[i].attrib)) != 0)
			fatal("%s: buffer error: %s", __func__, ssh_err(r));
	}
	send_msg(msg);
	sshbuf_free(msg);
}
예제 #27
0
/*
 * Removes all identities from the agent.
 * This call is intended only for use by ssh-add(1) and like applications.
 */
int
ssh_remove_all_identities(int sock, int version)
{
	struct sshbuf *msg;
	u_char type = (version == 1) ?
	    SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES :
	    SSH2_AGENTC_REMOVE_ALL_IDENTITIES;
	int r;

	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_u8(msg, type)) != 0)
		goto out;
	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	r = decode_reply(type);
 out:
	sshbuf_free(msg);
	return r;
}
예제 #28
0
int
ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
    u_char session_id[16], u_char response[16])
{
	struct sshbuf *msg;
	int r;
	u_char type;

	if (key->type != KEY_RSA1)
		return SSH_ERR_INVALID_ARGUMENT;
	if ((msg = sshbuf_new()) == NULL)
		return SSH_ERR_ALLOC_FAIL;
	if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 ||
	    (r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
	    (r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
	    (r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 ||
	    (r = sshbuf_put_bignum1(msg, challenge)) != 0 ||
	    (r = sshbuf_put(msg, session_id, 16)) != 0 ||
	    (r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */
		goto out;
	if ((r = ssh_request_reply(sock, msg, msg)) != 0)
		goto out;
	if ((r = sshbuf_get_u8(msg, &type)) != 0)
		goto out;
	if (agent_failed(type)) {
		r = SSH_ERR_AGENT_FAILURE;
		goto out;
	} else if (type != SSH_AGENT_RSA_RESPONSE) {
		r = SSH_ERR_INVALID_FORMAT;
		goto out;
	}
	if ((r = sshbuf_get(msg, response, 16)) != 0)
		goto out;
	r = 0;
 out:
	sshbuf_free(msg);
	return r;
}
예제 #29
0
int
sshkey_load_private_type_fd(int fd, int type, const char *passphrase,
    struct sshkey **keyp, char **commentp)
{
	struct sshbuf *buffer = NULL;
	int r;

	if ((buffer = sshbuf_new()) == NULL) {
		r = SSH_ERR_ALLOC_FAIL;
		goto out;
	}
	if ((r = sshkey_load_file(fd, buffer)) != 0 ||
	    (r = sshkey_parse_private_fileblob_type(buffer, type,
	    passphrase, keyp, commentp)) != 0)
		goto out;

	/* success */
	r = 0;
 out:
	if (buffer != NULL)
		sshbuf_free(buffer);
	return r;
}
예제 #30
0
/*
 * Caclulate a new key after a reconnect
 */
void
calculate_new_key(u_int64_t *key, u_int64_t cookie, u_int64_t challenge)
{
	u_char hash[SSH_DIGEST_MAX_LENGTH];
	struct sshbuf *b;
	int r;

	if ((b = sshbuf_new()) == NULL)
		fatal("%s: sshbuf_new failed", __func__);
	if ((r = sshbuf_put_u64(b, *key)) != 0 ||
	    (r = sshbuf_put_u64(b, cookie)) != 0 ||
	    (r = sshbuf_put_u64(b, challenge)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));

	if (ssh_digest_buffer(SSH_DIGEST_SHA1, b, hash, sizeof(hash)) != 0)
		fatal("%s: digest_buffer failed", __func__);

	sshbuf_reset(b);
	if ((r = sshbuf_put(b, hash, ssh_digest_bytes(SSH_DIGEST_SHA1))) != 0 ||
	    (r = sshbuf_get_u64(b, key)) != 0)
		fatal("%s: buffer error: %s", __func__, ssh_err(r));
	sshbuf_free(b);
}