Exemple #1
0
/* Confirmation hash calculation */
void
jpake_confirm_hash(const BIGNUM *k,
    const u_char *endpoint_id, u_int endpoint_id_len,
    const u_char *sess_id, u_int sess_id_len,
    u_char **confirm_hash, u_int *confirm_hash_len)
{
	Buffer b;

	/*
	 * Calculate confirmation proof:
	 *     client: H(k || client_id || session_id)
	 *     server: H(k || server_id || session_id)
	 */
	buffer_init(&b);
	buffer_put_bignum2(&b, k);
	buffer_put_string(&b, endpoint_id, endpoint_id_len);
	buffer_put_string(&b, sess_id, sess_id_len);
	if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(),
	    confirm_hash, confirm_hash_len) != 0)
		fatal("%s: hash_buffer", __func__);
	buffer_free(&b);
}
Exemple #2
0
int
mm_answer_rsa_challenge(int sock, Buffer *m)
{
	Key *key = NULL;
	u_char *blob;
	u_int blen;

	debug3("%s entering", __func__);

	if (!authctxt->valid)
		fatal("%s: authctxt not valid", __func__);
	blob = buffer_get_string(m, &blen);
	if (!monitor_allowed_key(blob, blen))
		fatal("%s: bad key, not previously allowed", __func__);
	if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY)
		fatal("%s: key type mismatch", __func__);
	if ((key = key_from_blob(blob, blen)) == NULL)
		fatal("%s: received bad key", __func__);
	if (key->type != KEY_RSA)
		fatal("%s: received bad key type %d", __func__, key->type);
	key->type = KEY_RSA1;
	if (ssh1_challenge)
		BN_clear_free(ssh1_challenge);
	ssh1_challenge = auth_rsa_generate_challenge(key);

	buffer_clear(m);
	buffer_put_bignum2(m, ssh1_challenge);

	debug3("%s sending reply", __func__);
	mm_request_send(sock, MONITOR_ANS_RSACHALLENGE, m);

	monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1);

	xfree(blob);
	key_free(key);
	return (0);
}
Exemple #3
0
int
mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n,
    struct sshkey **rkey)
{
	Buffer m;
	struct sshkey *key;
	u_char *blob;
	u_int blen;
	int r, allowed = 0, have_forced = 0;

	debug3("%s entering", __func__);

