/**
   * The ServerKeyExchange message is sent by the server only when the server {@link
   * CertificateMessage} (if sent) does not contain enough data to allow the client to exchange a
   * premaster secret. Used when the key exchange is ECDH. The client tries to verify the server's
   * signature and on success prepares the ECDH key agreement.
   *
   * @param message the server's {@link ServerKeyExchange} message.
   * @throws HandshakeException if the message can't be verified.
   */
  private void receivedServerKeyExchange(ECDHServerKeyExchange message) throws HandshakeException {
    if (serverKeyExchange != null
        && (serverKeyExchange.getMessageSeq() == message.getMessageSeq())) {
      // discard duplicate message
      return;
    }

    serverKeyExchange = message;
    message.verifySignature(serverPublicKey, clientRandom, serverRandom);

    // get the curve parameter spec by the named curve id
    ECParameterSpec params = ECDHServerKeyExchange.NAMED_CURVE_PARAMETERS.get(message.getCurveId());
    if (params == null) {
      AlertMessage alert = new AlertMessage(AlertLevel.FATAL, AlertDescription.HANDSHAKE_FAILURE);
      throw new HandshakeException("Server used unsupported elliptic curve for ECDH", alert);
    }

    ephemeralServerPublicKey = message.getPublicKey(params);
    ecdhe = new ECDHECryptography(ephemeralServerPublicKey.getParams());
  }