Exemplo n.º 1
0
/* If OPTIONAL fields have not been initialized then
 * disable them.
 */
static void disable_optional_stuff(gnutls_x509_crt_t cert)
{
	asn1_data_node_st n;
	asn1_node node;
	unsigned remove_subject_unique_id = 1;
	unsigned remove_issuer_unique_id = 1;

	node = asn1_find_node(cert->cert, "tbsCertificate.issuerUniqueID");
	if (node) {
		if (asn1_read_node_value(node, &n) == ASN1_SUCCESS && n.value_len != 0)
			remove_issuer_unique_id = 0;
	}

	node = asn1_find_node(cert->cert, "tbsCertificate.subjectUniqueID");
	if (node) {
		if (asn1_read_node_value(node, &n) == ASN1_SUCCESS && n.value_len != 0)
			remove_subject_unique_id = 0;
	}

	if (remove_issuer_unique_id)
		asn1_write_value(cert->cert, "tbsCertificate.issuerUniqueID", NULL,
				 0);

	if (remove_subject_unique_id)
		asn1_write_value(cert->cert, "tbsCertificate.subjectUniqueID",
				 NULL, 0);

	if (cert->use_extensions == 0) {
		_gnutls_debug_log("Disabling X.509 extensions.\n");
		asn1_write_value(cert->cert, "tbsCertificate.extensions",
				 NULL, 0);
	}

	return;
}
Exemplo n.º 2
0
/**
 * asn1_delete_element:
 * @structure: pointer to the structure that contains the element you
 *   want to delete.
 * @element_name: element's name you want to delete.
 *
 * Deletes the element named *@element_name inside *@structure.
 *
 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
 *   the @element_name was not found.
 **/
asn1_retCode
asn1_delete_element (ASN1_TYPE structure, const char *element_name)
{
  ASN1_TYPE p2, p3, source_node;

  source_node = asn1_find_node (structure, element_name);

  if (source_node == ASN1_TYPE_EMPTY)
    return ASN1_ELEMENT_NOT_FOUND;

  p2 = source_node->right;
  p3 = _asn1_find_left (source_node);
  if (!p3)
    {
      p3 = _asn1_find_up (source_node);
      if (p3)
	_asn1_set_down (p3, p2);
      else if (source_node->right)
	source_node->right->left = NULL;
    }
  else
    _asn1_set_right (p3, p2);

  return asn1_delete_structure (&source_node);
}
Exemplo n.º 3
0
/**
 * asn1_number_of_elements:
 * @element: pointer to the root of an ASN1 structure.
 * @name: the name of a sub-structure of ROOT.
 * @num: pointer to an integer where the result will be stored
 *
 * Counts the number of elements of a sub-structure called NAME with
 * names equal to "?1","?2", ...
 *
 * Returns: %ASN1_SUCCESS if successful, %ASN1_ELEMENT_NOT_FOUND if
 *   @name is not known, %ASN1_GENERIC_ERROR if pointer @num is %NULL.
 **/
asn1_retCode
asn1_number_of_elements (ASN1_TYPE element, const char *name, int *num)
{
  ASN1_TYPE node, p;

  if (num == NULL)
    return ASN1_GENERIC_ERROR;

  *num = 0;

  node = asn1_find_node (element, name);
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  p = node->down;

  while (p)
    {
      if ((p->name) && (p->name[0] == '?'))
	(*num)++;
      p = p->right;
    }

  return ASN1_SUCCESS;
}
Exemplo n.º 4
0
static ASN1_TYPE
_asn1_copy_structure2 (ASN1_TYPE root, const char *source_name)
{
  ASN1_TYPE source_node;

  source_node = asn1_find_node (root, source_name);

  return _asn1_copy_structure3 (source_node);

}
Exemplo n.º 5
0
/**
 * asn1_copy_node:
 * @dst: Destination ASN1_TYPE node.
 * @dst_name: Field name in destination node.
 * @src: Source ASN1_TYPE node.
 * @src_name: Field name in source node.
 *
 * Create a deep copy of a ASN1_TYPE variable.
 *
 * Returns: Return %ASN1_SUCCESS on success.
 **/
