_gnutls_gen_cert_server_cert_req (gnutls_session_t session,
                                  gnutls_buffer_st * data)
{
  gnutls_certificate_credentials_t cred;
  int size, ret;
  uint8_t tmp_data[CERTTYPE_SIZE];
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

  /* Now we need to generate the RDN sequence. This is
   * already in the CERTIFICATE_CRED structure, to improve
   * performance.
   */

  cred = (gnutls_certificate_credentials_t)
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
  if (cred == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  size = CERTTYPE_SIZE + 2;     /* 2 for gnutls_certificate_type_t + 2 for size of rdn_seq 
                                 */

  if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
      session->internals.ignore_rdn_sequence == 0)
    size += cred->x509_rdn_sequence.size;

  if (_gnutls_version_has_selectable_sighash (ver))
    /* Need two bytes to announce the number of supported hash
       functions (see below).  */
    size += MAX_SIGN_ALGO_SIZE;

  tmp_data[0] = CERTTYPE_SIZE - 1;
  tmp_data[1] = RSA_SIGN;
  tmp_data[2] = DSA_SIGN;
  tmp_data[3] = ECDSA_SIGN;     /* only these for now */

  ret = _gnutls_buffer_append_data (data, tmp_data, CERTTYPE_SIZE);
  if (ret < 0)
    return gnutls_assert_val (ret);

  if (_gnutls_version_has_selectable_sighash (ver))
    {
      uint8_t p[MAX_SIGN_ALGO_SIZE];

      ret =
        _gnutls_sign_algorithm_write_params (session, p, MAX_SIGN_ALGO_SIZE);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }

      /* recalculate size */
      size -= MAX_SIGN_ALGO_SIZE + ret;

      ret = _gnutls_buffer_append_data (data, p, ret);
      if (ret < 0)
        return gnutls_assert_val (ret);
    }

  if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
      session->internals.ignore_rdn_sequence == 0)
    {
      ret =
        _gnutls_buffer_append_data_prefix (data, 16,
                                           cred->x509_rdn_sequence.data,
                                           cred->x509_rdn_sequence.size);
      if (ret < 0)
        return gnutls_assert_val (ret);
    }
  else
    {
      ret = _gnutls_buffer_append_prefix (data, 16, 0);
      if (ret < 0)
        return gnutls_assert_val (ret);
    }

  return data->length;
}
_gnutls_gen_cert_server_cert_req (gnutls_session_t session,
                                  gnutls_buffer_st * data)
{
  gnutls_certificate_credentials_t cred;
  int size, ret;
  uint8_t tmp_data[CERTTYPE_SIZE];
  gnutls_protocol_t ver = gnutls_protocol_get_version (session);

   

  cred = (gnutls_certificate_credentials_t)
    _gnutls_get_cred (session->key, GNUTLS_CRD_CERTIFICATE, NULL);
  if (cred == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_INSUFFICIENT_CREDENTIALS;
    }

  size = CERTTYPE_SIZE + 2;      

  if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
      session->internals.ignore_rdn_sequence == 0)
    size += cred->x509_rdn_sequence.size;

  if (_gnutls_version_has_selectable_sighash (ver))
     
    size += MAX_SIGN_ALGO_SIZE;

  tmp_data[0] = CERTTYPE_SIZE - 1;
  tmp_data[1] = RSA_SIGN;
  tmp_data[2] = DSA_SIGN;
  tmp_data[3] = ECDSA_SIGN;      

  ret = _gnutls_buffer_append_data (data, tmp_data, CERTTYPE_SIZE);
  if (ret < 0)
    return gnutls_assert_val (ret);

  if (_gnutls_version_has_selectable_sighash (ver))
    {
      uint8_t p[MAX_SIGN_ALGO_SIZE];

      ret =
        _gnutls_sign_algorithm_write_params (session, p, MAX_SIGN_ALGO_SIZE);
      if (ret < 0)
        {
          gnutls_assert ();
          return ret;
        }

       
      size -= MAX_SIGN_ALGO_SIZE + ret;

      ret = _gnutls_buffer_append_data (data, p, ret);
      if (ret < 0)
        return gnutls_assert_val (ret);
    }

  if (session->security_parameters.cert_type == GNUTLS_CRT_X509 &&
      session->internals.ignore_rdn_sequence == 0)
    {
      ret =
        _gnutls_buffer_append_data_prefix (data, 16,
                                           cred->x509_rdn_sequence.data,
                                           cred->x509_rdn_sequence.size);
      if (ret < 0)
        return gnutls_assert_val (ret);
    }
  else
    {
      ret = _gnutls_buffer_append_prefix (data, 16, 0);
      if (ret < 0)
        return gnutls_assert_val (ret);
    }

  return data->length;
}