0

there's something strange in my client/server socket using RSA. If i test it on localhost, everithing goes fine, but if i put client on a pc and server on othe pc, something gone wrong.

Client after call connect, call a method for public keys exchange with server. This part of code works fine. After this, client send a request to server:

strcpy(send_pack->op, "help\n");
RSA_public_encrypt(strlen(send_pack->op), send_pack->op, 
        encrypted_send->op, rsa_server, padding);

rw_value = write(server, encrypted_send, sizeof (encrypted_pack));
if (rw_value == -1) {
    stampa_errore(write_error);
    close(server);
    exit(1);
}
if (rw_value == 0) {
    stampa_errore(no_response);
    close(server);
    exit(1);
}
printf("---Help send, waiting for response\n");
set_alarm();
rw_value = read(server, encrypted_receive, sizeof (encrypted_pack));
alarm(0);
if (rw_value == -1) {
    stampa_errore(read_error);
    exit(1);
}
if (rw_value == 0) {
    stampa_errore(no_response);
    close(server);
    exit(1);
}
RSA_private_decrypt(RSA_size(rsa), encrypted_receive->message, 
        receive_pack->message, rsa, padding);
printf("%s\n", receive_pack->message);
return;
}

but when server try to decrypt the receive message on server side, the "help" string doesn't appear. This happen only on the net, on localhost the same code works fine...

EDIT:

typedef struct pack1 {
unsigned char user[encrypted_size];
unsigned char password[encrypted_size];
unsigned char op[encrypted_size];
unsigned char obj[encrypted_size];
unsigned char message[encrypted_size];
int id;
}encrypted_pack;

encrypted_size is 512, and padding used is RSA_PKCS1_PADDING

1
  • Could you please show the encrypted_pack structure? Commented Sep 15, 2012 at 14:54

1 Answer 1

0

You are assuming that you read the whole thing, 512 sizeof (encrypted_pack) bytes, in one go. This doesn't always happen. You can get less than that, so you should read(2) in a loop until you have your complete application message.

Edit 0:

You are trying to decrypt not complete message. TCP is a stream of bytes, and you have to treat it as such. It doesn't know about your application message boundaries. You should be doing something like this:

char buffer[sizeof( encrypted_pack )];
size_t to_read = sizeof( encrypted_pack );
size_t offset = 0;

while ( true ) {
    ssize_t rb = ::read( fd, buffer + offset, to_read - offset );
    if ( rb == -1 ) { /* handle error */ }
    else if ( rb == 0 ) { /* handle EOF */ }
    else {
        offset += rb;
        to_read -= rb;
        if ( to_read == 0 ) break;
    }
}

// handle complete message in buffer

You should do the same - write bytes into the socket in a loop - on the sending side too.

It "works" over loopback because MTU of that virtual interface is usually around 16K vs. 1500 for normal ethernet, so TCP transfers your data in one chunk. But you cannot rely on that.

Sign up to request clarification or add additional context in comments.

3 Comments

even worse, encrypted_pack contains FIVE arrays so sizeof(encrypted_pack) is 2560+sizeof(int) bytes
Thanks @ChrisDodd, I missed that.
i've try to print the RSA_private_decrypt error, and i obtain "padding check failed". I don't know why, because i use the same padding on both side...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.