Esempio n. 1
0
/*
 * Decrypt session_key_int using our private server key and private host key
 * (key with larger modulus first).
 */
int
ssh1_session_key(BIGNUM *session_key_int)
{
	int rsafail = 0;

	if (BN_cmp(sensitive_data.server_key->rsa->n, sensitive_data.ssh1_host_key->rsa->n) > 0) {
		/* Server key has bigger modulus. */
		if (BN_num_bits(sensitive_data.server_key->rsa->n) <
		    BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
			fatal("do_connection: %s: server_key %d < host_key %d + SSH_KEY_BITS_RESERVED %d",
			    get_remote_ipaddr(),
			    BN_num_bits(sensitive_data.server_key->rsa->n),
			    BN_num_bits(sensitive_data.ssh1_host_key->rsa->n),
			    SSH_KEY_BITS_RESERVED);
		}
		if (rsa_private_decrypt(session_key_int, session_key_int,
		    sensitive_data.server_key->rsa) <= 0)
			rsafail++;
		if (rsa_private_decrypt(session_key_int, session_key_int,
		    sensitive_data.ssh1_host_key->rsa) <= 0)
			rsafail++;
	} else {
		/* Host key has bigger modulus (or they are equal). */
		if (BN_num_bits(sensitive_data.ssh1_host_key->rsa->n) <
		    BN_num_bits(sensitive_data.server_key->rsa->n) + SSH_KEY_BITS_RESERVED) {
			fatal("do_connection: %s: host_key %d < server_key %d + SSH_KEY_BITS_RESERVED %d",
			    get_remote_ipaddr(),
			    BN_num_bits(sensitive_data.ssh1_host_key->rsa->n),
			    BN_num_bits(sensitive_data.server_key->rsa->n),
			    SSH_KEY_BITS_RESERVED);
		}
		if (rsa_private_decrypt(session_key_int, session_key_int,
		    sensitive_data.ssh1_host_key->rsa) < 0)
			rsafail++;
		if (rsa_private_decrypt(session_key_int, session_key_int,
		    sensitive_data.server_key->rsa) < 0)
			rsafail++;
	}
	return (rsafail);
}
Esempio n. 2
0
/*
 * Computes the proper response to a RSA challenge, and sends the response to
 * the server.
 */
static void
respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
{
	u_char buf[32], response[16];
	struct ssh_digest_ctx *md;
	int i, len;

	/* Decrypt the challenge using the private key. */
	/* XXX think about Bleichenbacher, too */
	if (rsa_private_decrypt(challenge, challenge, prv) != 0)
		packet_disconnect(
		    "respond_to_rsa_challenge: rsa_private_decrypt failed");

	/* Compute the response. */
	/* The response is MD5 of decrypted challenge plus session id. */
	len = BN_num_bytes(challenge);
	if (len <= 0 || (u_int)len > sizeof(buf))
		packet_disconnect(
		    "respond_to_rsa_challenge: bad challenge length %d", len);

	memset(buf, 0, sizeof(buf));
	BN_bn2bin(challenge, buf + sizeof(buf) - len);
	if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
	    ssh_digest_update(md, buf, 32) < 0 ||
	    ssh_digest_update(md, session_id, 16) < 0 ||
	    ssh_digest_final(md, response, sizeof(response)) < 0)
		fatal("%s: md5 failed", __func__);
	ssh_digest_free(md);

	debug("Sending response to host key RSA challenge.");

	/* Send the response back to the server. */
	packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
	for (i = 0; i < 16; i++)
		packet_put_char(response[i]);
	packet_send();
	packet_write_wait();

	explicit_bzero(buf, sizeof(buf));
	explicit_bzero(response, sizeof(response));
	explicit_bzero(&md, sizeof(md));
}
Esempio n. 3
0
/*
 * Computes the proper response to a RSA challenge, and sends the response to
 * the server.
 */
