Report generated at: Sat Sep 25 12:53:01 CEST 2010
| Total number of functions | 98 | 
| Number of low risk functions | 64 | 
| Number of moderate risk functions | 17 | 
| Number of high risk functions | 10 | 
| Number of untestable functions | 7 | 
Used ranges:
| Cyclomatic Complexity | Risk Evaluation | |
| 0 - 10 | Simple module, without much risk | |
| 11 - 20 | More complex module, moderate risk | |
| 21 - 50 | Complex module, high risk | |
| greater than 50 | Untestable module, very high risk | 
| Function Name | Cyclomatic Complexity | Number of Statements | Number of Lines | Source File | |
| ↓ | asn1_der_decoding_element | 155 | 401 | 744 | ../../lib/decoding.c | 
| 
asn1_retCode
asn1_der_decoding_element (ASN1_TYPE * structure, const char *elementName,
			   const void *ider, int len, char *errorDescription)
{
  ASN1_TYPE node, p, p2, p3, nodeFound = ASN1_TYPE_EMPTY;
  char temp[128], currentName[ASN1_MAX_NAME_SIZE * 10], *dot_p, *char_p;
  int nameLen = ASN1_MAX_NAME_SIZE * 10 - 1, state;
  int counter, len2, len3, len4, move, ris, tlen;
  unsigned char class, *temp2;
  unsigned long tag;
  int indefinite, result;
  const unsigned char *der = ider;
  node = *structure;
  if (node == ASN1_TYPE_EMPTY)
    return ASN1_ELEMENT_NOT_FOUND;
  if (elementName == NULL)
    {
      asn1_delete_structure (structure);
      return ASN1_ELEMENT_NOT_FOUND;
    }
  if (node->type & CONST_OPTION)
    {
      asn1_delete_structure (structure);
      return ASN1_GENERIC_ERROR;
    }
  if ((*structure)->name)
    {				/* Has *structure got a name? */
      nameLen -= strlen ((*structure)->name);
      if (nameLen > 0)
	strcpy (currentName, (*structure)->name);
      else
	{
	  asn1_delete_structure (structure);
	  return ASN1_MEM_ERROR;
	}
      if (!(strcmp (currentName, elementName)))
	{
	  state = FOUND;
	  nodeFound = *structure;
	}
      else if (!memcmp (currentName, elementName, strlen (currentName)))
	state = SAME_BRANCH;
      else
	state = OTHER_BRANCH;
    }
  else
    {				/* *structure doesn't have a name? */
      currentName[0] = 0;
      if (elementName[0] == 0)
	{
	  state = FOUND;
	  nodeFound = *structure;
	}
      else
	{
	  state = SAME_BRANCH;
	}
    }
  counter = 0;
  move = DOWN;
  p = node;
  while (1)
    {
      ris = ASN1_SUCCESS;
      if (move != UP)
	{
	  if (p->type & CONST_SET)
	    {
	      p2 = _asn1_find_up (p);
	      len2 = strtol (p2->value, NULL, 10);
	      if (counter == len2)
		{
		  p = p2;
		  move = UP;
		  continue;
		}
	      else if (counter > len2)
		{
		  asn1_delete_structure (structure);
		  return ASN1_DER_ERROR;
		}
	      p2 = p2->down;
	      while (p2)
		{
		  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
		    {
		      if (type_field (p2->type) != TYPE_CHOICE)
			ris =
			  _asn1_extract_tag_der (p2, der + counter,
						 len - counter, &len2);
		      else
			{
			  p3 = p2->down;
			  while (p3)
			    {
			      ris =
				_asn1_extract_tag_der (p3, der + counter,
						       len - counter, &len2);
			      if (ris == ASN1_SUCCESS)
				break;
			      p3 = p3->right;
			    }
			}
		      if (ris == ASN1_SUCCESS)
			{
			  p2->type &= ~CONST_NOT_USED;
			  p = p2;
			  break;
			}
		    }
		  p2 = p2->right;
		}
	      if (p2 == NULL)
		{
		  asn1_delete_structure (structure);
		  return ASN1_DER_ERROR;
		}
	    }
	  if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
	    {
	      p2 = _asn1_find_up (p);
	      len2 = strtol (p2->value, NULL, 10);
	      if (counter == len2)
		{
		  if (p->right)
		    {
		      p2 = p->right;
		      move = RIGHT;
		    }
		  else
		    move = UP;
		  if (p->type & CONST_OPTION)
		    asn1_delete_structure (&p);
		  p = p2;
		  continue;
		}
	    }
	  if (type_field (p->type) == TYPE_CHOICE)
	    {
	      while (p->down)
		{
		  if (counter < len)
		    ris =
		      _asn1_extract_tag_der (p->down, der + counter,
					     len - counter, &len2);
		  else
		    ris = ASN1_DER_ERROR;
		  if (ris == ASN1_SUCCESS)
		    {
		      while (p->down->right)
			{
			  p2 = p->down->right;
			  asn1_delete_structure (&p2);
			}
		      break;
		    }
		  else if (ris == ASN1_ERROR_TYPE_ANY)
		    {
		      asn1_delete_structure (structure);
		      return ASN1_ERROR_TYPE_ANY;
		    }
		  else
		    {
		      p2 = p->down;
		      asn1_delete_structure (&p2);
		    }
		}
	      if (p->down == NULL)
		{
		  if (!(p->type & CONST_OPTION))
		    {
		      asn1_delete_structure (structure);
		      return ASN1_DER_ERROR;
		    }
		}
	      else
		p = p->down;
	    }
	  if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
	    {
	      p2 = _asn1_find_up (p);
	      len2 = strtol (p2->value, NULL, 10);
	      if (counter > len2)
		ris = ASN1_TAG_ERROR;
	    }
	  if (ris == ASN1_SUCCESS)
	    ris =
	      _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
	  if (ris != ASN1_SUCCESS)
	    {
	      if (p->type & CONST_OPTION)
		{
		  p->type |= CONST_NOT_USED;
		  move = RIGHT;
		}
	      else if (p->type & CONST_DEFAULT)
		{
		  _asn1_set_value (p, NULL, 0);
		  move = RIGHT;
		}
	      else
		{
		  if (errorDescription != NULL)
		    _asn1_error_description_tag_error (p, errorDescription);
		  asn1_delete_structure (structure);
		  return ASN1_TAG_ERROR;
		}
	    }
	  else
	    counter += len2;
	}
      if (ris == ASN1_SUCCESS)
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_NULL:
	      if (der[counter])
		{
		  asn1_delete_structure (structure);
		  return ASN1_DER_ERROR;
		}
	      if (p == nodeFound)
		state = EXIT;
	      counter++;
	      move = RIGHT;
	      break;
	    case TYPE_BOOLEAN:
	      if (der[counter++] != 1)
		{
		  asn1_delete_structure (structure);
		  return ASN1_DER_ERROR;
		}
	      if (state == FOUND)
		{
		  if (der[counter++] == 0)
		    _asn1_set_value (p, "F", 1);
		  else
		    _asn1_set_value (p, "T", 1);
		  if (p == nodeFound)
		    state = EXIT;
		}
	      else
		counter++;
	      move = RIGHT;
	      break;
	    case TYPE_INTEGER:
	    case TYPE_ENUMERATED:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      if (state == FOUND)
		{
		  if (len3 + len2 > len - counter)
		    return ASN1_DER_ERROR;
		  _asn1_set_value (p, der + counter, len3 + len2);
		  if (p == nodeFound)
		    state = EXIT;
		}
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case TYPE_OBJECT_ID:
	      if (state == FOUND)
		{
		  result =
		    _asn1_get_objectid_der (der + counter, len - counter,
					    &len2, temp, sizeof (temp));
		  if (result != ASN1_SUCCESS)
		    {
		      return result;
		    }
		  tlen = strlen (temp);
		  if (tlen > 0)
		    _asn1_set_value (p, temp, tlen + 1);
		  if (p == nodeFound)
		    state = EXIT;
		}
	      else
		{
		  len2 =
		    asn1_get_length_der (der + counter, len - counter, &len3);
		  if (len2 < 0)
		    return ASN1_DER_ERROR;
		  len2 += len3;
		}
	      counter += len2;
	      move = RIGHT;
	      break;
	    case TYPE_TIME:
	      if (state == FOUND)
		{
		  result =
		    _asn1_get_time_der (der + counter, len - counter, &len2,
					temp, sizeof (temp) - 1);
		  if (result != ASN1_SUCCESS)
		    {
		      asn1_delete_structure (structure);
		      return result;
		    }
		  tlen = strlen (temp);
		  if (tlen > 0)
		    _asn1_set_value (p, temp, tlen + 1);
		  if (p == nodeFound)
		    state = EXIT;
		}
	      else
		{
		  len2 =
		    asn1_get_length_der (der + counter, len - counter, &len3);
		  if (len2 < 0)
		    return ASN1_DER_ERROR;
		  len2 += len3;
		}
	      counter += len2;
	      move = RIGHT;
	      break;
	    case TYPE_OCTET_STRING:
	      len3 = len - counter;
	      if (state == FOUND)
		{
		  ris = _asn1_get_octet_string (der + counter, p, &len3);
		  if (p == nodeFound)
		    state = EXIT;
		}
	      else
		ris = _asn1_get_octet_string (der + counter, NULL, &len3);
	      if (ris != ASN1_SUCCESS)
		return ris;
	      counter += len3;
	      move = RIGHT;
	      break;
	    case TYPE_GENERALSTRING:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      if (state == FOUND)
		{
		  if (len3 + len2 > len - counter)
		    return ASN1_DER_ERROR;
		  _asn1_set_value (p, der + counter, len3 + len2);
		  if (p == nodeFound)
		    state = EXIT;
		}
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case TYPE_BIT_STRING:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      if (state == FOUND)
		{
		  if (len3 + len2 > len - counter)
		    return ASN1_DER_ERROR;
		  _asn1_set_value (p, der + counter, len3 + len2);
		  if (p == nodeFound)
		    state = EXIT;
		}
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case TYPE_SEQUENCE:
	    case TYPE_SET:
	      if (move == UP)
		{
		  len2 = strtol (p->value, NULL, 10);
		  _asn1_set_value (p, NULL, 0);
		  if (len2 == -1)
		    {		/* indefinite length method */
		      if ((der[counter]) || der[counter + 1])
			{
			  asn1_delete_structure (structure);
			  return ASN1_DER_ERROR;
			}
		      counter += 2;
		    }
		  else
		    {		/* definite length method */
		      if (len2 != counter)
			{
			  asn1_delete_structure (structure);
			  return ASN1_DER_ERROR;
			}
		    }
		  if (p == nodeFound)
		    state = EXIT;
		  move = RIGHT;
		}
	      else
		{		/* move==DOWN || move==RIGHT */
		  if (state == OTHER_BRANCH)
		    {
		      len3 =
			asn1_get_length_der (der + counter, len - counter,
					     &len2);
		      if (len3 < 0)
			return ASN1_DER_ERROR;
		      counter += len2 + len3;
		      move = RIGHT;
		    }
		  else
		    {		/*  state==SAME_BRANCH or state==FOUND */
		      len3 =
			asn1_get_length_der (der + counter, len - counter,
					     &len2);
		      if (len3 < 0)
			return ASN1_DER_ERROR;
		      counter += len2;
		      if (len3 > 0)
			{
			  _asn1_ltostr (counter + len3, temp);
			  tlen = strlen (temp);
			  if (tlen > 0)
			    _asn1_set_value (p, temp, tlen + 1);
			  move = DOWN;
			}
		      else if (len3 == 0)
			{
			  p2 = p->down;
			  while (p2)
			    {
			      if (type_field (p2->type) != TYPE_TAG)
				{
				  p3 = p2->right;
				  asn1_delete_structure (&p2);
				  p2 = p3;
				}
			      else
				p2 = p2->right;
			    }
			  move = RIGHT;
			}
		      else
			{	/* indefinite length method */
			  _asn1_set_value (p, "-1", 3);
			  move = DOWN;
			}
		    }
		}
	      break;
	    case TYPE_SEQUENCE_OF:
	    case TYPE_SET_OF:
	      if (move == UP)
		{
		  len2 = strtol (p->value, NULL, 10);
		  if (len2 > counter)
		    {
		      _asn1_append_sequence_set (p);
		      p = p->down;
		      while (p->right)
			p = p->right;
		      move = RIGHT;
		      continue;
		    }
		  _asn1_set_value (p, NULL, 0);
		  if (len2 != counter)
		    {
		      asn1_delete_structure (structure);
		      return ASN1_DER_ERROR;
		    }
		  if (p == nodeFound)
		    state = EXIT;
		}
	      else
		{		/* move==DOWN || move==RIGHT */
		  if (state == OTHER_BRANCH)
		    {
		      len3 =
			asn1_get_length_der (der + counter, len - counter,
					     &len2);
		      if (len3 < 0)
			return ASN1_DER_ERROR;
		      counter += len2 + len3;
		      move = RIGHT;
		    }
		  else
		    {		/* state==FOUND or state==SAME_BRANCH */
		      len3 =
			asn1_get_length_der (der + counter, len - counter,
					     &len2);
		      if (len3 < 0)
			return ASN1_DER_ERROR;
		      counter += len2;
		      if (len3)
			{
			  _asn1_ltostr (counter + len3, temp);
			  tlen = strlen (temp);
			  if (tlen > 0)
			    _asn1_set_value (p, temp, tlen + 1);
			  p2 = p->down;
			  while ((type_field (p2->type) == TYPE_TAG)
				 || (type_field (p2->type) == TYPE_SIZE))
			    p2 = p2->right;
			  if (p2->right == NULL)
			    _asn1_append_sequence_set (p);
			  p = p2;
			  state = FOUND;
			}
		    }
		}
	      break;
	    case TYPE_ANY:
	      if (asn1_get_tag_der
		  (der + counter, len - counter, &class, &len2,
		   &tag) != ASN1_SUCCESS)
		return ASN1_DER_ERROR;
	      if (counter + len2 > len)
		return ASN1_DER_ERROR;
	      len4 =
		asn1_get_length_der (der + counter + len2,
				     len - counter - len2, &len3);
	      if (len4 < -1)
		return ASN1_DER_ERROR;
	      if (len4 != -1)
		{
		  len2 += len4;
		  if (state == FOUND)
		    {
		      _asn1_set_value_octet (p, der + counter, len2 + len3);
		      temp2 = NULL;
		      if (p == nodeFound)
			state = EXIT;
		    }
		  counter += len2 + len3;
		}
	      else
		{		/* indefinite length */
		  /* Check indefinite lenth method in an EXPLICIT TAG */
		  if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
		    indefinite = 1;
		  else
		    indefinite = 0;
		  len2 = len - counter;
		  ris =
		    _asn1_get_indefinite_length_string (der + counter, &len2);
		  if (ris != ASN1_SUCCESS)
		    {
		      asn1_delete_structure (structure);
		      return ris;
		    }
		  if (state == FOUND)
		    {
		      _asn1_set_value_octet (p, der + counter, len2);
		      if (p == nodeFound)
			state = EXIT;
		    }
		  counter += len2;
		  /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
		     an indefinite length method. */
		  if (indefinite)
		    {
		      if (!der[counter] && !der[counter + 1])
			{
			  counter += 2;
			}
		      else
			{
			  asn1_delete_structure (structure);
			  return ASN1_DER_ERROR;
			}
		    }
		}
	      move = RIGHT;
	      break;
	    default:
	      move = (move == UP) ? RIGHT : DOWN;
	      break;
	    }
	}
      if ((p == node && move != DOWN) || (state == EXIT))
	break;
      if (move == DOWN)
	{
	  if (p->down)
	    {
	      p = p->down;
	      if (state != FOUND)
		{
		  nameLen -= strlen (p->name) + 1;
		  if (nameLen > 0)
		    {
		      if (currentName[0])
			strcat (currentName, ".");
		      strcat (currentName, p->name);
		    }
		  else
		    {
		      asn1_delete_structure (structure);
		      return ASN1_MEM_ERROR;
		    }
		  if (!(strcmp (currentName, elementName)))
		    {
		      state = FOUND;
		      nodeFound = p;
		    }
		  else
		    if (!memcmp
			(currentName, elementName, strlen (currentName)))
		    state = SAME_BRANCH;
		  else
		    state = OTHER_BRANCH;
		}
	    }
	  else
	    move = RIGHT;
	}
      if ((move == RIGHT) && !(p->type & CONST_SET))
	{
	  if (p->right)
	    {
	      p = p->right;
	      if (state != FOUND)
		{
		  dot_p = char_p = currentName;
		  while ((char_p = strchr (char_p, '.')))
		    {
		      dot_p = char_p++;
		      dot_p++;
		    }
		  nameLen += strlen (currentName) - (dot_p - currentName);
		  *dot_p = 0;
		  nameLen -= strlen (p->name);
		  if (nameLen > 0)
		    strcat (currentName, p->name);
		  else
		    {
		      asn1_delete_structure (structure);
		      return ASN1_MEM_ERROR;
		    }
		  if (!(strcmp (currentName, elementName)))
		    {
		      state = FOUND;
		      nodeFound = p;
		    }
		  else
		    if (!memcmp
			(currentName, elementName, strlen (currentName)))
		    state = SAME_BRANCH;
		  else
		    state = OTHER_BRANCH;
		}
	    }
	  else
	    move = UP;
	}
      if (move == UP)
	{
	  p = _asn1_find_up (p);
	  if (state != FOUND)
	    {
	      dot_p = char_p = currentName;
	      while ((char_p = strchr (char_p, '.')))
		{
		  dot_p = char_p++;
		  dot_p++;
		}
	      nameLen += strlen (currentName) - (dot_p - currentName);
	      *dot_p = 0;
	      if (!(strcmp (currentName, elementName)))
		{
		  state = FOUND;
		  nodeFound = p;
		}
	      else
		if (!memcmp (currentName, elementName, strlen (currentName)))
		state = SAME_BRANCH;
	      else
		state = OTHER_BRANCH;
	    }
	}
    }
  _asn1_delete_not_used (*structure);
  if (counter > len)
    {
      asn1_delete_structure (structure);
      return ASN1_DER_ERROR;
    }
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | asn1_der_decoding | 119 | 304 | 527 | ../../lib/decoding.c | 
| 
asn1_retCode
asn1_der_decoding (ASN1_TYPE * element, const void *ider, int len,
		   char *errorDescription)
{
  ASN1_TYPE node, p, p2, p3;
  char temp[128];
  int counter, len2, len3, len4, move, ris, tlen;
  unsigned char class;
  unsigned long tag;
  int indefinite, result;
  const unsigned char *der = ider;
  node = *element;
  if (node == ASN1_TYPE_EMPTY)
    return ASN1_ELEMENT_NOT_FOUND;
  if (node->type & CONST_OPTION)
    {
      asn1_delete_structure (element);
      return ASN1_GENERIC_ERROR;
    }
  counter = 0;
  move = DOWN;
  p = node;
  while (1)
    {
      ris = ASN1_SUCCESS;
      if (move != UP)
	{
	  if (p->type & CONST_SET)
	    {
	      p2 = _asn1_find_up (p);
	      len2 = strtol (p2->value, NULL, 10);
	      if (len2 == -1)
		{
		  if (!der[counter] && !der[counter + 1])
		    {
		      p = p2;
		      move = UP;
		      counter += 2;
		      continue;
		    }
		}
	      else if (counter == len2)
		{
		  p = p2;
		  move = UP;
		  continue;
		}
	      else if (counter > len2)
		{
		  asn1_delete_structure (element);
		  return ASN1_DER_ERROR;
		}
	      p2 = p2->down;
	      while (p2)
		{
		  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
		    {
		      if (type_field (p2->type) != TYPE_CHOICE)
			ris =
			  _asn1_extract_tag_der (p2, der + counter,
						 len - counter, &len2);
		      else
			{
			  p3 = p2->down;
			  while (p3)
			    {
			      ris =
				_asn1_extract_tag_der (p3, der + counter,
						       len - counter, &len2);
			      if (ris == ASN1_SUCCESS)
				break;
			      p3 = p3->right;
			    }
			}
		      if (ris == ASN1_SUCCESS)
			{
			  p2->type &= ~CONST_NOT_USED;
			  p = p2;
			  break;
			}
		    }
		  p2 = p2->right;
		}
	      if (p2 == NULL)
		{
		  asn1_delete_structure (element);
		  return ASN1_DER_ERROR;
		}
	    }
	  if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
	    {
	      p2 = _asn1_find_up (p);
	      len2 = strtol (p2->value, NULL, 10);
	      if (counter == len2)
		{
		  if (p->right)
		    {
		      p2 = p->right;
		      move = RIGHT;
		    }
		  else
		    move = UP;
		  if (p->type & CONST_OPTION)
		    asn1_delete_structure (&p);
		  p = p2;
		  continue;
		}
	    }
	  if (type_field (p->type) == TYPE_CHOICE)
	    {
	      while (p->down)
		{
		  if (counter < len)
		    ris =
		      _asn1_extract_tag_der (p->down, der + counter,
					     len - counter, &len2);
		  else
		    ris = ASN1_DER_ERROR;
		  if (ris == ASN1_SUCCESS)
		    {
		      while (p->down->right)
			{
			  p2 = p->down->right;
			  asn1_delete_structure (&p2);
			}
		      break;
		    }
		  else if (ris == ASN1_ERROR_TYPE_ANY)
		    {
		      asn1_delete_structure (element);
		      return ASN1_ERROR_TYPE_ANY;
		    }
		  else
		    {
		      p2 = p->down;
		      asn1_delete_structure (&p2);
		    }
		}
	      if (p->down == NULL)
		{
		  if (!(p->type & CONST_OPTION))
		    {
		      asn1_delete_structure (element);
		      return ASN1_DER_ERROR;
		    }
		}
	      else
		p = p->down;
	    }
	  if ((p->type & CONST_OPTION) || (p->type & CONST_DEFAULT))
	    {
	      p2 = _asn1_find_up (p);
	      len2 = strtol (p2->value, NULL, 10);
	      if ((len2 != -1) && (counter > len2))
		ris = ASN1_TAG_ERROR;
	    }
	  if (ris == ASN1_SUCCESS)
	    ris =
	      _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
	  if (ris != ASN1_SUCCESS)
	    {
	      if (p->type & CONST_OPTION)
		{
		  p->type |= CONST_NOT_USED;
		  move = RIGHT;
		}
	      else if (p->type & CONST_DEFAULT)
		{
		  _asn1_set_value (p, NULL, 0);
		  move = RIGHT;
		}
	      else
		{
		  if (errorDescription != NULL)
		    _asn1_error_description_tag_error (p, errorDescription);
		  asn1_delete_structure (element);
		  return ASN1_TAG_ERROR;
		}
	    }
	  else
	    counter += len2;
	}
      if (ris == ASN1_SUCCESS)
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_NULL:
	      if (der[counter])
		{
		  asn1_delete_structure (element);
		  return ASN1_DER_ERROR;
		}
	      counter++;
	      move = RIGHT;
	      break;
	    case TYPE_BOOLEAN:
	      if (der[counter++] != 1)
		{
		  asn1_delete_structure (element);
		  return ASN1_DER_ERROR;
		}
	      if (der[counter++] == 0)
		_asn1_set_value (p, "F", 1);
	      else
		_asn1_set_value (p, "T", 1);
	      move = RIGHT;
	      break;
	    case TYPE_INTEGER:
	    case TYPE_ENUMERATED:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      if (len2 + len3 > len - counter)
		return ASN1_DER_ERROR;
	      _asn1_set_value (p, der + counter, len3 + len2);
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case TYPE_OBJECT_ID:
	      result =
		_asn1_get_objectid_der (der + counter, len - counter, &len2,
					temp, sizeof (temp));
	      if (result != ASN1_SUCCESS)
		{
		  asn1_delete_structure (element);
		  return result;
		}
	      tlen = strlen (temp);
	      if (tlen > 0)
		_asn1_set_value (p, temp, tlen + 1);
	      counter += len2;
	      move = RIGHT;
	      break;
	    case TYPE_TIME:
	      result =
		_asn1_get_time_der (der + counter, len - counter, &len2, temp,
				    sizeof (temp) - 1);
	      if (result != ASN1_SUCCESS)
		{
		  asn1_delete_structure (element);
		  return result;
		}
	      tlen = strlen (temp);
	      if (tlen > 0)
		_asn1_set_value (p, temp, tlen + 1);
	      counter += len2;
	      move = RIGHT;
	      break;
	    case TYPE_OCTET_STRING:
	      len3 = len - counter;
	      ris = _asn1_get_octet_string (der + counter, p, &len3);
	      if (ris != ASN1_SUCCESS)
		return ris;
	      counter += len3;
	      move = RIGHT;
	      break;
	    case TYPE_GENERALSTRING:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      if (len3 + len2 > len - counter)
		return ASN1_DER_ERROR;
	      _asn1_set_value (p, der + counter, len3 + len2);
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case TYPE_BIT_STRING:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      if (len3 + len2 > len - counter)
		return ASN1_DER_ERROR;
	      _asn1_set_value (p, der + counter, len3 + len2);
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case TYPE_SEQUENCE:
	    case TYPE_SET:
	      if (move == UP)
		{
		  len2 = strtol (p->value, NULL, 10);
		  _asn1_set_value (p, NULL, 0);
		  if (len2 == -1)
		    {		/* indefinite length method */
		      if (len - counter + 1 > 0)
			{
			  if ((der[counter]) || der[counter + 1])
			    {
			      asn1_delete_structure (element);
			      return ASN1_DER_ERROR;
			    }
			}
		      else
			return ASN1_DER_ERROR;
		      counter += 2;
		    }
		  else
		    {		/* definite length method */
		      if (len2 != counter)
			{
			  asn1_delete_structure (element);
			  return ASN1_DER_ERROR;
			}
		    }
		  move = RIGHT;
		}
	      else
		{		/* move==DOWN || move==RIGHT */
		  len3 =
		    asn1_get_length_der (der + counter, len - counter, &len2);
		  if (len3 < -1)
		    return ASN1_DER_ERROR;
		  counter += len2;
		  if (len3 > 0)
		    {
		      _asn1_ltostr (counter + len3, temp);
		      tlen = strlen (temp);
		      if (tlen > 0)
			_asn1_set_value (p, temp, tlen + 1);
		      move = DOWN;
		    }
		  else if (len3 == 0)
		    {
		      p2 = p->down;
		      while (p2)
			{
			  if (type_field (p2->type) != TYPE_TAG)
			    {
			      p3 = p2->right;
			      asn1_delete_structure (&p2);
			      p2 = p3;
			    }
			  else
			    p2 = p2->right;
			}
		      move = RIGHT;
		    }
		  else
		    {		/* indefinite length method */
		      _asn1_set_value (p, "-1", 3);
		      move = DOWN;
		    }
		}
	      break;
	    case TYPE_SEQUENCE_OF:
	    case TYPE_SET_OF:
	      if (move == UP)
		{
		  len2 = strtol (p->value, NULL, 10);
		  if (len2 == -1)
		    {		/* indefinite length method */
		      if ((counter + 2) > len)
			return ASN1_DER_ERROR;
		      if ((der[counter]) || der[counter + 1])
			{
			  _asn1_append_sequence_set (p);
			  p = p->down;
			  while (p->right)
			    p = p->right;
			  move = RIGHT;
			  continue;
			}
		      _asn1_set_value (p, NULL, 0);
		      counter += 2;
		    }
		  else
		    {		/* definite length method */
		      if (len2 > counter)
			{
			  _asn1_append_sequence_set (p);
			  p = p->down;
			  while (p->right)
			    p = p->right;
			  move = RIGHT;
			  continue;
			}
		      _asn1_set_value (p, NULL, 0);
		      if (len2 != counter)
			{
			  asn1_delete_structure (element);
			  return ASN1_DER_ERROR;
			}
		    }
		}
	      else
		{		/* move==DOWN || move==RIGHT */
		  len3 =
		    asn1_get_length_der (der + counter, len - counter, &len2);
		  if (len3 < -1)
		    return ASN1_DER_ERROR;
		  counter += len2;
		  if (len3)
		    {
		      if (len3 > 0)
			{	/* definite length method */
			  _asn1_ltostr (counter + len3, temp);
			  tlen = strlen (temp);
			  if (tlen > 0)
			    _asn1_set_value (p, temp, tlen + 1);
			}
		      else
			{	/* indefinite length method */
			  _asn1_set_value (p, "-1", 3);
			}
		      p2 = p->down;
		      while ((type_field (p2->type) == TYPE_TAG)
			     || (type_field (p2->type) == TYPE_SIZE))
			p2 = p2->right;
		      if (p2->right == NULL)
			_asn1_append_sequence_set (p);
		      p = p2;
		    }
		}
	      move = RIGHT;
	      break;
	    case TYPE_ANY:
	      if (asn1_get_tag_der
		  (der + counter, len - counter, &class, &len2,
		   &tag) != ASN1_SUCCESS)
		return ASN1_DER_ERROR;
	      if (counter + len2 > len)
		return ASN1_DER_ERROR;
	      len4 =
		asn1_get_length_der (der + counter + len2,
				     len - counter - len2, &len3);
	      if (len4 < -1)
		return ASN1_DER_ERROR;
	      if (len4 > len - counter + len2 + len3)
		return ASN1_DER_ERROR;
	      if (len4 != -1)
		{
		  len2 += len4;
		  _asn1_set_value_octet (p, der + counter, len2 + len3);
		  counter += len2 + len3;
		}
	      else
		{		/* indefinite length */
		  /* Check indefinite lenth method in an EXPLICIT TAG */
		  if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
		    indefinite = 1;
		  else
		    indefinite = 0;
		  len2 = len - counter;
		  ris =
		    _asn1_get_indefinite_length_string (der + counter, &len2);
		  if (ris != ASN1_SUCCESS)
		    {
		      asn1_delete_structure (element);
		      return ris;
		    }
		  _asn1_set_value_octet (p, der + counter, len2);
		  counter += len2;
		  /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
		     an indefinite length method. */
		  if (indefinite)
		    {
		      if (!der[counter] && !der[counter + 1])
			{
			  counter += 2;
			}
		      else
			{
			  asn1_delete_structure (element);
			  return ASN1_DER_ERROR;
			}
		    }
		}
	      move = RIGHT;
	      break;
	    default:
	      move = (move == UP) ? RIGHT : DOWN;
	      break;
	    }
	}
      if (p == node && move != DOWN)
	break;
      if (move == DOWN)
	{
	  if (p->down)
	    p = p->down;
	  else
	    move = RIGHT;
	}
      if ((move == RIGHT) && !(p->type & CONST_SET))
	{
	  if (p->right)
	    p = p->right;
	  else
	    move = UP;
	}
      if (move == UP)
	p = _asn1_find_up (p);
    }
  _asn1_delete_not_used (*element);
  if (counter != len)
    {
      asn1_delete_structure (element);
      return ASN1_DER_ERROR;
    }
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | asn1_write_value | 111 | 208 | 343 | ../../lib/element.c | 
| 
asn1_retCode
asn1_write_value (ASN1_TYPE node_root, const char *name,
		  const void *ivalue, int len)
{
  ASN1_TYPE node, p, p2;
  unsigned char *temp, *value_temp = NULL, *default_temp = NULL;
  int len2, k, k2, negative;
  size_t i;
  const unsigned char *value = ivalue;
  node = asn1_find_node (node_root, name);
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  if ((node->type & CONST_OPTION) && (value == NULL) && (len == 0))
    {
      asn1_delete_structure (&node);
      return ASN1_SUCCESS;
    }
  if ((type_field (node->type) == TYPE_SEQUENCE_OF) && (value == NULL)
      && (len == 0))
    {
      p = node->down;
      while ((type_field (p->type) == TYPE_TAG)
	     || (type_field (p->type) == TYPE_SIZE))
	p = p->right;
      while (p->right)
	asn1_delete_structure (&p->right);
      return ASN1_SUCCESS;
    }
  switch (type_field (node->type))
    {
    case TYPE_BOOLEAN:
      if (!strcmp (value, "TRUE"))
	{
	  if (node->type & CONST_DEFAULT)
	    {
	      p = node->down;
	      while (type_field (p->type) != TYPE_DEFAULT)
		p = p->right;
	      if (p->type & CONST_TRUE)
		_asn1_set_value (node, NULL, 0);
	      else
		_asn1_set_value (node, "T", 1);
	    }
	  else
	    _asn1_set_value (node, "T", 1);
	}
      else if (!strcmp (value, "FALSE"))
	{
	  if (node->type & CONST_DEFAULT)
	    {
	      p = node->down;
	      while (type_field (p->type) != TYPE_DEFAULT)
		p = p->right;
	      if (p->type & CONST_FALSE)
		_asn1_set_value (node, NULL, 0);
	      else
		_asn1_set_value (node, "F", 1);
	    }
	  else
	    _asn1_set_value (node, "F", 1);
	}
      else
	return ASN1_VALUE_NOT_VALID;
      break;
    case TYPE_INTEGER:
    case TYPE_ENUMERATED:
      if (len == 0)
	{
	  if ((isdigit (value[0])) || (value[0] == '-'))
	    {
	      value_temp =
		(unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
	      if (value_temp == NULL)
		return ASN1_MEM_ALLOC_ERROR;
	      _asn1_convert_integer (value, value_temp,
				     SIZEOF_UNSIGNED_LONG_INT, &len);
	    }
	  else
	    {			/* is an identifier like v1 */
	      if (!(node->type & CONST_LIST))
		return ASN1_VALUE_NOT_VALID;
	      p = node->down;
	      while (p)
		{
		  if (type_field (p->type) == TYPE_CONSTANT)
		    {
		      if ((p->name) && (!strcmp (p->name, value)))
			{
			  value_temp =
			    (unsigned char *)
			    _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
			  if (value_temp == NULL)
			    return ASN1_MEM_ALLOC_ERROR;
			  _asn1_convert_integer (p->value,
						 value_temp,
						 SIZEOF_UNSIGNED_LONG_INT,
						 &len);
			  break;
			}
		    }
		  p = p->right;
		}
	      if (p == NULL)
		return ASN1_VALUE_NOT_VALID;
	    }
	}
      else
	{			/* len != 0 */
	  value_temp = (unsigned char *) _asn1_malloc (len);
	  if (value_temp == NULL)
	    return ASN1_MEM_ALLOC_ERROR;
	  memcpy (value_temp, value, len);
	}
      if (value_temp[0] & 0x80)
	negative = 1;
      else
	negative = 0;
      if (negative && (type_field (node->type) == TYPE_ENUMERATED))
	{
	  _asn1_free (value_temp);
	  return ASN1_VALUE_NOT_VALID;
	}
      for (k = 0; k < len - 1; k++)
	if (negative && (value_temp[k] != 0xFF))
	  break;
	else if (!negative && value_temp[k])
	  break;
      if ((negative && !(value_temp[k] & 0x80)) ||
	  (!negative && (value_temp[k] & 0x80)))
	k--;
      _asn1_set_value_octet (node, value_temp + k, len - k);
      if (node->type & CONST_DEFAULT)
	{
	  p = node->down;
	  while (type_field (p->type) != TYPE_DEFAULT)
	    p = p->right;
	  if ((isdigit (p->value[0])) || (p->value[0] == '-'))
	    {
	      default_temp =
		(unsigned char *) _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
	      if (default_temp == NULL)
		{
		  _asn1_free (value_temp);
		  return ASN1_MEM_ALLOC_ERROR;
		}
	      _asn1_convert_integer (p->value, default_temp,
				     SIZEOF_UNSIGNED_LONG_INT, &len2);
	    }
	  else
	    {			/* is an identifier like v1 */
	      if (!(node->type & CONST_LIST))
		{
		  _asn1_free (value_temp);
		  return ASN1_VALUE_NOT_VALID;
		}
	      p2 = node->down;
	      while (p2)
		{
		  if (type_field (p2->type) == TYPE_CONSTANT)
		    {
		      if ((p2->name) && (!strcmp (p2->name, p->value)))
			{
			  default_temp =
			    (unsigned char *)
			    _asn1_malloc (SIZEOF_UNSIGNED_LONG_INT);
			  if (default_temp == NULL)
			    {
			      _asn1_free (value_temp);
			      return ASN1_MEM_ALLOC_ERROR;
			    }
			  _asn1_convert_integer (p2->value,
						 default_temp,
						 SIZEOF_UNSIGNED_LONG_INT,
						 &len2);
			  break;
			}
		    }
		  p2 = p2->right;
		}
	      if (p2 == NULL)
		{
		  _asn1_free (value_temp);
		  return ASN1_VALUE_NOT_VALID;
		}
	    }
	  if ((len - k) == len2)
	    {
	      for (k2 = 0; k2 < len2; k2++)
		if (value_temp[k + k2] != default_temp[k2])
		  {
		    break;
		  }
	      if (k2 == len2)
		_asn1_set_value (node, NULL, 0);
	    }
	  _asn1_free (default_temp);
	}
      _asn1_free (value_temp);
      break;
    case TYPE_OBJECT_ID:
      for (i = 0; i < strlen (value); i++)
	if ((!isdigit (value[i])) && (value[i] != '.') && (value[i] != '+'))
	  return ASN1_VALUE_NOT_VALID;
      if (node->type & CONST_DEFAULT)
	{
	  p = node->down;
	  while (type_field (p->type) != TYPE_DEFAULT)
	    p = p->right;
	  if (!strcmp (value, p->value))
	    {
	      _asn1_set_value (node, NULL, 0);
	      break;
	    }
	}
      _asn1_set_value (node, value, strlen (value) + 1);
      break;
    case TYPE_TIME:
      if (node->type & CONST_UTC)
	{
	  if (strlen (value) < 11)
	    return ASN1_VALUE_NOT_VALID;
	  for (k = 0; k < 10; k++)
	    if (!isdigit (value[k]))
	      return ASN1_VALUE_NOT_VALID;
	  switch (strlen (value))
	    {
	    case 11:
	      if (value[10] != 'Z')
		return ASN1_VALUE_NOT_VALID;
	      break;
	    case 13:
	      if ((!isdigit (value[10])) || (!isdigit (value[11])) ||
		  (value[12] != 'Z'))
		return ASN1_VALUE_NOT_VALID;
	      break;
	    case 15:
	      if ((value[10] != '+') && (value[10] != '-'))
		return ASN1_VALUE_NOT_VALID;
	      for (k = 11; k < 15; k++)
		if (!isdigit (value[k]))
		  return ASN1_VALUE_NOT_VALID;
	      break;
	    case 17:
	      if ((!isdigit (value[10])) || (!isdigit (value[11])))
		return ASN1_VALUE_NOT_VALID;
	      if ((value[12] != '+') && (value[12] != '-'))
		return ASN1_VALUE_NOT_VALID;
	      for (k = 13; k < 17; k++)
		if (!isdigit (value[k]))
		  return ASN1_VALUE_NOT_VALID;
	      break;
	    default:
	      return ASN1_VALUE_NOT_FOUND;
	    }
	  _asn1_set_value (node, value, strlen (value) + 1);
	}
      else
	{			/* GENERALIZED TIME */
	  if (value)
	    _asn1_set_value (node, value, strlen (value) + 1);
	}
      break;
    case TYPE_OCTET_STRING:
      if (len == 0)
	len = strlen (value);
      _asn1_set_value_octet (node, value, len);
      break;
    case TYPE_GENERALSTRING:
      if (len == 0)
	len = strlen (value);
      _asn1_set_value_octet (node, value, len);
      break;
    case TYPE_BIT_STRING:
      if (len == 0)
	len = strlen (value);
      asn1_length_der ((len >> 3) + 2, NULL, &len2);
      temp = (unsigned char *) _asn1_malloc ((len >> 3) + 2 + len2);
      if (temp == NULL)
	return ASN1_MEM_ALLOC_ERROR;
      asn1_bit_der (value, len, temp, &len2);
      _asn1_set_value_m (node, temp, len2);
      temp = NULL;
      break;
    case TYPE_CHOICE:
      p = node->down;
      while (p)
	{
	  if (!strcmp (p->name, value))
	    {
	      p2 = node->down;
	      while (p2)
		{
		  if (p2 != p)
		    {
		      asn1_delete_structure (&p2);
		      p2 = node->down;
		    }
		  else
		    p2 = p2->right;
		}
	      break;
	    }
	  p = p->right;
	}
      if (!p)
	return ASN1_ELEMENT_NOT_FOUND;
      break;
    case TYPE_ANY:
      _asn1_set_value_octet (node, value, len);
      break;
    case TYPE_SEQUENCE_OF:
    case TYPE_SET_OF:
      if (strcmp (value, "NEW"))
	return ASN1_VALUE_NOT_VALID;
      _asn1_append_sequence_set (node);
      break;
    default:
      return ASN1_ELEMENT_NOT_FOUND;
      break;
    }
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | asn1_print_structure | 125 | 235 | 349 | ../../lib/structure.c | 
| 
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_der_decoding_startEnd | 85 | 188 | 320 | ../../lib/decoding.c | 
| 
asn1_retCode
asn1_der_decoding_startEnd (ASN1_TYPE element, const void *ider, int len,
			    const char *name_element, int *start, int *end)
{
  ASN1_TYPE node, node_to_find, p, p2, p3;
  int counter, len2, len3, len4, move, ris;
  unsigned char class;
  unsigned long tag;
  int indefinite;
  const unsigned char *der = ider;
  node = element;
  if (node == ASN1_TYPE_EMPTY)
    return ASN1_ELEMENT_NOT_FOUND;
  node_to_find = asn1_find_node (node, name_element);
  if (node_to_find == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  if (node_to_find == node)
    {
      *start = 0;
      *end = len - 1;
      return ASN1_SUCCESS;
    }
  if (node->type & CONST_OPTION)
    return ASN1_GENERIC_ERROR;
  counter = 0;
  move = DOWN;
  p = node;
  while (1)
    {
      ris = ASN1_SUCCESS;
      if (move != UP)
	{
	  if (p->type & CONST_SET)
	    {
	      p2 = _asn1_find_up (p);
	      len2 = strtol (p2->value, NULL, 10);
	      if (len2 == -1)
		{
		  if (!der[counter] && !der[counter + 1])
		    {
		      p = p2;
		      move = UP;
		      counter += 2;
		      continue;
		    }
		}
	      else if (counter == len2)
		{
		  p = p2;
		  move = UP;
		  continue;
		}
	      else if (counter > len2)
		return ASN1_DER_ERROR;
	      p2 = p2->down;
	      while (p2)
		{
		  if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED))
		    {		/* CONTROLLARE */
		      if (type_field (p2->type) != TYPE_CHOICE)
			ris =
			  _asn1_extract_tag_der (p2, der + counter,
						 len - counter, &len2);
		      else
			{
			  p3 = p2->down;
			  ris =
			    _asn1_extract_tag_der (p3, der + counter,
						   len - counter, &len2);
			}
		      if (ris == ASN1_SUCCESS)
			{
			  p2->type &= ~CONST_NOT_USED;
			  p = p2;
			  break;
			}
		    }
		  p2 = p2->right;
		}
	      if (p2 == NULL)
		return ASN1_DER_ERROR;
	    }
	  if (p == node_to_find)
	    *start = counter;
	  if (type_field (p->type) == TYPE_CHOICE)
	    {
	      p = p->down;
	      ris =
		_asn1_extract_tag_der (p, der + counter, len - counter,
				       &len2);
	      if (p == node_to_find)
		*start = counter;
	    }
	  if (ris == ASN1_SUCCESS)
	    ris =
	      _asn1_extract_tag_der (p, der + counter, len - counter, &len2);
	  if (ris != ASN1_SUCCESS)
	    {
	      if (p->type & CONST_OPTION)
		{
		  p->type |= CONST_NOT_USED;
		  move = RIGHT;
		}
	      else if (p->type & CONST_DEFAULT)
		{
		  move = RIGHT;
		}
	      else
		{
		  return ASN1_TAG_ERROR;
		}
	    }
	  else
	    counter += len2;
	}
      if (ris == ASN1_SUCCESS)
	{
	  switch (type_field (p->type))
	    {
	    case TYPE_NULL:
	      if (der[counter])
		return ASN1_DER_ERROR;
	      counter++;
	      move = RIGHT;
	      break;
	    case TYPE_BOOLEAN:
	      if (der[counter++] != 1)
		return ASN1_DER_ERROR;
	      counter++;
	      move = RIGHT;
	      break;
	    case TYPE_INTEGER:
	    case TYPE_ENUMERATED:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case TYPE_OBJECT_ID:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      counter += len2 + len3;
	      move = RIGHT;
	      break;
	    case TYPE_TIME:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      counter += len2 + len3;
	      move = RIGHT;
	      break;
	    case TYPE_OCTET_STRING:
	      len3 = len - counter;
	      ris = _asn1_get_octet_string (der + counter, NULL, &len3);
	      if (ris != ASN1_SUCCESS)
		return ris;
	      counter += len3;
	      move = RIGHT;
	      break;
	    case TYPE_GENERALSTRING:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case TYPE_BIT_STRING:
	      len2 =
		asn1_get_length_der (der + counter, len - counter, &len3);
	      if (len2 < 0)
		return ASN1_DER_ERROR;
	      counter += len3 + len2;
	      move = RIGHT;
	      break;
	    case TYPE_SEQUENCE:
	    case TYPE_SET:
	      if (move != UP)
		{
		  len3 =
		    asn1_get_length_der (der + counter, len - counter, &len2);
		  if (len3 < -1)
		    return ASN1_DER_ERROR;
		  counter += len2;
		  if (len3 == 0)
		    move = RIGHT;
		  else
		    move = DOWN;
		}
	      else
		{
		  if (!der[counter] && !der[counter + 1])	/* indefinite length method */
		    counter += 2;
		  move = RIGHT;
		}
	      break;
	    case TYPE_SEQUENCE_OF:
	    case TYPE_SET_OF:
	      if (move != UP)
		{
		  len3 =
		    asn1_get_length_der (der + counter, len - counter, &len2);
		  if (len3 < -1)
		    return ASN1_DER_ERROR;
		  counter += len2;
		  if ((len3 == -1) && !der[counter] && !der[counter + 1])
		    counter += 2;
		  else if (len3)
		    {
		      p2 = p->down;
		      while ((type_field (p2->type) == TYPE_TAG) ||
			     (type_field (p2->type) == TYPE_SIZE))
			p2 = p2->right;
		      p = p2;
		    }
		}
	      else
		{
		  if (!der[counter] && !der[counter + 1])	/* indefinite length method */
		    counter += 2;
		}
	      move = RIGHT;
	      break;
	    case TYPE_ANY:
	      if (asn1_get_tag_der
		  (der + counter, len - counter, &class, &len2,
		   &tag) != ASN1_SUCCESS)
		return ASN1_DER_ERROR;
	      if (counter + len2 > len)
		return ASN1_DER_ERROR;
	      len4 =
		asn1_get_length_der (der + counter + len2,
				     len - counter - len2, &len3);
	      if (len4 < -1)
		return ASN1_DER_ERROR;
	      if (len4 != -1)
		{
		  counter += len2 + len4 + len3;
		}
	      else
		{		/* indefinite length */
		  /* Check indefinite lenth method in an EXPLICIT TAG */
		  if ((p->type & CONST_TAG) && (der[counter - 1] == 0x80))
		    indefinite = 1;
		  else
		    indefinite = 0;
		  len2 = len - counter;
		  ris =
		    _asn1_get_indefinite_length_string (der + counter, &len2);
		  if (ris != ASN1_SUCCESS)
		    return ris;
		  counter += len2;
		  /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with
		     an indefinite length method. */
		  if (indefinite)
		    {
		      if (!der[counter] && !der[counter + 1])
			counter += 2;
		      else
			return ASN1_DER_ERROR;
		    }
		}
	      move = RIGHT;
	      break;
	    default:
	      move = (move == UP) ? RIGHT : DOWN;
	      break;
	    }
	}
      if ((p == node_to_find) && (move == RIGHT))
	{
	  *end = counter - 1;
	  return ASN1_SUCCESS;
	}
      if (p == node && move != DOWN)
	break;
      if (move == DOWN)
	{
	  if (p->down)
	    p = p->down;
	  else
	    move = RIGHT;
	}
      if ((move == RIGHT) && !(p->type & CONST_SET))
	{
	  if (p->right)
	    p = p->right;
	  else
	    move = UP;
	}
      if (move == UP)
	p = _asn1_find_up (p);
    }
  return ASN1_ELEMENT_NOT_FOUND;
}
 | |||||
| ↓ | asn1_der_coding | 83 | 226 | 357 | ../../lib/coding.c | 
| 
asn1_retCode
asn1_der_coding (ASN1_TYPE element, const char *name, void *ider, int *len,
		 char *ErrorDescription)
{
  ASN1_TYPE node, p, p2;
  char temp[SIZEOF_UNSIGNED_LONG_INT * 3 + 1];
  int counter, counter_old, len2, len3, tlen, move, max_len, max_len_old;
  asn1_retCode err;
  unsigned char *der = ider;
  node = asn1_find_node (element, name);
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  /* Node is now a locally allocated variable.
   * That is because in some point we modify the
   * structure, and I don't know why! --nmav
   */
  node = _asn1_copy_structure3 (node);
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  max_len = *len;
  counter = 0;
  move = DOWN;
  p = node;
  while (1)
    {
      counter_old = counter;
      max_len_old = max_len;
      if (move != UP)
	{
	  err = _asn1_insert_tag_der (p, der, &counter, &max_len);
	  if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
	    goto error;
	}
      switch (type_field (p->type))
	{
	case TYPE_NULL:
	  max_len--;
	  if (max_len >= 0)
	    der[counter] = 0;
	  counter++;
	  move = RIGHT;
	  break;
	case TYPE_BOOLEAN:
	  if ((p->type & CONST_DEFAULT) && (p->value == NULL))
	    {
	      counter = counter_old;
	      max_len = max_len_old;
	    }
	  else
	    {
	      if (p->value == NULL)
		{
		  _asn1_error_description_value_not_found (p,
							   ErrorDescription);
		  err = ASN1_VALUE_NOT_FOUND;
		  goto error;
		}
	      max_len -= 2;
	      if (max_len >= 0)
		{
		  der[counter++] = 1;
		  if (p->value[0] == 'F')
		    der[counter++] = 0;
		  else
		    der[counter++] = 0xFF;
		}
	      else
		counter += 2;
	    }
	  move = RIGHT;
	  break;
	case TYPE_INTEGER:
	case TYPE_ENUMERATED:
	  if ((p->type & CONST_DEFAULT) && (p->value == NULL))
	    {
	      counter = counter_old;
	      max_len = max_len_old;
	    }
	  else
	    {
	      if (p->value == NULL)
		{
		  _asn1_error_description_value_not_found (p,
							   ErrorDescription);
		  err = ASN1_VALUE_NOT_FOUND;
		  goto error;
		}
	      len2 = asn1_get_length_der (p->value, p->value_len, &len3);
	      if (len2 < 0)
		{
		  err = ASN1_DER_ERROR;
		  goto error;
		}
	      max_len -= len2 + len3;
	      if (max_len >= 0)
		memcpy (der + counter, p->value, len3 + len2);
	      counter += len3 + len2;
	    }
	  move = RIGHT;
	  break;
	case TYPE_OBJECT_ID:
	  if ((p->type & CONST_DEFAULT) && (p->value == NULL))
	    {
	      counter = counter_old;
	      max_len = max_len_old;
	    }
	  else
	    {
	      if (p->value == NULL)
		{
		  _asn1_error_description_value_not_found (p,
							   ErrorDescription);
		  err = ASN1_VALUE_NOT_FOUND;
		  goto error;
		}
	      len2 = max_len;
	      err = _asn1_objectid_der (p->value, der + counter, &len2);
	      if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
		goto error;
	      max_len -= len2;
	      counter += len2;
	    }
	  move = RIGHT;
	  break;
	case TYPE_TIME:
	  if (p->value == NULL)
	    {
	      _asn1_error_description_value_not_found (p, ErrorDescription);
	      err = ASN1_VALUE_NOT_FOUND;
	      goto error;
	    }
	  len2 = max_len;
	  err = _asn1_time_der (p->value, der + counter, &len2);
	  if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
	    goto error;
	  max_len -= len2;
	  counter += len2;
	  move = RIGHT;
	  break;
	case TYPE_OCTET_STRING:
	  if (p->value == NULL)
	    {
	      _asn1_error_description_value_not_found (p, ErrorDescription);
	      err = ASN1_VALUE_NOT_FOUND;
	      goto error;
	    }
	  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
	  if (len2 < 0)
	    {
	      err = ASN1_DER_ERROR;
	      goto error;
	    }
	  max_len -= len2 + len3;
	  if (max_len >= 0)
	    memcpy (der + counter, p->value, len3 + len2);
	  counter += len3 + len2;
	  move = RIGHT;
	  break;
	case TYPE_GENERALSTRING:
	  if (p->value == NULL)
	    {
	      _asn1_error_description_value_not_found (p, ErrorDescription);
	      err = ASN1_VALUE_NOT_FOUND;
	      goto error;
	    }
	  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
	  if (len2 < 0)
	    {
	      err = ASN1_DER_ERROR;
	      goto error;
	    }
	  max_len -= len2 + len3;
	  if (max_len >= 0)
	    memcpy (der + counter, p->value, len3 + len2);
	  counter += len3 + len2;
	  move = RIGHT;
	  break;
	case TYPE_BIT_STRING:
	  if (p->value == NULL)
	    {
	      _asn1_error_description_value_not_found (p, ErrorDescription);
	      err = ASN1_VALUE_NOT_FOUND;
	      goto error;
	    }
	  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
	  if (len2 < 0)
	    {
	      err = ASN1_DER_ERROR;
	      goto error;
	    }
	  max_len -= len2 + len3;
	  if (max_len >= 0)
	    memcpy (der + counter, p->value, len3 + len2);
	  counter += len3 + len2;
	  move = RIGHT;
	  break;
	case TYPE_SEQUENCE:
	case TYPE_SET:
	  if (move != UP)
	    {
	      _asn1_ltostr (counter, temp);
	      tlen = strlen (temp);
	      if (tlen > 0)
		_asn1_set_value (p, temp, tlen + 1);
	      if (p->down == NULL)
		{
		  move = UP;
		  continue;
		}
	      else
		{
		  p2 = p->down;
		  while (p2 && (type_field (p2->type) == TYPE_TAG))
		    p2 = p2->right;
		  if (p2)
		    {
		      p = p2;
		      move = RIGHT;
		      continue;
		    }
		  move = UP;
		  continue;
		}
	    }
	  else
	    {			/* move==UP */
	      len2 = strtol (p->value, NULL, 10);
	      _asn1_set_value (p, NULL, 0);
	      if ((type_field (p->type) == TYPE_SET) && (max_len >= 0))
		_asn1_ordering_set (der + len2, max_len - len2, p);
	      asn1_length_der (counter - len2, temp, &len3);
	      max_len -= len3;
	      if (max_len >= 0)
		{
		  memmove (der + len2 + len3, der + len2, counter - len2);
		  memcpy (der + len2, temp, len3);
		}
	      counter += len3;
	      move = RIGHT;
	    }
	  break;
	case TYPE_SEQUENCE_OF:
	case TYPE_SET_OF:
	  if (move != UP)
	    {
	      _asn1_ltostr (counter, temp);
	      tlen = strlen (temp);
	      if (tlen > 0)
		_asn1_set_value (p, temp, tlen + 1);
	      p = p->down;
	      while ((type_field (p->type) == TYPE_TAG)
		     || (type_field (p->type) == TYPE_SIZE))
		p = p->right;
	      if (p->right)
		{
		  p = p->right;
		  move = RIGHT;
		  continue;
		}
	      else
		p = _asn1_find_up (p);
	      move = UP;
	    }
	  if (move == UP)
	    {
	      len2 = strtol (p->value, NULL, 10);
	      _asn1_set_value (p, NULL, 0);
	      if ((type_field (p->type) == TYPE_SET_OF)
		  && (max_len - len2 > 0))
		{
		  _asn1_ordering_set_of (der + len2, max_len - len2, p);
		}
	      asn1_length_der (counter - len2, temp, &len3);
	      max_len -= len3;
	      if (max_len >= 0)
		{
		  memmove (der + len2 + len3, der + len2, counter - len2);
		  memcpy (der + len2, temp, len3);
		}
	      counter += len3;
	      move = RIGHT;
	    }
	  break;
	case TYPE_ANY:
	  if (p->value == NULL)
	    {
	      _asn1_error_description_value_not_found (p, ErrorDescription);
	      err = ASN1_VALUE_NOT_FOUND;
	      goto error;
	    }
	  len2 = asn1_get_length_der (p->value, p->value_len, &len3);
	  if (len2 < 0)
	    {
	      err = ASN1_DER_ERROR;
	      goto error;
	    }
	  max_len -= len2;
	  if (max_len >= 0)
	    memcpy (der + counter, p->value + len3, len2);
	  counter += len2;
	  move = RIGHT;
	  break;
	default:
	  move = (move == UP) ? RIGHT : DOWN;
	  break;
	}
      if ((move != DOWN) && (counter != counter_old))
	{
	  err = _asn1_complete_explicit_tag (p, der, &counter, &max_len);
	  if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR)
	    goto error;
	}
      if (p == node && move != DOWN)
	break;
      if (move == DOWN)
	{
	  if (p->down)
	    p = p->down;
	  else
	    move = RIGHT;
	}
      if (move == RIGHT)
	{
	  if (p->right)
	    p = p->right;
	  else
	    move = UP;
	}
      if (move == UP)
	p = _asn1_find_up (p);
    }
  *len = counter;
  if (max_len < 0)
    {
      err = ASN1_MEM_ERROR;
      goto error;
    }
  err = ASN1_SUCCESS;
error:
  asn1_delete_structure (&node);
  return err;
}
 | |||||
