/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <vector>

#if HAVE_CONFIG_H
#include "config.h"
#endif  // HAVE_CONFIG_H

#if HAVE_NSS_SSL_H

#include "webrtc/base/nssstreamadapter.h"

#include "keyhi.h"
#include "nspr.h"
#include "nss.h"
#include "pk11pub.h"
#include "secerr.h"

#ifdef NSS_SSL_RELATIVE_PATH
#include "ssl.h"
#include "sslerr.h"
#include "sslproto.h"
#else
#include "net/third_party/nss/ssl/ssl.h"
#include "net/third_party/nss/ssl/sslerr.h"
#include "net/third_party/nss/ssl/sslproto.h"
#endif

#include "webrtc/base/nssidentity.h"
#include "webrtc/base/safe_conversions.h"
#include "webrtc/base/thread.h"

namespace rtc {

PRDescIdentity NSSStreamAdapter::nspr_layer_identity = PR_INVALID_IO_LAYER;

#define UNIMPLEMENTED \
  PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0); \
  LOG(LS_ERROR) \
  << "Call to unimplemented function "<< __FUNCTION__; ASSERT(false)

#ifdef SRTP_AES128_CM_HMAC_SHA1_80
#define HAVE_DTLS_SRTP
#endif

#ifdef HAVE_DTLS_SRTP
// SRTP cipher suite table
struct SrtpCipherMapEntry {
  const char* external_name;
  PRUint16 cipher_id;
};

// This isn't elegant, but it's better than an external reference
static const SrtpCipherMapEntry kSrtpCipherMap[] = {
  {"AES_CM_128_HMAC_SHA1_80", SRTP_AES128_CM_HMAC_SHA1_80 },
  {"AES_CM_128_HMAC_SHA1_32", SRTP_AES128_CM_HMAC_SHA1_32 },
  {NULL, 0}
};
#endif

// Default cipher used between NSS stream adapters.
// This needs to be updated when the default of the SSL library changes.
static const char kDefaultSslCipher[] = "TLS_RSA_WITH_AES_128_CBC_SHA";


// Implementation of NSPR methods
static PRStatus StreamClose(PRFileDesc *socket) {
  ASSERT(!socket->lower);
  socket->dtor(socket);
  return PR_SUCCESS;
}

static PRInt32 StreamRead(PRFileDesc *socket, void *buf, PRInt32 length) {
  StreamInterface *stream = reinterpret_cast<StreamInterface *>(socket->secret);
  size_t read;
  int error;
  StreamResult result = stream->Read(buf, length, &read, &error);
  if (result == SR_SUCCESS) {
    return checked_cast<PRInt32>(read);
  }

  if (result == SR_EOS) {
    return 0;
  }

  if (result == SR_BLOCK) {
    PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
    return -1;
  }

  PR_SetError(PR_UNKNOWN_ERROR, error);
  return -1;
}

static PRInt32 StreamWrite(PRFileDesc *socket, const void *buf,
                           PRInt32 length) {
  StreamInterface *stream = reinterpret_cast<StreamInterface *>(socket->secret);
  size_t written;
  int error;
  StreamResult result = stream->Write(buf, length, &written, &error);
  if (result == SR_SUCCESS) {
    return checked_cast<PRInt32>(written);
  }

  if (result == SR_BLOCK) {
    LOG(LS_INFO) <<
        "NSSStreamAdapter: write to underlying transport would block";
    PR_SetError(PR_WOULD_BLOCK_ERROR, 0);
    return -1;
  }

  LOG(LS_ERROR) << "Write error";
  PR_SetError(PR_UNKNOWN_ERROR, error);
  return -1;
}

static PRInt32 StreamAvailable(PRFileDesc *socket) {
  UNIMPLEMENTED;
  return -1;
}

PRInt64 StreamAvailable64(PRFileDesc *socket) {
  UNIMPLEMENTED;
  return -1;
}

static PRStatus StreamSync(PRFileDesc *socket) {
  UNIMPLEMENTED;
  return PR_FAILURE;
}

static PROffset32 StreamSeek(PRFileDesc *socket, PROffset32 offset,
                             PRSeekWhence how) {
  UNIMPLEMENTED;
  return -1;
}

