Beispiel #1
0
/* encodes data and puts the result into result (locally allocated)
 * The result_size (including the null terminator) is the return value.
 */
int
_gnutls_fbase64_encode (const char *msg, const uint8_t * data,
                        size_t data_size, gnutls_datum_t * result)
{
  int tmp;
  unsigned int i;
  char tmpres[66];
  uint8_t *ptr;
  char top[80];
  char bottom[80];
  size_t size, max, bytes;
  int pos, top_len, bottom_len;

  if (msg == NULL || strlen(msg) > 50)
    {
      gnutls_assert ();
      return GNUTLS_E_BASE64_ENCODING_ERROR;
    }

  _gnutls_str_cpy (top, sizeof(top), "-----BEGIN ");
  _gnutls_str_cat (top, sizeof(top), msg);
  _gnutls_str_cat (top, sizeof(top), "-----\n");

  _gnutls_str_cpy (bottom, sizeof(bottom), "-----END ");
  _gnutls_str_cat (bottom, sizeof(bottom), msg);
  _gnutls_str_cat (bottom, sizeof(bottom), "-----\n");

  top_len = strlen (top);
  bottom_len = strlen (bottom);

  max = B64FSIZE (top_len+bottom_len, data_size);

  result->data = gnutls_malloc (max + 1);
  if (result->data == NULL)
    {
      gnutls_assert ();
      return GNUTLS_E_MEMORY_ERROR;
    }

  bytes = pos = 0;
  INCR (bytes, top_len, max);
  pos = top_len;

  memcpy (result->data, top, top_len);

  for (i = 0; i < data_size; i += 48)
    {
      if (data_size - i < 48)
        tmp = data_size - i;
      else
        tmp = 48;

      base64_encode ((void*)&data[i], tmp, tmpres, sizeof(tmpres));
      size = strlen(tmpres);

      INCR (bytes, size+1, max);
      ptr = &result->data[pos];

      memcpy(ptr, tmpres, size);
      ptr += size;
      *ptr++ = '\n';

      pos += size + 1;
    }

  INCR (bytes, bottom_len, max);

  memcpy (&result->data[bytes - bottom_len], bottom, bottom_len);
  result->data[bytes] = 0;
  result->size = bytes;

  return max + 1;
}
Beispiel #2
0
/* A generic export function. Will export the given ASN.1 encoded data
 * to PEM or DER raw data.
 */
int
_gnutls_x509_export_int (ASN1_TYPE asn1_data,
			 gnutls_x509_crt_fmt_t format, char *pem_header,
			 int tmp_buf_size, unsigned char *output_data,
			 size_t * output_data_size)
{
  int result, len;
  if (tmp_buf_size == 0)
    tmp_buf_size = 16 * 1024;

  if (format == GNUTLS_X509_FMT_DER)
    {

      if (output_data == NULL)
	*output_data_size = 0;

      len = *output_data_size;

      if ((result =
	   asn1_der_coding (asn1_data, "", output_data, &len,
			    NULL)) != ASN1_SUCCESS)
	{
	  *output_data_size = len;
	  if (result == ASN1_MEM_ERROR)
	    {
	      return GNUTLS_E_SHORT_MEMORY_BUFFER;
	    }
	  gnutls_assert ();
	  return _gnutls_asn2err (result);
	}

      *output_data_size = len;

    }
  else
    {				/* PEM */
      opaque *tmp;
      opaque *out;

      len = tmp_buf_size;

      tmp = gnutls_alloca (len);
      if (tmp == NULL)
	{
	  gnutls_assert ();
	  return GNUTLS_E_MEMORY_ERROR;
	}

      if ((result =
	   asn1_der_coding (asn1_data, "", tmp, &len, NULL)) != ASN1_SUCCESS)
	{
	  gnutls_assert ();
	  if (result == ASN1_MEM_ERROR)
	    {
	      *output_data_size = B64FSIZE (strlen (pem_header), len) + 1;
	    }
	  gnutls_afree (tmp);
	  return _gnutls_asn2err (result);
	}

      result = _gnutls_fbase64_encode (pem_header, tmp, len, &out);

      gnutls_afree (tmp);

      if (result < 0)
	{
	  gnutls_assert ();
	  return result;
	}

      if (result == 0)
	{			/* oooops */
	  gnutls_assert ();
	  return GNUTLS_E_INTERNAL_ERROR;
	}

      if ((unsigned) result > *output_data_size)
	{
	  gnutls_assert ();
	  gnutls_free (out);
	  *output_data_size = result;
	  return GNUTLS_E_SHORT_MEMORY_BUFFER;
	}

      *output_data_size = result;

      if (output_data)
	{
	  memcpy (output_data, out, result);

	  /* do not include the null character into output size.
	   */
	  *output_data_size = result - 1;
	}
      gnutls_free (out);

    }

  return 0;
}