1 #include "oid.h"
2
3 #include <errno.h>
4 #include "common.h"
5 #include "log.h"
6 #include "asn1/decode.h"
7
8 void
free_arcs(struct oid_arcs * arcs)9 free_arcs(struct oid_arcs *arcs)
10 {
11 free(arcs->arcs);
12 }
13
14 /*
15 * Wrapper for OBJECT_IDENTIFIER_get_arcs().
16 *
17 * Callers must free @result.
18 *
19 * TODO (fine) Most of the time, this function is called to compare @result
20 * to some oid. Maybe create a wrapper that takes care of all the boilerplate.
21 */
22 int
oid2arcs(OBJECT_IDENTIFIER_t * oid,struct oid_arcs * result)23 oid2arcs(OBJECT_IDENTIFIER_t *oid, struct oid_arcs *result)
24 {
25 static const size_t MAX_ARCS = 9;
26 ssize_t count;
27 ssize_t count2;
28 asn_oid_arc_t *tmp;
29
30 result->arcs = malloc(MAX_ARCS * sizeof(asn_oid_arc_t));
31 if (result->arcs == NULL)
32 return pr_enomem();
33
34 count = OBJECT_IDENTIFIER_get_arcs(oid, result->arcs, MAX_ARCS);
35 if (count < 0) {
36 pr_val_err("OBJECT_IDENTIFIER_get_arcs() returned %zd.", count);
37 free(result->arcs);
38 return count;
39 }
40
41 result->count = count;
42
43 /* If necessary, reallocate arcs array and try again. */
44 if (count > MAX_ARCS) {
45 tmp = realloc(result->arcs, count * sizeof(asn_oid_arc_t));
46 if (tmp == NULL) {
47 free(result->arcs);
48 return pr_enomem();
49 }
50 result->arcs = tmp;
51
52 count2 = OBJECT_IDENTIFIER_get_arcs(oid, result->arcs, count);
53 if (count != count2) {
54 pr_val_err("OBJECT_IDENTIFIER_get_arcs() returned %zd. (expected %zd)",
55 count2, count);
56 free(result->arcs);
57 return -EINVAL;
58 }
59 }
60
61 return 0;
62 }
63
oid_equal(OBJECT_IDENTIFIER_t * a,OBJECT_IDENTIFIER_t * b)64 bool oid_equal(OBJECT_IDENTIFIER_t *a, OBJECT_IDENTIFIER_t *b)
65 {
66 return (a->size == b->size) && (memcmp(a->buf, b->buf, a->size) == 0);
67 }
68
__arcs_equal(asn_oid_arc_t const * a,size_t a_count,asn_oid_arc_t const * b,size_t b_count)69 static bool __arcs_equal(asn_oid_arc_t const *a, size_t a_count,
70 asn_oid_arc_t const *b, size_t b_count)
71 {
72 long int i;
73
74 if (a_count != b_count)
75 return false;
76
77 /* Most OIDs start with the same numbers, so iterate backwards. */
78 for (i = a_count - 1; i >= 0; i--) {
79 if (a[i] != b[i])
80 return false;
81 }
82
83 return true;
84 }
85
arcs_equal(struct oid_arcs const * a,struct oid_arcs const * b)86 bool arcs_equal(struct oid_arcs const *a, struct oid_arcs const *b)
87 {
88 return __arcs_equal(a->arcs, a->count, b->arcs, b->count);
89 }
90
arcs_equal_oids(struct oid_arcs * arcs,asn_oid_arc_t const * oids,size_t oids_len)91 bool arcs_equal_oids(struct oid_arcs *arcs, asn_oid_arc_t const *oids,
92 size_t oids_len)
93 {
94 return __arcs_equal(arcs->arcs, arcs->count, oids, oids_len);
95 }
96