static void
respond_to_rsa_challenge(struct ssh *ssh, BIGNUM * challenge, RSA * prv)
{
    u_char buf[32], response[16];
    MD5_CTX md;
    int r, len;

    /* Decrypt the challenge using the private key. */
    /* XXX think about Bleichenbacher, too */
    if ((r = rsa_private_decrypt(challenge, challenge, prv)) != 0) {
        ssh_packet_disconnect(ssh,  "%s: rsa_private_decrypt: %s",
                              __func__, ssh_err(r));
    }

    /* Compute the response. */
    /* The response is MD5 of decrypted challenge plus session id. */
    len = BN_num_bytes(challenge);
    if (len <= 0 || (u_int)len > sizeof(buf))
        ssh_packet_disconnect(ssh,
                              "respond_to_rsa_challenge: bad challenge length %d", len);

    memset(buf, 0, sizeof(buf));
    BN_bn2bin(challenge, buf + sizeof(buf) - len);
    MD5_Init(&md);
    MD5_Update(&md, buf, 32);
    MD5_Update(&md, session_id, 16);
    MD5_Final(response, &md);

    debug("Sending response to host key RSA challenge.");

    /* Send the response back to the server. */
    if ((r = sshpkt_start(ssh, SSH_CMSG_AUTH_RSA_RESPONSE)) != 0 ||
            (r = sshpkt_put(ssh, &response, sizeof(response))) != 0 ||
            (r = sshpkt_send(ssh)) != 0)
        fatal("%s: %s", __func__, ssh_err(r));
    ssh_packet_write_wait(ssh);

    memset(buf, 0, sizeof(buf));
    memset(response, 0, sizeof(response));
    memset(&md, 0, sizeof(md));
}
Esempio n. 4
0
kal_bool che_sw_rsa(STCHE* che_context, CHE_ACTION act, kal_uint8* data_src, kal_uint8* data_dst, kal_int32 length, kal_bool last_block){
	rsa_context rsa;
    memset( &rsa, 0, sizeof( rsa ) );
    rsa.len = length;
    mpi_read( &rsa.N , che_context->modulusN, 16, che_context->modulusNLen );
    mpi_read( &rsa.E , che_context->pubExp, 16, che_context->pubExpLen );
    mpi_read( &rsa.D , che_context->privExpD, 16, che_context->privExpDLen );
    mpi_read( &rsa.P , che_context->primeP, 16, che_context->primePLen );
    mpi_read( &rsa.Q , che_context->primeQ, 16,che_context->primeQLen );
    mpi_read( &rsa.DP, che_context->dModPm1, 16,che_context->dModPm1Len );
    mpi_read( &rsa.DQ, che_context->dModQm1, 16,che_context->dModQm1Len );
    mpi_read( &rsa.QP, che_context->qInvModP, 16,che_context->qInvModPLen );
	if( rsa_check_pubkey(  &rsa ) != 0 || rsa_check_privkey( &rsa ) != 0 ){
	    ASSERT(0);
	}
	switch (act){
       case RSA_PUBLIC_ENC: 
         if( rsa_public_encrypt( &rsa, data_src, length, data_dst, length ) != 0 ){
             ASSERT(0);
		     }
       break;
       case RSA_PUBLIC_DEC: 
         if( rsa_public_decrypt( &rsa, data_src, length, data_dst, length ) != 0 ){
             ASSERT(0);
		 }
       break;
       case RSA_PRIVATE_ENC: 
         if( rsa_private_encrypt( &rsa, data_src, length, data_dst, length ) != 0 ){
             ASSERT(0);
		 }
       break;
	   case RSA_PRIVATE_DEC: 
         if( rsa_private_decrypt( &rsa, data_src, length, data_dst, length ) != 0 ){
             ASSERT(0);
		 }
	   break;
       default:
         return KAL_FALSE;
    }
    return KAL_TRUE;
}
Esempio n. 5
0
/*
 * Computes the proper response to a RSA challenge, and sends the response to
 * the server.
 */