static PROffset64 StreamSeek64(PRFileDesc *socket, PROffset64 offset,
                               PRSeekWhence how) {
  UNIMPLEMENTED;
  return -1;
}

static PRStatus StreamFileInfo(PRFileDesc *socket, PRFileInfo *info) {
  UNIMPLEMENTED;
  return PR_FAILURE;
}

static PRStatus StreamFileInfo64(PRFileDesc *socket, PRFileInfo64 *info) {
  UNIMPLEMENTED;
  return PR_FAILURE;
}

static PRInt32 StreamWritev(PRFileDesc *socket, const PRIOVec *iov,
                     PRInt32 iov_size, PRIntervalTime timeout) {
  UNIMPLEMENTED;
  return -1;
}

static PRStatus StreamConnect(PRFileDesc *socket, const PRNetAddr *addr,
                              PRIntervalTime timeout) {
  UNIMPLEMENTED;
  return PR_FAILURE;
}

static PRFileDesc *StreamAccept(PRFileDesc *sd, PRNetAddr *addr,
                                PRIntervalTime timeout) {
  UNIMPLEMENTED;
  return NULL;
}

static PRStatus StreamBind(PRFileDesc *socket, const PRNetAddr *addr) {
  UNIMPLEMENTED;
  return PR_FAILURE;
}

static PRStatus StreamListen(PRFileDesc *socket, PRIntn depth) {
  UNIMPLEMENTED;
  return PR_FAILURE;
}

static PRStatus StreamShutdown(PRFileDesc *socket, PRIntn how) {
  UNIMPLEMENTED;
  return PR_FAILURE;
}

// Note: this is always nonblocking and ignores the timeout.
// TODO(ekr@rtfm.com): In future verify that the socket is
// actually in non-blocking mode.
// This function does not support peek.
static PRInt32 StreamRecv(PRFileDesc *socket, void *buf, PRInt32 amount,
                   PRIntn flags, PRIntervalTime to) {
  ASSERT(flags == 0);

  if (flags != 0) {
    PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
    return -1;
  }

  return StreamRead(socket, buf, amount);
}

// Note: this is always nonblocking and assumes a zero timeout.
// This function does not support peek.
static PRInt32 StreamSend(PRFileDesc *socket, const void *buf,
                          PRInt32 amount, PRIntn flags,
                          PRIntervalTime to) {
  ASSERT(flags == 0);

  return StreamWrite(socket, buf, amount);
}

static PRInt32 StreamRecvfrom(PRFileDesc *socket, void *buf,
                              PRInt32 amount, PRIntn flags,
                              PRNetAddr *addr, PRIntervalTime to) {
  UNIMPLEMENTED;
  return -1;
}

static PRInt32 StreamSendto(PRFileDesc *socket, const void *buf,
                            PRInt32 amount, PRIntn flags,
                            const PRNetAddr *addr, PRIntervalTime to) {
  UNIMPLEMENTED;
  return -1;
}

static PRInt16 StreamPoll(PRFileDesc *socket, PRInt16 in_flags,
                          PRInt16 *out_flags) {
  UNIMPLEMENTED;
  return -1;
}

static PRInt32 StreamAcceptRead(PRFileDesc *sd, PRFileDesc **nd,
                                PRNetAddr **raddr,
                                void *buf, PRInt32 amount, PRIntervalTime t) {
  UNIMPLEMENTED;
  return -1;
}

static PRInt32 StreamTransmitFile(PRFileDesc *sd, PRFileDesc *socket,
                                  const void *headers, PRInt32 hlen,
                                  PRTransmitFileFlags flags, PRIntervalTime t) {
  UNIMPLEMENTED;
  return -1;
}

static PRStatus StreamGetPeerName(PRFileDesc *socket, PRNetAddr *addr) {
  // TODO(ekr@rtfm.com): Modify to return unique names for each channel
  // somehow, as opposed to always the same static address. The current
  // implementation messes up the session cache, which is why it's off
  // elsewhere
  addr->inet.family = PR_AF_INET;
  addr->inet.port = 0;
  addr->inet.ip = 0;

  return PR_SUCCESS;
}