asn1_retCode
asn1_copy_node (ASN1_TYPE dst, const char *dst_name,
		ASN1_TYPE src, const char *src_name)
{
/* FIXME: rewrite using copy_structure().
 * It seems quite hard to do.
 */
  int result;
  ASN1_TYPE dst_node;
  void *data = NULL;
  int size = 0;

  result = asn1_der_coding (src, src_name, NULL, &size, NULL);
  if (result != ASN1_MEM_ERROR)
    return result;

  data = _asn1_malloc (size);
  if (data == NULL)
    return ASN1_MEM_ERROR;

  result = asn1_der_coding (src, src_name, data, &size, NULL);
  if (result != ASN1_SUCCESS)
    {
      _asn1_free (data);
      return result;
    }

  dst_node = asn1_find_node (dst, dst_name);
  if (dst_node == NULL)
    {
      _asn1_free (data);
      return ASN1_ELEMENT_NOT_FOUND;
    }

  result = asn1_der_decoding (&dst_node, data, size, NULL);

  _asn1_free (data);

  return result;
}
Exemplo n.º 6
0
/**
 * asn1_print_structure:
 * @out: pointer to the output file (e.g. stdout).
 * @structure: pointer to the structure that you want to visit.
 * @name: an element of the structure
 * @mode: specify how much of the structure to print, can be
 *   %ASN1_PRINT_NAME, %ASN1_PRINT_NAME_TYPE,
 *   %ASN1_PRINT_NAME_TYPE_VALUE, or %ASN1_PRINT_ALL.
 *
 * Prints on the @out file descriptor the structure's tree starting
 * from the @name element inside the structure @structure.
 **/
