Exemplo n.º 1
0
void TransportLayerDtls::Handshake() {
  // Clear the retransmit timer
  timer_->Cancel();

  SECStatus rv = SSL_ForceHandshake(ssl_fd_);

  if (rv == SECSuccess) {
    MOZ_MTLOG(ML_NOTICE,
              LAYER_INFO << "****** SSL handshake completed ******");
    if (!cert_ok_) {
      MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Certificate check never occurred");
      TL_SET_STATE(TS_ERROR);
      return;
    }
    if (!CheckAlpn()) {
      // Despite connecting, the connection doesn't have a valid ALPN label.
      // Forcibly close the connection so that the peer isn't left hanging
      // (assuming the close_notify isn't dropped).
      ssl_fd_ = nullptr;
      TL_SET_STATE(TS_ERROR);
      return;
    }

    TL_SET_STATE(TS_OPEN);
  } else {
    int32_t err = PR_GetError();
    switch(err) {
      case SSL_ERROR_RX_MALFORMED_HANDSHAKE:
        MOZ_MTLOG(ML_ERROR, LAYER_INFO << "Malformed DTLS message; ignoring");
        // If this were TLS (and not DTLS), this would be fatal, but
        // here we're required to ignore bad messages, so fall through
        MOZ_FALLTHROUGH;
      case PR_WOULD_BLOCK_ERROR:
        MOZ_MTLOG(ML_NOTICE, LAYER_INFO << "Handshake would have blocked");
        PRIntervalTime timeout;
        rv = DTLS_GetHandshakeTimeout(ssl_fd_, &timeout);
        if (rv == SECSuccess) {
          uint32_t timeout_ms = PR_IntervalToMilliseconds(timeout);

          MOZ_MTLOG(ML_DEBUG,
                    LAYER_INFO << "Setting DTLS timeout to " << timeout_ms);
          timer_->SetTarget(target_);
          timer_->InitWithFuncCallback(TimerCallback,
                                       this, timeout_ms,
                                       nsITimer::TYPE_ONE_SHOT);
        }
        break;
      default:
        MOZ_MTLOG(ML_ERROR, LAYER_INFO << "SSL handshake error "<< err);
        TL_SET_STATE(TS_ERROR);
        break;
    }
  }
}
void TransportLayerDtls::Handshake() {
  SetState(TS_CONNECTING);

  // Clear the retransmit timer
  timer_->Cancel();

  SECStatus rv = SSL_ForceHandshake(ssl_fd_);

  if (rv == SECSuccess) {
    MOZ_MTLOG(PR_LOG_NOTICE, LAYER_INFO << "****** SSL handshake completed ******");
    if (!cert_ok_) {
      MOZ_MTLOG(PR_LOG_ERROR, LAYER_INFO << "Certificate check never occurred");
      SetState(TS_ERROR);
      return;
    }
    SetState(TS_OPEN);
  } else {
    int32_t err = PR_GetError();
    switch(err) {
      case SSL_ERROR_RX_MALFORMED_HANDSHAKE:
        if (mode_ != DGRAM) {
          MOZ_MTLOG(PR_LOG_ERROR, LAYER_INFO << "Malformed TLS message");
          SetState(TS_ERROR);
        } else {
          MOZ_MTLOG(PR_LOG_ERROR, LAYER_INFO << "Malformed DTLS message; ignoring");
        }
        // Fall through
      case PR_WOULD_BLOCK_ERROR:
        MOZ_MTLOG(PR_LOG_NOTICE, LAYER_INFO << "Would have blocked");
        if (mode_ == DGRAM) {
          PRIntervalTime timeout;
          rv = DTLS_GetHandshakeTimeout(ssl_fd_, &timeout);
          if (rv == SECSuccess) {
            uint32_t timeout_ms = PR_IntervalToMilliseconds(timeout);

            MOZ_MTLOG(PR_LOG_DEBUG, LAYER_INFO << "Setting DTLS timeout to " <<
                 timeout_ms);
            timer_->SetTarget(target_);
            timer_->InitWithFuncCallback(TimerCallback,
                                         this, timeout_ms,
                                         nsITimer::TYPE_ONE_SHOT);
          }
        }
        break;
      default:
        MOZ_MTLOG(PR_LOG_ERROR, LAYER_INFO << "SSL handshake error "<< err);
        SetState(TS_ERROR);
        break;
    }
  }
}