static PRStatus StreamGetSockName(PRFileDesc *socket, PRNetAddr *addr) {
  UNIMPLEMENTED;
  return PR_FAILURE;
}

static PRStatus StreamGetSockOption(PRFileDesc *socket, PRSocketOptionData *opt) {
  switch (opt->option) {
    case PR_SockOpt_Nonblocking:
      opt->value.non_blocking = PR_TRUE;
      return PR_SUCCESS;
    default:
      UNIMPLEMENTED;
      break;
  }

  return PR_FAILURE;
}

// Imitate setting socket options. These are mostly noops.
static PRStatus StreamSetSockOption(PRFileDesc *socket,
                                    const PRSocketOptionData *opt) {
  switch (opt->option) {
    case PR_SockOpt_Nonblocking:
      return PR_SUCCESS;
    case PR_SockOpt_NoDelay:
      return PR_SUCCESS;
    default:
      UNIMPLEMENTED;
      break;
  }

  return PR_FAILURE;
}

static PRInt32 StreamSendfile(PRFileDesc *out, PRSendFileData *in,
                              PRTransmitFileFlags flags, PRIntervalTime to) {
  UNIMPLEMENTED;
  return -1;
}

static PRStatus StreamConnectContinue(PRFileDesc *socket, PRInt16 flags) {
  UNIMPLEMENTED;
  return PR_FAILURE;
}

static PRIntn StreamReserved(PRFileDesc *socket) {
  UNIMPLEMENTED;
  return -1;
}

static const struct PRIOMethods nss_methods = {
  PR_DESC_LAYERED,
  StreamClose,
  StreamRead,
  StreamWrite,
  StreamAvailable,
  StreamAvailable64,
  StreamSync,
  StreamSeek,
  StreamSeek64,
  StreamFileInfo,
  StreamFileInfo64,
  StreamWritev,
  StreamConnect,
  StreamAccept,
  StreamBind,
  StreamListen,
  StreamShutdown,
  StreamRecv,
  StreamSend,
  StreamRecvfrom,
  StreamSendto,
  StreamPoll,
  StreamAcceptRead,
  StreamTransmitFile,
  StreamGetSockName,
  StreamGetPeerName,
  StreamReserved,
  StreamReserved,
  StreamGetSockOption,
  StreamSetSockOption,
  StreamSendfile,
  StreamConnectContinue,
  StreamReserved,
  StreamReserved,
  StreamReserved,
  StreamReserved
};

NSSStreamAdapter::NSSStreamAdapter(StreamInterface *stream)
    : SSLStreamAdapterHelper(stream),
      ssl_fd_(NULL),
      cert_ok_(false) {
}

bool NSSStreamAdapter::Init() {
  if (nspr_layer_identity == PR_INVALID_IO_LAYER) {
    nspr_layer_identity = PR_GetUniqueIdentity("nssstreamadapter");
  }
  PRFileDesc *pr_fd = PR_CreateIOLayerStub(nspr_layer_identity, &nss_methods);
  if (!pr_fd)
    return false;
  pr_fd->secret = reinterpret_cast<PRFilePrivate *>(stream());

  PRFileDesc *ssl_fd;
  if (ssl_mode_ == SSL_MODE_DTLS) {
    ssl_fd = DTLS_ImportFD(NULL, pr_fd);
  } else {
    ssl_fd = SSL_ImportFD(NULL, pr_fd);
  }
  ASSERT(ssl_fd != NULL);  // This should never happen
  if (!ssl_fd) {
    PR_Close(pr_fd);
    return false;
  }

  SECStatus rv;
  // Turn on security.
  rv = SSL_OptionSet(ssl_fd, SSL_SECURITY, PR_TRUE);
  if (rv != SECSuccess) {
    LOG(LS_ERROR) << "Error enabling security on SSL Socket";
    return false;
  }

  // Disable SSLv2.
  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_SSL2, PR_FALSE);
  if (rv != SECSuccess) {
    LOG(LS_ERROR) << "Error disabling SSL2";
    return false;
  }

  // Disable caching.
  // TODO(ekr@rtfm.com): restore this when I have the caching
  // identity set.
  rv = SSL_OptionSet(ssl_fd, SSL_NO_CACHE, PR_TRUE);
  if (rv != SECSuccess) {
    LOG(LS_ERROR) << "Error disabling cache";
    return false;
  }

  // Disable session tickets.
  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_SESSION_TICKETS, PR_FALSE);
  if (rv != SECSuccess) {
    LOG(LS_ERROR) << "Error enabling tickets";
    return false;
  }

  // Disable renegotiation.
  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_RENEGOTIATION,
                     SSL_RENEGOTIATE_NEVER);
  if (rv != SECSuccess) {
    LOG(LS_ERROR) << "Error disabling renegotiation";
    return false;
  }

  // Disable false start.
  rv = SSL_OptionSet(ssl_fd, SSL_ENABLE_FALSE_START, PR_FALSE);
  if (rv != SECSuccess) {
    LOG(LS_ERROR) << "Error disabling false start";
    return false;
  }

  ssl_fd_ = ssl_fd;

  return true;
}