static void
respond_to_rsa_challenge(BIGNUM * challenge, RSA * prv)
{
	u_char buf[32], response[16];
	MD5_CTX md;
	int i, len;

	/* Decrypt the challenge using the private key. */
	/* XXX think about Bleichenbacher, too */
	if (rsa_private_decrypt(challenge, challenge, prv) <= 0)
		packet_disconnect(
		    "respond_to_rsa_challenge: rsa_private_decrypt failed");

	/* Compute the response. */
	/* The response is MD5 of decrypted challenge plus session id. */
	len = BN_num_bytes(challenge);
	if (len <= 0 || len > sizeof(buf))
		packet_disconnect(
		    "respond_to_rsa_challenge: bad challenge length %d", len);

	memset(buf, 0, sizeof(buf));
	BN_bn2bin(challenge, buf + sizeof(buf) - len);
	MD5_Init(&md);
	MD5_Update(&md, buf, 32);
	MD5_Update(&md, session_id, 16);
	MD5_Final(response, &md);

	debug("Sending response to host key RSA challenge.");

	/* Send the response back to the server. */
	packet_start(SSH_CMSG_AUTH_RSA_RESPONSE);
	for (i = 0; i < 16; i++)
		packet_put_char(response[i]);
	packet_send();
	packet_write_wait();

	memset(buf, 0, sizeof(buf));
	memset(response, 0, sizeof(response));
	memset(&md, 0, sizeof(md));
}
Esempio n. 6
0
bool metakey_h(connection_t *c, const char *request) {
	if(!myself->connection->rsa)
		return false;

	char hexkey[MAX_STRING_SIZE];
	int cipher, digest, maclength, compression;
	const size_t len = rsa_size(myself->connection->rsa);
	char enckey[len];
	char key[len];

	if(sscanf(request, "%*d %d %d %d %d " MAX_STRING, &cipher, &digest, &maclength, &compression, hexkey) != 5) {
		logger(DEBUG_ALWAYS, LOG_ERR, "Got bad %s from %s (%s)", "METAKEY", c->name, c->hostname);
		return false;
	}

	/* Convert the challenge from hexadecimal back to binary */

	int inlen = hex2bin(hexkey, enckey, sizeof enckey);

	/* Check if the length of the meta key is all right */

	if(inlen != len) {
		logger(DEBUG_ALWAYS, LOG_ERR, "Possible intruder %s (%s): %s", c->name, c->hostname, "wrong keylength");
		return false;
	}

	/* Decrypt the meta key */

	if(!rsa_private_decrypt(myself->connection->rsa, enckey, len, key)) {
		logger(DEBUG_ALWAYS, LOG_ERR, "Error during decryption of meta key for %s (%s)", c->name, c->hostname);
		return false;
	}

	if(debug_level >= DEBUG_SCARY_THINGS) {
		bin2hex(key, hexkey, len);
		logger(DEBUG_SCARY_THINGS, LOG_DEBUG, "Received random meta key (unencrypted): %s", hexkey);
	}

	/* Check and lookup cipher and digest algorithms */

	if(cipher) {
		if(!(c->incipher = cipher_open_by_nid(cipher)) || !cipher_set_key_from_rsa(c->incipher, key, len, false)) {
			logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of cipher from %s (%s)", c->name, c->hostname);
			return false;
		}
	} else {
		c->incipher = NULL;
	}

	if(digest) {
		if(!(c->indigest = digest_open_by_nid(digest, -1))) {
			logger(DEBUG_ALWAYS, LOG_ERR, "Error during initialisation of digest from %s (%s)", c->name, c->hostname);
			return false;
		}
	} else {
		c->indigest = NULL;
	}

	c->status.decryptin = true;

	c->allow_request = CHALLENGE;

	return send_challenge(c);
}
Esempio n. 7
0
    int
