blob: ab4c3667152d894ddb802b783edb9246775d0385 [file] [log] [blame]
vlmfa67ddc2004-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>
vlm12557712004-06-17 23:43:39 +00006#include <limits.h> /* for CHAR_BIT */
vlmfa67ddc2004-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 */
vlmb42843a2004-06-05 08:17:50 +000028 0, /* Always in primitive form */
29 0 /* No specifics */
vlmfa67ddc2004-06-03 03:38:44 +000030};
31
32int
33RELATIVE_OID_print(asn1_TYPE_descriptor_t *td, const void *sptr, int ilevel,
34 asn_app_consume_bytes_f *cb, void *app_key) {
35 const RELATIVE_OID_t *st = sptr;
36 int startn;
37 int i;
38
vlmb42843a2004-06-05 08:17:50 +000039 (void)td; /* Unused argument */
40 (void)ilevel; /* Unused argument */
41
vlmfa67ddc2004-06-03 03:38:44 +000042 if(!st || !st->buf)
43 return cb("<absent>", 8, app_key);
44
45 /* Dump preamble */
46 if(cb("{ ", 2, app_key))
47 return -1;
48
49 for(i = 0, startn = 0; i < st->size; i++) {
50 uint8_t b = st->buf[i];
51 if((b & 0x80)) /* Continuation expected */
52 continue;
53 if(startn && cb(" ", 1, app_key)) /* Separate arcs */
54 return -1;
55 if(OBJECT_IDENTIFIER_print_arc(&st->buf[startn],
56 i - startn + 1, 0, cb, app_key))
57 return -1;
58 startn = i + 1;
59 }
60
61 return cb(" }", 2, app_key);
62}
63
64
65int
vlm2e3dd3b2004-06-14 07:24:36 +000066RELATIVE_OID_get_arcs(RELATIVE_OID_t *roid,
67 void *arcs, unsigned int arc_type_size, unsigned int arc_slots) {
68 void *arcs_end = arcs + (arc_slots * arc_type_size);
69 int num_arcs = 0;
vlmfa67ddc2004-06-03 03:38:44 +000070 int startn = 0;
71 int i;
72
73 if(!roid || !roid->buf) {
74 errno = EINVAL;
75 return -1;
76 }
77
78 for(i = 0; i < roid->size; i++) {
79 uint8_t b = roid->buf[i];
80 if((b & 0x80)) /* Continuation expected */
81 continue;
82
vlm2e3dd3b2004-06-14 07:24:36 +000083 if(arcs < arcs_end) {
84 if(OBJECT_IDENTIFIER_get_single_arc(
85 &roid->buf[startn],
86 i - startn + 1, 0,
87 arcs, arc_type_size))
vlmfa67ddc2004-06-03 03:38:44 +000088 return -1;
vlm2e3dd3b2004-06-14 07:24:36 +000089 arcs += arc_type_size;
90 num_arcs++;
vlmfa67ddc2004-06-03 03:38:44 +000091 }
92
93 startn = i + 1;
94 }
95
vlm2e3dd3b2004-06-14 07:24:36 +000096 return num_arcs;
vlmfa67ddc2004-06-03 03:38:44 +000097}
98
99int
vlm12557712004-06-17 23:43:39 +0000100RELATIVE_OID_set_arcs(RELATIVE_OID_t *roid, void *arcs, unsigned int arc_type_size, unsigned int arcs_slots) {
vlmfa67ddc2004-06-03 03:38:44 +0000101 uint8_t *buf;
102 uint8_t *bp;
vlma63e0292004-06-17 23:46:45 +0000103 unsigned int size;
104 unsigned int i;
vlmfa67ddc2004-06-03 03:38:44 +0000105
vlm12557712004-06-17 23:43:39 +0000106 if(roid == NULL || arcs == NULL || arc_type_size < 1) {
vlmfa67ddc2004-06-03 03:38:44 +0000107 errno = EINVAL;
108 return -1;
109 }
110
111 /*
112 * Roughly estimate the maximum size necessary to encode these arcs.
113 */
vlm12557712004-06-17 23:43:39 +0000114 size = ((arc_type_size * CHAR_BIT + 6) / 7) * arcs_slots;
vlmfa67ddc2004-06-03 03:38:44 +0000115 bp = buf = MALLOC(size + 1);
116 if(!buf) {
117 /* ENOMEM */
118 return -1;
119 }
120
121 /*
vlm12557712004-06-17 23:43:39 +0000122 * Encode the arcs.
vlmfa67ddc2004-06-03 03:38:44 +0000123 */
vlm12557712004-06-17 23:43:39 +0000124 for(i = 0; i < arcs_slots; i++, (char *)arcs += arc_type_size) {
125 bp += OBJECT_IDENTIFIER_set_single_arc(bp,
126 arcs, arc_type_size, 0);
vlmfa67ddc2004-06-03 03:38:44 +0000127 }
128
vlma63e0292004-06-17 23:46:45 +0000129 assert((unsigned)(bp - buf) <= size);
vlm12557712004-06-17 23:43:39 +0000130
vlmfa67ddc2004-06-03 03:38:44 +0000131 /*
132 * Replace buffer.
133 */
vlm12557712004-06-17 23:43:39 +0000134 roid->size = bp - buf;
vlmfa67ddc2004-06-03 03:38:44 +0000135 bp = roid->buf;
136 roid->buf = buf;
137 if(bp) FREEMEM(bp);
138
139 return 0;
140}
vlm12557712004-06-17 23:43:39 +0000141