NSSStreamAdapter::~NSSStreamAdapter() {
  if (ssl_fd_)
    PR_Close(ssl_fd_);
};


int NSSStreamAdapter::BeginSSL() {
  SECStatus rv;

  if (!Init()) {
    Error("Init", -1, false);
    return -1;
  }

  ASSERT(state_ == SSL_CONNECTING);
  // The underlying stream has been opened. If we are in peer-to-peer mode
  // then a peer certificate must have been specified by now.
  ASSERT(!ssl_server_name_.empty() ||
         peer_certificate_.get() != NULL ||
         !peer_certificate_digest_algorithm_.empty());
  LOG(LS_INFO) << "BeginSSL: "
               << (!ssl_server_name_.empty() ? ssl_server_name_ :
                                               "with peer");

  if (role_ == SSL_CLIENT) {
    LOG(LS_INFO) << "BeginSSL: as client";

    rv = SSL_GetClientAuthDataHook(ssl_fd_, GetClientAuthDataHook,
                                   this);
    if (rv != SECSuccess) {
      Error("BeginSSL", -1, false);
      return -1;
    }
  } else {
    LOG(LS_INFO) << "BeginSSL: as server";
    NSSIdentity *identity;

    if (identity_.get()) {
      identity = static_cast<NSSIdentity *>(identity_.get());
    } else {
      LOG(LS_ERROR) << "Can't be an SSL server without an identity";
      Error("BeginSSL", -1, false);
      return -1;
    }
    rv = SSL_ConfigSecureServer(ssl_fd_, identity->certificate().certificate(),
                                identity->keypair()->privkey(),
                                kt_rsa);
    if (rv != SECSuccess) {
      Error("BeginSSL", -1, false);
      return -1;
    }

    // Insist on a certificate from the client
    rv = SSL_OptionSet(ssl_fd_, SSL_REQUEST_CERTIFICATE, PR_TRUE);
    if (rv != SECSuccess) {
      Error("BeginSSL", -1, false);
      return -1;
    }

    // TODO(juberti): Check for client_auth_enabled()

    rv = SSL_OptionSet(ssl_fd_, SSL_REQUIRE_CERTIFICATE, PR_TRUE);
    if (rv != SECSuccess) {
      Error("BeginSSL", -1, false);
      return -1;
    }
  }

  // Set the version range.
  SSLVersionRange vrange;
  vrange.min =  (ssl_mode_ == SSL_MODE_DTLS) ?
      SSL_LIBRARY_VERSION_TLS_1_1 :
      SSL_LIBRARY_VERSION_TLS_1_0;
  vrange.max = SSL_LIBRARY_VERSION_TLS_1_1;

  rv = SSL_VersionRangeSet(ssl_fd_, &vrange);
  if (rv != SECSuccess) {
    Error("BeginSSL", -1, false);
    return -1;
  }

  // SRTP
#ifdef HAVE_DTLS_SRTP
  if (!srtp_ciphers_.empty()) {
    rv = SSL_SetSRTPCiphers(
        ssl_fd_, &srtp_ciphers_[0],
        checked_cast<unsigned int>(srtp_ciphers_.size()));
    if (rv != SECSuccess) {
      Error("BeginSSL", -1, false);
      return -1;
    }
  }
#endif

  // Certificate validation
  rv = SSL_AuthCertificateHook(ssl_fd_, AuthCertificateHook, this);
  if (rv != SECSuccess) {
    Error("BeginSSL", -1, false);
    return -1;
  }

  // Now start the handshake
  rv = SSL_ResetHandshake(ssl_fd_, role_ == SSL_SERVER ? PR_TRUE : PR_FALSE);
  if (rv != SECSuccess) {
    Error("BeginSSL", -1, false);
    return -1;
  }

  return ContinueSSL();
}