main( int argc, char **argv )
{
    int ret = 0;

    // read device register file
    unsigned char *reg_data = NULL;
    int            reg_len = 0;

    ret = rsa_read_file(C_REG_FILE, reg_data, &reg_len); 
    if( ret == -1) {
        printf("open %s failed!\n", C_REG_FILE);
        goto release_resource;
    }

    reg_data = calloc(reg_len, sizeof(char));
    if( reg_data == NULL) {
        printf("alloc reg data failed! request len = %d \n", reg_len);
        goto release_resource;
    }

    ret = rsa_read_file(C_REG_FILE, reg_data, &reg_len);
    if (ret == -1) {
        printf("read reg data file failed!\n");
        goto release_resource;
    }

    //read server private key buffer
    unsigned char *s_pri_key = NULL;
    int            s_pri_key_len = 0;
    ret = rsa_read_file(S_PRIVATE_KEY_FILE, s_pri_key, &s_pri_key_len);
    if( ret == -1) {
        printf("open %s failed!\n", S_PRIVATE_KEY_FILE);
        goto release_resource;
    }

    s_pri_key = calloc(s_pri_key_len , sizeof(char));
    if( s_pri_key == NULL) {
        printf("alloc s_pri_key failed! request len = %d \n", s_pri_key_len);
        goto release_resource;
    }

    ret = rsa_read_file(S_PRIVATE_KEY_FILE, s_pri_key, &s_pri_key_len);
    if( ret == -1) {
        printf("read server private key data failed!\n");
        goto release_resource;
    }

    //decrypto register file 
    unsigned char *out_data;
    int out_len = 0;
    out_len = 4 * reg_len;
    out_data = calloc(out_len, sizeof(char));
    if(out_data == NULL ) {
        printf("alloc decrypt data failed! request len = %d\n", out_len);
        goto release_resource;
    }
    ret = rsa_private_decrypt(reg_data, reg_len, out_data, &out_len
               ,s_pri_key, s_pri_key_len);
    if( ret == -1 ) {
        printf("decrypt register file failed!\n");
        goto release_resource;
    }
    printf("decrypt register file success , len = %d\n", out_len);

    //splite hardware info and client public key
    unsigned char   *hardware_info = NULL;
    int              hd_info_len = 0;
    
    memcpy(&hd_info_len, out_data, sizeof(int));
    hardware_info = calloc(hd_info_len, sizeof(char));
    if( hardware_info == NULL ) {
        printf("alloc hardware info mem failed! request len = %d\n"
                , hd_info_len);
        goto release_resource;
    }
    memcpy(hardware_info, out_data + sizeof(int), hd_info_len);

    unsigned char   *pub_key = NULL;
    int              key_len = 0;
    memcpy(&key_len, out_data + sizeof(int) + hd_info_len, sizeof(int));
    pub_key = calloc(key_len , sizeof(char));
    if( pub_key == NULL) {
        printf("calloc pub key mem failed! request len = %d\n", key_len);
        goto release_resource;
    }
    memcpy(pub_key, out_data + 2 * sizeof(int) + hd_info_len, key_len);

    // write device key file
    // hardware info and setup info
    unsigned char setup_data[1024];
    int setup_len = 0;

    FILE *fp = fopen(NRS_SETUP_FILE,"rb");
    if( fp == NULL ) {
        printf("open setup file %s failed!\n",NRS_SETUP_FILE);
        goto release_resource;
    }
    setup_len = fread(setup_data, sizeof(char), 1024, fp);
    if( setup_len < 0) {
        printf("read setup data failed!\n");
        goto release_resource;
    }

    unsigned char  *device_key = NULL;
    int  device_key_len = 0;

    device_key_len = setup_len + hd_info_len + sizeof(int) * 2;
    device_key = calloc(device_key_len , sizeof(char));
    if( device_key == NULL ) {
        printf("alloc device key buf failed! request len = %d\n"
                , device_key_len);
        goto release_resource;
    }
    
    memcpy(device_key, &hd_info_len, sizeof(int));
    memcpy(device_key + sizeof(int), hardware_info, hd_info_len);
    memcpy(device_key + sizeof(int) + hd_info_len , &setup_len, sizeof(int));
    memcpy(device_key + sizeof(int) * 2 + hd_info_len , setup_data, setup_len);
    
    ret = write_device_key(device_key, device_key_len,pub_key, key_len );
    if( ret == -1) {
        printf("rsa write device key file %s failed!\n", C_DEVICE_KEY_FILE);
        goto release_resource;
    }

release_resource:
    if( device_key )
        free(device_key);
    if( hardware_info )
        free(hardware_info);
    if( out_data )
        free(out_data);
    if( s_pri_key )
        free(s_pri_key);
    if( reg_data )
        free( reg_data);
    
    if( fp )
        fclose(fp);

    return 0;
}
Esempio n. 8
0
void do_connection(int privileged_port)
{
    int i;
    MP_INT session_key_int;
    unsigned char session_key[SSH_SESSION_KEY_LENGTH];
    unsigned char check_bytes[8];
    char *user;
    unsigned int cipher_type, auth_mask, protocol_flags;

    /* Generate check bytes that the client must send back in the user packet
       in order for it to be accepted; this is used to defy ip spoofing 
       attacks.  Note that this only works against somebody doing IP spoofing 
       from a remote machine; any machine on the local network can still see 
       outgoing packets and catch the random cookie.  This only affects
       rhosts authentication, and this is one of the reasons why it is
       inherently insecure. */
    for (i = 0; i < 8; i++)
        check_bytes[i] = random_get_byte(&sensitive_data.random_state);

    /* Send our public key.  We include in the packet 64 bits of random
       data that must be matched in the reply in order to prevent IP spoofing. */
    packet_start(SSH_SMSG_PUBLIC_KEY);
    for (i = 0; i < 8; i++)
        packet_put_char(check_bytes[i]);

    /* Store our public server RSA key. */
    packet_put_int(public_key.bits);
    packet_put_mp_int(&public_key.e);
    packet_put_mp_int(&public_key.n);

    /* Store our public host RSA key. */
    packet_put_int(sensitive_data.host_key.bits);
    packet_put_mp_int(&sensitive_data.host_key.e);
    packet_put_mp_int(&sensitive_data.host_key.n);

    /* Put protocol flags. */
    packet_put_int(SSH_PROTOFLAG_HOST_IN_FWD_OPEN);

    /* Declare which ciphers we support. */
    packet_put_int(cipher_mask());

    /* Declare supported authentication types. */
    auth_mask = 0;
    if (options.rhosts_authentication)
        auth_mask |= 1 << SSH_AUTH_RHOSTS;
    if (options.rhosts_rsa_authentication)
        auth_mask |= 1 << SSH_AUTH_RHOSTS_RSA;
    if (options.rsa_authentication)
        auth_mask |= 1 << SSH_AUTH_RSA;
    if (options.password_authentication)
        auth_mask |= 1 << SSH_AUTH_PASSWORD;
    packet_put_int(auth_mask);

    /* Send the packet and wait for it to be sent. */
    packet_send();
    packet_write_wait();

    debug("Sent %d bit public key and %d bit host key.", public_key.bits, sensitive_data.host_key.bits);

    /* Read clients reply (cipher type and session key). */
    packet_read_expect(SSH_CMSG_SESSION_KEY);

    /* Get cipher type. */
    cipher_type = packet_get_char();

    /* Get check bytes from the packet.  These must match those we sent earlier
       with the public key packet. */
    for (i = 0; i < 8; i++)
        if (check_bytes[i] != packet_get_char())
            packet_disconnect("IP Spoofing check bytes do not match.");

    debug("Encryption type: %.200s", cipher_name(cipher_type));

    /* Get the encrypted integer. */
    mpz_init(&session_key_int);
    packet_get_mp_int(&session_key_int);

    /* Get protocol flags. */
    protocol_flags = packet_get_int();
    packet_set_protocol_flags(protocol_flags);

    /* Decrypt it using our private server key and private host key (key with 
       larger modulus first). */
    if (mpz_cmp(&sensitive_data.private_key.n, &sensitive_data.host_key.n) > 0) {
        /* Private key has bigger modulus. */
        assert(sensitive_data.private_key.bits >= sensitive_data.host_key.bits + SSH_KEY_BITS_RESERVED);
        rsa_private_decrypt(&session_key_int, &session_key_int, &sensitive_data.private_key);
        rsa_private_decrypt(&session_key_int, &session_key_int, &sensitive_data.host_key);
    } else {
        /* Host key has bigger modulus (or they are equal). */
        assert(sensitive_data.host_key.bits >= sensitive_data.private_key.bits + SSH_KEY_BITS_RESERVED);
        rsa_private_decrypt(&session_key_int, &session_key_int, &sensitive_data.host_key);
        rsa_private_decrypt(&session_key_int, &session_key_int, &sensitive_data.private_key);
    }

    /* Compute session id for this session. */
    compute_session_id(session_id, check_bytes, sensitive_data.host_key.bits, &sensitive_data.host_key.n, sensitive_data.private_key.bits, &sensitive_data.private_key.n);

    /* Extract session key from the decrypted integer.  The key is in the 
       least significant 256 bits of the integer; the first byte of the 
       key is in the highest bits. */
    mp_linearize_msb_first(session_key, sizeof(session_key), &session_key_int);

    /* Xor the first 16 bytes of the session key with the session id. */
    for (i = 0; i < 16; i++)
        session_key[i] ^= session_id[i];

    /* Destroy the decrypted integer.  It is no longer needed. */
    mpz_clear(&session_key_int);

    /* Set the session key.  From this on all communications will be
       encrypted. */
    packet_set_encryption_key(session_key, SSH_SESSION_KEY_LENGTH, cipher_type, 0);

    /* Destroy our copy of the session key.  It is no longer needed. */
    memset(session_key, 0, sizeof(session_key));

    debug("Received session key; encryption turned on.");

    /* Send an acknowledgement packet.  Note that this packet is sent
       encrypted. */
    packet_start(SSH_SMSG_SUCCESS);
    packet_send();
    packet_write_wait();

    /* Get the name of the user that we wish to log in as. */
    packet_read_expect(SSH_CMSG_USER);

    /* Get the user name. */
    user = packet_get_string(NULL);

    /* Destroy the private and public keys.  They will no longer be needed. */
    rsa_clear_public_key(&public_key);
    rsa_clear_private_key(&sensitive_data.private_key);
    rsa_clear_private_key(&sensitive_data.host_key);

    /* Do the authentication. */
    do_authentication(user, privileged_port, cipher_type);
}