| ↓ | _asn1_extract_tag_der | 74 | 105 | 197 | ../../lib/decoding.c | 
| 
static int
_asn1_extract_tag_der (ASN1_TYPE node, const unsigned char *der, int der_len,
		       int *ret_len)
{
  ASN1_TYPE p;
  int counter, len2, len3, is_tag_implicit;
  unsigned long tag, tag_implicit = 0;
  unsigned char class, class2, class_implicit = 0;
  if (der_len <= 0)
    return ASN1_GENERIC_ERROR;
  counter = is_tag_implicit = 0;
  if (node->type & CONST_TAG)
    {
      p = node->down;
      while (p)
	{
	  if (type_field (p->type) == TYPE_TAG)
	    {
	      if (p->type & CONST_APPLICATION)
		class2 = ASN1_CLASS_APPLICATION;
	      else if (p->type & CONST_UNIVERSAL)
		class2 = ASN1_CLASS_UNIVERSAL;
	      else if (p->type & CONST_PRIVATE)
		class2 = ASN1_CLASS_PRIVATE;
	      else
		class2 = ASN1_CLASS_CONTEXT_SPECIFIC;
	      if (p->type & CONST_EXPLICIT)
		{
		  if (asn1_get_tag_der
		      (der + counter, der_len - counter, &class, &len2,
		       &tag) != ASN1_SUCCESS)
		    return ASN1_DER_ERROR;
		  if (counter + len2 > der_len)
		    return ASN1_DER_ERROR;
		  counter += len2;
		  len3 =
		    asn1_get_length_ber (der + counter, der_len - counter,
					 &len2);
		  if (len3 < 0)
		    return ASN1_DER_ERROR;
		  counter += len2;
		  if (counter > der_len)
		    return ASN1_DER_ERROR;
		  if (!is_tag_implicit)
		    {
		      if ((class != (class2 | ASN1_CLASS_STRUCTURED)) ||
			  (tag != strtoul ((char *) p->value, NULL, 10)))
			return ASN1_TAG_ERROR;
		    }
		  else
		    {		/* ASN1_TAG_IMPLICIT */
		      if ((class != class_implicit) || (tag != tag_implicit))
			return ASN1_TAG_ERROR;
		    }
		  is_tag_implicit = 0;
		}
	      else
		{		/* ASN1_TAG_IMPLICIT */
		  if (!is_tag_implicit)
		    {
		      if ((type_field (node->type) == TYPE_SEQUENCE) ||
			  (type_field (node->type) == TYPE_SEQUENCE_OF) ||
			  (type_field (node->type) == TYPE_SET) ||
			  (type_field (node->type) == TYPE_SET_OF))
			class2 |= ASN1_CLASS_STRUCTURED;
		      class_implicit = class2;
		      tag_implicit = strtoul ((char *) p->value, NULL, 10);
		      is_tag_implicit = 1;
		    }
		}
	    }
	  p = p->right;
	}
    }
  if (is_tag_implicit)
    {
      if (asn1_get_tag_der
	  (der + counter, der_len - counter, &class, &len2,
	   &tag) != ASN1_SUCCESS)
	return ASN1_DER_ERROR;
      if (counter + len2 > der_len)
	return ASN1_DER_ERROR;
      if ((class != class_implicit) || (tag != tag_implicit))
	{
	  if (type_field (node->type) == TYPE_OCTET_STRING)
	    {
	      class_implicit |= ASN1_CLASS_STRUCTURED;
	      if ((class != class_implicit) || (tag != tag_implicit))
		return ASN1_TAG_ERROR;
	    }
	  else
	    return ASN1_TAG_ERROR;
	}
    }
  else
    {
      if (type_field (node->type) == TYPE_TAG)
	{
	  counter = 0;
	  *ret_len = counter;
	  return ASN1_SUCCESS;
	}
      if (asn1_get_tag_der
	  (der + counter, der_len - counter, &class, &len2,
	   &tag) != ASN1_SUCCESS)
	return ASN1_DER_ERROR;
      if (counter + len2 > der_len)
	return ASN1_DER_ERROR;
      switch (type_field (node->type))
	{
	case TYPE_NULL:
	  if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_NULL))
	    return ASN1_DER_ERROR;
	  break;
	case TYPE_BOOLEAN:
	  if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BOOLEAN))
	    return ASN1_DER_ERROR;
	  break;
	case TYPE_INTEGER:
	  if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_INTEGER))
	    return ASN1_DER_ERROR;
	  break;
	case TYPE_ENUMERATED:
	  if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_ENUMERATED))
	    return ASN1_DER_ERROR;
	  break;
	case TYPE_OBJECT_ID:
	  if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_OBJECT_ID))
	    return ASN1_DER_ERROR;
	  break;
	case TYPE_TIME:
	  if (node->type & CONST_UTC)
	    {
	      if ((class != ASN1_CLASS_UNIVERSAL)
		  || (tag != ASN1_TAG_UTCTime))
		return ASN1_DER_ERROR;
	    }
	  else
	    {
	      if ((class != ASN1_CLASS_UNIVERSAL)
		  || (tag != ASN1_TAG_GENERALIZEDTime))
		return ASN1_DER_ERROR;
	    }
	  break;
	case TYPE_OCTET_STRING:
	  if (((class != ASN1_CLASS_UNIVERSAL)
	       && (class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED)))
	      || (tag != ASN1_TAG_OCTET_STRING))
	    return ASN1_DER_ERROR;
	  break;
	case TYPE_GENERALSTRING:
	  if ((class != ASN1_CLASS_UNIVERSAL)
	      || (tag != ASN1_TAG_GENERALSTRING))
	    return ASN1_DER_ERROR;
	  break;
	case TYPE_BIT_STRING:
	  if ((class != ASN1_CLASS_UNIVERSAL) || (tag != ASN1_TAG_BIT_STRING))
	    return ASN1_DER_ERROR;
	  break;
	case TYPE_SEQUENCE:
	case TYPE_SEQUENCE_OF:
	  if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
	      || (tag != ASN1_TAG_SEQUENCE))
	    return ASN1_DER_ERROR;
	  break;
	case TYPE_SET:
	case TYPE_SET_OF:
	  if ((class != (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED))
	      || (tag != ASN1_TAG_SET))
	    return ASN1_DER_ERROR;
	  break;
	case TYPE_ANY:
	  counter -= len2;
	  break;
	default:
	  return ASN1_DER_ERROR;
	  break;
	}
    }
  counter += len2;
  *ret_len = counter;
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | yyparse | 142 | 432 | 1199 | ../../lib/ASN1.c | 
| 
int
yyparse (void *YYPARSE_PARAM)
#else
int
yyparse (YYPARSE_PARAM)
    void *YYPARSE_PARAM;