int NSSStreamAdapter::ContinueSSL() {
  LOG(LS_INFO) << "ContinueSSL";
  ASSERT(state_ == SSL_CONNECTING);

  // Clear the DTLS timer
  Thread::Current()->Clear(this, MSG_DTLS_TIMEOUT);

  SECStatus rv = SSL_ForceHandshake(ssl_fd_);

  if (rv == SECSuccess) {
    LOG(LS_INFO) << "Handshake complete";

    ASSERT(cert_ok_);
    if (!cert_ok_) {
      Error("ContinueSSL", -1, true);
      return -1;
    }

    state_ = SSL_CONNECTED;
    StreamAdapterInterface::OnEvent(stream(), SE_OPEN|SE_READ|SE_WRITE, 0);
    return 0;
  }

  PRInt32 err = PR_GetError();
  switch (err) {
    case SSL_ERROR_RX_MALFORMED_HANDSHAKE:
      if (ssl_mode_ != SSL_MODE_DTLS) {
        Error("ContinueSSL", -1, true);
        return -1;
      } else {
        LOG(LS_INFO) << "Malformed DTLS message. Ignoring.";
        FALLTHROUGH();  // Fall through
      }
    case PR_WOULD_BLOCK_ERROR:
      LOG(LS_INFO) << "Would have blocked";
      if (ssl_mode_ == SSL_MODE_DTLS) {
        PRIntervalTime timeout;

        SECStatus rv = DTLS_GetHandshakeTimeout(ssl_fd_, &timeout);
        if (rv == SECSuccess) {
          LOG(LS_INFO) << "Timeout is " << timeout << " ms";
          Thread::Current()->PostDelayed(PR_IntervalToMilliseconds(timeout),
                                         this, MSG_DTLS_TIMEOUT, 0);
        }
      }

      return 0;
    default:
      LOG(LS_INFO) << "Error " << err;
      break;
  }

  Error("ContinueSSL", -1, true);
  return -1;
}

void NSSStreamAdapter::Cleanup() {
  if (state_ != SSL_ERROR) {
    state_ = SSL_CLOSED;
  }

  if (ssl_fd_) {
    PR_Close(ssl_fd_);
    ssl_fd_ = NULL;
  }

  identity_.reset();
  peer_certificate_.reset();

  Thread::Current()->Clear(this, MSG_DTLS_TIMEOUT);
}

bool NSSStreamAdapter::GetDigestLength(const std::string& algorithm,
                                       size_t* length) {
  return NSSCertificate::GetDigestLength(algorithm, length);
}

StreamResult NSSStreamAdapter::Read(void* data, size_t data_len,
                                    size_t* read, int* error) {
  // SSL_CONNECTED sanity check.
  switch (state_) {
    case SSL_NONE:
    case SSL_WAIT:
    case SSL_CONNECTING:
      return SR_BLOCK;

    case SSL_CONNECTED:
      break;

    case SSL_CLOSED:
      return SR_EOS;

    case SSL_ERROR:
    default:
      if (error)
        *error = ssl_error_code_;
      return SR_ERROR;
  }

  PRInt32 rv = PR_Read(ssl_fd_, data, checked_cast<PRInt32>(data_len));

  if (rv == 0) {
    return SR_EOS;
  }

  // Error
  if (rv < 0) {
    PRInt32 err = PR_GetError();

    switch (err) {
      case PR_WOULD_BLOCK_ERROR:
        return SR_BLOCK;
      default:
        Error("Read", -1, false);
        *error = err;  // libjingle semantics are that this is impl-specific
        return SR_ERROR;
    }
  }

  // Success
  *read = rv;

  return SR_SUCCESS;
}

