blob: 252cc37390eb17facda449792773672071279984 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001/*-
2 * Copyright (c) 2003, 2004 Lev Walkin <vlm@lionet.info>. All rights reserved.
3 * Redistribution and modifications are permitted subject to BSD license.
4 */
5#include <RELATIVE-OID.h>
Lev Walkin0787ff02004-06-17 23:43:39 +00006#include <limits.h> /* for CHAR_BIT */
Lev Walkinf15320b2004-06-03 03:38:44 +00007#include <assert.h>
8#include <errno.h>
9
10/*
11 * RELATIVE-OID basic type description.
12 */
13static ber_tlv_tag_t asn1_DEF_RELATIVE_OID_tags[] = {
14 (ASN_TAG_CLASS_UNIVERSAL | (13 << 2))
15};
16asn1_TYPE_descriptor_t asn1_DEF_RELATIVE_OID = {
17 "RELATIVE-OID",
18 asn_generic_no_constraint,
19 INTEGER_decode_ber, /* Implemented in terms of INTEGER type */
20 OBJECT_IDENTIFIER_encode_der,
21 RELATIVE_OID_print,
22 INTEGER_free,
23 0, /* Use generic outmost tag fetcher */
24 asn1_DEF_RELATIVE_OID_tags,
25 sizeof(asn1_DEF_RELATIVE_OID_tags)
26 / sizeof(asn1_DEF_RELATIVE_OID_tags[0]),
27 1, /* Single UNIVERSAL tag may be implicitly overriden */
Lev Walkind9bd7752004-06-05 08:17:50 +000028 0, /* Always in primitive form */
Lev Walkin449f8322004-08-20 13:23:42 +000029 0, 0, /* No members */
Lev Walkind9bd7752004-06-05 08:17:50 +000030 0 /* No specifics */
Lev Walkinf15320b2004-06-03 03:38:44 +000031};
32
33int
34RELATIVE_OID_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
35 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkinc2346572004-08-11 09:07:36 +000036 const RELATIVE_OID_t *st = (const RELATIVE_OID_t *)sptr;
Lev Walkinf15320b2004-06-03 03:38:44 +000037 int startn;
38 int i;
39
Lev Walkind9bd7752004-06-05 08:17:50 +000040 (void)td; /* Unused argument */
41 (void)ilevel; /* Unused argument */
42
Lev Walkinf15320b2004-06-03 03:38:44 +000043 if(!st || !st->buf)
44 return cb("<absent>", 8, app_key);
45
46 /* Dump preamble */
47 if(cb("{ ", 2, app_key))
48 return -1;
49
50 for(i = 0, startn = 0; i < st->size; i++) {
51 uint8_t b = st->buf[i];
52 if((b & 0x80)) /* Continuation expected */
53 continue;
54 if(startn && cb(" ", 1, app_key)) /* Separate arcs */
55 return -1;
56 if(OBJECT_IDENTIFIER_print_arc(&st->buf[startn],
57 i - startn + 1, 0, cb, app_key))
58 return -1;
59 startn = i + 1;
60 }
61
62 return cb(" }", 2, app_key);
63}
64
65
66int
Lev Walkin29a044b2004-06-14 07:24:36 +000067RELATIVE_OID_get_arcs(RELATIVE_OID_t *roid,
68 void *arcs, unsigned int arc_type_size, unsigned int arc_slots) {
Lev Walkin4d9528c2004-08-11 08:10:13 +000069 void *arcs_end = (char *)arcs + (arc_slots * arc_type_size);
Lev Walkin29a044b2004-06-14 07:24:36 +000070 int num_arcs = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +000071 int startn = 0;
72 int i;
73
74 if(!roid || !roid->buf) {
75 errno = EINVAL;
76 return -1;
77 }
78
79 for(i = 0; i < roid->size; i++) {
80 uint8_t b = roid->buf[i];
81 if((b & 0x80)) /* Continuation expected */
82 continue;
83
Lev Walkin29a044b2004-06-14 07:24:36 +000084 if(arcs < arcs_end) {
85 if(OBJECT_IDENTIFIER_get_single_arc(
86 &roid->buf[startn],
87 i - startn + 1, 0,
88 arcs, arc_type_size))
Lev Walkinf15320b2004-06-03 03:38:44 +000089 return -1;
Lev Walkin4ce78ca2004-08-25 01:34:11 +000090 arcs = ((char *)arcs) + arc_type_size;
Lev Walkin29a044b2004-06-14 07:24:36 +000091 num_arcs++;
Lev Walkinf15320b2004-06-03 03:38:44 +000092 }
93
94 startn = i + 1;
95 }
96
Lev Walkin29a044b2004-06-14 07:24:36 +000097 return num_arcs;
Lev Walkinf15320b2004-06-03 03:38:44 +000098}
99
100int
Lev Walkin0787ff02004-06-17 23:43:39 +0000101RELATIVE_OID_set_arcs(RELATIVE_OID_t *roid, void *arcs, unsigned int arc_type_size, unsigned int arcs_slots) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000102 uint8_t *buf;
103 uint8_t *bp;
Lev Walkin34b2a932004-06-17 23:46:45 +0000104 unsigned int size;
105 unsigned int i;
Lev Walkinf15320b2004-06-03 03:38:44 +0000106
Lev Walkin0787ff02004-06-17 23:43:39 +0000107 if(roid == NULL || arcs == NULL || arc_type_size < 1) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000108 errno = EINVAL;
109 return -1;
110 }
111
112 /*
113 * Roughly estimate the maximum size necessary to encode these arcs.
114 */
Lev Walkin0787ff02004-06-17 23:43:39 +0000115 size = ((arc_type_size * CHAR_BIT + 6) / 7) * arcs_slots;
Lev Walkinc2346572004-08-11 09:07:36 +0000116 bp = buf = (uint8_t *)MALLOC(size + 1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000117 if(!buf) {
118 /* ENOMEM */
119 return -1;
120 }
121
122 /*
Lev Walkin0787ff02004-06-17 23:43:39 +0000123 * Encode the arcs.
Lev Walkinf15320b2004-06-03 03:38:44 +0000124 */
Lev Walkin4ce78ca2004-08-25 01:34:11 +0000125 for(i = 0; i < arcs_slots; i++, arcs = ((char *)arcs) + arc_type_size) {
Lev Walkin0787ff02004-06-17 23:43:39 +0000126 bp += OBJECT_IDENTIFIER_set_single_arc(bp,
127 arcs, arc_type_size, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +0000128 }
129
Lev Walkin34b2a932004-06-17 23:46:45 +0000130 assert((unsigned)(bp - buf) <= size);
Lev Walkin0787ff02004-06-17 23:43:39 +0000131
Lev Walkinf15320b2004-06-03 03:38:44 +0000132 /*
133 * Replace buffer.
134 */
Lev Walkin0787ff02004-06-17 23:43:39 +0000135 roid->size = bp - buf;
Lev Walkinf15320b2004-06-03 03:38:44 +0000136 bp = roid->buf;
137 roid->buf = buf;
138 if(bp) FREEMEM(bp);
139
140 return 0;
141}
Lev Walkin0787ff02004-06-17 23:43:39 +0000142