#endif
#else /* ! YYPARSE_PARAM */
#if (defined __STDC__ || defined __C99__FUNC__ \
     || defined __cplusplus || defined _MSC_VER)
int
yyparse (void)
#else
int
yyparse ()
#endif
#endif
{
    int yystate;
    /* Number of tokens to shift before error messages enabled.  */
    int yyerrstatus;
    /* The stacks and their tools:
       `yyss': related to states.
       `yyvs': related to semantic values.
       Refer to the stacks thru separate pointers, to allow yyoverflow
       to reallocate them elsewhere.  */
    /* The state stack.  */
    yytype_int16 yyssa[YYINITDEPTH];
    yytype_int16 *yyss;
    yytype_int16 *yyssp;
    /* The semantic value stack.  */
    YYSTYPE yyvsa[YYINITDEPTH];
    YYSTYPE *yyvs;
    YYSTYPE *yyvsp;
    YYSIZE_T yystacksize;
  int yyn;
  int yyresult;
  /* Lookahead token as an internal (translated) token number.  */
  int yytoken;
  /* The variables used to return semantic value and location from the
     action routines.  */
  YYSTYPE yyval;
#if YYERROR_VERBOSE
  /* Buffer for error messages, and its allocated size.  */
  char yymsgbuf[128];
  char *yymsg = yymsgbuf;
  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
#endif
#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N))
  /* The number of symbols on the RHS of the reduced rule.
     Keep to zero when no symbol should be popped.  */
  int yylen = 0;
  yytoken = 0;
  yyss = yyssa;
  yyvs = yyvsa;
  yystacksize = YYINITDEPTH;
  YYDPRINTF ((stderr, "Starting parse\n"));
  yystate = 0;
  yyerrstatus = 0;
  yynerrs = 0;
  yychar = YYEMPTY; /* Cause a token to be read.  */
  /* Initialize stack pointers.
     Waste one element of value and location stack
     so that they stay on the same level as the state stack.
     The wasted elements are never initialized.  */
  yyssp = yyss;
  yyvsp = yyvs;
  goto yysetstate;
/*------------------------------------------------------------.
| yynewstate -- Push a new state, which is found in yystate.  |
`------------------------------------------------------------*/
 yynewstate:
  /* In all cases, when you get here, the value and location stacks
     have just been pushed.  So pushing a state here evens the stacks.  */
  yyssp++;
 yysetstate:
  *yyssp = yystate;
  if (yyss + yystacksize - 1 <= yyssp)
    {
      /* Get the current used size of the three stacks, in elements.  */
      YYSIZE_T yysize = yyssp - yyss + 1;
#ifdef yyoverflow
      {
	/* Give user a chance to reallocate the stack.  Use copies of
	   these so that the &'s don't force the real ones into
	   memory.  */
	YYSTYPE *yyvs1 = yyvs;
	yytype_int16 *yyss1 = yyss;
	/* Each stack pointer address is followed by the size of the
	   data in use in that stack, in bytes.  This used to be a
	   conditional around just the two extra args, but that might
	   be undefined if yyoverflow is a macro.  */
	yyoverflow (YY_("memory exhausted"),
		    &yyss1, yysize * sizeof (*yyssp),
		    &yyvs1, yysize * sizeof (*yyvsp),
		    &yystacksize);
	yyss = yyss1;
	yyvs = yyvs1;
      }
#else /* no yyoverflow */
# ifndef YYSTACK_RELOCATE
      goto yyexhaustedlab;
# else
      /* Extend the stack our own way.  */
      if (YYMAXDEPTH <= yystacksize)
	goto yyexhaustedlab;
      yystacksize *= 2;
      if (YYMAXDEPTH < yystacksize)
	yystacksize = YYMAXDEPTH;
      {
	yytype_int16 *yyss1 = yyss;
	union yyalloc *yyptr =
	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
	if (! yyptr)
	  goto yyexhaustedlab;
	YYSTACK_RELOCATE (yyss_alloc, yyss);
	YYSTACK_RELOCATE (yyvs_alloc, yyvs);
#  undef YYSTACK_RELOCATE
	if (yyss1 != yyssa)
	  YYSTACK_FREE (yyss1);
      }
# endif
#endif /* no yyoverflow */
      yyssp = yyss + yysize - 1;
      yyvsp = yyvs + yysize - 1;
      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
		  (unsigned long int) yystacksize));
      if (yyss + yystacksize - 1 <= yyssp)
	YYABORT;
    }
  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
  if (yystate == YYFINAL)
    YYACCEPT;
  goto yybackup;
/*-----------.
| yybackup.  |
`-----------*/
yybackup:
  /* Do appropriate processing given the current state.  Read a
     lookahead token if we need one and don't already have one.  */
  /* First try to decide what to do without reference to lookahead token.  */
  yyn = yypact[yystate];
  if (yyn == YYPACT_NINF)
    goto yydefault;
  /* Not known => get a lookahead token if don't already have one.  */
  /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol.  */
  if (yychar == YYEMPTY)
    {
      YYDPRINTF ((stderr, "Reading a token: "));
      yychar = YYLEX;
    }
  if (yychar <= YYEOF)
    {
      yychar = yytoken = YYEOF;
      YYDPRINTF ((stderr, "Now at end of input.\n"));
    }
  else
    {
      yytoken = YYTRANSLATE (yychar);
      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
    }
  /* If the proper action on seeing token YYTOKEN is to reduce or to
     detect an error, take that action.  */
  yyn += yytoken;
  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
    goto yydefault;
  yyn = yytable[yyn];
  if (yyn <= 0)
    {
      if (yyn == 0 || yyn == YYTABLE_NINF)
	goto yyerrlab;
      yyn = -yyn;
      goto yyreduce;
    }
  /* Count tokens shifted since error; after three, turn off error
     status.  */
  if (yyerrstatus)
    yyerrstatus--;
  /* Shift the lookahead token.  */
  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
  /* Discard the shifted token.  */
  yychar = YYEMPTY;
  yystate = yyn;
  *++yyvsp = yylval;
  goto yynewstate;
/*-----------------------------------------------------------.
| yydefault -- do the default action for the current state.  |
`-----------------------------------------------------------*/
yydefault:
  yyn = yydefact[yystate];
  if (yyn == 0)
    goto yyerrlab;
  goto yyreduce;
/*-----------------------------.
| yyreduce -- Do a reduction.  |
`-----------------------------*/
yyreduce:
  /* yyn is the number of a rule to reduce with.  */
  yylen = yyr2[yyn];
  /* If YYLEN is nonzero, implement the default value of the action:
     `$$ = $1'.
     Otherwise, the following line sets YYVAL to garbage.
     This behavior is undocumented and Bison
     users should not rely upon it.  Assigning to YYVAL
     unconditionally makes the parser a bit smaller, and it avoids a
     GCC warning that YYVAL may be used uninitialized.  */
  yyval = yyvsp[1-yylen];
  YY_REDUCE_PRINT (yyn);
  switch (yyn)
    {
        case 2:
/* Line 1455 of yacc.c  */
#line 122 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_DEFINITIONS|(yyvsp[(3) - (8)].constant));
                    _asn1_set_name((yyval.node),_asn1_get_name((yyvsp[(1) - (8)].node)));
                    _asn1_set_name((yyvsp[(1) - (8)].node),"");
                    _asn1_set_right((yyvsp[(1) - (8)].node),(yyvsp[(7) - (8)].node));
                    _asn1_set_down((yyval.node),(yyvsp[(1) - (8)].node));
		    p_tree=(yyval.node);
		    }
    break;
  case 3:
/* Line 1455 of yacc.c  */
#line 132 "ASN1.y"
    {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
    break;
  case 4:
/* Line 1455 of yacc.c  */
#line 133 "ASN1.y"
    {strcpy((yyval.str),(yyvsp[(2) - (2)].str));}
    break;
  case 5:
/* Line 1455 of yacc.c  */
#line 136 "ASN1.y"
    {strcpy((yyval.str),"-");
                       strcat((yyval.str),(yyvsp[(2) - (2)].str));}
    break;
  case 6:
/* Line 1455 of yacc.c  */
#line 140 "ASN1.y"
    {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
    break;
  case 7:
/* Line 1455 of yacc.c  */
#line 141 "ASN1.y"
    {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
    break;
  case 8:
/* Line 1455 of yacc.c  */
#line 144 "ASN1.y"
    {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
    break;
  case 9:
/* Line 1455 of yacc.c  */
#line 145 "ASN1.y"
    {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
    break;
  case 10:
/* Line 1455 of yacc.c  */
#line 148 "ASN1.y"
    {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
    break;
  case 11:
/* Line 1455 of yacc.c  */
#line 149 "ASN1.y"
    {strcpy((yyval.str),(yyvsp[(1) - (1)].str));}
    break;
  case 12:
/* Line 1455 of yacc.c  */
#line 152 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_CONSTANT);
                                       _asn1_set_value((yyval.node),(yyvsp[(2) - (3)].str),strlen((yyvsp[(2) - (3)].str))+1);}
    break;
  case 13:
/* Line 1455 of yacc.c  */
#line 154 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_CONSTANT);
	                               _asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
                                       _asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
    break;
  case 14:
/* Line 1455 of yacc.c  */
#line 159 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 15:
/* Line 1455 of yacc.c  */
#line 160 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (3)].node);
                                            _asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (3)].node)),(yyvsp[(3) - (3)].node));}
    break;
  case 16:
/* Line 1455 of yacc.c  */
#line 164 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_CONSTANT);
                                   _asn1_set_value((yyval.node),(yyvsp[(1) - (1)].str),strlen((yyvsp[(1) - (1)].str))+1);}
    break;
  case 17:
/* Line 1455 of yacc.c  */
#line 166 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_CONSTANT);
	                            _asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
                                    _asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
    break;
  case 18:
/* Line 1455 of yacc.c  */
#line 171 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 19:
/* Line 1455 of yacc.c  */
#line 172 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (2)].node);
                                                    _asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (2)].node)),(yyvsp[(2) - (2)].node));}
    break;
  case 20:
/* Line 1455 of yacc.c  */
#line 176 "ASN1.y"
    {(yyval.constant)=CONST_UNIVERSAL;}
    break;
  case 21:
/* Line 1455 of yacc.c  */
#line 177 "ASN1.y"
    {(yyval.constant)=CONST_PRIVATE;}
    break;
  case 22:
/* Line 1455 of yacc.c  */
#line 178 "ASN1.y"
    {(yyval.constant)=CONST_APPLICATION;}
    break;
  case 23:
/* Line 1455 of yacc.c  */
#line 181 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_TAG);
                            _asn1_set_value((yyval.node),(yyvsp[(2) - (3)].str),strlen((yyvsp[(2) - (3)].str))+1);}
    break;
  case 24:
/* Line 1455 of yacc.c  */
#line 183 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_TAG | (yyvsp[(2) - (4)].constant));
                                _asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
    break;
  case 25:
/* Line 1455 of yacc.c  */
#line 187 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 26:
/* Line 1455 of yacc.c  */
#line 188 "ASN1.y"
    {(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_EXPLICIT);}
    break;
  case 27:
/* Line 1455 of yacc.c  */
#line 189 "ASN1.y"
    {(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_IMPLICIT);}
    break;
  case 28:
/* Line 1455 of yacc.c  */
#line 192 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_DEFAULT);
                                       _asn1_set_value((yyval.node),(yyvsp[(2) - (2)].str),strlen((yyvsp[(2) - (2)].str))+1);}
    break;
  case 29:
/* Line 1455 of yacc.c  */
#line 194 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_DEFAULT|CONST_TRUE);}
    break;
  case 30:
/* Line 1455 of yacc.c  */
#line 195 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_DEFAULT|CONST_FALSE);}
    break;
  case 33:
/* Line 1455 of yacc.c  */
#line 204 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_INTEGER);}
    break;
  case 34:
/* Line 1455 of yacc.c  */
#line 205 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_INTEGER|CONST_LIST);
	                                 _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
    break;
  case 35:
/* Line 1455 of yacc.c  */
#line 207 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_INTEGER);}
    break;
  case 36:
/* Line 1455 of yacc.c  */
#line 209 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_INTEGER|CONST_MIN_MAX);
                                         _asn1_set_down((yyval.node),_asn1_add_node(TYPE_SIZE));
                                         _asn1_set_value(_asn1_get_down((yyval.node)),(yyvsp[(6) - (7)].str),strlen((yyvsp[(6) - (7)].str))+1);
                                         _asn1_set_name(_asn1_get_down((yyval.node)),(yyvsp[(3) - (7)].str));}
    break;
  case 37:
/* Line 1455 of yacc.c  */
#line 215 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_BOOLEAN);}
    break;
  case 38:
/* Line 1455 of yacc.c  */
#line 218 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_TIME|CONST_UTC);}
    break;
  case 39:
/* Line 1455 of yacc.c  */
#line 219 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_TIME|CONST_GENERALIZED);}
    break;
  case 40:
/* Line 1455 of yacc.c  */
#line 222 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_SIZE|CONST_1_PARAM);
	                              _asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
    break;
  case 41:
/* Line 1455 of yacc.c  */
#line 225 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_SIZE|CONST_MIN_MAX);
	                              _asn1_set_value((yyval.node),(yyvsp[(3) - (7)].str),strlen((yyvsp[(3) - (7)].str))+1);
                                      _asn1_set_name((yyval.node),(yyvsp[(6) - (7)].str));}
    break;
  case 42:
/* Line 1455 of yacc.c  */
#line 230 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 43:
/* Line 1455 of yacc.c  */
#line 231 "ASN1.y"
    {(yyval.node)=(yyvsp[(2) - (3)].node);}
    break;
  case 44:
/* Line 1455 of yacc.c  */
#line 234 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_GENERALSTRING);}
    break;
  case 45:
/* Line 1455 of yacc.c  */
#line 235 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_GENERALSTRING|CONST_SIZE);
					  _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
    break;
  case 46:
/* Line 1455 of yacc.c  */
#line 239 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_OCTET_STRING);}
    break;
  case 47:
/* Line 1455 of yacc.c  */
#line 240 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_OCTET_STRING|CONST_SIZE);
                                           _asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
    break;
  case 48:
/* Line 1455 of yacc.c  */
#line 244 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_CONSTANT);
	                           _asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
                                    _asn1_set_value((yyval.node),(yyvsp[(3) - (4)].str),strlen((yyvsp[(3) - (4)].str))+1);}
    break;
  case 49:
/* Line 1455 of yacc.c  */
#line 249 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 50:
/* Line 1455 of yacc.c  */
#line 250 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (3)].node);
                                                       _asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (3)].node)),(yyvsp[(3) - (3)].node));}
    break;
  case 51:
/* Line 1455 of yacc.c  */
#line 254 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_BIT_STRING);}
    break;
  case 52:
/* Line 1455 of yacc.c  */
#line 255 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_BIT_STRING|CONST_SIZE);}
    break;
  case 53:
/* Line 1455 of yacc.c  */
#line 257 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_BIT_STRING|CONST_LIST);
                                _asn1_set_down((yyval.node),(yyvsp[(4) - (5)].node));}
    break;
  case 54:
/* Line 1455 of yacc.c  */
#line 262 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_ENUMERATED|CONST_LIST);
                                _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
    break;
  case 55:
/* Line 1455 of yacc.c  */
#line 267 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_OBJECT_ID);}
    break;
  case 56:
/* Line 1455 of yacc.c  */
#line 270 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_IDENTIFIER);
                                       _asn1_set_value((yyval.node),(yyvsp[(1) - (1)].str),strlen((yyvsp[(1) - (1)].str))+1);}
    break;
  case 57:
/* Line 1455 of yacc.c  */
#line 272 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_IDENTIFIER|CONST_SIZE);
                                       _asn1_set_value((yyval.node),(yyvsp[(1) - (2)].str),strlen((yyvsp[(1) - (2)].str))+1);
                                       _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
    break;
  case 58:
/* Line 1455 of yacc.c  */
#line 275 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 59:
/* Line 1455 of yacc.c  */
#line 276 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 60:
/* Line 1455 of yacc.c  */
#line 277 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 62:
/* Line 1455 of yacc.c  */
#line 279 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 63:
/* Line 1455 of yacc.c  */
#line 280 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 64:
/* Line 1455 of yacc.c  */
#line 281 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 65:
/* Line 1455 of yacc.c  */
#line 282 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 66:
/* Line 1455 of yacc.c  */
#line 283 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 67:
/* Line 1455 of yacc.c  */
#line 284 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 68:
/* Line 1455 of yacc.c  */
#line 285 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 69:
/* Line 1455 of yacc.c  */
#line 286 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 70:
/* Line 1455 of yacc.c  */
#line 287 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_NULL);}
    break;
  case 71:
/* Line 1455 of yacc.c  */
#line 290 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 72:
/* Line 1455 of yacc.c  */
#line 291 "ASN1.y"
    {(yyval.node)=_asn1_mod_type((yyvsp[(2) - (2)].node),CONST_TAG);
                                               _asn1_set_right((yyvsp[(1) - (2)].node),_asn1_get_down((yyval.node)));
                                               _asn1_set_down((yyval.node),(yyvsp[(1) - (2)].node));}
    break;
  case 73:
/* Line 1455 of yacc.c  */
#line 296 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 74:
/* Line 1455 of yacc.c  */
#line 297 "ASN1.y"
    {(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_DEFAULT);
                                                       _asn1_set_right((yyvsp[(2) - (2)].node),_asn1_get_down((yyval.node)));
						       _asn1_set_down((yyval.node),(yyvsp[(2) - (2)].node));}
    break;
  case 75:
/* Line 1455 of yacc.c  */
#line 300 "ASN1.y"
    {(yyval.node)=_asn1_mod_type((yyvsp[(1) - (2)].node),CONST_OPTION);}
    break;
  case 76:
/* Line 1455 of yacc.c  */
#line 303 "ASN1.y"
    {(yyval.node)=_asn1_set_name((yyvsp[(2) - (2)].node),(yyvsp[(1) - (2)].str));}
    break;
  case 77:
/* Line 1455 of yacc.c  */
#line 306 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 78:
/* Line 1455 of yacc.c  */
#line 307 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (3)].node);
                                                _asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (3)].node)),(yyvsp[(3) - (3)].node));}
    break;
  case 79:
/* Line 1455 of yacc.c  */
#line 311 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_SEQUENCE);
                                              _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
    break;
  case 80:
/* Line 1455 of yacc.c  */
#line 313 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_SEQUENCE_OF);
                                              _asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
    break;
  case 81:
/* Line 1455 of yacc.c  */
#line 315 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_SEQUENCE_OF|CONST_SIZE);
                                            _asn1_set_right((yyvsp[(2) - (4)].node),(yyvsp[(4) - (4)].node));
                                            _asn1_set_down((yyval.node),(yyvsp[(2) - (4)].node));}
    break;
  case 82:
/* Line 1455 of yacc.c  */
#line 320 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_SET);
                                     _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
    break;
  case 83:
/* Line 1455 of yacc.c  */
#line 322 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_SET_OF);
                                     _asn1_set_down((yyval.node),(yyvsp[(3) - (3)].node));}
    break;
  case 84:
/* Line 1455 of yacc.c  */
#line 324 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_SET_OF|CONST_SIZE);
                                       _asn1_set_right((yyvsp[(2) - (4)].node),(yyvsp[(4) - (4)].node));
                                       _asn1_set_down((yyval.node),(yyvsp[(2) - (4)].node));}
    break;
  case 85:
/* Line 1455 of yacc.c  */
#line 329 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_CHOICE);
                                             _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));}
    break;
  case 86:
/* Line 1455 of yacc.c  */
#line 333 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_ANY);}
    break;
  case 87:
/* Line 1455 of yacc.c  */
#line 334 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_ANY|CONST_DEFINED_BY);
                                        _asn1_set_down((yyval.node),_asn1_add_node(TYPE_CONSTANT));
	                                _asn1_set_name(_asn1_get_down((yyval.node)),(yyvsp[(4) - (4)].str));}
    break;
  case 88:
/* Line 1455 of yacc.c  */
#line 339 "ASN1.y"
    {(yyval.node)=_asn1_set_name((yyvsp[(3) - (3)].node),(yyvsp[(1) - (3)].str));}
    break;
  case 89:
/* Line 1455 of yacc.c  */
#line 343 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN);
                         _asn1_set_name((yyval.node),(yyvsp[(1) - (7)].str));
                         _asn1_set_down((yyval.node),(yyvsp[(6) - (7)].node));}
    break;
  case 90:
/* Line 1455 of yacc.c  */
#line 347 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_OBJECT_ID|CONST_ASSIGN|CONST_1_PARAM);
                         _asn1_set_name((yyval.node),(yyvsp[(1) - (6)].str));
                         _asn1_set_value((yyval.node),(yyvsp[(2) - (6)].str),strlen((yyvsp[(2) - (6)].str))+1);
                         _asn1_set_down((yyval.node),(yyvsp[(5) - (6)].node));}
    break;
  case 91:
/* Line 1455 of yacc.c  */
#line 352 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_INTEGER|CONST_ASSIGN);
                         _asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));
                         _asn1_set_value((yyval.node),(yyvsp[(4) - (4)].str),strlen((yyvsp[(4) - (4)].str))+1);}
    break;
  case 92:
/* Line 1455 of yacc.c  */
#line 357 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 93:
/* Line 1455 of yacc.c  */
#line 358 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 94:
/* Line 1455 of yacc.c  */
#line 361 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (1)].node);}
    break;
  case 95:
/* Line 1455 of yacc.c  */
#line 362 "ASN1.y"
    {(yyval.node)=(yyvsp[(1) - (2)].node);
                                                          _asn1_set_right(_asn1_get_last_right((yyvsp[(1) - (2)].node)),(yyvsp[(2) - (2)].node));}
    break;
  case 96:
/* Line 1455 of yacc.c  */
#line 366 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_OBJECT_ID);
                                                          _asn1_set_down((yyval.node),(yyvsp[(3) - (4)].node));
                                                          _asn1_set_name((yyval.node),(yyvsp[(1) - (4)].str));}
    break;
  case 97:
/* Line 1455 of yacc.c  */
#line 369 "ASN1.y"
    {(yyval.node)=_asn1_add_node(TYPE_OBJECT_ID);
                                                          _asn1_set_name((yyval.node),(yyvsp[(1) - (3)].str));}
    break;
  case 98:
/* Line 1455 of yacc.c  */
#line 393 "ASN1.y"
    {(yyval.constant)=CONST_EXPLICIT;}
    break;
  case 99:
/* Line 1455 of yacc.c  */
#line 394 "ASN1.y"
    {(yyval.constant)=CONST_IMPLICIT;}
    break;
/* Line 1455 of yacc.c  */
#line 2371 "ASN1.c"
      default: break;
    }
  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
  YYPOPSTACK (yylen);
  yylen = 0;
  YY_STACK_PRINT (yyss, yyssp);
  *++yyvsp = yyval;
  /* Now `shift' the result of the reduction.  Determine what state
     that goes to, based on the state we popped back to and the rule
     number reduced by.  */
  yyn = yyr1[yyn];
  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
    yystate = yytable[yystate];
  else
    yystate = yydefgoto[yyn - YYNTOKENS];
  goto yynewstate;
/*------------------------------------.
| yyerrlab -- here on detecting error |
`------------------------------------*/
yyerrlab:
  /* If not already recovering from an error, report this error.  */
  if (!yyerrstatus)
    {
      ++yynerrs;
#if ! YYERROR_VERBOSE
      yyerror (YY_("syntax error"));
#else
      {
	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
	  {
	    YYSIZE_T yyalloc = 2 * yysize;
	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
	    if (yymsg != yymsgbuf)
	      YYSTACK_FREE (yymsg);
	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
	    if (yymsg)
	      yymsg_alloc = yyalloc;
	    else
	      {
		yymsg = yymsgbuf;
		yymsg_alloc = sizeof yymsgbuf;
	      }
	  }
	if (0 < yysize && yysize <= yymsg_alloc)
	  {
	    (void) yysyntax_error (yymsg, yystate, yychar);
	    yyerror (yymsg);
	  }
	else
	  {
	    yyerror (YY_("syntax error"));
	    if (yysize != 0)
	      goto yyexhaustedlab;
	  }
      }
#endif
    }
  if (yyerrstatus == 3)
    {
      /* If just tried and failed to reuse lookahead token after an
	 error, discard it.  */
      if (yychar <= YYEOF)
	{
	  /* Return failure if at end of input.  */
	  if (yychar == YYEOF)
	    YYABORT;
	}
      else
	{
	  yydestruct ("Error: discarding",
		      yytoken, &yylval);
	  yychar = YYEMPTY;
	}
    }
  /* Else will try to reuse lookahead token after shifting the error
     token.  */
  goto yyerrlab1;
/*---------------------------------------------------.
| yyerrorlab -- error raised explicitly by YYERROR.  |
`---------------------------------------------------*/
yyerrorlab:
  /* Pacify compilers like GCC when the user code never invokes
     YYERROR and the label yyerrorlab therefore never appears in user
     code.  */
  if (/*CONSTCOND*/ 0)
     goto yyerrorlab;
  /* Do not reclaim the symbols of the rule which action triggered
     this YYERROR.  */
  YYPOPSTACK (yylen);
  yylen = 0;
  YY_STACK_PRINT (yyss, yyssp);
  yystate = *yyssp;
  goto yyerrlab1;
/*-------------------------------------------------------------.
| yyerrlab1 -- common code for both syntax error and YYERROR.  |
`-------------------------------------------------------------*/
yyerrlab1:
  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
  for (;;)
    {
      yyn = yypact[yystate];
      if (yyn != YYPACT_NINF)
	{
	  yyn += YYTERROR;
	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
	    {
	      yyn = yytable[yyn];
	      if (0 < yyn)
		break;
	    }
	}
      /* Pop the current state because it cannot handle the error token.  */
      if (yyssp == yyss)
	YYABORT;
      yydestruct ("Error: popping",
		  yystos[yystate], yyvsp);
      YYPOPSTACK (1);
      yystate = *yyssp;
      YY_STACK_PRINT (yyss, yyssp);
    }
  *++yyvsp = yylval;
  /* Shift the error token.  */
  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
  yystate = yyn;
  goto yynewstate;
/*-------------------------------------.
| yyacceptlab -- YYACCEPT comes here.  |
`-------------------------------------*/
yyacceptlab:
  yyresult = 0;
  goto yyreturn;
/*-----------------------------------.
| yyabortlab -- YYABORT comes here.  |
`-----------------------------------*/
yyabortlab:
  yyresult = 1;
  goto yyreturn;
#if !defined(yyoverflow) || YYERROR_VERBOSE
/*-------------------------------------------------.
| yyexhaustedlab -- memory exhaustion comes here.  |
`-------------------------------------------------*/
yyexhaustedlab:
  yyerror (YY_("memory exhausted"));
  yyresult = 2;
  /* Fall through.  */
#endif
yyreturn:
  if (yychar != YYEMPTY)
     yydestruct ("Cleanup: discarding lookahead",
		 yytoken, &yylval);
  /* Do not reclaim the symbols of the rule which action triggered
     this YYABORT or YYACCEPT.  */
  YYPOPSTACK (yylen);
  YY_STACK_PRINT (yyss, yyssp);
  while (yyssp != yyss)
    {
      yydestruct ("Cleanup: popping",
		  yystos[*yyssp], yyvsp);
      YYPOPSTACK (1);
    }
#ifndef yyoverflow
  if (yyss != yyssa)
    YYSTACK_FREE (yyss);
#endif
#if YYERROR_VERBOSE
  if (yymsg != yymsgbuf)
    YYSTACK_FREE (yymsg);
#endif
  /* Make sure YYID is used.  */
  return YYID (yyresult);
}
 | |||||
| ↓ | _asn1_expand_object_id | 44 | 95 | 169 | ../../lib/parser_aux.c | 
| 
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), 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 = 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), 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), 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;
}
 | |||||