StreamResult NSSStreamAdapter::Write(const void* data, size_t data_len,
                                     size_t* written, int* error) {
  // SSL_CONNECTED sanity check.
  switch (state_) {
    case SSL_NONE:
    case SSL_WAIT:
    case SSL_CONNECTING:
      return SR_BLOCK;

    case SSL_CONNECTED:
      break;

    case SSL_ERROR:
    case SSL_CLOSED:
    default:
      if (error)
        *error = ssl_error_code_;
      return SR_ERROR;
  }

  PRInt32 rv = PR_Write(ssl_fd_, data, checked_cast<PRInt32>(data_len));

  // Error
  if (rv < 0) {
    PRInt32 err = PR_GetError();

    switch (err) {
      case PR_WOULD_BLOCK_ERROR:
        return SR_BLOCK;
      default:
        Error("Write", -1, false);
        *error = err;  // libjingle semantics are that this is impl-specific
        return SR_ERROR;
    }
  }

  // Success
  *written = rv;

  return SR_SUCCESS;
}

void NSSStreamAdapter::OnEvent(StreamInterface* stream, int events,
                               int err) {
  int events_to_signal = 0;
  int signal_error = 0;
  ASSERT(stream == this->stream());
  if ((events & SE_OPEN)) {
    LOG(LS_INFO) << "NSSStreamAdapter::OnEvent SE_OPEN";
    if (state_ != SSL_WAIT) {
      ASSERT(state_ == SSL_NONE);
      events_to_signal |= SE_OPEN;
    } else {
      state_ = SSL_CONNECTING;
      if (int err = BeginSSL()) {
        Error("BeginSSL", err, true);
        return;
      }
    }
  }
  if ((events & (SE_READ|SE_WRITE))) {
    LOG(LS_INFO) << "NSSStreamAdapter::OnEvent"
                 << ((events & SE_READ) ? " SE_READ" : "")
                 << ((events & SE_WRITE) ? " SE_WRITE" : "");
    if (state_ == SSL_NONE) {
      events_to_signal |= events & (SE_READ|SE_WRITE);
    } else if (state_ == SSL_CONNECTING) {
      if (int err = ContinueSSL()) {
        Error("ContinueSSL", err, true);
        return;
      }
    } else if (state_ == SSL_CONNECTED) {
      if (events & SE_WRITE) {
        LOG(LS_INFO) << " -- onStreamWriteable";
        events_to_signal |= SE_WRITE;
      }
      if (events & SE_READ) {
        LOG(LS_INFO) << " -- onStreamReadable";
        events_to_signal |= SE_READ;
      }
    }
  }
  if ((events & SE_CLOSE)) {
    LOG(LS_INFO) << "NSSStreamAdapter::OnEvent(SE_CLOSE, " << err << ")";
    Cleanup();
    events_to_signal |= SE_CLOSE;
    // SE_CLOSE is the only event that uses the final parameter to OnEvent().
    ASSERT(signal_error == 0);
    signal_error = err;
  }
  if (events_to_signal)
    StreamAdapterInterface::OnEvent(stream, events_to_signal, signal_error);
}

void NSSStreamAdapter::OnMessage(Message* msg) {
  // Process our own messages and then pass others to the superclass
  if (MSG_DTLS_TIMEOUT == msg->message_id) {
    LOG(LS_INFO) << "DTLS timeout expired";
    ContinueSSL();
  } else {
    StreamInterface::OnMessage(msg);
  }
}

