int tmplen;
int ret = 0;
- if (sizeofdata == 0)
- return 0;
+
if (state->gnutls_internals.valid_connection == VALID_FALSE)
return GNUTLS_E_INVALID_SESSION;
- while (gnutls_getDataBufferSize(state) < sizeofdata) {
-
+ while (gnutls_getDataBufferSize(type, state) < sizeofdata) {
if (read(cd, &gcipher.type, sizeof(ContentType)) !=
sizeof(ContentType)) {
GNUTLS_E_UNEXPECTED_PACKET_LENGTH;
}
break;
+ case GNUTLS_HANDSHAKE:
+ if (type == GNUTLS_HANDSHAKE) {
+ ret = _gnutls_recv_hello( cd, state, tmpdata, sizeofdata, NULL, 0);
+ }
}
}
}
+ /* Insert Application data to buffer */
if (gcipher.type == type == GNUTLS_APPLICATION_DATA) {
ret = gnutls_getDataFromBuffer(state, data, sizeofdata);
gnutls_free(tmpdata);
if (sizeofdata != tmplen)
return GNUTLS_E_RECEIVED_MORE_DATA;
memmove(data, tmpdata, sizeofdata);
+ gnutls_free(tmpdata);
ret = sizeofdata;
}
return ret;
}
+
+int _gnutls_send_change_cipher_spec( int cd, GNUTLS_STATE state) {
+ ChangeCipherSpecType x = GNUTLS_TYPE_CHANGE_CIPHER_SPEC;
+
+ return gnutls_send_int( cd, state, GNUTLS_CHANGE_CIPHER_SPEC, (void*) &x, 1);
+}
\ No newline at end of file
memmove( &data[pos++], &length.pint[0], 1);
memmove( &data[pos++], &length.pint[1], 1);
memmove( &data[pos++], &length.pint[2], 1);
- memmove( &data[pos], i_data, i_datasize);
+ if (i_datasize > 0) memmove( &data[pos], i_data, i_datasize);
ret = gnutls_send_int( cd, state, GNUTLS_HANDSHAKE, data, i_datasize);
return ret;
}
-
+int _gnutls_send_hello_request(int cd, GNUTLS_STATE state) {
+ return _gnutls_send_handshake( cd, state, NULL, 0, GNUTLS_HELLO_REQUEST);
+}
int _gnutls_send_hello(int cd, GNUTLS_STATE state, opaque* SessionID) {
if (state->security_parameters.entity == GNUTLS_CLIENT) {
+ datalen = sizeof(uint32) + session_id_len + 28;
+ data = gnutls_malloc ( datalen);
+
data[pos++] = GNUTLS_VERSION_MAJOR;
data[pos++] = GNUTLS_VERSION_MINOR;
#ifdef WORDS_BIGENDIAN
#endif
memmove( state->security_parameters.client_random, &cur_time, 4);
memmove( &state->security_parameters.client_random[4], rand, 28);
- datalen = sizeof(uint32) + session_id_len + 28;
- data = gnutls_malloc ( datalen);
memmove( &data[pos], &cur_time, sizeof(uint32));
pos += sizeof(uint32);
}
z = _gnutls_supported_compression_methods( &compression_methods);
-#ifdef WORDS_BIGENDIAN
+
memmove( &data[pos++], &z, sizeof(uint8));
-#endif
for (i=0;i<z;i++) {
datalen += 1;
data = gnutls_realloc( data, datalen);
gnutls_free(cipher_suites);
gnutls_free(compression_methods);
- } else {
+ } else { /* SERVER */
+ datalen = sizeof(uint32) + session_id_len + 28;
+ data = gnutls_malloc ( datalen);
+
+ data[pos++] = GNUTLS_VERSION_MAJOR;
+ data[pos++] = GNUTLS_VERSION_MINOR;
+#ifdef WORDS_BIGENDIAN
+ cur_time = time(NULL);
+#else
+ cur_time = byteswap32(time(NULL));
+#endif
+ memmove( state->security_parameters.server_random, &cur_time, 4);
+ memmove( &state->security_parameters.server_random[4], rand, 28);
+
+ memmove( &data[pos], &cur_time, sizeof(uint32));
+ pos += sizeof(uint32);
+ memmove( &data[pos], rand, 28);
+ pos+=28;
+
+ memmove( &data[pos++], &session_id_len, sizeof(uint8));
+ if (session_id_len>0) {
+ memmove( &data[pos], SessionID, session_id_len);
+ }
+ pos+=session_id_len;
+
+ datalen += 2;
+ data = gnutls_realloc( data, datalen);
+ memmove( &data[pos], &state->gnutls_internals.current_cipher_suite.CipherSuite, 2);
+ pos+=2;
+
+ datalen += 1;
+ data = gnutls_realloc( data, datalen);
+ memmove( &data[pos++], &state->gnutls_internals.compression_method, 1);
+
+ ret = _gnutls_send_handshake( cd, state, data, datalen, GNUTLS_CLIENT_HELLO);
+ gnutls_free(data);
+ gcry_free(rand);
+
+ gnutls_free(cipher_suites);
+ gnutls_free(compression_methods);
}
return ret;
return ret;
}
+
+gnutls_handshake(int cd, GNUTLS_STATE state) {
+int ret;
+
+ if (state->security_parameters.entity == GNUTLS_CLIENT) {
+ ret = _gnutls_send_hello( cd, state, NULL);
+ if (ret<0) {
+ fprintf(stderr, "handshake error(%d)\n", ret);
+ return ret;
+ }
+ /* receive the server handshake */
+ ret = gnutls_recv_int( cd, state, GNUTLS_HANDSHAKE, NULL, 0);
+ if (ret<0) {
+ fprintf(stderr, "handshake error(%d)\n", ret);
+ return ret;
+ }
+ ret = _gnutls_send_change_cipher_spec( cd, state);
+
+ } else { /* SERVER */
+
+ ret = gnutls_recv_int( cd, state, GNUTLS_HANDSHAKE, NULL, 0);
+ if (ret<0) {
+ fprintf(stderr, "handshake error(%d)\n", ret);
+ return ret;
+ }
+ ret = _gnutls_send_hello( cd, state, NULL);
+ if (ret<0) {
+ fprintf(stderr, "handshake error(%d)\n", ret);
+ return ret;
+ }
+ ret = _gnutls_send_change_cipher_spec( cd, state);
+ }
+
+ return ret;
+
+}
\ No newline at end of file