pike.git / lib / modules / SSL.pmod / Connection.pike

version» Context lines:

pike.git/lib/modules/SSL.pmod/Connection.pike:194:    mixed err = catch {    verification_ok = session->cipher_spec->verify(    session, signature_context, Buffer(signed), input);    };   #ifdef SSL3_DEBUG    if (err) {    master()->handle_error(err);    }   #endif    err = UNDEFINED; // Get rid of warning. -  if (!verification_ok) -  { -  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, -  "Validation of CertificateVerify failed.\n")); -  return -1; -  } -  +  COND_FATAL(!verification_ok, ALERT_unexpected_message, +  "Validation of CertificateVerify failed.\n");    return 0;   }      Packet heartbeat_packet(Buffer s)   {    return Packet(version, PACKET_heartbeat, s->read());   }      protected Crypto.AES heartbeat_encode;   protected Crypto.AES heartbeat_decode;
pike.git/lib/modules/SSL.pmod/Connection.pike:700:    data[..session->max_packet_size-1]));;    sent += size;    return size;   }      protected int handle_alert(string s)   {    // sizeof(s)==2, checked at caller.    int level = s[0];    int description = s[1]; -  if (! (ALERT_levels[level] && ALERT_descriptions[description])) -  { -  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, -  "invalid alert\n")); -  return -1; -  } +  COND_FATAL(!(ALERT_levels[level] && ALERT_descriptions[description]), +  ALERT_unexpected_message, "Invalid alert\n"); +     if (level == ALERT_fatal)    {    SSL3_DEBUG_MSG("SSL.Connection: Fatal alert %O\n",    ALERT_descriptions[description]);    state = [int(0..0)|ConnectionState](state | CONNECTION_peer_fatal |    CONNECTION_peer_closed);    // SSL3 5.4:    // Alert messages with a level of fatal result in the immediate    // termination of the connection. In this case, other    // connections corresponding to the session may continue, but
pike.git/lib/modules/SSL.pmod/Connection.pike:739:    if (description == ALERT_no_certificate)    {    SSL3_DEBUG_MSG("SSL.Connection: %O\n", ALERT_descriptions[description]);       if ( (certificate_state == CERT_requested) &&    (context->auth_level == AUTHLEVEL_ask) )    {    certificate_state = CERT_no_certificate;    return 0;    } else { -  send_packet(alert(ALERT_fatal, -  ((certificate_state == CERT_requested) +  COND_FATAL(1, ((certificate_state == CERT_requested)    ? ALERT_handshake_failure    : ALERT_unexpected_message), -  "Certificate required.\n")); -  return -1; +  "Certificate required.\n");    }    }   #ifdef SSL3_DEBUG    else    werror("SSL.Connection: Received warning alert %O\n",    ALERT_descriptions[description]);   #endif    return 0;   }      int handle_change_cipher(int c)   { -  if (!expect_change_cipher || (c != 1)) -  { -  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, -  "Unexpected change cipher!\n")); -  return -1; -  } -  else -  { +  COND_FATAL(!expect_change_cipher || (c != 1), +  ALERT_unexpected_message, "Unexpected change cipher!\n"); +     if (sizeof(pending_read_state)) {    SSL3_DEBUG_MSG("%O: Changing read state.\n", this);    current_read_state = pending_read_state[0];    pending_read_state = pending_read_state[1..];    } else {    error("No new read state pending!\n");    }    expect_change_cipher--;    return 0;   } - } +       void send_heartbeat()   {    if ((state != CONNECTION_ready) ||    (session->heartbeat_mode != HEARTBEAT_MODE_peer_allowed_to_send)) {    // We're not allowed to send heartbeats.    return;    }       Buffer hb_msg = Buffer();
pike.git/lib/modules/SSL.pmod/Connection.pike:950:    else    {    SSL3_DEBUG_MSG("SSL.Connection: received packet of type %d\n",    packet->content_type);    switch (packet->content_type)    {    case PACKET_alert:    {    SSL3_DEBUG_MSG("SSL.Connection: ALERT\n");    -  if( !sizeof(packet->fragment) ) -  { -  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, -  "Zero length Alert fragments not allowed.\n")); -  return -1; -  } +  COND_FATAL(!sizeof(packet->fragment), ALERT_unexpected_message, +  "Zero length Alert fragments not allowed.\n");       int i;    int err = 0;    alert_buffer += packet->fragment;    for (i = 0;    !err && ((sizeof(alert_buffer) - i) >= 2);    i+= 2)    err = handle_alert(alert_buffer[i..i+1]);       alert_buffer = alert_buffer[i..];
pike.git/lib/modules/SSL.pmod/Connection.pike:978:    // If we get a close then we return the data we got so far.    return res;    else    return err;    break;    }    case PACKET_change_cipher_spec:    {    SSL3_DEBUG_MSG("SSL.Connection: CHANGE_CIPHER_SPEC\n");    -  if( !sizeof(packet->fragment) ) -  { -  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, -  "Zero length ChangeCipherSpec fragments not allowed.\n")); -  return -1; -  } -  if (version >= PROTOCOL_TLS_1_3) { -  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, -  "ChangeCipherSpec not allowed in TLS 1.3 and later.\n")); -  return -1; -  } +  COND_FATAL(!sizeof(packet->fragment), ALERT_unexpected_message, +  "Zero length ChangeCipherSpec fragments not allowed.\n"); +  +  COND_FATAL(version >= PROTOCOL_TLS_1_3, ALERT_unexpected_message, +  "ChangeCipherSpec not allowed in TLS 1.3 and later.\n"); +     foreach(packet->fragment;; int c)    {    int err = handle_change_cipher(c);    SSL3_DEBUG_MSG("tried change_cipher: %d\n", err);    if (err)    return err;    }    break;    }    case PACKET_handshake:    {    SSL3_DEBUG_MSG("SSL.Connection: HANDSHAKE\n");    -  if( !sizeof(packet->fragment) ) -  { -  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, -  "Zero length Handshake fragments not allowed.\n")); -  return -1; -  } -  if (!(state & CONNECTION_handshaking) && -  !secure_renegotiation) { +  COND_FATAL(!sizeof(packet->fragment), ALERT_unexpected_message, +  "Zero length Handshake fragments not allowed.\n"); +     // Don't allow renegotiation in unsecure mode, to address    // http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2009-3555.    // For details see: http://www.g-sec.lu/practicaltls.pdf and    // RFC 5746. -  send_packet(alert(ALERT_warning, ALERT_no_renegotiation, -  "Renegotiation not supported in unsecure mode.\n")); -  return -1; -  } -  if (expect_change_cipher && (version < PROTOCOL_TLS_1_3)) -  { +  COND_FATAL(!(state & CONNECTION_handshaking) && +  !secure_renegotiation, ALERT_no_renegotiation, +  "Renegotiation not supported in unsecure mode.\n"); +     /* No change_cipher message was received */ -  // FIXME: There's a bug somewhere since expect_change_cipher often -  // remains set after the handshake is completed. The effect is that -  // renegotiation doesn't work all the time. +  // FIXME: There's a bug somewhere since expect_change_cipher +  // often remains set after the handshake is completed. The +  // effect is that renegotiation doesn't work all the time.    //    // A side effect is that we are partly invulnerable to the -  // renegotiation vulnerability mentioned above. It is however not -  // safe to assume that, since there might be routes past this, -  // maybe through the use of a version 2 hello message below. -  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, -  "Expected change cipher.\n")); -  return -1; -  } +  // renegotiation vulnerability mentioned above. It is however +  // not safe to assume that, since there might be routes past +  // this, maybe through the use of a version 2 hello message +  // below. +  COND_FATAL(expect_change_cipher && (version < PROTOCOL_TLS_1_3), +  ALERT_unexpected_message, "Expected change cipher.\n"); +     int err, len;    handshake_buffer += packet->fragment;       while (sizeof(handshake_buffer) >= 4)    {    sscanf(handshake_buffer, "%*c%3c", len);    if (sizeof(handshake_buffer) < (len + 4))    break;    mixed exception = catch {    err = handle_handshake(handshake_buffer[0],    handshake_buffer[4..len + 3],    handshake_buffer[.. len + 3]);    };    if( exception )    {    if( objectp(exception) && ([object]exception)->buffer_error )    {    Error.Generic e = [object(Error.Generic)]exception; -  send_packet(alert(ALERT_fatal, ALERT_decode_error, -  e->message())); -  return -1; +  COND_FATAL(1, ALERT_decode_error, e->message());    }    throw(exception);    }    handshake_buffer = handshake_buffer[len + 4..];    if (err < 0)    return err;    if (err > 0) {    state &= ~CONNECTION_handshaking;    }    }    break;    }    case PACKET_application_data:    SSL3_DEBUG_MSG("SSL.Connection: APPLICATION_DATA\n");    -  if (state & CONNECTION_handshaking) -  { -  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, -  "Handshake not finished yet!\n")); -  return -1; -  } +  COND_FATAL(state & CONNECTION_handshaking, +  ALERT_unexpected_message, +  "Handshake not finished yet!\n"); +     res += packet->fragment;    break;    case PACKET_heartbeat:    {    // RFC 6520.    SSL3_DEBUG_MSG("SSL.Connection: Heartbeat.\n");    if (state != CONNECTION_ready) {    // RFC 6520 3:    // The receiving peer SHOULD discard the message silently,    // if it arrives during the handshake.
pike.git/lib/modules/SSL.pmod/Connection.pike:1106:    }       mixed exception = catch {    handle_heartbeat(packet->fragment);    };    if( exception )    {    if( objectp(exception) && ([object]exception)->buffer_error )    {    Error.Generic e = [object(Error.Generic)]exception; -  send_packet(alert(ALERT_fatal, ALERT_decode_error, -  e->message())); -  return -1; +  COND_FATAL(1, ALERT_decode_error, e->message());    }    throw(exception);    }       }    break;    default: -  if (state & CONNECTION_handshaking) -  { -  send_packet(alert(ALERT_fatal, ALERT_unexpected_message, -  "Unexpected message during handshake!\n")); -  return -1; -  } +  COND_FATAL(state & CONNECTION_handshaking, +  ALERT_unexpected_message, +  "Unexpected message during handshake!\n"); +     // RFC 4346 6:    // If a TLS implementation receives a record type it does not    // understand, it SHOULD just ignore it.    SSL3_DEBUG_MSG("SSL.Connection: Ignoring packet of type %s\n",    fmt_constant(packet->content_type, "PACKET"));    break;    }    }    }    if (sizeof(res)) return res;    if (state & CONNECTION_peer_closed) return 1;    return "";   }