// Certificate verification callback. Called to check any certificate
SECStatus NSSStreamAdapter::AuthCertificateHook(void *arg,
                                                PRFileDesc *fd,
                                                PRBool checksig,
                                                PRBool isServer) {
  LOG(LS_INFO) << "NSSStreamAdapter::AuthCertificateHook";
  // SSL_PeerCertificate returns a pointer that is owned by the caller, and
  // the NSSCertificate constructor copies its argument, so |raw_peer_cert|
  // must be destroyed in this function.
  CERTCertificate* raw_peer_cert = SSL_PeerCertificate(fd);
  NSSCertificate peer_cert(raw_peer_cert);
  CERT_DestroyCertificate(raw_peer_cert);

  NSSStreamAdapter *stream = reinterpret_cast<NSSStreamAdapter *>(arg);
  stream->cert_ok_ = false;

  // Read the peer's certificate chain.
  CERTCertList* cert_list = SSL_PeerCertificateChain(fd);
  ASSERT(cert_list != NULL);

  // If the peer provided multiple certificates, check that they form a valid
  // chain as defined by RFC 5246 Section 7.4.2: "Each following certificate
  // MUST directly certify the one preceding it.".  This check does NOT
  // verify other requirements, such as whether the chain reaches a trusted
  // root, self-signed certificates have valid signatures, certificates are not
  // expired, etc.
  // Even if the chain is valid, the leaf certificate must still match a
  // provided certificate or digest.
  if (!NSSCertificate::IsValidChain(cert_list)) {
    CERT_DestroyCertList(cert_list);
    PORT_SetError(SEC_ERROR_BAD_SIGNATURE);
    return SECFailure;
  }

  if (stream->peer_certificate_.get()) {
    LOG(LS_INFO) << "Checking against specified certificate";

    // The peer certificate was specified
    if (reinterpret_cast<NSSCertificate *>(stream->peer_certificate_.get())->
        Equals(&peer_cert)) {
      LOG(LS_INFO) << "Accepted peer certificate";
      stream->cert_ok_ = true;
    }
  } else if (!stream->peer_certificate_digest_algorithm_.empty()) {
    LOG(LS_INFO) << "Checking against specified digest";
    // The peer certificate digest was specified
    unsigned char digest[64];  // Maximum size
    size_t digest_length;

    if (!peer_cert.ComputeDigest(
            stream->peer_certificate_digest_algorithm_,
            digest, sizeof(digest), &digest_length)) {
      LOG(LS_ERROR) << "Digest computation failed";
    } else {
      Buffer computed_digest(digest, digest_length);
      if (computed_digest == stream->peer_certificate_digest_value_) {
        LOG(LS_INFO) << "Accepted peer certificate";
        stream->cert_ok_ = true;
      }
    }
  } else {
    // Other modes, but we haven't implemented yet
    // TODO(ekr@rtfm.com): Implement real certificate validation
    UNIMPLEMENTED;
  }

  if (!stream->cert_ok_ && stream->ignore_bad_cert()) {
    LOG(LS_WARNING) << "Ignoring cert error while verifying cert chain";
    stream->cert_ok_ = true;
  }

  if (stream->cert_ok_)
    stream->peer_certificate_.reset(new NSSCertificate(cert_list));

  CERT_DestroyCertList(cert_list);

  if (stream->cert_ok_)
    return SECSuccess;

  PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
  return SECFailure;
}


SECStatus NSSStreamAdapter::GetClientAuthDataHook(void *arg, PRFileDesc *fd,
                                                  CERTDistNames *caNames,
                                                  CERTCertificate **pRetCert,
                                                  SECKEYPrivateKey **pRetKey) {
  LOG(LS_INFO) << "Client cert requested";
  NSSStreamAdapter *stream = reinterpret_cast<NSSStreamAdapter *>(arg);

  if (!stream->identity_.get()) {
    LOG(LS_ERROR) << "No identity available";
    return SECFailure;
  }

  NSSIdentity *identity = static_cast<NSSIdentity *>(stream->identity_.get());
  // Destroyed internally by NSS
  *pRetCert = CERT_DupCertificate(identity->certificate().certificate());
  *pRetKey = SECKEY_CopyPrivateKey(identity->keypair()->privkey());

  return SECSuccess;
}

bool NSSStreamAdapter::GetSslCipher(std::string* cipher) {
  ASSERT(state_ == SSL_CONNECTED);
  if (state_ != SSL_CONNECTED)
    return false;

  SSLChannelInfo channel_info;
  SECStatus rv = SSL_GetChannelInfo(ssl_fd_, &channel_info,
                                    sizeof(channel_info));
  if (rv == SECFailure)
    return false;

  SSLCipherSuiteInfo ciphersuite_info;
  rv = SSL_GetCipherSuiteInfo(channel_info.cipherSuite, &ciphersuite_info,
                              sizeof(ciphersuite_info));
  if (rv == SECFailure)
    return false;

  *cipher = ciphersuite_info.cipherSuiteName;
  return true;
}

// RFC 5705 Key Exporter
bool NSSStreamAdapter::ExportKeyingMaterial(const std::string& label,
                                            const uint8* context,
                                            size_t context_len,
                                            bool use_context,
                                            uint8* result,
                                            size_t result_len) {
  SECStatus rv = SSL_ExportKeyingMaterial(
      ssl_fd_,
      label.c_str(),
      checked_cast<unsigned int>(label.size()),
      use_context,
      context,
      checked_cast<unsigned int>(context_len),
      result,
      checked_cast<unsigned int>(result_len));

  return rv == SECSuccess;
}

bool NSSStreamAdapter::SetDtlsSrtpCiphers(
    const std::vector<std::string>& ciphers) {
#ifdef HAVE_DTLS_SRTP
  std::vector<PRUint16> internal_ciphers;
  if (state_ != SSL_NONE)
    return false;

  for (std::vector<std::string>::const_iterator cipher = ciphers.begin();
       cipher != ciphers.end(); ++cipher) {
    bool found = false;
    for (const SrtpCipherMapEntry *entry = kSrtpCipherMap; entry->cipher_id;
         ++entry) {
      if (*cipher == entry->external_name) {
        found = true;
        internal_ciphers.push_back(entry->cipher_id);
        break;
      }
    }

    if (!found) {
      LOG(LS_ERROR) << "Could not find cipher: " << *cipher;
      return false;
    }
  }

  if (internal_ciphers.empty())
    return false;

  srtp_ciphers_ = internal_ciphers;

  return true;
#else
  return false;
#endif
}

bool NSSStreamAdapter::GetDtlsSrtpCipher(std::string* cipher) {
#ifdef HAVE_DTLS_SRTP
  ASSERT(state_ == SSL_CONNECTED);
  if (state_ != SSL_CONNECTED)
    return false;

  PRUint16 selected_cipher;

  SECStatus rv = SSL_GetSRTPCipher(ssl_fd_, &selected_cipher);
  if (rv == SECFailure)
    return false;

  for (const SrtpCipherMapEntry *entry = kSrtpCipherMap;
       entry->cipher_id; ++entry) {
    if (selected_cipher == entry->cipher_id) {
      *cipher = entry->external_name;
      return true;
    }
  }

  ASSERT(false);  // This should never happen
#endif
  return false;
}


GlobalLockPod NSSContext::lock;
NSSContext *NSSContext::global_nss_context;

// Static initialization and shutdown
NSSContext *NSSContext::Instance() {
  lock.Lock();
  if (!global_nss_context) {
    scoped_ptr<NSSContext> new_ctx(new NSSContext(PK11_GetInternalSlot()));
    if (new_ctx->slot_)
      global_nss_context = new_ctx.release();
  }
  lock.Unlock();

  return global_nss_context;
}

bool NSSContext::InitializeSSL(VerificationCallback callback) {
  ASSERT(!callback);

  static bool initialized = false;

  if (!initialized) {
    SECStatus rv;

    rv = NSS_NoDB_Init(NULL);
    if (rv != SECSuccess) {
      LOG(LS_ERROR) << "Couldn't initialize NSS error=" <<
          PORT_GetError();
      return false;
    }

    NSS_SetDomesticPolicy();

    initialized = true;
  }

  return true;
}

bool NSSContext::InitializeSSLThread() {
  // Not needed
  return true;
}

bool NSSContext::CleanupSSL() {
  // Not needed
  return true;
}

bool NSSStreamAdapter::HaveDtls() {
  return true;
}

bool NSSStreamAdapter::HaveDtlsSrtp() {
#ifdef HAVE_DTLS_SRTP
  return true;
#else
  return false;
#endif
}

bool NSSStreamAdapter::HaveExporter() {
  return true;
}

std::string NSSStreamAdapter::GetDefaultSslCipher() {
  return kDefaultSslCipher;
}

}  // namespace rtc

#endif  // HAVE_NSS_SSL_H
