blob: bee795c481fe44622889b888c4ef8d30205c4777 [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]),
Lev Walkin188ed2c2004-09-13 08:31:01 +000027 asn1_DEF_RELATIVE_OID_tags, /* Same as above */
28 sizeof(asn1_DEF_RELATIVE_OID_tags)
29 / sizeof(asn1_DEF_RELATIVE_OID_tags[0]),
Lev Walkind9bd7752004-06-05 08:17:50 +000030 0, /* Always in primitive form */
Lev Walkin449f8322004-08-20 13:23:42 +000031 0, 0, /* No members */
Lev Walkind9bd7752004-06-05 08:17:50 +000032 0 /* No specifics */
Lev Walkinf15320b2004-06-03 03:38:44 +000033};
34
35int
36RELATIVE_OID_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
37 asn_app_consume_bytes_f *cb, void *app_key) {
Lev Walkinc2346572004-08-11 09:07:36 +000038 const RELATIVE_OID_t *st = (const RELATIVE_OID_t *)sptr;
Lev Walkinf15320b2004-06-03 03:38:44 +000039 int startn;
40 int i;
41
Lev Walkind9bd7752004-06-05 08:17:50 +000042 (void)td; /* Unused argument */
43 (void)ilevel; /* Unused argument */
44
Lev Walkinf15320b2004-06-03 03:38:44 +000045 if(!st || !st->buf)
46 return cb("<absent>", 8, app_key);
47
48 /* Dump preamble */
49 if(cb("{ ", 2, app_key))
50 return -1;
51
52 for(i = 0, startn = 0; i < st->size; i++) {
53 uint8_t b = st->buf[i];
54 if((b & 0x80)) /* Continuation expected */
55 continue;
56 if(startn && cb(" ", 1, app_key)) /* Separate arcs */
57 return -1;
58 if(OBJECT_IDENTIFIER_print_arc(&st->buf[startn],
59 i - startn + 1, 0, cb, app_key))
60 return -1;
61 startn = i + 1;
62 }
63
64 return cb(" }", 2, app_key);
65}
66
67
68int
Lev Walkin29a044b2004-06-14 07:24:36 +000069RELATIVE_OID_get_arcs(RELATIVE_OID_t *roid,
70 void *arcs, unsigned int arc_type_size, unsigned int arc_slots) {
Lev Walkin4d9528c2004-08-11 08:10:13 +000071 void *arcs_end = (char *)arcs + (arc_slots * arc_type_size);
Lev Walkin29a044b2004-06-14 07:24:36 +000072 int num_arcs = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +000073 int startn = 0;
74 int i;
75
76 if(!roid || !roid->buf) {
77 errno = EINVAL;
78 return -1;
79 }
80
81 for(i = 0; i < roid->size; i++) {
82 uint8_t b = roid->buf[i];
83 if((b & 0x80)) /* Continuation expected */
84 continue;
85
Lev Walkin29a044b2004-06-14 07:24:36 +000086 if(arcs < arcs_end) {
87 if(OBJECT_IDENTIFIER_get_single_arc(
88 &roid->buf[startn],
89 i - startn + 1, 0,
90 arcs, arc_type_size))
Lev Walkinf15320b2004-06-03 03:38:44 +000091 return -1;
Lev Walkin4ce78ca2004-08-25 01:34:11 +000092 arcs = ((char *)arcs) + arc_type_size;
Lev Walkin29a044b2004-06-14 07:24:36 +000093 num_arcs++;
Lev Walkinf15320b2004-06-03 03:38:44 +000094 }
95
96 startn = i + 1;
97 }
98
Lev Walkin29a044b2004-06-14 07:24:36 +000099 return num_arcs;
Lev Walkinf15320b2004-06-03 03:38:44 +0000100}
101
102int
Lev Walkin0787ff02004-06-17 23:43:39 +0000103RELATIVE_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 +0000104 uint8_t *buf;
105 uint8_t *bp;
Lev Walkin34b2a932004-06-17 23:46:45 +0000106 unsigned int size;
107 unsigned int i;
Lev Walkinf15320b2004-06-03 03:38:44 +0000108
Lev Walkin0787ff02004-06-17 23:43:39 +0000109 if(roid == NULL || arcs == NULL || arc_type_size < 1) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000110 errno = EINVAL;
111 return -1;
112 }
113
114 /*
115 * Roughly estimate the maximum size necessary to encode these arcs.
116 */
Lev Walkin0787ff02004-06-17 23:43:39 +0000117 size = ((arc_type_size * CHAR_BIT + 6) / 7) * arcs_slots;
Lev Walkinc2346572004-08-11 09:07:36 +0000118 bp = buf = (uint8_t *)MALLOC(size + 1);
Lev Walkinf15320b2004-06-03 03:38:44 +0000119 if(!buf) {
120 /* ENOMEM */
121 return -1;
122 }
123
124 /*
Lev Walkin0787ff02004-06-17 23:43:39 +0000125 * Encode the arcs.
Lev Walkinf15320b2004-06-03 03:38:44 +0000126 */
Lev Walkin4ce78ca2004-08-25 01:34:11 +0000127 for(i = 0; i < arcs_slots; i++, arcs = ((char *)arcs) + arc_type_size) {
Lev Walkin0787ff02004-06-17 23:43:39 +0000128 bp += OBJECT_IDENTIFIER_set_single_arc(bp,
129 arcs, arc_type_size, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +0000130 }
131
Lev Walkin34b2a932004-06-17 23:46:45 +0000132 assert((unsigned)(bp - buf) <= size);
Lev Walkin0787ff02004-06-17 23:43:39 +0000133
Lev Walkinf15320b2004-06-03 03:38:44 +0000134 /*
135 * Replace buffer.
136 */
Lev Walkin0787ff02004-06-17 23:43:39 +0000137 roid->size = bp - buf;
Lev Walkinf15320b2004-06-03 03:38:44 +0000138 bp = roid->buf;
139 roid->buf = buf;
140 if(bp) FREEMEM(bp);
141
142 return 0;
143}
Lev Walkin0787ff02004-06-17 23:43:39 +0000144