📄 gnu_tls_funcs.c
字号:
{
return gnutls_funcs_process_other(mytls_vars, eappacket);
}
}
/**************************************************************************
*
* This function pulls data out of the queue that needs to be sent to the
* authentication server.
*
***************************************************************************/
int tls_funcs_get_packet(struct tls_vars *mytls_vars, int maxsize,
uint8_t **result, uint16_t *res_size)
{
uint8_t *retdata;
uint32_t retlen;
if ((mytls_vars->tlsoutdata == NULL) && (mytls_vars->send_ack == TRUE))
{
retdata = Malloc(1);
if (retdata == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for return "
"buffer!\n");
return XEMALLOC;
}
debug_printf(DEBUG_TLS_CORE, "Sending ACK!\n");
retdata[0] = EAPTLS_ACK;
*res_size = 1;
(*result) = retdata;
return XENONE;
}
if (mytls_vars->tlsoutsize == 0)
{
debug_printf(DEBUG_TLS_CORE, "No data left to send.\n");
(*result) = NULL;
*res_size = 0;
return XENONE;
}
if (mytls_vars->tlsoutsize < maxsize)
{
// Send everything.
(*res_size) = mytls_vars->tlsoutsize + 5;
retdata = Malloc((*res_size));
if (retdata == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for return "
"buffer!\n");
return XEMALLOC;
}
retdata[0] = EAPTLS_LENGTH_INCL; // No additional fragments.
retlen = htonl(mytls_vars->tlsoutsize);
memcpy(&retdata[1], &retlen, sizeof(uint32_t));
memcpy(&retdata[5], mytls_vars->tlsoutdata, mytls_vars->tlsoutsize);
(*result) = retdata;
// There is nothing left, so free the memory we used.
FREE(mytls_vars->tlsoutdata);
mytls_vars->tlsoutsize = 0;
return XENONE;
}
if (mytls_vars->tlsoutptr < mytls_vars->tlsoutsize)
{
maxsize -= 5;
if ((mytls_vars->tlsoutsize - mytls_vars->tlsoutptr) > maxsize)
{
(*res_size) = maxsize;
}
else
{
(*res_size) = (mytls_vars->tlsoutsize - mytls_vars->tlsoutptr);
}
retdata = Malloc((*res_size) + 5);
if (retdata == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory for return "
"fragment!\n");
return XEMALLOC;
}
// Need to send a fragment.
if (mytls_vars->tlsoutptr == 0)
{
debug_printf(DEBUG_TLS_CORE, "Sending response with length & frags."
"\n");
// This is the first packet, so send a length value with it.
retdata[0] = EAPTLS_LENGTH_INCL + EAPTLS_MORE_FRAGS;
retlen = htonl(mytls_vars->tlsoutsize);
memcpy(&retdata[1], &retlen, sizeof(uint32_t));
memcpy(&retdata[5], &mytls_vars->tlsoutdata[mytls_vars->tlsoutptr],
(*res_size));
(*result) = retdata;
mytls_vars->tlsoutptr += (*res_size);
(*res_size) += 5;
}
else
{
if ((mytls_vars->tlsoutsize - mytls_vars->tlsoutptr) > maxsize)
{
debug_printf(DEBUG_TLS_CORE, "More frags comming.\n");
retdata[0] = EAPTLS_MORE_FRAGS;
}
else
{
debug_printf(DEBUG_TLS_CORE, "Fragment done.\n");
retdata[0] = EAPTLS_FINAL;
}
memcpy(&retdata[1], &mytls_vars->tlsoutdata[mytls_vars->tlsoutptr],
(*res_size));
(*result) = retdata;
(*res_size) += 1;
}
if (mytls_vars->tlsoutptr >= mytls_vars->tlsoutsize)
{
// We are done.
FREE(mytls_vars->tlsoutdata);
mytls_vars->tlsoutptr = 0;
mytls_vars->tlsoutsize = 0;
}
return XENONE;
}
debug_printf(DEBUG_NORMAL, "No data to send?!\n");
return XEGENERROR;
}
/************************************************************************
*
* Request that GNU-TLS encrypt some amount of data. This call will result
* in a call to the push callback function which should queue the encrypted
* data, and return it on the next request.
*
************************************************************************/
int tls_funcs_encrypt(struct tls_vars *mytls_vars, uint8_t *tosend,
uint16_t tosend_size)
{
debug_printf(DEBUG_TLS_CORE, "Encrypting :\n");
debug_hex_dump(DEBUG_TLS_CORE, tosend, tosend_size);
if (gnutls_record_send(mytls_vars->session, tosend, tosend_size) != tosend_size)
{
debug_printf(DEBUG_NORMAL, "More to send? \n");
return XEGENERROR;
}
return XENONE;
}
/************************************************************************
*
* Decrypt data that we got from the authentication server. This should
* result in a call to the push callback function, which should queue the
* encrypted data, and return it on the next request.
*
************************************************************************/
int tls_funcs_decrypt(struct tls_vars *mytls_vars, uint8_t *tosend,
uint16_t *tosend_size)
{
int retsiz;
if (mytls_vars->tlsindata == NULL)
{
debug_printf(DEBUG_NORMAL, "The decrypt buffer is currently empty. "
"Please put something in it using the tls_funcs_buffer"
"() call, and try again.\n");
return XEGENERROR;
}
retsiz = gnutls_record_recv(mytls_vars->session, tosend,
(size_t)tosend_size);
*tosend_size = retsiz;
if (retsiz < 0)
{
debug_printf(DEBUG_NORMAL, "Error writing data.\n");
return XEGENERROR;
}
debug_printf(DEBUG_TLS_CORE, "Decrypted dump (%d) :\n", retsiz);
debug_hex_dump(DEBUG_TLS_CORE, tosend, retsiz);
return XENONE;
}
/************************************************************************
*
* Determine if our decrypt buffer is full. If it is, then return the
* amount of data that is currently stored in our buffer,
* if not, return 0. If the buffer appears to be over-full, then
* display a warning, and continue anyway.
*
************************************************************************/
int tls_funcs_decrypt_ready(struct tls_vars *mytls_vars)
{
if (!xsup_assert((mytls_vars != NULL), "mytls_vars != NULL", FALSE))
return -1;
// The buffer is full.
if (mytls_vars->tlsinsize == mytls_vars->tlsinptr)
{
mytls_vars->tlsinptr = 0;
return mytls_vars->tlsinsize;
}
// The buffer is over full.
if (mytls_vars->tlsinptr > mytls_vars->tlsinsize)
{
if (config_get_friendly_warnings() == TRUE)
{
debug_printf(DEBUG_NORMAL, "Your decryption buffer has overflowed. "
"It is likely that decryption will fail, however we "
"will attempt to proceed anyway.\n");
}
mytls_vars->tlsinsize = mytls_vars->tlsinptr;
mytls_vars->tlsinptr = 0;
return mytls_vars->tlsinsize;
}
// Otherwise, we aren't ready yet.
return 0;
}
/************************************************************************
*
* Buffer input data until it is ready to be decrypted. If the variable
* totalsize is 0, then we will not update the tlsinsize value. (This is
* useful for adding fragments that don't contain a length field.)
*
************************************************************************/
int tls_funcs_buffer(struct tls_vars *mytls_vars, uint8_t *newfrag,
uint16_t fragsize)
{
uint32_t value32;
uint8_t *p;
if (!xsup_assert((mytls_vars != NULL), "mytls_vars != NULL", FALSE))
return XEGENERROR;
if (!xsup_assert((newfrag != NULL), "newfrag != NULL", FALSE))
return XEGENERROR;
p = newfrag;
if ((newfrag[0] & EAPTLS_LENGTH_INCL) == EAPTLS_LENGTH_INCL)
{
// We have length data, which means this should be the first piece
// of a fragment. So, verify that there isn't anything already
// buffered.
if (mytls_vars->tlsindata != NULL)
{
if (config_get_friendly_warnings() == TRUE)
{
debug_printf(DEBUG_NORMAL, "This appears to be the first piece "
"of a data fragment. However, there is already "
"data in the fragment buffer. It "
"is likely that your authentication will fail!\n");
}
}
p++; // Skip to the bytes that contain the value.
memcpy(&value32, p, 4);
value32 = ntohl(value32);
p+=3;
mytls_vars->tlsinsize = value32;
fragsize -= 4; // Skip the length value.
}
p++; // Skip the ID bytes.
fragsize--;
debug_printf(DEBUG_TLS_CORE, "Total data size should be %d. We currently"
" have %d byte(s) of data, and will be adding %d more.\n",
mytls_vars->tlsinsize, mytls_vars->tlsinptr, fragsize);
mytls_vars->tlsindata = realloc(mytls_vars->tlsindata,
mytls_vars->tlsinptr + fragsize);
if (mytls_vars->tlsindata == NULL)
{
debug_printf(DEBUG_NORMAL, "Couldn't allocate memory to buffer data.\n");
return XEMALLOC;
}
memcpy(&mytls_vars->tlsindata[mytls_vars->tlsinptr], p, fragsize);
mytls_vars->tlsinptr += fragsize;
if (((newfrag[0] & EAPTLS_MORE_FRAGS) != EAPTLS_MORE_FRAGS) &&
(mytls_vars->tlsinptr < mytls_vars->tlsinsize))
{
if (config_get_friendly_warnings() == TRUE)
{
debug_printf(DEBUG_NORMAL, "The server indicated that there are no "
"fragments remaining. However, we only have %d of %d "
"byte(s). It is likely your authentication will fail."
"\n", mytls_vars->tlsinptr, mytls_vars->tlsinsize);
}
}
if (((newfrag[0] & EAPTLS_MORE_FRAGS) != EAPTLS_MORE_FRAGS) &&
(mytls_vars->tlsinptr > mytls_vars->tlsinsize))
{
mytls_vars->tlsinsize += mytls_vars->tlsinptr;
}
return XENONE;
}
/************************************************************************
*
* Generate our TLS keyblock to use as keying material, or an implicit
* challenge for TTLS.
*
************************************************************************/
uint8_t *tls_funcs_gen_keyblock(struct tls_vars *mytls_vars,
uint8_t *sesskey, uint16_t sesskeylen)
{
uint8_t *retblock = NULL;
int err;
debug_printf(DEBUG_TLS_CORE, "Generating key block!\n");
if (!xsup_assert((mytls_vars != NULL), "mytls_vars != NULL", FALSE))
return NULL;
if (sesskey == NULL)
{
debug_printf(DEBUG_NORMAL, "No keying material is available! It is "
"unlikely that your session will work properly.\n");
return NULL;
}
debug_printf(DEBUG_TLS_CORE, "Using session key constant of : %s\n",
sesskey);
retblock = Malloc(TLS_SESSION_KEY_SIZE);
if (!retblock)
{
return NULL;
}
err = gnutls_prf(mytls_vars->session, sesskeylen, sesskey, FALSE, 0, NULL,
TLS_SESSION_KEY_SIZE, retblock);
if (err != 0)
{
debug_printf(DEBUG_NORMAL, "Error generating key block. Error was (%d)"
" : %s\n", err, gnutls_strerror(err));
return NULL;
}
return retblock;
}
/************************************************************************
*
* Clean up after ourselves.
*
************************************************************************/
void tls_funcs_deinit(struct tls_vars *mytls_vars)
{
gnutls_certificate_free_credentials(mytls_vars->creds);
if (mytls_vars->session != NULL)
gnutls_deinit(mytls_vars->session);
gnutls_global_deinit();
debug_printf(DEBUG_TLS_CORE, "(TLS Engine : GNU) TLS Deinit complete.\n");
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -