asn1_node _asn1_cpy_name (asn1_node dst, asn1_node src) { if (dst == NULL) return dst; if (src == NULL) { dst->name[0] = 0; dst->name_hash = hash_pjw_bare (dst->name, 0); return dst; } _asn1_str_cpy (dst->name, sizeof (dst->name), src->name); dst->name_hash = src->name_hash; return dst; }
asn1_node _asn1_set_name (asn1_node node, const char *name) { unsigned int nsize; if (node == NULL) return node; if (name == NULL) { node->name[0] = 0; node->name_hash = hash_pjw_bare (node->name, 0); return node; } nsize = _asn1_str_cpy (node->name, sizeof (node->name), name); node->name_hash = hash_pjw_bare (node->name, nsize); return node; }
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_retCode _asn1_check_identifier (ASN1_TYPE node) { ASN1_TYPE p, p2; char name2[ASN1_MAX_NAME_SIZE * 2 + 2]; if (node == NULL) return ASN1_ELEMENT_NOT_FOUND; p = node; while (p) { if (type_field (p->type) == TYPE_IDENTIFIER) { _asn1_str_cpy (name2, sizeof (name2), node->name); _asn1_str_cat (name2, sizeof (name2), "."); _asn1_str_cat (name2, sizeof (name2), (char *) p->value); p2 = asn1_find_node (node, name2); if (p2 == NULL) { _asn1_strcpy (_asn1_identifierMissing, p->value); return ASN1_IDENTIFIER_NOT_FOUND; } } else if ((type_field (p->type) == TYPE_OBJECT_ID) && (p->type & CONST_DEFAULT)) { p2 = p->down; if (p2 && (type_field (p2->type) == TYPE_DEFAULT)) { _asn1_str_cpy (name2, sizeof (name2), node->name); _asn1_str_cat (name2, sizeof (name2), "."); _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); _asn1_strcpy (_asn1_identifierMissing, p2->value); p2 = asn1_find_node (node, name2); if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) || !(p2->type & CONST_ASSIGN)) return ASN1_IDENTIFIER_NOT_FOUND; else _asn1_identifierMissing[0] = 0; } } else if ((type_field (p->type) == TYPE_OBJECT_ID) && (p->type & CONST_ASSIGN)) { p2 = p->down; if (p2 && (type_field (p2->type) == TYPE_CONSTANT)) { if (p2->value && !isdigit (p2->value[0])) { _asn1_str_cpy (name2, sizeof (name2), node->name); _asn1_str_cat (name2, sizeof (name2), "."); _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); _asn1_strcpy (_asn1_identifierMissing, p2->value); p2 = asn1_find_node (node, name2); if (!p2 || (type_field (p2->type) != TYPE_OBJECT_ID) || !(p2->type & CONST_ASSIGN)) return ASN1_IDENTIFIER_NOT_FOUND; else _asn1_identifierMissing[0] = 0; } } } if (p->down) { p = p->down; } else if (p->right) p = p->right; else { while (1) { p = _asn1_find_up (p); if (p == node) { p = NULL; break; } if (p->right) { p = p->right; break; } } } } return ASN1_SUCCESS; }
/** * asn1_find_node: * @pointer: NODE_ASN element pointer. * @name: null terminated string with the element's name to find. * * Searches for an element called @name starting from @pointer. The * name is composed by differents identifiers separated by dots. When * *@pointer has a name, the first identifier must be the name of * *@pointer, otherwise it must be the name of one child of *@pointer. * * Returns: the search result, or %NULL if not found. **/ 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_retCode _asn1_expand_object_id (ASN1_TYPE node) { ASN1_TYPE p, p2, p3, p4, p5; char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; int move, tlen; if (node == NULL) return ASN1_ELEMENT_NOT_FOUND; _asn1_str_cpy (name_root, sizeof (name_root), node->name); p = node; move = DOWN; while (!((p == node) && (move == UP))) { if (move != UP) { if ((type_field (p->type) == TYPE_OBJECT_ID) && (p->type & CONST_ASSIGN)) { p2 = p->down; if (p2 && (type_field (p2->type) == TYPE_CONSTANT)) { if (p2->value && !isdigit (p2->value[0])) { _asn1_str_cpy (name2, sizeof (name2), name_root); _asn1_str_cat (name2, sizeof (name2), "."); _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); p3 = asn1_find_node (node, name2); if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) || !(p3->type & CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND; _asn1_set_down (p, p2->right); _asn1_remove_node (p2); p2 = p; p4 = p3->down; while (p4) { if (type_field (p4->type) == TYPE_CONSTANT) { p5 = _asn1_add_node_only (TYPE_CONSTANT); _asn1_set_name (p5, p4->name); tlen = _asn1_strlen (p4->value); if (tlen > 0) _asn1_set_value (p5, p4->value, tlen + 1); if (p2 == p) { _asn1_set_right (p5, p->down); _asn1_set_down (p, p5); } else { _asn1_set_right (p5, p2->right); _asn1_set_right (p2, p5); } p2 = p5; } p4 = p4->right; } move = DOWN; continue; } } } move = DOWN; } else move = RIGHT; if (move == DOWN) { if (p->down) p = p->down; else move = RIGHT; } if (p == node) { move = UP; continue; } if (move == RIGHT) { if (p->right) p = p->right; else move = UP; } if (move == UP) p = _asn1_find_up (p); } /*******************************/ /* expand DEFAULT */ /*******************************/ p = node; move = DOWN; while (!((p == node) && (move == UP))) { if (move != UP) { if ((type_field (p->type) == TYPE_OBJECT_ID) && (p->type & CONST_DEFAULT)) { p2 = p->down; if (p2 && (type_field (p2->type) == TYPE_DEFAULT)) { _asn1_str_cpy (name2, sizeof (name2), name_root); _asn1_str_cat (name2, sizeof (name2), "."); _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); p3 = asn1_find_node (node, name2); if (!p3 || (type_field (p3->type) != TYPE_OBJECT_ID) || !(p3->type & CONST_ASSIGN)) return ASN1_ELEMENT_NOT_FOUND; p4 = p3->down; name2[0] = 0; while (p4) { if (type_field (p4->type) == TYPE_CONSTANT) { if (name2[0]) _asn1_str_cat (name2, sizeof (name2), "."); _asn1_str_cat (name2, sizeof (name2), (char *) p4->value); } p4 = p4->right; } tlen = strlen (name2); if (tlen > 0) _asn1_set_value (p2, name2, tlen + 1); } } move = DOWN; } else move = RIGHT; if (move == DOWN) { if (p->down) p = p->down; else move = RIGHT; } if (p == node) { move = UP; continue; } if (move == RIGHT) { if (p->right) p = p->right; else move = UP; } if (move == UP) p = _asn1_find_up (p); } return ASN1_SUCCESS; }
/** * asn1_find_node: * @pointer: NODE_ASN element pointer. * @name: null terminated string with the element's name to find. * * Searches for an element called @name starting from @pointer. The * name is composed by differents identifiers separated by dots. When * *@pointer has a name, the first identifier must be the name of * *@pointer, otherwise it must be the name of one child of *@pointer. * * Returns: the search result, or %NULL if not found. **/ asn1_node asn1_find_node (asn1_node pointer, const char *name) { asn1_node p; char *n_end, n[ASN1_MAX_NAME_SIZE + 1]; const char *n_start; unsigned int nsize; unsigned int nhash; if (pointer == NULL) return NULL; if (name == NULL) return NULL; p = pointer; n_start = name; if (p->name[0] != 0) { /* has *pointer got a name ? */ n_end = strchr (n_start, '.'); /* search the first dot */ if (n_end) { nsize = n_end - n_start; memcpy (n, n_start, nsize); n[nsize] = 0; n_start = n_end; n_start++; nhash = hash_pjw_bare (n, nsize); } else { nsize = _asn1_str_cpy (n, sizeof (n), n_start); nhash = hash_pjw_bare (n, nsize); n_start = NULL; } while (p) { if ((p->name) && nhash == p->name_hash && (!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) { nsize = n_end - n_start; memcpy (n, n_start, nsize); n[nsize] = 0; n_start = n_end; n_start++; nhash = hash_pjw_bare (n, nsize); } else { nsize = _asn1_str_cpy (n, sizeof (n), n_start); nhash = hash_pjw_bare (n, nsize); 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_hash == nhash && !strcmp (p->name, n)) break; else p = p->right; } if (p == NULL) return NULL; } } /* while */ return p; }