	buffer_init(&m);
	buffer_put_bignum2(&m, client_n);

	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);

	allowed = buffer_get_int(&m);

	/* fake forced command */
	auth_clear_options();
	have_forced = buffer_get_int(&m);
	forced_command = have_forced ? xstrdup("true") : NULL;

	if (allowed && rkey != NULL) {
		blob = buffer_get_string(&m, &blen);
		if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
			fatal("%s: key_from_blob failed: %s",
			    __func__, ssh_err(r));
		*rkey = key;
		xfree(blob);
	}
	buffer_free(&m);

	return (allowed);
}
Exemple #4
0
void key_private_serialize(Key *key, buffer_t *b)
{
	char *s;
	
	s = get_sshname_from_key(key);
	buffer_put_cstring(b, s);

	switch (key->type) {
		case KEY_RSA:
			buffer_put_bignum2(b, key->rsa->n);
			buffer_put_bignum2(b, key->rsa->e);
			buffer_put_bignum2(b, key->rsa->d);
			buffer_put_bignum2(b, key->rsa->iqmp);
			buffer_put_bignum2(b, key->rsa->p);
			buffer_put_bignum2(b, key->rsa->q);
			break;

		case KEY_DSA:
			buffer_put_bignum2(b, key->dsa->p);
			buffer_put_bignum2(b, key->dsa->q);
			buffer_put_bignum2(b, key->dsa->g);
			buffer_put_bignum2(b, key->dsa->pub_key);
			buffer_put_bignum2(b, key->dsa->priv_key);
			break;

		case KEY_ECDSA256:
		case KEY_ECDSA384:
		case KEY_ECDSA521:
			buffer_put_cstring(b, curve_keytype_to_name(key->type));
			buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
				EC_KEY_get0_public_key(key->ecdsa));
			buffer_put_bignum2(b, (BIGNUM *)EC_KEY_get0_private_key(key->ecdsa));
			break;

		case KEY_ED25519:
			buffer_put_string(b, key->ed25519_pk, ED25519_PK_SZ);
			buffer_put_string(b, key->ed25519_sk, ED25519_SK_SZ);
			break;

		default:
			break;
	}
}
Exemple #5
0
BOOL generate_SSH2_keysign(Key *keypair, char **sigptr, int *siglen, char *data, int datalen)
{
	buffer_t *msg = NULL;
	char *s;
	int ret;

	msg = buffer_init();
	if (msg == NULL) {
		// TODO: error check
		return FALSE;
	}

	switch (keypair->type) {
	case KEY_RSA: // RSA
	{
		const EVP_MD *evp_md = EVP_sha1();
		EVP_MD_CTX md;
		u_char digest[EVP_MAX_MD_SIZE], *sig;
		u_int slen, dlen, len;
		int ok, nid = NID_sha1;

		// ダイジェスト値の計算
		EVP_DigestInit(&md, evp_md);
		EVP_DigestUpdate(&md, data, datalen);
		EVP_DigestFinal(&md, digest, &dlen);

		slen = RSA_size(keypair->rsa);
		sig = malloc(slen);
		if (sig == NULL)
			goto error;

		// 電子署名を計算
		ok = RSA_sign(nid, digest, dlen, sig, &len, keypair->rsa);
		memset(digest, 'd', sizeof(digest));
		if (ok != 1) { // error
			free(sig);
			goto error;
		}
		// 署名のサイズがバッファより小さい場合、後ろへずらす。先頭はゼロで埋める。
		if (len < slen) {
			u_int diff = slen - len;
			memmove(sig + diff, sig, len);
			memset(sig, 0, diff);

		} else if (len > slen) {
			free(sig);
			goto error;

		} else {
			// do nothing

		}

		s = get_sshname_from_key(keypair);
		buffer_put_string(msg, s, strlen(s));
		buffer_append_length(msg, sig, slen);
		len = buffer_len(msg);

		// setting
		*siglen = len;
		*sigptr = malloc(len);
		if (*sigptr == NULL) {
			free(sig);
			goto error;
		}
		memcpy(*sigptr, buffer_ptr(msg), len);
		free(sig);
		
		break;
	}
	case KEY_DSA: // DSA
	{
		DSA_SIG *sig;
		const EVP_MD *evp_md = EVP_sha1();
		EVP_MD_CTX md;
		u_char digest[EVP_MAX_MD_SIZE], sigblob[SIGBLOB_LEN];
		u_int rlen, slen, len, dlen;

		// ダイジェストの計算
		EVP_DigestInit(&md, evp_md);
		EVP_DigestUpdate(&md, data, datalen);
		EVP_DigestFinal(&md, digest, &dlen);

		// DSA電子署名を計算
		sig = DSA_do_sign(digest, dlen, keypair->dsa);
		memset(digest, 'd', sizeof(digest));
		if (sig == NULL) {
			goto error;
		}

		// BIGNUMからバイナリ値への変換
		rlen = BN_num_bytes(sig->r);
		slen = BN_num_bytes(sig->s);
		if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
			DSA_SIG_free(sig);
			goto error;
		}
		memset(sigblob, 0, SIGBLOB_LEN);
		BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
		BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
		DSA_SIG_free(sig);

		// setting
		s = get_sshname_from_key(keypair);
		buffer_put_string(msg, s, strlen(s));
		buffer_append_length(msg, sigblob, sizeof(sigblob));
		len = buffer_len(msg);

		// setting
		*siglen = len;
		*sigptr = malloc(len);
		if (*sigptr == NULL) {
			goto error;
		}
		memcpy(*sigptr, buffer_ptr(msg), len);

		break;
	}
	case KEY_ECDSA256: // ECDSA
	case KEY_ECDSA384:
	case KEY_ECDSA521:
	{
		ECDSA_SIG *sig;
		const EVP_MD *evp_md;
		EVP_MD_CTX md;
		u_char digest[EVP_MAX_MD_SIZE];
		u_int len, dlen, nid;
		buffer_t *buf2 = NULL;

		nid = keytype_to_hash_nid(keypair->type);
		if ((evp_md = EVP_get_digestbynid(nid)) == NULL) {
			goto error;
		}
		EVP_DigestInit(&md, evp_md);
		EVP_DigestUpdate(&md, data, datalen);
		EVP_DigestFinal(&md, digest, &dlen);

		sig = ECDSA_do_sign(digest, dlen, keypair->ecdsa);
		memset(digest, 'd', sizeof(digest));

		if (sig == NULL) {
			goto error;
		}

		buf2 = buffer_init();
		if (buf2 == NULL) {
			// TODO: error check
			goto error;
		}
		buffer_put_bignum2(buf2, sig->r);
		buffer_put_bignum2(buf2, sig->s);
		ECDSA_SIG_free(sig);

		s = get_sshname_from_key(keypair);
		buffer_put_string(msg, s, strlen(s));
		buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
		buffer_free(buf2);
		len = buffer_len(msg);

		*siglen = len;
		*sigptr = malloc(len);
		if (*sigptr == NULL) {
			goto error;
		}
		memcpy(*sigptr, buffer_ptr(msg), len);

		break;
	}

	case KEY_ED25519:
		ret = ssh_ed25519_sign(keypair, sigptr, siglen, data, datalen);
		if (ret != 0) 
			goto error;
		break;

	default:
		buffer_free(msg);
		return FALSE;
		break;
	}

	buffer_free(msg);
	return TRUE;

error:
	buffer_free(msg);

	return FALSE;
}
static void
ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
{
	buffer_put_cstring(b, key_ssh_name(key));
	switch (key->type) {
	case KEY_RSA:
		buffer_put_bignum2(b, key->rsa->n);
		buffer_put_bignum2(b, key->rsa->e);
		buffer_put_bignum2(b, key->rsa->d);
		buffer_put_bignum2(b, key->rsa->iqmp);
		buffer_put_bignum2(b, key->rsa->p);
		buffer_put_bignum2(b, key->rsa->q);
		break;
	case KEY_DSA:
		buffer_put_bignum2(b, key->dsa->p);
		buffer_put_bignum2(b, key->dsa->q);
		buffer_put_bignum2(b, key->dsa->g);
		buffer_put_bignum2(b, key->dsa->pub_key);
		buffer_put_bignum2(b, key->dsa->priv_key);
		break;
	}
	buffer_put_cstring(b, comment);
}
Exemple #7
0
// SHA-1(160bit)/SHA-256(256bit)を求める
unsigned char *kex_dh_gex_hash(const EVP_MD *evp_md,
                               char *client_version_string,
                               char *server_version_string,
                               char *ckexinit, int ckexinitlen,
                               char *skexinit, int skexinitlen,
                               u_char *serverhostkeyblob, int sbloblen,
                               int kexgex_min,
                               int kexgex_bits,
                               int kexgex_max,
                               BIGNUM *kexgex_p,
                               BIGNUM *kexgex_g,
                               BIGNUM *client_dh_pub,
                               BIGNUM *server_dh_pub,
                               BIGNUM *shared_secret,
                               unsigned int *hashlen)
{
	buffer_t *b;
	static unsigned char digest[EVP_MAX_MD_SIZE];
	EVP_MD_CTX md;

	b = buffer_init();
	buffer_put_string(b, client_version_string, strlen(client_version_string));
	buffer_put_string(b, server_version_string, strlen(server_version_string));

	/* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
	buffer_put_int(b, ckexinitlen+1);
	buffer_put_char(b, SSH2_MSG_KEXINIT);
	buffer_append(b, ckexinit, ckexinitlen);
	buffer_put_int(b, skexinitlen+1);
	buffer_put_char(b, SSH2_MSG_KEXINIT);
	buffer_append(b, skexinit, skexinitlen);

	buffer_put_string(b, serverhostkeyblob, sbloblen);

	// DH group sizeのビット数を加算する
	buffer_put_int(b, kexgex_min);
	buffer_put_int(b, kexgex_bits);
	buffer_put_int(b, kexgex_max);

	// DH鍵の素数と生成元を加算する
	buffer_put_bignum2(b, kexgex_p);
	buffer_put_bignum2(b, kexgex_g);

	buffer_put_bignum2(b, client_dh_pub);
	buffer_put_bignum2(b, server_dh_pub);
	buffer_put_bignum2(b, shared_secret);

	// yutaka
	//debug_print(38, buffer_ptr(b), buffer_len(b));

	EVP_DigestInit(&md, evp_md);
	EVP_DigestUpdate(&md, buffer_ptr(b), buffer_len(b));
	EVP_DigestFinal(&md, digest, NULL);

	buffer_free(b);

	//write_buffer_file(digest, EVP_MD_size(evp_md));

	*hashlen = EVP_MD_size(evp_md);

	return digest;
}
Exemple #8
0
static void
ssh_encode_identity_ssh2(Buffer *b, Key *key, const char *comment)
{
	buffer_put_cstring(b, key_ssh_name(key));
	switch (key->type) {
	case KEY_RSA:
		buffer_put_bignum2(b, key->rsa->n);
		buffer_put_bignum2(b, key->rsa->e);
		buffer_put_bignum2(b, key->rsa->d);
		buffer_put_bignum2(b, key->rsa->iqmp);
		buffer_put_bignum2(b, key->rsa->p);
		buffer_put_bignum2(b, key->rsa->q);
		break;
	case KEY_RSA_CERT_V00:
	case KEY_RSA_CERT:
		if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
			fatal("%s: no cert/certblob", __func__);
		buffer_put_string(b, buffer_ptr(&key->cert->certblob),
		    buffer_len(&key->cert->certblob));
		buffer_put_bignum2(b, key->rsa->d);
		buffer_put_bignum2(b, key->rsa->iqmp);
		buffer_put_bignum2(b, key->rsa->p);
		buffer_put_bignum2(b, key->rsa->q);
		break;
	case KEY_DSA:
		buffer_put_bignum2(b, key->dsa->p);
		buffer_put_bignum2(b, key->dsa->q);
		buffer_put_bignum2(b, key->dsa->g);
		buffer_put_bignum2(b, key->dsa->pub_key);
		buffer_put_bignum2(b, key->dsa->priv_key);
		break;
	case KEY_DSA_CERT_V00:
	case KEY_DSA_CERT:
		if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
			fatal("%s: no cert/certblob", __func__);
		buffer_put_string(b, buffer_ptr(&key->cert->certblob),
		    buffer_len(&key->cert->certblob));
		buffer_put_bignum2(b, key->dsa->priv_key);
		break;
	case KEY_ECDSA:
		buffer_put_cstring(b, key_curve_nid_to_name(key->ecdsa_nid));
		buffer_put_ecpoint(b, EC_KEY_get0_group(key->ecdsa),
		    EC_KEY_get0_public_key(key->ecdsa));
		buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
		break;
	case KEY_ECDSA_CERT:
		if (key->cert == NULL || buffer_len(&key->cert->certblob) == 0)
			fatal("%s: no cert/certblob", __func__);
		buffer_put_string(b, buffer_ptr(&key->cert->certblob),
		    buffer_len(&key->cert->certblob));
		buffer_put_bignum2(b, EC_KEY_get0_private_key(key->ecdsa));
		break;
	}
	buffer_put_cstring(b, comment);
}