void
asn1_print_structure (FILE * out, ASN1_TYPE structure, const char *name,
		      int mode)
{
  ASN1_TYPE p, root;
  int k, indent = 0, len, len2, len3;

  if (out == NULL)
    return;

  root = asn1_find_node (structure, name);

  if (root == NULL)
    return;

  p = root;
  while (p)
    {
      if (mode == ASN1_PRINT_ALL)
	{
	  for (k = 0; k < indent; k++)
	    fprintf (out, " ");
	  fprintf (out, "name:");
	  if (p->name)
	    fprintf (out, "%s  ", p->name);
	  else
	    fprintf (out, "NULL  ");
	}
      else
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_CONSTANT:
	    case TYPE_TAG:
	    case TYPE_SIZE:
	      break;
	    default:
	      for (k = 0; k < indent; k++)
		fprintf (out, " ");
	      fprintf (out, "name:");
	      if (p->name)
		fprintf (out, "%s  ", p->name);
	      else
		fprintf (out, "NULL  ");
	    }
	}

      if (mode != ASN1_PRINT_NAME)
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_CONSTANT:
	      if (mode == ASN1_PRINT_ALL)
		fprintf (out, "type:CONST");
	      break;
	    case TYPE_TAG:
	      if (mode == ASN1_PRINT_ALL)
		fprintf (out, "type:TAG");
	      break;
	    case TYPE_SIZE:
	      if (mode == ASN1_PRINT_ALL)
		fprintf (out, "type:SIZE");
	      break;
	    case TYPE_DEFAULT:
	      fprintf (out, "type:DEFAULT");
	      break;
	    case TYPE_NULL:
	      fprintf (out, "type:NULL");
	      break;
	    case TYPE_IDENTIFIER:
	      fprintf (out, "type:IDENTIFIER");
	      break;
	    case TYPE_INTEGER:
	      fprintf (out, "type:INTEGER");
	      break;
	    case TYPE_ENUMERATED:
	      fprintf (out, "type:ENUMERATED");
	      break;
	    case TYPE_TIME:
	      fprintf (out, "type:TIME");
	      break;
	    case TYPE_BOOLEAN:
	      fprintf (out, "type:BOOLEAN");
	      break;
	    case TYPE_SEQUENCE:
	      fprintf (out, "type:SEQUENCE");
	      break;
	    case TYPE_BIT_STRING:
	      fprintf (out, "type:BIT_STR");
	      break;
	    case TYPE_OCTET_STRING:
	      fprintf (out, "type:OCT_STR");
	      break;
	    case TYPE_GENERALSTRING:
	      fprintf (out, "type:GENERALSTRING");
	      break;
	    case TYPE_SEQUENCE_OF:
	      fprintf (out, "type:SEQ_OF");
	      break;
	    case TYPE_OBJECT_ID:
	      fprintf (out, "type:OBJ_ID");
	      break;
	    case TYPE_ANY:
	      fprintf (out, "type:ANY");
	      break;
	    case TYPE_SET:
	      fprintf (out, "type:SET");
	      break;
	    case TYPE_SET_OF:
	      fprintf (out, "type:SET_OF");
	      break;
	    case TYPE_CHOICE:
	      fprintf (out, "type:CHOICE");
	      break;
	    case TYPE_DEFINITIONS:
	      fprintf (out, "type:DEFINITIONS");
	      break;
	    default:
	      break;
	    }
	}

      if ((mode == ASN1_PRINT_NAME_TYPE_VALUE) || (mode == ASN1_PRINT_ALL))
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_CONSTANT:
	      if (mode == ASN1_PRINT_ALL)
		if (p->value)
		  fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_TAG:
	      if (mode == ASN1_PRINT_ALL)
		if (p->value)
		  fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_SIZE:
	      if (mode == ASN1_PRINT_ALL)
		if (p->value)
		  fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_DEFAULT:
	      if (p->value)
		fprintf (out, "  value:%s", p->value);
	      else if (p->type & CONST_TRUE)
		fprintf (out, "  value:TRUE");
	      else if (p->type & CONST_FALSE)
		fprintf (out, "  value:FALSE");
	      break;
	    case TYPE_IDENTIFIER:
	      if (p->value)
		fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_INTEGER:
	      if (p->value)
		{
		  len2 = -1;
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
		  fprintf (out, "  value:0x");
		  if (len > 0)
		    for (k = 0; k < len; k++)
		      fprintf (out, "%02x", (p->value)[k + len2]);
		}
	      break;
	    case TYPE_ENUMERATED:
	      if (p->value)
		{
		  len2 = -1;
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
		  fprintf (out, "  value:0x");
		  if (len > 0)
		    for (k = 0; k < len; k++)
		      fprintf (out, "%02x", (p->value)[k + len2]);
		}
	      break;
	    case TYPE_TIME:
	      if (p->value)
		fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_BOOLEAN:
	      if (p->value)
		{
		  if (p->value[0] == 'T')
		    fprintf (out, "  value:TRUE");
		  else if (p->value[0] == 'F')
		    fprintf (out, "  value:FALSE");
		}
	      break;
	    case TYPE_BIT_STRING:
	      if (p->value)
		{
		  len2 = -1;
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
		  if (len > 0)
		    {
		      fprintf (out, "  value(%i):",
			       (len - 1) * 8 - (p->value[len2]));
		      for (k = 1; k < len; k++)
			fprintf (out, "%02x", (p->value)[k + len2]);
		    }
		}
	      break;
	    case TYPE_OCTET_STRING:
	      if (p->value)
		{
		  len2 = -1;
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
		  fprintf (out, "  value:");
		  if (len > 0)
		    for (k = 0; k < len; k++)
		      fprintf (out, "%02x", (p->value)[k + len2]);
		}
	      break;
	    case TYPE_GENERALSTRING:
	      if (p->value)
		{
		  len2 = -1;
		  len = asn1_get_length_der (p->value, p->value_len, &len2);
		  fprintf (out, "  value:");
		  if (len > 0)
		    for (k = 0; k < len; k++)
		      fprintf (out, "%02x", (p->value)[k + len2]);
		}
	      break;
	    case TYPE_OBJECT_ID:
	      if (p->value)
		fprintf (out, "  value:%s", p->value);
	      break;
	    case TYPE_ANY:
	      if (p->value)
		{
		  len3 = -1;
		  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
		  fprintf (out, "  value:");
		  if (len2 > 0)
		    for (k = 0; k < len2; k++)
		      fprintf (out, "%02x", (p->value)[k + len3]);
		}
	      break;
	    case TYPE_SET:
	    case TYPE_SET_OF:
	    case TYPE_CHOICE:
	    case TYPE_DEFINITIONS:
	    case TYPE_SEQUENCE_OF:
	    case TYPE_SEQUENCE:
	    case TYPE_NULL:
	      break;
	    default:
	      break;
	    }
	}

      if (mode == ASN1_PRINT_ALL)
	{
	  if (p->type & 0x1FFFFF00)
	    {
	      fprintf (out, "  attr:");
	      if (p->type & CONST_UNIVERSAL)
		fprintf (out, "UNIVERSAL,");
	      if (p->type & CONST_PRIVATE)
		fprintf (out, "PRIVATE,");
	      if (p->type & CONST_APPLICATION)
		fprintf (out, "APPLICATION,");
	      if (p->type & CONST_EXPLICIT)
		fprintf (out, "EXPLICIT,");
	      if (p->type & CONST_IMPLICIT)
		fprintf (out, "IMPLICIT,");
	      if (p->type & CONST_TAG)
		fprintf (out, "TAG,");
	      if (p->type & CONST_DEFAULT)
		fprintf (out, "DEFAULT,");
	      if (p->type & CONST_TRUE)
		fprintf (out, "TRUE,");
	      if (p->type & CONST_FALSE)
		fprintf (out, "FALSE,");
	      if (p->type & CONST_LIST)
		fprintf (out, "LIST,");
	      if (p->type & CONST_MIN_MAX)
		fprintf (out, "MIN_MAX,");
	      if (p->type & CONST_OPTION)
		fprintf (out, "OPTION,");
	      if (p->type & CONST_1_PARAM)
		fprintf (out, "1_PARAM,");
	      if (p->type & CONST_SIZE)
		fprintf (out, "SIZE,");
	      if (p->type & CONST_DEFINED_BY)
		fprintf (out, "DEF_BY,");
	      if (p->type & CONST_GENERALIZED)
		fprintf (out, "GENERALIZED,");
	      if (p->type & CONST_UTC)
		fprintf (out, "UTC,");
	      if (p->type & CONST_SET)
		fprintf (out, "SET,");
	      if (p->type & CONST_NOT_USED)
		fprintf (out, "NOT_USED,");
	      if (p->type & CONST_ASSIGN)
		fprintf (out, "ASSIGNMENT,");
	    }
	}

      if (mode == ASN1_PRINT_ALL)
	{
	  fprintf (out, "\n");
	}
      else
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_CONSTANT:
	    case TYPE_TAG:
	    case TYPE_SIZE:
	      break;
	    default:
	      fprintf (out, "\n");
	    }
	}

      if (p->down)
	{
	  p = p->down;
	  indent += 2;
	}
      else if (p == root)
	{
	  p = NULL;
	  break;
	}
      else if (p->right)
	p = p->right;
      else
	{
	  while (1)
	    {
	      p = _asn1_find_up (p);
	      if (p == root)
		{
		  p = NULL;
		  break;
		}
	      indent -= 2;
	      if (p->right)
		{
		  p = p->right;
		  break;
		}
	    }
	}
    }
}
asn1_retCode
_asn1_check_identifier (ASN1_TYPE node)
{
  ASN1_TYPE p, p2;
  char name2[ASN1_MAX_NAME_SIZE * 2 + 2];

  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  p = node;
  while (p)
    {
      if (type_field (p->type) == TYPE_IDENTIFIER)
	{
	  _asn1_str_cpy (name2, sizeof (name2), node->name);
	  _asn1_str_cat (name2, sizeof (name2), ".");
	  _asn1_str_cat (name2, sizeof (name2), (char *) p->value);
	  p2 = asn1_find_node (node, name2);
	  if (p2 == NULL)
	    {
	      _asn1_strcpy (_asn1_identifierMissing, p->value);
	      return ASN1_IDENTIFIER_NOT_FOUND;
	    }
	}
      else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
	       (p->type & CONST_DEFAULT))
	{
	  p2 = p->down;
	  if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
	    {
	      _asn1_str_cpy (name2, sizeof (name2), node->name);
	      _asn1_str_cat (name2, sizeof (name2), ".");
	      _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
	      _asn1_strcpy (_asn1_identifierMissing, p2->value);
	      p2 = asn1_find_node (node, name2);
	      if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
		  !(p2->type & CONST_ASSIGN))
		return ASN1_IDENTIFIER_NOT_FOUND;
	      else
		_asn1_identifierMissing[0] = 0;
	    }
	}
      else if ((type_field (p->type) == TYPE_OBJECT_ID) &&
	       (p->type & CONST_ASSIGN))
	{
	  p2 = p->down;
	  if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
	    {
	      if (p2->value && !isdigit (p2->value[0]))
		{
		  _asn1_str_cpy (name2, sizeof (name2), node->name);
		  _asn1_str_cat (name2, sizeof (name2), ".");
		  _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
		  _asn1_strcpy (_asn1_identifierMissing, p2->value);
		  p2 = asn1_find_node (node, name2);
		  if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) ||
		      !(p2->type & CONST_ASSIGN))
		    return ASN1_IDENTIFIER_NOT_FOUND;
		  else
		    _asn1_identifierMissing[0] = 0;
		}
	    }
	}

      if (p->down)
	{
	  p = p->down;
	}
      else if (p->right)
	p = p->right;
      else
	{
	  while (1)
	    {
	      p = _asn1_find_up (p);
	      if (p == node)
		{
		  p = NULL;
		  break;
		}
	      if (p->right)
		{
		  p = p->right;
		  break;
		}
	    }
	}
    }

  return ASN1_SUCCESS;
}
asn1_retCode
_asn1_expand_object_id (ASN1_TYPE node)
{
  ASN1_TYPE p, p2, p3, p4, p5;
  char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1];
  int move, tlen;

  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;

  _asn1_str_cpy (name_root, sizeof (name_root), node->name);

  p = node;
  move = DOWN;

  while (!((p == node) && (move == UP)))
    {
      if (move != UP)
	{
	  if ((type_field (p->type) == TYPE_OBJECT_ID)
	      && (p->type & CONST_ASSIGN))
	    {
	      p2 = p->down;
	      if (p2 && (type_field (p2->type) == TYPE_CONSTANT))
		{
		  if (p2->value && !isdigit (p2->value[0]))
		    {
		      _asn1_str_cpy (name2, sizeof (name2), name_root);
		      _asn1_str_cat (name2, sizeof (name2), ".");
		      _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
		      p3 = asn1_find_node (node, name2);
		      if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
			  !(p3->type & CONST_ASSIGN))
			return ASN1_ELEMENT_NOT_FOUND;
		      _asn1_set_down (p, p2->right);
		      _asn1_remove_node (p2);
		      p2 = p;
		      p4 = p3->down;
		      while (p4)
			{
			  if (type_field (p4->type) == TYPE_CONSTANT)
			    {
			      p5 = _asn1_add_node_only (TYPE_CONSTANT);
			      _asn1_set_name (p5, p4->name);
			      tlen = _asn1_strlen (p4->value);
			      if (tlen > 0)
				_asn1_set_value (p5, p4->value, tlen + 1);
			      if (p2 == p)
				{
				  _asn1_set_right (p5, p->down);
				  _asn1_set_down (p, p5);
				}
			      else
				{
				  _asn1_set_right (p5, p2->right);
				  _asn1_set_right (p2, p5);
				}
			      p2 = p5;
			    }
			  p4 = p4->right;
			}
		      move = DOWN;
		      continue;
		    }
		}
	    }
	  move = DOWN;
	}
      else
	move = RIGHT;

      if (move == DOWN)
	{
	  if (p->down)
	    p = p->down;
	  else
	    move = RIGHT;
	}

      if (p == node)
	{
	  move = UP;
	  continue;
	}

      if (move == RIGHT)
	{
	  if (p->right)
	    p = p->right;
	  else
	    move = UP;
	}
      if (move == UP)
	p = _asn1_find_up (p);
    }


  /*******************************/
  /*       expand DEFAULT        */
  /*******************************/
  p = node;
  move = DOWN;

  while (!((p == node) && (move == UP)))
    {
      if (move != UP)
	{
	  if ((type_field (p->type) == TYPE_OBJECT_ID) &&
	      (p->type & CONST_DEFAULT))
	    {
	      p2 = p->down;
	      if (p2 && (type_field (p2->type) == TYPE_DEFAULT))
		{
		  _asn1_str_cpy (name2, sizeof (name2), name_root);
		  _asn1_str_cat (name2, sizeof (name2), ".");
		  _asn1_str_cat (name2, sizeof (name2), (char *) p2->value);
		  p3 = asn1_find_node (node, name2);
		  if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) ||
		      !(p3->type & CONST_ASSIGN))
		    return ASN1_ELEMENT_NOT_FOUND;
		  p4 = p3->down;
		  name2[0] = 0;
		  while (p4)
		    {
		      if (type_field (p4->type) == TYPE_CONSTANT)
			{
			  if (name2[0])
			    _asn1_str_cat (name2, sizeof (name2), ".");
			  _asn1_str_cat (name2, sizeof (name2),
					 (char *) p4->value);
			}
		      p4 = p4->right;
		    }
		  tlen = strlen (name2);
		  if (tlen > 0)
		    _asn1_set_value (p2, name2, tlen + 1);
		}
	    }
	  move = DOWN;
	}
      else
	move = RIGHT;

      if (move == DOWN)
	{
	  if (p->down)
	    p = p->down;
	  else
	    move = RIGHT;
	}

      if (p == node)
	{
	  move = UP;
	  continue;
	}

      if (move == RIGHT)
	{
	  if (p->right)
	    p = p->right;
	  else
	    move = UP;
	}
      if (move == UP)
	p = _asn1_find_up (p);
    }

  return ASN1_SUCCESS;
}
Exemplo n.º 9
0
/**
 * gnutls_x509_crl_iter_crt_serial:
 * @crl: should contain a #gnutls_x509_crl_t structure
 * @iter: A pointer to an iterator (initially the iterator should be %NULL)
 * @serial: where the serial number will be copied
 * @serial_size: initially holds the size of serial
 * @t: if non null, will hold the time this certificate was revoked
 *
 * This function performs the same as gnutls_x509_crl_get_crt_serial(),
 * but reads sequentially and keeps state in the iterator 
 * between calls. That allows it to provide better performance in sequences 
 * with many elements (50000+).
 *
 * When past the last element is accessed %GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE
 * is returned and the iterator is reset.
 *
 * After use, the iterator must be deinitialized using gnutls_x509_crl_iter_deinit().
 *
 * Returns: On success, %GNUTLS_E_SUCCESS (0) is returned, otherwise a
 *   negative error value.
 **/
int
gnutls_x509_crl_iter_crt_serial(gnutls_x509_crl_t crl,
				gnutls_x509_crl_iter_t *iter,
			        unsigned char *serial,
			        size_t * serial_size, time_t * t)
{

	int result, _serial_size;
	char serial_name[ASN1_MAX_NAME_SIZE];
	char date_name[ASN1_MAX_NAME_SIZE];

	if (crl == NULL || iter == NULL) {
		gnutls_assert();
		return GNUTLS_E_INVALID_REQUEST;
	}

	if (*iter == NULL) {
		*iter = gnutls_calloc(1, sizeof(struct gnutls_x509_crl_iter));
		if (*iter == NULL)
			return gnutls_assert_val(GNUTLS_E_MEMORY_ERROR);
	}

	if ((*iter)->rcache == NULL) {
		(*iter)->rcache = asn1_find_node (crl->crl, "tbsCertList.revokedCertificates.?1");
		(*iter)->rcache_idx = 1;
	} else {
		snprintf(serial_name, sizeof(serial_name),
			 "?%d", (*iter)->rcache_idx);
		(*iter)->rcache = asn1_find_node ((*iter)->rcache, serial_name);
	}
	if ((*iter)->rcache == NULL) {
		/* reset */
		(*iter)->rcache = NULL;
		return gnutls_assert_val(GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE);
	}

	snprintf(serial_name, sizeof(serial_name),
		 "?%d.userCertificate", (*iter)->rcache_idx);

	_serial_size = *serial_size;
	result =
	    asn1_read_value((*iter)->rcache, serial_name, serial, &_serial_size);

	*serial_size = _serial_size;
	if (result != ASN1_SUCCESS) {
		gnutls_assert();
		if (result == ASN1_ELEMENT_NOT_FOUND) {
			/* reset */
			(*iter)->rcache = NULL;
			return GNUTLS_E_REQUESTED_DATA_NOT_AVAILABLE;
		}
		return _gnutls_asn2err(result);
	}

	if (t) {
		snprintf(date_name, sizeof(date_name),
			 "?%d.revocationDate", (*iter)->rcache_idx);
		*t = _gnutls_x509_get_time((*iter)->rcache, date_name, 0);
	}

	(*iter)->rcache_idx++;

	return 0;
}
Exemplo n.º 10
0
/**
 * gnutls_x509_dn_get_rdn_ava:
 * @dn: a pointer to DN
 * @irdn: index of RDN
 * @iava: index of AVA.
 * @ava: Pointer to structure which will hold output information.
 *
 * Get pointers to data within the DN. The format of the @ava structure
 * is shown below.
 *
 *  struct gnutls_x509_ava_st {
 *    gnutls_datum_t oid;
 *    gnutls_datum_t value;
 *    unsigned long value_tag;
 *  };
 *
 * The X.509 distinguished name is a sequence of sequences of strings
 * and this is what the @irdn and @iava indexes model.
 *
 * Note that @ava will contain pointers into the @dn structure which
 * in turns points to the original certificate. Thus you should not
 * modify any data or deallocate any of those.
 *
 * This is a low-level function that requires the caller to do the
 * value conversions when necessary (e.g. from UCS-2).
 *
 * Returns: Returns 0 on success, or an error code.
 **/
