Ejemplo n.º 1
0
int signkey_generate(enum signkey_type keytype, int bits, const char* filename)
{
	sign_key * key = NULL;
	buffer *buf = NULL;
	int ret = DROPBEAR_FAILURE;
	if (bits == 0)
	{
		bits = get_default_bits(keytype);
	}

	/* now we can generate the key */
	key = new_sign_key();

	seedrandom();

	switch(keytype) {
#ifdef DROPBEAR_RSA
		case DROPBEAR_SIGNKEY_RSA:
			key->rsakey = gen_rsa_priv_key(bits);
			break;
#endif
#ifdef DROPBEAR_DSS
		case DROPBEAR_SIGNKEY_DSS:
			key->dsskey = gen_dss_priv_key(bits);
			break;
#endif
#ifdef DROPBEAR_ECDSA
		case DROPBEAR_SIGNKEY_ECDSA_KEYGEN:
		case DROPBEAR_SIGNKEY_ECDSA_NISTP521:
		case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
		case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
			{
				ecc_key *ecckey = gen_ecdsa_priv_key(bits);
				keytype = ecdsa_signkey_type(ecckey);
				*signkey_key_ptr(key, keytype) = ecckey;
			}
			break;
#endif
		default:
			dropbear_exit("Internal error");
	}

	seedrandom();

	buf = buf_new(MAX_PRIVKEY_SIZE); 

	buf_put_priv_key(buf, key, keytype);
	sign_key_free(key);
	key = NULL;
	buf_setpos(buf, 0);
	ret = buf_writefile(buf, filename);

	buf_burn(buf);
	buf_free(buf);
	buf = NULL;
	return ret;
}
Ejemplo n.º 2
0
/* if skip_exist is set it will silently return if the key file exists */
int signkey_generate(enum signkey_type keytype, int bits, const char* filename, int skip_exist)
{
	sign_key * key = NULL;
	buffer *buf = NULL;
	char *fn_temp = NULL;
	int ret = DROPBEAR_FAILURE;
	bits = signkey_generate_get_bits(keytype, bits);

	/* now we can generate the key */
	key = new_sign_key();

	seedrandom();

	switch(keytype) {
#if DROPBEAR_RSA
		case DROPBEAR_SIGNKEY_RSA:
			key->rsakey = gen_rsa_priv_key(bits);
			break;
#endif
#if DROPBEAR_DSS
		case DROPBEAR_SIGNKEY_DSS:
			key->dsskey = gen_dss_priv_key(bits);
			break;
#endif
#if DROPBEAR_ECDSA
		case DROPBEAR_SIGNKEY_ECDSA_KEYGEN:
		case DROPBEAR_SIGNKEY_ECDSA_NISTP521:
		case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
		case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
			{
				ecc_key *ecckey = gen_ecdsa_priv_key(bits);
				keytype = ecdsa_signkey_type(ecckey);
				*signkey_key_ptr(key, keytype) = ecckey;
			}
			break;
#endif
		default:
			dropbear_exit("Internal error");
	}

	seedrandom();

	buf = buf_new(MAX_PRIVKEY_SIZE); 

	buf_put_priv_key(buf, key, keytype);
	sign_key_free(key);
	key = NULL;
	buf_setpos(buf, 0);

	fn_temp = m_malloc(strlen(filename) + 30);
	snprintf(fn_temp, strlen(filename)+30, "%s.tmp%d", filename, getpid());
	ret = buf_writefile(buf, fn_temp);

	if (ret == DROPBEAR_FAILURE) {
		goto out;
	}

	if (link(fn_temp, filename) < 0) {
		/* If generating keys on connection (skipexist) it's OK to get EEXIST 
		- we probably just lost a race with another connection to generate the key */
		if (!(skip_exist && errno == EEXIST)) {
			dropbear_log(LOG_ERR, "Failed moving key file to %s: %s", filename,
				strerror(errno));
			/* XXX fallback to non-atomic copy for some filesystems? */
			ret = DROPBEAR_FAILURE;
			goto out;
		}
	}

out:
	if (buf) {
		buf_burn(buf);
		buf_free(buf);
	}
	
	if (fn_temp) {
		unlink(fn_temp);
		m_free(fn_temp);
	}

	return ret;
}