?? tls_funcs.c
字號:
return XEBADPACKETSIZE; } if (chunksize == 0) { chunksize = 1398; } if (thisint->eap_data == NULL) { debug_printf(DEBUG_NORMAL, "(TLS) eap_data has been destroyed, or not allocated!\n"); return XEMALLOC; } mytls_vars = (struct tls_vars *)thisint->eap_data; if (mytls_vars->tlsoutsize==0) { if (indata != NULL) { BIO_reset(mytls_vars->ssl_in); BIO_write(mytls_vars->ssl_in, indata, insize); } BIO_reset(mytls_vars->ssl_out); if (mytls_vars->ssl == NULL) { debug_printf(DEBUG_NORMAL, "SSL context is NULL!!!!\n"); return XETLSNOCTX; } rc = SSL_connect(mytls_vars->ssl); BIO_get_mem_ptr(mytls_vars->ssl_out, &retData); mytls_vars->tlsoutdata = retData->data; mytls_vars->tlsoutsize = retData->length; } if (mytls_vars->tlsoutsize == 0) { return XTLSNEEDDATA; } if ((mytls_vars->tlsoutsize - mytls_vars->tlsoutptr)>chunksize) { // Return a maximum sized chunk. if (mytls_vars->tlsoutptr == 0) // This is our first chunk, include { // the length. outdata[0] = EAPTLS_LENGTH_MORE; // We will have a length value, and more. length = htonl(mytls_vars->tlsoutsize); memcpy(&outdata[1], &length, 4); retVal = &outdata[5]; *outsize = chunksize+5; // To account for length. } else { outdata[0] = EAPTLS_MORE_FRAGS; retVal = &outdata[1]; *outsize = chunksize+1; } memcpy(retVal, &mytls_vars->tlsoutdata[mytls_vars->tlsoutptr], chunksize); mytls_vars->tlsoutptr += chunksize; } else { // Return what is left. if (mytls_vars->tlsoutptr == 0) // This is our first chunk, include { // the length. outdata[0] = EAPTLS_LENGTH_INCL; // We will have a length value. length = htonl(mytls_vars->tlsoutsize); memcpy(&outdata[1], &length, 4); retVal = &outdata[5]; *outsize = (mytls_vars->tlsoutsize - mytls_vars->tlsoutptr)+5; } else { outdata[0] = EAPTLS_FINAL; retVal = &outdata[1]; *outsize = (mytls_vars->tlsoutsize - mytls_vars->tlsoutptr)+1; } memcpy(retVal, &mytls_vars->tlsoutdata[mytls_vars->tlsoutptr], *outsize); // Clean out the data chunk. mytls_vars->tlsoutptr = 0; mytls_vars->tlsoutsize = 0; } return XENONE;}int tls_funcs_decode_packet(struct generic_eap_data *thisint, char *inframe, int insize, char *outframe, int *outsize, phase2_call dophase2, int chunksize){ unsigned long err; int rtnVal, tlsindex; char *tlsptr, *cnname = NULL, *temp; struct tls_vars *mytls_vars; if ((!thisint) || (!inframe) || (!outframe) || (!outsize)) { debug_printf(DEBUG_NORMAL, "Invalid data passed in to tls_funcs_decode_packet()!\n"); return XEMALLOC; } if (insize > 1520) { debug_printf(DEBUG_NORMAL, "Packet size too big in tls_funcs_decode_packet()! Ignoring!\n"); return XEBADPACKETSIZE; } // First, make sure we don't have any errors. err = ERR_get_error(); if (err != 0) { debug_printf(DEBUG_NORMAL, "OpenSSL Error -- %s\n", ERR_error_string(err, NULL)); } mytls_vars = (struct tls_vars *)thisint->eap_data; if (mytls_vars == NULL) { debug_printf(DEBUG_NORMAL, "EAP data is invalid in tls_funcs_decode_packet()!\n"); return XEMALLOC; } *outsize = 0; // Set up a pointer to the start of the data. tlsindex = 1; tlsptr = &inframe[tlsindex]; rtnVal = XENONE; // The first byte should tell us what to do. switch ((uint8_t)inframe[0]) { case EAPTLS_START: tls_funcs_start(mytls_vars); if (mytls_vars->ssl == NULL) { debug_printf(DEBUG_NORMAL, "The SSL handle is invalid in tls_funcs_decode_packet()!\n"); return XETLSNOCTX; } rtnVal = tls_funcs_parse(thisint, NULL, 0, outframe, outsize, chunksize); if (rtnVal < 0) { debug_printf(DEBUG_NORMAL, "Failed to generate TLS data!\n"); } break; case EAPTLS_LENGTH_MORE: case EAPTLS_LENGTH_INCL: // Skip the four octets that contain the length. OpenSSL knows when // we are done. tlsptr+=4; tlsindex+=4; // DON'T BREAK HERE! We want to do the next case! case EAPTLS_MORE_FRAGS: case EAPTLS_ACK: if ((SSL_get_state(mytls_vars->ssl) == 0x0003) && (dophase2 != NULL)) { // Handle the phase 2 piece. We pass in the encrypted piece of // the packet, and let phase 2 deal with it! // But, before we do anything, verify the CN. if (mytls_vars->cncheck != NULL) { cnname = get_cert_common_name(mytls_vars->ssl); debug_printf(DEBUG_AUTHTYPES, "Certificate CN : %s\n",cnname); // mytls_vars->cncheck == NULL, do nothing. debug_printf(DEBUG_AUTHTYPES, "Doing a CN Check!\n"); if (mytls_vars->cnexact == 1) { debug_printf(DEBUG_AUTHTYPES, "Looking for an exact match!\n"); if (cnname != NULL) { if (strcmp(mytls_vars->cncheck, cnname) != 0) { debug_printf(DEBUG_AUTHTYPES, "Certificate CN didn't match!\n"); outframe = NULL; outsize = 0; free(cnname); return XEBADCN; } else { debug_printf(DEBUG_AUTHTYPES, "Certificate CN matched!\n"); } } } else { debug_printf(DEBUG_AUTHTYPES, "Looking for a relative match!\n"); temp = mytls_vars->cncheck; if (cnname != NULL) { if (strstr(cnname, temp) == NULL) { debug_printf(DEBUG_AUTHTYPES, "Certificate CN didn't match!\n"); outframe = NULL; outsize = 0; free(cnname); return XEBADCN; } else { debug_printf(DEBUG_AUTHTYPES, "Certificate CN matched!\n"); } } } } if (cnname != NULL) { free(cnname); cnname = NULL; } // We are in phase 2, so indicate it. mytls_vars->phase = 2; if ((mytls_vars->resuming != 1) || (mytls_vars->quickResponse != TRUE)) { (*dophase2)(thisint, tlsptr, (insize-tlsindex), outframe, outsize); } else { if (*outsize == 0) { debug_printf(DEBUG_AUTHTYPES, "Resumed session, ACKing ACK!\n"); tls_funcs_build_ack(outframe, outsize); rtnVal = XENONE; } } } else { rtnVal = tls_funcs_parse(thisint, tlsptr, (insize-tlsindex), outframe, outsize, chunksize); if (rtnVal < 0) { debug_printf(DEBUG_NORMAL, "Couldn't parse TLS data.\n"); } if ((SSL_get_state(mytls_vars->ssl) == 0x0003) && (dophase2 != NULL) && (mytls_vars->quickResponse == TRUE)) { if (mytls_vars->cncheck != NULL) { // But, before we do anything, verify the CN. cnname = get_cert_common_name(mytls_vars->ssl); debug_printf(DEBUG_AUTHTYPES, "Certificate CN : %s\n",cnname); } if (cnname != NULL) { // mytls_vars->cncheck == NULL, do nothing. if (mytls_vars->cncheck != NULL) { debug_printf(DEBUG_AUTHTYPES, "Doing a CN Check!\n"); if (mytls_vars->cnexact == 1) { debug_printf(DEBUG_AUTHTYPES, "Looking for an exact match!\n"); if (strcmp(mytls_vars->cncheck, cnname) != 0) { debug_printf(DEBUG_AUTHTYPES, "Certificate CN didn't match!\n"); outframe = NULL; outsize = 0; return XEBADCN; } else { debug_printf(DEBUG_AUTHTYPES, "Certificate CN matched!\n"); } } else { debug_printf(DEBUG_AUTHTYPES, "Looking for a relative match!\n"); temp = mytls_vars->cncheck; if (strstr(cnname, temp) == NULL) { debug_printf(DEBUG_AUTHTYPES, "Certificate CN didn't match!\n"); outframe = NULL; outsize = 0; return XEBADCN; } else { debug_printf(DEBUG_AUTHTYPES, "Certificate CN matched!\n"); } } } } if (cnname != NULL) { free(cnname); cnname = NULL; } // We made it to phase 2. So, indicate it. mytls_vars->phase = 2; if ((mytls_vars->resuming != 1) || (mytls_vars->quickResponse != TRUE)) { (*dophase2)(thisint, tlsptr, (insize-tlsindex), outframe, outsize); } else { if (*outsize == 0) { debug_printf(DEBUG_AUTHTYPES, "Resumed session, ACKing ACK!\n"); tls_funcs_build_ack(outframe, outsize); rtnVal = XENONE; } } } else if (rtnVal == XTLSNEEDDATA) { tls_funcs_build_ack(outframe, outsize); rtnVal = XENONE; } } break; default: debug_printf(DEBUG_NORMAL, "Invalid TLS flags! (%02X)\n",(uint8_t)inframe[0]); rtnVal = XETLSBADFLAGS; } return rtnVal;}char *tls_funcs_gen_keyblock(struct generic_eap_data *thisint){ struct tls_vars *mydata; if (!thisint) { debug_printf(DEBUG_NORMAL, "EAP data passed in to tls_funcs_gen_keyblock() is NULL!\n"); return NULL; } mydata = (struct tls_vars *)thisint->eap_data; if (mydata == NULL) return NULL; return tls_crypt_gen_keyblock(thisint, mydata->sessionkeyconst, mydata->sessionkeylen);}int tls_funcs_build_ack(char *outframe, int *outsize){ debug_printf(DEBUG_EVERYTHING, "Sending TLS ACK!\n"); outframe[0] = 0x00; *outsize = 1; return XENONE;}static void ssl_info_callback(SSL *ssl, int w, int r){ if (!ssl) { debug_printf(DEBUG_NORMAL, "Invalid context in ssl_info_callback!\n"); return; } debug_printf(DEBUG_AUTHTYPES, " --- SSL : %s\n", SSL_state_string_long(ssl)); if (w & SSL_CB_ALERT) debug_printf(DEBUG_AUTHTYPES, " --- ALERT : %s\n", SSL_alert_desc_string_long(r));}static int return_password(char *buf, int size, int rwflag, void *userdata){ strncpy(buf, (char *)(userdata), size); buf[size-1] = '\0'; return(strlen(buf));}int tls_funcs_load_root_certs(struct generic_eap_data *thisint, char *root_cert, char *root_dir, char *crl_dir){ struct tls_vars *mytls_vars;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -