Пример #1
0
static void
recv_rexec_state(int fd, Buffer *conf)
{
	Buffer m;
	char *cp;
	u_int len;

	debug3("%s: entering fd = %d", __func__, fd);

	buffer_init(&m);

	if (ssh_msg_recv(fd, &m) == -1)
		fatal("%s: ssh_msg_recv failed", __func__);
	if (buffer_get_char(&m) != 0)
		fatal("%s: rexec version mismatch", __func__);

	cp = buffer_get_string(&m, &len);
	if (conf != NULL)
		buffer_append(conf, cp, len + 1);
	xfree(cp);

	if (buffer_get_int(&m)) {
		if (sensitive_data.server_key != NULL)
			key_free(sensitive_data.server_key);
		sensitive_data.server_key = key_new_private(KEY_RSA1);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->e);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->n);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->d);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->iqmp);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->p);
		buffer_get_bignum(&m, sensitive_data.server_key->rsa->q);
		rsa_generate_additional_parameters(
		    sensitive_data.server_key->rsa);
	}
	buffer_free(&m);

	debug3("%s: done", __func__);
}
Пример #2
0
Key *key_private_deserialize(buffer_t *blob)
{
	int success = 0;
	char *type_name = NULL;
	Key *k = NULL;
	unsigned int pklen, sklen;
	int type;

	type_name = buffer_get_string_msg(blob, NULL);
	if (type_name == NULL)
		goto error;
	type = get_keytype_from_name(type_name);

	k = key_new_private(type);

	switch (type) {
		case KEY_RSA:
			buffer_get_bignum2_msg(blob, k->rsa->n);
			buffer_get_bignum2_msg(blob, k->rsa->e);
			buffer_get_bignum2_msg(blob, k->rsa->d);
			buffer_get_bignum2_msg(blob, k->rsa->iqmp);
			buffer_get_bignum2_msg(blob, k->rsa->p);
			buffer_get_bignum2_msg(blob, k->rsa->q);

			/* Generate additional parameters */
			rsa_generate_additional_parameters(k->rsa);
			break;

		case KEY_DSA:
			buffer_get_bignum2_msg(blob, k->dsa->p);
			buffer_get_bignum2_msg(blob, k->dsa->q);
			buffer_get_bignum2_msg(blob, k->dsa->g);
			buffer_get_bignum2_msg(blob, k->dsa->pub_key);
			buffer_get_bignum2_msg(blob, k->dsa->priv_key);
			break;

		case KEY_ECDSA256:
		case KEY_ECDSA384:
		case KEY_ECDSA521:
			{
			int success = 0;
			unsigned int nid;
			char *curve = NULL;
			ssh_keytype skt;
			BIGNUM *exponent = NULL;
			EC_POINT *q = NULL;

			nid = keytype_to_cipher_nid(type);
			curve = buffer_get_string_msg(blob, NULL);
			skt = key_curve_name_to_keytype(curve);
			if (nid != keytype_to_cipher_nid(skt))
				goto ecdsa_error;

			k->ecdsa = EC_KEY_new_by_curve_name(nid);
			if (k->ecdsa == NULL)
				goto ecdsa_error;

			q = EC_POINT_new(EC_KEY_get0_group(k->ecdsa));
			if (q == NULL)
				goto ecdsa_error;

			if ((exponent = BN_new()) == NULL)
				goto ecdsa_error;
			buffer_get_ecpoint_msg(blob,
				EC_KEY_get0_group(k->ecdsa), q);
			buffer_get_bignum2_msg(blob, exponent);
			if (EC_KEY_set_public_key(k->ecdsa, q) != 1)
				goto ecdsa_error;
			if (EC_KEY_set_private_key(k->ecdsa, exponent) != 1)
				goto ecdsa_error;
			if (key_ec_validate_public(EC_KEY_get0_group(k->ecdsa),
				EC_KEY_get0_public_key(k->ecdsa)) != 0)
				goto ecdsa_error;
			if (key_ec_validate_private(k->ecdsa) != 0)
				goto ecdsa_error;

			success = 1;

ecdsa_error:
			free(curve);
			if (exponent)
				BN_clear_free(exponent);
			if (q)
				EC_POINT_free(q);
			if (success == 0)
				goto error;
			}
			break;

		case KEY_ED25519:
			k->ed25519_pk = buffer_get_string_msg(blob, &pklen);
			k->ed25519_sk = buffer_get_string_msg(blob, &sklen);
			if (pklen != ED25519_PK_SZ) 
				goto error;
			if (sklen != ED25519_SK_SZ)
				goto error;
			break;

		default:
			goto error;
			break;
	}

	/* enable blinding */
	switch (k->type) {
		case KEY_RSA1:
		case KEY_RSA:
			if (RSA_blinding_on(k->rsa, NULL) != 1) 
				goto error;
			break;
	}

	success = 1;

error:
	free(type_name);

	if (success == 0) {
		key_free(k);
		k = NULL;
	}

	return (k);
}
Пример #3
0
static Key *
key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
                      char **commentp)
{
    int i, check1, check2, cipher_type;
    off_t len;
    Buffer buffer, decrypted;
    u_char *cp;
    CipherContext ciphercontext;
    Cipher *cipher;
    Key *prv = NULL;
    struct stat st;

    if (fstat(fd, &st) < 0) {
        error("fstat for key file %.200s failed: %.100s",
              filename, strerror(errno));
        close(fd);
        return NULL;
    }
    len = st.st_size;

    buffer_init(&buffer);
    cp = buffer_append_space(&buffer, len);

    if (read(fd, cp, (size_t) len) != (size_t) len) {
        debug("Read from key file %.200s failed: %.100s", filename,
              strerror(errno));
        buffer_free(&buffer);
        close(fd);
        return NULL;
    }

    /* Check that it is at least big enough to contain the ID string. */
    if (len < sizeof(authfile_id_string)) {
        debug3("Not a RSA1 key file %.200s.", filename);
        buffer_free(&buffer);
        close(fd);
        return NULL;
    }
    /*
     * Make sure it begins with the id string.  Consume the id string
     * from the buffer.
     */
    for (i = 0; i < sizeof(authfile_id_string); i++)
        if (buffer_get_char(&buffer) != authfile_id_string[i]) {
            debug3("Not a RSA1 key file %.200s.", filename);
            buffer_free(&buffer);
            close(fd);
            return NULL;
        }

    /* Read cipher type. */
    cipher_type = buffer_get_char(&buffer);
    (void) buffer_get_int(&buffer);	/* Reserved data. */

    /* Read the public key from the buffer. */
    (void) buffer_get_int(&buffer);
    prv = key_new_private(KEY_RSA1);

    buffer_get_bignum(&buffer, prv->rsa->n);
    buffer_get_bignum(&buffer, prv->rsa->e);
    if (commentp)
        *commentp = buffer_get_string(&buffer, NULL);
    else
        xfree(buffer_get_string(&buffer, NULL));

    /* Check that it is a supported cipher. */
    cipher = cipher_by_number(cipher_type);
    if (cipher == NULL) {
        debug("Unsupported cipher %d used in key file %.200s.",
              cipher_type, filename);
        buffer_free(&buffer);
        goto fail;
    }
    /* Initialize space for decrypted data. */
    buffer_init(&decrypted);
    cp = buffer_append_space(&decrypted, buffer_len(&buffer));

    /* Rest of the buffer is encrypted.  Decrypt it using the passphrase. */
    cipher_set_key_string(&ciphercontext, cipher, passphrase,
                          CIPHER_DECRYPT);
    cipher_crypt(&ciphercontext, cp,
                 buffer_ptr(&buffer), buffer_len(&buffer));
    cipher_cleanup(&ciphercontext);
    memset(&ciphercontext, 0, sizeof(ciphercontext));
    buffer_free(&buffer);

    check1 = buffer_get_char(&decrypted);
    check2 = buffer_get_char(&decrypted);
    if (check1 != buffer_get_char(&decrypted) ||
            check2 != buffer_get_char(&decrypted)) {
        if (strcmp(passphrase, "") != 0)
            debug("Bad passphrase supplied for key file %.200s.",
                  filename);
        /* Bad passphrase. */
        buffer_free(&decrypted);
        goto fail;
    }
    /* Read the rest of the private key. */
    buffer_get_bignum(&decrypted, prv->rsa->d);
    buffer_get_bignum(&decrypted, prv->rsa->iqmp);		/* u */
    /* in SSL and SSH v1 p and q are exchanged */
    buffer_get_bignum(&decrypted, prv->rsa->q);		/* p */
    buffer_get_bignum(&decrypted, prv->rsa->p);		/* q */

    /* calculate p-1 and q-1 */
    rsa_generate_additional_parameters(prv->rsa);

    buffer_free(&decrypted);

    /* enable blinding */
    if (RSA_blinding_on(prv->rsa, NULL) != 1) {
        error("key_load_private_rsa1: RSA_blinding_on failed");
        goto fail;
    }
    close(fd);
    return prv;

fail:
    if (commentp)
        xfree(*commentp);
    close(fd);
    key_free(prv);
    return NULL;
}