int
gnutls_x509_dn_get_rdn_ava(gnutls_x509_dn_t dn,
			   int irdn, int iava, gnutls_x509_ava_st * ava)
{
	ASN1_TYPE rdn, elem;
	ASN1_DATA_NODE vnode;
	long len;
	int lenlen, remlen, ret;
	char rbuf[MAX_NAME_SIZE];
	unsigned char cls;
	const unsigned char *ptr;

	iava++;
	irdn++;			/* 0->1, 1->2 etc */

	snprintf(rbuf, sizeof(rbuf), "rdnSequence.?%d.?%d", irdn, iava);
	rdn = asn1_find_node(dn->asn, rbuf);
	if (!rdn) {
		gnutls_assert();
		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
	}

	snprintf(rbuf, sizeof(rbuf), "?%d.type", iava);
	elem = asn1_find_node(rdn, rbuf);
	if (!elem) {
		gnutls_assert();
		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
	}

	ret = asn1_read_node_value(elem, &vnode);
	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
	}

	ava->oid.data = (void *) vnode.value;
	ava->oid.size = vnode.value_len;

	snprintf(rbuf, sizeof(rbuf), "?%d.value", iava);
	elem = asn1_find_node(rdn, rbuf);
	if (!elem) {
		gnutls_assert();
		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
	}

	ret = asn1_read_node_value(elem, &vnode);
	if (ret != ASN1_SUCCESS) {
		gnutls_assert();
		return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
	}
	/* The value still has the previous tag's length bytes, plus the
	 * current value's tag and length bytes. Decode them.
	 */

	ptr = vnode.value;
	remlen = vnode.value_len;
	len = asn1_get_length_der(ptr, remlen, &lenlen);
	if (len < 0) {
		gnutls_assert();
		return GNUTLS_E_ASN1_DER_ERROR;
	}

	ptr += lenlen;
	remlen -= lenlen;
	ret =
	    asn1_get_tag_der(ptr, remlen, &cls, &lenlen, &ava->value_tag);
	if (ret) {
		gnutls_assert();
		return _gnutls_asn2err(ret);
	}

	ptr += lenlen;
	remlen -= lenlen;

	{
		signed long tmp;

		tmp = asn1_get_length_der(ptr, remlen, &lenlen);
		if (tmp < 0) {
			gnutls_assert();
			return GNUTLS_E_ASN1_DER_ERROR;
		}
		ava->value.size = tmp;
	}
	ava->value.data = (void *) (ptr + lenlen);

	return 0;
}