| ↓ | _asn1_yylex | 44 | 54 | 80 | ../../lib/ASN1.c | 
| 
static int
_asn1_yylex()
{
  int c,counter=0,k,lastc;
  char string[ASN1_MAX_NAME_SIZE+1]; /* will contain the next token */
  size_t i;
  while(1)
    {
    while((c=fgetc(file_asn1))==' ' || c=='\t' || c=='\n')
      if(c=='\n') lineNumber++;
    if(c==EOF){
      strcpy(lastToken,"End Of File");
      return 0;
    }
    if(c=='(' || c==')' || c=='[' || c==']' ||
       c=='{' || c=='}' || c==',' || c=='.' ||
       c=='+' || c=='|'){
      lastToken[0]=c;lastToken[1]=0;
      return c;
    }
    if(c=='-'){  /* Maybe the first '-' of a comment */
      if((c=fgetc(file_asn1))!='-'){
	ungetc(c,file_asn1);
	lastToken[0]='-';lastToken[1]=0;
	return '-';
      }
      else{ /* Comments */
	lastc=0;
	counter=0;
	/* A comment finishes at the next double hypen or the end of line */
	while((c=fgetc(file_asn1))!=EOF && c!='\n' &&
	      (lastc!='-' || (lastc=='-' && c!='-')))
	  lastc=c;
	if(c==EOF){
	  strcpy(lastToken,"End Of File");
	  return 0;
	}
	else{
	  if(c=='\n') lineNumber++;
	  continue; /* next char, please! (repeat the search) */
	}
      }
    }
    string[counter++]=c;
    /* Till the end of the token */
    while(!((c=fgetc(file_asn1))==EOF || c==' '|| c=='\t' || c=='\n' ||
	     c=='(' || c==')' || c=='[' || c==']' ||
	     c=='{' || c=='}' || c==',' || c=='.'))
      {
	if(counter>=ASN1_MAX_NAME_SIZE){
	  result_parse=ASN1_NAME_TOO_LONG;
	  return 0;
	}
	string[counter++]=c;
      }
    ungetc(c,file_asn1);
    string[counter]=0;
    strcpy(lastToken,string);
    /* Is STRING a number? */
    for(k=0;k | |||||
| ↓ | asn1_expand_any_defined_by | 43 | 101 | 211 | ../../lib/decoding.c | 
| 
asn1_retCode
asn1_expand_any_defined_by (ASN1_TYPE definitions, ASN1_TYPE * element)
{
  char definitionsName[ASN1_MAX_NAME_SIZE], name[2 * ASN1_MAX_NAME_SIZE + 1],
    value[ASN1_MAX_NAME_SIZE];
  asn1_retCode retCode = ASN1_SUCCESS, result;
  int len, len2, len3;
  ASN1_TYPE p, p2, p3, aux = ASN1_TYPE_EMPTY;
  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
  if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
    return ASN1_ELEMENT_NOT_FOUND;
  strcpy (definitionsName, definitions->name);
  strcat (definitionsName, ".");
  p = *element;
  while (p)
    {
      switch (type_field (p->type))
	{
	case TYPE_ANY:
	  if ((p->type & CONST_DEFINED_BY) && (p->value))
	    {
	      /* search the "DEF_BY" element */
	      p2 = p->down;
	      while ((p2) && (type_field (p2->type) != TYPE_CONSTANT))
		p2 = p2->right;
	      if (!p2)
		{
		  retCode = ASN1_ERROR_TYPE_ANY;
		  break;
		}
	      p3 = _asn1_find_up (p);
	      if (!p3)
		{
		  retCode = ASN1_ERROR_TYPE_ANY;
		  break;
		}
	      p3 = p3->down;
	      while (p3)
		{
		  if ((p3->name) && !(strcmp (p3->name, p2->name)))
		    break;
		  p3 = p3->right;
		}
	      if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
		  (p3->value == NULL))
		{
		  p3 = _asn1_find_up (p);
		  p3 = _asn1_find_up (p3);
		  if (!p3)
		    {
		      retCode = ASN1_ERROR_TYPE_ANY;
		      break;
		    }
		  p3 = p3->down;
		  while (p3)
		    {
		      if ((p3->name) && !(strcmp (p3->name, p2->name)))
			break;
		      p3 = p3->right;
		    }
		  if ((!p3) || (type_field (p3->type) != TYPE_OBJECT_ID) ||
		      (p3->value == NULL))
		    {
		      retCode = ASN1_ERROR_TYPE_ANY;
		      break;
		    }
		}
	      /* search the OBJECT_ID into definitions */
	      p2 = definitions->down;
	      while (p2)
		{
		  if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
		      (p2->type & CONST_ASSIGN))
		    {
		      strcpy (name, definitionsName);
		      strcat (name, p2->name);
		      len = ASN1_MAX_NAME_SIZE;
		      result =
			asn1_read_value (definitions, name, value, &len);
		      if ((result == ASN1_SUCCESS)
			  && (!strcmp (p3->value, value)))
			{
			  p2 = p2->right;	/* pointer to the structure to
						   use for expansion */
			  while ((p2) && (p2->type & CONST_ASSIGN))
			    p2 = p2->right;
			  if (p2)
			    {
			      strcpy (name, definitionsName);
			      strcat (name, p2->name);
			      result =
				asn1_create_element (definitions, name, &aux);
			      if (result == ASN1_SUCCESS)
				{
				  _asn1_set_name (aux, p->name);
				  len2 =
				    asn1_get_length_der (p->value,
							 p->value_len, &len3);
				  if (len2 < 0)
				    return ASN1_DER_ERROR;
				  result =
				    asn1_der_decoding (&aux, p->value + len3,
						       len2,
						       errorDescription);
				  if (result == ASN1_SUCCESS)
				    {
				      _asn1_set_right (aux, p->right);
				      _asn1_set_right (p, aux);
				      result = asn1_delete_structure (&p);
				      if (result == ASN1_SUCCESS)
					{
					  p = aux;
					  aux = ASN1_TYPE_EMPTY;
					  break;
					}
				      else
					{	/* error with asn1_delete_structure */
					  asn1_delete_structure (&aux);
					  retCode = result;
					  break;
					}
				    }
				  else
				    {	/* error with asn1_der_decoding */
				      retCode = result;
				      break;
				    }
				}
			      else
				{	/* error with asn1_create_element */
				  retCode = result;
				  break;
				}
			    }
			  else
			    {	/* error with the pointer to the structure to exapand */
			      retCode = ASN1_ERROR_TYPE_ANY;
			      break;
			    }
			}
		    }
		  p2 = p2->right;
		}		/* end while */
	      if (!p2)
		{
		  retCode = ASN1_ERROR_TYPE_ANY;
		  break;
		}
	    }
	  break;
	default:
	  break;
	}
      if (p->down)
	{
	  p = p->down;
	}
      else if (p == *element)
	{
	  p = NULL;
	  break;
	}
      else if (p->right)
	p = p->right;
      else
	{
	  while (1)
	    {
	      p = _asn1_find_up (p);
	      if (p == *element)
		{
		  p = NULL;
		  break;
		}
	      if (p->right)
		{
		  p = p->right;
		  break;
		}
	    }
	}
    }
  return retCode;
}
 | |||||
| ↓ | asn1_read_value | 47 | 83 | 161 | ../../lib/element.c | 
| 
asn1_retCode
asn1_read_value (ASN1_TYPE root, const char *name, void *ivalue, int *len)
{
  ASN1_TYPE node, p, p2;
  int len2, len3;
  int value_size = *len;
  unsigned char *value = ivalue;
  node = asn1_find_node (root, name);
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  if ((type_field (node->type) != TYPE_NULL) &&
      (type_field (node->type) != TYPE_CHOICE) &&
      !(node->type & CONST_DEFAULT) && !(node->type & CONST_ASSIGN) &&
      (node->value == NULL))
    return ASN1_VALUE_NOT_FOUND;
  switch (type_field (node->type))
    {
    case TYPE_NULL:
      PUT_STR_VALUE (value, value_size, "NULL");
      break;
    case TYPE_BOOLEAN:
      if ((node->type & CONST_DEFAULT) && (node->value == NULL))
	{
	  p = node->down;
	  while (type_field (p->type) != TYPE_DEFAULT)
	    p = p->right;
	  if (p->type & CONST_TRUE)
	    {
	      PUT_STR_VALUE (value, value_size, "TRUE");
	    }
	  else
	    {
	      PUT_STR_VALUE (value, value_size, "FALSE");
	    }
	}
      else if (node->value[0] == 'T')
	{
	  PUT_STR_VALUE (value, value_size, "TRUE");
	}
      else
	{
	  PUT_STR_VALUE (value, value_size, "FALSE");
	}
      break;
    case TYPE_INTEGER:
    case TYPE_ENUMERATED:
      if ((node->type & CONST_DEFAULT) && (node->value == NULL))
	{
	  p = node->down;
	  while (type_field (p->type) != TYPE_DEFAULT)
	    p = p->right;
	  if ((isdigit (p->value[0])) || (p->value[0] == '-')
	      || (p->value[0] == '+'))
	    {
	      if (_asn1_convert_integer
		  (p->value, value, value_size, len) != ASN1_SUCCESS)
		return ASN1_MEM_ERROR;
	    }
	  else
	    {			/* is an identifier like v1 */
	      p2 = node->down;
	      while (p2)
		{
		  if (type_field (p2->type) == TYPE_CONSTANT)
		    {
		      if ((p2->name) && (!strcmp (p2->name, p->value)))
			{
			  if (_asn1_convert_integer
			      (p2->value, value, value_size,
			       len) != ASN1_SUCCESS)
			    return ASN1_MEM_ERROR;
			  break;
			}
		    }
		  p2 = p2->right;
		}
	    }
	}
      else
	{
	  len2 = -1;
	  if (asn1_get_octet_der
	      (node->value, node->value_len, &len2, value, value_size,
	       len) != ASN1_SUCCESS)
	    return ASN1_MEM_ERROR;
	}
      break;
    case TYPE_OBJECT_ID:
      if (node->type & CONST_ASSIGN)
	{
	  value[0] = 0;
	  p = node->down;
	  while (p)
	    {
	      if (type_field (p->type) == TYPE_CONSTANT)
		{
		  ADD_STR_VALUE (value, value_size, p->value);
		  if (p->right)
		    {
		      ADD_STR_VALUE (value, value_size, ".");
		    }
		}
	      p = p->right;
	    }
	  *len = strlen (value) + 1;
	}
      else if ((node->type & CONST_DEFAULT) && (node->value == NULL))
	{
	  p = node->down;
	  while (type_field (p->type) != TYPE_DEFAULT)
	    p = p->right;
	  PUT_STR_VALUE (value, value_size, p->value);
	}
      else
	{
	  PUT_STR_VALUE (value, value_size, node->value);
	}
      break;
    case TYPE_TIME:
      PUT_STR_VALUE (value, value_size, node->value);
      break;
    case TYPE_OCTET_STRING:
      len2 = -1;
      if (asn1_get_octet_der
	  (node->value, node->value_len, &len2, value, value_size,
	   len) != ASN1_SUCCESS)
	return ASN1_MEM_ERROR;
      break;
    case TYPE_GENERALSTRING:
      len2 = -1;
      if (asn1_get_octet_der
	  (node->value, node->value_len, &len2, value, value_size,
	   len) != ASN1_SUCCESS)
	return ASN1_MEM_ERROR;
      break;
    case TYPE_BIT_STRING:
      len2 = -1;
      if (asn1_get_bit_der
	  (node->value, node->value_len, &len2, value, value_size,
	   len) != ASN1_SUCCESS)
	return ASN1_MEM_ERROR;
      break;
    case TYPE_CHOICE:
      PUT_STR_VALUE (value, value_size, node->down->name);
      break;
    case TYPE_ANY:
      len3 = -1;
      len2 = asn1_get_length_der (node->value, node->value_len, &len3);
      if (len2 < 0)
	return ASN1_DER_ERROR;
      PUT_VALUE (value, value_size, node->value + len3, len2);
      break;
    default:
      return ASN1_ELEMENT_NOT_FOUND;
      break;
    }
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | _asn1_check_identifier | 26 | 50 | 91 | ../../lib/parser_aux.c | 
| 
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), p->value);
	  p2 = asn1_find_node (node, name2);
	  if (p2 == NULL)
	    {
	      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), p2->value);
	      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), p2->value);
		  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_expand_identifier | 25 | 68 | 107 | ../../lib/structure.c | 
| 
static asn1_retCode
_asn1_expand_identifier (ASN1_TYPE * node, ASN1_TYPE root)
{
  ASN1_TYPE p, p2, p3;
  char name2[ASN1_MAX_NAME_SIZE + 2];
  int move;
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  p = *node;
  move = DOWN;
  while (!((p == *node) && (move == UP)))
    {
      if (move != UP)
	{
	  if (type_field (p->type) == TYPE_IDENTIFIER)
	    {
	      _asn1_str_cpy (name2, sizeof (name2), root->name);
	      _asn1_str_cat (name2, sizeof (name2), ".");
	      _asn1_str_cat (name2, sizeof (name2), p->value);
	      p2 = _asn1_copy_structure2 (root, name2);
	      if (p2 == NULL)
		{
		  return ASN1_IDENTIFIER_NOT_FOUND;
		}
	      _asn1_set_name (p2, p->name);
	      p2->right = p->right;
	      p2->left = p->left;
	      if (p->right)
		p->right->left = p2;
	      p3 = p->down;
	      if (p3)
		{
		  while (p3->right)
		    p3 = p3->right;
		  _asn1_set_right (p3, p2->down);
		  _asn1_set_down (p2, p->down);
		}
	      p3 = _asn1_find_left (p);
	      if (p3)
		_asn1_set_right (p3, p2);
	      else
		{
		  p3 = _asn1_find_up (p);
		  if (p3)
		    _asn1_set_down (p3, p2);
		  else
		    {
		      p2->left = NULL;
		    }
		}
	      if (p->type & CONST_SIZE)
		p2->type |= CONST_SIZE;
	      if (p->type & CONST_TAG)
		p2->type |= CONST_TAG;
	      if (p->type & CONST_OPTION)
		p2->type |= CONST_OPTION;
	      if (p->type & CONST_DEFAULT)
		p2->type |= CONST_DEFAULT;
	      if (p->type & CONST_SET)
		p2->type |= CONST_SET;
	      if (p->type & CONST_NOT_USED)
		p2->type |= CONST_NOT_USED;
	      if (p == *node)
		*node = p2;
	      _asn1_remove_node (p);
	      p = p2;
	      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);
    }
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | _asn1_ordering_set_of | 23 | 72 | 124 | ../../lib/coding.c | 
| 
static void
_asn1_ordering_set_of (unsigned char *der, int der_len, ASN1_TYPE node)
{
  struct vet
  {
    int end;
    struct vet *next, *prev;
  };
  int counter, len, len2, change;
  struct vet *first, *last, *p_vet, *p2_vet;
  ASN1_TYPE p;
  unsigned char *temp, class;
  unsigned long k, max;
  counter = 0;
  if (type_field (node->type) != TYPE_SET_OF)
    return;
  p = node->down;
  while ((type_field (p->type) == TYPE_TAG)
	 || (type_field (p->type) == TYPE_SIZE))
    p = p->right;
  p = p->right;
  if ((p == NULL) || (p->right == NULL))
    return;
  first = last = NULL;
  while (p)
    {
      p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
      if (p_vet == NULL)
	return;
      p_vet->next = NULL;
      p_vet->prev = last;
      if (first == NULL)
	first = p_vet;
      else
	last->next = p_vet;
      last = p_vet;
      /* extraction of tag and length */
      if (der_len - counter > 0)
	{
	  if (asn1_get_tag_der
	      (der + counter, der_len - counter, &class, &len,
	       NULL) != ASN1_SUCCESS)
	    return;
	  counter += len;
	  len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
	  if (len2 < 0)
	    return;
	  counter += len + len2;
	}
      p_vet->end = counter;
      p = p->right;
    }
  p_vet = first;
  while (p_vet)
    {
      p2_vet = p_vet->next;
      counter = 0;
      while (p2_vet)
	{
	  if ((p_vet->end - counter) > (p2_vet->end - p_vet->end))
	    max = p_vet->end - counter;
	  else
	    max = p2_vet->end - p_vet->end;
	  change = -1;
	  for (k = 0; k < max; k++)
	    if (der[counter + k] > der[p_vet->end + k])
	      {
		change = 1;
		break;
	      }
	    else if (der[counter + k] < der[p_vet->end + k])
	      {
		change = 0;
		break;
	      }
	  if ((change == -1)
	      && ((p_vet->end - counter) > (p2_vet->end - p_vet->end)))
	    change = 1;
	  if (change == 1)
	    {
	      /* change position */
	      temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
	      if (temp == NULL)
		return;
	      memcpy (temp, der + counter, (p_vet->end) - counter);
	      memcpy (der + counter, der + (p_vet->end),
		      (p2_vet->end) - (p_vet->end));
	      memcpy (der + counter + (p2_vet->end) - (p_vet->end), temp,
		      (p_vet->end) - counter);
	      _asn1_free (temp);
	      p_vet->end = counter + (p2_vet->end - p_vet->end);
	    }
	  counter = p_vet->end;
	  p2_vet = p2_vet->next;
	  p_vet = p_vet->next;
	}
      if (p_vet != first)
	p_vet->prev->next = NULL;
      else
	first = NULL;
      _asn1_free (p_vet);
      p_vet = first;
    }
}
 | |||||
| ↓ | asn1_expand_octet_string | 22 | 65 | 123 | ../../lib/decoding.c | 
| 
asn1_retCode
asn1_expand_octet_string (ASN1_TYPE definitions, ASN1_TYPE * element,
			  const char *octetName, const char *objectName)
{
  char name[2 * ASN1_MAX_NAME_SIZE + 1], value[ASN1_MAX_NAME_SIZE];
  asn1_retCode retCode = ASN1_SUCCESS, result;
  int len, len2, len3;
  ASN1_TYPE p2, aux = ASN1_TYPE_EMPTY;
  ASN1_TYPE octetNode = ASN1_TYPE_EMPTY, objectNode = ASN1_TYPE_EMPTY;
  char errorDescription[ASN1_MAX_ERROR_DESCRIPTION_SIZE];
  if ((definitions == ASN1_TYPE_EMPTY) || (*element == ASN1_TYPE_EMPTY))
    return ASN1_ELEMENT_NOT_FOUND;
  octetNode = asn1_find_node (*element, octetName);
  if (octetNode == ASN1_TYPE_EMPTY)
    return ASN1_ELEMENT_NOT_FOUND;
  if (type_field (octetNode->type) != TYPE_OCTET_STRING)
    return ASN1_ELEMENT_NOT_FOUND;
  if (octetNode->value == NULL)
    return ASN1_VALUE_NOT_FOUND;
  objectNode = asn1_find_node (*element, objectName);
  if (objectNode == ASN1_TYPE_EMPTY)
    return ASN1_ELEMENT_NOT_FOUND;
  if (type_field (objectNode->type) != TYPE_OBJECT_ID)
    return ASN1_ELEMENT_NOT_FOUND;
  if (objectNode->value == NULL)
    return ASN1_VALUE_NOT_FOUND;
  /* search the OBJECT_ID into definitions */
  p2 = definitions->down;
  while (p2)
    {
      if ((type_field (p2->type) == TYPE_OBJECT_ID) &&
	  (p2->type & CONST_ASSIGN))
	{
	  strcpy (name, definitions->name);
	  strcat (name, ".");
	  strcat (name, p2->name);
	  len = sizeof (value);
	  result = asn1_read_value (definitions, name, value, &len);
	  if ((result == ASN1_SUCCESS)
	      && (!strcmp (objectNode->value, value)))
	    {
	      p2 = p2->right;	/* pointer to the structure to
				   use for expansion */
	      while ((p2) && (p2->type & CONST_ASSIGN))
		p2 = p2->right;
	      if (p2)
		{
		  strcpy (name, definitions->name);
		  strcat (name, ".");
		  strcat (name, p2->name);
		  result = asn1_create_element (definitions, name, &aux);
		  if (result == ASN1_SUCCESS)
		    {
		      _asn1_set_name (aux, octetNode->name);
		      len2 =
			asn1_get_length_der (octetNode->value,
					     octetNode->value_len, &len3);
		      if (len2 < 0)
			return ASN1_DER_ERROR;
		      result =
			asn1_der_decoding (&aux, octetNode->value + len3,
					   len2, errorDescription);
		      if (result == ASN1_SUCCESS)
			{
			  _asn1_set_right (aux, octetNode->right);
			  _asn1_set_right (octetNode, aux);
			  result = asn1_delete_structure (&octetNode);
			  if (result == ASN1_SUCCESS)
			    {
			      aux = ASN1_TYPE_EMPTY;
			      break;
			    }
			  else
			    {	/* error with asn1_delete_structure */
			      asn1_delete_structure (&aux);
			      retCode = result;
			      break;
			    }
			}
		      else
			{	/* error with asn1_der_decoding */
			  retCode = result;
			  break;
			}
		    }
		  else
		    {		/* error with asn1_create_element */
		      retCode = result;
		      break;
		    }
		}
	      else
		{		/* error with the pointer to the structure to exapand */
		  retCode = ASN1_VALUE_NOT_VALID;
		  break;
		}
	    }
	}
      p2 = p2->right;
    }
  if (!p2)
    retCode = ASN1_VALUE_NOT_VALID;
  return retCode;
}
 | |||||
| ↓ | asn1_array2tree | 21 | 53 | 97 | ../../lib/structure.c | 
| 
asn1_retCode
asn1_array2tree (const ASN1_ARRAY_TYPE * array, ASN1_TYPE * definitions,
		 char *errorDescription)
{
  ASN1_TYPE p, p_last = NULL;
  unsigned long k;
  int move;
  asn1_retCode result;
  if (*definitions != ASN1_TYPE_EMPTY)
    return ASN1_ELEMENT_NOT_EMPTY;
  move = UP;
  k = 0;
  while (array[k].value || array[k].type || array[k].name)
    {
      p = _asn1_add_node (array[k].type & (~CONST_DOWN));
      if (array[k].name)
	_asn1_set_name (p, array[k].name);
      if (array[k].value)
	_asn1_set_value (p, array[k].value, strlen (array[k].value) + 1);
      if (*definitions == NULL)
	*definitions = p;
      if (move == DOWN)
	_asn1_set_down (p_last, p);
      else if (move == RIGHT)
	_asn1_set_right (p_last, p);
      p_last = p;
      if (array[k].type & CONST_DOWN)
	move = DOWN;
      else if (array[k].type & CONST_RIGHT)
	move = RIGHT;
      else
	{
	  while (1)
	    {
	      if (p_last == *definitions)
		break;
	      p_last = _asn1_find_up (p_last);
	      if (p_last == NULL)
		break;
	      if (p_last->type & CONST_RIGHT)
		{
		  p_last->type &= ~CONST_RIGHT;
		  move = RIGHT;
		  break;
		}
	    }			/* while */
	}
      k++;
    }				/* while */
  if (p_last == *definitions)
    {
      result = _asn1_check_identifier (*definitions);
      if (result == ASN1_SUCCESS)
	{
	  _asn1_change_integer_value (*definitions);
	  _asn1_expand_object_id (*definitions);
	}
    }
  else
    {
      result = ASN1_ARRAY_ERROR;
    }
  if (errorDescription != NULL)
    {
      if (result == ASN1_IDENTIFIER_NOT_FOUND)
	{
	  Estrcpy (errorDescription, ":: identifier '");
	  Estrcat (errorDescription, _asn1_identifierMissing);
	  Estrcat (errorDescription, "' not found");
	}
      else
	errorDescription[0] = 0;
    }
  if (result != ASN1_SUCCESS)
    {
      _asn1_delete_list_and_nodes ();
      *definitions = ASN1_TYPE_EMPTY;
    }
  else
    _asn1_delete_list ();
  return result;
}
 | |||||
| ↓ | _asn1_insert_tag_der | 35 | 75 | 151 | ../../lib/coding.c | 
| 
static asn1_retCode
_asn1_insert_tag_der (ASN1_TYPE node, unsigned char *der, int *counter,
		      int *max_len)
{
  ASN1_TYPE p;
  int tag_len, is_tag_implicit;
  unsigned char class, class_implicit = 0, temp[SIZEOF_UNSIGNED_INT * 3 + 1];
  unsigned long tag_implicit = 0;
  char tag_der[MAX_TAG_LEN];
  is_tag_implicit = 0;
  if (node->type & CONST_TAG)
    {
      p = node->down;
      while (p)
	{
	  if (type_field (p->type) == TYPE_TAG)
	    {
	      if (p->type & CONST_APPLICATION)
		class = ASN1_CLASS_APPLICATION;
	      else if (p->type & CONST_UNIVERSAL)
		class = ASN1_CLASS_UNIVERSAL;
	      else if (p->type & CONST_PRIVATE)
		class = ASN1_CLASS_PRIVATE;
	      else
		class = ASN1_CLASS_CONTEXT_SPECIFIC;
	      if (p->type & CONST_EXPLICIT)
		{
		  if (is_tag_implicit)
		    _asn1_tag_der (class_implicit, tag_implicit, tag_der,
				   &tag_len);
		  else
		    _asn1_tag_der (class | ASN1_CLASS_STRUCTURED,
				   strtoul (p->value, NULL, 10), tag_der,
				   &tag_len);
		  *max_len -= tag_len;
		  if (*max_len >= 0)
		    memcpy (der + *counter, tag_der, tag_len);
		  *counter += tag_len;
		  _asn1_ltostr (*counter, temp);
		  _asn1_set_name (p, temp);
		  is_tag_implicit = 0;
		}
	      else
		{		/* CONST_IMPLICIT */
		  if (!is_tag_implicit)
		    {
		      if ((type_field (node->type) == TYPE_SEQUENCE) ||
			  (type_field (node->type) == TYPE_SEQUENCE_OF) ||
			  (type_field (node->type) == TYPE_SET) ||
			  (type_field (node->type) == TYPE_SET_OF))
			class |= ASN1_CLASS_STRUCTURED;
		      class_implicit = class;
		      tag_implicit = strtoul (p->value, NULL, 10);
		      is_tag_implicit = 1;
		    }
		}
	    }
	  p = p->right;
	}
    }
  if (is_tag_implicit)
    {
      _asn1_tag_der (class_implicit, tag_implicit, tag_der, &tag_len);
    }
  else
    {
      switch (type_field (node->type))
	{
	case TYPE_NULL:
	  _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_NULL, tag_der,
			 &tag_len);
	  break;
	case TYPE_BOOLEAN:
	  _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BOOLEAN, tag_der,
			 &tag_len);
	  break;
	case TYPE_INTEGER:
	  _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_INTEGER, tag_der,
			 &tag_len);
	  break;
	case TYPE_ENUMERATED:
	  _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_ENUMERATED, tag_der,
			 &tag_len);
	  break;
	case TYPE_OBJECT_ID:
	  _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OBJECT_ID, tag_der,
			 &tag_len);
	  break;
	case TYPE_TIME:
	  if (node->type & CONST_UTC)
	    {
	      _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_UTCTime, tag_der,
			     &tag_len);
	    }
	  else
	    _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALIZEDTime,
			   tag_der, &tag_len);
	  break;
	case TYPE_OCTET_STRING:
	  _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_OCTET_STRING, tag_der,
			 &tag_len);
	  break;
	case TYPE_GENERALSTRING:
	  _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_GENERALSTRING,
			 tag_der, &tag_len);
	  break;
	case TYPE_BIT_STRING:
	  _asn1_tag_der (ASN1_CLASS_UNIVERSAL, ASN1_TAG_BIT_STRING, tag_der,
			 &tag_len);
	  break;
	case TYPE_SEQUENCE:
	case TYPE_SEQUENCE_OF:
	  _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
			 ASN1_TAG_SEQUENCE, tag_der, &tag_len);
	  break;
	case TYPE_SET:
	case TYPE_SET_OF:
	  _asn1_tag_der (ASN1_CLASS_UNIVERSAL | ASN1_CLASS_STRUCTURED,
			 ASN1_TAG_SET, tag_der, &tag_len);
	  break;
	case TYPE_TAG:
	  tag_len = 0;
	  break;
	case TYPE_CHOICE:
	  tag_len = 0;
	  break;
	case TYPE_ANY:
	  tag_len = 0;
	  break;
	default:
	  return ASN1_GENERIC_ERROR;
	}
    }
  *max_len -= tag_len;
  if (*max_len >= 0)
    memcpy (der + *counter, tag_der, tag_len);
  *counter += tag_len;
  if (*max_len < 0)
    return ASN1_MEM_ERROR;
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | asn1_find_node | 20 | 50 | 95 | ../../lib/parser_aux.c | 
| 
ASN1_TYPE
asn1_find_node (ASN1_TYPE pointer, const char *name)
{
  ASN1_TYPE p;
  char *n_end, n[ASN1_MAX_NAME_SIZE + 1];
  const char *n_start;
  if (pointer == NULL)
    return NULL;
  if (name == NULL)
    return NULL;
  p = pointer;
  n_start = name;
  if (p->name != NULL)
    {				/* has *pointer got a name ? */
      n_end = strchr (n_start, '.');	/* search the first dot */
      if (n_end)
	{
	  memcpy (n, n_start, n_end - n_start);
	  n[n_end - n_start] = 0;
	  n_start = n_end;
	  n_start++;
	}
      else
	{
	  _asn1_str_cpy (n, sizeof (n), n_start);
	  n_start = NULL;
	}
      while (p)
	{
	  if ((p->name) && (!strcmp (p->name, n)))
	    break;
	  else
	    p = p->right;
	}			/* while */
      if (p == NULL)
	return NULL;
    }
  else
    {				/* *pointer doesn't have a name */
      if (n_start[0] == 0)
	return p;
    }
  while (n_start)
    {				/* Has the end of NAME been reached? */
      n_end = strchr (n_start, '.');	/* search the next dot */
      if (n_end)
	{
	  memcpy (n, n_start, n_end - n_start);
	  n[n_end - n_start] = 0;
	  n_start = n_end;
	  n_start++;
	}
      else
	{
	  _asn1_str_cpy (n, sizeof (n), n_start);
	  n_start = NULL;
	}
      if (p->down == NULL)
	return NULL;
      p = p->down;
      /* The identifier "?LAST" indicates the last element
         in the right chain. */
      if (!strcmp (n, "?LAST"))
	{
	  if (p == NULL)
	    return NULL;
	  while (p->right)
	    p = p->right;
	}
      else
	{			/* no "?LAST" */
	  while (p)
	    {
	      if ((p->name) && (!strcmp (p->name, n)))
		break;
	      else
		p = p->right;
	    }
	  if (p == NULL)
	    return NULL;
	}
    }				/* while */
  return p;
}
 | |||||
| ↓ | _asn1_type_choice_config | 20 | 47 | 83 | ../../lib/structure.c | 
| 
static asn1_retCode
_asn1_type_choice_config (ASN1_TYPE node)
{
  ASN1_TYPE p, p2, p3, p4;
  int move, tlen;
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  p = node;
  move = DOWN;
  while (!((p == node) && (move == UP)))
    {
      if (move != UP)
	{
	  if ((type_field (p->type) == TYPE_CHOICE) && (p->type & CONST_TAG))
	    {
	      p2 = p->down;
	      while (p2)
		{
		  if (type_field (p2->type) != TYPE_TAG)
		    {
		      p2->type |= CONST_TAG;
		      p3 = _asn1_find_left (p2);
		      while (p3)
			{
			  if (type_field (p3->type) == TYPE_TAG)
			    {
			      p4 = _asn1_add_node_only (p3->type);
			      tlen = strlen (p3->value);
			      if (tlen > 0)
				_asn1_set_value (p4, p3->value, tlen + 1);
			      _asn1_set_right (p4, p2->down);
			      _asn1_set_down (p2, p4);
			    }
			  p3 = _asn1_find_left (p3);
			}
		    }
		  p2 = p2->right;
		}
	      p->type &= ~(CONST_TAG);
	      p2 = p->down;
	      while (p2)
		{
		  p3 = p2->right;
		  if (type_field (p2->type) == TYPE_TAG)
		    asn1_delete_structure (&p2);
		  p2 = p3;
		}
	    }
	  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;
}
 | |||||
| ↓ | _asn1_get_octet_string | 17 | 47 | 82 | ../../lib/decoding.c | 
| 
static asn1_retCode
_asn1_get_octet_string (const unsigned char *der, ASN1_TYPE node, int *len)
{
  int len2, len3, counter, tot_len, indefinite;
  counter = 0;
  if (*(der - 1) & ASN1_CLASS_STRUCTURED)
    {
      tot_len = 0;
      indefinite = asn1_get_length_der (der, *len, &len3);
      if (indefinite < -1)
	return ASN1_DER_ERROR;
      counter += len3;
      if (indefinite >= 0)
	indefinite += len3;
      while (1)
	{
	  if (counter > (*len))
	    return ASN1_DER_ERROR;
	  if (indefinite == -1)
	    {
	      if ((der[counter] == 0) && (der[counter + 1] == 0))
		{
		  counter += 2;
		  break;
		}
	    }
	  else if (counter >= indefinite)
	    break;
	  if (der[counter] != ASN1_TAG_OCTET_STRING)
	    return ASN1_DER_ERROR;
	  counter++;
	  len2 = asn1_get_length_der (der + counter, *len - counter, &len3);
	  if (len2 <= 0)
	    return ASN1_DER_ERROR;
	  counter += len3 + len2;
	  tot_len += len2;
	}
      /* copy */
      if (node)
	{
	  unsigned char temp[DER_LEN];
	  int ret;
	  len2 = sizeof (temp);
	  asn1_length_der (tot_len, temp, &len2);
	  _asn1_set_value (node, temp, len2);
	  tot_len += len2;
	  ret = _asn1_extract_der_octet (node, der, *len);
	  if (ret != ASN1_SUCCESS)
	    return ret;
	}
    }
  else
    {				/* NOT STRUCTURED */
      len2 = asn1_get_length_der (der, *len, &len3);
      if (len2 < 0)
	return ASN1_DER_ERROR;
      if (len3 + len2 > *len)
	return ASN1_DER_ERROR;
      if (node)
	_asn1_set_value (node, der, len3 + len2);
      counter = len3 + len2;
    }
  *len = counter;
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | _asn1_ordering_set | 16 | 59 | 104 | ../../lib/coding.c | 
| 
static void
_asn1_ordering_set (unsigned char *der, int der_len, ASN1_TYPE node)
{
  struct vet
  {
    int end;
    unsigned long value;
    struct vet *next, *prev;
  };
  int counter, len, len2;
  struct vet *first, *last, *p_vet, *p2_vet;
  ASN1_TYPE p;
  unsigned char class, *temp;
  unsigned long tag;
  counter = 0;
  if (type_field (node->type) != TYPE_SET)
    return;
  p = node->down;
  while ((type_field (p->type) == TYPE_TAG)
	 || (type_field (p->type) == TYPE_SIZE))
    p = p->right;
  if ((p == NULL) || (p->right == NULL))
    return;
  first = last = NULL;
  while (p)
    {
      p_vet = (struct vet *) _asn1_malloc (sizeof (struct vet));
      if (p_vet == NULL)
	return;
      p_vet->next = NULL;
      p_vet->prev = last;
      if (first == NULL)
	first = p_vet;
      else
	last->next = p_vet;
      last = p_vet;
      /* tag value calculation */
      if (asn1_get_tag_der
	  (der + counter, der_len - counter, &class, &len2,
	   &tag) != ASN1_SUCCESS)
	return;
      p_vet->value = (class << 24) | tag;
      counter += len2;
      /* extraction and length */
      len2 = asn1_get_length_der (der + counter, der_len - counter, &len);
      if (len2 < 0)
	return;
      counter += len + len2;
      p_vet->end = counter;
      p = p->right;
    }
  p_vet = first;
  while (p_vet)
    {
      p2_vet = p_vet->next;
      counter = 0;
      while (p2_vet)
	{
	  if (p_vet->value > p2_vet->value)
	    {
	      /* change position */
	      temp = (unsigned char *) _asn1_malloc (p_vet->end - counter);
	      if (temp == NULL)
		return;
	      memcpy (temp, der + counter, p_vet->end - counter);
	      memcpy (der + counter, der + p_vet->end,
		      p2_vet->end - p_vet->end);
	      memcpy (der + counter + p2_vet->end - p_vet->end, temp,
		      p_vet->end - counter);
	      _asn1_free (temp);
	      tag = p_vet->value;
	      p_vet->value = p2_vet->value;
	      p2_vet->value = tag;
	      p_vet->end = counter + (p2_vet->end - p_vet->end);
	    }
	  counter = p_vet->end;
	  p2_vet = p2_vet->next;
	  p_vet = p_vet->next;
	}
      if (p_vet != first)
	p_vet->prev->next = NULL;
      else
	first = NULL;
      _asn1_free (p_vet);
      p_vet = first;
    }
}
 | |||||
| ↓ | yysyntax_error | 15 | 62 | 100 | ../../lib/ASN1.c | 
| 
static YYSIZE_T
yysyntax_error (char *yyresult, int yystate, int yychar)
{
  int yyn = yypact[yystate];
  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
    return 0;
  else
    {
      int yytype = YYTRANSLATE (yychar);
      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
      YYSIZE_T yysize = yysize0;
      YYSIZE_T yysize1;
      int yysize_overflow = 0;
      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
      int yyx;
# if 0
      /* This is so xgettext sees the translatable formats that are
	 constructed on the fly.  */
      YY_("syntax error, unexpected %s");
      YY_("syntax error, unexpected %s, expecting %s");
      YY_("syntax error, unexpected %s, expecting %s or %s");
      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
# endif
      char *yyfmt;
      char const *yyf;
      static char const yyunexpected[] = "syntax error, unexpected %s";
      static char const yyexpecting[] = ", expecting %s";
      static char const yyor[] = " or %s";
      char yyformat[sizeof yyunexpected
		    + sizeof yyexpecting - 1
		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
		       * (sizeof yyor - 1))];
      char const *yyprefix = yyexpecting;
      /* Start YYX at -YYN if negative to avoid negative indexes in
	 YYCHECK.  */
      int yyxbegin = yyn < 0 ? -yyn : 0;
      /* Stay within bounds of both yycheck and yytname.  */
      int yychecklim = YYLAST - yyn + 1;
      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
      int yycount = 1;
      yyarg[0] = yytname[yytype];
      yyfmt = yystpcpy (yyformat, yyunexpected);
      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
	  {
	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
	      {
		yycount = 1;
		yysize = yysize0;
		yyformat[sizeof yyunexpected - 1] = '\0';
		break;
	      }
	    yyarg[yycount++] = yytname[yyx];
	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
	    yysize_overflow |= (yysize1 < yysize);
	    yysize = yysize1;
	    yyfmt = yystpcpy (yyfmt, yyprefix);
	    yyprefix = yyor;
	  }
      yyf = YY_(yyformat);
      yysize1 = yysize + yystrlen (yyf);
      yysize_overflow |= (yysize1 < yysize);
      yysize = yysize1;
      if (yysize_overflow)
	return YYSIZE_MAXIMUM;
      if (yyresult)
	{
	  /* Avoid sprintf, as that infringes on the user's name space.
	     Don't have undefined behavior even if the translation
	     produced a string with the wrong number of "%s"s.  */
	  char *yyp = yyresult;
	  int yyi = 0;
	  while ((*yyp = *yyf) != '\0')
	    {
	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
		{
		  yyp += yytnamerr (yyp, yyarg[yyi++]);
		  yyf += 2;
		}
	      else
		{
		  yyp++;
		  yyf++;
		}
	    }
	}
      return yysize;
    }
}
 | |||||
| ↓ | _asn1_convert_integer | 15 | 35 | 50 | ../../lib/element.c | 
| 
asn1_retCode
_asn1_convert_integer (const char *value, unsigned char *value_out,
		       int value_out_size, int *len)
{
  char negative;
  unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
  long valtmp;
  int k, k2;
  valtmp = strtol (value, NULL, 10);
  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
    {
      val[SIZEOF_UNSIGNED_LONG_INT - k - 1] = (valtmp >> (8 * k)) & 0xFF;
    }
  if (val[0] & 0x80)
    negative = 1;
  else
    negative = 0;
  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT - 1; k++)
    {
      if (negative && (val[k] != 0xFF))
	break;
      else if (!negative && val[k])
	break;
    }
  if ((negative && !(val[k] & 0x80)) || (!negative && (val[k] & 0x80)))
    k--;
  *len = SIZEOF_UNSIGNED_LONG_INT - k;
  if (SIZEOF_UNSIGNED_LONG_INT - k > value_out_size)
    /* VALUE_OUT is too short to contain the value conversion */
    return ASN1_MEM_ERROR;
  for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++)
    value_out[k2 - k] = val[k2];
#if 0
  printf ("_asn1_convert_integer: valueIn=%s, lenOut=%d", value, *len);
  for (k = 0; k < SIZEOF_UNSIGNED_LONG_INT; k++)
    printf (", vOut[%d]=%d", k, value_out[k]);
  printf ("\n");
#endif
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | asn1_read_tag | 29 | 51 | 101 | ../../lib/element.c | 
| 
asn1_retCode
asn1_read_tag (ASN1_TYPE root, const char *name, int *tagValue,
	       int *classValue)
{
  ASN1_TYPE node, p, pTag;
  node = asn1_find_node (root, name);
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  p = node->down;
  /* pTag will points to the IMPLICIT TAG */
  pTag = NULL;
  if (node->type & CONST_TAG)
    {
      while (p)
	{
	  if (type_field (p->type) == TYPE_TAG)
	    {
	      if ((p->type & CONST_IMPLICIT) && (pTag == NULL))
		pTag = p;
	      else if (p->type & CONST_EXPLICIT)
		pTag = NULL;
	    }
	  p = p->right;
	}
    }
  if (pTag)
    {
      *tagValue = strtoul (pTag->value, NULL, 10);
      if (pTag->type & CONST_APPLICATION)
	*classValue = ASN1_CLASS_APPLICATION;
      else if (pTag->type & CONST_UNIVERSAL)
	*classValue = ASN1_CLASS_UNIVERSAL;
      else if (pTag->type & CONST_PRIVATE)
	*classValue = ASN1_CLASS_PRIVATE;
      else
	*classValue = ASN1_CLASS_CONTEXT_SPECIFIC;
    }
  else
    {
      *classValue = ASN1_CLASS_UNIVERSAL;
      switch (type_field (node->type))
	{
	case TYPE_NULL:
	  *tagValue = ASN1_TAG_NULL;
	  break;
	case TYPE_BOOLEAN:
	  *tagValue = ASN1_TAG_BOOLEAN;
	  break;
	case TYPE_INTEGER:
	  *tagValue = ASN1_TAG_INTEGER;
	  break;
	case TYPE_ENUMERATED:
	  *tagValue = ASN1_TAG_ENUMERATED;
	  break;
	case TYPE_OBJECT_ID:
	  *tagValue = ASN1_TAG_OBJECT_ID;
	  break;
	case TYPE_TIME:
	  if (node->type & CONST_UTC)
	    {
	      *tagValue = ASN1_TAG_UTCTime;
	    }
	  else
	    *tagValue = ASN1_TAG_GENERALIZEDTime;
	  break;
	case TYPE_OCTET_STRING:
	  *tagValue = ASN1_TAG_OCTET_STRING;
	  break;
	case TYPE_GENERALSTRING:
	  *tagValue = ASN1_TAG_GENERALSTRING;
	  break;
	case TYPE_BIT_STRING:
	  *tagValue = ASN1_TAG_BIT_STRING;
	  break;
	case TYPE_SEQUENCE:
	case TYPE_SEQUENCE_OF:
	  *tagValue = ASN1_TAG_SEQUENCE;
	  break;
	case TYPE_SET:
	case TYPE_SET_OF:
	  *tagValue = ASN1_TAG_SET;
	  break;
	case TYPE_TAG:
	case TYPE_CHOICE:
	case TYPE_ANY:
	  break;
	default:
	  break;
	}
    }
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | _asn1_objectid_der | 14 | 44 | 69 | ../../lib/coding.c | 
| 
static asn1_retCode
_asn1_objectid_der (unsigned char *str, unsigned char *der, int *der_len)
{
  int len_len, counter, k, first, max_len;
  char *temp, *n_end, *n_start;
  unsigned char bit7;
  unsigned long val, val1 = 0;
  max_len = *der_len;
  temp = (char *) _asn1_malloc (strlen (str) + 2);
  if (temp == NULL)
    return ASN1_MEM_ALLOC_ERROR;
  strcpy (temp, str);
  strcat (temp, ".");
  counter = 0;
  n_start = temp;
  while ((n_end = strchr (n_start, '.')))
    {
      *n_end = 0;
      val = strtoul (n_start, NULL, 10);
      counter++;
      if (counter == 1)
	val1 = val;
      else if (counter == 2)
	{
	  if (max_len > 0)
	    der[0] = 40 * val1 + val;
	  *der_len = 1;
	}
      else
	{
	  first = 0;
	  for (k = 4; k >= 0; k--)
	    {
	      bit7 = (val >> (k * 7)) & 0x7F;
	      if (bit7 || first || !k)
		{
		  if (k)
		    bit7 |= 0x80;
		  if (max_len > (*der_len))
		    der[*der_len] = bit7;
		  (*der_len)++;
		  first = 1;
		}
	    }
	}
      n_start = n_end + 1;
    }
  asn1_length_der (*der_len, NULL, &len_len);
  if (max_len >= (*der_len + len_len))
    {
      memmove (der + len_len, der, *der_len);
      asn1_length_der (*der_len, der, &len_len);
    }
  *der_len += len_len;
  _asn1_free (temp);
  if (max_len < (*der_len))
    return ASN1_MEM_ERROR;
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | _asn1_type_set_config | 14 | 30 | 58 | ../../lib/parser_aux.c | 
| 
asn1_retCode
_asn1_type_set_config (ASN1_TYPE node)
{
  ASN1_TYPE p, p2;
  int move;
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  p = node;
  move = DOWN;
  while (!((p == node) && (move == UP)))
    {
      if (move != UP)
	{
	  if (type_field (p->type) == TYPE_SET)
	    {
	      p2 = p->down;
	      while (p2)
		{
		  if (type_field (p2->type) != TYPE_TAG)
		    p2->type |= CONST_SET | CONST_NOT_USED;
		  p2 = p2->right;
		}
	    }
	  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;
}
 | |||||
| ↓ | _asn1_get_objectid_der | 13 | 39 | 60 | ../../lib/decoding.c | 
| 
static int
_asn1_get_objectid_der (const unsigned char *der, int der_len, int *ret_len,
			char *str, int str_size)
{
  int len_len, len, k;
  int leading;
  char temp[20];
  unsigned long val, val1, prev_val;
  *ret_len = 0;
  if (str && str_size > 0)
    str[0] = 0;			/* no oid */
  if (str == NULL || der_len <= 0)
    return ASN1_GENERIC_ERROR;
  len = asn1_get_length_der (der, der_len, &len_len);
  if (len < 0 || len > der_len || len_len > der_len)
    return ASN1_DER_ERROR;
  val1 = der[len_len] / 40;
  val = der[len_len] - val1 * 40;
  _asn1_str_cpy (str, str_size, _asn1_ltostr (val1, temp));
  _asn1_str_cat (str, str_size, ".");
  _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
  prev_val = 0;
  val = 0;
  leading = 1;
  for (k = 1; k < len; k++)
    {
      /* X.690 mandates that the leading byte must never be 0x80
       */
      if (leading != 0 && der[len_len + k] == 0x80)
	return ASN1_DER_ERROR;
      leading = 0;
      /* check for wrap around */
      val = val << 7;
      val |= der[len_len + k] & 0x7F;
      if (val < prev_val)
	return ASN1_DER_ERROR;
      prev_val = val;
      if (!(der[len_len + k] & 0x80))
	{
	  _asn1_str_cat (str, str_size, ".");
	  _asn1_str_cat (str, str_size, _asn1_ltostr (val, temp));
	  val = 0;
	  prev_val = 0;
	  leading = 1;
	}
    }
  *ret_len = len + len_len;
  return ASN1_SUCCESS;
}
 | |||||
| ↓ | _asn1_delete_not_used | 13 | 30 | 58 | ../../lib/decoding.c | 
| 
static int
_asn1_delete_not_used (ASN1_TYPE node)
{
  ASN1_TYPE p, p2;
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  p = node;
  while (p)
    {
      if (p->type & CONST_NOT_USED)
	{
	  p2 = NULL;
	  if (p != node)
	    {
	      p2 = _asn1_find_left (p);
	      if (!p2)
		p2 = _asn1_find_up (p);
	    }
	  asn1_delete_structure (&p);
	  p = p2;
	}
      if (!p)
	break;			/* reach node */
      if (p->down)
	{
	  p = p->down;
	}
      else
	{
	  if (p == node)
	    p = NULL;
	  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_set_default_tag | 13 | 22 | 47 | ../../lib/parser_aux.c | 
| 
asn1_retCode
_asn1_set_default_tag (ASN1_TYPE node)
{
  ASN1_TYPE p;
  if ((node == NULL) || (type_field (node->type) != TYPE_DEFINITIONS))
    return ASN1_ELEMENT_NOT_FOUND;
  p = node;
  while (p)
    {
      if ((type_field (p->type) == TYPE_TAG) &&
	  !(p->type & CONST_EXPLICIT) && !(p->type & CONST_IMPLICIT))
	{
	  if (node->type & CONST_EXPLICIT)
	    p->type |= CONST_EXPLICIT;
	  else
	    p->type |= CONST_IMPLICIT;
	}
      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_create_static_structure | 12 | 41 | 78 | ../../lib/structure.c | 
| 
asn1_retCode
_asn1_create_static_structure (ASN1_TYPE pointer, char *output_file_name,
			       char *vector_name)
{
  FILE *file;
  ASN1_TYPE p;
  unsigned long t;
  file = fopen (output_file_name, "w");
  if (file == NULL)
    return ASN1_FILE_NOT_FOUND;
  fprintf (file, "#if HAVE_CONFIG_H\n");
  fprintf (file, "# include \"config.h\"\n");
  fprintf (file, "#endif\n\n");
  fprintf (file, "#include  | |||||
| ↓ | _asn1_copy_structure3 | 12 | 37 | 67 | ../../lib/structure.c | 
| 
ASN1_TYPE
_asn1_copy_structure3 (ASN1_TYPE source_node)
{
  ASN1_TYPE dest_node, p_s, p_d, p_d_prev;
  int move;
  if (source_node == NULL)
    return NULL;
  dest_node = _asn1_add_node_only (source_node->type);
  p_s = source_node;
  p_d = dest_node;
  move = DOWN;
  do
    {
      if (move != UP)
	{
	  if (p_s->name)
	    _asn1_set_name (p_d, p_s->name);
	  if (p_s->value)
	    _asn1_set_value (p_d, p_s->value, p_s->value_len);
	  move = DOWN;
	}
      else
	move = RIGHT;
      if (move == DOWN)
	{
	  if (p_s->down)
	    {
	      p_s = p_s->down;
	      p_d_prev = p_d;
	      p_d = _asn1_add_node_only (p_s->type);
	      _asn1_set_down (p_d_prev, p_d);
	    }
	  else
	    move = RIGHT;
	}
      if (p_s == source_node)
	break;
      if (move == RIGHT)
	{
	  if (p_s->right)
	    {
	      p_s = p_s->right;
	      p_d_prev = p_d;
	      p_d = _asn1_add_node_only (p_s->type);
	      _asn1_set_right (p_d_prev, p_d);
	    }
	  else
	    move = UP;
	}
      if (move == UP)
	{
	  p_s = _asn1_find_up (p_s);
	  p_d = _asn1_find_up (p_d);
	}
    }
  while (p_s != source_node);
  return dest_node;
}
 | |||||
| ↓ | _asn1_change_integer_value | 12 | 28 | 56 | ../../lib/parser_aux.c | 
| 
asn1_retCode
_asn1_change_integer_value (ASN1_TYPE node)
{
  ASN1_TYPE p;
  unsigned char val[SIZEOF_UNSIGNED_LONG_INT];
  unsigned char val2[SIZEOF_UNSIGNED_LONG_INT + 1];
  int len;
  if (node == NULL)
    return ASN1_ELEMENT_NOT_FOUND;
  p = node;
  while (p)
    {
      if ((type_field (p->type) == TYPE_INTEGER) && (p->type & CONST_ASSIGN))
	{
	  if (p->value)
	    {
	      _asn1_convert_integer (p->value, val, sizeof (val), &len);
	      asn1_octet_der (val, len, val2, &len);
	      _asn1_set_value (p, val2, len);
	    }
	}
      if (p->down)
	{
	  p = p->down;
	}
      else
	{
	  if (p == node)
	    p = NULL;
	  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_get_tag_der | 11 | 24 | 44 | ../../lib/decoding.c | 
| 
int
asn1_get_tag_der (const unsigned char *der, int der_len,
		  unsigned char *cls, int *len, unsigned long *tag)
{
  int punt, ris;
  if (der == NULL || der_len < 2 || len == NULL)
    return ASN1_DER_ERROR;
  *cls = der[0] & 0xE0;
  if ((der[0] & 0x1F) != 0x1F)
    {
      /* short form */
      *len = 1;
      ris = der[0] & 0x1F;
    }
  else
    {
      /* Long form */
      punt = 1;
      ris = 0;
      while (punt <= der_len && der[punt] & 128)
	{
	  int last = ris;
	  ris = ris * 128 + (der[punt++] & 0x7F);
	  if (ris < last)
	    /* wrapper around, and no bignums... */
	    return ASN1_DER_ERROR;
	}
      if (punt >= der_len)
	return ASN1_DER_ERROR;
      {
	int last = ris;
	ris = ris * 128 + (der[punt++] & 0x7F);
	if (ris < last)
	  /* wrapper around, and no bignums... */
	  return ASN1_DER_ERROR;
      }
      *len = punt;
    }
  if (tag)
    *tag = ris;
  return ASN1_SUCCESS;
}
 | |||||
| _asn1_get_indefinite_length_string | 10 | 27 | 49 | ../../lib/decoding.c | |
| _asn1_complete_explicit_tag | 10 | 26 | 56 | ../../lib/coding.c | |
| asn1_parser2array | 9 | 48 | 95 | ../../lib/ASN1.c | |
| asn1_find_structure_from_oid | 9 | 23 | 43 | ../../lib/structure.c | |
| asn1_delete_structure | 8 | 25 | 50 | ../../lib/structure.c | |
| yytnamerr | 11 | 20 | 38 | ../../lib/ASN1.c | |
| _asn1_append_value | 7 | 22 | 39 | ../../lib/parser_aux.c | |
| _asn1_extract_der_octet | 7 | 20 | 44 | ../../lib/decoding.c | |
| asn1_get_length_der | 7 | 20 | 43 | ../../lib/decoding.c | |
| _asn1_append_sequence_set | 7 | 20 | 33 | ../../lib/element.c | |
| _asn1_set_value | 7 | 17 | 31 | ../../lib/parser_aux.c | |
| _asn1_create_errorDescription | 11 | 29 | 42 | ../../lib/ASN1.c | |
| asn1_parser2tree | 6 | 26 | 58 | ../../lib/ASN1.c | |
| asn1_length_der | 6 | 15 | 31 | ../../lib/coding.c | |
| _asn1_set_name | 6 | 13 | 25 | ../../lib/parser_aux.c | |
| asn1_number_of_elements | 6 | 13 | 25 | ../../lib/structure.c | |
| _asn1_remove_node | 5 | 7 | 12 | ../../lib/parser_aux.c | |
| asn1_copy_node | 5 | 21 | 40 | ../../lib/structure.c | |
| asn1_delete_element | 5 | 14 | 25 | ../../lib/structure.c | |
| _asn1_set_value_m | 5 | 12 | 22 | ../../lib/parser_aux.c | |
| _asn1_get_time_der | 5 | 10 | 17 | ../../lib/decoding.c | |
| _asn1_find_up | 4 | 7 | 15 | ../../lib/parser_aux.c | |
| _asn1_find_left | 4 | 3 | 8 | ../../lib/structure.c | |
| _asn1_ltostr | 4 | 22 | 32 | ../../lib/parser_aux.c | |
| _asn1_tag_der | 4 | 14 | 29 | ../../lib/coding.c | |
| _asn1_hierarchical_name | 4 | 12 | 25 | ../../lib/element.c | |
| asn1_get_bit_der | 4 | 12 | 25 | ../../lib/decoding.c | |
| asn1_get_octet_der | 4 | 11 | 26 | ../../lib/decoding.c | |
| _asn1_time_der | 4 | 11 | 19 | ../../lib/coding.c | |
| yy_symbol_value_print | 3 | 6 | 24 | ../../lib/ASN1.c | |
| asn1_get_length_ber | 3 | 9 | 17 | ../../lib/decoding.c | |
| asn1_strerror | 3 | 7 | 11 | ../../lib/errors.c | |
| _asn1_get_last_right | 3 | 7 | 12 | ../../lib/parser_aux.c | |
| _asn1_str_cat | 3 | 7 | 19 | ../../lib/gstr.c | |
| _asn1_str_cpy | 3 | 6 | 18 | ../../lib/gstr.c | |
| _asn1_set_down | 3 | 6 | 10 | ../../lib/parser_aux.c | |
| _asn1_set_right | 3 | 6 | 10 | ../../lib/parser_aux.c | |
| asn1_octet_der | 3 | 6 | 12 | ../../lib/coding.c | |
| asn1_check_version | 3 | 3 | 8 | ../../lib/version.c | |
| _asn1_add_node | 3 | 14 | 25 | ../../lib/parser_aux.c | |
| asn1_bit_der | 3 | 13 | 20 | ../../lib/coding.c | |
| _asn1_set_value_octet | 3 | 10 | 17 | ../../lib/parser_aux.c | |
| yydestruct | 2 | 5 | 32 | ../../lib/ASN1.c | |
| yy_stack_print | 2 | 7 | 17 | ../../lib/ASN1.c | |
| _asn1_delete_list_and_nodes | 2 | 6 | 13 | ../../lib/parser_aux.c | |
| _asn1_add_node_only | 2 | 6 | 13 | ../../lib/structure.c | |
| yystrlen | 2 | 6 | 24 | ../../lib/ASN1.c | |
| yy_symbol_print | 2 | 5 | 18 | ../../lib/ASN1.c | |
| _asn1_delete_list | 2 | 5 | 12 | ../../lib/parser_aux.c | |
| _asn1_error_description_value_not_found | 2 | 5 | 14 | ../../lib/coding.c | |
| yystpcpy | 2 | 5 | 17 | ../../lib/ASN1.c | |
| _asn1_mod_type | 2 | 4 | 8 | ../../lib/parser_aux.c | |
| _asn1_yyerror | 2 | 4 | 14 | ../../lib/ASN1.c | |
| asn1_perror | 2 | 3 | 6 | ../../lib/errors.c | |
| _asn1_get_name | 2 | 3 | 7 | ../../lib/parser_aux.c | |
| _asn1_get_down | 2 | 3 | 7 | ../../lib/parser_aux.c | |
| _asn1_get_right | 2 | 3 | 7 | ../../lib/parser_aux.c | |
| asn1_create_element | 2 | 10 | 21 | ../../lib/structure.c | |
| yy_reduce_print | 2 | 10 | 24 | ../../lib/ASN1.c | |
| _asn1_copy_structure2 | 1 | 3 | 10 | ../../lib/structure.c | |
| _asn1_error_description_tag_error | 1 | 3 | 10 | ../../lib/decoding.c | |
| YYID | 1 | 1 | 10 | ../../lib/ASN1.c | |
| libtasn1_strerror | 1 | 1 | 5 | ../../lib/errors.c | |